From d1a80e6ad7ce5909301c4fa1549bcedefc4f89cd Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 7 Sep 2011 21:42:14 -0700 Subject: [PATCH 01/10] Fix Bug #12885783 - BLOCK LOADING TABLE WITH LARGE COLLATION NUMBER FROM 5.6 SERVER rb://747 approved by Marko --- storage/innobase/dict/dict0load.c | 40 ++++++++++++++++++++-- storage/innobase/handler/ha_innodb.cc | 11 +++--- storage/innobase/include/data0type.h | 9 +++++ storage/innobase/include/data0type.ic | 6 ++-- storage/innodb_plugin/ChangeLog | 7 ++++ storage/innodb_plugin/dict/dict0load.c | 40 ++++++++++++++++++++-- storage/innodb_plugin/handler/ha_innodb.cc | 7 ++-- storage/innodb_plugin/include/data0type.h | 9 +++++ storage/innodb_plugin/include/data0type.ic | 2 +- 9 files changed, 114 insertions(+), 17 deletions(-) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index 7e820cfb08d..4b5087e6e22 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -25,6 +25,7 @@ Created 4/24/1996 Heikki Tuuri #include "rem0cmp.h" #include "srv0start.h" #include "srv0srv.h" +#include "db0err.h" /******************************************************************** Returns TRUE if index's i'th column's name is 'name' .*/ @@ -329,7 +330,7 @@ loop: /************************************************************************ Loads definitions for table columns. */ static -void +ulint dict_load_columns( /*==============*/ dict_table_t* table, /* in: table */ @@ -350,6 +351,7 @@ dict_load_columns( ulint col_len; ulint i; mtr_t mtr; + ulint err = DB_SUCCESS; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -397,6 +399,30 @@ dict_load_columns( field = rec_get_nth_field_old(rec, 6, &len); prtype = mach_read_from_4(field); + /* We can rely on dtype_get_charset_coll() to check + charset collation number exceed limit, since it comes + with a smaller mask. We have to do the check explicitly + here */ + if (((prtype >> 16) & LARGE_CHAR_COLL_PRTYPE_MASK) + > MAX_CHAR_COLL_NUM) { + fprintf(stderr, "InnoDB: Error: load column" + " '%s' for table '%s' failed.\n" + "InnoDB: column '%s' has a charset" + " collation number of %lu, exceeds" + " maximum value %lu supported\n", + name, name, table->name, + (ulong) ((prtype >> 16) + & LARGE_CHAR_COLL_PRTYPE_MASK), + (ulong) MAX_CHAR_COLL_NUM); + err = DB_CORRUPTION; + + /* If the force recovery flag is not set, it will + stop loading and exit */ + if (!srv_force_recovery) { + goto func_exit; + } + } + if (dtype_get_charset_coll(prtype) == 0 && dtype_is_string_type(mtype)) { /* The table was created with < 4.1.2. */ @@ -428,8 +454,11 @@ dict_load_columns( btr_pcur_move_to_next_user_rec(&pcur, &mtr); } +func_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); + + return(err); } /************************************************************************ @@ -899,7 +928,12 @@ err_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); - dict_load_columns(table, heap); + err = dict_load_columns(table, heap); + + if (err != DB_SUCCESS && !srv_force_recovery) { + table = NULL; + goto func_exit; + } dict_table_add_to_cache(table, heap); @@ -961,6 +995,8 @@ err_exit: mutex_exit(&dict_foreign_err_mutex); } #endif /* 0 */ + +func_exit: mem_heap_free(heap); return(table); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index dfe13ccbbfe..64f6b5da414 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5336,13 +5336,14 @@ create_table_def( charset_no = (ulint)field->charset()->number; - ut_a(charset_no < 256); /* in data0type.h we assume - that the number fits in one - byte */ + /* in data0type.h we assume + that the number fits in one byte */ + ut_a(charset_no <= MAX_CHAR_COLL_NUM); } - ut_a(field->type() < 256); /* we assume in dtype_form_prtype() - that this fits in one byte */ + /* we assume in dtype_form_prtype() that this fits in + one byte */ + ut_a(field->type() <= MAX_CHAR_COLL_NUM); col_len = field->pack_length(); /* The MySQL pack length contains 1 or 2 bytes length field diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h index e5e9c5076be..5b1628bb56c 100644 --- a/storage/innobase/include/data0type.h +++ b/storage/innobase/include/data0type.h @@ -149,6 +149,15 @@ SQL null*/ store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 +/* We support 8 bits (up to 255) collation number until 5.6.3, in which +the collation number is extended to 32767 */ +#define MAX_CHAR_COLL_NUM 255 + +/* Mask to get the large charset-collation number in PRTYPE +This is used to mainly block loading tables with large charset-collation +value with database from 5.6 */ +#define LARGE_CHAR_COLL_PRTYPE_MASK 0xFFFFUL + /************************************************************************* Gets the MySQL type code from a dtype. */ UNIV_INLINE diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic index ad0f95755d2..9135f2afa61 100644 --- a/storage/innobase/include/data0type.ic +++ b/storage/innobase/include/data0type.ic @@ -272,7 +272,7 @@ dtype_new_store_for_order_and_null_size( mach_write_to_2(buf + 2, len & 0xFFFFUL); - ut_ad(dtype_get_charset_coll(type->prtype) < 256); + ut_ad(dtype_get_charset_coll(type->prtype) <= MAX_CHAR_COLL_NUM); mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype)); if (type->prtype & DATA_NOT_NULL) { @@ -339,12 +339,10 @@ dtype_new_read_for_order_and_null_size( type->len = mach_read_from_2(buf + 2); - mach_read_from_2(buf + 4); - charset_coll = mach_read_from_2(buf + 4) & 0x7fff; if (dtype_is_string_type(type->mtype)) { - ut_a(charset_coll < 256); + ut_a(charset_coll <= MAX_CHAR_COLL_NUM); if (charset_coll == 0) { /* This insert buffer record was inserted with MySQL diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index a29aaf2077e..2e66a987745 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,10 @@ +2011-09-08 The InnoDB Team + + * dict/dict0load.c, handler/ha_innodb.cc, include/data0type.h + include/data0type.ic: + Fix Bug##12885783 - BLOCK LOADING TABLE WITH LARGE COLLATION + NUMBER FROM 5.6 SERVER + 2011-09-06 The InnoDB Team * buf/buf0buddy.c: diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index 7a0b6edcb08..1bbced84091 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -40,6 +40,7 @@ Created 4/24/1996 Heikki Tuuri #include "rem0cmp.h" #include "srv0start.h" #include "srv0srv.h" +#include "db0err.h" /****************************************************************//** Compare the name of an index column. @@ -449,7 +450,7 @@ loop: /********************************************************************//** Loads definitions for table columns. */ static -void +enum db_err dict_load_columns( /*==============*/ dict_table_t* table, /*!< in: table */ @@ -470,6 +471,7 @@ dict_load_columns( ulint col_len; ulint i; mtr_t mtr; + enum db_err err = DB_SUCCESS; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -517,6 +519,30 @@ dict_load_columns( field = rec_get_nth_field_old(rec, 6, &len); prtype = mach_read_from_4(field); + /* We can rely on dtype_get_charset_coll() to check + charset collation number exceed limit, since it comes + with a smaller mask. We have to do the check explicitly + here */ + if (((prtype >> 16) & LARGE_CHAR_COLL_PRTYPE_MASK) + > MAX_CHAR_COLL_NUM) { + fprintf(stderr, "InnoDB: Error: load column" + " '%s' for table '%s' failed.\n" + "InnoDB: column '%s' has a charset" + " collation number of %lu, exceeds" + " maximum value %lu supported\n", + name, name, table->name, + (ulong) ((prtype >> 16) + & LARGE_CHAR_COLL_PRTYPE_MASK), + (ulong) MAX_CHAR_COLL_NUM); + err = DB_CORRUPTION; + + /* If the force recovery flag is not set, it will + stop loading and exit */ + if (!srv_force_recovery) { + goto func_exit; + } + } + if (dtype_get_charset_coll(prtype) == 0 && dtype_is_string_type(mtype)) { /* The table was created with < 4.1.2. */ @@ -548,8 +574,11 @@ dict_load_columns( btr_pcur_move_to_next_user_rec(&pcur, &mtr); } +func_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); + + return(err); } /********************************************************************//** @@ -1044,7 +1073,12 @@ err_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); - dict_load_columns(table, heap); + err = dict_load_columns(table, heap); + + if (err != DB_SUCCESS && !srv_force_recovery) { + table = NULL; + goto func_exit; + } dict_table_add_to_cache(table, heap); @@ -1106,6 +1140,8 @@ err_exit: mutex_exit(&dict_foreign_err_mutex); } #endif /* 0 */ + +func_exit: mem_heap_free(heap); return(table); diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 609299efce5..e7c5cbdedae 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6086,7 +6086,7 @@ create_table_def( charset_no = (ulint)field->charset()->number; - if (UNIV_UNLIKELY(charset_no >= 256)) { + if (UNIV_UNLIKELY(charset_no > MAX_CHAR_COLL_NUM)) { /* in data0type.h we assume that the number fits in one byte in prtype */ push_warning_printf( @@ -6101,8 +6101,9 @@ create_table_def( } } - ut_a(field->type() < 256); /* we assume in dtype_form_prtype() - that this fits in one byte */ + /* we assume in dtype_form_prtype() that this fits in + one byte */ + ut_a(field->type() <= MAX_CHAR_COLL_NUM); col_len = field->pack_length(); /* The MySQL pack length contains 1 or 2 bytes length field diff --git a/storage/innodb_plugin/include/data0type.h b/storage/innodb_plugin/include/data0type.h index a73bed3a9f5..87699e8ab5d 100644 --- a/storage/innodb_plugin/include/data0type.h +++ b/storage/innodb_plugin/include/data0type.h @@ -168,6 +168,15 @@ SQL null*/ store the charset-collation number; one byte is left unused, though */ #define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6 +/* We support 8 bits (up to 255) collation number until 5.6.3, in which +the collation number is extended to 32767 */ +#define MAX_CHAR_COLL_NUM 255 + +/* Mask to get the large charset-collation number in PRTYPE +This is used to mainly block loading tables with large charset-collation +value with database from 5.6 */ +#define LARGE_CHAR_COLL_PRTYPE_MASK 0xFFFFUL + #ifndef UNIV_HOTBACKUP /*********************************************************************//** Gets the MySQL type code from a dtype. diff --git a/storage/innodb_plugin/include/data0type.ic b/storage/innodb_plugin/include/data0type.ic index 2bf67a941bd..44b6cf273e5 100644 --- a/storage/innodb_plugin/include/data0type.ic +++ b/storage/innodb_plugin/include/data0type.ic @@ -306,7 +306,7 @@ dtype_new_store_for_order_and_null_size( mach_write_to_2(buf + 2, len & 0xFFFFUL); - ut_ad(dtype_get_charset_coll(type->prtype) < 256); + ut_ad(dtype_get_charset_coll(type->prtype) <= MAX_CHAR_COLL_NUM); mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype)); if (type->prtype & DATA_NOT_NULL) { From de8c70e70b3fd335e1d34a5635fc4357adb43d95 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 20 Oct 2011 15:03:22 +0400 Subject: [PATCH 02/10] BUG#11757032 - 49030: OPTIMIZE TABLE BREAKS MYISAM TABLE WHEN USING MYISAM_USE_MMAP ON WINDOWS When OPTIMIZE/REPAIR TABLE is switching to new data file, old data file is removed while memory mapping is still active. With 5.1 implementation of nt_share_delete() it is not permitted to remove mmaped file. This fix disables memory mapping for mi_repair() operations. mysql-test/r/myisam.result: A test case for BUG#11757032. mysql-test/t/myisam.test: A test case for BUG#11757032. storage/myisam/ha_myisam.cc: mi_repair*() functions family use file I/O even if memory mapping is available. Since mixing mmap I/O and file I/O may cause various artifacts, memory mapping must be disabled. storage/myisam/mi_delete_all.c: Clean-up: do not attempt to remap file after truncate, since there is nothing to map. --- mysql-test/r/myisam.result | 24 ++++++++++++++++++++++++ mysql-test/t/myisam.test | 18 ++++++++++++++++++ storage/myisam/ha_myisam.cc | 16 ++++++++++++++++ storage/myisam/mi_delete_all.c | 5 ----- 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 433fc7c16a7..620c1f8b4b6 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2412,4 +2412,28 @@ CARDINALITY DROP TABLE t1; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; SET myisam_repair_threads=@@global.myisam_repair_threads; +# +# BUG#11757032 - 49030: OPTIMIZE TABLE BREAKS MYISAM TABLE WHEN +# USING MYISAM_USE_MMAP ON WINDOWS +# +SET GLOBAL myisam_use_mmap=1; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1),(2); +DELETE FROM t1 WHERE a=1; +FLUSH TABLE t1; +LOCK TABLE t1 WRITE; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +INSERT INTO t1 VALUES(3); +UNLOCK TABLES; +SELECT * FROM t1; +a +2 +3 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET GLOBAL myisam_use_mmap=default; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 4abd7dd2b1b..5340ddcaa48 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1645,4 +1645,22 @@ DROP TABLE t1; SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size; SET myisam_repair_threads=@@global.myisam_repair_threads; +--echo # +--echo # BUG#11757032 - 49030: OPTIMIZE TABLE BREAKS MYISAM TABLE WHEN +--echo # USING MYISAM_USE_MMAP ON WINDOWS +--echo # +SET GLOBAL myisam_use_mmap=1; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1),(2); +DELETE FROM t1 WHERE a=1; +FLUSH TABLE t1; +LOCK TABLE t1 WRITE; +OPTIMIZE TABLE t1; +INSERT INTO t1 VALUES(3); +UNLOCK TABLES; +SELECT * FROM t1; +CHECK TABLE t1; +DROP TABLE t1; +SET GLOBAL myisam_use_mmap=default; + --echo End of 5.1 tests diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 881102433d8..173dc356778 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1135,6 +1135,18 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) mi_get_mask_all_keys_active(share->base.keys) : share->state.key_map); uint testflag=param.testflag; +#ifdef HAVE_MMAP + bool remap= test(share->file_map); + /* + mi_repair*() functions family use file I/O even if memory + mapping is available. + + Since mixing mmap I/O and file I/O may cause various artifacts, + memory mapping must be disabled. + */ + if (remap) + mi_munmap_file(file); +#endif if (mi_test_if_sort_rep(file,file->state->records,key_map,0) && (local_testflag & T_REP_BY_SORT)) { @@ -1166,6 +1178,10 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) error= mi_repair(¶m, file, fixed_name, param.testflag & T_QUICK); } +#ifdef HAVE_MMAP + if (remap) + mi_dynmap_file(file, file->state->data_file_length); +#endif param.testflag=testflag; optimize_done=1; } diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c index 6ba542c112f..126359a0864 100644 --- a/storage/myisam/mi_delete_all.c +++ b/storage/myisam/mi_delete_all.c @@ -63,11 +63,6 @@ int mi_delete_all_rows(MI_INFO *info) my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) ) goto err; VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); -#ifdef HAVE_MMAP - /* Map again */ - if (share->file_map) - mi_dynmap_file(info, (my_off_t) 0); -#endif allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); From 8a0be8a541a1fd79bce33fc5157e8c7ff613c185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 21 Oct 2011 06:32:16 +0300 Subject: [PATCH 03/10] Bug#13116045 Compilation failure using GCC 4.6.1 in btr/btr0cur.c btr_record_not_null_field_in_rec(): Remove the parameter rec. Use rec_offs_nth_sql_null() instead of rec_get_nth_field(). rb:788 approved by Jimmy Yang --- storage/innobase/btr/btr0cur.c | 18 +++++------------- storage/innodb_plugin/ChangeLog | 5 +++++ storage/innodb_plugin/btr/btr0cur.c | 18 +++++------------- 3 files changed, 15 insertions(+), 26 deletions(-) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index a1dda8edf69..37bb3188785 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -2864,7 +2864,6 @@ static void btr_record_not_null_field_in_rec( /*=============================*/ - rec_t* rec, /* in: physical record */ ulint n_unique, /* in: dict_index_get_n_unique(index), number of columns uniquely determine an index entry */ @@ -2883,17 +2882,11 @@ btr_record_not_null_field_in_rec( } for (i = 0; i < n_unique; i++) { - ulint rec_len; - byte* field; - - field = rec_get_nth_field(rec, offsets, i, &rec_len); - - if (rec_len != UNIV_SQL_NULL) { - n_not_null[i]++; - } else { - /* Break if we hit the first NULL value */ + if (rec_offs_nth_sql_null(offsets, i)) { break; } + + n_not_null[i]++; } } @@ -2988,7 +2981,7 @@ btr_estimate_number_of_different_key_vals( if (n_not_null) { btr_record_not_null_field_in_rec( - rec, n_cols, offsets_rec, n_not_null); + n_cols, offsets_rec, n_not_null); } } @@ -3023,8 +3016,7 @@ btr_estimate_number_of_different_key_vals( if (n_not_null) { btr_record_not_null_field_in_rec( - next_rec, n_cols, offsets_next_rec, - n_not_null); + n_cols, offsets_next_rec, n_not_null); } total_external_size diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index b560f69daea..68f60c37f1f 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2011-10-20 The InnoDB Team + + * btr/brt0cur.c: + Fix Bug#13116045 Compilation failure using GCC 4.6.1 in btr/btr0cur.c + 2011-10-12 The InnoDB Team * btr/btr0cur.c, btr/btr0sea.c, buf/buf0buf.c, buf/buf0lru.c, diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 5fe16ff1215..1e603a6fc81 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -3261,7 +3261,6 @@ static void btr_record_not_null_field_in_rec( /*=============================*/ - rec_t* rec, /*!< in: physical record */ ulint n_unique, /*!< in: dict_index_get_n_unique(index), number of columns uniquely determine an index entry */ @@ -3280,17 +3279,11 @@ btr_record_not_null_field_in_rec( } for (i = 0; i < n_unique; i++) { - ulint rec_len; - byte* field; - - field = rec_get_nth_field(rec, offsets, i, &rec_len); - - if (rec_len != UNIV_SQL_NULL) { - n_not_null[i]++; - } else { - /* Break if we hit the first NULL value */ + if (rec_offs_nth_sql_null(offsets, i)) { break; } + + n_not_null[i]++; } } @@ -3398,7 +3391,7 @@ btr_estimate_number_of_different_key_vals( if (n_not_null) { btr_record_not_null_field_in_rec( - rec, n_cols, offsets_rec, n_not_null); + n_cols, offsets_rec, n_not_null); } } @@ -3433,8 +3426,7 @@ btr_estimate_number_of_different_key_vals( if (n_not_null) { btr_record_not_null_field_in_rec( - next_rec, n_cols, offsets_next_rec, - n_not_null); + n_cols, offsets_next_rec, n_not_null); } total_external_size From 3e250dc83f263b3a541f1e780c2382f5e21897d2 Mon Sep 17 00:00:00 2001 From: Ashish Agarwal Date: Fri, 21 Oct 2011 16:19:58 +0530 Subject: [PATCH 04/10] bug#11758979 - 51252: ARCHIVE TABLES STILL FAIL UNDER STRESS TESTS: CRASH, CORRUPTION, 4G MEMOR Issue: Valgrind errors due to checksum and optimize query angaist archive tables with null columns. Table record buffer was not initialized. Solution: Initialize the record buffer. --- mysql-test/r/archive.result | 19 +++++++++++++++++++ mysql-test/t/archive.test | 15 +++++++++++++++ storage/archive/ha_archive.cc | 12 ++++++++++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index aacaff30898..3ffefd2aedb 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12823,3 +12823,22 @@ a b c d e f -1 b c d e 1 DROP TABLE t1; SET sort_buffer_size=DEFAULT; +# +# BUG#11758979 - 51252: ARCHIVE TABLES STILL FAIL UNDER STRESS +# TESTS: CRASH, CORRUPTION, 4G MEMOR +# (to be executed with valgrind) +CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(NULL, ''); +FLUSH TABLE t1; +# we need this select to workaround BUG#11764364 +SELECT * FROM t1; +a b +NULL +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 286155052 +FLUSH TABLE t1; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP TABLE t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 4686b3ca1dc..3c18152ccc6 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1745,3 +1745,18 @@ INSERT INTO t1 SELECT t1.* FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6; SELECT * FROM t1 ORDER BY f LIMIT 1; DROP TABLE t1; SET sort_buffer_size=DEFAULT; + + +--echo # +--echo # BUG#11758979 - 51252: ARCHIVE TABLES STILL FAIL UNDER STRESS +--echo # TESTS: CRASH, CORRUPTION, 4G MEMOR +--echo # (to be executed with valgrind) +CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE; +INSERT INTO t1 VALUES(NULL, ''); +FLUSH TABLE t1; +--echo # we need this select to workaround BUG#11764364 +SELECT * FROM t1; +CHECKSUM TABLE t1 EXTENDED; +FLUSH TABLE t1; +OPTIMIZE TABLE t1; +DROP TABLE t1; diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 345c1b6835f..b6947688768 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -819,6 +819,7 @@ uint32 ha_archive::max_row_length(const uchar *buf) ptr != end ; ptr++) { + if (!table->field[*ptr]->is_null()) length += 2 + ((Field_blob*)table->field[*ptr])->get_length(); } @@ -1178,6 +1179,17 @@ int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record) /* Copy null bits */ const uchar *ptr= record_buffer->buffer; + /* + Field::unpack() is not called when field is NULL. For VARCHAR + Field::unpack() only unpacks as much bytes as occupied by field + value. In these cases respective memory area on record buffer is + not initialized. + + These uninitialized areas may be accessed by CHECKSUM TABLE or + by optimizer using temporary table (BUG#12997905). We may remove + this memset() when they're fixed. + */ + memset(record, 0, table->s->reclength); memcpy(record, ptr, table->s->null_bytes); ptr+= table->s->null_bytes; for (Field **field=table->field ; *field ; field++) From 62a40350b162a73a20a0d66b7efebd470b520c2b Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Fri, 21 Oct 2011 18:10:12 +0530 Subject: [PATCH 05/10] Bug#13106585 PUSH FOR "WL#5945 : IMPROVE LIBEDIT LIBRARY" BREAKS SOURCE RELEASE BUILD Some of the required files were not getting copied while performing 'make dist' and hence the build failed for the created distribution source. Added the missing files to Makefile.am. --- cmd-line-utils/libedit/Makefile.am | 9 +++++---- cmd-line-utils/libedit/chartype.c | 3 --- cmd-line-utils/libedit/histedit.h | 9 --------- cmd-line-utils/libedit/refresh.c | 2 -- cmd-line-utils/libedit/sys.h | 15 ++++++++++++++- cmd-line-utils/libedit/terminal.c | 3 --- 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index 87ca8b591bb..b68eca7f44a 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -7,8 +7,8 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include noinst_LIBRARIES = libedit.a -libedit_a_SOURCES = chared.c el.c eln.c history.c historyn.c map.c prompt.c readline.c \ - search.c tokenizer.c tokenizern.c vi.c common.c emacs.c \ +libedit_a_SOURCES = chared.c el.c eln.c history.c historyn.c map.c prompt.c chartype.c \ + readline.c search.c tokenizer.c tokenizern.c vi.c common.c emacs.c \ hist.c keymacro.c parse.c read.c refresh.c sig.c terminal.c \ tty.c help.c fcns.c filecomplete.c \ np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ @@ -19,8 +19,8 @@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ pkginclude_HEADERS = readline/readline.h -noinst_HEADERS = chared.h el.h el_terminal.h histedit.h keymacro.h parse.h refresh.h sig.h \ - sys.h config.h hist.h map.h prompt.h read.h \ +noinst_HEADERS = chared.h chartype.h el.h el_terminal.h histedit.h keymacro.h parse.h \ + refresh.h sig.h sys.h config.h hist.h map.h prompt.h read.h \ search.h tty.h filecomplete.h np/vis.h EXTRA_DIST = makelist.sh @@ -74,6 +74,7 @@ eln.o: vi.h emacs.h common.h help.h fcns.h history.o: vi.h emacs.h common.h help.h fcns.h historyn.o: vi.h emacs.h common.h help.h fcns.h map.o: vi.h emacs.h common.h help.h fcns.h +chartype.o: vi.h emacs.h common.h help.h fcns.h prompt.o: vi.h emacs.h common.h help.h fcns.h readline.o: vi.h emacs.h common.h help.h fcns.h search.o: vi.h emacs.h common.h help.h fcns.h diff --git a/cmd-line-utils/libedit/chartype.c b/cmd-line-utils/libedit/chartype.c index 3d66c48c36e..b70aebeec46 100644 --- a/cmd-line-utils/libedit/chartype.c +++ b/cmd-line-utils/libedit/chartype.c @@ -258,9 +258,6 @@ out: return NULL; } -#ifdef WIDECHAR -int wcwidth(wchar_t wc); // Signature. -#endif protected int ct_visual_width(Char c) diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h index b066593cefd..9f2b245f851 100644 --- a/cmd-line-utils/libedit/histedit.h +++ b/cmd-line-utils/libedit/histedit.h @@ -247,15 +247,6 @@ int tok_str(Tokenizer *, const char *, /* * Begin Wide Character Support */ -#ifdef __linux__ -/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#endif - -#include -#include /* * Wide character versions diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c index a144059f700..64057eaabfe 100644 --- a/cmd-line-utils/libedit/refresh.c +++ b/cmd-line-utils/libedit/refresh.c @@ -40,8 +40,6 @@ static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; #endif #endif /* not lint && not SCCSID */ -#include "chartype.c" /* XXXMYSQL */ - /* * refresh.c: Lower level screen refreshing functions */ diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h index 2731fb5f30e..33638d1565b 100644 --- a/cmd-line-utils/libedit/sys.h +++ b/cmd-line-utils/libedit/sys.h @@ -92,8 +92,21 @@ size_t strlcpy(char *dst, const char *src, size_t size); char *fgetln(FILE *fp, size_t *len); #endif -#ifndef HAVE_WCSDUP +#ifdef __linux__ +/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#endif + +#ifndef __USE_XOPEN +#define __USE_XOPEN +#endif + #include +#include + +#ifndef HAVE_WCSDUP wchar_t *wcsdup(const wchar_t *); #endif diff --git a/cmd-line-utils/libedit/terminal.c b/cmd-line-utils/libedit/terminal.c index ae91d9afe92..8cfbeac7c52 100644 --- a/cmd-line-utils/libedit/terminal.c +++ b/cmd-line-utils/libedit/terminal.c @@ -636,9 +636,6 @@ mc_again: el->el_cursor.h = where; /* now where is here */ } -#ifdef WIDECHAR -int wcwidth(wchar_t); // Signature. -#endif /* terminal_overwrite(): * Overstrike num characters From a656ff83c822f79806aaaf71d2aca98529db23f9 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Sun, 23 Oct 2011 09:37:35 +0400 Subject: [PATCH 06/10] Fix for bug #13116518 - "OPEN_TABLES() SHOULD NOT ALLOCATE AND FREE NEW_FRM_MEM WITHOUT NEEDING TO". During the process of opening tables for a statement, we allocated memory which was used only during view loading even in cases when the statement didn't use any views. Such an unnecessary allocation (and corresponding freeing) might have caused significant performance overhead in some workloads. For example, it caused up to 15% slowdown in a simple stored routine calculating Fibonacci's numbers. This memory was pre-allocated as part of "new_frm_mem" MEM_ROOT initialization at the beginning of open_tables(). This patch addresses this issue by turning off memory pre-allocation during initialization for this MEM_ROOT. Now, memory on this root will be allocated only at the point when the first .FRM for a view is opened. The patch doesn't contain a test case since it is hard to test the performance improvements or the absence of memory allocation in our test framework. --- sql/sql_base.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 644796ea337..e0472e2c9b5 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4810,10 +4810,11 @@ bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags, } /* - temporary mem_root for new .frm parsing. - TODO: variables for size + Initialize temporary MEM_ROOT for new .FRM parsing. Do not allocate + anything yet, to avoid penalty for statements which don't use views + and thus new .FRM format. */ - init_sql_alloc(&new_frm_mem, 8024, 8024); + init_sql_alloc(&new_frm_mem, 8024, 0); thd->current_tablenr= 0; restart: From f66002f8eb5747e95721790b30a5e02be6ca6929 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Mon, 24 Oct 2011 13:35:28 +0530 Subject: [PATCH 07/10] WL#5945 - Improve libedit library Fixed a misplaced parenthesis, injected due to syncing from libedit CVS head. --- cmd-line-utils/libedit/README | 2 +- cmd-line-utils/libedit/chared.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd-line-utils/libedit/README b/cmd-line-utils/libedit/README index 28041766a2e..c4bc1554b03 100644 --- a/cmd-line-utils/libedit/README +++ b/cmd-line-utils/libedit/README @@ -42,7 +42,7 @@ then merge remaining bits by hand. All MySQL-specific changes should be marked with XXXMYSQL to make them easier to identify and merge. To generate a 'clean' diff against upstream you can use the above commands but use - cvs co -D "2011/10/04 15:27:04" [..] + cvs co -D "2011/10/23 17:37:55" [..] to fetch the baseline of most recent merge. diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c index aba30086b9f..647a5afe439 100644 --- a/cmd-line-utils/libedit/chared.c +++ b/cmd-line-utils/libedit/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.35 2011/08/16 16:25:15 christos Exp $ */ +/* $NetBSD: chared.c,v 1.36 2011/10/23 17:37:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -200,7 +200,7 @@ c_delbefore1(EditLine *el) protected int ce__isword(Int p) { - return Isalnum(p || Strchr(STR("*?_-.[]~="), p) != NULL); + return Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL; } From 8b482e837b3ae1da8f1b92fff970663e43b9d294 Mon Sep 17 00:00:00 2001 From: Hery Ramilison Date: Wed, 26 Oct 2011 20:44:18 +0200 Subject: [PATCH 08/10] cloning 5.5.18 off --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 7bac52ecdfb..4eec6bf9d34 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=18 +MYSQL_VERSION_PATCH=19 MYSQL_VERSION_EXTRA= From 006f649f4b13060a79e05f69eae8e44e0c1b0e0a Mon Sep 17 00:00:00 2001 From: Karen Langford Date: Wed, 26 Oct 2011 20:48:42 +0200 Subject: [PATCH 09/10] Increased version number after cloning 5.1.60 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 120717d6afa..080de523c1b 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.60], [], [mysql]) +AC_INIT([MySQL Server], [5.1.61], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 1d9c841c3bd1aea647127d39836429a9a0e4f03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 27 Oct 2011 14:58:12 +0300 Subject: [PATCH 10/10] Bug #12884631 62146: TABLES ARE LOST FOR DDL row_rename_table_for_mysql(): Return DB_ERROR instead of DB_SUCCESS when fil_rename_tablespace() returns an error. This bug was introduced in the InnoDB Plugin. Approved by Sunny Bains over IM. --- storage/innodb_plugin/ChangeLog | 5 +++++ storage/innodb_plugin/row/row0mysql.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 68f60c37f1f..5a4ef5fa4ef 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2011-10-27 The InnoDB Team + + * row/row0mysql.c: + Fix Bug #12884631 62146: TABLES ARE LOST FOR DDL + 2011-10-20 The InnoDB Team * btr/brt0cur.c: diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 4e6a49cf8b0..6f689f9909d 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 2000, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -3971,6 +3971,7 @@ end: trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, NULL); trx->error_state = DB_SUCCESS; + err = DB_ERROR; goto funct_exit; }