From 239ca6006b1c52ab057e36e10d4c7103386c78bd Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Wed, 24 Nov 2010 14:07:43 +1100 Subject: [PATCH 01/25] Fix bug# 18274 InnoDB auto_increment field reset on OPTIMIZE TABLE OPTIMIZE TABLE recreates the whole table. That is why the counter gets reset. Making the next autoinc column persistent is a separate issue from resetting the value after an OPTIMIZE TABLE. We already have a check for ALTER TABLE and CREATE INDEX to preserve the value on table recreate. We should be able to add an additional check for OPTIMIZE TABLE to preserve the next value. rb://519 Approved by Jimmy Yang. --- .../r/innodb-autoinc-18274.result | 26 +++++++++++++++++ .../innodb_plugin/t/innodb-autoinc-18274.test | 29 +++++++++++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 24 ++++++++------- 3 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb-autoinc-18274.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb-autoinc-18274.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb-autoinc-18274.result b/mysql-test/suite/innodb_plugin/r/innodb-autoinc-18274.result new file mode 100644 index 00000000000..22afc65a649 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb-autoinc-18274.result @@ -0,0 +1,26 @@ +drop table if exists t1; +SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (null); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 +DELETE FROM t1; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES(null); +SELECT * FROM t1; +c1 +2 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-autoinc-18274.test b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-18274.test new file mode 100644 index 00000000000..8734311dd7a --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-18274.test @@ -0,0 +1,29 @@ +-- source include/have_innodb_plugin.inc +# embedded server ignores 'delayed', so skip this +-- source include/not_embedded.inc + +let $innodb_file_format_check_orig=`select @@innodb_file_format_check`; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Bug #18274 InnoDB auto_increment field reset on OPTIMIZE TABLE +SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (null); +SHOW CREATE TABLE t1; +DELETE FROM t1; +OPTIMIZE TABLE t1; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES(null); +SELECT * FROM t1; +DROP TABLE t1; + +# +# restore environment to the state it was before this test execution +# + +-- disable_query_log +eval set global innodb_file_format_check=$innodb_file_format_check_orig; diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 5965bd0e59e..cffe1e8459e 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6808,23 +6808,25 @@ ha_innobase::create( setup at this stage and so we use thd. */ /* We need to copy the AUTOINC value from the old table if - this is an ALTER TABLE or CREATE INDEX because CREATE INDEX - does a table copy too. */ + this is an ALTER|OPTIMIZE TABLE or CREATE INDEX because CREATE INDEX + does a table copy too. If query was one of : + + CREATE TABLE ...AUTO_INCREMENT = x; or + ALTER TABLE...AUTO_INCREMENT = x; or + OPTIMIZE TABLE t; or + CREATE INDEX x on t(...); + + Find out a table definition from the dictionary and get + the current value of the auto increment field. Set a new + value to the auto increment field if the value is greater + than the maximum value in the column. */ if (((create_info->used_fields & HA_CREATE_USED_AUTO) || thd_sql_command(thd) == SQLCOM_ALTER_TABLE + || thd_sql_command(thd) == SQLCOM_OPTIMIZE || thd_sql_command(thd) == SQLCOM_CREATE_INDEX) && create_info->auto_increment_value > 0) { - /* Query was one of : - CREATE TABLE ...AUTO_INCREMENT = x; or - ALTER TABLE...AUTO_INCREMENT = x; or - CREATE INDEX x on t(...); - Find out a table definition from the dictionary and get - the current value of the auto increment field. Set a new - value to the auto increment field if the value is greater - than the maximum value in the column. */ - auto_inc_value = create_info->auto_increment_value; dict_table_autoinc_lock(innobase_table); From 951244c6501642275d2a44fd4a6b0086f3abb80b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 25 Nov 2010 08:55:47 +0200 Subject: [PATCH 02/25] Bug#47350 Support innodb plugin without separate shared object Add a _commented_ workaround for Bug#47350. The full solution is tricky to get right as explained in the bug report. It is not worth the effort to extend the deprecated autotools framework to support conflicting plugins and would be too risky for MySQL 5.1 (GA). --- storage/innodb_plugin/plug.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/storage/innodb_plugin/plug.in b/storage/innodb_plugin/plug.in index 2ee45389e9c..b2af11295bc 100644 --- a/storage/innodb_plugin/plug.in +++ b/storage/innodb_plugin/plug.in @@ -17,6 +17,9 @@ MYSQL_STORAGE_ENGINE(innodb_plugin,, [InnoDB Storage Engine], [Transactional Tables using InnoDB], [max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(innodb_plugin, [storage/innodb_plugin]) +# Enable if you know what you are doing (trying to link both InnoDB and +# InnoDB Plugin statically into MySQL does not work). +#MYSQL_PLUGIN_STATIC(innodb_plugin, [libinnobase.a]) MYSQL_PLUGIN_DYNAMIC(innodb_plugin, [ha_innodb_plugin.la]) MYSQL_PLUGIN_ACTIONS(innodb_plugin, [ AC_CHECK_HEADERS(sched.h) From 03d1576b60bb28c484110f21beb2d4f777cff1d8 Mon Sep 17 00:00:00 2001 From: "kevin.lewis@oracle.com" <> Date: Tue, 30 Nov 2010 10:03:55 -0600 Subject: [PATCH 03/25] RB://518 approved by Jimmy Yang and Sunny bains Code cleanup after changes for Bug 56628. The general approach for InnoDB is to make a reference to each enum value whenever it is used in a switch statement. In addition, no default case should be used for switch statements on enum types. This assures that if there is ever any change in the enum values, the switch will need to change to reflect it since a compiler warning will occur. In this case, the enum row_type is declared in handler.h and could be changed for another storage engine. If so, a warning will occur in the InnoDB build. Other changes; * This patch uses 2 macros to help consolidate warning messages that need to occur twice in the single switch for row_format. * Using row_format as the variable name to distinguish it from the enum type. * Function declaration format correction. --- storage/innodb_plugin/handler/ha_innodb.cc | 182 ++++++++++----------- 1 file changed, 89 insertions(+), 93 deletions(-) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index cffe1e8459e..86168e2bc9b 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6293,10 +6293,11 @@ create_clustered_index_when_no_primary( /*****************************************************************//** Return a display name for the row format @return row format name */ - -const char *get_row_format_name( -/*============================*/ -enum row_type row_format) /*!< in: Row Format */ +UNIV_INTERN +const char* +get_row_format_name( +/*================*/ + enum row_type row_format) /*!< in: Row Format */ { switch (row_format) { case ROW_TYPE_COMPACT: @@ -6311,12 +6312,38 @@ enum row_type row_format) /*!< in: Row Format */ return("DEFAULT"); case ROW_TYPE_FIXED: return("FIXED"); - default: + case ROW_TYPE_PAGE: + case ROW_TYPE_NOT_USED: break; } return("NOT USED"); } +/** If file-per-table is missing, issue warning and set ret false */ +#define CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE \ + if (!srv_file_per_table) { \ + push_warning_printf( \ + thd, MYSQL_ERROR::WARN_LEVEL_WARN, \ + ER_ILLEGAL_HA_CREATE_OPTION, \ + "InnoDB: ROW_FORMAT=%s requires" \ + " innodb_file_per_table.", \ + get_row_format_name(row_format)); \ + ret = FALSE; \ + } + +/** If file-format is Antelope, issue warning and set ret false */ +#define CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE \ + if (srv_file_format < DICT_TF_FORMAT_ZIP) { \ + push_warning_printf( \ + thd, MYSQL_ERROR::WARN_LEVEL_WARN, \ + ER_ILLEGAL_HA_CREATE_OPTION, \ + "InnoDB: ROW_FORMAT=%s requires" \ + " innodb_file_format > Antelope.", \ + get_row_format_name(row_format)); \ + ret = FALSE; \ + } + + /*****************************************************************//** Validates the create options. We may build on this function in future. For now, it checks two specifiers: @@ -6334,7 +6361,7 @@ create_options_are_valid( { ibool kbs_specified = FALSE; ibool ret = TRUE; - enum row_type row_type = form->s->row_type; + enum row_type row_format = form->s->row_type; ut_ad(thd != NULL); @@ -6343,23 +6370,6 @@ create_options_are_valid( return(TRUE); } - /* Check for a valid Innodb ROW_FORMAT specifier. For example, - ROW_TYPE_FIXED can be sent to Innodb */ - switch (row_type) { - case ROW_TYPE_COMPACT: - case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - case ROW_TYPE_REDUNDANT: - case ROW_TYPE_DEFAULT: - break; - default: - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: invalid ROW_FORMAT specifier."); - ret = FALSE; - } - ut_ad(form != NULL); ut_ad(create_info != NULL); @@ -6372,7 +6382,23 @@ create_options_are_valid( case 4: case 8: case 16: - /* Valid value. */ + /* Valid KEY_BLOCK_SIZE, check its dependencies. */ + if (!srv_file_per_table) { + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_per_table."); + ret = FALSE; + } + if (srv_file_format < DICT_TF_FORMAT_ZIP) { + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_format > Antelope."); + ret = FALSE; + } break; default: push_warning_printf( @@ -6382,72 +6408,43 @@ create_options_are_valid( " Valid values are [1, 2, 4, 8, 16]", create_info->key_block_size); ret = FALSE; + break; } } - /* If KEY_BLOCK_SIZE was specified, check for its - dependencies. */ - if (kbs_specified && !srv_file_per_table) { - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); - ret = FALSE; - } - - if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE requires" - " innodb_file_format > Antelope."); - ret = FALSE; - } - - switch (row_type) { + /* Check for a valid Innodb ROW_FORMAT specifier and + other incompatibilities. */ + switch (row_format) { case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - /* These two ROW_FORMATs require srv_file_per_table - and srv_file_format > Antelope */ - if (!srv_file_per_table) { - push_warning_printf( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - get_row_format_name(row_type)); - ret = FALSE; - } - - if (srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning_printf( - thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s requires" - " innodb_file_format > Antelope.", - get_row_format_name(row_type)); - ret = FALSE; - } - default: + CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE; + CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE; break; - } - - switch (row_type) { - case ROW_TYPE_REDUNDANT: - case ROW_TYPE_COMPACT: case ROW_TYPE_DYNAMIC: - /* KEY_BLOCK_SIZE is only allowed with Compressed or Default */ + CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE; + CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE; + /* fall through since dynamic also shuns KBS */ + case ROW_TYPE_COMPACT: + case ROW_TYPE_REDUNDANT: if (kbs_specified) { push_warning_printf( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: cannot specify ROW_FORMAT = %s" " with KEY_BLOCK_SIZE.", - get_row_format_name(row_type)); - ret = FALSE; + get_row_format_name(row_format)); + ret = FALSE; } - default: + break; + case ROW_TYPE_DEFAULT: + break; + case ROW_TYPE_FIXED: + case ROW_TYPE_PAGE: + case ROW_TYPE_NOT_USED: + push_warning( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, \ + "InnoDB: invalid ROW_FORMAT specifier."); + ret = FALSE; break; } @@ -6498,7 +6495,7 @@ ha_innobase::create( const ulint file_format = srv_file_format; const char* stmt; size_t stmt_len; - enum row_type row_type; + enum row_type row_format; DBUG_ENTER("ha_innobase::create"); @@ -6598,8 +6595,8 @@ ha_innobase::create( push_warning( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: KEY_BLOCK_SIZE" - " requires innodb_file_per_table."); + "InnoDB: KEY_BLOCK_SIZE requires" + " innodb_file_per_table."); flags = 0; } @@ -6616,20 +6613,19 @@ ha_innobase::create( push_warning_printf( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring" - " KEY_BLOCK_SIZE=%lu.", + "InnoDB: ignoring KEY_BLOCK_SIZE=%lu.", create_info->key_block_size); } } - row_type = form->s->row_type; + row_format = form->s->row_type; if (flags) { /* if ROW_FORMAT is set to default, automatically change it to COMPRESSED.*/ - if (row_type == ROW_TYPE_DEFAULT) { - row_type = ROW_TYPE_COMPRESSED; - } else if (row_type != ROW_TYPE_COMPRESSED) { + if (row_format == ROW_TYPE_DEFAULT) { + row_format = ROW_TYPE_COMPRESSED; + } else if (row_format != ROW_TYPE_COMPRESSED) { /* ROW_FORMAT other than COMPRESSED ignores KEY_BLOCK_SIZE. It does not make sense to reject conflicting @@ -6646,7 +6642,7 @@ ha_innobase::create( } } else { /* flags == 0 means no KEY_BLOCK_SIZE.*/ - if (row_type == ROW_TYPE_COMPRESSED) { + if (row_format == ROW_TYPE_COMPRESSED) { /* ROW_FORMAT=COMPRESSED without KEY_BLOCK_SIZE implies half the maximum KEY_BLOCK_SIZE. */ @@ -6661,7 +6657,7 @@ ha_innobase::create( } } - switch (row_type) { + switch (row_format) { case ROW_TYPE_REDUNDANT: break; case ROW_TYPE_COMPRESSED: @@ -6672,25 +6668,25 @@ ha_innobase::create( ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ROW_FORMAT=%s requires" " innodb_file_per_table.", - get_row_format_name(row_type)); + get_row_format_name(row_format)); } else if (file_format < DICT_TF_FORMAT_ZIP) { push_warning_printf( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ROW_FORMAT=%s requires" " innodb_file_format > Antelope.", - get_row_format_name(row_type)); + get_row_format_name(row_format)); } else { flags |= DICT_TF_COMPACT - | (DICT_TF_FORMAT_ZIP - << DICT_TF_FORMAT_SHIFT); + | (DICT_TF_FORMAT_ZIP + << DICT_TF_FORMAT_SHIFT); break; } /* fall through */ case ROW_TYPE_NOT_USED: case ROW_TYPE_FIXED: - default: + case ROW_TYPE_PAGE: push_warning( thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, From 55a12f888ac086809f59a5268e44ee1062896933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 1 Dec 2010 10:03:53 +0200 Subject: [PATCH 04/25] Bug#58623: Bogus debug assertion failure in i_s_locks_row_validate() This bogus assertion was introduced in the fix of Bug #57802: Empty ASSERTION parameter passed to the HASH_SEARCH macro. --- storage/innodb_plugin/trx/trx0i_s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/trx/trx0i_s.c b/storage/innodb_plugin/trx/trx0i_s.c index a3ffc4ec015..3bf5ece9b9c 100644 --- a/storage/innodb_plugin/trx/trx0i_s.c +++ b/storage/innodb_plugin/trx/trx0i_s.c @@ -435,7 +435,7 @@ i_s_locks_row_validate( /* record lock */ ut_ad(!strcmp("RECORD", row->lock_type)); ut_ad(row->lock_index != NULL); - ut_ad(row->lock_data != NULL); + /* row->lock_data == NULL if buf_page_try_get() == NULL */ ut_ad(row->lock_page != ULINT_UNDEFINED); ut_ad(row->lock_rec != ULINT_UNDEFINED); } From ee321e803b9c353b918763436fd60e085091fa28 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 9 Dec 2010 01:19:46 -0800 Subject: [PATCH 05/25] Fix Bug #57600 output of I/O sum[%lu] can go negative rb://532 approved by Sunny Bains --- storage/innodb_plugin/ChangeLog | 4 ++++ storage/innodb_plugin/buf/buf0lru.c | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 5ca60eb73d5..347dc9a5183 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,7 @@ +2010-12-09 The InnoDB Team + * buf/buf0lru.c: + Fix Bug#57600 output of I/O sum[%lu] can go negative + 2010-11-11 The InnoDB Team * thr/thr0loc.c, trx/trx0i_s.c: Fix Bug#57802 Empty ASSERTION parameter passed to the HASH_SEARCH macro diff --git a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c index 78d8d348e2a..e4cf218bf2e 100644 --- a/storage/innodb_plugin/buf/buf0lru.c +++ b/storage/innodb_plugin/buf/buf0lru.c @@ -1942,6 +1942,7 @@ buf_LRU_stat_update(void) /*=====================*/ { buf_LRU_stat_t* item; + buf_LRU_stat_t cur_stat; /* If we haven't started eviction yet then don't update stats. */ if (buf_pool->freed_page_clock == 0) { @@ -1955,12 +1956,19 @@ buf_LRU_stat_update(void) buf_LRU_stat_arr_ind++; buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL; - /* Add the current value and subtract the obsolete entry. */ - buf_LRU_stat_sum.io += buf_LRU_stat_cur.io - item->io; - buf_LRU_stat_sum.unzip += buf_LRU_stat_cur.unzip - item->unzip; + /* Add the current value and subtract the obsolete entry. + Since buf_LRU_stat_cur is not protected by any mutex, + it can be changing between adding to buf_LRU_stat_sum + and copying to item. Assign it to local variables to make + sure the same value assign to the buf_LRU_stat_sum + and item */ + cur_stat = buf_LRU_stat_cur; + + buf_LRU_stat_sum.io += cur_stat.io - item->io; + buf_LRU_stat_sum.unzip += cur_stat.unzip - item->unzip; /* Put current entry in the array. */ - memcpy(item, &buf_LRU_stat_cur, sizeof *item); + memcpy(item, &cur_stat, sizeof *item); buf_pool_mutex_exit(); From 66c518dceffe0e355c405273ac173e9d5c7628a5 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Dec 2010 11:38:19 +0200 Subject: [PATCH 06/25] Speed up innodb_bug57255.test Submitted by: Stewart Smith (via internals@lists.mysql.com) --- mysql-test/suite/innodb/t/innodb_bug57255.test | 2 ++ mysql-test/suite/innodb_plugin/t/innodb_bug57255.test | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/suite/innodb/t/innodb_bug57255.test b/mysql-test/suite/innodb/t/innodb_bug57255.test index 2b37a0a6092..0bf686578b2 100644 --- a/mysql-test/suite/innodb/t/innodb_bug57255.test +++ b/mysql-test/suite/innodb/t/innodb_bug57255.test @@ -12,6 +12,7 @@ create table C(id int not null auto_increment primary key, f1 int not null, fore insert into A values(1), (2); --disable_query_log +begin; let $i=257; while ($i) { @@ -24,6 +25,7 @@ while ($i) insert into C(f1) values(2); dec $i; } +commit; --enable_query_log # Following Deletes should not report error diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test index 96184c355b6..e5056d3e23c 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test @@ -12,6 +12,7 @@ create table C(id int not null auto_increment primary key, f1 int not null, fore insert into A values(1), (2); --disable_query_log +begin; let $i=257; while ($i) { @@ -24,6 +25,7 @@ while ($i) insert into C(f1) values(2); dec $i; } +commit; --enable_query_log # Following Deletes should not report error From 2317da0d00ef127cc89680e80fc8e081903d3597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 21 Dec 2010 11:39:19 +0200 Subject: [PATCH 07/25] Bug#58912 InnoDB unnecessarily avoids update-in-place on column prefix indexes row_upd_changes_ord_field_binary(): Do not return TRUE if the update vector changes a column that is covered by a prefix index, but does not change the column prefix. Add the row_ext_t parameter for determining whether the prefixes of externally stored columns match. dfield_datas_are_binary_equal(): Add the parameter len, for comparing column prefixes when len > 0. innodb.test: Add a test case where the patch of Bug #55284 failed without this fix. rb:537 approved by Jimmy Yang --- .../suite/innodb_plugin/r/innodb.result | 8 +- mysql-test/suite/innodb_plugin/t/innodb.test | 12 +++ storage/innodb_plugin/ChangeLog | 10 ++ storage/innodb_plugin/btr/btr0cur.c | 3 +- storage/innodb_plugin/include/data0data.h | 11 ++- storage/innodb_plugin/include/data0data.ic | 22 +++-- storage/innodb_plugin/include/row0upd.h | 5 +- storage/innodb_plugin/row/row0purge.c | 2 +- storage/innodb_plugin/row/row0umod.c | 4 +- storage/innodb_plugin/row/row0upd.c | 93 +++++++++++++------ 10 files changed, 128 insertions(+), 42 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb.result b/mysql-test/suite/innodb_plugin/r/innodb.result index 75a7023f9d0..d3f7a0b9fff 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb.result +++ b/mysql-test/suite/innodb_plugin/r/innodb.result @@ -1,5 +1,8 @@ drop table if exists t1,t2,t3,t4; drop database if exists mysqltest; +CREATE TABLE bug58912 (a BLOB, b TEXT, PRIMARY KEY(a(1))) ENGINE=InnoDB; +INSERT INTO bug58912 VALUES(REPEAT('a',8000),REPEAT('b',8000)); +UPDATE bug58912 SET a=REPEAT('a',7999); create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb; insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt'); select id, code, name from t1 order by id; @@ -1676,10 +1679,10 @@ variable_value - @innodb_rows_deleted_orig 71 SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; variable_value - @innodb_rows_inserted_orig -1066 +1067 SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; variable_value - @innodb_rows_updated_orig -865 +866 SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'; variable_value - @innodb_row_lock_waits_orig 0 @@ -3239,3 +3242,4 @@ Variable_name Value Handler_update 1 Variable_name Value Handler_delete 1 +DROP TABLE bug58912; diff --git a/mysql-test/suite/innodb_plugin/t/innodb.test b/mysql-test/suite/innodb_plugin/t/innodb.test index 60ba7d1e3bf..cfc2277d501 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb.test +++ b/mysql-test/suite/innodb_plugin/t/innodb.test @@ -43,6 +43,15 @@ drop table if exists t1,t2,t3,t4; drop database if exists mysqltest; --enable_warnings +# Bug#58912 InnoDB unnecessarily avoids update-in-place on column prefixes +CREATE TABLE bug58912 (a BLOB, b TEXT, PRIMARY KEY(a(1))) ENGINE=InnoDB; +INSERT INTO bug58912 VALUES(REPEAT('a',8000),REPEAT('b',8000)); +UPDATE bug58912 SET a=REPEAT('a',7999); +# The above statements used to trigger a failure during purge when +# Bug#55284 was fixed while Bug#58912 was not. Defer the DROP TABLE, +# so that purge gets a chance to run (and a double free of the +# off-page column can be detected, if one is to occur.) + # # Small basic test with ignore # @@ -2541,6 +2550,9 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; -- enable_query_log +# Clean up after the Bug#55284/Bug#58912 test case. +DROP TABLE bug58912; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 347dc9a5183..13e2836dc98 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,8 +1,18 @@ +2010-12-21 The InnoDB Team + + * include/data0data.h, include/data0data.ic, include/row0upd.h, + btr/btr0cur.c, row/row0purge.c, row/row0umod.c, row/row0upd.c, + innodb.result, innodb.test: + Fix Bug#58912 InnoDB unnecessarily avoids update-in-place + on column prefix indexes + 2010-12-09 The InnoDB Team + * buf/buf0lru.c: Fix Bug#57600 output of I/O sum[%lu] can go negative 2010-11-11 The InnoDB Team + * thr/thr0loc.c, trx/trx0i_s.c: Fix Bug#57802 Empty ASSERTION parameter passed to the HASH_SEARCH macro diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index f9f0d156f52..2a26d8ffb33 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -1756,7 +1756,8 @@ btr_cur_update_in_place( NOT call it if index is secondary */ if (!dict_index_is_clust(index) - || row_upd_changes_ord_field_binary(NULL, index, update)) { + || row_upd_changes_ord_field_binary(NULL, NULL, + index, update)) { /* Remove possible hash index pointer to this record */ btr_search_update_hash_on_delete(cursor); diff --git a/storage/innodb_plugin/include/data0data.h b/storage/innodb_plugin/include/data0data.h index f9fce3f3657..cab8d790ac1 100644 --- a/storage/innodb_plugin/include/data0data.h +++ b/storage/innodb_plugin/include/data0data.h @@ -154,14 +154,19 @@ dfield_dup( dfield_t* field, /*!< in/out: data field */ mem_heap_t* heap); /*!< in: memory heap where allocated */ /*********************************************************************//** -Tests if data length and content is equal for two dfields. -@return TRUE if equal */ +Tests if two data fields are equal. +If len==0, tests the data length and content for equality. +If len>0, tests the first len bytes of the content for equality. +@return TRUE if both fields are NULL or if they are equal */ UNIV_INLINE ibool dfield_datas_are_binary_equal( /*==========================*/ const dfield_t* field1, /*!< in: field */ - const dfield_t* field2);/*!< in: field */ + const dfield_t* field2, /*!< in: field */ + ulint len) /*!< in: maximum prefix to compare, + or 0 to compare the whole field length */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Tests if dfield data length and content is equal to the given. @return TRUE if equal */ diff --git a/storage/innodb_plugin/include/data0data.ic b/storage/innodb_plugin/include/data0data.ic index da79aa33702..74e0f7d09a0 100644 --- a/storage/innodb_plugin/include/data0data.ic +++ b/storage/innodb_plugin/include/data0data.ic @@ -229,20 +229,30 @@ dfield_dup( } /*********************************************************************//** -Tests if data length and content is equal for two dfields. -@return TRUE if equal */ +Tests if two data fields are equal. +If len==0, tests the data length and content for equality. +If len>0, tests the first len bytes of the content for equality. +@return TRUE if both fields are NULL or if they are equal */ UNIV_INLINE ibool dfield_datas_are_binary_equal( /*==========================*/ const dfield_t* field1, /*!< in: field */ - const dfield_t* field2) /*!< in: field */ + const dfield_t* field2, /*!< in: field */ + ulint len) /*!< in: maximum prefix to compare, + or 0 to compare the whole field length */ { - ulint len; + ulint len2 = len; - len = field1->len; + if (field1->len == UNIV_SQL_NULL || len == 0 || field1->len < len) { + len = field1->len; + } - return(len == field2->len + if (field2->len == UNIV_SQL_NULL || len2 == 0 || field2->len < len2) { + len2 = field2->len; + } + + return(len == len2 && (len == UNIV_SQL_NULL || !memcmp(field1->data, field2->data, len))); } diff --git a/storage/innodb_plugin/include/row0upd.h b/storage/innodb_plugin/include/row0upd.h index ea14cd64213..58d7ad15ecc 100644 --- a/storage/innodb_plugin/include/row0upd.h +++ b/storage/innodb_plugin/include/row0upd.h @@ -286,10 +286,13 @@ row_upd_changes_ord_field_binary( row and the data values in update are not known when this function is called, e.g., at compile time */ + const row_ext_t*ext, /*!< NULL, or prefixes of the externally + stored columns in the old row */ dict_index_t* index, /*!< in: index of the record */ - const upd_t* update);/*!< in: update vector for the row; NOTE: the + const upd_t* update) /*!< in: update vector for the row; NOTE: the field numbers in this MUST be clustered index positions! */ + __attribute__((nonnull(3,4), warn_unused_result)); /***********************************************************//** Checks if an update vector changes an ordering field of an index record. This function is fast if the update vector is short or the number of ordering diff --git a/storage/innodb_plugin/row/row0purge.c b/storage/innodb_plugin/row/row0purge.c index 31b255cf2d4..8bf2ae0f458 100644 --- a/storage/innodb_plugin/row/row0purge.c +++ b/storage/innodb_plugin/row/row0purge.c @@ -413,7 +413,7 @@ row_purge_upd_exist_or_extern( while (node->index != NULL) { index = node->index; - if (row_upd_changes_ord_field_binary(NULL, node->index, + if (row_upd_changes_ord_field_binary(NULL, NULL, node->index, node->update)) { /* Build the older version of the index entry */ entry = row_build_index_entry(node->row, NULL, diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index 5998dadd16d..49c51a75f18 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -668,8 +668,8 @@ row_undo_mod_upd_exist_sec( while (node->index != NULL) { index = node->index; - if (row_upd_changes_ord_field_binary(node->row, node->index, - node->update)) { + if (row_upd_changes_ord_field_binary( + node->row, node->ext, node->index, node->update)) { /* Build the newest version of the index entry */ entry = row_build_index_entry(node->row, node->ext, diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 0dc550b93f5..20f31e15514 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -1198,20 +1198,21 @@ row_upd_changes_ord_field_binary( row and the data values in update are not known when this function is called, e.g., at compile time */ + const row_ext_t*ext, /*!< NULL, or prefixes of the externally + stored columns in the old row */ dict_index_t* index, /*!< in: index of the record */ const upd_t* update) /*!< in: update vector for the row; NOTE: the field numbers in this MUST be clustered index positions! */ { - ulint n_unique; - ulint n_upd_fields; - ulint i, j; - dict_index_t* clust_index; + ulint n_unique; + ulint i; + const dict_index_t* clust_index; - ut_ad(update && index); + ut_ad(update); + ut_ad(index); n_unique = dict_index_get_n_unique(index); - n_upd_fields = upd_get_n_fields(update); clust_index = dict_table_get_first_index(index->table); @@ -1219,33 +1220,72 @@ row_upd_changes_ord_field_binary( const dict_field_t* ind_field; const dict_col_t* col; - ulint col_pos; ulint col_no; + const upd_field_t* upd_field; + const dfield_t* dfield; + dfield_t dfield_ext; + ulint dfield_len; + const byte* buf; ind_field = dict_index_get_nth_field(index, i); col = dict_field_get_col(ind_field); - col_pos = dict_col_get_clust_pos(col, clust_index); col_no = dict_col_get_no(col); - for (j = 0; j < n_upd_fields; j++) { + upd_field = upd_get_field_by_field_no( + update, dict_col_get_clust_pos(col, clust_index)); - const upd_field_t* upd_field - = upd_get_nth_field(update, j); + if (upd_field == NULL) { + continue; + } - /* Note that if the index field is a column prefix - then it may be that row does not contain an externally - stored part of the column value, and we cannot compare - the datas */ + if (row == NULL) { + ut_ad(ext == NULL); + return(TRUE); + } - if (col_pos == upd_field->field_no - && (row == NULL - || ind_field->prefix_len > 0 - || !dfield_datas_are_binary_equal( - dtuple_get_nth_field(row, col_no), - &(upd_field->new_val)))) { + dfield = dtuple_get_nth_field(row, col_no); - return(TRUE); + /* This treatment of column prefix indexes is loosely + based on row_build_index_entry(). */ + + if (UNIV_LIKELY(ind_field->prefix_len == 0) + || dfield_is_null(dfield)) { + /* do nothing special */ + } else if (UNIV_LIKELY_NULL(ext)) { + /* See if the column is stored externally. */ + buf = row_ext_lookup(ext, col_no, &dfield_len); + + ut_ad(col->ord_part); + + if (UNIV_LIKELY_NULL(buf)) { + if (UNIV_UNLIKELY(buf == field_ref_zero)) { + /* This should never happen, but + we try to fail safe here. */ + ut_ad(0); + return(TRUE); + } + + goto copy_dfield; } + } else if (dfield_is_ext(dfield)) { + dfield_len = dfield_get_len(dfield); + ut_a(dfield_len > BTR_EXTERN_FIELD_REF_SIZE); + dfield_len -= BTR_EXTERN_FIELD_REF_SIZE; + ut_a(dict_index_is_clust(index) + || ind_field->prefix_len <= dfield_len); + buf = dfield_get_data(dfield); +copy_dfield: + ut_a(dfield_len > 0); + dfield_copy(&dfield_ext, dfield); + dfield_set_data(&dfield_ext, buf, dfield_len); + dfield = &dfield_ext; + } + + if (!dfield_datas_are_binary_equal( + dfield, &upd_field->new_val, + ind_field->prefix_len)) { + + return(TRUE); } } @@ -1329,7 +1369,7 @@ row_upd_changes_first_fields_binary( if (col_pos == upd_field->field_no && !dfield_datas_are_binary_equal( dtuple_get_nth_field(entry, i), - &(upd_field->new_val))) { + &upd_field->new_val, 0)) { return(TRUE); } @@ -1568,8 +1608,8 @@ row_upd_sec_step( ut_ad(!dict_index_is_clust(node->index)); if (node->state == UPD_NODE_UPDATE_ALL_SEC - || row_upd_changes_ord_field_binary(node->row, node->index, - node->update)) { + || row_upd_changes_ord_field_binary(node->row, node->ext, + node->index, node->update)) { return(row_upd_sec_index_entry(node, thr)); } @@ -1973,7 +2013,8 @@ exit_func: row_upd_store_row(node); - if (row_upd_changes_ord_field_binary(node->row, index, node->update)) { + if (row_upd_changes_ord_field_binary(node->row, node->ext, index, + node->update)) { /* Update causes an ordering field (ordering fields within the B-tree) of the clustered index record to change: perform From 91df7abd36a8add4e93eabb18c78853bb8db6ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 21 Dec 2010 13:27:22 +0200 Subject: [PATCH 08/25] Bug #55284 Double BLOB free due to lock wait while updating PRIMARY KEY This bug fix requires that Bug #58912 be fixed as well (bzr revision id marko.makela@oracle.com-20101221093919-mcmmgd4zpse9567d). Otherwise, another double BLOB free could occur when InnoDB would try to perform an update-in-place as delete-and-insert-by-update-in-place. row_upd_clust_rec_by_insert(): Do not disown the externally stored columns from the old record (btr_cur_mark_extern_inherited_fields()) until after checking the foreign key constraints and successfully inserting the updated record. If a lock wait timeout occurs between the delete-marking of the old record and the insertion of the updated record, mark the columns inherited before retrying the insert. Distinguish the state UPD_NODE_INSERT_BLOB from UPD_NODE_INSERT_CLUSTERED. btr_cur_del_mark_set_clust_rec(): Replace the cursor with block,rec,index,offsets so that the offsets need not be recalculated. Assert that rec is on a clustered index leaf page. btr_cur_disown_inherited_fields(): Renamed from btr_cur_mark_extern_inherited_fields(). Use upd_get_field_by_field_no(). Assert that there are externally stored columns. Assert that a mini-transaction is passed. Remove the return status. (The only caller, row_upd_clust_rec_by_insert(), will have determined that some fields have changed ownership.) btr_cur_mark_dtuple_inherited_extern(): Rename to row_upd_clust_rec_by_insert_inherit_func() and declare as static. Add the debug parameters rec, offsets. When rec is given, assert that the off-page columns match those in the inesrt tuple and that the off-page columns are owned by the record. Assert that the non-updated off-page columns in the insert tuple are owned, and mark them inherited. row_upd_clust_rec_by_insert_inherit(): A wrapper macro for row_upd_clust_rec_by_insert_inherit_func(). row_undo_mod_upd_exist_sec(): Adjust a comment about row_upd_clust_rec_by_insert(). rb:508 approved by Jimmy Yang --- storage/innodb_plugin/ChangeLog | 6 + storage/innodb_plugin/btr/btr0cur.c | 153 +++------------ storage/innodb_plugin/include/btr0cur.h | 42 ++-- storage/innodb_plugin/include/row0upd.h | 9 +- storage/innodb_plugin/row/row0umod.c | 9 +- storage/innodb_plugin/row/row0upd.c | 246 ++++++++++++++++++------ 6 files changed, 240 insertions(+), 225 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 13e2836dc98..ce470a0c027 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-12-21 The InnoDB Team + * include/btr0cur.h, include/row0upd.h, btr/btr0cur.c, + row/row0umod.c, row/row0upd.c: + Fix Bug#55284 Double free of off-page columns due to lock wait + while updating PRIMARY KEY + 2010-12-21 The InnoDB Team * include/data0data.h, include/data0data.ic, include/row0upd.h, diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 2a26d8ffb33..c57255a25ae 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -2509,27 +2509,24 @@ ulint btr_cur_del_mark_set_clust_rec( /*===========================*/ ulint flags, /*!< in: undo logging and locking flags */ - btr_cur_t* cursor, /*!< in: cursor */ + buf_block_t* block, /*!< in/out: buffer block of the record */ + rec_t* rec, /*!< in/out: record */ + dict_index_t* index, /*!< in: clustered index of the record */ + const ulint* offsets,/*!< in: rec_get_offsets(rec) */ ibool val, /*!< in: value to set */ que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr) /*!< in: mtr */ { - dict_index_t* index; - buf_block_t* block; roll_ptr_t roll_ptr; ulint err; - rec_t* rec; page_zip_des_t* page_zip; trx_t* trx; - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); - rec = btr_cur_get_rec(cursor); - index = cursor->index; + ut_ad(dict_index_is_clust(index)); + ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); - offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); + ut_ad(buf_block_get_frame(block) == page_align(rec)); + ut_ad(page_is_leaf(page_align(rec))); #ifdef UNIV_DEBUG if (btr_cur_print_record_ops && thr) { @@ -2541,13 +2538,12 @@ btr_cur_del_mark_set_clust_rec( ut_ad(dict_index_is_clust(index)); ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); - err = lock_clust_rec_modify_check_and_lock(flags, - btr_cur_get_block(cursor), + err = lock_clust_rec_modify_check_and_lock(flags, block, rec, index, offsets, thr); if (err != DB_SUCCESS) { - goto func_exit; + return(err); } err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr, @@ -2555,11 +2551,9 @@ btr_cur_del_mark_set_clust_rec( &roll_ptr); if (err != DB_SUCCESS) { - goto func_exit; + return(err); } - block = btr_cur_get_block(cursor); - if (block->is_hashed) { rw_lock_x_lock(&btr_search_latch); } @@ -2582,10 +2576,6 @@ btr_cur_del_mark_set_clust_rec( btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, roll_ptr, mtr); -func_exit: - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } return(err); } @@ -3477,108 +3467,36 @@ btr_cur_set_ownership_of_extern_field( } /*******************************************************************//** -Marks not updated extern fields as not-owned by this record. The ownership -is transferred to the updated record which is inserted elsewhere in the +Marks non-updated off-page fields as disowned by this record. The ownership +must be transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. -@return TRUE if BLOB ownership was transferred */ +to free the field. */ UNIV_INTERN -ibool -btr_cur_mark_extern_inherited_fields( -/*=================================*/ +void +btr_cur_disown_inherited_fields( +/*============================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed part will be updated, or NULL */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const upd_t* update, /*!< in: update vector */ - mtr_t* mtr) /*!< in: mtr, or NULL if not logged */ + mtr_t* mtr) /*!< in/out: mini-transaction */ { - ulint n; - ulint j; ulint i; - ibool change_ownership = FALSE; - ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); + ut_ad(rec_offs_any_extern(offsets)); + ut_ad(mtr); - if (!rec_offs_any_extern(offsets)) { - - return(FALSE); - } - - n = rec_offs_n_fields(offsets); - - for (i = 0; i < n; i++) { - if (rec_offs_nth_extern(offsets, i)) { - - /* Check it is not in updated fields */ - - if (update) { - for (j = 0; j < upd_get_n_fields(update); - j++) { - if (upd_get_nth_field(update, j) - ->field_no == i) { - - goto updated; - } - } - } - + for (i = 0; i < rec_offs_n_fields(offsets); i++) { + if (rec_offs_nth_extern(offsets, i) + && !upd_get_field_by_field_no(update, i)) { btr_cur_set_ownership_of_extern_field( page_zip, rec, index, offsets, i, FALSE, mtr); - - change_ownership = TRUE; -updated: - ; } } - - return(change_ownership); -} - -/*******************************************************************//** -The complement of the previous function: in an update entry may inherit -some externally stored fields from a record. We must mark them as inherited -in entry, so that they are not freed in a rollback. */ -UNIV_INTERN -void -btr_cur_mark_dtuple_inherited_extern( -/*=================================*/ - dtuple_t* entry, /*!< in/out: updated entry to be - inserted to clustered index */ - const upd_t* update) /*!< in: update vector */ -{ - ulint i; - - for (i = 0; i < dtuple_get_n_fields(entry); i++) { - - dfield_t* dfield = dtuple_get_nth_field(entry, i); - byte* data; - ulint len; - ulint j; - - if (!dfield_is_ext(dfield)) { - continue; - } - - /* Check if it is in updated fields */ - - for (j = 0; j < upd_get_n_fields(update); j++) { - if (upd_get_nth_field(update, j)->field_no == i) { - - goto is_updated; - } - } - - data = dfield_get_data(dfield); - len = dfield_get_len(dfield); - data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN] - |= BTR_EXTERN_INHERITED_FLAG; - -is_updated: - ; - } } /*******************************************************************//** @@ -3616,29 +3534,6 @@ btr_cur_unmark_extern_fields( } } -/*******************************************************************//** -Marks all extern fields in a dtuple as owned by the record. */ -UNIV_INTERN -void -btr_cur_unmark_dtuple_extern_fields( -/*================================*/ - dtuple_t* entry) /*!< in/out: clustered index entry */ -{ - ulint i; - - for (i = 0; i < dtuple_get_n_fields(entry); i++) { - dfield_t* dfield = dtuple_get_nth_field(entry, i); - - if (dfield_is_ext(dfield)) { - byte* data = dfield_get_data(dfield); - ulint len = dfield_get_len(dfield); - - data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN] - &= ~BTR_EXTERN_OWNER_FLAG; - } - } -} - /*******************************************************************//** Flags the data tuple fields that are marked as extern storage in the update vector. We use this function to remember which fields we must diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index 1e1dc0f580a..b477ad0320a 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -332,10 +332,14 @@ ulint btr_cur_del_mark_set_clust_rec( /*===========================*/ ulint flags, /*!< in: undo logging and locking flags */ - btr_cur_t* cursor, /*!< in: cursor */ + buf_block_t* block, /*!< in/out: buffer block of the record */ + rec_t* rec, /*!< in/out: record */ + dict_index_t* index, /*!< in: clustered index of the record */ + const ulint* offsets,/*!< in: rec_get_offsets(rec) */ ibool val, /*!< in: value to set */ que_thr_t* thr, /*!< in: query thread */ - mtr_t* mtr); /*!< in: mtr */ + mtr_t* mtr) /*!< in: mtr */ + __attribute__((nonnull)); /***********************************************************//** Sets a secondary index record delete mark to TRUE or FALSE. @return DB_SUCCESS, DB_LOCK_WAIT, or error number */ @@ -481,40 +485,22 @@ btr_estimate_number_of_different_key_vals( /*======================================*/ dict_index_t* index); /*!< in: index */ /*******************************************************************//** -Marks not updated extern fields as not-owned by this record. The ownership -is transferred to the updated record which is inserted elsewhere in the +Marks non-updated off-page fields as disowned by this record. The ownership +must be transferred to the updated record which is inserted elsewhere in the index tree. In purge only the owner of externally stored field is allowed -to free the field. -@return TRUE if BLOB ownership was transferred */ +to free the field. */ UNIV_INTERN -ibool -btr_cur_mark_extern_inherited_fields( -/*=================================*/ +void +btr_cur_disown_inherited_fields( +/*============================*/ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed part will be updated, or NULL */ rec_t* rec, /*!< in/out: record in a clustered index */ dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const upd_t* update, /*!< in: update vector */ - mtr_t* mtr); /*!< in: mtr, or NULL if not logged */ -/*******************************************************************//** -The complement of the previous function: in an update entry may inherit -some externally stored fields from a record. We must mark them as inherited -in entry, so that they are not freed in a rollback. */ -UNIV_INTERN -void -btr_cur_mark_dtuple_inherited_extern( -/*=================================*/ - dtuple_t* entry, /*!< in/out: updated entry to be - inserted to clustered index */ - const upd_t* update); /*!< in: update vector */ -/*******************************************************************//** -Marks all extern fields in a dtuple as owned by the record. */ -UNIV_INTERN -void -btr_cur_unmark_dtuple_extern_fields( -/*================================*/ - dtuple_t* entry); /*!< in/out: clustered index entry */ + mtr_t* mtr) /*!< in/out: mini-transaction */ + __attribute__((nonnull(2,3,4,5,6))); /*******************************************************************//** Stores the fields in big_rec_vec to the tablespace and puts pointers to them in rec. The extern flags in rec will have to be set beforehand. diff --git a/storage/innodb_plugin/include/row0upd.h b/storage/innodb_plugin/include/row0upd.h index 58d7ad15ecc..b61e6b6dca1 100644 --- a/storage/innodb_plugin/include/row0upd.h +++ b/storage/innodb_plugin/include/row0upd.h @@ -465,11 +465,16 @@ struct upd_node_struct{ #define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be inserted, old record is already delete marked */ -#define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered +#define UPD_NODE_INSERT_BLOB 4 /* clustered index record should be + inserted, old record is already + delete-marked; non-updated BLOBs + should be inherited by the new record + and disowned by the old record */ +#define UPD_NODE_UPDATE_ALL_SEC 5 /* an ordering field of the clustered index record was changed, or this is a delete operation: should update all the secondary index records */ -#define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be +#define UPD_NODE_UPDATE_SOME_SEC 6 /* secondary index entries should be looked at and updated if an ordering field changed */ diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index 49c51a75f18..562f8093c38 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -676,11 +676,10 @@ row_undo_mod_upd_exist_sec( index, heap); if (UNIV_UNLIKELY(!entry)) { /* The server must have crashed in - row_upd_clust_rec_by_insert(), in - row_ins_index_entry_low() before - btr_store_big_rec_extern_fields() - has written the externally stored columns - (BLOBs) of the new clustered index entry. */ + row_upd_clust_rec_by_insert() before + the updated externally stored columns (BLOBs) + of the new clustered index entry were + written. */ /* The table must be in DYNAMIC or COMPRESSED format. REDUNDANT and COMPACT formats diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 20f31e15514..248f270bd9f 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -1616,6 +1616,91 @@ row_upd_sec_step( return(DB_SUCCESS); } +#ifdef UNIV_DEBUG +# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \ + row_upd_clust_rec_by_insert_inherit_func(rec,offsets,entry,update) +#else /* UNIV_DEBUG */ +# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \ + row_upd_clust_rec_by_insert_inherit_func(entry,update) +#endif /* UNIV_DEBUG */ +/*******************************************************************//** +Mark non-updated off-page columns inherited when the primary key is +updated. We must mark them as inherited in entry, so that they are not +freed in a rollback. A limited version of this function used to be +called btr_cur_mark_dtuple_inherited_extern(). +@return TRUE if any columns were inherited */ +static __attribute__((warn_unused_result)) +ibool +row_upd_clust_rec_by_insert_inherit_func( +/*=====================================*/ +#ifdef UNIV_DEBUG + const rec_t* rec, /*!< in: old record, or NULL */ + const ulint* offsets,/*!< in: rec_get_offsets(rec), or NULL */ +#endif /* UNIV_DEBUG */ + dtuple_t* entry, /*!< in/out: updated entry to be + inserted into the clustered index */ + const upd_t* update) /*!< in: update vector */ +{ + ibool inherit = FALSE; + ulint i; + + ut_ad(!rec == !offsets); + ut_ad(!rec || rec_offs_any_extern(offsets)); + + for (i = 0; i < dtuple_get_n_fields(entry); i++) { + dfield_t* dfield = dtuple_get_nth_field(entry, i); + byte* data; + ulint len; + + ut_ad(!offsets + || !rec_offs_nth_extern(offsets, i) + == !dfield_is_ext(dfield) + || upd_get_field_by_field_no(update, i)); + if (!dfield_is_ext(dfield) + || upd_get_field_by_field_no(update, i)) { + continue; + } + +#ifdef UNIV_DEBUG + if (UNIV_LIKELY(rec != NULL)) { + const byte* rec_data + = rec_get_nth_field(rec, offsets, i, &len); + ut_ad(len == dfield_get_len(dfield)); + ut_ad(len != UNIV_SQL_NULL); + ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE); + + rec_data += len - BTR_EXTERN_FIELD_REF_SIZE; + + /* The pointer must not be zero. */ + ut_ad(memcmp(rec_data, field_ref_zero, + BTR_EXTERN_FIELD_REF_SIZE)); + /* The BLOB must be owned. */ + ut_ad(!(rec_data[BTR_EXTERN_LEN] + & BTR_EXTERN_OWNER_FLAG)); + } +#endif /* UNIV_DEBUG */ + + len = dfield_get_len(dfield); + ut_a(len != UNIV_SQL_NULL); + ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE); + data = dfield_get_data(dfield) + len + - BTR_EXTERN_FIELD_REF_SIZE; + /* The pointer must not be zero. */ + ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)); + /* The BLOB must be owned. */ + ut_a(!(data[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG)); + + data[BTR_EXTERN_LEN] |= BTR_EXTERN_INHERITED_FLAG; + /* The BTR_EXTERN_INHERITED_FLAG only matters in + rollback. Purge will always free the extern fields of + a delete-marked row. */ + + inherit = TRUE; + } + + return(inherit); +} + /***********************************************************//** Marks the clustered index record deleted and inserts the updated version of the record to the index. This function should be used when the ordering @@ -1634,14 +1719,16 @@ row_upd_clust_rec_by_insert( a foreign key constraint */ mtr_t* mtr) /*!< in/out: mtr; gets committed here */ { - mem_heap_t* heap = NULL; + mem_heap_t* heap; btr_pcur_t* pcur; btr_cur_t* btr_cur; trx_t* trx; dict_table_t* table; dtuple_t* entry; ulint err; - ibool change_ownership = FALSE; + ibool change_ownership = FALSE; + rec_t* rec; + ulint* offsets = NULL; ut_ad(node); ut_ad(dict_index_is_clust(index)); @@ -1651,53 +1738,7 @@ row_upd_clust_rec_by_insert( pcur = node->pcur; btr_cur = btr_pcur_get_btr_cur(pcur); - if (node->state != UPD_NODE_INSERT_CLUSTERED) { - rec_t* rec; - dict_index_t* index; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets; - rec_offs_init(offsets_); - - err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, - btr_cur, TRUE, thr, mtr); - if (err != DB_SUCCESS) { - mtr_commit(mtr); - return(err); - } - - /* Mark as not-owned the externally stored fields which the new - row inherits from the delete marked record: purge should not - free those externally stored fields even if the delete marked - record is removed from the index tree, or updated. */ - - rec = btr_cur_get_rec(btr_cur); - index = dict_table_get_first_index(table); - offsets = rec_get_offsets(rec, index, offsets_, - ULINT_UNDEFINED, &heap); - change_ownership = btr_cur_mark_extern_inherited_fields( - btr_cur_get_page_zip(btr_cur), rec, index, offsets, - node->update, mtr); - if (check_ref) { - /* NOTE that the following call loses - the position of pcur ! */ - err = row_upd_check_references_constraints( - node, pcur, table, index, offsets, thr, mtr); - if (err != DB_SUCCESS) { - mtr_commit(mtr); - if (UNIV_LIKELY_NULL(heap)) { - mem_heap_free(heap); - } - return(err); - } - } - } - - mtr_commit(mtr); - - if (!heap) { - heap = mem_heap_create(500); - } - node->state = UPD_NODE_INSERT_CLUSTERED; + heap = mem_heap_create(1000); entry = row_build_index_entry(node->upd_row, node->upd_ext, index, heap); @@ -1705,23 +1746,104 @@ row_upd_clust_rec_by_insert( row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); - if (change_ownership) { - /* If we return from a lock wait, for example, we may have - extern fields marked as not-owned in entry (marked in the - if-branch above). We must unmark them, take the ownership - back. */ + switch (node->state) { + default: + ut_error; + case UPD_NODE_INSERT_BLOB: + /* A lock wait occurred in row_ins_index_entry() in + the previous invocation of this function. Mark the + off-page columns in the entry inherited. */ - btr_cur_unmark_dtuple_extern_fields(entry); + change_ownership = row_upd_clust_rec_by_insert_inherit( + NULL, NULL, entry, node->update); + ut_a(change_ownership); + /* fall through */ + case UPD_NODE_INSERT_CLUSTERED: + /* A lock wait occurred in row_ins_index_entry() in + the previous invocation of this function. */ + break; + case UPD_NODE_UPDATE_CLUSTERED: + /* This is the first invocation of the function where + we update the primary key. Delete-mark the old record + in the clustered index and prepare to insert a new entry. */ + rec = btr_cur_get_rec(btr_cur); + offsets = rec_get_offsets(rec, index, NULL, + ULINT_UNDEFINED, &heap); + ut_ad(page_rec_is_user_rec(rec)); - /* We must mark non-updated extern fields in entry as - inherited, so that a possible rollback will not free them. */ + err = btr_cur_del_mark_set_clust_rec( + BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur), + rec, index, offsets, TRUE, thr, mtr); + if (err != DB_SUCCESS) { +err_exit: + mtr_commit(mtr); + mem_heap_free(heap); + return(err); + } - btr_cur_mark_dtuple_inherited_extern(entry, node->update); + /* If the the new row inherits externally stored + fields (off-page columns a.k.a. BLOBs) from the + delete-marked old record, mark them disowned by the + old record and owned by the new entry. */ + + if (rec_offs_any_extern(offsets)) { + change_ownership = row_upd_clust_rec_by_insert_inherit( + rec, offsets, entry, node->update); + + if (change_ownership) { + btr_pcur_store_position(pcur, mtr); + } + } + + if (check_ref) { + /* NOTE that the following call loses + the position of pcur ! */ + err = row_upd_check_references_constraints( + node, pcur, table, index, offsets, thr, mtr); + if (err != DB_SUCCESS) { + goto err_exit; + } + } } + mtr_commit(mtr); + err = row_ins_index_entry(index, entry, node->upd_ext ? node->upd_ext->n_ext : 0, TRUE, thr); + node->state = change_ownership + ? UPD_NODE_INSERT_BLOB + : UPD_NODE_INSERT_CLUSTERED; + + if (err == DB_SUCCESS && change_ownership) { + /* Mark the non-updated fields disowned by the old record. */ + + /* NOTE: this transaction has an x-lock on the record + and therefore other transactions cannot modify the + record when we have no latch on the page. In addition, + we assume that other query threads of the same + transaction do not modify the record in the meantime. + Therefore we can assert that the restoration of the + cursor succeeds. */ + + mtr_start(mtr); + + if (!btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr)) { + ut_error; + } + + rec = btr_cur_get_rec(btr_cur); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); + ut_ad(page_rec_is_user_rec(rec)); + + btr_cur_disown_inherited_fields( + btr_cur_get_page_zip(btr_cur), + rec, index, offsets, node->update, mtr); + + mtr_commit(mtr); + } + mem_heap_free(heap); return(err); @@ -1865,8 +1987,9 @@ row_upd_del_mark_clust_rec( /* Mark the clustered index record deleted; we do not have to check locks, because we assume that we have an x-lock on the record */ - err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, - btr_cur, TRUE, thr, mtr); + err = btr_cur_del_mark_set_clust_rec( + BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur), + btr_cur_get_rec(btr_cur), index, offsets, TRUE, thr, mtr); if (err == DB_SUCCESS && check_ref) { /* NOTE that the following call loses the position of pcur ! */ @@ -2083,7 +2206,8 @@ row_upd( } if (node->state == UPD_NODE_UPDATE_CLUSTERED - || node->state == UPD_NODE_INSERT_CLUSTERED) { + || node->state == UPD_NODE_INSERT_CLUSTERED + || node->state == UPD_NODE_INSERT_BLOB) { log_free_check(); err = row_upd_clust_step(node, thr); From ac326735a7c7cd3712b69bb05c79966c8a9eb527 Mon Sep 17 00:00:00 2001 From: Calvin Sun Date: Mon, 27 Dec 2010 22:55:49 -0600 Subject: [PATCH 09/25] Fix a build error on Windows, introduced by revision-id: marko.makela@oracle.com-20101221112722-1yxxzzgqtem8bcm7 The fix was suggested by Jimmy. --- storage/innodb_plugin/row/row0upd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 248f270bd9f..4aa1474a25b 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -1683,8 +1683,8 @@ row_upd_clust_rec_by_insert_inherit_func( len = dfield_get_len(dfield); ut_a(len != UNIV_SQL_NULL); ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE); - data = dfield_get_data(dfield) + len - - BTR_EXTERN_FIELD_REF_SIZE; + data = dfield_get_data(dfield); + data += len - BTR_EXTERN_FIELD_REF_SIZE; /* The pointer must not be zero. */ ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE)); /* The BLOB must be owned. */ From ee12d72444beedc9b2bb7bbdb46b18f10099909b Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Fri, 31 Dec 2010 12:07:34 +0100 Subject: [PATCH 10/25] Test which runs slowly on some machines, is marked as big so will be run only weekly; this closes BUG#50595. --- mysql-test/collections/default.weekly | 2 +- .../funcs_1/r/{myisam_views.result => myisam_views-big.result} | 0 .../funcs_1/t/{myisam_views.test => myisam_views-big.test} | 3 +++ 3 files changed, 4 insertions(+), 1 deletion(-) rename mysql-test/suite/funcs_1/r/{myisam_views.result => myisam_views-big.result} (100%) rename mysql-test/suite/funcs_1/t/{myisam_views.test => myisam_views-big.test} (87%) diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly index 92750cca166..1ca79a582d2 100644 --- a/mysql-test/collections/default.weekly +++ b/mysql-test/collections/default.weekly @@ -1,2 +1,2 @@ perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st -perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.partition_alter1_2_ndb parts.part_supported_sql_func_innodb parts.partition_alter1_2_innodb parts.partition_alter4_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_ndb rpl_ndb.rpl_truncate_7ndb_2 main.archive-big main.sum_distinct-big main.mysqlbinlog_row_big main.alter_table-big main.variables-big main.type_newdecimal-big main.read_many_rows_innodb main.log_tables-big main.count_distinct3 main.events_time_zone main.merge-big main.create-big main.events_stress main.ssl-big +perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.partition_alter1_2_ndb parts.part_supported_sql_func_innodb parts.partition_alter1_2_innodb parts.partition_alter4_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_ndb rpl_ndb.rpl_truncate_7ndb_2 main.archive-big main.sum_distinct-big main.mysqlbinlog_row_big main.alter_table-big main.variables-big main.type_newdecimal-big main.read_many_rows_innodb main.log_tables-big main.count_distinct3 main.events_time_zone main.merge-big main.create-big main.events_stress main.ssl-big funcs_1.myisam_views-big diff --git a/mysql-test/suite/funcs_1/r/myisam_views.result b/mysql-test/suite/funcs_1/r/myisam_views-big.result similarity index 100% rename from mysql-test/suite/funcs_1/r/myisam_views.result rename to mysql-test/suite/funcs_1/r/myisam_views-big.result diff --git a/mysql-test/suite/funcs_1/t/myisam_views.test b/mysql-test/suite/funcs_1/t/myisam_views-big.test similarity index 87% rename from mysql-test/suite/funcs_1/t/myisam_views.test rename to mysql-test/suite/funcs_1/t/myisam_views-big.test index fe72843cfaf..21613e78b24 100644 --- a/mysql-test/suite/funcs_1/t/myisam_views.test +++ b/mysql-test/suite/funcs_1/t/myisam_views-big.test @@ -1,6 +1,9 @@ #### suite/funcs_1/t/myisam_views.test --source include/no_valgrind_without_big.inc +# because of a pair of slow Solaris Sparc machines in pb2, +# this test is marked as big: +--source include/big_test.inc # MyISAM tables should be used # From 78df8c4fbafa512edad2bd9191cce669a3ca0035 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 4 Jan 2011 14:36:37 +0100 Subject: [PATCH 11/25] Bug #50619 assert in handler::update_auto_increment This assert could be triggered if -1 was inserted into an auto increment column by a statement writing more than one row. Unless explicitly given, an interval of auto increment values is generated when a statement first needs an auto increment value. The triggered assert checks that the auto increment counter is equal to or higher than the lower bound of this interval. Generally, the auto increment counter starts at 1 and is incremented by 1 each time it is used. However, inserting an explicit value into the auto increment column, sets the auto increment counter to this value + 1 if this value is higher than the current value of the auto increment counter. This bug was triggered if the explicit value was -1. Since the value was converted to unsigned before any comparisons were made, it was found to be higher than the current vale of the auto increment counter and the counter was set to -1 + 1. This value was below the reserved interval and caused the assert to be triggered the next time the statement tried to write a row. With the patch for Bug#39828, this bug is no longer repeatable. Now, -1 + 1 is detected as an "overflow" which causes the auto increment counter to be set to ULONGLONG_MAX. This avoids hitting the assert for the next insert and causes a new interval of auto increment values to be generated. This resolves the issue. This patch therefore only contains a regression test and no code changes. Test case added to auto_increment.test. --- mysql-test/r/auto_increment.result | 19 +++++++++++++++++++ mysql-test/t/auto_increment.test | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 5fae14e2c07..edd23050294 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -497,3 +497,22 @@ SET @@SESSION.AUTO_INCREMENT_INCREMENT=default; SET @@SESSION.AUTO_INCREMENT_OFFSET=default; DROP TABLE t1; End of 5.1 tests +# +# Bug#50619 assert in handler::update_auto_increment +# +CREATE TABLE t1 (pk INT AUTO_INCREMENT, PRIMARY KEY (pk)); +INSERT INTO t1 VALUES (NULL), (-1), (NULL); +SELECT * FROM t1; +pk +-1 +1 +2 +DROP TABLE t1; +CREATE TABLE t1 (pk BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY (pk)); +INSERT INTO t1 VALUES (NULL), (18446744073709551615-1), (NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +SELECT * FROM t1; +pk +1 +18446744073709551614 +DROP TABLE t1; diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index 8ab2e6fcf31..2a621250480 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -363,3 +363,20 @@ SET @@SESSION.AUTO_INCREMENT_OFFSET=default; DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # Bug#50619 assert in handler::update_auto_increment +--echo # + +CREATE TABLE t1 (pk INT AUTO_INCREMENT, PRIMARY KEY (pk)); +# This triggered the assert +INSERT INTO t1 VALUES (NULL), (-1), (NULL); +SELECT * FROM t1; +DROP TABLE t1; + +# Check that that true overflow still gives error +CREATE TABLE t1 (pk BIGINT UNSIGNED AUTO_INCREMENT, PRIMARY KEY (pk)); +--error ER_AUTOINC_READ_FAILED +INSERT INTO t1 VALUES (NULL), (18446744073709551615-1), (NULL); +SELECT * FROM t1; +DROP TABLE t1; From 66d50854af5c48725dce724f856727d6df343a44 Mon Sep 17 00:00:00 2001 From: "kevin.lewis@oracle.com" <> Date: Tue, 4 Jan 2011 12:34:39 -0600 Subject: [PATCH 12/25] 43818 - Patch for mysql-5.1-innodb Avoid handler::info() call for three Information Schema tables; TABLE_CONSTRAINTS, KEY_COLUMN_USAGE, & REFERENTIAL_CONTRAINTS --- sql/sql_show.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ed7a8d32eb8..7eff7740fc0 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4647,9 +4647,10 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, TABLE *show_table= tables->table; KEY *key_info=show_table->key_info; uint primary_key= show_table->s->primary_key; - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | - HA_STATUS_TIME); + + // This is not needed since no statistics are displayed. + // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); + for (uint i=0 ; i < show_table->s->keys ; i++, key_info++) { if (i != primary_key && !(key_info->flags & HA_NOSAME)) @@ -4831,9 +4832,10 @@ static int get_schema_key_column_usage_record(THD *thd, TABLE *show_table= tables->table; KEY *key_info=show_table->key_info; uint primary_key= show_table->s->primary_key; - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | - HA_STATUS_TIME); + + // This is not needed since no statistics are displayed. + // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); + for (uint i=0 ; i < show_table->s->keys ; i++, key_info++) { if (i != primary_key && !(key_info->flags & HA_NOSAME)) @@ -5562,9 +5564,9 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, { List f_key_list; TABLE *show_table= tables->table; - show_table->file->info(HA_STATUS_VARIABLE | - HA_STATUS_NO_LOCK | - HA_STATUS_TIME); + + // This is not needed since no statistics are displayed. + // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); show_table->file->get_foreign_key_list(thd, &f_key_list); FOREIGN_KEY_INFO *f_key_info; From 0f412ffb59fea97cd515593e6a39ff27a1742df8 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Tue, 4 Jan 2011 22:31:46 -0800 Subject: [PATCH 13/25] Fix Bug #59157 valgrind conditional jump warning from dict_load_foreign. This is 5.1 built-in specific as the dict_table_t strcture is allocated with mem_heap_zalloc since 5.1 plugin. Approved by Sunny Bains --- storage/innobase/dict/dict0mem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c index 168771ca307..9573ea18fde 100644 --- a/storage/innobase/dict/dict0mem.c +++ b/storage/innobase/dict/dict0mem.c @@ -87,6 +87,8 @@ dict_mem_table_create( table->big_rows = 0; + table->fk_max_recusive_level = 0; + mutex_create(&table->autoinc_mutex, SYNC_DICT_AUTOINC_MUTEX); table->autoinc = 0; From 7a9120a119070ff032b388219e062279f92738b1 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Tue, 4 Jan 2011 22:44:12 -0800 Subject: [PATCH 14/25] Fix Bug #59197 double quote in field comment prevents foreign key constraint creation rb://557 Approved by Sunny Bains --- storage/innobase/dict/dict0dict.c | 2 +- storage/innodb_plugin/ChangeLog | 5 +++++ storage/innodb_plugin/dict/dict0dict.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index b52a94c3348..fda6555e082 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -2217,7 +2217,7 @@ dict_scan_to( quote = '\0'; } else if (quote) { /* Within quotes: do nothing. */ - } else if (*ptr == '`' || *ptr == '"') { + } else if (*ptr == '`' || *ptr == '"' || *ptr == '\'') { /* Starting quote: remember the quote character. */ quote = *ptr; } else { diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index ce470a0c027..cf76d0fe432 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2011-01-04 The InnoDB Team + * dict/dict0dict.c: + Fix Bug#59197 double quote in field comment prevents foreign + key constraint creation + 2010-12-21 The InnoDB Team * include/btr0cur.h, include/row0upd.h, btr/btr0cur.c, row/row0umod.c, row/row0upd.c: diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index eb3169bd176..67765555658 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -2688,7 +2688,7 @@ dict_scan_to( quote = '\0'; } else if (quote) { /* Within quotes: do nothing. */ - } else if (*ptr == '`' || *ptr == '"') { + } else if (*ptr == '`' || *ptr == '"' || *ptr == '\'') { /* Starting quote: remember the quote character. */ quote = *ptr; } else { From 616fd28c5144264c6d59c7c7686265d0f074876f Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Wed, 5 Jan 2011 12:16:07 +0530 Subject: [PATCH 15/25] Modifications in mysql-5.1 engines test suite. --- .../suite/engines/funcs/r/rpl_000015.result | 143 ++++++++++++- .../suite/engines/funcs/r/rpl_REDIRECT.result | 3 +- .../engines/funcs/r/rpl_change_master.result | 6 + .../funcs/r/rpl_empty_master_crash.result | 2 + .../engines/funcs/r/rpl_flushlog_loop.result | 41 +++- .../engines/funcs/r/rpl_loaddata_s.result | 2 +- .../suite/engines/funcs/r/rpl_log_pos.result | 28 ++- .../engines/funcs/r/rpl_rbr_to_sbr.result | 51 ++++- .../suite/engines/funcs/r/rpl_row_drop.result | 9 +- .../funcs/r/rpl_row_inexist_tbl.result | 40 +++- .../engines/funcs/r/rpl_row_until.result | 188 ++++++++++++++++-- .../engines/funcs/r/rpl_server_id1.result | 4 +- .../engines/funcs/r/rpl_server_id2.result | 3 + .../engines/funcs/r/rpl_slave_status.result | 39 ++++ .../suite/engines/funcs/r/rpl_sp.result | 2 +- .../funcs/r/rpl_switch_stm_row_mixed.result | 4 +- mysql-test/suite/engines/funcs/t/disabled.def | 89 +++++++++ .../suite/engines/funcs/t/rpl_000015.test | 26 ++- .../suite/engines/funcs/t/rpl_REDIRECT.test | 12 +- .../engines/funcs/t/rpl_change_master.test | 25 +-- .../funcs/t/rpl_empty_master_crash.test | 3 + .../engines/funcs/t/rpl_flushlog_loop.test | 7 +- .../suite/engines/funcs/t/rpl_loaddata_s.test | 4 +- .../suite/engines/funcs/t/rpl_log_pos.test | 45 ++--- .../suite/engines/funcs/t/rpl_rbr_to_sbr.test | 16 +- .../suite/engines/funcs/t/rpl_row_drop.test | 5 +- .../engines/funcs/t/rpl_row_inexist_tbl.test | 10 +- .../suite/engines/funcs/t/rpl_row_until.test | 49 ++--- .../suite/engines/funcs/t/rpl_server_id1.test | 9 +- .../suite/engines/funcs/t/rpl_server_id2.test | 3 + .../engines/funcs/t/rpl_slave_status.test | 12 +- .../funcs/t/rpl_switch_stm_row_mixed.test | 8 +- .../suite/engines/iuds/t/insert_year.test | 2 + 33 files changed, 731 insertions(+), 159 deletions(-) diff --git a/mysql-test/suite/engines/funcs/r/rpl_000015.result b/mysql-test/suite/engines/funcs/r/rpl_000015.result index 8cd48141127..eee3b505ad6 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_000015.result +++ b/mysql-test/suite/engines/funcs/r/rpl_000015.result @@ -10,25 +10,166 @@ File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000001 106 stop slave; reset slave; +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry # Master_Log_File Read_Master_Log_Pos 4 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File +Slave_IO_Running No +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 Exec_Master_Log_Pos 0 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error change master to master_host='127.0.0.1'; +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry # Master_Log_File Read_Master_Log_Pos 4 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File +Slave_IO_Running No +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 Exec_Master_Log_Pos 0 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=MASTER_PORT; +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry # Master_Log_File Read_Master_Log_Pos 4 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File +Slave_IO_Running No +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 Exec_Master_Log_Pos 0 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error start slave; +show slave status; +Slave_IO_State Waiting for master to send event +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 Master_Log_File master-bin.000001 +Read_Master_Log_Pos 106 +Relay_Log_File slave-relay-bin.000002 +Relay_Log_Pos 252 Relay_Master_Log_File master-bin.000001 -Checking that both slave threads are running. +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 106 +Relay_Log_Space 407 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error drop table if exists t1; create table t1 (n int, PRIMARY KEY(n)); insert into t1 values (10),(45),(90); diff --git a/mysql-test/suite/engines/funcs/r/rpl_REDIRECT.result b/mysql-test/suite/engines/funcs/r/rpl_REDIRECT.result index b6cb2c0e7de..7a901b65810 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_REDIRECT.result +++ b/mysql-test/suite/engines/funcs/r/rpl_REDIRECT.result @@ -4,7 +4,8 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -SHOW SLAVE STATUS;; +SHOW SLAVE STATUS; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error SHOW SLAVE HOSTS; Server_id Host Port Rpl_recovery_rank Master_id 2 127.0.0.1 SLAVE_PORT 0 1 diff --git a/mysql-test/suite/engines/funcs/r/rpl_change_master.result b/mysql-test/suite/engines/funcs/r/rpl_change_master.result index 2258a35a869..62c5ffdd4f8 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_change_master.result +++ b/mysql-test/suite/engines/funcs/r/rpl_change_master.result @@ -11,7 +11,13 @@ stop slave sql_thread; insert into t1 values(1); insert into t1 values(2); stop slave; +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 # # # master-bin.000001 No No 0 0 191 # None 0 No # No 0 0 change master to master_user='root'; +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 # # # master-bin.000001 No No 0 0 191 # None 0 No # No 0 0 start slave; select * from t1; n diff --git a/mysql-test/suite/engines/funcs/r/rpl_empty_master_crash.result b/mysql-test/suite/engines/funcs/r/rpl_empty_master_crash.result index f71411c68dd..b5e14d3adac 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_empty_master_crash.result +++ b/mysql-test/suite/engines/funcs/r/rpl_empty_master_crash.result @@ -4,6 +4,8 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error load table t1 from master; ERROR 08S01: Error connecting to master: Master is not configured load table t1 from master; diff --git a/mysql-test/suite/engines/funcs/r/rpl_flushlog_loop.result b/mysql-test/suite/engines/funcs/r/rpl_flushlog_loop.result index ef4d7797dbf..c894ad0135b 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_flushlog_loop.result +++ b/mysql-test/suite/engines/funcs/r/rpl_flushlog_loop.result @@ -17,6 +17,43 @@ let $result_pattern= '%127.0.0.1%root%slave-bin.000001%slave-bin.000001%Yes%Yes% --source include/wait_slave_status.inc flush logs; -Relay_Log_File mysqld-relay-bin.000003 -Checking that both slave threads are running. +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port SLAVE_PORT +Connect_Retry 60 +Master_Log_File slave-bin.000001 +Read_Master_Log_Pos 106 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File slave-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table # +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 106 +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error STOP SLAVE; diff --git a/mysql-test/suite/engines/funcs/r/rpl_loaddata_s.result b/mysql-test/suite/engines/funcs/r/rpl_loaddata_s.result index 779a3af9631..d858ced1352 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_loaddata_s.result +++ b/mysql-test/suite/engines/funcs/r/rpl_loaddata_s.result @@ -10,6 +10,6 @@ load data infile '../../std_data/rpl_loaddata.dat' into table test.t1; select count(*) from test.t1; count(*) 2 -show binlog events from ; +show binlog events from 106; Log_name Pos Event_type Server_id End_log_pos Info drop table test.t1; diff --git a/mysql-test/suite/engines/funcs/r/rpl_log_pos.result b/mysql-test/suite/engines/funcs/r/rpl_log_pos.result index 1b2ded26f66..f26f4350cf1 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_log_pos.result +++ b/mysql-test/suite/engines/funcs/r/rpl_log_pos.result @@ -4,23 +4,39 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +show master status; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 106 +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 106 # # master-bin.000001 Yes Yes 0 0 106 # None 0 No # No 0 0 stop slave; -change master to master_log_pos=MASTER_LOG_POS; +change master to master_log_pos=106; start slave; stop slave; -change master to master_log_pos=MASTER_LOG_POS; +change master to master_log_pos=106; +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 106 # # master-bin.000001 No No 0 0 106 # None 0 No # No 0 0 start slave; +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 106 # # master-bin.000001 Yes Yes 0 0 106 # None 0 No # No 0 0 stop slave; -# impossible position leads to an error -change master to master_log_pos=MASTER_LOG_POS; +change master to master_log_pos=177; start slave; -Last_IO_Error = Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position' +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 177 # # master-bin.000001 No Yes 0 0 177 # None 0 No # No 1236 Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position' 0 +show master status; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 106 create table if not exists t1 (n int); drop table if exists t1; create table t1 (n int); insert into t1 values (1),(2),(3); stop slave; -change master to master_log_pos=MASTER_LOG_POS; +change master to master_log_pos=206; start slave; select * from t1 ORDER BY n; n diff --git a/mysql-test/suite/engines/funcs/r/rpl_rbr_to_sbr.result b/mysql-test/suite/engines/funcs/r/rpl_rbr_to_sbr.result index ced1693bdc8..b4b04d35208 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_rbr_to_sbr.result +++ b/mysql-test/suite/engines/funcs/r/rpl_rbr_to_sbr.result @@ -14,16 +14,47 @@ MIXED MIXED CREATE TABLE t1 (a INT, b LONG); INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (3,UUID()), (4,UUID()); -show binlog events from ; +SHOW BINLOG EVENTS; **** On Slave **** -show binlog events from ; -Log_name Pos Event_type Server_id End_log_pos Info -slave-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) -slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2) -slave-bin.000001 # Query # # BEGIN -slave-bin.000001 # Table_map # # table_id: # (test.t1) -slave-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F -slave-bin.000001 # Query # # COMMIT -show binlog events from ; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error +SHOW BINLOG EVENTS; DROP TABLE IF EXISTS t1; SET GLOBAL BINLOG_FORMAT=@saved_binlog_format; diff --git a/mysql-test/suite/engines/funcs/r/rpl_row_drop.result b/mysql-test/suite/engines/funcs/r/rpl_row_drop.result index 048e07271b3..89654ebf165 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_row_drop.result +++ b/mysql-test/suite/engines/funcs/r/rpl_row_drop.result @@ -41,11 +41,12 @@ t1 t2 **** On Master **** DROP TABLE t1,t2; -show binlog events from ; +SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int) -master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int) -master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +master-bin.000001 4 Format_desc 1 106 Server ver: VERSION, Binlog ver: 4 +master-bin.000001 106 Query 1 192 use `test`; CREATE TABLE t1 (a int) +master-bin.000001 192 Query 1 278 use `test`; CREATE TABLE t2 (a int) +master-bin.000001 278 Query 1 382 use `test`; DROP TABLE `t1` /* generated by server */ SHOW TABLES; Tables_in_test t2 diff --git a/mysql-test/suite/engines/funcs/r/rpl_row_inexist_tbl.result b/mysql-test/suite/engines/funcs/r/rpl_row_inexist_tbl.result index cd7528280d0..ad192b530a7 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_row_inexist_tbl.result +++ b/mysql-test/suite/engines/funcs/r/rpl_row_inexist_tbl.result @@ -17,5 +17,43 @@ a 0 drop table t1; insert into t1 values (1); -Last_SQL_Error = Error 'Table 'test.t1' doesn't exist' on opening tables +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table test.t2 +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1146 +Last_Error Error 'Table 'test.t1' doesn't exist' on opening tables +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1146 +Last_SQL_Error Error 'Table 'test.t1' doesn't exist' on opening tables drop table t1, t2; diff --git a/mysql-test/suite/engines/funcs/r/rpl_row_until.result b/mysql-test/suite/engines/funcs/r/rpl_row_until.result index 72dd1a6a7c3..5091a9f6468 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_row_until.result +++ b/mysql-test/suite/engines/funcs/r/rpl_row_until.result @@ -12,39 +12,193 @@ create table t2(n int not null auto_increment primary key); insert into t2 values (1),(2); insert into t2 values (3),(4); drop table t2; -start slave until master_log_file='master-bin.000001', master_log_pos=MASTER_LOG_POS; +start slave until master_log_file='master-bin.000001', master_log_pos=311; select * from t1; n 1 2 3 4 -start slave until master_log_file='master-no-such-bin.000001', master_log_pos=MASTER_LOG_POS; +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition Master +Until_Log_File master-bin.000001 +Until_Log_Pos 311 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error +start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; -n -1 -2 -3 -4 -start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=RELAY_LOG_POS; +n 1 +n 2 +n 3 +n 4 +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition Master +Until_Log_File master-no-such-bin.000001 +Until_Log_Pos 291 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error +start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; select * from t2; -n -1 -2 +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition Relay +Until_Log_File slave-relay-bin.000004 +Until_Log_Pos 728 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error start slave; stop slave; -start slave until master_log_file='master-bin.000001', master_log_pos=MASTER_LOG_POS; -start slave until master_log_file='master-bin', master_log_pos=MASTER_LOG_POS; +start slave until master_log_file='master-bin.000001', master_log_pos=740; +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition Master +Until_Log_File master-bin.000001 +Until_Log_Pos 740 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error +start slave until master_log_file='master-bin', master_log_pos=561; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL -start slave until master_log_file='master-bin.000001', master_log_pos=MASTER_LOG_POS, relay_log_pos=RELAY_LOG_POS; +start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL start slave until master_log_file='master-bin.000001'; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL start slave until relay_log_file='slave-relay-bin.000002'; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL -start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=MASTER_LOG_POS; +start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL start slave sql_thread; -start slave until master_log_file='master-bin.000001', master_log_pos=MASTER_LOG_POS; +start slave until master_log_file='master-bin.000001', master_log_pos=740; Warnings: -Note 1254 Slave is already running +Level Note +Code 1254 +Message Slave is already running diff --git a/mysql-test/suite/engines/funcs/r/rpl_server_id1.result b/mysql-test/suite/engines/funcs/r/rpl_server_id1.result index 1e7108d7961..47c2a522094 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_server_id1.result +++ b/mysql-test/suite/engines/funcs/r/rpl_server_id1.result @@ -8,8 +8,10 @@ create table t1 (n int); reset master; stop slave; change master to master_port=SLAVE_PORT; +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error + 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # # 0 0 0 106 None 0 No NULL No 0 0 start slave; -Last_IO_Error = Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it). insert into t1 values (1); show status like "slave_running"; Variable_name Value diff --git a/mysql-test/suite/engines/funcs/r/rpl_server_id2.result b/mysql-test/suite/engines/funcs/r/rpl_server_id2.result index 066b563c4e8..d50814022d8 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_server_id2.result +++ b/mysql-test/suite/engines/funcs/r/rpl_server_id2.result @@ -8,6 +8,9 @@ create table t1 (n int); reset master; stop slave; change master to master_port=SLAVE_PORT; +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error + 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 106 None 0 No NULL No 0 0 start slave; insert into t1 values (1); select * from t1; diff --git a/mysql-test/suite/engines/funcs/r/rpl_slave_status.result b/mysql-test/suite/engines/funcs/r/rpl_slave_status.result index c4dc7686045..dfc82f61e68 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_slave_status.result +++ b/mysql-test/suite/engines/funcs/r/rpl_slave_status.result @@ -18,5 +18,44 @@ drop user rpl@127.0.0.1; flush privileges; stop slave; start slave; +show slave status; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User rpl +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running No +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master NULL +Master_SSL_Verify_Server_Cert No +Last_IO_Errno # +Last_IO_Error # +Last_SQL_Errno 0 +Last_SQL_Error drop table t1; drop table t1; diff --git a/mysql-test/suite/engines/funcs/r/rpl_sp.result b/mysql-test/suite/engines/funcs/r/rpl_sp.result index c7b869c32e3..efbfde15020 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_sp.result +++ b/mysql-test/suite/engines/funcs/r/rpl_sp.result @@ -176,7 +176,7 @@ end| ERROR HY000: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) set global log_bin_trust_routine_creators=1; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.6. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 '@@log_bin_trust_routine_creators' is deprecated and will be removed in a future release. Please use '@@log_bin_trust_function_creators' instead set global log_bin_trust_function_creators=0; set global log_bin_trust_function_creators=1; set global log_bin_trust_function_creators=1; diff --git a/mysql-test/suite/engines/funcs/r/rpl_switch_stm_row_mixed.result b/mysql-test/suite/engines/funcs/r/rpl_switch_stm_row_mixed.result index 61d77c0dc2a..466302000af 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_switch_stm_row_mixed.result +++ b/mysql-test/suite/engines/funcs/r/rpl_switch_stm_row_mixed.result @@ -376,7 +376,7 @@ CREATE TABLE t12 (data LONG); LOCK TABLES t12 WRITE; INSERT INTO t12 VALUES(UUID()); UNLOCK TABLES; -show binlog events from ; -show binlog events from ; +show binlog events; +show binlog events; drop database mysqltest1; set global binlog_format= @saved_binlog_format; diff --git a/mysql-test/suite/engines/funcs/t/disabled.def b/mysql-test/suite/engines/funcs/t/disabled.def index 2aca7006b4e..5b6e3f6a281 100644 --- a/mysql-test/suite/engines/funcs/t/disabled.def +++ b/mysql-test/suite/engines/funcs/t/disabled.def @@ -5,3 +5,92 @@ crash_manycolumns_string : Bug#50495 'Row size too large' for plugin, but works ix_unique_lob : Bug#52283 Innodb reports extra warnings when SELECT/WHERE is performed using invalid value ix_unique_string_length : Bug#52283 Innodb reports extra warnings when SELECT/WHERE is performed using invalid value +rpl_create_database : Result Difference Due to Change in .inc file +rpl_loaddata_m : Result Difference Due to Change in .inc file +rpl_sp_effects : Result Difference Due to Change in .inc file +rpl_variables : Result Difference Due to Change in .inc file +rpl_loaddata_s : Result Difference Due to Change in .inc file +rpl_server_id2 : Result Difference Due to Change in .inc file +rpl000010 : Result Difference Due to Change in .inc file +rpl_init_slave : Result Difference Due to Change in .inc file +rpl_dual_pos_advance : Result Difference Due to Change in .inc file +rpl_empty_master_crash : Result Difference Due to Change in .inc file +rpl000011 : Result Difference Due to Change in .inc file +rpl000013 : Result Difference Due to Change in .inc file +rpl_000015 : Result Difference Due to Change in .inc file +rpl_LD_INFILE : Result Difference Due to Change in .inc file +rpl_REDIRECT : Result Difference Due to Change in .inc file +rpl_alter : Result Difference Due to Change in .inc file +rpl_alter_db : Result Difference Due to Change in .inc file +rpl_bit : Result Difference Due to Change in .inc file +rpl_bit_npk : Result Difference Due to Change in .inc file +rpl_change_master : Result Difference Due to Change in .inc file +rpl_do_grant : Result Difference Due to Change in .inc file +rpl_drop : Result Difference Due to Change in .inc file +rpl_drop_db : Result Difference Due to Change in .inc file +rpl_flushlog_loop : Result Difference Due to Change in .inc file +rpl_get_lock : Result Difference Due to Change in .inc file +rpl_insert : Result Difference Due to Change in .inc file +rpl_insert_select : Result Difference Due to Change in .inc file +rpl_loaddata2 : Result Difference Due to Change in .inc file +rpl_loaddatalocal : Result Difference Due to Change in .inc file +rpl_loadfile : Result Difference Due to Change in .inc file +rpl_log_pos : Result Difference Due to Change in .inc file +rpl_many_optimize : Result Difference Due to Change in .inc file +rpl_master_pos_wait : Result Difference Due to Change in .inc file +rpl_misc_functions : Result Difference Due to Change in .inc file +rpl_ps : Result Difference Due to Change in .inc file +rpl_rbr_to_sbr : Result Difference Due to Change in .inc file +rpl_row_max_relay_size : Result Difference Due to Change in .inc file +rpl_server_id1 : Result Difference Due to Change in .inc file +rpl_session_var : Result Difference Due to Change in .inc file +rpl_sf : Result Difference Due to Change in .inc file +rpl_slave_status : Result Difference Due to Change in .inc file +rpl_sp004 : Result Difference Due to Change in .inc file +rpl_start_stop_slave : Result Difference Due to Change in .inc file +rpl_stm_max_relay_size : Result Difference Due to Change in .inc file +rpl_stm_mystery22 : Result Difference Due to Change in .inc file +rpl_stm_no_op : Result Difference Due to Change in .inc file +rpl_stm_reset_slave : Result Difference Due to Change in .inc file +rpl_temp_table : Result Difference Due to Change in .inc file +rpl_temporary : Result Difference Due to Change in .inc file +rpl_trigger : Result Difference Due to Change in .inc file +rpl_trunc_temp : Result Difference Due to Change in .inc file +rpl_user_variables : Result Difference Due to Change in .inc file +rpl_relayspace : Result Difference Due to Change in .inc file +rpl_multi_delete2 : Result Difference Due to Change in .inc file +rpl_view : Result Difference Due to Change in .inc file +rpl_ignore_table_update : Result Difference Due to Change in .inc file +rpl_err_ignoredtable : Result Difference Due to Change in .inc file +rpl_multi_update4 : Result Difference Due to Change in .inc file +rpl_multi_delete : Result Difference Due to Change in .inc file +rpl_ignore_grant : Result Difference Due to Change in .inc file +rpl_ignore_revoke : Result Difference Due to Change in .inc file +rpl_free_items : Result Difference Due to Change in .inc file +rpl_replicate_ignore_db : Result Difference Due to Change in .inc file +rpl000017 : Result Difference Due to Change in .inc file +rpl_skip_error : Result Difference Due to Change in .inc file +rpl_sp : Result Difference Due to Change in .inc file + +rpl_row_until : Test Present in rpl suite as well . Test Fails with table t2 not found. +rpl_loaddata_s : Test Present in rpl suite as well . Test Fails due to bin log truncation. +rpl_log_pos : Test Present in rpl suite as well . Test Fails due to bin log truncation. +rpl_row_NOW : Result Difference Due to Change in .inc file +rpl_row_USER : Result Difference Due to Change in .inc file +rpl_row_drop : Result Difference Due to Change in .inc file +rpl_row_func001 : Result Difference Due to Change in .inc file +rpl_row_reset_slave : Result Difference Due to Change in .inc file +rpl_row_sp001 : Result Difference Due to Change in .inc file +rpl_row_sp005 : Result Difference Due to Change in .inc file +rpl_row_sp008 : Result Difference Due to Change in .inc file +rpl_row_sp009 : Result Difference Due to Change in .inc file +rpl_row_sp010 : Result Difference Due to Change in .inc file +rpl_row_sp011 : Result Difference Due to Change in .inc file +rpl_row_sp012 : Result Difference Due to Change in .inc file +rpl_row_stop_middle : Result Difference Due to Change in .inc file +rpl_row_trig001 : Result Difference Due to Change in .inc file +rpl_row_trig002 : Result Difference Due to Change in .inc file +rpl_row_trig003 : Result Difference Due to Change in .inc file +rpl_row_view01 : Result Difference Due to Change in .inc file +rpl_switch_stm_row_mixed : Result Difference Due to Change in .inc file +rpl_row_inexist_tbl : Result Difference Due to Change in .inc file diff --git a/mysql-test/suite/engines/funcs/t/rpl_000015.test b/mysql-test/suite/engines/funcs/t/rpl_000015.test index 6c18e66a3a6..817ed6f407c 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_000015.test +++ b/mysql-test/suite/engines/funcs/t/rpl_000015.test @@ -11,25 +11,31 @@ save_master_pos; connection slave; stop slave; reset slave; -let $status_items= Master_Log_File, Read_Master_Log_Pos, Relay_Master_Log_File, Exec_Master_Log_Pos; -source include/show_slave_status.inc; +--vertical_results +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 5 # 8 # 9 # 23 # 33 # +show slave status; change master to master_host='127.0.0.1'; # The following needs to be cleaned up when change master is fixed -source include/show_slave_status.inc; - +--vertical_results +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 5 # 8 # 9 # 23 # 33 # +show slave status; --replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$MASTER_MYPORT; -source include/show_slave_status.inc; - +--vertical_results +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 5 # 8 # 9 # 23 # 33 # +show slave status; start slave; sync_with_master; -let $status_items= Master_Log_File, Relay_Master_Log_File; -source include/show_slave_status.inc; -source include/check_slave_is_running.inc; - --vertical_results +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 5 # 8 # 9 # 23 # 33 # +--replace_column 33 # +show slave status; connection master; --disable_warnings drop table if exists t1; diff --git a/mysql-test/suite/engines/funcs/t/rpl_REDIRECT.test b/mysql-test/suite/engines/funcs/t/rpl_REDIRECT.test index 7644b18ee7e..078d1048794 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_REDIRECT.test +++ b/mysql-test/suite/engines/funcs/t/rpl_REDIRECT.test @@ -7,11 +7,15 @@ source include/master-slave.inc; --disable_ps_protocol #first, make sure the slave has had enough time to register -sync_slave_with_master; +save_master_pos; +connection slave; +sync_with_master; #discover slaves connection master; ---query_vertical SHOW SLAVE STATUS; +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 8 # 9 # 16 # 23 # 33 # +SHOW SLAVE STATUS; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW SLAVE HOSTS; rpl_probe; @@ -21,7 +25,9 @@ enable_rpl_parse; create table t1 ( n int); insert into t1 values (1),(2),(3),(4); disable_rpl_parse; -sync_slave_with_master; +save_master_pos; +connection slave; +sync_with_master; insert into t1 values(5); connection master; enable_rpl_parse; diff --git a/mysql-test/suite/engines/funcs/t/rpl_change_master.test b/mysql-test/suite/engines/funcs/t/rpl_change_master.test index ce8c921c2ad..c031464c95e 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_change_master.test +++ b/mysql-test/suite/engines/funcs/t/rpl_change_master.test @@ -18,26 +18,13 @@ save_master_pos; connection slave; --real_sleep 3 # wait for I/O thread to have read updates stop slave; -source include/wait_for_slave_to_stop.inc; - -let $read_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); -let $exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); -if (`SELECT $read_pos = $exec_pos`) -{ - source include/show_rpl_debug_info.inc; - echo 'Read_Master_Log_Pos: $read_pos' == 'Exec_Master_Log_Pos: $exec_pos'; - die Failed because Read_Master_Log_Pos is equal to Exec_Master_Log_Pos; -} +--replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_column 1 # 7 # 8 # 9 # 23 # 33 # +show slave status; change master to master_user='root'; -let $read_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1); -let $exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); -if (`SELECT $read_pos <> $exec_pos`) -{ - source include/show_rpl_debug_info.inc; - echo 'Read_Master_Log_Pos: $read_pos' <> 'Exec_Master_Log_Pos: $exec_pos'; - die Failed because Read_Master_Log_Pos is not equal to Exec_Master_Log_Pos; -} - +--replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_column 1 # 7 # 8 # 9 # 23 # 33 # +show slave status; start slave; sync_with_master; select * from t1; diff --git a/mysql-test/suite/engines/funcs/t/rpl_empty_master_crash.test b/mysql-test/suite/engines/funcs/t/rpl_empty_master_crash.test index 863b450a6d9..707d1eca8c2 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_empty_master_crash.test +++ b/mysql-test/suite/engines/funcs/t/rpl_empty_master_crash.test @@ -1,5 +1,8 @@ source include/master-slave.inc; +--replace_column 1 # 8 # 9 # 16 # 23 # 33 # +show slave status; + # # Load table should not succeed on the master as this is not a slave # diff --git a/mysql-test/suite/engines/funcs/t/rpl_flushlog_loop.test b/mysql-test/suite/engines/funcs/t/rpl_flushlog_loop.test index 0b71817226a..2e481f5e5e7 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_flushlog_loop.test +++ b/mysql-test/suite/engines/funcs/t/rpl_flushlog_loop.test @@ -41,7 +41,8 @@ sleep 5; # # Show status of slave # ---let status_items= Relay_Log_File ---source include/show_slave_status.inc ---source include/check_slave_is_running.inc +--replace_result $SLAVE_MYPORT SLAVE_PORT +--replace_column 1 # 8 # 9 # 16 # 23 # 33 # +--vertical_results +SHOW SLAVE STATUS; STOP SLAVE; diff --git a/mysql-test/suite/engines/funcs/t/rpl_loaddata_s.test b/mysql-test/suite/engines/funcs/t/rpl_loaddata_s.test index 2dd2218eb5c..791fe84420f 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_loaddata_s.test +++ b/mysql-test/suite/engines/funcs/t/rpl_loaddata_s.test @@ -20,7 +20,9 @@ save_master_pos; connection slave; sync_with_master; select count(*) from test.t1; # check that LOAD was replicated -source include/show_binlog_events.inc; +--replace_column 2 # 5 # +--replace_regex /table_id: [0-9]+/table_id: #/ +show binlog events from 106; # should be nothing # Cleanup connection master; diff --git a/mysql-test/suite/engines/funcs/t/rpl_log_pos.test b/mysql-test/suite/engines/funcs/t/rpl_log_pos.test index e07f0d5f2a7..13083e47bcf 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_log_pos.test +++ b/mysql-test/suite/engines/funcs/t/rpl_log_pos.test @@ -11,41 +11,36 @@ # Passes with rbr no problem, removed statement include [jbm] source include/master-slave.inc; -let $master_log_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +--replace_column 3 +show master status; sync_slave_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 8 # 9 # 23 # 33 # +show slave status; stop slave; - ---replace_result $master_log_pos MASTER_LOG_POS -eval change master to master_log_pos=$master_log_pos; +change master to master_log_pos=106; start slave; sleep 5; stop slave; - ---replace_result $master_log_pos MASTER_LOG_POS -eval change master to master_log_pos=$master_log_pos; ---let $slave_param= Read_Master_Log_Pos ---let $slave_param_value= $master_log_pos ---source include/wait_for_slave_param.inc - +change master to master_log_pos=106; +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 8 # 9 # 23 # 33 # +show slave status; start slave; sleep 5; ---let $slave_param= Read_Master_Log_Pos ---let $slave_param_value= $master_log_pos ---source include/wait_for_slave_param.inc ---source include/check_slave_no_error.inc - +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 8 # 9 # 23 # 33 # +show slave status; stop slave; ---echo # impossible position leads to an error ---replace_result 177 MASTER_LOG_POS change master to master_log_pos=177; start slave; sleep 2; -let $slave_io_errno= 1236; -let $show_slave_io_error= 1; -source include/wait_for_slave_io_error.inc; +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 8 # 9 # 23 # 33 # +show slave status; connection master; - -let $master_log_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +--replace_column 3 +show master status; create table if not exists t1 (n int); drop table if exists t1; create table t1 (n int); @@ -53,9 +48,7 @@ insert into t1 values (1),(2),(3); save_master_pos; connection slave; stop slave; - ---replace_result $master_log_pos MASTER_LOG_POS -eval change master to master_log_pos=$master_log_pos; +change master to master_log_pos=206; start slave; sync_with_master; select * from t1 ORDER BY n; diff --git a/mysql-test/suite/engines/funcs/t/rpl_rbr_to_sbr.test b/mysql-test/suite/engines/funcs/t/rpl_rbr_to_sbr.test index c9d27d1ea6a..d466382dc92 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_rbr_to_sbr.test +++ b/mysql-test/suite/engines/funcs/t/rpl_rbr_to_sbr.test @@ -15,17 +15,25 @@ SELECT @@GLOBAL.BINLOG_FORMAT, @@SESSION.BINLOG_FORMAT; CREATE TABLE t1 (a INT, b LONG); INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (3,UUID()), (4,UUID()); +let $VERSION=`select version()`; +--replace_result $VERSION VERSION +--replace_column 2 # 5 # +--replace_regex /table_id: [0-9]+/table_id: #/ # Different number of binlog events are generated by different engines --disable_result_log -source include/show_binlog_events.inc; +SHOW BINLOG EVENTS; --enable_result_log sync_slave_with_master; --echo **** On Slave **** -source include/show_binlog_events.inc; - +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS +--replace_result $VERSION VERSION +--replace_column 2 # 5 # +--replace_regex /table_id: [0-9]+/table_id: #/ # Different number of binlog events are generated by different engines --disable_result_log -source include/show_binlog_events.inc; +SHOW BINLOG EVENTS; --enable_result_log --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_rbr_to_sbr_master.sql --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/rpl_rbr_to_sbr_slave.sql diff --git a/mysql-test/suite/engines/funcs/t/rpl_row_drop.test b/mysql-test/suite/engines/funcs/t/rpl_row_drop.test index d18ebc2846b..20c217a7c3a 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_row_drop.test +++ b/mysql-test/suite/engines/funcs/t/rpl_row_drop.test @@ -30,7 +30,10 @@ connection master; --echo **** On Master **** # Should drop the non-temporary table t1 and the temporary table t2 DROP TABLE t1,t2; -source include/show_binlog_events.inc; +let $VERSION=`select version()`; +--replace_result $VERSION VERSION +--replace_regex /table_id: [0-9]+/table_id: #/ +SHOW BINLOG EVENTS; SHOW TABLES; sync_slave_with_master; --echo **** On Slave **** diff --git a/mysql-test/suite/engines/funcs/t/rpl_row_inexist_tbl.test b/mysql-test/suite/engines/funcs/t/rpl_row_inexist_tbl.test index dca2894c9da..736071a8ece 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_row_inexist_tbl.test +++ b/mysql-test/suite/engines/funcs/t/rpl_row_inexist_tbl.test @@ -22,11 +22,13 @@ connection master; insert into t1 values (1); connection slave; -# slave should have stopped because can't find table t1 +# slave should have stopped because can't find table t1 +wait_for_slave_to_stop; # see if we have a good error message: ---let $slave_sql_errno= 1146 ---let $show_slave_sql_error= 1 ---source include/wait_for_slave_sql_error.inc +--replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--vertical_results +show slave status; # cleanup connection master; diff --git a/mysql-test/suite/engines/funcs/t/rpl_row_until.test b/mysql-test/suite/engines/funcs/t/rpl_row_until.test index b60734317c6..ccd9ce11637 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_row_until.test +++ b/mysql-test/suite/engines/funcs/t/rpl_row_until.test @@ -18,50 +18,44 @@ connection master; # create some events on master create table t1(n int not null auto_increment primary key); insert into t1 values (1),(2),(3),(4); -let $master_log_pos_1= query_get_value(SHOW MASTER STATUS, Position, 1); drop table t1; - create table t2(n int not null auto_increment primary key); insert into t2 values (1),(2); -let $master_log_pos_2= query_get_value(SHOW MASTER STATUS, Position, 1); insert into t2 values (3),(4); drop table t2; # try to replicate all queries until drop of t1 connection slave; ---replace_result $master_log_pos_1 MASTER_LOG_POS -eval start slave until master_log_file='master-bin.000001', master_log_pos=$master_log_pos_1; +start slave until master_log_file='master-bin.000001', master_log_pos=311; sleep 2; wait_for_slave_to_stop; # here table should be still not deleted select * from t1; ---let $slave_param= Exec_Master_Log_Pos ---let $slave_param_value= $master_log_pos_1 ---source include/check_slave_param.inc +--vertical_results +--replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_column 1 # 7 # 9 # 11 # 22 # 23 # 33 # +show slave status; # this should fail right after start ---replace_result 291 MASTER_LOG_POS start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; # again this table should be still not deleted select * from t1; sleep 2; wait_for_slave_to_stop; ---let $slave_param= Exec_Master_Log_Pos ---let $slave_param_value= $master_log_pos_1 ---source include/check_slave_param.inc +--vertical_results +--replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_column 1 # 7 # 9 # 11 # 22 # 23 # 33 # +show slave status; # try replicate all up to and not including the second insert to t2; -let $master_log_pos= $master_log_pos_2; -let $relay_log_file= slave-relay-bin.000004; ---source include/get_relay_log_pos.inc ---replace_result $relay_log_pos RELAY_LOG_POS -eval start slave until relay_log_file='$relay_log_file', relay_log_pos=$relay_log_pos; +start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; sleep 2; wait_for_slave_to_stop; select * from t2; ---let $slave_param= Exec_Master_Log_Pos ---let $slave_param_value= $master_log_pos ---source include/check_slave_param.inc +--vertical_results +--replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_column 1 # 7 # 9 # 11 # 22 # 23 # 33 # +show slave status; # clean up start slave; @@ -71,32 +65,27 @@ connection slave; sync_with_master; stop slave; ---let $exec_log_pos_1= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1) # this should stop immediately as we are already there ---replace_result $master_log_pos_2 MASTER_LOG_POS -eval start slave until master_log_file='master-bin.000001', master_log_pos=$master_log_pos_2; +start slave until master_log_file='master-bin.000001', master_log_pos=740; sleep 2; wait_for_slave_to_stop; # here the sql slave thread should be stopped ---let $slave_param= Exec_Master_Log_Pos ---let $slave_param_value= $exec_log_pos_1 ---source include/check_slave_param.inc +--vertical_results +--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 +--replace_column 1 # 7 # 9 # 22 # 23 # 33 # +show slave status; #testing various error conditions ---replace_result 561 MASTER_LOG_POS --error 1277 start slave until master_log_file='master-bin', master_log_pos=561; ---replace_result 561 MASTER_LOG_POS 12 RELAY_LOG_POS --error 1277 start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; --error 1277 start slave until master_log_file='master-bin.000001'; --error 1277 start slave until relay_log_file='slave-relay-bin.000002'; ---replace_result 561 MASTER_LOG_POS --error 1277 start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; # Warning should be given for second command start slave sql_thread; ---replace_result 740 MASTER_LOG_POS start slave until master_log_file='master-bin.000001', master_log_pos=740; diff --git a/mysql-test/suite/engines/funcs/t/rpl_server_id1.test b/mysql-test/suite/engines/funcs/t/rpl_server_id1.test index 014f38d3544..71310750b60 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_server_id1.test +++ b/mysql-test/suite/engines/funcs/t/rpl_server_id1.test @@ -12,13 +12,10 @@ reset master; stop slave; --replace_result $SLAVE_MYPORT SLAVE_PORT eval change master to master_port=$SLAVE_MYPORT; -source include/check_slave_no_error.inc; - +--replace_result $SLAVE_MYPORT SLAVE_PORT +--replace_column 16 # 18 # +show slave status; start slave; -let $slave_io_errno= 1593; -let $show_slave_io_error= 1; -source include/wait_for_slave_io_error.inc; - insert into t1 values (1); # can't MASTER_POS_WAIT(), it does not work in this weird setup # (when slave is its own master without --replicate-same-server-id) diff --git a/mysql-test/suite/engines/funcs/t/rpl_server_id2.test b/mysql-test/suite/engines/funcs/t/rpl_server_id2.test index 5b8683ecfb1..0f2eb560d18 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_server_id2.test +++ b/mysql-test/suite/engines/funcs/t/rpl_server_id2.test @@ -9,6 +9,9 @@ reset master; stop slave; --replace_result $SLAVE_MYPORT SLAVE_PORT eval change master to master_port=$SLAVE_MYPORT; +--replace_result $SLAVE_MYPORT SLAVE_PORT +--replace_column 18 # +show slave status; start slave; insert into t1 values (1); save_master_pos; diff --git a/mysql-test/suite/engines/funcs/t/rpl_slave_status.test b/mysql-test/suite/engines/funcs/t/rpl_slave_status.test index cc3fbf6abee..b3d6e49e215 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_slave_status.test +++ b/mysql-test/suite/engines/funcs/t/rpl_slave_status.test @@ -22,7 +22,9 @@ drop table if exists t1; --enable_warnings create table t1 (n int); insert into t1 values (1); -sync_slave_with_master; +save_master_pos; +connection slave; +sync_with_master; select * from t1; # 3. Delete new replication user @@ -38,8 +40,12 @@ stop slave; start slave; # 5. Make sure Slave_IO_Running = No -let $slave_io_errno= 1045; -source include/wait_for_slave_io_error.inc; +--replace_result $MASTER_MYPORT MASTER_MYPORT +# Column 1 is replaced, since the output can be either +# "Connecting to master" or "Waiting for master update" +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 35 # 36 # +--vertical_results +show slave status; # Cleanup (Note that slave IO thread is not running) connection slave; diff --git a/mysql-test/suite/engines/funcs/t/rpl_switch_stm_row_mixed.test b/mysql-test/suite/engines/funcs/t/rpl_switch_stm_row_mixed.test index eb2e2a828f3..d89765fb28d 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_switch_stm_row_mixed.test +++ b/mysql-test/suite/engines/funcs/t/rpl_switch_stm_row_mixed.test @@ -501,7 +501,9 @@ INSERT INTO t12 VALUES(UUID()); UNLOCK TABLES; --disable_result_log -source include/show_binlog_events.inc; +--replace_column 2 # 5 # +--replace_regex /table_id: [0-9]+/table_id: #/ +show binlog events; --enable_result_log sync_slave_with_master; @@ -518,7 +520,9 @@ diff_files $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql $MYSQLTEST_ connection master; --disable_result_log -source include/show_binlog_events.inc; +--replace_column 2 # 5 # +--replace_regex /table_id: [0-9]+/table_id: #/ +show binlog events; --enable_result_log # Now test that mysqlbinlog works fine on a binlog generated by the diff --git a/mysql-test/suite/engines/iuds/t/insert_year.test b/mysql-test/suite/engines/iuds/t/insert_year.test index 60a4029df18..392b4544376 100644 --- a/mysql-test/suite/engines/iuds/t/insert_year.test +++ b/mysql-test/suite/engines/iuds/t/insert_year.test @@ -226,6 +226,7 @@ SELECT * FROM t2 WHERE c1 IS NOT NULL ORDER BY c1,c2 DESC LIMIT 2; ## Full table scan ## --sorted_result SELECT * FROM t2; + --sorted_result SELECT count(*) as total_rows, min(c2) as min_value, max(c2) FROM t2; --sorted_result @@ -300,6 +301,7 @@ SELECT * FROM t2 WHERE c2 IS NOT NULL ORDER BY c1,c2 DESC LIMIT 2; ## Full table scan ## --sorted_result SELECT * FROM t2; + --sorted_result SELECT count(*) as total_rows, min(c2) as min_value, max(c2) FROM t2; --sorted_result From 48a3544a902ba943baa4628315d1ecb33e953d71 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 5 Jan 2011 14:58:05 +0200 Subject: [PATCH 16/25] Bug #59178: disable the test case --- mysql-test/suite/rpl/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 5b150288935..b5956a78371 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -12,3 +12,4 @@ rpl_row_create_table : Bug#51574 Feb 27 2010 andrei failed different way than earlier with bug#45576 rpl_log_pos : BUG#55675 Sep 10 2010 27 2010 alfranio rpl.rpl_log_pos fails sporadically with error binlog truncated in the middle +rpl_get_master_version_and_clock : Bug#59178 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock From b9f22348903f7f433cd7bb80761764eaa42cb77d Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 6 Jan 2011 09:05:45 +0200 Subject: [PATCH 17/25] (Builtin InnoDB) Fix Bug#59303 Correct URL in crash message old URL: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html new URL: http://dev.mysql.com/doc/refman/5.1/en/forcing-innodb-recovery.html Notice that there is a redirect from the old URL to the new URL, so visiting the old URL does not give "page not found" error. --- storage/innobase/btr/btr0btr.c | 2 +- storage/innobase/buf/buf0buf.c | 4 ++-- storage/innobase/fsp/fsp0fsp.c | 2 +- storage/innobase/include/buf0buf.ic | 4 ++-- storage/innobase/log/log0recv.c | 2 +- storage/innobase/row/row0mysql.c | 2 +- storage/innobase/ut/ut0dbg.c | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index b1b59227883..9438277050d 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -610,7 +610,7 @@ btr_page_get_father_for_rec( "InnoDB: corruption. If the crash happens at " "the database startup, see\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html about\n" + "forcing-innodb-recovery.html about\n" "InnoDB: forcing recovery. " "Then dump + drop + reimport.\n", stderr); } diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 500088c3901..08e033e7a63 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -334,7 +334,7 @@ buf_page_is_corrupted( "InnoDB: tablespace but not the InnoDB " "log files. See\n" "InnoDB: http://dev.mysql.com/doc/refman/" - "5.1/en/forcing-recovery.html\n" + "5.1/en/forcing-innodb-recovery.html\n" "InnoDB: for more information.\n", (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET), @@ -2067,7 +2067,7 @@ buf_page_io_complete( " table for corruption.\n" "InnoDB: See also" " http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c index 1f033c4b140..d228e683957 100644 --- a/storage/innobase/fsp/fsp0fsp.c +++ b/storage/innobase/fsp/fsp0fsp.c @@ -3046,7 +3046,7 @@ fseg_free_page_low( crash: fputs("InnoDB: Please refer to\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); ut_error; } diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index b077ff0c181..58c5fd9ef3d 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -218,7 +218,7 @@ buf_block_align( "InnoDB: corruption. If this happens in an" " InnoDB database recovery, see\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "forcing-innodb-recovery.html\n" "InnoDB: how to force recovery.\n", ptr, frame_zero, buf_pool->high_end); @@ -257,7 +257,7 @@ buf_frame_align( "InnoDB: corruption. If this happens in an" " InnoDB database recovery, see\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "forcing-innodb-recovery.html\n" "InnoDB: how to force recovery.\n", ptr, buf_pool->frame_zero, buf_pool->high_end); diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index 6e1ca58cb15..9683486238c 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1826,7 +1826,7 @@ recv_report_corrupt_log( "InnoDB: on your InnoDB tables to check that they are ok!\n" "InnoDB: If mysqld crashes after this recovery, look at\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); fflush(stderr); diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 4fdd92c7cba..cee97871470 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -552,7 +552,7 @@ handle_new_error: " after the startup or when\n" "InnoDB: you dump the tables, look at\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html" + "forcing-innodb-recovery.html" " for help.\n", stderr); } else if (err == DB_FOREIGN_EXCEED_MAX_CASCADE) { diff --git a/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c index 8c4be190d77..88be1b34d9b 100644 --- a/storage/innobase/ut/ut0dbg.c +++ b/storage/innobase/ut/ut0dbg.c @@ -58,7 +58,7 @@ ut_dbg_assertion_failed( "InnoDB: immediately after the mysqld startup, there may be\n" "InnoDB: corruption in the InnoDB tablespace. Please refer to\n" "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/" - "forcing-recovery.html\n" + "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); #if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT) ut_dbg_stop_threads = TRUE; From 00cbd03fd855f917e8010392d1c58f221d438f20 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 6 Jan 2011 09:12:53 +0200 Subject: [PATCH 18/25] (InnoDB Plugin) Fix Bug#59303 Correct URL in crash message old URL: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html new URL: http://dev.mysql.com/doc/refman/5.1/en/forcing-innodb-recovery.html Notice that there is a redirect from the old URL to the new URL, so visiting the old URL does not give "page not found" error. --- storage/innodb_plugin/btr/btr0btr.c | 2 +- storage/innodb_plugin/buf/buf0buf.c | 4 ++-- storage/innodb_plugin/fsp/fsp0fsp.c | 2 +- storage/innodb_plugin/log/log0recv.c | 2 +- storage/innodb_plugin/row/row0mysql.c | 2 +- storage/innodb_plugin/ut/ut0dbg.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index 29cd470e650..32e2caecdb8 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -663,7 +663,7 @@ btr_page_get_father_node_ptr_func( " to fix the\n" "InnoDB: corruption. If the crash happens at " "the database startup, see\n" - "InnoDB: " REFMAN "forcing-recovery.html about\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html about\n" "InnoDB: forcing recovery. " "Then dump + drop + reimport.\n", stderr); diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 65d4311b840..dac416f9472 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -375,7 +375,7 @@ buf_page_is_corrupted( "you may have copied the InnoDB\n" "InnoDB: tablespace but not the InnoDB " "log files. See\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: for more information.\n", (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET), @@ -3240,7 +3240,7 @@ corrupt: "InnoDB: TABLE to scan your" " table for corruption.\n" "InnoDB: See also " - REFMAN "forcing-recovery.html\n" + REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { diff --git a/storage/innodb_plugin/fsp/fsp0fsp.c b/storage/innodb_plugin/fsp/fsp0fsp.c index f600e96bf88..e9d24b8fdf6 100644 --- a/storage/innodb_plugin/fsp/fsp0fsp.c +++ b/storage/innodb_plugin/fsp/fsp0fsp.c @@ -3326,7 +3326,7 @@ fseg_free_page_low( "InnoDB: database!\n", (ulong) page); crash: fputs("InnoDB: Please refer to\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); ut_error; } diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index c1d12dad413..1591bb02ec2 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -2188,7 +2188,7 @@ recv_report_corrupt_log( "InnoDB: far enough in recovery! Please run CHECK TABLE\n" "InnoDB: on your InnoDB tables to check that they are ok!\n" "InnoDB: If mysqld crashes after this recovery, look at\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); fflush(stderr); diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index fa89f0c0f25..c4911400cee 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -573,7 +573,7 @@ handle_new_error: "InnoDB: If the mysqld server crashes" " after the startup or when\n" "InnoDB: you dump the tables, look at\n" - "InnoDB: " REFMAN "forcing-recovery.html" + "InnoDB: " REFMAN "forcing-innodb-recovery.html" " for help.\n", stderr); break; case DB_FOREIGN_EXCEED_MAX_CASCADE: diff --git a/storage/innodb_plugin/ut/ut0dbg.c b/storage/innodb_plugin/ut/ut0dbg.c index 4484e6c36de..7839466e16f 100644 --- a/storage/innodb_plugin/ut/ut0dbg.c +++ b/storage/innodb_plugin/ut/ut0dbg.c @@ -79,7 +79,7 @@ ut_dbg_assertion_failed( " or crashes, even\n" "InnoDB: immediately after the mysqld startup, there may be\n" "InnoDB: corruption in the InnoDB tablespace. Please refer to\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); #if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT) ut_dbg_stop_threads = TRUE; From 5db83bab285ffcd4ec35a4d059ba99460ca1cac7 Mon Sep 17 00:00:00 2001 From: Saikumar V Date: Thu, 6 Jan 2011 16:09:45 +0530 Subject: [PATCH 19/25] Adding more mtr commands to runs engine suites. --- mysql-test/collections/default.weekly | 6 ++++++ 1 file changed, 6 insertions(+) mode change 100644 => 100755 mysql-test/collections/default.weekly diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly old mode 100644 new mode 100755 index 1ca79a582d2..f10bc0776a0 --- a/mysql-test/collections/default.weekly +++ b/mysql-test/collections/default.weekly @@ -1,2 +1,8 @@ perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.partition_alter1_2_ndb parts.part_supported_sql_func_innodb parts.partition_alter1_2_innodb parts.partition_alter4_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_ndb rpl_ndb.rpl_truncate_7ndb_2 main.archive-big main.sum_distinct-big main.mysqlbinlog_row_big main.alter_table-big main.variables-big main.type_newdecimal-big main.read_many_rows_innodb main.log_tables-big main.count_distinct3 main.events_time_zone main.merge-big main.create-big main.events_stress main.ssl-big funcs_1.myisam_views-big +perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam +perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-row-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=row +perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-mixed-tests-myisam-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-myisam-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=myisam --do-test=rpl --mysqld=--binlog-format=mixed +perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-stmt-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-row-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-row-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=row +perl mysql-test-run.pl --timer --force --parallel=auto --comment=eits-rpl-binlog-mixed-tests-innodb-engine --experimental=collections/default.experimental --vardir=var-binlog-mixed-eits-tests-innodb-engine --suite=engines/iuds,engines/funcs --suite-timeout=500 --max-test-fail=0 --retry-failure=0 --mysqld=--default-storage-engine=innodb --mysqld=--innodb --do-test=rpl --mysqld=--binlog-format=mixed From 25d285ce9c7eb6443df278d02f17b3c0fc9cf340 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 6 Jan 2011 19:36:20 -0800 Subject: [PATCH 20/25] Fix Bug #55397 cannot select from innodb_trx when trx_query contains blobs that aren't strings rb://560 approved by Sunny Bains --- storage/innodb_plugin/ChangeLog | 5 +++++ storage/innodb_plugin/handler/i_s.cc | 12 ++++++++++-- storage/innodb_plugin/include/trx0i_s.h | 2 ++ storage/innodb_plugin/trx/trx0i_s.c | 3 ++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index cf76d0fe432..8eb63fe8c78 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2011-01-06 The InnoDB Team + * handler/i_s.cc, include/trx0i_s.h, trx/trx0i_s.c: + Fix Bug#55397 cannot select from innodb_trx when trx_query contains + blobs that aren't strings + 2011-01-04 The InnoDB Team * dict/dict0dict.c: Fix Bug#59197 double quote in field comment prevents foreign diff --git a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc index 9ad2d656365..24996496b0c 100644 --- a/storage/innodb_plugin/handler/i_s.cc +++ b/storage/innodb_plugin/handler/i_s.cc @@ -371,8 +371,16 @@ fill_innodb_trx_from_cache( row->trx_mysql_thread_id)); /* trx_query */ - OK(field_store_string(fields[IDX_TRX_QUERY], - row->trx_query)); + if (row->trx_query) { + /* store will do appropriate character set + conversion check */ + fields[IDX_TRX_QUERY]->store( + row->trx_query, strlen(row->trx_query), + row->trx_query_cs); + fields[IDX_TRX_QUERY]->set_notnull(); + } else { + fields[IDX_TRX_QUERY]->set_null(); + } OK(schema_table_store_record(thd, table)); } diff --git a/storage/innodb_plugin/include/trx0i_s.h b/storage/innodb_plugin/include/trx0i_s.h index 7bd4e1b88c8..48d41038ea4 100644 --- a/storage/innodb_plugin/include/trx0i_s.h +++ b/storage/innodb_plugin/include/trx0i_s.h @@ -110,6 +110,8 @@ struct i_s_trx_row_struct { /*!< thd_get_thread_id() */ const char* trx_query; /*!< MySQL statement being executed in the transaction */ + struct charset_info_st* trx_query_cs; /*!< charset encode the MySQL + statement */ }; /** This structure represents INFORMATION_SCHEMA.innodb_lock_waits row */ diff --git a/storage/innodb_plugin/trx/trx0i_s.c b/storage/innodb_plugin/trx/trx0i_s.c index 3bf5ece9b9c..267e91db22e 100644 --- a/storage/innodb_plugin/trx/trx0i_s.c +++ b/storage/innodb_plugin/trx/trx0i_s.c @@ -498,7 +498,6 @@ fill_trx_row( stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len); if (stmt != NULL) { - char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1]; if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) { @@ -512,6 +511,8 @@ fill_trx_row( cache->storage, stmt, stmt_len + 1, MAX_ALLOWED_FOR_STORAGE(cache)); + row->trx_query_cs = innobase_get_charset(trx->mysql_thd); + if (row->trx_query == NULL) { return(FALSE); From 05231aeef0accf8a2c63c0a061d53a8391caa4e6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 7 Jan 2011 11:12:22 +0200 Subject: [PATCH 21/25] Fix Bug#59327 Fix autoconf usage for innodb_plugin AC_CHECK_FUNCS(f1 f2 f3, ACTION_IF_PRESENT) ACTION_IF_PRESENT is executed if any of f1, f2 or f3 is present. Fix this misusage, we want the action to be executed if all of the functions are present. --- storage/innodb_plugin/plug.in | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/storage/innodb_plugin/plug.in b/storage/innodb_plugin/plug.in index b2af11295bc..fa793647b1f 100644 --- a/storage/innodb_plugin/plug.in +++ b/storage/innodb_plugin/plug.in @@ -139,16 +139,20 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [ ) AC_MSG_CHECKING(whether Solaris libc atomic functions are available) - # either define HAVE_IB_SOLARIS_ATOMICS or not - AC_CHECK_FUNCS(atomic_cas_ulong \ - atomic_cas_32 \ - atomic_cas_64 \ - atomic_add_long_nv \ - atomic_swap_uchar, - - AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], - [Define to 1 if Solaris libc atomic functions \ - are available]) + # Define HAVE_IB_SOLARIS_ATOMICS if _all_ of the following + # functions are present. + AC_CHECK_FUNC(atomic_add_long_nv, + AC_CHECK_FUNC(atomic_cas_32, + AC_CHECK_FUNC(atomic_cas_64, + AC_CHECK_FUNC(atomic_cas_ulong, + AC_CHECK_FUNC(atomic_swap_uchar, + AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], + [Define to 1 if Solaris libc atomic functions are available] + ) + ) + ) + ) + ) ) AC_MSG_CHECKING(whether pthread_t can be used by Solaris libc atomic functions) From c4aee1b45a7b435dc5ea55a47a79052eb6dd7bcf Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 7 Jan 2011 16:52:44 +0200 Subject: [PATCH 22/25] Followup to vasil.dimov@oracle.com-20110107091222-q23qpb5skev0j9gc Do not use nested AC_CHECK_FUNC() because they result in: ./configure: line 52688: syntax error: unexpected end of file (which happens only on some platforms and does not happen on others, I have no idea what is the reason for this) --- storage/innodb_plugin/plug.in | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/storage/innodb_plugin/plug.in b/storage/innodb_plugin/plug.in index fa793647b1f..765025149a1 100644 --- a/storage/innodb_plugin/plug.in +++ b/storage/innodb_plugin/plug.in @@ -141,19 +141,22 @@ MYSQL_PLUGIN_ACTIONS(innodb_plugin, [ AC_MSG_CHECKING(whether Solaris libc atomic functions are available) # Define HAVE_IB_SOLARIS_ATOMICS if _all_ of the following # functions are present. - AC_CHECK_FUNC(atomic_add_long_nv, - AC_CHECK_FUNC(atomic_cas_32, - AC_CHECK_FUNC(atomic_cas_64, - AC_CHECK_FUNC(atomic_cas_ulong, - AC_CHECK_FUNC(atomic_swap_uchar, - AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], - [Define to 1 if Solaris libc atomic functions are available] - ) - ) - ) - ) + AC_CHECK_FUNCS(atomic_add_long_nv \ + atomic_cas_32 \ + atomic_cas_64 \ + atomic_cas_ulong \ + atomic_swap_uchar) + + if test "${ac_cv_func_atomic_add_long_nv}" = "yes" -a \ + "${ac_cv_func_atomic_cas_32}" = "yes" -a \ + "${ac_cv_func_atomic_cas_64}" = "yes" -a \ + "${ac_cv_func_atomic_cas_ulong}" = "yes" -a \ + "${ac_cv_func_atomic_swap_uchar}" = "yes" ; then + + AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1], + [Define to 1 if Solaris libc atomic functions are available] ) - ) + fi AC_MSG_CHECKING(whether pthread_t can be used by Solaris libc atomic functions) # either define HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS or not From 78b6ca55cbc2ee278c953a00b0e5aa32511253a8 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 7 Jan 2011 16:33:36 -0200 Subject: [PATCH 23/25] Bug#51023: Mysql server crashes on SIGHUP and destroys InnoDB files From a user perspective, the problem is that a FLUSH LOGS or SIGHUP signal could end up associating the stdout and stderr to random files. In the case of this bug report, the streams would end up associated to InnoDB ibd files. The freopen(3) function is not thread-safe on FreeBSD. What this means is that if another thread calls open(2) during freopen() is executing that another thread's fd returned by open(2) may get re-associated with the file being passed to freopen(3). See FreeBSD PR number 79887 for reference: http://www.freebsd.org/cgi/query-pr.cgi?pr=79887 This problem is worked around by substituting a internal hook within the FILE structure. This avoids the loss of atomicity by not having the original fd closed before its duplicated. Patch based on the original work by Vasil Dimov. --- include/my_sys.h | 1 + mysys/my_fopen.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++- sql/log.cc | 76 ++++---------------------- 3 files changed, 146 insertions(+), 66 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 90fd78f77ba..0ac220cec31 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -664,6 +664,7 @@ extern void init_glob_errs(void); extern void wait_for_free_space(const char *filename, int errors); extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags); extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags); +extern FILE *my_freopen(const char *path, const char *mode, FILE *stream); extern int my_fclose(FILE *fd,myf MyFlags); extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags); extern int my_sync(File fd, myf my_flags); diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index 44156da6ae3..a822b63dd63 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -18,6 +18,10 @@ #include #include "mysys_err.h" +#if defined(__FreeBSD__) +extern int getosreldate(void); +#endif + static void make_ftype(char * to,int flag); /* @@ -97,8 +101,137 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) } /* my_fopen */ - /* Close a stream */ +#if defined(_WIN32) +static FILE *my_win_freopen(const char *path, FILE *stream) +{ + int handle_fd, fd= _fileno(stream); + HANDLE osfh; + + DBUG_ASSERT(filename && stream); + + /* Services don't have stdout/stderr on Windows, so _fileno returns -1. */ + if (fd < 0) + { + if (!freopen(filename, mode, stream)) + return NULL; + + fd= _fileno(stream); + } + + if ((osfh= CreateFile(path, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | + FILE_SHARE_DELETE, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) + return NULL; + + if ((handle_fd= _open_osfhandle((intptr_t)osfh, + _O_APPEND | _O_TEXT)) == -1) + { + CloseHandle(osfh); + return NULL; + } + + if (_dup2(handle_fd, fd) < 0) + { + CloseHandle(osfh); + return NULL; + } + + _close(handle_fd); + + return stream; +} + +#elif defined(__FreeBSD__) + +/* No close operation hook. */ + +static int no_close(void *cookie __attribute__((unused))) +{ + return 0; +} + +/* + A hack around a race condition in the implementation of freopen. + + The race condition steams from the fact that the current fd of + the stream is closed before its number is used to duplicate the + new file descriptor. This defeats the desired atomicity of the + close and duplicate of dup2(). + + See PR number 79887 for reference: + http://www.freebsd.org/cgi/query-pr.cgi?pr=79887 +*/ + +static FILE *my_freebsd_freopen(const char *path, const char *mode, FILE *stream) +{ + int old_fd; + FILE *result; + + flockfile(stream); + + old_fd= fileno(stream); + + /* Use a no operation close hook to avoid having the fd closed. */ + stream->_close= no_close; + + /* Relies on the implicit dup2 to close old_fd. */ + result= freopen(path, mode, stream); + + /* If successful, the _close hook was replaced. */ + + if (result == NULL) + close(old_fd); + else + funlockfile(result); + + return result; +} + +#endif + + +/** + Change the file associated with a file stream. + + @param path Path to file. + @param mode Mode of the stream. + @param stream File stream. + + @note + This function is used to redirect stdout and stderr to a file and + subsequently to close and reopen that file for log rotation. + + @retval A FILE pointer on success. Otherwise, NULL. +*/ + +FILE *my_freopen(const char *path, const char *mode, FILE *stream) +{ + FILE *result; + +#if defined(_WIN32) + result= my_win_freopen(path, mode, stream); +#elif defined(__FreeBSD__) + /* + XXX: Once the fix is ported to the stable releases, this should + be dependent upon the specific FreeBSD versions. Check at: + http://www.freebsd.org/cgi/query-pr.cgi?pr=79887 + */ + if (getosreldate() > 900027) + result= freopen(path, mode, stream); + else + result= my_freebsd_freopen(path, mode, stream); +#else + result= freopen(path, mode, stream); +#endif + + return result; +} + + +/* Close a stream */ int my_fclose(FILE *fd, myf MyFlags) { int err,file; diff --git a/sql/log.cc b/sql/log.cc index f3d3420194c..23182fa1902 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -5171,80 +5171,26 @@ void sql_perror(const char *message) } -#ifdef __WIN__ +/* + Change the file associated with two output streams. Used to + redirect stdout and stderr to a file. The streams are reopened + only for appending (writing at end of file). +*/ extern "C" my_bool reopen_fstreams(const char *filename, FILE *outstream, FILE *errstream) { - int handle_fd; - int err_fd, out_fd; - HANDLE osfh; + if (outstream && !my_freopen(filename, "a", outstream)) + return TRUE; - DBUG_ASSERT(filename && errstream); - - // Services don't have stdout/stderr on Windows, so _fileno returns -1. - err_fd= _fileno(errstream); - if (err_fd < 0) - { - if (!freopen(filename, "a+", errstream)) - return TRUE; + if (errstream && !my_freopen(filename, "a", errstream)) + return TRUE; + /* The error stream must be unbuffered. */ + if (errstream) setbuf(errstream, NULL); - err_fd= _fileno(errstream); - } - - if (outstream) - { - out_fd= _fileno(outstream); - if (out_fd < 0) - { - if (!freopen(filename, "a+", outstream)) - return TRUE; - out_fd= _fileno(outstream); - } - } - - if ((osfh= CreateFile(filename, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE | - FILE_SHARE_DELETE, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, - NULL)) == INVALID_HANDLE_VALUE) - return TRUE; - - if ((handle_fd= _open_osfhandle((intptr_t)osfh, - _O_APPEND | _O_TEXT)) == -1) - { - CloseHandle(osfh); - return TRUE; - } - - if (_dup2(handle_fd, err_fd) < 0) - { - CloseHandle(osfh); - return TRUE; - } - - if (outstream && _dup2(handle_fd, out_fd) < 0) - { - CloseHandle(osfh); - return TRUE; - } - - _close(handle_fd); - return FALSE; -} -#else -extern "C" my_bool reopen_fstreams(const char *filename, - FILE *outstream, FILE *errstream) -{ - if (outstream && !freopen(filename, "a+", outstream)) - return TRUE; - - if (errstream && !freopen(filename, "a+", errstream)) - return TRUE; return FALSE; } -#endif /* From 4c810790f74deb9a3697accc12c2756bff4dad44 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 7 Jan 2011 17:28:06 -0200 Subject: [PATCH 24/25] Bug#51023: Mysql server crashes on SIGHUP and destroys InnoDB files WIN32 compilation fixes: define ETIMEDOUT only if not available and fix typos and add a missing parameter. --- include/my_pthread.h | 4 +++- mysys/my_fopen.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index a7e4ea25064..3880511da2d 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -126,7 +126,9 @@ struct tm *gmtime_r(const time_t *timep,struct tm *tmp); void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ -#define ETIMEDOUT 145 /* Win32 doesn't have this */ +#ifndef ETIMEDOUT +#define ETIMEDOUT 145 /* Win32 might not have this */ +#endif #define getpid() GetCurrentThreadId() #define HAVE_LOCALTIME_R 1 #define _REENTRANT 1 diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index a822b63dd63..b8373ecb3ab 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -103,17 +103,17 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) #if defined(_WIN32) -static FILE *my_win_freopen(const char *path, FILE *stream) +static FILE *my_win_freopen(const char *path, const char *mode, FILE *stream) { int handle_fd, fd= _fileno(stream); HANDLE osfh; - DBUG_ASSERT(filename && stream); + DBUG_ASSERT(path && stream); /* Services don't have stdout/stderr on Windows, so _fileno returns -1. */ if (fd < 0) { - if (!freopen(filename, mode, stream)) + if (!freopen(path, mode, stream)) return NULL; fd= _fileno(stream); From 2d32d7c9a9ef68171596a511253fa4e53ac2566c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Sat, 8 Jan 2011 16:51:19 +0200 Subject: [PATCH 25/25] Increment InnoDB Plugin version from 1.0.14 to 1.0.15. InnoDB Plugin 1.0.14 has been released with MySQL 5.1.54. --- storage/innodb_plugin/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index cab3af5297e..bbff8ddf1e3 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 14 +#define INNODB_VERSION_BUGFIX 15 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins;