summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@oracle.com>2011-03-08 09:41:57 +0100
committerJon Olav Hauglid <jon.hauglid@oracle.com>2011-03-08 09:41:57 +0100
commit0db0e64f33bda17852d9de57aa5a1d376af95db2 (patch)
treefb3ca01906c1101545f56910a7c3783185e1958e /sql
parent5e32755e4cd7d1f8b6c3fd667540f34dacc4c3d2 (diff)
downloadmariadb-git-0db0e64f33bda17852d9de57aa5a1d376af95db2.tar.gz
Bug #11755431 (former 47205)
MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR ENGINES NOT SUPPORTING NATIVE REPAIR Executing 'mysqlcheck --check-upgrade --auto-repair ...' will first issue 'CHECK TABLE FOR UPGRADE' for all tables in the database in order to check if the tables are compatible with the current version of MySQL. Any tables that are found incompatible are then upgraded using 'REPAIR TABLE'. The problem was that some engines (e.g. InnoDB) do not support 'REPAIR TABLE'. This caused any such tables to be left incompatible. As a result such tables were not properly fixed by the mysql_upgrade tool. This patch fixes the problem by first changing 'CHECK TABLE FOR UPGRADE' to return a different error message if the engine does not support REPAIR. Instead of "Table upgrade required. Please do "REPAIR TABLE ..." it will report "Table rebuild required. Please do "ALTER TABLE ... FORCE ..." Second, the patch changes mysqlcheck to do 'ALTER TABLE ... FORCE' instead of 'REPAIR TABLE' in these cases. This patch also fixes 'ALTER TABLE ... FORCE' to actually rebuild the table. This change should be reflected in the documentation. Before this patch, 'ALTER TABLE ... FORCE' was unused (See Bug#11746162) Test case added to mysqlcheck.test client/mysqlcheck.c: Changed mysqlcheck to do 'ALTER TABLE ... FORCE' if 'CHECK TABLE FOR UPGRADE' reports ER_TABLE_NEEDS_REBUILD and not ER_TABLE_NEEDS_UPGRADE. mysql-test/r/mysqlcheck.result: Added regression test. mysql-test/std_data/bug47205.frm: InnoDB 5.0 FRM which contains a varchar primary key using utf8_general_ci. This is an incompatible FRM for 5.5. mysql-test/t/mysqlcheck.test: Added regression test. sql/handler.h: Added new HA_CAN_REPAIR flag. sql/share/errmsg-utf8.txt: Added new error message ER_TABLE_NEEDS_REBUILD sql/sql_admin.cc: Changed 'CHECK TABLE FOR UPDATE' to give ER_TABLE_NEEDS_REBUILD instead of ER_TABLE_NEEDS_UPGRADE if the engine does not support REPAIR (as indicated by the new HA_CAN_REPAIR flag). sql/sql_lex.h: Remove unused ALTER_FORCE flag. sql/sql_yacc.yy: Make sure ALTER TABLE ... FORCE recreates the table by setting the ALTER_RECREATE flag as the ALTER_FORCE flag was unused. storage/archive/ha_archive.h: Added new HA_CAN_REPAIR flag to Archive storage/csv/ha_tina.h: Added new HA_CAN_REPAIR flag to CSV storage/federated/ha_federated.h: Added new HA_CAN_REPAIR flag to Federated storage/myisam/ha_myisam.cc: Added new HA_CAN_REPAIR flag to MyISAM
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc10
-rw-r--r--sql/handler.h11
-rw-r--r--sql/share/errmsg-utf8.txt5
-rw-r--r--sql/sql_admin.cc8
-rw-r--r--sql/sql_lex.h27
-rw-r--r--sql/sql_yacc.yy2
6 files changed, 42 insertions, 21 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 9ca1f3a20f8..fefc0553c88 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -3214,9 +3214,13 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
mark_trx_read_write();
- if ((result= repair(thd, check_opt)))
- return result;
- return update_frm_version(table);
+ result= repair(thd, check_opt);
+ DBUG_ASSERT(result == HA_ADMIN_NOT_IMPLEMENTED ||
+ ha_table_flags() & HA_CAN_REPAIR);
+
+ if (result == HA_ADMIN_OK)
+ result= update_frm_version(table);
+ return result;
}
diff --git a/sql/handler.h b/sql/handler.h
index 3cd4acee80d..ca72640f887 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -153,6 +153,12 @@
ordered.
*/
#define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36)
+/*
+ Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
+ incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
+ will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
+*/
+#define HA_CAN_REPAIR (LL(1) << 37)
/*
Set of all binlog flags. Currently only contain the capabilities
@@ -2010,7 +2016,10 @@ private:
upon the table.
*/
virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
- { return HA_ADMIN_NOT_IMPLEMENTED; }
+ {
+ DBUG_ASSERT(!(ha_table_flags() & HA_CAN_REPAIR));
+ return HA_ADMIN_NOT_IMPLEMENTED;
+ }
virtual void start_bulk_insert(ha_rows rows) {}
virtual int end_bulk_insert() { return 0; }
virtual int index_read(uchar * buf, const uchar * key, uint key_len,
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 998e88704d8..0d315fe1441 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6397,3 +6397,8 @@ ER_STMT_CACHE_FULL
ER_MULTI_UPDATE_KEY_CONFLICT
eng "Primary key/partition key update is not allowed since the table is updated both as '%-.192s' and '%-.192s'."
+
+# When translating this error message make sure to include "ALTER TABLE" in the
+# message as mysqlcheck parses the error message looking for ALTER TABLE.
+ER_TABLE_NEEDS_REBUILD
+ eng "Table rebuild required. Please do \"ALTER TABLE `%-.32s` FORCE\" or dump/reload to fix it!"
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index eb6853751ee..dea8d38938c 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -771,8 +771,12 @@ send_result_message:
size_t length;
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
- length=my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
- table->table_name);
+ if (table->table->file->ha_table_flags() & HA_CAN_REPAIR)
+ length= my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
+ table->table_name);
+ else
+ length= my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_REBUILD),
+ table->table_name);
protocol->store(buf, length, system_charset_info);
fatal_error=1;
break;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a9abe174d6e..e6b5f23f17e 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -944,20 +944,19 @@ inline bool st_select_lex_unit::is_union ()
#define ALTER_CHANGE_COLUMN_DEFAULT (1L << 8)
#define ALTER_KEYS_ONOFF (1L << 9)
#define ALTER_CONVERT (1L << 10)
-#define ALTER_FORCE (1L << 11)
-#define ALTER_RECREATE (1L << 12)
-#define ALTER_ADD_PARTITION (1L << 13)
-#define ALTER_DROP_PARTITION (1L << 14)
-#define ALTER_COALESCE_PARTITION (1L << 15)
-#define ALTER_REORGANIZE_PARTITION (1L << 16)
-#define ALTER_PARTITION (1L << 17)
-#define ALTER_ADMIN_PARTITION (1L << 18)
-#define ALTER_TABLE_REORG (1L << 19)
-#define ALTER_REBUILD_PARTITION (1L << 20)
-#define ALTER_ALL_PARTITION (1L << 21)
-#define ALTER_REMOVE_PARTITIONING (1L << 22)
-#define ALTER_FOREIGN_KEY (1L << 23)
-#define ALTER_TRUNCATE_PARTITION (1L << 24)
+#define ALTER_RECREATE (1L << 11)
+#define ALTER_ADD_PARTITION (1L << 12)
+#define ALTER_DROP_PARTITION (1L << 13)
+#define ALTER_COALESCE_PARTITION (1L << 14)
+#define ALTER_REORGANIZE_PARTITION (1L << 15)
+#define ALTER_PARTITION (1L << 16)
+#define ALTER_ADMIN_PARTITION (1L << 17)
+#define ALTER_TABLE_REORG (1L << 18)
+#define ALTER_REBUILD_PARTITION (1L << 19)
+#define ALTER_ALL_PARTITION (1L << 20)
+#define ALTER_REMOVE_PARTITIONING (1L << 21)
+#define ALTER_FOREIGN_KEY (1L << 22)
+#define ALTER_TRUNCATE_PARTITION (1L << 23)
enum enum_alter_table_change_level
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 02e0d347ef7..13a1b8029f2 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6747,7 +6747,7 @@ alter_list_item:
}
| FORCE_SYM
{
- Lex->alter_info.flags|= ALTER_FORCE;
+ Lex->alter_info.flags|= ALTER_RECREATE;
}
| alter_order_clause
{