#At file:///export/home/x/mysql-5.5-bug11755431/ based on revid:tor.didriksen@stripped
3357 Jon Olav Hauglid 2011-02-28
Bug #11755431 (former 47205)
MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR ENGINES NOT
SUPPORTING NATIVE REPAIR
This is a draft patch.
Executing 'mysqlcheck --check --auto-repair ...' will first issue
'CHECK TABLE FOR UPDATE' 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) does not support 'REPAIR TABLE'.
This caused any such tables to be left incompatible. This could in turn cause
problems for mysql_upgrade.
This patch fixes the problem by first changing 'CHECK TABLE FOR UPDATE' 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.
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_SUPPORTS_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_SUPPORTS_REPAIR flag).
@ storage/archive/ha_archive.h
Added new HA_SUPPORTS_REPAIR flag to Archive
@ storage/csv/ha_tina.h
Added new HA_SUPPORTS_REPAIR flag to CSV
@ storage/federated/ha_federated.h
Added new HA_SUPPORTS_REPAIR flag to Federated
@ storage/myisam/ha_myisam.cc
Added new HA_SUPPORTS_REPAIR flag to MyISAM
added:
mysql-test/std_data/bug47205.frm
modified:
client/mysqlcheck.c
mysql-test/r/mysqlcheck.result
mysql-test/t/mysqlcheck.test
sql/handler.h
sql/share/errmsg-utf8.txt
sql/sql_admin.cc
storage/archive/ha_archive.h
storage/csv/ha_tina.h
storage/federated/ha_federated.h
storage/myisam/ha_myisam.cc
=== modified file 'client/mysqlcheck.c'
--- a/client/mysqlcheck.c 2011-01-16 03:59:05 +0000
+++ b/client/mysqlcheck.c 2011-02-28 16:31:23 +0000
@@ -42,13 +42,13 @@ static char *opt_password = 0, *current_
*default_charset= 0, *current_host= 0;
static char *opt_plugin_dir= 0, *opt_default_auth= 0;
static int first_error = 0;
-DYNAMIC_ARRAY tables4repair;
+DYNAMIC_ARRAY tables4repair, tables4rebuild;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
-enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
+enum operations { DO_CHECK=1, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE, DO_REBUILD };
static struct my_option my_long_options[] =
{
@@ -626,6 +626,25 @@ static int fix_database_storage_name(con
return rc;
}
+static int rebuild_table(const char *full_name)
+{
+ char qbuf[100 + NAME_LEN*4];
+ int rc= 0;
+ const char *name= strchr(full_name, '.');
+ if (name == NULL)
+ return 1;
+ sprintf(qbuf, "ALTER TABLE `%s` FORCE", name + 1);
+ if (mysql_query(sock, qbuf))
+ {
+ fprintf(stderr, "Failed to %s\n", qbuf);
+ fprintf(stderr, "Error: %s\n", mysql_error(sock));
+ rc= 1;
+ }
+ if (verbose)
+ printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
+ return rc;
+}
+
static int process_one_db(char *database)
{
if (what_to_do == DO_UPGRADE)
@@ -695,6 +714,8 @@ static int handle_request_for_tables(cha
if (opt_extended) end = strmov(end, " EXTENDED");
if (opt_frm) end = strmov(end, " USE_FRM");
break;
+ case DO_REBUILD:
+ return rebuild_table(tables);
case DO_ANALYZE:
op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
break;
@@ -739,7 +760,7 @@ static void print_result()
MYSQL_ROW row;
char prev[NAME_LEN*2+2];
uint i;
- my_bool found_error=0;
+ my_bool found_error=0, table_rebuild=0;
res = mysql_use_result(sock);
@@ -758,8 +779,14 @@ static void print_result()
*/
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
strcmp(row[3],"OK"))
- insert_dynamic(&tables4repair, (uchar*) prev);
+ {
+ if (table_rebuild)
+ insert_dynamic(&tables4rebuild, (uchar*) prev);
+ else
+ insert_dynamic(&tables4repair, (uchar*) prev);
+ }
found_error=0;
+ table_rebuild=0;
if (opt_silent)
continue;
}
@@ -770,6 +797,8 @@ static void print_result()
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
if (strcmp(row[2],"note"))
found_error=1;
+ if (opt_auto_repair && strncmp(row[3], "Table rebuild", 13) == 0)
+ table_rebuild=1;
}
else
printf("%-9s: %s", row[2], row[3]);
@@ -778,7 +807,12 @@ static void print_result()
}
/* add the last table to be repaired to the list */
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
- insert_dynamic(&tables4repair, (uchar*) prev);
+ {
+ if (table_rebuild)
+ insert_dynamic(&tables4rebuild, (uchar*) prev);
+ else
+ insert_dynamic(&tables4repair, (uchar*) prev);
+ }
mysql_free_result(res);
}
@@ -876,7 +910,8 @@ int main(int argc, char **argv)
}
if (opt_auto_repair &&
- my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
+ (my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64) ||
+ my_init_dynamic_array(&tables4rebuild, sizeof(char)*(NAME_LEN*2+2),16,64)))
{
first_error = 1;
goto end;
@@ -894,7 +929,7 @@ int main(int argc, char **argv)
{
uint i;
- if (!opt_silent && tables4repair.elements)
+ if (!opt_silent && (tables4repair.elements || tables4rebuild.elements))
puts("\nRepairing tables");
what_to_do = DO_REPAIR;
for (i = 0; i < tables4repair.elements ; i++)
@@ -902,11 +937,20 @@ int main(int argc, char **argv)
char *name= (char*) dynamic_array_ptr(&tables4repair, i);
handle_request_for_tables(name, fixed_name_length(name));
}
+ what_to_do = DO_REBUILD;
+ for (i = 0; i < tables4rebuild.elements ; i++)
+ {
+ char *name= (char*) dynamic_array_ptr(&tables4rebuild, i);
+ handle_request_for_tables(name, fixed_name_length(name));
+ }
}
end:
dbDisconnect(current_host);
if (opt_auto_repair)
+ {
delete_dynamic(&tables4repair);
+ delete_dynamic(&tables4rebuild);
+ }
my_free(opt_password);
#ifdef HAVE_SMEM
my_free(shared_memory_base_name);
=== modified file 'mysql-test/r/mysqlcheck.result'
--- a/mysql-test/r/mysqlcheck.result 2010-12-17 11:11:34 +0000
+++ b/mysql-test/r/mysqlcheck.result 2011-02-28 16:31:23 +0000
@@ -260,3 +260,41 @@ End of 5.1 tests
#
# Bug #35269: mysqlcheck behaves different depending on order of parameters
#
+#
+# Bug#11755431 47205: MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR
+# ENGINES NOT SUPPORTING NATIVE
+#
+DROP TABLE IF EXISTS bug47205;
+#
+# Test 1: InnoDB - REPAIR not supported
+CREATE TABLE bug47205(a VARCHAR(20) PRIMARY KEY)
+DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci engine=innodb;
+# Should indicate that ALTER TABLE .. FORCE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.bug47205 check error Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
+test.bug47205
+error : Table rebuild required. Please do "ALTER TABLE `bug47205` FORCE" or dump/reload to fix it!
+
+Repairing tables
+# Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.bug47205 check status OK
+DROP TABLE bug47205;
+#
+# Test 2: MyISAM - REPAIR supported
+# Should indicate that REPAIR TABLE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.bug47205 check error Table upgrade required. Please do "REPAIR TABLE `bug47205`" or dump/reload to fix it!
+test.bug47205
+error : Table upgrade required. Please do "REPAIR TABLE `bug47205`" or dump/reload to fix it!
+
+Repairing tables
+test.bug47205 OK
+# Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.bug47205 check status OK
+DROP TABLE bug47205;
=== added file 'mysql-test/std_data/bug47205.frm'
Binary files a/mysql-test/std_data/bug47205.frm 1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/bug47205.frm 2011-02-28 16:31:23 +0000 differ
=== modified file 'mysql-test/t/mysqlcheck.test'
--- a/mysql-test/t/mysqlcheck.test 2010-10-08 07:09:47 +0000
+++ b/mysql-test/t/mysqlcheck.test 2011-02-28 16:31:23 +0000
@@ -229,3 +229,49 @@ drop table `t1-1`;
--error 1
--exec $MYSQL_CHECK -aoc test "#mysql50#t1-1"
+
+--echo #
+--echo # Bug#11755431 47205: MAP 'REPAIR TABLE' TO RECREATE +ANALYZE FOR
+--echo # ENGINES NOT SUPPORTING NATIVE
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS bug47205;
+--enable_warnings
+
+--echo #
+--echo # Test 1: InnoDB - REPAIR not supported
+
+CREATE TABLE bug47205(a VARCHAR(20) PRIMARY KEY)
+ DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci engine=innodb;
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--remove_file $MYSQLD_DATADIR/test/bug47205.frm
+--copy_file std_data/bug47205.frm $MYSQLD_DATADIR/test/bug47205.frm
+
+--echo # Should indicate that ALTER TABLE .. FORCE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+
+--exec $MYSQL_CHECK --check --auto-repair test
+
+--echo # Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+
+DROP TABLE bug47205;
+
+--echo #
+--echo # Test 2: MyISAM - REPAIR supported
+
+--copy_file std_data/bug36055.frm $MYSQLD_DATADIR/test/bug47205.frm
+--copy_file std_data/bug36055.MYD $MYSQLD_DATADIR/test/bug47205.MYD
+--copy_file std_data/bug36055.MYI $MYSQLD_DATADIR/test/bug47205.MYI
+
+--echo # Should indicate that REPAIR TABLE is needed
+CHECK TABLE bug47205 FOR UPGRADE;
+
+--exec $MYSQL_CHECK --check --auto-repair test
+
+--echo # Table should now be ok
+CHECK TABLE bug47205 FOR UPGRADE;
+
+DROP TABLE bug47205;
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2011-01-26 13:23:29 +0000
+++ b/sql/handler.h 2011-02-28 16:31:23 +0000
@@ -153,6 +153,7 @@
ordered.
*/
#define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36)
+#define HA_SUPPORTS_REPAIR (LL(1) << 37)
/*
Set of all binlog flags. Currently only contain the capabilities
@@ -2010,7 +2011,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_SUPPORTS_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,
=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt 2011-02-21 15:49:03 +0000
+++ b/sql/share/errmsg-utf8.txt 2011-02-28 16:31:23 +0000
@@ -6397,3 +6397,6 @@ 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'."
+
+ER_TABLE_NEEDS_REBUILD
+ eng "Table rebuild required. Please do \"ALTER TABLE `%-.32s` FORCE\" or dump/reload to fix it!"
=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc 2011-01-10 13:12:23 +0000
+++ b/sql/sql_admin.cc 2011-02-28 16:31:23 +0000
@@ -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_SUPPORTS_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;
=== modified file 'storage/archive/ha_archive.h'
--- a/storage/archive/ha_archive.h 2010-10-06 14:34:28 +0000
+++ b/storage/archive/ha_archive.h 2011-02-28 16:31:23 +0000
@@ -90,7 +90,7 @@ public:
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_BIT_FIELD |
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
HA_STATS_RECORDS_IS_EXACT |
- HA_HAS_RECORDS |
+ HA_HAS_RECORDS | HA_SUPPORTS_REPAIR |
HA_FILE_BASED | HA_CAN_INSERT_DELAYED | HA_CAN_GEOMETRY);
}
ulong index_flags(uint idx, uint part, bool all_parts) const
=== modified file 'storage/csv/ha_tina.h'
--- a/storage/csv/ha_tina.h 2010-07-08 21:20:08 +0000
+++ b/storage/csv/ha_tina.h 2011-02-28 16:31:23 +0000
@@ -106,7 +106,8 @@ public:
ulonglong table_flags() const
{
return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT |
- HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE);
+ HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
+ HA_SUPPORTS_REPAIR);
}
ulong index_flags(uint idx, uint part, bool all_parts) const
{
=== modified file 'storage/federated/ha_federated.h'
--- a/storage/federated/ha_federated.h 2010-10-06 14:34:28 +0000
+++ b/storage/federated/ha_federated.h 2011-02-28 16:31:23 +0000
@@ -149,7 +149,8 @@ public:
HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE |
HA_NO_TRANSACTIONS /* until fixed by WL#2952 */ |
- HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY);
+ HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY |
+ HA_SUPPORTS_REPAIR);
}
/*
This is a bitmap of flags that says how the storage engine
=== modified file 'storage/myisam/ha_myisam.cc'
--- a/storage/myisam/ha_myisam.cc 2011-01-11 09:07:37 +0000
+++ b/storage/myisam/ha_myisam.cc 2011-02-28 16:31:23 +0000
@@ -639,7 +639,7 @@ ha_myisam::ha_myisam(handlerton *hton, T
HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
- HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT),
+ HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT | HA_SUPPORTS_REPAIR),
can_enable_indexes(1)
{}
Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20110228163123-oh6y1jbe52aoocrc.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5 branch (jon.hauglid:3357) Bug#11755431 | Jon Olav Hauglid | 28 Feb |