summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2013-03-01 18:01:44 +0200
committerMichael Widenius <monty@askmonty.org>2013-03-01 18:01:44 +0200
commit8ed283d882e7147b1caa3f90f708720c94446024 (patch)
tree6331e41475ba0f8408cde0700b86d44f04ff32fa /sql/sql_table.cc
parentb917fdb9f1427786ec54adfeb963fabd6bf11f74 (diff)
downloadmariadb-git-8ed283d882e7147b1caa3f90f708720c94446024.tar.gz
Fixed bug MPDEV-628 / LP:989055 - Querying myisam table metadata may corrupt the table.
The issue was that there was that SHOW commands could open the table in the store engine, even in cases where it should not be allowed to do that (ie, the storage engines meta data for that table was under big changes). The cases where this should not be allowed are: - ALTER TABLE DISABLE KEYS - ALTER TABLE ENABLE KEYS - REPAIR TABLE - OPTIMIZE TABLE - DROP TABLE This patch adds a new mode, protected_against_usage(). If this is used then the SHOW command will wait until the table is accessable. This is implemented by re-using the already exising 'version' flag for TABLE_SHARE. It also added functions to be used to change TABLE_SHARE->version instead of changing it directly. mysql-test/r/myisam-metadata.result: Added test case mysql-test/t/myisam-metadata.test: Added test case sql/mysqld.cc: Start from refresh_version 2 as 0 and 1 are reserved. sql/sql_admin.cc: Added MYSQL_OPEN_FOR_REPAIR Updated call to wait_while_table_is_used() sql/sql_base.cc: Updated call to wait_while_table_is_used() - Allow one to specify how the table should be removed (for all commands except show or for all commands). - Don't allow one to reopen the table if one has called share->protect_against_usage() sql/sql_base.h: Added TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE, which is used to mark that no one can reopen this table, except with MYSQL_OPEN_FOR_REPAIR . - Added MYSQL_OPEN_FOR_REPAIR - Updated prototype for wait_while_table_is_used() sql/sql_table.cc: Updated call to wait_while_table_is_used() Use MYSQL_OPEN_FOR_REPAIR for open tables that where repaired. sql/sql_truncate.cc: Updated call to wait_while_table_is_used() sql/table.cc: Use set_refresh_version() sql/table.h: Added functions to be used to change TABLE_SHARE->version instead of changing it directly
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc19
1 files changed, 13 insertions, 6 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 330c28ebbd8..fed05c5902e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2190,7 +2190,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
if (thd->locked_tables_mode)
{
- if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
+ if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
{
error= -1;
goto err;
@@ -6237,13 +6238,15 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
case LEAVE_AS_IS:
break;
case ENABLE:
- if (wait_while_table_is_used(thd, table, extra_func))
+ if (wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err;
DEBUG_SYNC(thd,"alter_table_enable_indexes");
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
break;
case DISABLE:
- if (wait_while_table_is_used(thd, table, extra_func))
+ if (wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err;
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
break;
@@ -6271,7 +6274,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
simple rename did nothing and therefore we can safely return
without additional clean-up.
*/
- if (wait_while_table_is_used(thd, table, extra_func))
+ if (wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err;
close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME);
/*
@@ -6704,6 +6708,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (table->s->tmp_table)
{
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
+ MYSQL_OPEN_FOR_REPAIR |
MYSQL_LOCK_IGNORE_TIMEOUT));
TABLE_LIST tbl;
bzero((void*) &tbl, sizeof(tbl));
@@ -6776,7 +6781,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
table->file->indexes_are_disabled())
need_lock_for_indexes= true;
if (!table->s->tmp_table && need_lock_for_indexes &&
- wait_while_table_is_used(thd, table, extra_func))
+ wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err_new_table_cleanup;
thd_proc_info(thd, "manage keys");
DEBUG_SYNC(thd, "alter_table_manage_keys");
@@ -6996,7 +7002,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (lower_case_table_names)
my_casedn_str(files_charset_info, old_name);
- if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
+ if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
{
if (pending_inplace_add_index)
{