Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
a489ae89
Commit
a489ae89
authored
Apr 09, 2013
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix mysql_rm_table_no_locks() not to use dd_frm_type, because the frm file
may not exist (the table exists only in the engine).
parent
e5a323e1
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
127 additions
and
61 deletions
+127
-61
mysql-test/include/mix1.inc
mysql-test/include/mix1.inc
+0
-6
mysql-test/r/plugin.result
mysql-test/r/plugin.result
+7
-1
mysql-test/suite/innodb/r/innodb_mysql.result
mysql-test/suite/innodb/r/innodb_mysql.result
+4
-3
mysql-test/t/plugin.test
mysql-test/t/plugin.test
+18
-3
sql/handler.cc
sql/handler.cc
+54
-13
sql/handler.h
sql/handler.h
+4
-1
sql/sql_plugin.cc
sql/sql_plugin.cc
+2
-1
sql/sql_table.cc
sql/sql_table.cc
+35
-31
sql/table.h
sql/table.h
+3
-2
No files found.
mysql-test/include/mix1.inc
View file @
a489ae89
...
...
@@ -630,15 +630,9 @@ copy_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/bug29807.frm;
--
error
ER_NO_SUCH_TABLE_IN_ENGINE
select
*
from
bug29807
;
drop
table
t1
;
--
error
ER_BAD_TABLE_ERROR
drop
table
bug29807
;
create
table
bug29807
(
a
int
);
drop
table
bug29807
;
--
disable_query_log
call
mtr
.
add_suppression
(
"InnoDB: Error: table .test...bug29807. does not exist in the InnoDB internal"
);
call
mtr
.
add_suppression
(
"Cannot find or open table test\/bug29807 from"
);
call
mtr
.
add_suppression
(
"Table 'test.bug29807' doesn't exist in engine"
);
--
enable_query_log
#
...
...
mysql-test/r/plugin.result
View file @
a489ae89
...
...
@@ -35,7 +35,9 @@ PLUGIN_LICENSE GPL
LOAD_OPTION ON
PLUGIN_MATURITY Experimental
PLUGIN_AUTH_VERSION 3.14.15.926
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
CREATE TABLE t1 (a int) ENGINE=EXAMPLE;
CREATE TABLE t2 (a int) ENGINE=EXAMPLE;
FLUSH TABLES;
SELECT * FROM t1;
a
set global example_ulong_var=500;
...
...
@@ -65,6 +67,10 @@ LOAD_OPTION ON
PLUGIN_MATURITY Experimental
PLUGIN_AUTH_VERSION 0.1
DROP TABLE t1;
select * from information_schema.plugins where plugin_library like 'ha_example%';
SELECT * FROM t2;
ERROR 42000: Unknown storage engine 'EXAMPLE'
DROP TABLE t2;
UNINSTALL PLUGIN EXAMPLE;
ERROR 42000: PLUGIN EXAMPLE does not exist
UNINSTALL PLUGIN non_exist;
...
...
mysql-test/suite/innodb/r/innodb_mysql.result
View file @
a489ae89
...
...
@@ -633,9 +633,10 @@ select * from bug29807;
ERROR 42S02: Table 'test.bug29807' doesn't exist in engine
drop table t1;
drop table bug29807;
ERROR 42S02: Unknown table 'bug29807'
create table bug29807 (a int);
drop table bug29807;
Warnings:
Warning 155 Table 'test.bug29807' doesn't exist in engine
call mtr.add_suppression("InnoDB: Error: table .test...bug29807. does not exist in the InnoDB internal");
call mtr.add_suppression("Cannot find or open table test\/bug29807 from");
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
switch to connection c1
...
...
mysql-test/t/plugin.test
View file @
a489ae89
...
...
@@ -16,12 +16,13 @@ INSTALL SONAME 'ha_example';
--
replace_regex
/
\
.
dll
/.
so
/
--
query_vertical
select
*
from
information_schema
.
plugins
where
plugin_library
like
'ha_example%'
CREATE
TABLE
t1
(
a
int
)
ENGINE
=
EXAMPLE
;
CREATE
TABLE
t1
(
a
int
)
ENGINE
=
EXAMPLE
;
CREATE
TABLE
t2
(
a
int
)
ENGINE
=
EXAMPLE
;
FLUSH
TABLES
;
# Let's do some advanced ops with the example engine :)
SELECT
*
FROM
t1
;
# a couple of tests for variables
set
global
example_ulong_var
=
500
;
set
global
example_enum_var
=
e1
;
...
...
@@ -29,12 +30,26 @@ show status like 'example%';
show
variables
like
'example%'
;
UNINSTALL
SONAME
'ha_example'
;
# the engine is NOT uninstalled yet,
# because the table `t1` is open, sitting in the table defintion cache
--
replace_column
5
#
--
replace_regex
/
\
.
dll
/.
so
/
--
query_vertical
select
*
from
information_schema
.
plugins
where
plugin_library
like
'ha_example%'
DROP
TABLE
t1
;
# now the engine IS unloaded
# and the table `t2` belongs to an unknown engine
--
replace_column
5
#
--
replace_regex
/
\
.
dll
/.
so
/
--
query_vertical
select
*
from
information_schema
.
plugins
where
plugin_library
like
'ha_example%'
--
error
ER_UNKNOWN_STORAGE_ENGINE
SELECT
*
FROM
t2
;
DROP
TABLE
t2
;
--
error
1305
UNINSTALL
PLUGIN
EXAMPLE
;
...
...
sql/handler.cc
View file @
a489ae89
...
...
@@ -2202,15 +2202,15 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
TABLE_SHARE
dummy_share
;
DBUG_ENTER
(
"ha_delete_table"
);
/* table_type is NULL in ALTER TABLE when renaming only .frm files */
if
(
table_type
==
NULL
||
table_type
==
view_pseudo_hton
||
!
(
file
=
get_new_handler
((
TABLE_SHARE
*
)
0
,
thd
->
mem_root
,
table_type
)))
DBUG_RETURN
(
HA_ERR_NO_SUCH_TABLE
);
bzero
((
char
*
)
&
dummy_table
,
sizeof
(
dummy_table
));
bzero
((
char
*
)
&
dummy_share
,
sizeof
(
dummy_share
));
dummy_table
.
s
=
&
dummy_share
;
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
if
(
table_type
==
NULL
||
!
(
file
=
get_new_handler
((
TABLE_SHARE
*
)
0
,
thd
->
mem_root
,
table_type
)))
DBUG_RETURN
(
HA_ERR_NO_SUCH_TABLE
);
path
=
get_canonical_filename
(
file
,
path
,
tmp_path
);
if
((
error
=
file
->
ha_delete_table
(
path
))
&&
generate_warning
)
{
...
...
@@ -4319,10 +4319,6 @@ int ha_discover_table(THD *thd, TABLE_SHARE *share)
DBUG_RETURN
(
share
->
error
!=
OPEN_FRM_OK
);
}
/**
Check if a given table exists, without doing a full discover, if possible
*/
static
my_bool
file_ext_exists
(
char
*
path
,
size_t
path_len
,
const
char
*
ext
)
{
strmake
(
path
+
path_len
,
ext
,
FN_REFLEN
-
path_len
);
...
...
@@ -4334,6 +4330,7 @@ struct st_discover_existence_args
char
*
path
;
size_t
path_len
;
const
char
*
db
,
*
table_name
;
handlerton
*
hton
;
};
static
my_bool
discover_existence
(
THD
*
thd
,
plugin_ref
plugin
,
...
...
@@ -4344,6 +4341,8 @@ static my_bool discover_existence(THD *thd, plugin_ref plugin,
if
(
ht
->
state
!=
SHOW_OPTION_YES
||
!
ht
->
discover_table_existence
)
return
FALSE
;
args
->
hton
=
ht
;
if
(
ht
->
discover_table_existence
==
ext_based_existence
)
return
file_ext_exists
(
args
->
path
,
args
->
path_len
,
ht
->
tablefile_extensions
[
0
]);
...
...
@@ -4390,25 +4389,53 @@ private:
int
m_unhandled_errors
;
};
bool
ha_table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
)
/**
Check if a given table exists, without doing a full discover, if possible
If the 'hton' is not NULL, it's set to the handlerton of the storage engine
of this table, or to view_pseudo_hton if the frm belongs to a view.
@retval true Table exists (even if the error occurred, like bad frm)
@retval false Table does not exist (one can do CREATE TABLE table_name)
*/
bool
ha_table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
handlerton
**
hton
)
{
DBUG_ENTER
(
"ha_discover_table_existence"
);
DBUG_ENTER
(
"ha_table_exists"
);
if
(
hton
)
*
hton
=
0
;
if
(
need_full_discover_for_existence
)
{
TABLE_LIST
table
;
uint
flags
=
GTS_TABLE
|
GTS_VIEW
;
if
(
!
hton
)
flags
|=
GTS_NOLOCK
;
Table_exists_error_handler
no_such_table_handler
;
thd
->
push_internal_handler
(
&
no_such_table_handler
);
get_table_share
(
thd
,
db
,
table_name
,
GTS_TABLE
|
GTS_VIEW
|
GTS_NOLOCK
);
TABLE_SHARE
*
share
=
get_table_share
(
thd
,
db
,
table_name
,
flags
);
thd
->
pop_internal_handler
();
if
(
hton
&&
share
)
{
*
hton
=
share
->
db_type
();
mysql_mutex_lock
(
&
LOCK_open
);
release_table_share
(
share
);
mysql_mutex_unlock
(
&
LOCK_open
);
}
// the table doesn't exist if we've caught ER_NO_SUCH_TABLE and nothing else
DBUG_RETURN
(
!
no_such_table_handler
.
safely_trapped_errors
());
}
mysql_mutex_lock
(
&
LOCK_open
);
TABLE_SHARE
*
share
=
get_cached_table_share
(
db
,
table_name
);
if
(
hton
&&
share
)
*
hton
=
share
->
db_type
();
mysql_mutex_unlock
(
&
LOCK_open
);
if
(
share
)
...
...
@@ -4419,13 +4446,27 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name)
db
,
table_name
,
""
,
0
);
if
(
file_ext_exists
(
path
,
path_len
,
reg_ext
))
{
if
(
hton
)
{
enum
legacy_db_type
db_type
;
if
(
dd_frm_type
(
thd
,
path
,
&
db_type
)
!=
FRMTYPE_VIEW
)
*
hton
=
ha_resolve_by_legacy_type
(
thd
,
db_type
);
else
*
hton
=
view_pseudo_hton
;
}
DBUG_RETURN
(
TRUE
);
}
st_discover_existence_args
args
=
{
path
,
path_len
,
db
,
table_name
};
st_discover_existence_args
args
=
{
path
,
path_len
,
db
,
table_name
,
0
};
if
(
plugin_foreach
(
thd
,
discover_existence
,
MYSQL_STORAGE_ENGINE_PLUGIN
,
&
args
))
{
if
(
hton
)
*
hton
=
args
.
hton
;
DBUG_RETURN
(
TRUE
);
}
DBUG_RETURN
(
FALSE
);
}
...
...
sql/handler.h
View file @
a489ae89
...
...
@@ -3073,6 +3073,8 @@ static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
(
db_type
->
state
==
SHOW_OPTION_YES
)
:
FALSE
;
}
#define view_pseudo_hton ((handlerton *)1)
/* basic stuff */
int
ha_init_errors
(
void
);
int
ha_init
(
void
);
...
...
@@ -3102,7 +3104,8 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
int
ha_discover_table
(
THD
*
thd
,
TABLE_SHARE
*
share
);
int
ha_discover_table_names
(
THD
*
thd
,
LEX_STRING
*
db
,
MY_DIR
*
dirp
,
handlerton
::
discovered_list
*
result
);
bool
ha_table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
);
bool
ha_table_exists
(
THD
*
thd
,
const
char
*
db
,
const
char
*
table_name
,
handlerton
**
hton
=
0
);
#ifdef MYSQL_SERVER
extern
volatile
int32
engines_with_discover_table_names
;
...
...
sql/sql_plugin.cc
View file @
a489ae89
...
...
@@ -906,7 +906,8 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc)
mysql_mutex_assert_owner
(
&
LOCK_plugin
);
if
(
pi
->
state
&
(
PLUGIN_IS_READY
|
PLUGIN_IS_UNINITIALIZED
))
if
(
pi
->
state
&
(
PLUGIN_IS_READY
|
PLUGIN_IS_UNINITIALIZED
|
PLUGIN_IS_DELETED
))
{
plugin_ref
plugin
;
#ifdef DBUG_OFF
...
...
sql/sql_table.cc
View file @
a489ae89
...
...
@@ -54,7 +54,6 @@
#include "sql_parse.h"
#include "sql_show.h"
#include "transaction.h"
#include "datadict.h" // dd_frm_type()
#ifdef __WIN__
#include <io.h>
...
...
@@ -2137,8 +2136,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
bool
is_trans
;
char
*
db
=
table
->
db
;
size_t
db_length
=
table
->
db_length
;
handlerton
*
table_type
;
enum
legacy_db_type
frm_db_type
=
DB_TYPE_UNKNOWN
;
handlerton
*
table_type
=
0
;
DBUG_PRINT
(
"table"
,
(
"table_l: '%s'.'%s' table: 0x%lx s: 0x%lx"
,
table
->
db
,
table
->
table_name
,
(
long
)
table
->
table
,
...
...
@@ -2262,8 +2260,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
DEBUG_SYNC
(
thd
,
"rm_table_no_locks_before_delete_table"
);
error
=
0
;
if
(
!
table
->
internal_tmp_table
&&
(
drop_temporary
||
!
ha_table_exists
(
thd
,
db
,
alias
)
||
(
!
drop_view
&&
dd_frm_type
(
thd
,
path
,
&
frm_db_type
)
!=
FRMTYPE_TABLE
)))
(
drop_temporary
||
!
ha_table_exists
(
thd
,
db
,
alias
,
&
table_type
)
||
(
!
drop_view
&&
table_type
==
view_pseudo_hton
)))
{
/*
One of the following cases happened:
...
...
@@ -2290,6 +2288,19 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
{
char
*
end
;
/*
It could happen that table's share in the table_def_cache
is the only thing that keeps the engine plugin loaded
(if it is uninstalled and waits for the ref counter to drop to 0).
In this case, the tdc_remove_table() below will release and unload
the plugin. And ha_delete_table() will get a dangling pointer.
Let's lock the plugin till the end of the statement.
*/
if
(
table_type
&&
table_type
!=
view_pseudo_hton
)
plugin_lock
(
thd
,
plugin_int_to_ref
(
hton2plugin
[
table_type
->
slot
]));
if
(
thd
->
locked_tables_mode
)
{
if
(
wait_while_table_is_used
(
thd
,
table
->
table
,
HA_EXTRA_NOT_USED
,
...
...
@@ -2298,6 +2309,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
error
=
-
1
;
goto
err
;
}
/* the following internally does TDC_RT_REMOVE_ALL */
close_all_tables_for_name
(
thd
,
table
->
table
->
s
,
HA_EXTRA_PREPARE_FOR_DROP
);
table
->
table
=
0
;
...
...
@@ -2311,30 +2323,12 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
table
->
table_name
,
MDL_EXCLUSIVE
));
/*
Cannot use the db_type from the table, since that might have changed
while waiting for the exclusive name lock.
*/
if
(
frm_db_type
==
DB_TYPE_UNKNOWN
)
{
dd_frm_type
(
thd
,
path
,
&
frm_db_type
);
DBUG_PRINT
(
"info"
,
(
"frm_db_type %d from %s"
,
frm_db_type
,
path
));
}
table_type
=
ha_resolve_by_legacy_type
(
thd
,
frm_db_type
);
// Remove extension for delete
*
(
end
=
path
+
path_length
-
reg_ext_length
)
=
'\0'
;
DBUG_PRINT
(
"info"
,
(
"deleting table of type %d"
,
(
table_type
?
table_type
->
db_type
:
0
)));
error
=
ha_delete_table
(
thd
,
table_type
,
path
,
db
,
table
->
table_name
,
!
dont_log_query
);
/* No error if non existent table and 'IF EXIST' clause or view */
if
(
error
==
ENOENT
||
(
error
==
HA_ERR_NO_SUCH_TABLE
&&
(
if_exists
||
table_type
==
NULL
)))
{
error
=
0
;
thd
->
clear_error
();
}
if
(
error
==
HA_ERR_ROW_IS_REFERENCED
)
{
/* the table is referenced by a foreign key constraint */
...
...
@@ -2342,18 +2336,29 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
}
if
(
!
error
||
error
==
ENOENT
||
error
==
HA_ERR_NO_SUCH_TABLE
)
{
int
new_error
;
int
frm_delete_error
,
trigger_drop_error
=
0
;
/* Delete the table definition file */
strmov
(
end
,
reg_ext
);
if
(
!
(
new_error
=
mysql_file_delete
(
key_file_frm
,
path
,
MYF
(
MY_WME
))))
frm_delete_error
=
mysql_file_delete
(
key_file_frm
,
path
,
MYF
(
MY_WME
));
if
(
frm_delete_error
)
frm_delete_error
=
my_errno
;
else
{
non_tmp_table_deleted
=
TRUE
;
new_error
=
Table_triggers_list
::
drop_all_triggers
(
thd
,
db
,
table
->
table_name
);
trigger_drop_error
=
Table_triggers_list
::
drop_all_triggers
(
thd
,
db
,
table
->
table_name
);
}
if
(
trigger_drop_error
||
(
frm_delete_error
&&
frm_delete_error
!=
ENOENT
))
error
=
1
;
else
if
(
!
frm_delete_error
||
!
error
||
if_exists
)
{
error
=
0
;
thd
->
clear_error
();
}
error
|=
new_error
;
}
non_tmp_error
=
error
?
TRUE
:
non_tmp_error
;
non_tmp_error
=
error
?
TRUE
:
non_tmp_error
;
}
if
(
error
)
{
...
...
@@ -2376,7 +2381,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
err:
if
(
wrong_tables
.
length
())
{
thd
->
clear_error
();
if
(
!
foreign_key_error
)
my_printf_error
(
ER_BAD_TABLE_ERROR
,
ER
(
ER_BAD_TABLE_ERROR
),
MYF
(
0
),
wrong_tables
.
c_ptr_safe
());
...
...
sql/table.h
View file @
a489ae89
...
...
@@ -665,8 +665,9 @@ struct TABLE_SHARE
plugin_ref
db_plugin
;
/* storage engine plugin */
inline
handlerton
*
db_type
()
const
/* table_type for handler */
{
// DBUG_ASSERT(db_plugin);
return
db_plugin
?
plugin_data
(
db_plugin
,
handlerton
*
)
:
NULL
;
return
is_view
?
view_pseudo_hton
:
db_plugin
?
plugin_data
(
db_plugin
,
handlerton
*
)
:
NULL
;
}
enum
row_type
row_type
;
/* How rows are stored */
enum
tmp_table_type
tmp_table
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment