diff options
-rw-r--r-- | mysql-test/r/archive.result | 12 | ||||
-rw-r--r-- | mysql-test/std_data/archive_5_0.ARM | bin | 0 -> 19 bytes | |||
-rw-r--r-- | mysql-test/std_data/archive_5_0.ARZ | bin | 0 -> 138 bytes | |||
-rw-r--r-- | mysql-test/std_data/archive_5_0.frm | bin | 0 -> 8578 bytes | |||
-rw-r--r-- | mysql-test/std_data/long_table_name.MYD (renamed from mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD) | bin | 56 -> 56 bytes | |||
-rw-r--r-- | mysql-test/std_data/long_table_name.MYI (renamed from mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI) | bin | 6144 -> 6144 bytes | |||
-rw-r--r-- | mysql-test/std_data/long_table_name.frm (renamed from mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm) | bin | 8650 -> 8650 bytes | |||
-rw-r--r-- | mysql-test/t/archive.test | 13 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 | ||||
-rw-r--r-- | sql/table.cc | 3 | ||||
-rw-r--r-- | storage/archive/azio.c | 11 | ||||
-rw-r--r-- | storage/archive/ha_archive.cc | 42 | ||||
-rw-r--r-- | storage/archive/ha_archive.h | 3 |
13 files changed, 72 insertions, 15 deletions
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index f90bcb521e1..5a731e6476c 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12725,8 +12725,7 @@ INSERT INTO t1 (col1, col2) VALUES (1, "value"); ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! REPAIR TABLE t1; Table Op Msg_type Msg_text -test.t1 repair Error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! -test.t1 repair error Corrupt +test.t1 repair status OK DROP TABLE t1; # # BUG#48757 - missing .ARZ file causes server crash @@ -12756,3 +12755,12 @@ a 1 2 DROP TABLE t1; +select * from t1; +ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! +repair table t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +select sum(length(a)),sum(b) from t1; +sum(length(a)) sum(b) +8670 187 +drop table t1; diff --git a/mysql-test/std_data/archive_5_0.ARM b/mysql-test/std_data/archive_5_0.ARM Binary files differnew file mode 100644 index 00000000000..8f1111437d8 --- /dev/null +++ b/mysql-test/std_data/archive_5_0.ARM diff --git a/mysql-test/std_data/archive_5_0.ARZ b/mysql-test/std_data/archive_5_0.ARZ Binary files differnew file mode 100644 index 00000000000..d24e76884cc --- /dev/null +++ b/mysql-test/std_data/archive_5_0.ARZ diff --git a/mysql-test/std_data/archive_5_0.frm b/mysql-test/std_data/archive_5_0.frm Binary files differnew file mode 100644 index 00000000000..827213d329d --- /dev/null +++ b/mysql-test/std_data/archive_5_0.frm diff --git a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD b/mysql-test/std_data/long_table_name.MYD Binary files differindex 2ff33451b5f..2ff33451b5f 100644 --- a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYD +++ b/mysql-test/std_data/long_table_name.MYD diff --git a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI b/mysql-test/std_data/long_table_name.MYI Binary files differindex cffa158beae..cffa158beae 100644 --- a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.MYI +++ b/mysql-test/std_data/long_table_name.MYI diff --git a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm b/mysql-test/std_data/long_table_name.frm Binary files differindex 6a812a8b137..6a812a8b137 100644 --- a/mysql-test/std_data/ltoriaeinnovacionendesarrolloempres?9120761097220077376?cio_com.frm +++ b/mysql-test/std_data/long_table_name.frm diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 6704257f9af..7478c7dcdce 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1680,3 +1680,16 @@ SELECT * FROM t1; REPAIR TABLE t1 EXTENDED; SELECT * FROM t1; DROP TABLE t1; + +# +# Bug #47012 archive tables are not upgradeable, and server crashes on +# any access +# +copy_file std_data/archive_5_0.frm $MYSQLD_DATADIR/test/t1.frm; +copy_file std_data/archive_5_0.ARZ $MYSQLD_DATADIR/test/t1.ARZ; +copy_file std_data/archive_5_0.ARM $MYSQLD_DATADIR/test/t1.ARM; +--error ER_TABLE_NEEDS_UPGRADE +select * from t1; +repair table t1; +select sum(length(a)),sum(b) from t1; +drop table t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a0621dbbdcf..96be7c4437c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4804,7 +4804,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (check_old_types == HA_ADMIN_NEEDS_ALTER || check_for_upgrade == HA_ADMIN_NEEDS_ALTER) { + /* We use extra_open_options to be able to open crashed tables */ + thd->open_options|= extra_open_options; result_code= admin_recreate_table(thd, table); + thd->open_options= ~extra_open_options; goto send_result; } if (check_old_types || check_for_upgrade) diff --git a/sql/table.cc b/sql/table.cc index a7ed2dd40ff..a3c6f07cddf 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -866,7 +866,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, /* Read extra data segment */ uchar *buff, *next_chunk, *buff_end; DBUG_PRINT("info", ("extra segment size is %u bytes", n_length)); - if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME)))) + if (!(next_chunk= buff= (uchar*) my_malloc(n_length+1, MYF(MY_WME)))) goto err; if (my_pread(file, buff, n_length, record_offset + share->reclength, MYF(MY_NABP))) @@ -945,6 +945,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, { /* purecov: begin inspected */ error= 8; + name.str[name.length]= 0; my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str); my_free(buff, MYF(0)); goto err; diff --git a/storage/archive/azio.c b/storage/archive/azio.c index a24350dd454..fc54d98ab15 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -150,6 +150,17 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) } else { + /* Reset values in case of old version of archive file */ + s->rows= 0; + s->forced_flushes= 0; + s->shortest_row= 0; + s->longest_row= 0; + s->auto_increment= 0; + s->check_point= 0; + s->comment_start_pos= 0; + s->comment_length= 0; + s->frm_start_pos= 0; + s->frm_length= 0; check_header(s); /* skip the .az header */ } diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 988337ec50e..d0cb34455b9 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -293,7 +293,7 @@ int ha_archive::read_data_header(azio_stream *file_to_read) DBUG_PRINT("ha_archive", ("Version %u", data_buffer[1])); if ((data_buffer[0] != (uchar)ARCHIVE_CHECK_HEADER) && - (data_buffer[1] != (uchar)ARCHIVE_VERSION)) + (data_buffer[1] == 1 || data_buffer[1] == 2)) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); DBUG_RETURN(0); @@ -360,9 +360,19 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc) my_free(share, MYF(0)); DBUG_RETURN(NULL); } - stats.auto_increment_value= archive_tmp.auto_increment + 1; - share->rows_recorded= (ha_rows)archive_tmp.rows; - share->crashed= archive_tmp.dirty; + share->version= archive_tmp.version; + if (archive_tmp.version == ARCHIVE_VERSION) + { + stats.auto_increment_value= archive_tmp.auto_increment + 1; + share->rows_recorded= (ha_rows)archive_tmp.rows; + share->crashed= archive_tmp.dirty; + } + else + { + /* Used by repair */ + share->rows_recorded= ~(ha_rows) 0; + stats.auto_increment_value= 0; + } /* If archive version is less than 3, It should be upgraded before use. @@ -512,10 +522,19 @@ int ha_archive::open(const char *name, int mode, uint open_options) case 0: break; case HA_ERR_CRASHED_ON_USAGE: + DBUG_PRINT("ha_archive", ("archive table was crashed")); if (open_options & HA_OPEN_FOR_REPAIR) + { + rc= 0; break; + } /* fall through */ case HA_ERR_TABLE_NEEDS_UPGRADE: + if (open_options & HA_OPEN_FOR_REPAIR) + { + rc= 0; + break; + } free_share(); /* fall through */ default: @@ -535,13 +554,6 @@ int ha_archive::open(const char *name, int mode, uint open_options) thr_lock_data_init(&share->lock, &lock, NULL); - DBUG_PRINT("ha_archive", ("archive table was crashed %s", - rc == HA_ERR_CRASHED_ON_USAGE ? "yes" : "no")); - if (rc == HA_ERR_CRASHED_ON_USAGE && open_options & HA_OPEN_FOR_REPAIR) - { - DBUG_RETURN(0); - } - DBUG_RETURN(rc); } @@ -1267,6 +1279,14 @@ int ha_archive::rnd_pos(uchar * buf, uchar *pos) DBUG_RETURN(get_row(&archive, buf)); } +int ha_archive::check_for_upgrade(HA_CHECK_OPT *check_opt) +{ + if (share->version < ARCHIVE_VERSION) + return HA_ADMIN_NEEDS_ALTER; + return 0; +} + + /* This method repairs the meta file. It does this by walking the datafile and rewriting the meta file. If EXTENDED repair is requested, we attempt to diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index ab630ed22fd..653a13b242d 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -35,7 +35,7 @@ typedef struct st_archive_record_buffer { typedef struct st_archive_share { char *table_name; char data_file_name[FN_REFLEN]; - uint table_name_length,use_count; + uint table_name_length,use_count, version; pthread_mutex_t mutex; THR_LOCK lock; azio_stream archive_write; /* Archive file we are working with */ @@ -133,6 +133,7 @@ public: int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); int optimize(THD* thd, HA_CHECK_OPT* check_opt); int repair(THD* thd, HA_CHECK_OPT* check_opt); + int check_for_upgrade(HA_CHECK_OPT *check_opt); void start_bulk_insert(ha_rows rows); int end_bulk_insert(); enum row_type get_row_type() const |