From 253a8df24c600ed5607dc483a868a22a4f0c85f2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Jul 2007 07:22:28 +0200 Subject: [PATCH 01/22] wait_until_ready may return greater that 1 since wait time for second node to connect is 0 --- storage/ndb/ndbapi-examples/ndbapi_async1/ndbapi_async1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/ndb/ndbapi-examples/ndbapi_async1/ndbapi_async1.cpp b/storage/ndb/ndbapi-examples/ndbapi_async1/ndbapi_async1.cpp index a195a419aaf..1f19f36d674 100644 --- a/storage/ndb/ndbapi-examples/ndbapi_async1/ndbapi_async1.cpp +++ b/storage/ndb/ndbapi-examples/ndbapi_async1/ndbapi_async1.cpp @@ -75,7 +75,7 @@ int main(int argc, char** argv) exit(-1); } - if (cluster_connection->wait_until_ready(30,0)) + if (cluster_connection->wait_until_ready(30,0) < 0) { std::cout << "Cluster was not ready within 30 secs." << std::endl; exit(-1); From 7e056fee171b2a4b6bfcbaaa73382761fa6c73f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Jul 2007 07:24:25 +0200 Subject: [PATCH 02/22] BUG#30017 log-slave-updates incorrect behavior for cluster - let the receiving injector thread decide what to do --- sql/ha_ndbcluster.cc | 50 +++++++++++++++++++++++++++---------- sql/ha_ndbcluster_binlog.cc | 13 ++++++++++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 3c64a1401cd..5c7ead196cc 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2812,10 +2812,16 @@ int ha_ndbcluster::write_row(byte *record) if (unlikely(m_slow_path)) { - if (!(thd->options & OPTION_BIN_LOG)) - op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); - else if (thd->slave_thread) + /* + ignore OPTION_BIN_LOG for slave thd. It is used to indicate + log-slave-updates option. This is instead handled in the + injector thread, by looking explicitly at the + opt_log_slave_updates flag. + */ + if (thd->slave_thread) op->setAnyValue(thd->server_id); + else if (!(thd->options & OPTION_BIN_LOG)) + op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); } m_rows_changed++; @@ -3101,10 +3107,16 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) if (unlikely(m_slow_path)) { - if (!(thd->options & OPTION_BIN_LOG)) - op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); - else if (thd->slave_thread) + /* + ignore OPTION_BIN_LOG for slave thd. It is used to indicate + log-slave-updates option. This is instead handled in the + injector thread, by looking explicitly at the + opt_log_slave_updates flag + */ + if (thd->slave_thread) op->setAnyValue(thd->server_id); + else if (!(thd->options & OPTION_BIN_LOG)) + op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); } /* Execute update operation if we are not doing a scan for update @@ -3168,12 +3180,18 @@ int ha_ndbcluster::delete_row(const byte *record) if (unlikely(m_slow_path)) { - if (!(thd->options & OPTION_BIN_LOG)) - ((NdbOperation *)trans->getLastDefinedOperation())-> - setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); - else if (thd->slave_thread) + /* + ignore OPTION_BIN_LOG for slave thd. It is used to indicate + log-slave-updates option. This is instead handled in the + injector thread, by looking explicitly at the + opt_log_slave_updates flag + */ + if (thd->slave_thread) ((NdbOperation *)trans->getLastDefinedOperation())-> setAnyValue(thd->server_id); + else if (!(thd->options & OPTION_BIN_LOG)) + ((NdbOperation *)trans->getLastDefinedOperation())-> + setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); } if (!(m_primary_key_update || m_delete_cannot_batch)) // If deleting from cursor, NoCommit will be handled in next_result @@ -3207,10 +3225,16 @@ int ha_ndbcluster::delete_row(const byte *record) if (unlikely(m_slow_path)) { - if (!(thd->options & OPTION_BIN_LOG)) - op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); - else if (thd->slave_thread) + /* + ignore OPTION_BIN_LOG for slave thd. It is used to indicate + log-slave-updates option. This is instead handled in the + injector thread, by looking explicitly at the + opt_log_slave_updates flag + */ + if (thd->slave_thread) op->setAnyValue(thd->server_id); + else if (!(thd->options & OPTION_BIN_LOG)) + op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING); } } diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 987d217873b..940af612f1c 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -114,6 +114,9 @@ NDB_SHARE *ndb_apply_status_share= 0; NDB_SHARE *ndb_schema_share= 0; pthread_mutex_t ndb_schema_share_mutex; +extern my_bool opt_log_slave_updates; +static my_bool g_ndb_log_slave_updates; + /* Schema object distribution handling */ HASH ndb_schema_objects; typedef struct st_ndb_schema_object { @@ -3297,6 +3300,14 @@ ndb_binlog_thread_handle_data_event(Ndb *ndb, NdbEventOperation *pOp, originating_server_id); return 0; } + else if (!g_ndb_log_slave_updates) + { + /* + This event comes from a slave applier since it has an originating + server id set. Since option to log slave updates is not set, skip it. + */ + return 0; + } TABLE *table= share->table; DBUG_ASSERT(trans.good()); @@ -3949,6 +3960,8 @@ restart: ! IS_NDB_BLOB_PREFIX(pOp->getEvent()->getTable()->getName())); DBUG_ASSERT(gci <= ndb_latest_received_binlog_epoch); + /* initialize some variables for this epoch */ + g_ndb_log_slave_updates= opt_log_slave_updates; i_ndb-> setReportThreshEventGCISlip(ndb_report_thresh_binlog_epoch_slip); i_ndb->setReportThreshEventFreeMem(ndb_report_thresh_binlog_mem_usage); From b50015f280f2eca4676267c79e868c2a0b511016 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jul 2007 20:24:54 +1000 Subject: [PATCH 03/22] [PATCH] BUG#26793 test: mysqld crashes in NDB on I_S query Reduce case and formalise into something we should be able to use in mysql-test-run. Index: ndb-work/mysql-test/t/ndb_bug26793.test =================================================================== mysql-test/r/ndb_bug26793.result: BUG#26793 test: mysqld crashes in NDB on I_S query mysql-test/t/ndb_bug26793.test: BUG#26793 test: mysqld crashes in NDB on I_S query --- mysql-test/r/ndb_bug26793.result | 9 +++++++++ mysql-test/t/ndb_bug26793.test | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 mysql-test/r/ndb_bug26793.result create mode 100644 mysql-test/t/ndb_bug26793.test diff --git a/mysql-test/r/ndb_bug26793.result b/mysql-test/r/ndb_bug26793.result new file mode 100644 index 00000000000..9a15841e670 --- /dev/null +++ b/mysql-test/r/ndb_bug26793.result @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE `test` ( +`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , +`t` VARCHAR( 10 ) NOT NULL +) ENGINE = ndbcluster; +delete from mysql.db where user=''; +flush privileges; +GRANT USAGE ON *.* TO user1@localhost IDENTIFIED BY 'pass'; +DROP TABLE `test`.`test`; diff --git a/mysql-test/t/ndb_bug26793.test b/mysql-test/t/ndb_bug26793.test new file mode 100644 index 00000000000..66595639c3e --- /dev/null +++ b/mysql-test/t/ndb_bug26793.test @@ -0,0 +1,33 @@ +-- source include/have_ndb.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE `test` ( +`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , +`t` VARCHAR( 10 ) NOT NULL +) ENGINE = ndbcluster; + +delete from mysql.db where user=''; + +flush privileges; + +GRANT USAGE ON *.* TO user1@localhost IDENTIFIED BY 'pass'; + +connect (user1,localhost,user1,pass,*NO-ONE*); + +disable_query_log; +disable_result_log; +let $i= 100; +while ($i) +{ +select count(*) from information_schema.tables union all select count(*) from information_schema.tables union all select count(*) from information_schema.tables; +dec $i; +} +enable_query_log; +enable_result_log; + +connect (root,localhost,root,,test); +connection root; +DROP TABLE `test`.`test`; From ffa5fb613d6078ddaef0e9476e30da557fa4ad6b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Jul 2007 20:25:05 +1000 Subject: [PATCH 04/22] [PATCH] Bug#26793 I_S query crashes in NDB If ::exteral_lock hadn't been called, we'd have no NDB object, so need to check/get one here. It looks like sql_show.cc is the only place that does this.... or at least the other places will be well hidden. Index: ndb-work/sql/ha_ndbcluster.cc =================================================================== sql/ha_ndbcluster.cc: Bug#26793 I_S query crashes in NDB --- sql/ha_ndbcluster.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 357b797ec75..03b6bcf3242 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3310,6 +3310,8 @@ int ha_ndbcluster::info(uint flag) DBUG_PRINT("info", ("HA_STATUS_AUTO")); if (m_table && table->found_next_number_field) { + if ((my_errno= check_ndb_connection())) + DBUG_RETURN(my_errno); Ndb *ndb= get_ndb(); Uint64 auto_increment_value64; From 32d29bbe861d807668d46564f25c620a2ba66f8b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 15:08:51 +1000 Subject: [PATCH 05/22] point to bugs needing to be addressed before rpl_ndb_ctype_ucs2_def can be enabled --- mysql-test/t/disabled.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 0b17e47fead..217061ee094 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -31,7 +31,7 @@ rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb faile rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly synchronization : Bug#24529 Test 'synchronization' fails on Mac pushbuild; Also on Linux 64 bit. -rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset +rpl_ndb_ctype_ucs2_def : BUG#29562, BUG#29563 and BUG#29564 # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events From 180068ddceb0e400bb22f19c10df9187b301dedb Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 17:12:53 +1000 Subject: [PATCH 06/22] save the data from mysql.db that we delete (side effect that made read_only fail) --- mysql-test/r/ndb_bug26793.result | 4 ++++ mysql-test/t/ndb_bug26793.test | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/mysql-test/r/ndb_bug26793.result b/mysql-test/r/ndb_bug26793.result index 9a15841e670..31f9763dd6b 100644 --- a/mysql-test/r/ndb_bug26793.result +++ b/mysql-test/r/ndb_bug26793.result @@ -3,7 +3,11 @@ CREATE TABLE `test` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `t` VARCHAR( 10 ) NOT NULL ) ENGINE = ndbcluster; +create table test.db_temp as select * from mysql.db where user=''; delete from mysql.db where user=''; flush privileges; GRANT USAGE ON *.* TO user1@localhost IDENTIFIED BY 'pass'; DROP TABLE `test`.`test`; +insert into mysql.db select * from test.db_temp; +drop table db_temp; +flush privileges; diff --git a/mysql-test/t/ndb_bug26793.test b/mysql-test/t/ndb_bug26793.test index 66595639c3e..4f5a78fdca4 100644 --- a/mysql-test/t/ndb_bug26793.test +++ b/mysql-test/t/ndb_bug26793.test @@ -9,6 +9,7 @@ CREATE TABLE `test` ( `t` VARCHAR( 10 ) NOT NULL ) ENGINE = ndbcluster; +create table test.db_temp as select * from mysql.db where user=''; delete from mysql.db where user=''; flush privileges; @@ -31,3 +32,7 @@ enable_result_log; connect (root,localhost,root,,test); connection root; DROP TABLE `test`.`test`; +insert into mysql.db select * from test.db_temp; +drop table db_temp; +flush privileges; + From 0e0b05ec1dd46c5cf6ed5404974710d6eef6424e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 13:58:37 -0400 Subject: [PATCH 07/22] WL#3228 (NDB) : RBR using different table defs on slave/master This patch adds the ability to store extra field metadata in the table map event. This data can include pack_length() or field_lenght() for fields such as CHAR or VARCHAR enabling developers to add code that can check for compatibilty between master and slave columns. More importantly, the extra field metadata can be used to store data from the master correctly should a VARCHAR field on the master be <= 255 bytes while the same field on the slave is > 255 bytes. ' The patch also includes the needed changes to unpack to ensure that data which is smaller on the master can be unpacked correctly on the slave. mysql-test/extra/rpl_tests/rpl_log.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to display slave status vertically. mysql-test/r/rpl_ndb_log.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_rbr_to_sbr.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_basic_11bugs.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_create_table.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_flsh_tbls.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_inexist_tbl.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_log.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_log_innodb.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_max_relay_size.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_until.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_stm_log.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the rpl_log.test modifications. mysql-test/r/rpl_truncate_7ndb.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/t/binlog_row_mix_innodb_myisam.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to coincide with changes to binlog size of table map event. mysql-test/t/rpl_row_create_table.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to coincide with changes to binlog size of table map event. mysql-test/t/rpl_row_flsh_tbls.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to coincide with changes to binlog size of table map event. sql/field.cc: WL#3228 : RBR using different table defs on slave/master This patch includes updates to the unpack() methods for the variable length fields. A new parameter was added (from_length) that is the value stored in the field_metadata of the table map from the table_def class. If the value is non-zero and less than what the field on the slave is then use the from_length else use the original value from the field on the slave. sql/field.h: WL#3228 : RBR using different table defs on slave/master This patch includes updates to the unpack() methods for the variable length fields. A new parameter was added (from_length) that is the value stored in the field_metadata of the table map from the table_def class. sql/log_event.cc: WL#3228 : RBR using different table defs on slave/master This patch adds methods to calculate the field metadata size, prepare the field metadata for writing to the binlog, and additions to the Table_map_log_event::write_body method to include the field metadata in the table map that is written to the binlog. sql/log_event.h: WL#3228 : RBR using different table defs on slave/master This patch adds method declarations and variables needed to support storing field metadata in the table map that is written to the binlog. sql/rpl_record.cc: WL#3228 : RBR using different table defs on slave/master This patch modifies the unpack_row() method to unpack fields passing in the value from the table_def class. This value is the extra field metadata stored there from the master. sql/rpl_rli.h: WL#3228 : RBR using different table defs on slave/master This patch adds a helper function to retrieve the table_def for a given table in the RPL_TABLE_LIST structure. sql/rpl_utility.cc: WL#3228 : RBR using different table defs on slave/master This patch adds a helper method that retrieves the correct size parameter for the field. This method is used to compare the size as sent by the master with that on the slave for all types of fields that can vary in size and storage requirements. sql/rpl_utility.h: WL#3228 : RBR using different table defs on slave/master This patch changes the table_def class constructor to pass in the raw data read from the table map and extract it into an array of dimension size (number of fields). It also adds a method to return the field metadata for any field. The method returns the data stored in the table map or 0 if no data was stored for that field. Lastly, a method to return the results of field->maybe_null() is included so that the slave can determine if a field that is not on the slave is null. mysql-test/r/rpl_colSize.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/t/rpl_colSize.test: WL#3228 : RBR using different table defs on slave/master This patch contains a new test designed to test the feature of having columns on the master that are smaller than what is on the slave. --- mysql-test/extra/rpl_tests/rpl_log.test | 2 +- mysql-test/r/rpl_colSize.result | 179 +++++++++++++ mysql-test/r/rpl_ndb_log.result | 8 +- mysql-test/r/rpl_rbr_to_sbr.result | 4 +- mysql-test/r/rpl_row_basic_11bugs.result | 4 +- mysql-test/r/rpl_row_create_table.result | 84 +++--- mysql-test/r/rpl_row_flsh_tbls.result | 4 +- mysql-test/r/rpl_row_inexist_tbl.result | 2 +- mysql-test/r/rpl_row_log.result | 46 +++- mysql-test/r/rpl_row_log_innodb.result | 46 +++- mysql-test/r/rpl_row_max_relay_size.result | 20 +- mysql-test/r/rpl_row_until.result | 8 +- mysql-test/r/rpl_stm_log.result | 38 ++- mysql-test/r/rpl_truncate_7ndb.result | 64 ++--- .../t/binlog_row_mix_innodb_myisam.test | 2 +- mysql-test/t/rpl_colSize.test | 216 ++++++++++++++++ mysql-test/t/rpl_row_create_table.test | 10 +- mysql-test/t/rpl_row_flsh_tbls.test | 2 +- sql/field.cc | 232 +++++++++++++++++ sql/field.h | 31 +++ sql/log_event.cc | 239 +++++++++++++++++- sql/log_event.h | 10 + sql/rpl_record.cc | 18 +- sql/rpl_rli.h | 10 + sql/rpl_utility.cc | 89 ++++--- sql/rpl_utility.h | 127 +++++++++- 26 files changed, 1316 insertions(+), 179 deletions(-) create mode 100644 mysql-test/r/rpl_colSize.result create mode 100644 mysql-test/t/rpl_colSize.test diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test index b3a0b513705..b68cebdbf64 100644 --- a/mysql-test/extra/rpl_tests/rpl_log.test +++ b/mysql-test/extra/rpl_tests/rpl_log.test @@ -108,7 +108,7 @@ show binlog events in 'slave-bin.000001' from 4; show binlog events in 'slave-bin.000002' from 4; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 8 # 9 # 16 # 23 # 33 # -show slave status; +--query_vertical show slave status; # Need to recode the following diff --git a/mysql-test/r/rpl_colSize.result b/mysql-test/r/rpl_colSize.result new file mode 100644 index 00000000000..91456742833 --- /dev/null +++ b/mysql-test/r/rpl_colSize.result @@ -0,0 +1,179 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +DROP TABLE IF EXISTS t1; +**** Testing WL#3228 changes. **** +*** Create "wider" table on slave *** +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 ( +a float (47), +b double (143,9), +c decimal (65,30), +d numeric (4,0), +e bit (32), +f char (21), +g varchar (1300), +h binary (33), +j varbinary (200), +k enum ('5','6','7', '8','9','0'), +l set ('1','2','3','4','5','6','7','8','9','0','11','12','13','14','15','16','17','18','19','21','22','23','24','25','26','27','28','29'), +m TINYBLOB, +n BLOB, +o MEDIUMBLOB, +p LONGBLOB, +q TINYTEXT, +r TEXT, +s MEDIUMTEXT, +t LONGTEXT +); +*** Create same table on master but with narrow columns *** +CREATE TABLE t1 ( +a float (44), +b double (10,3), +c decimal (10,2), +d numeric (3,0), +e bit (16), +f char (10), +g varchar (100), +h binary (20), +j varbinary (20), +k enum ('5','6','7'), +l set ('1','2','3','4','5','6','7','8','9','0'), +m TINYBLOB, +n BLOB, +o MEDIUMBLOB, +p LONGBLOB, +q TINYTEXT, +r TEXT, +s MEDIUMTEXT, +t LONGTEXT +); +RESET MASTER; +*** Start replication *** +START SLAVE; +*** Insert data on master and display it. *** +INSERT INTO t1 () VALUES ( +17.567, +2.123, +10.20, +125, +hex(64), +'TEST', +'This is a test', +'binary data', +'more binary data', +'6', +'7', +"blob 1", +"blob 2", +"blob 3", +"blob 4", +"text 1", +"text 2", +"text 3", +"text 4"); +SELECT * FROM t1 ORDER BY a; +a b c d e f g h j k l m n o p q r s t +17.567 2.123 10.20 125 # TEST This is a test # more binary data 6 7 blob 1 blob 2 blob 3 blob 4 text 1 text 2 text 3 text 4 +*** Select data from slave to compare *** +SELECT * FROM t1 ORDER BY a; +a b c d e f g h j k l m n o p q r s t +17.567 2.123000000 10.200000000000000000000000000000 125 # TEST This is a test # more binary data 6 7 blob 1 blob 2 blob 3 blob 4 text 1 text 2 text 3 text 4 +DROP TABLE t1; +Create varchar table on master +CREATE TABLE t1 ( +a VARCHAR(50), +b VARCHAR(100), +c VARCHAR(300), +d CHAR(5) +); +Alter varchar table on slave +ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(100); +ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(400); +ALTER TABLE t1 CHANGE COLUMN c c VARCHAR(500); +ALTER TABLE t1 CHANGE COLUMN d d CHAR(100); +Insert some values and select them on master +INSERT INTO t1 VALUES ("This is a test of col a.", +"This is another test of col b.", +"This is a test of the large col c.", +"Col d"); +SELECT * FROM t1; +a b c d +This is a test of col a. This is another test of col b. This is a test of the large col c. Col d +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) DEFAULT NULL, + `b` varchar(100) DEFAULT NULL, + `c` varchar(300) DEFAULT NULL, + `d` char(5) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +Insert some values and select them on slave +SELECT * FROM t1; +a b c d +This is a test of col a. This is another test of col b. This is a test of the large col c. Col d +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(100) DEFAULT NULL, + `b` varchar(400) DEFAULT NULL, + `c` varchar(500) DEFAULT NULL, + `d` char(100) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +Create bit table on master +CREATE TABLE t1 ( +a BIT(7), +b BIT(8), +c BIT(21), +d BIT(11), +e BIT(11) +); +Create bit table on slave +DROP TABLE t1; +CREATE TABLE t1 ( +a BIT(16), +b BIT(22), +c BIT(54), +d BIT(25), +e BIT(13) +); +Insert some values and select them on master +INSERT INTO t1 VALUES ( +b'1010101', +b'10101011', +b'101010110101010101111', +b'10101010101', +b'10101011111' + ); +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +BIN(a) BIN(b) BIN(c) BIN(d) BIN(e) +1010101 10101011 101010110101010101111 10101010101 10101011111 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bit(7) DEFAULT NULL, + `b` bit(8) DEFAULT NULL, + `c` bit(21) DEFAULT NULL, + `d` bit(11) DEFAULT NULL, + `e` bit(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +Insert some values and select them on master +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +BIN(a) BIN(b) BIN(c) BIN(d) BIN(e) +1010101 10101011 101010110101010101111 10101010101 10101011111 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bit(16) DEFAULT NULL, + `b` bit(22) DEFAULT NULL, + `c` bit(54) DEFAULT NULL, + `d` bit(25) DEFAULT NULL, + `e` bit(13) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +*** Cleanup *** +DROP TABLE t1; diff --git a/mysql-test/r/rpl_ndb_log.result b/mysql-test/r/rpl_ndb_log.result index db2ce27d43b..272c8dfea6d 100644 --- a/mysql-test/r/rpl_ndb_log.result +++ b/mysql-test/r/rpl_ndb_log.result @@ -88,12 +88,12 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000002 # Query 1 # COMMIT show binary logs; Log_name File_size -master-bin.000001 1775 -master-bin.000002 617 +master-bin.000001 1789 +master-bin.000002 623 start slave; show binary logs; Log_name File_size -slave-bin.000001 1870 +slave-bin.000001 1884 slave-bin.000002 202 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info @@ -128,7 +128,7 @@ slave-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F slave-bin.000002 # Query 2 # COMMIT 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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 617 # # master-bin.000002 Yes Yes # 0 0 617 # None 0 No # No +# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 623 # # master-bin.000002 Yes Yes # 0 0 623 # None 0 No # No show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_rbr_to_sbr.result b/mysql-test/r/rpl_rbr_to_sbr.result index 47adb70bcf5..175a277b744 100644 --- a/mysql-test/r/rpl_rbr_to_sbr.result +++ b/mysql-test/r/rpl_rbr_to_sbr.result @@ -28,7 +28,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 454 +Read_Master_Log_Pos 457 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -43,7 +43,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 454 +Exec_Master_Log_Pos 457 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/r/rpl_row_basic_11bugs.result b/mysql-test/r/rpl_row_basic_11bugs.result index 1025b965589..3cdaf137240 100644 --- a/mysql-test/r/rpl_row_basic_11bugs.result +++ b/mysql-test/r/rpl_row_basic_11bugs.result @@ -56,8 +56,8 @@ SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 106 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 106 Query 1 192 use `test`; CREATE TABLE t1 (a INT) -master-bin.000001 192 Table_map 1 231 table_id: # (test.t1) -master-bin.000001 231 Write_rows 1 270 table_id: # flags: STMT_END_F +master-bin.000001 192 Table_map 1 233 table_id: # (test.t1) +master-bin.000001 233 Write_rows 1 272 table_id: # flags: STMT_END_F DROP TABLE t1; ================ Test for BUG#17620 ================ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_row_create_table.result b/mysql-test/r/rpl_row_create_table.result index e76ce5b962d..84881e82702 100644 --- a/mysql-test/r/rpl_row_create_table.result +++ b/mysql-test/r/rpl_row_create_table.result @@ -127,7 +127,7 @@ NULL 5 10 NULL 6 12 CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; ERROR 23000: Duplicate entry '2' for key 'b' -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; Log_name Pos Event_type Server_id End_log_pos Info CREATE TABLE t7 (a INT, b INT UNIQUE); INSERT INTO t7 SELECT a,b FROM tt3; @@ -137,11 +137,11 @@ a b 1 2 2 4 3 6 -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; Log_name Pos Event_type Server_id End_log_pos Info -# 1098 Query # 1198 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) -# 1198 Table_map # 1238 table_id: # (test.t7) -# 1238 Write_rows # 1294 table_id: # flags: STMT_END_F +# 1100 Query # 1200 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) +# 1200 Table_map # 1242 table_id: # (test.t7) +# 1242 Write_rows # 1298 table_id: # flags: STMT_END_F SELECT * FROM t7 ORDER BY a,b; a b 1 2 @@ -154,10 +154,10 @@ INSERT INTO t7 SELECT a,b FROM tt4; ROLLBACK; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back -SHOW BINLOG EVENTS FROM 1294; +SHOW BINLOG EVENTS FROM 1298; Log_name Pos Event_type Server_id End_log_pos Info -# 1294 Table_map # 1334 table_id: # (test.t7) -# 1334 Write_rows # 1390 table_id: # flags: STMT_END_F +# 1298 Table_map # 1340 table_id: # (test.t7) +# 1340 Write_rows # 1396 table_id: # flags: STMT_END_F SELECT * FROM t7 ORDER BY a,b; a b 1 2 @@ -192,10 +192,10 @@ Create Table CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -SHOW BINLOG EVENTS FROM 1390; +SHOW BINLOG EVENTS FROM 1396; Log_name Pos Event_type Server_id End_log_pos Info -# 1390 Query # 1476 use `test`; CREATE TABLE t8 LIKE t4 -# 1476 Query # 1615 use `test`; CREATE TABLE `t9` ( +# 1396 Query # 1482 use `test`; CREATE TABLE t8 LIKE t4 +# 1482 Query # 1621 use `test`; CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) @@ -276,31 +276,31 @@ SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info # 4 Format_desc # 106 Server ver: #, Binlog ver: # # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT) -# 192 Table_map # 231 table_id: # (test.t1) -# 231 Write_rows # 275 table_id: # flags: STMT_END_F -# 275 Query # 343 use `test`; BEGIN -# 343 Query # 125 use `test`; CREATE TABLE `t2` ( +# 192 Table_map # 233 table_id: # (test.t1) +# 233 Write_rows # 277 table_id: # flags: STMT_END_F +# 277 Query # 345 use `test`; BEGIN +# 345 Query # 125 use `test`; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 468 Table_map # 164 table_id: # (test.t2) -# 507 Write_rows # 208 table_id: # flags: STMT_END_F -# 551 Xid # 578 COMMIT /* XID */ -# 578 Query # 646 use `test`; BEGIN -# 646 Query # 125 use `test`; CREATE TABLE `t3` ( +# 470 Table_map # 166 table_id: # (test.t2) +# 511 Write_rows # 210 table_id: # flags: STMT_END_F +# 555 Xid # 582 COMMIT /* XID */ +# 582 Query # 650 use `test`; BEGIN +# 650 Query # 125 use `test`; CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 771 Table_map # 164 table_id: # (test.t3) -# 810 Write_rows # 208 table_id: # flags: STMT_END_F -# 854 Xid # 881 COMMIT /* XID */ -# 881 Query # 949 use `test`; BEGIN -# 949 Query # 125 use `test`; CREATE TABLE `t4` ( +# 775 Table_map # 166 table_id: # (test.t3) +# 816 Write_rows # 210 table_id: # flags: STMT_END_F +# 860 Xid # 887 COMMIT /* XID */ +# 887 Query # 955 use `test`; BEGIN +# 955 Query # 125 use `test`; CREATE TABLE `t4` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 1074 Table_map # 164 table_id: # (test.t4) -# 1113 Write_rows # 208 table_id: # flags: STMT_END_F -# 1157 Xid # 1184 COMMIT /* XID */ -# 1184 Table_map # 1223 table_id: # (test.t1) -# 1223 Write_rows # 1267 table_id: # flags: STMT_END_F +# 1080 Table_map # 166 table_id: # (test.t4) +# 1121 Write_rows # 210 table_id: # flags: STMT_END_F +# 1165 Xid # 1192 COMMIT /* XID */ +# 1192 Table_map # 1233 table_id: # (test.t1) +# 1233 Write_rows # 1277 table_id: # flags: STMT_END_F SHOW TABLES; Tables_in_test t1 @@ -367,15 +367,15 @@ SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info # 4 Format_desc # 106 Server ver: #, Binlog ver: # # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT) -# 192 Table_map # 231 table_id: # (test.t1) -# 231 Write_rows # 275 table_id: # flags: STMT_END_F -# 275 Query # 375 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB -# 375 Query # 443 use `test`; BEGIN -# 443 Table_map # 39 table_id: # (test.t2) -# 482 Write_rows # 83 table_id: # flags: STMT_END_F -# 526 Table_map # 122 table_id: # (test.t2) -# 565 Write_rows # 161 table_id: # flags: STMT_END_F -# 604 Xid # 631 COMMIT /* XID */ +# 192 Table_map # 233 table_id: # (test.t1) +# 233 Write_rows # 277 table_id: # flags: STMT_END_F +# 277 Query # 377 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB +# 377 Query # 445 use `test`; BEGIN +# 445 Table_map # 41 table_id: # (test.t2) +# 486 Write_rows # 85 table_id: # flags: STMT_END_F +# 530 Table_map # 126 table_id: # (test.t2) +# 571 Write_rows # 165 table_id: # flags: STMT_END_F +# 610 Xid # 637 COMMIT /* XID */ SELECT * FROM t2 ORDER BY a; a 1 @@ -394,10 +394,10 @@ INSERT INTO t2 SELECT a+2 FROM tt2; ROLLBACK; SELECT * FROM t2 ORDER BY a; a -SHOW BINLOG EVENTS FROM 631; +SHOW BINLOG EVENTS FROM 637; Log_name Pos Event_type Server_id End_log_pos Info -# 631 Query # 80 use `test`; TRUNCATE TABLE t2 -# 711 Xid # 738 COMMIT /* XID */ +# 637 Query # 80 use `test`; TRUNCATE TABLE t2 +# 717 Xid # 744 COMMIT /* XID */ SELECT * FROM t2 ORDER BY a; a DROP TABLE t1,t2; diff --git a/mysql-test/r/rpl_row_flsh_tbls.result b/mysql-test/r/rpl_row_flsh_tbls.result index 942a6b83bf6..072f15cbbd3 100644 --- a/mysql-test/r/rpl_row_flsh_tbls.result +++ b/mysql-test/r/rpl_row_flsh_tbls.result @@ -12,13 +12,13 @@ create table t4 (a int); insert into t4 select * from t3; rename table t1 to t5, t2 to t1; flush no_write_to_binlog tables; -SHOW BINLOG EVENTS FROM 619 ; +SHOW BINLOG EVENTS FROM 623 ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1 select * from t3; a flush tables; -SHOW BINLOG EVENTS FROM 619 ; +SHOW BINLOG EVENTS FROM 623 ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1 master-bin.000001 # Query 1 # use `test`; flush tables diff --git a/mysql-test/r/rpl_row_inexist_tbl.result b/mysql-test/r/rpl_row_inexist_tbl.result index 4412a1fa75c..4065809a63e 100644 --- a/mysql-test/r/rpl_row_inexist_tbl.result +++ b/mysql-test/r/rpl_row_inexist_tbl.result @@ -39,7 +39,7 @@ Replicate_Wild_Ignore_Table Last_Errno 1146 Last_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1` Skip_Counter 0 -Exec_Master_Log_Pos 524 +Exec_Master_Log_Pos 530 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/r/rpl_row_log.result b/mysql-test/r/rpl_row_log.result index 9de0d3d0ebb..b8121a9c24f 100644 --- a/mysql-test/r/rpl_row_log.result +++ b/mysql-test/r/rpl_row_log.result @@ -66,13 +66,13 @@ master-bin.000002 # Table_map 1 # table_id: # (test.t2) master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F show binary logs; Log_name File_size -master-bin.000001 1260 -master-bin.000002 377 +master-bin.000001 1266 +master-bin.000002 379 start slave; show binary logs; Log_name File_size -slave-bin.000001 1358 -slave-bin.000002 278 +slave-bin.000001 1364 +slave-bin.000002 280 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 @@ -91,9 +91,41 @@ slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=MyISAM slave-bin.000002 # Table_map 1 # table_id: # (test.t2) slave-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F -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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 377 # # master-bin.000002 Yes Yes # 0 0 377 # None 0 No # No +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.000002 +Read_Master_Log_Pos 379 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000002 +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 379 +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 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_row_log_innodb.result b/mysql-test/r/rpl_row_log_innodb.result index 4d8175142b2..92bffcd9f34 100644 --- a/mysql-test/r/rpl_row_log_innodb.result +++ b/mysql-test/r/rpl_row_log_innodb.result @@ -71,13 +71,13 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000002 # Xid 1 # COMMIT /* XID */ show binary logs; Log_name File_size -master-bin.000001 1314 -master-bin.000002 404 +master-bin.000001 1320 +master-bin.000002 406 start slave; show binary logs; Log_name File_size -slave-bin.000001 1412 -slave-bin.000002 305 +slave-bin.000001 1418 +slave-bin.000002 307 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 @@ -99,9 +99,41 @@ slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=InnoDB slave-bin.000002 # Table_map 1 # table_id: # (test.t2) slave-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F slave-bin.000002 # Xid 1 # COMMIT /* XID */ -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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 404 # # master-bin.000002 Yes Yes # 0 0 404 # None 0 No # No +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.000002 +Read_Master_Log_Pos 406 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000002 +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 406 +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 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_row_max_relay_size.result b/mysql-test/r/rpl_row_max_relay_size.result index cb1692568fc..9aca60a8ad7 100644 --- a/mysql-test/r/rpl_row_max_relay_size.result +++ b/mysql-test/r/rpl_row_max_relay_size.result @@ -30,7 +30,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58668 +Read_Master_Log_Pos 60268 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -45,7 +45,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58668 +Exec_Master_Log_Pos 60268 Relay_Log_Space # Until_Condition None Until_Log_File @@ -74,7 +74,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58668 +Read_Master_Log_Pos 60268 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -89,7 +89,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58668 +Exec_Master_Log_Pos 60268 Relay_Log_Space # Until_Condition None Until_Log_File @@ -118,7 +118,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58668 +Read_Master_Log_Pos 60268 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -133,7 +133,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58668 +Exec_Master_Log_Pos 60268 Relay_Log_Space # Until_Condition None Until_Log_File @@ -201,7 +201,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58754 +Read_Master_Log_Pos 60354 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -216,7 +216,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58754 +Exec_Master_Log_Pos 60354 Relay_Log_Space # Until_Condition None Until_Log_File @@ -241,7 +241,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58830 +Read_Master_Log_Pos 60430 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -256,7 +256,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58830 +Exec_Master_Log_Pos 60430 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/r/rpl_row_until.result b/mysql-test/r/rpl_row_until.result index c691185650a..c232dfcbc9f 100644 --- a/mysql-test/r/rpl_row_until.result +++ b/mysql-test/r/rpl_row_until.result @@ -21,7 +21,7 @@ n 4 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-bin.000001 311 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 # No 0 0 317 # Master master-bin.000001 311 No # No start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n @@ -31,7 +31,7 @@ n 4 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-no-such-bin.000001 291 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 # No 0 0 317 # Master master-no-such-bin.000001 291 No # No start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; select * from t2; n @@ -39,13 +39,13 @@ n 2 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 590 # Relay slave-relay-bin.000004 728 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 # No 0 0 594 # Relay slave-relay-bin.000004 728 No # No start slave; stop slave; start slave until master_log_file='master-bin.000001', master_log_pos=740; 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 744 # Master master-bin.000001 740 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 750 # Master master-bin.000001 740 No # No 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=561, relay_log_pos=12; diff --git a/mysql-test/r/rpl_stm_log.result b/mysql-test/r/rpl_stm_log.result index 3ee2d990159..07f66475e56 100644 --- a/mysql-test/r/rpl_stm_log.result +++ b/mysql-test/r/rpl_stm_log.result @@ -89,9 +89,41 @@ Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=MyISAM slave-bin.000002 # Query 1 # use `test`; insert into t2 values (1) -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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 392 # # master-bin.000002 Yes Yes # 0 0 392 # None 0 No # No +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.000002 +Read_Master_Log_Pos 392 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000002 +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 392 +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 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_truncate_7ndb.result b/mysql-test/r/rpl_truncate_7ndb.result index 62ace911e45..0b3b655b0aa 100644 --- a/mysql-test/r/rpl_truncate_7ndb.result +++ b/mysql-test/r/rpl_truncate_7ndb.result @@ -32,14 +32,14 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 106 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 106 Query 1 223 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB master-bin.000001 223 Query 1 287 BEGIN -master-bin.000001 287 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 327 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 385 Write_rows 1 157 table_id: # -master-bin.000001 444 Write_rows 1 195 table_id: # -master-bin.000001 482 Write_rows 1 233 table_id: # flags: STMT_END_F -master-bin.000001 520 Query 1 585 COMMIT -master-bin.000001 585 Query 1 665 use `test`; TRUNCATE TABLE t1 -master-bin.000001 665 Query 1 741 use `test`; DROP TABLE t1 +master-bin.000001 287 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 330 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 392 Write_rows 1 164 table_id: # +master-bin.000001 451 Write_rows 1 202 table_id: # +master-bin.000001 489 Write_rows 1 240 table_id: # flags: STMT_END_F +master-bin.000001 527 Query 1 592 COMMIT +master-bin.000001 592 Query 1 672 use `test`; TRUNCATE TABLE t1 +master-bin.000001 672 Query 1 748 use `test`; DROP TABLE t1 **** On Master **** CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB; INSERT INTO t1 VALUES (1,1), (2,2); @@ -69,27 +69,27 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 106 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 106 Query 1 223 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB master-bin.000001 223 Query 1 287 BEGIN -master-bin.000001 287 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 327 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 385 Write_rows 1 157 table_id: # -master-bin.000001 444 Write_rows 1 195 table_id: # -master-bin.000001 482 Write_rows 1 233 table_id: # flags: STMT_END_F -master-bin.000001 520 Query 1 585 COMMIT -master-bin.000001 585 Query 1 665 use `test`; TRUNCATE TABLE t1 -master-bin.000001 665 Query 1 741 use `test`; DROP TABLE t1 -master-bin.000001 741 Query 1 858 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB -master-bin.000001 858 Query 1 922 BEGIN -master-bin.000001 922 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 962 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 1020 Write_rows 1 157 table_id: # -master-bin.000001 1079 Write_rows 1 195 table_id: # -master-bin.000001 1117 Write_rows 1 233 table_id: # flags: STMT_END_F -master-bin.000001 1155 Query 1 1220 COMMIT -master-bin.000001 1220 Query 1 1284 BEGIN -master-bin.000001 1284 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 1324 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 1382 Write_rows 1 157 table_id: # -master-bin.000001 1441 Delete_rows 1 191 table_id: # -master-bin.000001 1475 Delete_rows 1 225 table_id: # flags: STMT_END_F -master-bin.000001 1509 Query 1 1574 COMMIT -master-bin.000001 1574 Query 1 1650 use `test`; DROP TABLE t1 +master-bin.000001 287 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 330 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 392 Write_rows 1 164 table_id: # +master-bin.000001 451 Write_rows 1 202 table_id: # +master-bin.000001 489 Write_rows 1 240 table_id: # flags: STMT_END_F +master-bin.000001 527 Query 1 592 COMMIT +master-bin.000001 592 Query 1 672 use `test`; TRUNCATE TABLE t1 +master-bin.000001 672 Query 1 748 use `test`; DROP TABLE t1 +master-bin.000001 748 Query 1 865 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB +master-bin.000001 865 Query 1 929 BEGIN +master-bin.000001 929 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 972 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 1034 Write_rows 1 164 table_id: # +master-bin.000001 1093 Write_rows 1 202 table_id: # +master-bin.000001 1131 Write_rows 1 240 table_id: # flags: STMT_END_F +master-bin.000001 1169 Query 1 1234 COMMIT +master-bin.000001 1234 Query 1 1298 BEGIN +master-bin.000001 1298 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 1341 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 1403 Write_rows 1 164 table_id: # +master-bin.000001 1462 Delete_rows 1 198 table_id: # +master-bin.000001 1496 Delete_rows 1 232 table_id: # flags: STMT_END_F +master-bin.000001 1530 Query 1 1595 COMMIT +master-bin.000001 1595 Query 1 1671 use `test`; DROP TABLE t1 diff --git a/mysql-test/t/binlog_row_mix_innodb_myisam.test b/mysql-test/t/binlog_row_mix_innodb_myisam.test index 335a05be146..03475f5bf3b 100644 --- a/mysql-test/t/binlog_row_mix_innodb_myisam.test +++ b/mysql-test/t/binlog_row_mix_innodb_myisam.test @@ -20,7 +20,7 @@ # ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction # and does not make slave to stop) flush logs; ---exec $MYSQL_BINLOG --start-position=520 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output +--exec $MYSQL_BINLOG --start-position=524 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output")) diff --git a/mysql-test/t/rpl_colSize.test b/mysql-test/t/rpl_colSize.test new file mode 100644 index 00000000000..44fb878d4d2 --- /dev/null +++ b/mysql-test/t/rpl_colSize.test @@ -0,0 +1,216 @@ +################################################################## +# rpl_colSize # +# # +# This test is designed to test the changes included in WL#3228. # +# The changes include the ability to replicate with the master # +# having columns that are smaller (shorter) than the slave. # +################################################################## + +-- source include/master-slave.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo **** Testing WL#3228 changes. **** +--echo *** Create "wider" table on slave *** +sync_slave_with_master; +STOP SLAVE; +RESET SLAVE; + +eval CREATE TABLE t1 ( + a float (47), + b double (143,9), + c decimal (65,30), + d numeric (4,0), + e bit (32), + f char (21), + g varchar (1300), + h binary (33), + j varbinary (200), + k enum ('5','6','7', '8','9','0'), + l set ('1','2','3','4','5','6','7','8','9','0','11','12','13','14','15','16','17','18','19','21','22','23','24','25','26','27','28','29'), + m TINYBLOB, + n BLOB, + o MEDIUMBLOB, + p LONGBLOB, + q TINYTEXT, + r TEXT, + s MEDIUMTEXT, + t LONGTEXT +); + +--echo *** Create same table on master but with narrow columns *** +connection master; +eval CREATE TABLE t1 ( + a float (44), + b double (10,3), + c decimal (10,2), + d numeric (3,0), + e bit (16), + f char (10), + g varchar (100), + h binary (20), + j varbinary (20), + k enum ('5','6','7'), + l set ('1','2','3','4','5','6','7','8','9','0'), + m TINYBLOB, + n BLOB, + o MEDIUMBLOB, + p LONGBLOB, + q TINYTEXT, + r TEXT, + s MEDIUMTEXT, + t LONGTEXT +); + +RESET MASTER; + +--echo *** Start replication *** +connection slave; +START SLAVE; + +--echo *** Insert data on master and display it. *** +connection master; + +INSERT INTO t1 () VALUES ( + 17.567, + 2.123, + 10.20, + 125, + hex(64), + 'TEST', + 'This is a test', + 'binary data', + 'more binary data', + '6', + '7', + "blob 1", + "blob 2", + "blob 3", + "blob 4", + "text 1", + "text 2", + "text 3", + "text 4"); + +# Replace values in columns that display differently between SBR & RBR +--replace_column 5 # 8 # +SELECT * FROM t1 ORDER BY a; + +--echo *** Select data from slave to compare *** +sync_slave_with_master; +connection slave; + +# Replace values in columns that display differently between SBR & RBR +--replace_column 5 # 8 # +SELECT * FROM t1 ORDER BY a; + +# Test boundary limits of varchar and char fields +# Master/Slave +# <256/<256 with m < s, m > s, and m == s <-- col a +# >255/<256 with m < s, m > s, and m == s <-- error will be caught in BUG#22086 +# <256/>255 with m < s, m > s, and m == s <-- col b +# >255/>255 with m < s, m > s, and m == s <-- col c +# +# Test boundary limits of CHAR fields +# Master/Slave +# <256/<256 with m < s, m > s, and m == s <-- col d +# >255/<256 with m < s, m > s, and m == s <-- error char limited to 255 chars +# <256/>255 with m < s, m > s, and m == s <-- error char limited to 255 chars +# >255/>255 with m < s, m > s, and m == s <-- error char limited to 255 chars + +connection master; +DROP TABLE t1; + +--echo Create varchar table on master +CREATE TABLE t1 ( + a VARCHAR(50), + b VARCHAR(100), + c VARCHAR(300), + d CHAR(5) +); + +sync_slave_with_master slave; + +--echo Alter varchar table on slave +ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(100); +ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(400); +ALTER TABLE t1 CHANGE COLUMN c c VARCHAR(500); +ALTER TABLE t1 CHANGE COLUMN d d CHAR(100); + +connection master; + +--echo Insert some values and select them on master +INSERT INTO t1 VALUES ("This is a test of col a.", + "This is another test of col b.", + "This is a test of the large col c.", + "Col d"); +SELECT * FROM t1; +SHOW CREATE TABLE t1; + +sync_slave_with_master slave; + +--echo Insert some values and select them on slave +SELECT * FROM t1; +SHOW CREATE TABLE t1; + + +# Test boundary limits of bit fields +# m < s, m % 8 != 0, and s % 8 == 0 col a +# m < s, m % 8 == 0, and s % 8 != 0 col b +# m < s, m % 8 != 0, and s % 8 != 0 col c +# m > s, m % 8 != 0, and s % 8 == 0 <-- error will be caught in BUG#22086 +# m > s, m % 8 == 0, and s % 8 != 0 <-- error will be caught in BUG#22086 +# m > s, m % 8 != 0, and s % 8 != 0 <-- error will be caught in BUG#22086 + +connection master; +DROP TABLE t1; + +--echo Create bit table on master +CREATE TABLE t1 ( + a BIT(7), + b BIT(8), + c BIT(21), + d BIT(11), + e BIT(11) +); + +sync_slave_with_master slave; + +--echo Create bit table on slave +DROP TABLE t1; +CREATE TABLE t1 ( + a BIT(16), + b BIT(22), + c BIT(54), + d BIT(25), + e BIT(13) +); + +connection master; + +--echo Insert some values and select them on master +INSERT INTO t1 VALUES ( + b'1010101', + b'10101011', + b'101010110101010101111', + b'10101010101', + b'10101011111' + ); + +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +SHOW CREATE TABLE t1; + +sync_slave_with_master slave; + +--echo Insert some values and select them on master +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +SHOW CREATE TABLE t1; + +--echo *** Cleanup *** +connection master; +DROP TABLE t1; +sync_slave_with_master; + +# END 5.1 Test Case diff --git a/mysql-test/t/rpl_row_create_table.test b/mysql-test/t/rpl_row_create_table.test index d1b26f9e3f4..d41f6b0bf69 100644 --- a/mysql-test/t/rpl_row_create_table.test +++ b/mysql-test/t/rpl_row_create_table.test @@ -72,7 +72,7 @@ CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; # Shouldn't be written to the binary log --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; # Test that INSERT-SELECT works the same way as for SBR. CREATE TABLE t7 (a INT, b INT UNIQUE); @@ -82,7 +82,7 @@ SELECT * FROM t7 ORDER BY a,b; # Should be written to the binary log --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; sync_slave_with_master; SELECT * FROM t7 ORDER BY a,b; @@ -94,7 +94,7 @@ INSERT INTO t7 SELECT a,b FROM tt4; ROLLBACK; --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1294; +SHOW BINLOG EVENTS FROM 1298; SELECT * FROM t7 ORDER BY a,b; sync_slave_with_master; SELECT * FROM t7 ORDER BY a,b; @@ -110,7 +110,7 @@ CREATE TEMPORARY TABLE tt7 SELECT 1; --query_vertical SHOW CREATE TABLE t9 --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1390; +SHOW BINLOG EVENTS FROM 1396; sync_slave_with_master; --echo **** On Slave **** --query_vertical SHOW CREATE TABLE t8 @@ -227,7 +227,7 @@ ROLLBACK; SELECT * FROM t2 ORDER BY a; --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 631; +SHOW BINLOG EVENTS FROM 637; sync_slave_with_master; SELECT * FROM t2 ORDER BY a; diff --git a/mysql-test/t/rpl_row_flsh_tbls.test b/mysql-test/t/rpl_row_flsh_tbls.test index a2f9e31fc5d..bfa356fbfb4 100644 --- a/mysql-test/t/rpl_row_flsh_tbls.test +++ b/mysql-test/t/rpl_row_flsh_tbls.test @@ -1,7 +1,7 @@ # depends on the binlog output -- source include/have_binlog_format_row.inc -let $rename_event_pos= 619; +let $rename_event_pos= 623; # Bug#18326: Do not lock table for writing during prepare of statement # The use of the ps protocol causes extra table maps in the binlog, so diff --git a/sql/field.cc b/sql/field.cc index fa25871fe61..d9aa822b93f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1358,6 +1358,49 @@ bool Field::send_binary(Protocol *protocol) } +/** + Unpack a field from row data. + + This method is used to unpack a field from a master whose size + of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Pack length of the field data + + @return New pointer into memory based on from + length of the data +*/ +const char *Field::unpack(char* to, const char *from, uint param_data) +{ + uint length=pack_length(); + int from_type= 0; + /* + If from length is > 255, it has encoded data in the upper bits. Need + to mask it out. + */ + if (param_data > 255) + { + from_type= (param_data & 0xff00) >> 8U; // real_type. + param_data= param_data & 0x00ff; // length. + } + uint len= (param_data && (param_data < length)) ? + param_data : length; + /* + If the length is the same, use old unpack method. + If the param_data is 0, use the old unpack method. + This is possible if the table map was generated from a down-level + master or if the data was not available on the master. + If the real_types are not the same, use the old unpack method. + */ + if ((length == param_data) || + (param_data == 0) || + (from_type != real_type())) + return(unpack(to, from)); + memcpy(to, from, param_data > length ? length : len); + return from+len; +} + + my_decimal *Field::val_decimal(my_decimal *decimal) { /* This never have to be called */ @@ -2635,6 +2678,51 @@ uint Field_new_decimal::is_equal(create_field *new_field) (new_field->decimals == dec)); } +/** + Unpack a decimal field from row data. + + This method is used to unpack a decimal or numeric field from a master + whose size of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Precision (upper) and decimal (lower) values + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_new_decimal::unpack(char* to, + const char *from, + uint param_data) +{ + uint from_precision= (param_data & 0xff00) >> 8U; + uint from_decimal= param_data & 0x00ff; + uint length=pack_length(); + uint from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal); + uint len= (param_data && (from_pack_len < length)) ? + from_pack_len : length; + if (from_pack_len && (from_pack_len < length)) + { + /* + If the master's data is smaller than the slave, we need to convert + the binary to decimal then resize the decimal converting it back to + a decimal and write that to the raw data buffer. + */ + decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION]; + decimal_t dec; + dec.len= from_precision; + dec.buf= dec_buf; + /* + Note: bin2decimal does not change the length of the field. So it is + just the first step the resizing operation. The second step does the + resizing using the precision and decimals from the slave. + */ + bin2decimal((char *)from, &dec, from_precision, from_decimal); + decimal2bin(&dec, to, precision, decimals()); + } + else + memcpy(to, from, len); // Sizes are the same, just copy the data. + return from+len; +} /**************************************************************************** ** tiny int @@ -6294,6 +6382,37 @@ char *Field_string::pack(char *to, const char *from, uint max_length) } +/** + Unpack a string field from row data. + + This method is used to unpack a string field from a master whose size + of the field is less than that of the slave. Note that there can be a + variety of field types represented with this class. Certain types like + ENUM or SET are processed differently. Hence, the upper byte of the + @c param_data argument contains the result of field->real_type() from + the master. + + @param to Destination of the data + @param from Source of the data + @param param_data Real type (upper) and length (lower) values + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_string::unpack(char *to, + const char *from, + uint param_data) +{ + uint from_len= param_data & 0x00ff; // length. + uint length= 0; + uint f_length= (from_len < field_length) ? from_len : field_length; + DBUG_ASSERT(f_length <= 255); + length= (uint) *from++; + bitmap_set_bit(table->write_set,field_index); + store(from, length, system_charset_info); + return from+length; +} + + const char *Field_string::unpack(char *to, const char *from) { uint length; @@ -6782,6 +6901,44 @@ char *Field_varstring::pack_key_from_key_image(char *to, const char *from, } +/** + Unpack a varstring field from row data. + + This method is used to unpack a varstring field from a master + whose size of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Length bytes from the master's field data + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_varstring::unpack(char *to, + const char *from, + uint param_data) +{ + uint length; + uint l_bytes= (param_data && (param_data < field_length)) ? + (param_data <= 255) ? 1 : 2 : length_bytes; + if (l_bytes == 1) + { + to[0]= *from++; + length= to[0]; + if (length_bytes == 2) + to[1]= 0; + } + else + { + length= uint2korr(from); + to[0]= *from++; + to[1]= *from++; + } + if (length) + memcpy(to+ length_bytes, from, length); + return from+length; +} + + /* unpack field packed with Field_varstring::pack() */ @@ -7473,6 +7630,29 @@ char *Field_blob::pack(char *to, const char *from, uint max_length) } +/** + Unpack a blob field from row data. + + This method is used to unpack a blob field from a master whose size of + the field is less than that of the slave. Note: This method is included + to satisfy inheritance rules, but is not needed for blob fields. It + simply is used as a pass-through to the original unpack() method for + blob fields. + + @param to Destination of the data + @param from Source of the data + @param param_data + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_blob::unpack(char *to, + const char *from, + uint param_data) +{ + return unpack(to, from); +} + + const char *Field_blob::unpack(char *to, const char *from) { memcpy(to,from,packlength); @@ -8510,6 +8690,58 @@ char *Field_bit::pack(char *to, const char *from, uint max_length) } +/** + Unpack a bit field from row data. + + This method is used to unpack a bit field from a master whose size + of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Bit length (upper) and length (lower) values + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_bit::unpack(char *to, + const char *from, + uint param_data) +{ + uint const from_len= (param_data >> 8U) & 0x00ff; + uint const from_bit_len= param_data & 0x00ff; + /* + If the master and slave have the same sizes, then use the old + unpack() method. + */ + if ((from_bit_len == bit_len) && + (from_len == bytes_in_rec)) + return(unpack(to, from)); + /* + We are converting a smaller bit field to a larger one here. + To do that, we first need to construct a raw value for the original + bit value stored in the from buffer. Then that needs to be converted + to the larger field then sent to store() for writing to the field. + Lastly the odd bits need to be masked out if the bytes_in_rec > 0. + Otherwise stray bits can cause spurious values. + */ + uint new_len= (field_length + 7) / 8; + char *value= (char *)my_alloca(new_len); + bzero(value, new_len); + uint len= from_len + ((from_bit_len > 0) ? 1 : 0); + memcpy(value + (new_len - len), from, len); + /* + Mask out the unused bits in the partial byte. + TODO: Add code to the master to always mask these bits and remove + the following. + */ + if ((from_bit_len > 0) && (from_len > 0)) + value[new_len - len]= value[new_len - len] & ((1U << from_bit_len) - 1); + bitmap_set_bit(table->write_set,field_index); + store(value, new_len, system_charset_info); + my_afree(value); + return from + len; +} + + const char *Field_bit::unpack(char *to, const char *from) { if (bit_len > 0) diff --git a/sql/field.h b/sql/field.h index 2c2640a8262..545e34bd551 100644 --- a/sql/field.h +++ b/sql/field.h @@ -342,6 +342,7 @@ public: memcpy(to,from,length); return to+length; } + virtual const char *unpack(char* to, const char *from, uint param_data); virtual const char *unpack(char* to, const char *from) { uint length=pack_length(); @@ -613,6 +614,7 @@ public: uint size_of() const { return sizeof(*this); } uint32 pack_length() const { return (uint32) bin_size; } uint is_equal(create_field *new_field); + virtual const char *unpack(char* to, const char *from, uint param_data); }; @@ -1154,6 +1156,7 @@ public: void sort_string(char *buff,uint length); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + virtual const char *unpack(char* to, const char *from, uint param_data); const char *unpack(char* to, const char *from); int pack_cmp(const char *a,const char *b,uint key_length, my_bool insert_or_update); @@ -1224,6 +1227,7 @@ public: char *pack(char *to, const char *from, uint max_length=~(uint) 0); char *pack_key(char *to, const char *from, uint max_length); char *pack_key_from_key_image(char* to, const char *from, uint max_length); + virtual const char *unpack(char* to, const char *from, uint param_data); const char *unpack(char* to, const char *from); const char *unpack_key(char* to, const char *from, uint max_length); int pack_cmp(const char *a, const char *b, uint key_length, @@ -1279,6 +1283,9 @@ public: l_char_length <= 16777215 ? 3 : 4; } } + Field_blob(uint32 packlength_arg) + :Field_longstr((char*) 0, 0, (uchar*) "", 0, NONE, "temp", system_charset_info), + packlength(packlength_arg) {} enum_field_types type() const { return MYSQL_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } @@ -1300,6 +1307,17 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return (uint32) (packlength+table->s->blob_ptr_size); } + + /** + Return the packed length without the pointer size added. + + This is used to determine the size of the actual data in the row + buffer. + + @retval The length of the raw data itself without the pointer. + */ + uint32 pack_length_no_ptr() const + { return (uint32) (packlength); } uint32 sort_length() const; inline uint32 max_data_length() const { @@ -1316,6 +1334,17 @@ public: store_length(ptr, packlength, number); } + /** + Return the packed length plus the length of the data. + + This is used to determine the size of the data plus the + packed length portion in the row data. + + @retval The length in the row plus the size of the data. + */ + uint32 get_packed_size(const uchar *ptr) + {return packlength + get_length((uint)ptr);} + inline uint32 get_length(uint row_offset=0) { return get_length(ptr+row_offset); } uint32 get_length(const char *ptr); @@ -1360,6 +1389,7 @@ public: char *pack(char *to, const char *from, uint max_length= ~(uint) 0); char *pack_key(char *to, const char *from, uint max_length); char *pack_key_from_key_image(char* to, const char *from, uint max_length); + virtual const char *unpack(char *to, const char *from, uint param_data); const char *unpack(char *to, const char *from); const char *unpack_key(char* to, const char *from, uint max_length); int pack_cmp(const char *a, const char *b, uint key_length, @@ -1534,6 +1564,7 @@ public: uint32 pack_length_in_rec() const { return bytes_in_rec; } void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + virtual const char *unpack(char *to, const char *from, uint param_data); const char *unpack(char* to, const char *from); virtual void set_default(); diff --git a/sql/log_event.cc b/sql/log_event.cc index 6565278e6d3..eb1f6aeeaf9 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5976,11 +5976,8 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) #ifdef HAVE_QUERY_CACHE query_cache.invalidate_locked_for_write(rli->tables_to_lock); #endif - const_cast(rli)->clear_tables_to_lock(); } - DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count == 0); - TABLE* table= const_cast(rli)->m_table_map.get_table(m_table_id); if (table) @@ -6076,6 +6073,13 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) } } + /* + We need to delay this clear until the table def is no longer needed. + The table def is needed in unpack_row(). + */ + if (rli->tables_to_lock && get_flags(STMT_END_F)) + const_cast(rli)->clear_tables_to_lock(); + if (error) { /* error has occured during the transaction */ slave_print_msg(ERROR_LEVEL, rli, thd->net.last_errno, @@ -6314,6 +6318,163 @@ void Rows_log_event::print_helper(FILE *file, Table_map_log_event member functions and support functions **************************************************************************/ +/** + * Calculate field metadata size based on the real_type of the field. + * + * @returns int Size of field metadata. + */ +#if !defined(MYSQL_CLIENT) +const int Table_map_log_event::calc_field_metadata_size() +{ + DBUG_ENTER("Table_map_log_event::calc_field_metadata_size"); + int size= 0; + for (unsigned int i= 0 ; i < m_table->s->fields ; i++) + { + switch (m_table->s->field[i]->real_type()) { + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + { + size++; // Store one byte here. + break; + } + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_NEWDECIMAL: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_SET: + { + size= size + sizeof(short int); // Store short int here. + break; + } + default: + break; + } + } + m_field_metadata_size= size; + DBUG_PRINT("info", ("Table_map_log_event: %d bytes in field metadata.", + (int)m_field_metadata_size)); + DBUG_RETURN(m_field_metadata_size); +} +#endif /* !defined(MYSQL_CLIENT) */ + +/** + @page How replication of field metadata works. + + When a table map is created, the master first calls + Table_map_log_event::get_field_metadata_size() which calculates how many + values will be in the field metadata. Only those fields that require the + extra data are added (see table above). The master then loops through all + of the fields in the table calling the method + Table_map_log_event::get_field_metadata() which returns the values for the + field that will be saved in the metadata and replicated to the slave. Once + all fields have been processed, the table map is written to the binlog + adding the size of the field metadata and the field metadata to the end of + the body of the table map. + + When a table map is read on the slave, the field metadata is read from the + table map and passed to the table_def class constructor which saves the + field metadata from the table map into an array based on the type of the + field. Field metadata values not present (those fields that do not use extra + data) in the table map are initialized as zero (0). The array size is the + same as the columns for the table on the slave. + +*/ + +/** + Save the field metadata based on the real_type of the field. + The metadata saved depends on the type of the field. Some fields + store a single byte for pack_length() while others store two bytes + for field_length (max length). + + @retval 0 Ok. + + TODO: We may want to consider changing the encoding of the information. + Currently, the code attempts to minimize the number of bytes written to + the tablemap. There are at least two other alternatives; 1) using + net_store_length() to store the data allowing it to choose the number of + bytes that are appropriate thereby making the code much easier to + maintain (only 1 place to change the encoding), or 2) use a fixed number + of bytes for each field. The problem with option 1 is that net_store_length() + will use one byte if the value < 251, but 3 bytes if it is > 250. Thus, + for fields like CHAR which can be no larger than 255 characters, the method + will use 3 bytes when the value is > 250. Further, every value that is + encoded using 2 parts (e.g., pack_length, field_length) will be numerically + > 250 therefore will use 3 bytes for eah value. The problem with option 2 + is less wasteful for space but does waste 1 byte for every field that does + not encode 2 parts. +*/ +#if !defined(MYSQL_CLIENT) +int Table_map_log_event::save_field_metadata() +{ + DBUG_ENTER("Table_map_log_event::save_field_metadata"); + int index= 0; + for (unsigned int i= 0 ; i < m_table->s->fields ; i++) + { + switch (m_table->s->field[i]->real_type()) { + case MYSQL_TYPE_NEWDECIMAL: + { + m_field_metadata[index++]= + (uchar)((Field_new_decimal *)m_table->s->field[i])->precision; + m_field_metadata[index++]= + (uchar)((Field_new_decimal *)m_table->s->field[i])->decimals(); + break; + } + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + { + m_field_metadata[index++]= + (uchar)((Field_blob *)m_table->s->field[i])->pack_length_no_ptr(); + break; + } + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + { + m_field_metadata[index++]= (uchar)m_table->s->field[i]->pack_length(); + break; + } + case MYSQL_TYPE_BIT: + { + m_field_metadata[index++]= + (uchar)((Field_bit *)m_table->s->field[i])->bit_len; + m_field_metadata[index++]= + (uchar)((Field_bit *)m_table->s->field[i])->bytes_in_rec; + break; + } + case MYSQL_TYPE_VARCHAR: + { + short int *x= (short int *)&m_field_metadata[index]; + int2store(x, m_table->s->field[i]->field_length); + index= index + sizeof(short int); + break; + } + case MYSQL_TYPE_STRING: + { + m_field_metadata[index++]= (uchar)m_table->s->field[i]->real_type(); + m_field_metadata[index++]= m_table->s->field[i]->field_length; + break; + } + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + { + m_field_metadata[index++]= (uchar)m_table->s->field[i]->real_type(); + m_field_metadata[index++]= m_table->s->field[i]->pack_length(); + break; + } + default: + break; + } + } + DBUG_RETURN(0); +} +#endif /* !defined(MYSQL_CLIENT) */ + /* Constructor used to build an event for writing to the binary log. Mats says tbl->s lives longer than this event so it's ok to copy pointers @@ -6328,9 +6489,8 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, m_dblen(m_dbnam ? tbl->s->db.length : 0), m_tblnam(tbl->s->table_name.str), m_tbllen(tbl->s->table_name.length), - m_colcnt(tbl->s->fields), m_coltype(0), - m_table_id(tid), - m_flags(flags) + m_colcnt(tbl->s->fields), m_field_metadata(0), + m_table_id(tid), m_null_bits(0), m_flags(flags) { DBUG_ASSERT(m_table_id != ~0UL); /* @@ -6349,6 +6509,16 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, m_data_size+= m_dblen + 2; // Include length and terminating \0 m_data_size+= m_tbllen + 2; // Include length and terminating \0 m_data_size+= 1 + m_colcnt; // COLCNT and column types + m_field_metadata_size= calc_field_metadata_size(); + + /* + Now set the size of the data to the size of the field metadata array + plus one or two bytes for number of elements in the field metadata array. + */ + if (m_field_metadata_size > 255) + m_data_size+= m_field_metadata_size + 2; + else + m_data_size+= m_field_metadata_size + 1; /* If malloc fails, catched in is_valid() */ if ((m_memory= my_malloc(m_colcnt, MYF(MY_WME)))) @@ -6357,6 +6527,28 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, for (unsigned int i= 0 ; i < m_table->s->fields ; ++i) m_coltype[i]= m_table->field[i]->type(); } + + /* + Calculate a bitmap for the results of maybe_null() for all columns. + The bitmap is used to determine when there is a column from the master + that is not on the slave and is null and thus not in the row data during + replication. + */ + uint num_null_bytes= (m_table->s->fields + 7) / 8; + m_data_size+= num_null_bytes; + m_meta_memory= my_multi_malloc(MYF(MY_WME), + &m_null_bits, num_null_bytes, + &m_field_metadata, m_field_metadata_size, + NULL); + bzero(m_null_bits, num_null_bytes); + for (unsigned int i= 0 ; i < m_table->s->fields ; ++i) + if (m_table->field[i]->maybe_null()) + m_null_bits[(i / 8)]+= 1 << (i % 8); + + /* + Create an array for the field metadata and store it. + */ + save_field_metadata(); } #endif /* !defined(MYSQL_CLIENT) */ @@ -6372,8 +6564,10 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, #ifndef MYSQL_CLIENT m_table(NULL), #endif - m_memory(NULL) + m_memory(NULL), + m_field_metadata(0), m_field_metadata_size(0) { + unsigned int bytes_read= 0; DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)"); uint8 common_header_len= description_event->common_header_len; @@ -6444,6 +6638,22 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, strncpy(const_cast(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1); strncpy(const_cast(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1); memcpy(m_coltype, ptr_after_colcnt, m_colcnt); + + ptr_after_colcnt= ptr_after_colcnt + m_colcnt; + bytes_read= ptr_after_colcnt - (uchar *)buf; + DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read)); + if (bytes_read < event_len) + { + m_field_metadata_size= net_field_length(&ptr_after_colcnt); + uint num_null_bytes= (m_colcnt + 7) / 8; + m_meta_memory= my_multi_malloc(MYF(MY_WME), + &m_null_bits, num_null_bytes, + &m_field_metadata, m_field_metadata_size, + NULL); + memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size); + ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size; + memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes); + } } DBUG_VOID_RETURN; @@ -6452,6 +6662,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, Table_map_log_event::~Table_map_log_event() { + my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR)); my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR)); } @@ -6585,7 +6796,8 @@ int Table_map_log_event::do_apply_event(RELAY_LOG_INFO const *rli) inside st_relay_log_info::clear_tables_to_lock() by calling the table_def destructor explicitly. */ - new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt); + new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt, + m_field_metadata, m_field_metadata_size, m_null_bits); table_list->m_tabledef_valid= TRUE; /* @@ -6644,13 +6856,22 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file) char *const cbuf_end= net_store_length((char*) cbuf, (uint) m_colcnt); DBUG_ASSERT(static_cast(cbuf_end - cbuf) <= sizeof(cbuf)); + /* + Store the size of the field metadata. + */ + char mbuf[sizeof(m_field_metadata_size)]; + char *const mbuf_end= net_store_length(mbuf, (size_t) m_field_metadata_size); + return (my_b_safe_write(file, dbuf, sizeof(dbuf)) || my_b_safe_write(file, (const byte*)m_dbnam, m_dblen+1) || my_b_safe_write(file, tbuf, sizeof(tbuf)) || my_b_safe_write(file, (const byte*)m_tblnam, m_tbllen+1) || my_b_safe_write(file, reinterpret_cast(cbuf), cbuf_end - (char*) cbuf) || - my_b_safe_write(file, reinterpret_cast(m_coltype), m_colcnt)); + my_b_safe_write(file, reinterpret_cast(m_coltype), m_colcnt) || + my_b_safe_write(file, reinterpret_cast(mbuf), (size_t) (mbuf_end - mbuf)) || + my_b_safe_write(file, reinterpret_cast(m_field_metadata), m_field_metadata_size), + my_b_safe_write(file, reinterpret_cast(m_null_bits), (m_colcnt + 7) / 8)); } #endif diff --git a/sql/log_event.h b/sql/log_event.h index 4e43822cb38..0ac17e304ca 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -2048,6 +2048,8 @@ public: virtual int get_data_size() { return m_data_size; } #ifndef MYSQL_CLIENT + virtual const int calc_field_metadata_size(); + virtual int save_field_metadata(); virtual bool write_data_header(IO_CACHE *file); virtual bool write_data_body(IO_CACHE *file); virtual const char *get_db() { return m_dbnam; } @@ -2083,6 +2085,14 @@ private: flag_set m_flags; my_size_t m_data_size; + + uchar *m_field_metadata; // buffer for field metadata + /* + The size of field metadata buffer set by calling calc_field_metadata_size() + */ + ulong m_field_metadata_size; + uchar *m_null_bits; + gptr m_meta_memory; }; diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 4c6686cf446..d33d60300fd 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -16,6 +16,8 @@ #include "mysql_priv.h" #include "rpl_record.h" #include "slave.h" // Need to pull in slave_print_msg +#include "rpl_utility.h" +#include "rpl_rli.h" /** Pack a record of data for a table into a format suitable for @@ -190,7 +192,9 @@ unpack_row(RELAY_LOG_INFO const *rli, unsigned int null_mask= 1U; // The "current" null bits unsigned int null_bits= *null_ptr++; - for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr) + uint i= 0; + table_def *tabledef= ((RELAY_LOG_INFO*)rli)->get_tabledef(table); + for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr) { Field *const f= *field_ptr; @@ -219,14 +223,20 @@ unpack_row(RELAY_LOG_INFO const *rli, f->set_notnull(); /* - We only unpack the field if it was non-null - */ - pack_ptr= f->unpack(f->ptr, pack_ptr); + We only unpack the field if it was non-null. + Use the master's size information if available else call + normal unpack operation. + */ + if (tabledef && tabledef->field_metadata(i)) + pack_ptr= f->unpack(f->ptr, pack_ptr, tabledef->field_metadata(i)); + else + pack_ptr= f->unpack(f->ptr, pack_ptr); } bitmap_set_bit(rw_set, f->field_index); null_mask <<= 1; } + i++; } /* diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index fada45722f6..b30f8599f6a 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -19,6 +19,7 @@ #define MAX_SLAVE_ERRMSG 1024 #include "rpl_tblmap.h" +#include "rpl_utility.h" struct RPL_TABLE_LIST; @@ -305,6 +306,15 @@ typedef struct st_relay_log_info uint tables_to_lock_count; /* RBR: Count of tables to lock */ table_mapping m_table_map; /* RBR: Mapping table-id to table */ + inline table_def *get_tabledef(TABLE *tbl) + { + table_def *td= 0; + for (TABLE_LIST *ptr= tables_to_lock; ptr && !td; ptr= ptr->next_global) + if (ptr->table == tbl) + td= &((RPL_TABLE_LIST *)ptr)->m_tabledef; + return (td); + } + /* Last charset (6 bytes) seen by slave SQL thread is cached here; it helps the thread save 3 get_charset() per Query_log_event if the charset is not diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 1d7cc808f0c..143251991b5 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -15,17 +15,46 @@ #include "rpl_utility.h" -uint32 -field_length_from_packed(enum_field_types const field_type, - byte const *const data) + +/********************************************************************* + * table_def member definitions * + *********************************************************************/ + +/* + This function returns the field size in raw bytes based on the type + and the encoded field data from the master's raw data. +*/ +uint32 table_def::calc_field_size(uint col, uchar *master_data) { uint32 length; - switch (field_type) { - case MYSQL_TYPE_DECIMAL: + switch (type(col)) { case MYSQL_TYPE_NEWDECIMAL: - length= ~(uint32) 0; + length= my_decimal_get_binary_size(m_field_metadata[col] >> 8, + m_field_metadata[col] - ((m_field_metadata[col] >> 8) << 8)); break; + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + length= m_field_metadata[col]; + break; + case MYSQL_TYPE_SET: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_STRING: + { + if (((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_SET << 8)) || + ((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_ENUM << 8))) + length= m_field_metadata[col] & 0x00ff; + else + { + length= m_field_metadata[col] & 0x00ff; + if (length > 255) + length= uint2korr(master_data) + 2; + else + length= (uint) *master_data + 1; + } + break; + } case MYSQL_TYPE_YEAR: case MYSQL_TYPE_TINY: length= 1; @@ -44,12 +73,6 @@ field_length_from_packed(enum_field_types const field_type, length= 8; break; #endif - case MYSQL_TYPE_FLOAT: - length= sizeof(float); - break; - case MYSQL_TYPE_DOUBLE: - length= sizeof(double); - break; case MYSQL_TYPE_NULL: length= 0; break; @@ -57,8 +80,6 @@ field_length_from_packed(enum_field_types const field_type, length= 3; break; case MYSQL_TYPE_DATE: - length= 4; - break; case MYSQL_TYPE_TIME: length= 3; break; @@ -68,41 +89,33 @@ field_length_from_packed(enum_field_types const field_type, case MYSQL_TYPE_DATETIME: length= 8; break; - break; case MYSQL_TYPE_BIT: - length= ~(uint32) 0; + { + uint from_len= (m_field_metadata[col] >> 8U) & 0x00ff; + uint from_bit_len= m_field_metadata[col] & 0x00ff; + length= from_len + ((from_bit_len > 0) ? 1 : 0); break; - default: - /* This case should never be chosen */ - DBUG_ASSERT(0); - /* If something goes awfully wrong, it's better to get a string than die */ - case MYSQL_TYPE_STRING: - length= uint2korr(data); - break; - - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_VAR_STRING: + } case MYSQL_TYPE_VARCHAR: - length= ~(uint32) 0; // NYI + length= m_field_metadata[col] > 255 ? 2 : 1; // c&p of Field_varstring::data_length() + length+= length == 1 ? (uint32) *master_data : uint2korr(master_data); break; - case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_GEOMETRY: - length= ~(uint32) 0; // NYI + { + Field_blob fb(m_field_metadata[col]); + length= fb.get_packed_size(master_data); break; } - + default: + length= -1; + } return length; } -/********************************************************************* - * table_def member definitions * - *********************************************************************/ - /* Is the definition compatible with a table? @@ -135,8 +148,14 @@ table_def::compatible_with(RELAY_LOG_INFO const *rli_arg, TABLE *table) tsh->fields); } + /* + We now check for column type and size compatibility. + */ for (uint col= 0 ; col < cols_to_check ; ++col) { + /* + Checking types. + */ if (table->field[col]->type() != type(col)) { DBUG_ASSERT(col < size() && col < tsh->fields); diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 82992eec690..b4707a4c7bd 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -21,13 +21,11 @@ #endif #include "mysql_priv.h" +#include "my_bitmap.h" struct st_relay_log_info; typedef st_relay_log_info RELAY_LOG_INFO; -uint32 -field_length_from_packed(enum_field_types field_type, byte const *data); - /** A table definition from the master. @@ -57,19 +55,90 @@ public: @param types Array of types @param size Number of elements in array 'types' + @param field_metadata Array of extra information about fields + @param metadata_size Size of the field_metadata array + @param null_bitmap The bitmap of fields that can be null */ - table_def(field_type *types, my_size_t size) - : m_size(size), m_type(new unsigned char [size]) + table_def(field_type *types, ulong size, uchar *field_metadata, + int metadata_size, uchar *null_bitmap) + : m_size(size), m_type(0), + m_field_metadata(0), m_null_bits(0), m_memory(NULL) { + m_memory= my_multi_malloc(MYF(MY_WME), + &m_type, size, + &m_field_metadata, size * sizeof(short), + &m_null_bits, (m_size + 7) / 8, + NULL); if (m_type) memcpy(m_type, types, size); else m_size= 0; + /* + Extract the data from the table map into the field metadata array + iff there is field metadata. The variable metadata_size will be + 0 if we are replicating from an older version server since no field + metadata was written to the table map. This can also happen if + there were no fields in the master that needed extra metadata. + */ + if (m_size && metadata_size) + { + int index= 0; + for (unsigned int i= 0; i < m_size; i++) + { + switch (m_type[i]) { + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + { + /* + These types store a single byte. + */ + m_field_metadata[i]= (uchar)field_metadata[index]; + index++; + break; + } + case MYSQL_TYPE_SET: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_STRING: + { + short int x= field_metadata[index++] << 8U; // real_type + x = x + field_metadata[index++]; // pack or field length + m_field_metadata[i]= x; + break; + } + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_VARCHAR: + { + /* + These types store two bytes. + */ + short int *x= (short int *)&field_metadata[index]; + m_field_metadata[i]= sint2korr(x); + index= index + sizeof(short int); + break; + } + case MYSQL_TYPE_NEWDECIMAL: + { + short int x= field_metadata[index++] << 8U; // precision + x = x + field_metadata[index++]; // decimals + m_field_metadata[i]= x; + break; + } + default: + m_field_metadata[i]= 0; + break; + } + } + } + if (m_size && null_bitmap) + memcpy(m_null_bits, null_bitmap, (m_size + 7) / 8); } ~table_def() { - if (m_type) - delete [] m_type; + my_free(m_memory, MYF(0)); #ifndef DBUG_OFF m_type= 0; m_size= 0; @@ -100,6 +169,47 @@ public: return m_type[index]; } + /* + This function allows callers to get the extra field data from the + table map for a given field. If there is no metadata for that field + or there is no extra metadata at all, the function returns 0. + + The function returns the value for the field metadata for column at + position indicated by index. As mentioned, if the field was a type + that stores field metadata, that value is returned else zero (0) is + returned. This method is used in the unpack() methods of the + corresponding fields to properly extract the data from the binary log + in the event that the master's field is smaller than the slave. + */ + uint16 field_metadata(uint index) const + { + DBUG_ASSERT(index < m_size); + if (m_field_metadata) + return m_field_metadata[index]; + else + return 0; + } + + /* + This function returns whether the field on the master can be null. + This value is derived from field->maybe_null(). + */ + my_bool maybe_null(uint index) const + { + DBUG_ASSERT(index < m_size); + return ((m_null_bits[(index / 8)] & + (1 << (index % 8))) == (1 << (index %8))); + } + + /* + This function returns the field size in raw bytes based on the type + and the encoded field data from the master's raw data. This method can + be used for situations where the slave needs to skip a column (e.g., + WL#3915) or needs to advance the pointer for the fields in the raw + data from the master to a specific column. + */ + uint32 calc_field_size(uint col, uchar *master_data); + /** Decide if the table definition is compatible with a table. @@ -122,6 +232,9 @@ public: private: my_size_t m_size; // Number of elements in the types array field_type *m_type; // Array of type descriptors + short int *m_field_metadata; + uchar *m_null_bits; + gptr m_memory; }; /** From ef79d224c3991d3d436e3b259a5cf6c8995dba34 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 14:38:36 -0400 Subject: [PATCH 08/22] WL#3228 (NDB) : RBR using different table defs on slave/master This patch adds the ability to store extra field metadata in the table map event. This data can include pack_length() or field_lenght() for fields such as CHAR or VARCHAR enabling developers to add code that can check for compatibilty between master and slave columns. More importantly, the extra field metadata can be used to store data from the master correctly should a VARCHAR field on the master be <= 255 bytes while the same field on the slave is > 255 bytes. ' The patch also includes the needed changes to unpack to ensure that data which is smaller on the master can be unpacked correctly on the slave. mysql-test/extra/rpl_tests/rpl_log.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to display slave status vertically. mysql-test/r/rpl_ndb_log.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_rbr_to_sbr.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_basic_11bugs.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_create_table.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_flsh_tbls.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_inexist_tbl.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_log.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_log_innodb.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_max_relay_size.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_row_until.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_stm_log.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the rpl_log.test modifications. mysql-test/r/rpl_truncate_7ndb.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/t/binlog_row_mix_innodb_myisam.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to coincide with changes to binlog size of table map event. mysql-test/t/rpl_row_create_table.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to coincide with changes to binlog size of table map event. mysql-test/t/rpl_row_flsh_tbls.test: WL#3228 : RBR using different table defs on slave/master This patch changes the test to coincide with changes to binlog size of table map event. sql/field.cc: WL#3228 : RBR using different table defs on slave/master This patch includes updates to the unpack() methods for the variable length fields. A new parameter was added (from_length) that is the value stored in the field_metadata of the table map from the table_def class. If the value is non-zero and less than what the field on the slave is then use the from_length else use the original value from the field on the slave. sql/field.h: WL#3228 : RBR using different table defs on slave/master This patch includes updates to the unpack() methods for the variable length fields. A new parameter was added (from_length) that is the value stored in the field_metadata of the table map from the table_def class. sql/log_event.cc: WL#3228 : RBR using different table defs on slave/master This patch adds methods to calculate the field metadata size, prepare the field metadata for writing to the binlog, and additions to the Table_map_log_event::write_body method to include the field metadata in the table map that is written to the binlog. sql/log_event.h: WL#3228 : RBR using different table defs on slave/master This patch adds method declarations and variables needed to support storing field metadata in the table map that is written to the binlog. sql/rpl_record.cc: WL#3228 : RBR using different table defs on slave/master This patch modifies the unpack_row() method to unpack fields passing in the value from the table_def class. This value is the extra field metadata stored there from the master. sql/rpl_rli.h: WL#3228 : RBR using different table defs on slave/master This patch adds a helper function to retrieve the table_def for a given table in the RPL_TABLE_LIST structure. sql/rpl_utility.cc: WL#3228 : RBR using different table defs on slave/master This patch adds a helper method that retrieves the correct size parameter for the field. This method is used to compare the size as sent by the master with that on the slave for all types of fields that can vary in size and storage requirements. sql/rpl_utility.h: WL#3228 : RBR using different table defs on slave/master This patch changes the table_def class constructor to pass in the raw data read from the table map and extract it into an array of dimension size (number of fields). It also adds a method to return the field metadata for any field. The method returns the data stored in the table map or 0 if no data was stored for that field. Lastly, a method to return the results of field->maybe_null() is included so that the slave can determine if a field that is not on the slave is null. mysql-test/t/rpl_colSize.test: WL#3228 : RBR using different table defs on slave/master This patch contains a new test designed to test the feature of having columns on the master that are smaller than what is on the slave. mysql-test/r/rpl_colSize.result: WL#3228 : RBR using different table defs on slave/master This patch contains a result file for the new test designed to test the feature of having columns on the master that are smaller than what is on the slave. --- mysql-test/extra/rpl_tests/rpl_log.test | 2 +- mysql-test/r/rpl_colSize.result | 179 +++++++++++++ mysql-test/r/rpl_ndb_log.result | 44 +++- mysql-test/r/rpl_rbr_to_sbr.result | 4 +- mysql-test/r/rpl_row_basic_11bugs.result | 4 +- mysql-test/r/rpl_row_create_table.result | 84 +++--- mysql-test/r/rpl_row_flsh_tbls.result | 4 +- mysql-test/r/rpl_row_inexist_tbl.result | 2 +- mysql-test/r/rpl_row_log.result | 46 +++- mysql-test/r/rpl_row_log_innodb.result | 46 +++- mysql-test/r/rpl_row_max_relay_size.result | 20 +- mysql-test/r/rpl_row_until.result | 8 +- mysql-test/r/rpl_stm_log.result | 38 ++- mysql-test/r/rpl_truncate_7ndb.result | 64 ++--- .../t/binlog_row_mix_innodb_myisam.test | 2 +- mysql-test/t/rpl_colSize.test | 216 ++++++++++++++++ mysql-test/t/rpl_row_create_table.test | 10 +- mysql-test/t/rpl_row_flsh_tbls.test | 2 +- sql/field.cc | 232 +++++++++++++++++ sql/field.h | 31 +++ sql/log_event.cc | 239 +++++++++++++++++- sql/log_event.h | 10 + sql/rpl_record.cc | 18 +- sql/rpl_rli.h | 10 + sql/rpl_utility.cc | 89 ++++--- sql/rpl_utility.h | 127 +++++++++- 26 files changed, 1350 insertions(+), 181 deletions(-) create mode 100644 mysql-test/r/rpl_colSize.result create mode 100644 mysql-test/t/rpl_colSize.test diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test index b3a0b513705..b68cebdbf64 100644 --- a/mysql-test/extra/rpl_tests/rpl_log.test +++ b/mysql-test/extra/rpl_tests/rpl_log.test @@ -108,7 +108,7 @@ show binlog events in 'slave-bin.000001' from 4; show binlog events in 'slave-bin.000002' from 4; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 8 # 9 # 16 # 23 # 33 # -show slave status; +--query_vertical show slave status; # Need to recode the following diff --git a/mysql-test/r/rpl_colSize.result b/mysql-test/r/rpl_colSize.result new file mode 100644 index 00000000000..91456742833 --- /dev/null +++ b/mysql-test/r/rpl_colSize.result @@ -0,0 +1,179 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +DROP TABLE IF EXISTS t1; +**** Testing WL#3228 changes. **** +*** Create "wider" table on slave *** +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 ( +a float (47), +b double (143,9), +c decimal (65,30), +d numeric (4,0), +e bit (32), +f char (21), +g varchar (1300), +h binary (33), +j varbinary (200), +k enum ('5','6','7', '8','9','0'), +l set ('1','2','3','4','5','6','7','8','9','0','11','12','13','14','15','16','17','18','19','21','22','23','24','25','26','27','28','29'), +m TINYBLOB, +n BLOB, +o MEDIUMBLOB, +p LONGBLOB, +q TINYTEXT, +r TEXT, +s MEDIUMTEXT, +t LONGTEXT +); +*** Create same table on master but with narrow columns *** +CREATE TABLE t1 ( +a float (44), +b double (10,3), +c decimal (10,2), +d numeric (3,0), +e bit (16), +f char (10), +g varchar (100), +h binary (20), +j varbinary (20), +k enum ('5','6','7'), +l set ('1','2','3','4','5','6','7','8','9','0'), +m TINYBLOB, +n BLOB, +o MEDIUMBLOB, +p LONGBLOB, +q TINYTEXT, +r TEXT, +s MEDIUMTEXT, +t LONGTEXT +); +RESET MASTER; +*** Start replication *** +START SLAVE; +*** Insert data on master and display it. *** +INSERT INTO t1 () VALUES ( +17.567, +2.123, +10.20, +125, +hex(64), +'TEST', +'This is a test', +'binary data', +'more binary data', +'6', +'7', +"blob 1", +"blob 2", +"blob 3", +"blob 4", +"text 1", +"text 2", +"text 3", +"text 4"); +SELECT * FROM t1 ORDER BY a; +a b c d e f g h j k l m n o p q r s t +17.567 2.123 10.20 125 # TEST This is a test # more binary data 6 7 blob 1 blob 2 blob 3 blob 4 text 1 text 2 text 3 text 4 +*** Select data from slave to compare *** +SELECT * FROM t1 ORDER BY a; +a b c d e f g h j k l m n o p q r s t +17.567 2.123000000 10.200000000000000000000000000000 125 # TEST This is a test # more binary data 6 7 blob 1 blob 2 blob 3 blob 4 text 1 text 2 text 3 text 4 +DROP TABLE t1; +Create varchar table on master +CREATE TABLE t1 ( +a VARCHAR(50), +b VARCHAR(100), +c VARCHAR(300), +d CHAR(5) +); +Alter varchar table on slave +ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(100); +ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(400); +ALTER TABLE t1 CHANGE COLUMN c c VARCHAR(500); +ALTER TABLE t1 CHANGE COLUMN d d CHAR(100); +Insert some values and select them on master +INSERT INTO t1 VALUES ("This is a test of col a.", +"This is another test of col b.", +"This is a test of the large col c.", +"Col d"); +SELECT * FROM t1; +a b c d +This is a test of col a. This is another test of col b. This is a test of the large col c. Col d +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(50) DEFAULT NULL, + `b` varchar(100) DEFAULT NULL, + `c` varchar(300) DEFAULT NULL, + `d` char(5) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +Insert some values and select them on slave +SELECT * FROM t1; +a b c d +This is a test of col a. This is another test of col b. This is a test of the large col c. Col d +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varchar(100) DEFAULT NULL, + `b` varchar(400) DEFAULT NULL, + `c` varchar(500) DEFAULT NULL, + `d` char(100) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +Create bit table on master +CREATE TABLE t1 ( +a BIT(7), +b BIT(8), +c BIT(21), +d BIT(11), +e BIT(11) +); +Create bit table on slave +DROP TABLE t1; +CREATE TABLE t1 ( +a BIT(16), +b BIT(22), +c BIT(54), +d BIT(25), +e BIT(13) +); +Insert some values and select them on master +INSERT INTO t1 VALUES ( +b'1010101', +b'10101011', +b'101010110101010101111', +b'10101010101', +b'10101011111' + ); +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +BIN(a) BIN(b) BIN(c) BIN(d) BIN(e) +1010101 10101011 101010110101010101111 10101010101 10101011111 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bit(7) DEFAULT NULL, + `b` bit(8) DEFAULT NULL, + `c` bit(21) DEFAULT NULL, + `d` bit(11) DEFAULT NULL, + `e` bit(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +Insert some values and select them on master +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +BIN(a) BIN(b) BIN(c) BIN(d) BIN(e) +1010101 10101011 101010110101010101111 10101010101 10101011111 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bit(16) DEFAULT NULL, + `b` bit(22) DEFAULT NULL, + `c` bit(54) DEFAULT NULL, + `d` bit(25) DEFAULT NULL, + `e` bit(13) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +*** Cleanup *** +DROP TABLE t1; diff --git a/mysql-test/r/rpl_ndb_log.result b/mysql-test/r/rpl_ndb_log.result index db2ce27d43b..741e434986d 100644 --- a/mysql-test/r/rpl_ndb_log.result +++ b/mysql-test/r/rpl_ndb_log.result @@ -88,12 +88,12 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000002 # Query 1 # COMMIT show binary logs; Log_name File_size -master-bin.000001 1775 -master-bin.000002 617 +master-bin.000001 1789 +master-bin.000002 623 start slave; show binary logs; Log_name File_size -slave-bin.000001 1870 +slave-bin.000001 1884 slave-bin.000002 202 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info @@ -126,9 +126,41 @@ slave-bin.000002 # Table_map 2 # table_id: # (mysql.ndb_apply_status) slave-bin.000002 # Write_rows 2 # table_id: # slave-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F slave-bin.000002 # Query 2 # COMMIT -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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 617 # # master-bin.000002 Yes Yes # 0 0 617 # None 0 No # No +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.000002 +Read_Master_Log_Pos 623 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000002 +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 623 +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 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_rbr_to_sbr.result b/mysql-test/r/rpl_rbr_to_sbr.result index 47adb70bcf5..175a277b744 100644 --- a/mysql-test/r/rpl_rbr_to_sbr.result +++ b/mysql-test/r/rpl_rbr_to_sbr.result @@ -28,7 +28,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 454 +Read_Master_Log_Pos 457 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -43,7 +43,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 454 +Exec_Master_Log_Pos 457 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/r/rpl_row_basic_11bugs.result b/mysql-test/r/rpl_row_basic_11bugs.result index 1025b965589..3cdaf137240 100644 --- a/mysql-test/r/rpl_row_basic_11bugs.result +++ b/mysql-test/r/rpl_row_basic_11bugs.result @@ -56,8 +56,8 @@ SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 106 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 106 Query 1 192 use `test`; CREATE TABLE t1 (a INT) -master-bin.000001 192 Table_map 1 231 table_id: # (test.t1) -master-bin.000001 231 Write_rows 1 270 table_id: # flags: STMT_END_F +master-bin.000001 192 Table_map 1 233 table_id: # (test.t1) +master-bin.000001 233 Write_rows 1 272 table_id: # flags: STMT_END_F DROP TABLE t1; ================ Test for BUG#17620 ================ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_row_create_table.result b/mysql-test/r/rpl_row_create_table.result index e76ce5b962d..84881e82702 100644 --- a/mysql-test/r/rpl_row_create_table.result +++ b/mysql-test/r/rpl_row_create_table.result @@ -127,7 +127,7 @@ NULL 5 10 NULL 6 12 CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; ERROR 23000: Duplicate entry '2' for key 'b' -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; Log_name Pos Event_type Server_id End_log_pos Info CREATE TABLE t7 (a INT, b INT UNIQUE); INSERT INTO t7 SELECT a,b FROM tt3; @@ -137,11 +137,11 @@ a b 1 2 2 4 3 6 -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; Log_name Pos Event_type Server_id End_log_pos Info -# 1098 Query # 1198 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) -# 1198 Table_map # 1238 table_id: # (test.t7) -# 1238 Write_rows # 1294 table_id: # flags: STMT_END_F +# 1100 Query # 1200 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) +# 1200 Table_map # 1242 table_id: # (test.t7) +# 1242 Write_rows # 1298 table_id: # flags: STMT_END_F SELECT * FROM t7 ORDER BY a,b; a b 1 2 @@ -154,10 +154,10 @@ INSERT INTO t7 SELECT a,b FROM tt4; ROLLBACK; Warnings: Warning 1196 Some non-transactional changed tables couldn't be rolled back -SHOW BINLOG EVENTS FROM 1294; +SHOW BINLOG EVENTS FROM 1298; Log_name Pos Event_type Server_id End_log_pos Info -# 1294 Table_map # 1334 table_id: # (test.t7) -# 1334 Write_rows # 1390 table_id: # flags: STMT_END_F +# 1298 Table_map # 1340 table_id: # (test.t7) +# 1340 Write_rows # 1396 table_id: # flags: STMT_END_F SELECT * FROM t7 ORDER BY a,b; a b 1 2 @@ -192,10 +192,10 @@ Create Table CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -SHOW BINLOG EVENTS FROM 1390; +SHOW BINLOG EVENTS FROM 1396; Log_name Pos Event_type Server_id End_log_pos Info -# 1390 Query # 1476 use `test`; CREATE TABLE t8 LIKE t4 -# 1476 Query # 1615 use `test`; CREATE TABLE `t9` ( +# 1396 Query # 1482 use `test`; CREATE TABLE t8 LIKE t4 +# 1482 Query # 1621 use `test`; CREATE TABLE `t9` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL ) @@ -276,31 +276,31 @@ SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info # 4 Format_desc # 106 Server ver: #, Binlog ver: # # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT) -# 192 Table_map # 231 table_id: # (test.t1) -# 231 Write_rows # 275 table_id: # flags: STMT_END_F -# 275 Query # 343 use `test`; BEGIN -# 343 Query # 125 use `test`; CREATE TABLE `t2` ( +# 192 Table_map # 233 table_id: # (test.t1) +# 233 Write_rows # 277 table_id: # flags: STMT_END_F +# 277 Query # 345 use `test`; BEGIN +# 345 Query # 125 use `test`; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 468 Table_map # 164 table_id: # (test.t2) -# 507 Write_rows # 208 table_id: # flags: STMT_END_F -# 551 Xid # 578 COMMIT /* XID */ -# 578 Query # 646 use `test`; BEGIN -# 646 Query # 125 use `test`; CREATE TABLE `t3` ( +# 470 Table_map # 166 table_id: # (test.t2) +# 511 Write_rows # 210 table_id: # flags: STMT_END_F +# 555 Xid # 582 COMMIT /* XID */ +# 582 Query # 650 use `test`; BEGIN +# 650 Query # 125 use `test`; CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 771 Table_map # 164 table_id: # (test.t3) -# 810 Write_rows # 208 table_id: # flags: STMT_END_F -# 854 Xid # 881 COMMIT /* XID */ -# 881 Query # 949 use `test`; BEGIN -# 949 Query # 125 use `test`; CREATE TABLE `t4` ( +# 775 Table_map # 166 table_id: # (test.t3) +# 816 Write_rows # 210 table_id: # flags: STMT_END_F +# 860 Xid # 887 COMMIT /* XID */ +# 887 Query # 955 use `test`; BEGIN +# 955 Query # 125 use `test`; CREATE TABLE `t4` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 1074 Table_map # 164 table_id: # (test.t4) -# 1113 Write_rows # 208 table_id: # flags: STMT_END_F -# 1157 Xid # 1184 COMMIT /* XID */ -# 1184 Table_map # 1223 table_id: # (test.t1) -# 1223 Write_rows # 1267 table_id: # flags: STMT_END_F +# 1080 Table_map # 166 table_id: # (test.t4) +# 1121 Write_rows # 210 table_id: # flags: STMT_END_F +# 1165 Xid # 1192 COMMIT /* XID */ +# 1192 Table_map # 1233 table_id: # (test.t1) +# 1233 Write_rows # 1277 table_id: # flags: STMT_END_F SHOW TABLES; Tables_in_test t1 @@ -367,15 +367,15 @@ SHOW BINLOG EVENTS; Log_name Pos Event_type Server_id End_log_pos Info # 4 Format_desc # 106 Server ver: #, Binlog ver: # # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT) -# 192 Table_map # 231 table_id: # (test.t1) -# 231 Write_rows # 275 table_id: # flags: STMT_END_F -# 275 Query # 375 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB -# 375 Query # 443 use `test`; BEGIN -# 443 Table_map # 39 table_id: # (test.t2) -# 482 Write_rows # 83 table_id: # flags: STMT_END_F -# 526 Table_map # 122 table_id: # (test.t2) -# 565 Write_rows # 161 table_id: # flags: STMT_END_F -# 604 Xid # 631 COMMIT /* XID */ +# 192 Table_map # 233 table_id: # (test.t1) +# 233 Write_rows # 277 table_id: # flags: STMT_END_F +# 277 Query # 377 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB +# 377 Query # 445 use `test`; BEGIN +# 445 Table_map # 41 table_id: # (test.t2) +# 486 Write_rows # 85 table_id: # flags: STMT_END_F +# 530 Table_map # 126 table_id: # (test.t2) +# 571 Write_rows # 165 table_id: # flags: STMT_END_F +# 610 Xid # 637 COMMIT /* XID */ SELECT * FROM t2 ORDER BY a; a 1 @@ -394,10 +394,10 @@ INSERT INTO t2 SELECT a+2 FROM tt2; ROLLBACK; SELECT * FROM t2 ORDER BY a; a -SHOW BINLOG EVENTS FROM 631; +SHOW BINLOG EVENTS FROM 637; Log_name Pos Event_type Server_id End_log_pos Info -# 631 Query # 80 use `test`; TRUNCATE TABLE t2 -# 711 Xid # 738 COMMIT /* XID */ +# 637 Query # 80 use `test`; TRUNCATE TABLE t2 +# 717 Xid # 744 COMMIT /* XID */ SELECT * FROM t2 ORDER BY a; a DROP TABLE t1,t2; diff --git a/mysql-test/r/rpl_row_flsh_tbls.result b/mysql-test/r/rpl_row_flsh_tbls.result index 942a6b83bf6..072f15cbbd3 100644 --- a/mysql-test/r/rpl_row_flsh_tbls.result +++ b/mysql-test/r/rpl_row_flsh_tbls.result @@ -12,13 +12,13 @@ create table t4 (a int); insert into t4 select * from t3; rename table t1 to t5, t2 to t1; flush no_write_to_binlog tables; -SHOW BINLOG EVENTS FROM 619 ; +SHOW BINLOG EVENTS FROM 623 ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1 select * from t3; a flush tables; -SHOW BINLOG EVENTS FROM 619 ; +SHOW BINLOG EVENTS FROM 623 ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1 master-bin.000001 # Query 1 # use `test`; flush tables diff --git a/mysql-test/r/rpl_row_inexist_tbl.result b/mysql-test/r/rpl_row_inexist_tbl.result index 4412a1fa75c..4065809a63e 100644 --- a/mysql-test/r/rpl_row_inexist_tbl.result +++ b/mysql-test/r/rpl_row_inexist_tbl.result @@ -39,7 +39,7 @@ Replicate_Wild_Ignore_Table Last_Errno 1146 Last_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1` Skip_Counter 0 -Exec_Master_Log_Pos 524 +Exec_Master_Log_Pos 530 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/r/rpl_row_log.result b/mysql-test/r/rpl_row_log.result index 9de0d3d0ebb..b8121a9c24f 100644 --- a/mysql-test/r/rpl_row_log.result +++ b/mysql-test/r/rpl_row_log.result @@ -66,13 +66,13 @@ master-bin.000002 # Table_map 1 # table_id: # (test.t2) master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F show binary logs; Log_name File_size -master-bin.000001 1260 -master-bin.000002 377 +master-bin.000001 1266 +master-bin.000002 379 start slave; show binary logs; Log_name File_size -slave-bin.000001 1358 -slave-bin.000002 278 +slave-bin.000001 1364 +slave-bin.000002 280 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 @@ -91,9 +91,41 @@ slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=MyISAM slave-bin.000002 # Table_map 1 # table_id: # (test.t2) slave-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F -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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 377 # # master-bin.000002 Yes Yes # 0 0 377 # None 0 No # No +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.000002 +Read_Master_Log_Pos 379 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000002 +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 379 +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 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_row_log_innodb.result b/mysql-test/r/rpl_row_log_innodb.result index 4d8175142b2..92bffcd9f34 100644 --- a/mysql-test/r/rpl_row_log_innodb.result +++ b/mysql-test/r/rpl_row_log_innodb.result @@ -71,13 +71,13 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000002 # Xid 1 # COMMIT /* XID */ show binary logs; Log_name File_size -master-bin.000001 1314 -master-bin.000002 404 +master-bin.000001 1320 +master-bin.000002 406 start slave; show binary logs; Log_name File_size -slave-bin.000001 1412 -slave-bin.000002 305 +slave-bin.000001 1418 +slave-bin.000002 307 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 @@ -99,9 +99,41 @@ slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=InnoDB slave-bin.000002 # Table_map 1 # table_id: # (test.t2) slave-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F slave-bin.000002 # Xid 1 # COMMIT /* XID */ -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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 404 # # master-bin.000002 Yes Yes # 0 0 404 # None 0 No # No +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.000002 +Read_Master_Log_Pos 406 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000002 +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 406 +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 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_row_max_relay_size.result b/mysql-test/r/rpl_row_max_relay_size.result index cb1692568fc..9aca60a8ad7 100644 --- a/mysql-test/r/rpl_row_max_relay_size.result +++ b/mysql-test/r/rpl_row_max_relay_size.result @@ -30,7 +30,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58668 +Read_Master_Log_Pos 60268 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -45,7 +45,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58668 +Exec_Master_Log_Pos 60268 Relay_Log_Space # Until_Condition None Until_Log_File @@ -74,7 +74,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58668 +Read_Master_Log_Pos 60268 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -89,7 +89,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58668 +Exec_Master_Log_Pos 60268 Relay_Log_Space # Until_Condition None Until_Log_File @@ -118,7 +118,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58668 +Read_Master_Log_Pos 60268 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -133,7 +133,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58668 +Exec_Master_Log_Pos 60268 Relay_Log_Space # Until_Condition None Until_Log_File @@ -201,7 +201,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58754 +Read_Master_Log_Pos 60354 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -216,7 +216,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58754 +Exec_Master_Log_Pos 60354 Relay_Log_Space # Until_Condition None Until_Log_File @@ -241,7 +241,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 58830 +Read_Master_Log_Pos 60430 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -256,7 +256,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 58830 +Exec_Master_Log_Pos 60430 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/r/rpl_row_until.result b/mysql-test/r/rpl_row_until.result index c691185650a..c232dfcbc9f 100644 --- a/mysql-test/r/rpl_row_until.result +++ b/mysql-test/r/rpl_row_until.result @@ -21,7 +21,7 @@ n 4 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-bin.000001 311 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 # No 0 0 317 # Master master-bin.000001 311 No # No start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n @@ -31,7 +31,7 @@ n 4 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-no-such-bin.000001 291 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 # No 0 0 317 # Master master-no-such-bin.000001 291 No # No start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; select * from t2; n @@ -39,13 +39,13 @@ n 2 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 590 # Relay slave-relay-bin.000004 728 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 # No 0 0 594 # Relay slave-relay-bin.000004 728 No # No start slave; stop slave; start slave until master_log_file='master-bin.000001', master_log_pos=740; 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 -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 744 # Master master-bin.000001 740 No # No +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 750 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 750 # Master master-bin.000001 740 No # No 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=561, relay_log_pos=12; diff --git a/mysql-test/r/rpl_stm_log.result b/mysql-test/r/rpl_stm_log.result index 3ee2d990159..07f66475e56 100644 --- a/mysql-test/r/rpl_stm_log.result +++ b/mysql-test/r/rpl_stm_log.result @@ -89,9 +89,41 @@ Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000002 # Query 1 # use `test`; create table t2 (n int)ENGINE=MyISAM slave-bin.000002 # Query 1 # use `test`; insert into t2 values (1) -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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 392 # # master-bin.000002 Yes Yes # 0 0 392 # None 0 No # No +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.000002 +Read_Master_Log_Pos 392 +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000002 +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 392 +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 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log DROP TABLE t1; diff --git a/mysql-test/r/rpl_truncate_7ndb.result b/mysql-test/r/rpl_truncate_7ndb.result index 62ace911e45..0b3b655b0aa 100644 --- a/mysql-test/r/rpl_truncate_7ndb.result +++ b/mysql-test/r/rpl_truncate_7ndb.result @@ -32,14 +32,14 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 106 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 106 Query 1 223 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB master-bin.000001 223 Query 1 287 BEGIN -master-bin.000001 287 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 327 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 385 Write_rows 1 157 table_id: # -master-bin.000001 444 Write_rows 1 195 table_id: # -master-bin.000001 482 Write_rows 1 233 table_id: # flags: STMT_END_F -master-bin.000001 520 Query 1 585 COMMIT -master-bin.000001 585 Query 1 665 use `test`; TRUNCATE TABLE t1 -master-bin.000001 665 Query 1 741 use `test`; DROP TABLE t1 +master-bin.000001 287 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 330 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 392 Write_rows 1 164 table_id: # +master-bin.000001 451 Write_rows 1 202 table_id: # +master-bin.000001 489 Write_rows 1 240 table_id: # flags: STMT_END_F +master-bin.000001 527 Query 1 592 COMMIT +master-bin.000001 592 Query 1 672 use `test`; TRUNCATE TABLE t1 +master-bin.000001 672 Query 1 748 use `test`; DROP TABLE t1 **** On Master **** CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB; INSERT INTO t1 VALUES (1,1), (2,2); @@ -69,27 +69,27 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 4 Format_desc 1 106 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 106 Query 1 223 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB master-bin.000001 223 Query 1 287 BEGIN -master-bin.000001 287 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 327 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 385 Write_rows 1 157 table_id: # -master-bin.000001 444 Write_rows 1 195 table_id: # -master-bin.000001 482 Write_rows 1 233 table_id: # flags: STMT_END_F -master-bin.000001 520 Query 1 585 COMMIT -master-bin.000001 585 Query 1 665 use `test`; TRUNCATE TABLE t1 -master-bin.000001 665 Query 1 741 use `test`; DROP TABLE t1 -master-bin.000001 741 Query 1 858 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB -master-bin.000001 858 Query 1 922 BEGIN -master-bin.000001 922 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 962 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 1020 Write_rows 1 157 table_id: # -master-bin.000001 1079 Write_rows 1 195 table_id: # -master-bin.000001 1117 Write_rows 1 233 table_id: # flags: STMT_END_F -master-bin.000001 1155 Query 1 1220 COMMIT -master-bin.000001 1220 Query 1 1284 BEGIN -master-bin.000001 1284 Table_map 1 40 table_id: # (test.t1) -master-bin.000001 1324 Table_map 1 98 table_id: # (mysql.ndb_apply_status) -master-bin.000001 1382 Write_rows 1 157 table_id: # -master-bin.000001 1441 Delete_rows 1 191 table_id: # -master-bin.000001 1475 Delete_rows 1 225 table_id: # flags: STMT_END_F -master-bin.000001 1509 Query 1 1574 COMMIT -master-bin.000001 1574 Query 1 1650 use `test`; DROP TABLE t1 +master-bin.000001 287 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 330 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 392 Write_rows 1 164 table_id: # +master-bin.000001 451 Write_rows 1 202 table_id: # +master-bin.000001 489 Write_rows 1 240 table_id: # flags: STMT_END_F +master-bin.000001 527 Query 1 592 COMMIT +master-bin.000001 592 Query 1 672 use `test`; TRUNCATE TABLE t1 +master-bin.000001 672 Query 1 748 use `test`; DROP TABLE t1 +master-bin.000001 748 Query 1 865 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB +master-bin.000001 865 Query 1 929 BEGIN +master-bin.000001 929 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 972 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 1034 Write_rows 1 164 table_id: # +master-bin.000001 1093 Write_rows 1 202 table_id: # +master-bin.000001 1131 Write_rows 1 240 table_id: # flags: STMT_END_F +master-bin.000001 1169 Query 1 1234 COMMIT +master-bin.000001 1234 Query 1 1298 BEGIN +master-bin.000001 1298 Table_map 1 43 table_id: # (test.t1) +master-bin.000001 1341 Table_map 1 105 table_id: # (mysql.ndb_apply_status) +master-bin.000001 1403 Write_rows 1 164 table_id: # +master-bin.000001 1462 Delete_rows 1 198 table_id: # +master-bin.000001 1496 Delete_rows 1 232 table_id: # flags: STMT_END_F +master-bin.000001 1530 Query 1 1595 COMMIT +master-bin.000001 1595 Query 1 1671 use `test`; DROP TABLE t1 diff --git a/mysql-test/t/binlog_row_mix_innodb_myisam.test b/mysql-test/t/binlog_row_mix_innodb_myisam.test index 335a05be146..03475f5bf3b 100644 --- a/mysql-test/t/binlog_row_mix_innodb_myisam.test +++ b/mysql-test/t/binlog_row_mix_innodb_myisam.test @@ -20,7 +20,7 @@ # ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction # and does not make slave to stop) flush logs; ---exec $MYSQL_BINLOG --start-position=520 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output +--exec $MYSQL_BINLOG --start-position=524 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output")) diff --git a/mysql-test/t/rpl_colSize.test b/mysql-test/t/rpl_colSize.test new file mode 100644 index 00000000000..44fb878d4d2 --- /dev/null +++ b/mysql-test/t/rpl_colSize.test @@ -0,0 +1,216 @@ +################################################################## +# rpl_colSize # +# # +# This test is designed to test the changes included in WL#3228. # +# The changes include the ability to replicate with the master # +# having columns that are smaller (shorter) than the slave. # +################################################################## + +-- source include/master-slave.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo **** Testing WL#3228 changes. **** +--echo *** Create "wider" table on slave *** +sync_slave_with_master; +STOP SLAVE; +RESET SLAVE; + +eval CREATE TABLE t1 ( + a float (47), + b double (143,9), + c decimal (65,30), + d numeric (4,0), + e bit (32), + f char (21), + g varchar (1300), + h binary (33), + j varbinary (200), + k enum ('5','6','7', '8','9','0'), + l set ('1','2','3','4','5','6','7','8','9','0','11','12','13','14','15','16','17','18','19','21','22','23','24','25','26','27','28','29'), + m TINYBLOB, + n BLOB, + o MEDIUMBLOB, + p LONGBLOB, + q TINYTEXT, + r TEXT, + s MEDIUMTEXT, + t LONGTEXT +); + +--echo *** Create same table on master but with narrow columns *** +connection master; +eval CREATE TABLE t1 ( + a float (44), + b double (10,3), + c decimal (10,2), + d numeric (3,0), + e bit (16), + f char (10), + g varchar (100), + h binary (20), + j varbinary (20), + k enum ('5','6','7'), + l set ('1','2','3','4','5','6','7','8','9','0'), + m TINYBLOB, + n BLOB, + o MEDIUMBLOB, + p LONGBLOB, + q TINYTEXT, + r TEXT, + s MEDIUMTEXT, + t LONGTEXT +); + +RESET MASTER; + +--echo *** Start replication *** +connection slave; +START SLAVE; + +--echo *** Insert data on master and display it. *** +connection master; + +INSERT INTO t1 () VALUES ( + 17.567, + 2.123, + 10.20, + 125, + hex(64), + 'TEST', + 'This is a test', + 'binary data', + 'more binary data', + '6', + '7', + "blob 1", + "blob 2", + "blob 3", + "blob 4", + "text 1", + "text 2", + "text 3", + "text 4"); + +# Replace values in columns that display differently between SBR & RBR +--replace_column 5 # 8 # +SELECT * FROM t1 ORDER BY a; + +--echo *** Select data from slave to compare *** +sync_slave_with_master; +connection slave; + +# Replace values in columns that display differently between SBR & RBR +--replace_column 5 # 8 # +SELECT * FROM t1 ORDER BY a; + +# Test boundary limits of varchar and char fields +# Master/Slave +# <256/<256 with m < s, m > s, and m == s <-- col a +# >255/<256 with m < s, m > s, and m == s <-- error will be caught in BUG#22086 +# <256/>255 with m < s, m > s, and m == s <-- col b +# >255/>255 with m < s, m > s, and m == s <-- col c +# +# Test boundary limits of CHAR fields +# Master/Slave +# <256/<256 with m < s, m > s, and m == s <-- col d +# >255/<256 with m < s, m > s, and m == s <-- error char limited to 255 chars +# <256/>255 with m < s, m > s, and m == s <-- error char limited to 255 chars +# >255/>255 with m < s, m > s, and m == s <-- error char limited to 255 chars + +connection master; +DROP TABLE t1; + +--echo Create varchar table on master +CREATE TABLE t1 ( + a VARCHAR(50), + b VARCHAR(100), + c VARCHAR(300), + d CHAR(5) +); + +sync_slave_with_master slave; + +--echo Alter varchar table on slave +ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(100); +ALTER TABLE t1 CHANGE COLUMN b b VARCHAR(400); +ALTER TABLE t1 CHANGE COLUMN c c VARCHAR(500); +ALTER TABLE t1 CHANGE COLUMN d d CHAR(100); + +connection master; + +--echo Insert some values and select them on master +INSERT INTO t1 VALUES ("This is a test of col a.", + "This is another test of col b.", + "This is a test of the large col c.", + "Col d"); +SELECT * FROM t1; +SHOW CREATE TABLE t1; + +sync_slave_with_master slave; + +--echo Insert some values and select them on slave +SELECT * FROM t1; +SHOW CREATE TABLE t1; + + +# Test boundary limits of bit fields +# m < s, m % 8 != 0, and s % 8 == 0 col a +# m < s, m % 8 == 0, and s % 8 != 0 col b +# m < s, m % 8 != 0, and s % 8 != 0 col c +# m > s, m % 8 != 0, and s % 8 == 0 <-- error will be caught in BUG#22086 +# m > s, m % 8 == 0, and s % 8 != 0 <-- error will be caught in BUG#22086 +# m > s, m % 8 != 0, and s % 8 != 0 <-- error will be caught in BUG#22086 + +connection master; +DROP TABLE t1; + +--echo Create bit table on master +CREATE TABLE t1 ( + a BIT(7), + b BIT(8), + c BIT(21), + d BIT(11), + e BIT(11) +); + +sync_slave_with_master slave; + +--echo Create bit table on slave +DROP TABLE t1; +CREATE TABLE t1 ( + a BIT(16), + b BIT(22), + c BIT(54), + d BIT(25), + e BIT(13) +); + +connection master; + +--echo Insert some values and select them on master +INSERT INTO t1 VALUES ( + b'1010101', + b'10101011', + b'101010110101010101111', + b'10101010101', + b'10101011111' + ); + +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +SHOW CREATE TABLE t1; + +sync_slave_with_master slave; + +--echo Insert some values and select them on master +SELECT BIN(a), BIN(b), BIN(c), BIN(d), BIN(e) FROM t1; +SHOW CREATE TABLE t1; + +--echo *** Cleanup *** +connection master; +DROP TABLE t1; +sync_slave_with_master; + +# END 5.1 Test Case diff --git a/mysql-test/t/rpl_row_create_table.test b/mysql-test/t/rpl_row_create_table.test index d1b26f9e3f4..d41f6b0bf69 100644 --- a/mysql-test/t/rpl_row_create_table.test +++ b/mysql-test/t/rpl_row_create_table.test @@ -72,7 +72,7 @@ CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; # Shouldn't be written to the binary log --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; # Test that INSERT-SELECT works the same way as for SBR. CREATE TABLE t7 (a INT, b INT UNIQUE); @@ -82,7 +82,7 @@ SELECT * FROM t7 ORDER BY a,b; # Should be written to the binary log --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1098; +SHOW BINLOG EVENTS FROM 1100; sync_slave_with_master; SELECT * FROM t7 ORDER BY a,b; @@ -94,7 +94,7 @@ INSERT INTO t7 SELECT a,b FROM tt4; ROLLBACK; --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1294; +SHOW BINLOG EVENTS FROM 1298; SELECT * FROM t7 ORDER BY a,b; sync_slave_with_master; SELECT * FROM t7 ORDER BY a,b; @@ -110,7 +110,7 @@ CREATE TEMPORARY TABLE tt7 SELECT 1; --query_vertical SHOW CREATE TABLE t9 --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 1390; +SHOW BINLOG EVENTS FROM 1396; sync_slave_with_master; --echo **** On Slave **** --query_vertical SHOW CREATE TABLE t8 @@ -227,7 +227,7 @@ ROLLBACK; SELECT * FROM t2 ORDER BY a; --replace_column 1 # 4 # --replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/ -SHOW BINLOG EVENTS FROM 631; +SHOW BINLOG EVENTS FROM 637; sync_slave_with_master; SELECT * FROM t2 ORDER BY a; diff --git a/mysql-test/t/rpl_row_flsh_tbls.test b/mysql-test/t/rpl_row_flsh_tbls.test index a2f9e31fc5d..bfa356fbfb4 100644 --- a/mysql-test/t/rpl_row_flsh_tbls.test +++ b/mysql-test/t/rpl_row_flsh_tbls.test @@ -1,7 +1,7 @@ # depends on the binlog output -- source include/have_binlog_format_row.inc -let $rename_event_pos= 619; +let $rename_event_pos= 623; # Bug#18326: Do not lock table for writing during prepare of statement # The use of the ps protocol causes extra table maps in the binlog, so diff --git a/sql/field.cc b/sql/field.cc index fa25871fe61..d9aa822b93f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1358,6 +1358,49 @@ bool Field::send_binary(Protocol *protocol) } +/** + Unpack a field from row data. + + This method is used to unpack a field from a master whose size + of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Pack length of the field data + + @return New pointer into memory based on from + length of the data +*/ +const char *Field::unpack(char* to, const char *from, uint param_data) +{ + uint length=pack_length(); + int from_type= 0; + /* + If from length is > 255, it has encoded data in the upper bits. Need + to mask it out. + */ + if (param_data > 255) + { + from_type= (param_data & 0xff00) >> 8U; // real_type. + param_data= param_data & 0x00ff; // length. + } + uint len= (param_data && (param_data < length)) ? + param_data : length; + /* + If the length is the same, use old unpack method. + If the param_data is 0, use the old unpack method. + This is possible if the table map was generated from a down-level + master or if the data was not available on the master. + If the real_types are not the same, use the old unpack method. + */ + if ((length == param_data) || + (param_data == 0) || + (from_type != real_type())) + return(unpack(to, from)); + memcpy(to, from, param_data > length ? length : len); + return from+len; +} + + my_decimal *Field::val_decimal(my_decimal *decimal) { /* This never have to be called */ @@ -2635,6 +2678,51 @@ uint Field_new_decimal::is_equal(create_field *new_field) (new_field->decimals == dec)); } +/** + Unpack a decimal field from row data. + + This method is used to unpack a decimal or numeric field from a master + whose size of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Precision (upper) and decimal (lower) values + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_new_decimal::unpack(char* to, + const char *from, + uint param_data) +{ + uint from_precision= (param_data & 0xff00) >> 8U; + uint from_decimal= param_data & 0x00ff; + uint length=pack_length(); + uint from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal); + uint len= (param_data && (from_pack_len < length)) ? + from_pack_len : length; + if (from_pack_len && (from_pack_len < length)) + { + /* + If the master's data is smaller than the slave, we need to convert + the binary to decimal then resize the decimal converting it back to + a decimal and write that to the raw data buffer. + */ + decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION]; + decimal_t dec; + dec.len= from_precision; + dec.buf= dec_buf; + /* + Note: bin2decimal does not change the length of the field. So it is + just the first step the resizing operation. The second step does the + resizing using the precision and decimals from the slave. + */ + bin2decimal((char *)from, &dec, from_precision, from_decimal); + decimal2bin(&dec, to, precision, decimals()); + } + else + memcpy(to, from, len); // Sizes are the same, just copy the data. + return from+len; +} /**************************************************************************** ** tiny int @@ -6294,6 +6382,37 @@ char *Field_string::pack(char *to, const char *from, uint max_length) } +/** + Unpack a string field from row data. + + This method is used to unpack a string field from a master whose size + of the field is less than that of the slave. Note that there can be a + variety of field types represented with this class. Certain types like + ENUM or SET are processed differently. Hence, the upper byte of the + @c param_data argument contains the result of field->real_type() from + the master. + + @param to Destination of the data + @param from Source of the data + @param param_data Real type (upper) and length (lower) values + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_string::unpack(char *to, + const char *from, + uint param_data) +{ + uint from_len= param_data & 0x00ff; // length. + uint length= 0; + uint f_length= (from_len < field_length) ? from_len : field_length; + DBUG_ASSERT(f_length <= 255); + length= (uint) *from++; + bitmap_set_bit(table->write_set,field_index); + store(from, length, system_charset_info); + return from+length; +} + + const char *Field_string::unpack(char *to, const char *from) { uint length; @@ -6782,6 +6901,44 @@ char *Field_varstring::pack_key_from_key_image(char *to, const char *from, } +/** + Unpack a varstring field from row data. + + This method is used to unpack a varstring field from a master + whose size of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Length bytes from the master's field data + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_varstring::unpack(char *to, + const char *from, + uint param_data) +{ + uint length; + uint l_bytes= (param_data && (param_data < field_length)) ? + (param_data <= 255) ? 1 : 2 : length_bytes; + if (l_bytes == 1) + { + to[0]= *from++; + length= to[0]; + if (length_bytes == 2) + to[1]= 0; + } + else + { + length= uint2korr(from); + to[0]= *from++; + to[1]= *from++; + } + if (length) + memcpy(to+ length_bytes, from, length); + return from+length; +} + + /* unpack field packed with Field_varstring::pack() */ @@ -7473,6 +7630,29 @@ char *Field_blob::pack(char *to, const char *from, uint max_length) } +/** + Unpack a blob field from row data. + + This method is used to unpack a blob field from a master whose size of + the field is less than that of the slave. Note: This method is included + to satisfy inheritance rules, but is not needed for blob fields. It + simply is used as a pass-through to the original unpack() method for + blob fields. + + @param to Destination of the data + @param from Source of the data + @param param_data + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_blob::unpack(char *to, + const char *from, + uint param_data) +{ + return unpack(to, from); +} + + const char *Field_blob::unpack(char *to, const char *from) { memcpy(to,from,packlength); @@ -8510,6 +8690,58 @@ char *Field_bit::pack(char *to, const char *from, uint max_length) } +/** + Unpack a bit field from row data. + + This method is used to unpack a bit field from a master whose size + of the field is less than that of the slave. + + @param to Destination of the data + @param from Source of the data + @param param_data Bit length (upper) and length (lower) values + + @return New pointer into memory based on from + length of the data +*/ +const char *Field_bit::unpack(char *to, + const char *from, + uint param_data) +{ + uint const from_len= (param_data >> 8U) & 0x00ff; + uint const from_bit_len= param_data & 0x00ff; + /* + If the master and slave have the same sizes, then use the old + unpack() method. + */ + if ((from_bit_len == bit_len) && + (from_len == bytes_in_rec)) + return(unpack(to, from)); + /* + We are converting a smaller bit field to a larger one here. + To do that, we first need to construct a raw value for the original + bit value stored in the from buffer. Then that needs to be converted + to the larger field then sent to store() for writing to the field. + Lastly the odd bits need to be masked out if the bytes_in_rec > 0. + Otherwise stray bits can cause spurious values. + */ + uint new_len= (field_length + 7) / 8; + char *value= (char *)my_alloca(new_len); + bzero(value, new_len); + uint len= from_len + ((from_bit_len > 0) ? 1 : 0); + memcpy(value + (new_len - len), from, len); + /* + Mask out the unused bits in the partial byte. + TODO: Add code to the master to always mask these bits and remove + the following. + */ + if ((from_bit_len > 0) && (from_len > 0)) + value[new_len - len]= value[new_len - len] & ((1U << from_bit_len) - 1); + bitmap_set_bit(table->write_set,field_index); + store(value, new_len, system_charset_info); + my_afree(value); + return from + len; +} + + const char *Field_bit::unpack(char *to, const char *from) { if (bit_len > 0) diff --git a/sql/field.h b/sql/field.h index 2c2640a8262..545e34bd551 100644 --- a/sql/field.h +++ b/sql/field.h @@ -342,6 +342,7 @@ public: memcpy(to,from,length); return to+length; } + virtual const char *unpack(char* to, const char *from, uint param_data); virtual const char *unpack(char* to, const char *from) { uint length=pack_length(); @@ -613,6 +614,7 @@ public: uint size_of() const { return sizeof(*this); } uint32 pack_length() const { return (uint32) bin_size; } uint is_equal(create_field *new_field); + virtual const char *unpack(char* to, const char *from, uint param_data); }; @@ -1154,6 +1156,7 @@ public: void sort_string(char *buff,uint length); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + virtual const char *unpack(char* to, const char *from, uint param_data); const char *unpack(char* to, const char *from); int pack_cmp(const char *a,const char *b,uint key_length, my_bool insert_or_update); @@ -1224,6 +1227,7 @@ public: char *pack(char *to, const char *from, uint max_length=~(uint) 0); char *pack_key(char *to, const char *from, uint max_length); char *pack_key_from_key_image(char* to, const char *from, uint max_length); + virtual const char *unpack(char* to, const char *from, uint param_data); const char *unpack(char* to, const char *from); const char *unpack_key(char* to, const char *from, uint max_length); int pack_cmp(const char *a, const char *b, uint key_length, @@ -1279,6 +1283,9 @@ public: l_char_length <= 16777215 ? 3 : 4; } } + Field_blob(uint32 packlength_arg) + :Field_longstr((char*) 0, 0, (uchar*) "", 0, NONE, "temp", system_charset_info), + packlength(packlength_arg) {} enum_field_types type() const { return MYSQL_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } @@ -1300,6 +1307,17 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return (uint32) (packlength+table->s->blob_ptr_size); } + + /** + Return the packed length without the pointer size added. + + This is used to determine the size of the actual data in the row + buffer. + + @retval The length of the raw data itself without the pointer. + */ + uint32 pack_length_no_ptr() const + { return (uint32) (packlength); } uint32 sort_length() const; inline uint32 max_data_length() const { @@ -1316,6 +1334,17 @@ public: store_length(ptr, packlength, number); } + /** + Return the packed length plus the length of the data. + + This is used to determine the size of the data plus the + packed length portion in the row data. + + @retval The length in the row plus the size of the data. + */ + uint32 get_packed_size(const uchar *ptr) + {return packlength + get_length((uint)ptr);} + inline uint32 get_length(uint row_offset=0) { return get_length(ptr+row_offset); } uint32 get_length(const char *ptr); @@ -1360,6 +1389,7 @@ public: char *pack(char *to, const char *from, uint max_length= ~(uint) 0); char *pack_key(char *to, const char *from, uint max_length); char *pack_key_from_key_image(char* to, const char *from, uint max_length); + virtual const char *unpack(char *to, const char *from, uint param_data); const char *unpack(char *to, const char *from); const char *unpack_key(char* to, const char *from, uint max_length); int pack_cmp(const char *a, const char *b, uint key_length, @@ -1534,6 +1564,7 @@ public: uint32 pack_length_in_rec() const { return bytes_in_rec; } void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + virtual const char *unpack(char *to, const char *from, uint param_data); const char *unpack(char* to, const char *from); virtual void set_default(); diff --git a/sql/log_event.cc b/sql/log_event.cc index 6565278e6d3..eb1f6aeeaf9 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5976,11 +5976,8 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) #ifdef HAVE_QUERY_CACHE query_cache.invalidate_locked_for_write(rli->tables_to_lock); #endif - const_cast(rli)->clear_tables_to_lock(); } - DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count == 0); - TABLE* table= const_cast(rli)->m_table_map.get_table(m_table_id); if (table) @@ -6076,6 +6073,13 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) } } + /* + We need to delay this clear until the table def is no longer needed. + The table def is needed in unpack_row(). + */ + if (rli->tables_to_lock && get_flags(STMT_END_F)) + const_cast(rli)->clear_tables_to_lock(); + if (error) { /* error has occured during the transaction */ slave_print_msg(ERROR_LEVEL, rli, thd->net.last_errno, @@ -6314,6 +6318,163 @@ void Rows_log_event::print_helper(FILE *file, Table_map_log_event member functions and support functions **************************************************************************/ +/** + * Calculate field metadata size based on the real_type of the field. + * + * @returns int Size of field metadata. + */ +#if !defined(MYSQL_CLIENT) +const int Table_map_log_event::calc_field_metadata_size() +{ + DBUG_ENTER("Table_map_log_event::calc_field_metadata_size"); + int size= 0; + for (unsigned int i= 0 ; i < m_table->s->fields ; i++) + { + switch (m_table->s->field[i]->real_type()) { + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + { + size++; // Store one byte here. + break; + } + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_NEWDECIMAL: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VARCHAR: + case MYSQL_TYPE_SET: + { + size= size + sizeof(short int); // Store short int here. + break; + } + default: + break; + } + } + m_field_metadata_size= size; + DBUG_PRINT("info", ("Table_map_log_event: %d bytes in field metadata.", + (int)m_field_metadata_size)); + DBUG_RETURN(m_field_metadata_size); +} +#endif /* !defined(MYSQL_CLIENT) */ + +/** + @page How replication of field metadata works. + + When a table map is created, the master first calls + Table_map_log_event::get_field_metadata_size() which calculates how many + values will be in the field metadata. Only those fields that require the + extra data are added (see table above). The master then loops through all + of the fields in the table calling the method + Table_map_log_event::get_field_metadata() which returns the values for the + field that will be saved in the metadata and replicated to the slave. Once + all fields have been processed, the table map is written to the binlog + adding the size of the field metadata and the field metadata to the end of + the body of the table map. + + When a table map is read on the slave, the field metadata is read from the + table map and passed to the table_def class constructor which saves the + field metadata from the table map into an array based on the type of the + field. Field metadata values not present (those fields that do not use extra + data) in the table map are initialized as zero (0). The array size is the + same as the columns for the table on the slave. + +*/ + +/** + Save the field metadata based on the real_type of the field. + The metadata saved depends on the type of the field. Some fields + store a single byte for pack_length() while others store two bytes + for field_length (max length). + + @retval 0 Ok. + + TODO: We may want to consider changing the encoding of the information. + Currently, the code attempts to minimize the number of bytes written to + the tablemap. There are at least two other alternatives; 1) using + net_store_length() to store the data allowing it to choose the number of + bytes that are appropriate thereby making the code much easier to + maintain (only 1 place to change the encoding), or 2) use a fixed number + of bytes for each field. The problem with option 1 is that net_store_length() + will use one byte if the value < 251, but 3 bytes if it is > 250. Thus, + for fields like CHAR which can be no larger than 255 characters, the method + will use 3 bytes when the value is > 250. Further, every value that is + encoded using 2 parts (e.g., pack_length, field_length) will be numerically + > 250 therefore will use 3 bytes for eah value. The problem with option 2 + is less wasteful for space but does waste 1 byte for every field that does + not encode 2 parts. +*/ +#if !defined(MYSQL_CLIENT) +int Table_map_log_event::save_field_metadata() +{ + DBUG_ENTER("Table_map_log_event::save_field_metadata"); + int index= 0; + for (unsigned int i= 0 ; i < m_table->s->fields ; i++) + { + switch (m_table->s->field[i]->real_type()) { + case MYSQL_TYPE_NEWDECIMAL: + { + m_field_metadata[index++]= + (uchar)((Field_new_decimal *)m_table->s->field[i])->precision; + m_field_metadata[index++]= + (uchar)((Field_new_decimal *)m_table->s->field[i])->decimals(); + break; + } + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + { + m_field_metadata[index++]= + (uchar)((Field_blob *)m_table->s->field[i])->pack_length_no_ptr(); + break; + } + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + { + m_field_metadata[index++]= (uchar)m_table->s->field[i]->pack_length(); + break; + } + case MYSQL_TYPE_BIT: + { + m_field_metadata[index++]= + (uchar)((Field_bit *)m_table->s->field[i])->bit_len; + m_field_metadata[index++]= + (uchar)((Field_bit *)m_table->s->field[i])->bytes_in_rec; + break; + } + case MYSQL_TYPE_VARCHAR: + { + short int *x= (short int *)&m_field_metadata[index]; + int2store(x, m_table->s->field[i]->field_length); + index= index + sizeof(short int); + break; + } + case MYSQL_TYPE_STRING: + { + m_field_metadata[index++]= (uchar)m_table->s->field[i]->real_type(); + m_field_metadata[index++]= m_table->s->field[i]->field_length; + break; + } + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + { + m_field_metadata[index++]= (uchar)m_table->s->field[i]->real_type(); + m_field_metadata[index++]= m_table->s->field[i]->pack_length(); + break; + } + default: + break; + } + } + DBUG_RETURN(0); +} +#endif /* !defined(MYSQL_CLIENT) */ + /* Constructor used to build an event for writing to the binary log. Mats says tbl->s lives longer than this event so it's ok to copy pointers @@ -6328,9 +6489,8 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, m_dblen(m_dbnam ? tbl->s->db.length : 0), m_tblnam(tbl->s->table_name.str), m_tbllen(tbl->s->table_name.length), - m_colcnt(tbl->s->fields), m_coltype(0), - m_table_id(tid), - m_flags(flags) + m_colcnt(tbl->s->fields), m_field_metadata(0), + m_table_id(tid), m_null_bits(0), m_flags(flags) { DBUG_ASSERT(m_table_id != ~0UL); /* @@ -6349,6 +6509,16 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, m_data_size+= m_dblen + 2; // Include length and terminating \0 m_data_size+= m_tbllen + 2; // Include length and terminating \0 m_data_size+= 1 + m_colcnt; // COLCNT and column types + m_field_metadata_size= calc_field_metadata_size(); + + /* + Now set the size of the data to the size of the field metadata array + plus one or two bytes for number of elements in the field metadata array. + */ + if (m_field_metadata_size > 255) + m_data_size+= m_field_metadata_size + 2; + else + m_data_size+= m_field_metadata_size + 1; /* If malloc fails, catched in is_valid() */ if ((m_memory= my_malloc(m_colcnt, MYF(MY_WME)))) @@ -6357,6 +6527,28 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, for (unsigned int i= 0 ; i < m_table->s->fields ; ++i) m_coltype[i]= m_table->field[i]->type(); } + + /* + Calculate a bitmap for the results of maybe_null() for all columns. + The bitmap is used to determine when there is a column from the master + that is not on the slave and is null and thus not in the row data during + replication. + */ + uint num_null_bytes= (m_table->s->fields + 7) / 8; + m_data_size+= num_null_bytes; + m_meta_memory= my_multi_malloc(MYF(MY_WME), + &m_null_bits, num_null_bytes, + &m_field_metadata, m_field_metadata_size, + NULL); + bzero(m_null_bits, num_null_bytes); + for (unsigned int i= 0 ; i < m_table->s->fields ; ++i) + if (m_table->field[i]->maybe_null()) + m_null_bits[(i / 8)]+= 1 << (i % 8); + + /* + Create an array for the field metadata and store it. + */ + save_field_metadata(); } #endif /* !defined(MYSQL_CLIENT) */ @@ -6372,8 +6564,10 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, #ifndef MYSQL_CLIENT m_table(NULL), #endif - m_memory(NULL) + m_memory(NULL), + m_field_metadata(0), m_field_metadata_size(0) { + unsigned int bytes_read= 0; DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)"); uint8 common_header_len= description_event->common_header_len; @@ -6444,6 +6638,22 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, strncpy(const_cast(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1); strncpy(const_cast(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1); memcpy(m_coltype, ptr_after_colcnt, m_colcnt); + + ptr_after_colcnt= ptr_after_colcnt + m_colcnt; + bytes_read= ptr_after_colcnt - (uchar *)buf; + DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read)); + if (bytes_read < event_len) + { + m_field_metadata_size= net_field_length(&ptr_after_colcnt); + uint num_null_bytes= (m_colcnt + 7) / 8; + m_meta_memory= my_multi_malloc(MYF(MY_WME), + &m_null_bits, num_null_bytes, + &m_field_metadata, m_field_metadata_size, + NULL); + memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size); + ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size; + memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes); + } } DBUG_VOID_RETURN; @@ -6452,6 +6662,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, Table_map_log_event::~Table_map_log_event() { + my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR)); my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR)); } @@ -6585,7 +6796,8 @@ int Table_map_log_event::do_apply_event(RELAY_LOG_INFO const *rli) inside st_relay_log_info::clear_tables_to_lock() by calling the table_def destructor explicitly. */ - new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt); + new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt, + m_field_metadata, m_field_metadata_size, m_null_bits); table_list->m_tabledef_valid= TRUE; /* @@ -6644,13 +6856,22 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file) char *const cbuf_end= net_store_length((char*) cbuf, (uint) m_colcnt); DBUG_ASSERT(static_cast(cbuf_end - cbuf) <= sizeof(cbuf)); + /* + Store the size of the field metadata. + */ + char mbuf[sizeof(m_field_metadata_size)]; + char *const mbuf_end= net_store_length(mbuf, (size_t) m_field_metadata_size); + return (my_b_safe_write(file, dbuf, sizeof(dbuf)) || my_b_safe_write(file, (const byte*)m_dbnam, m_dblen+1) || my_b_safe_write(file, tbuf, sizeof(tbuf)) || my_b_safe_write(file, (const byte*)m_tblnam, m_tbllen+1) || my_b_safe_write(file, reinterpret_cast(cbuf), cbuf_end - (char*) cbuf) || - my_b_safe_write(file, reinterpret_cast(m_coltype), m_colcnt)); + my_b_safe_write(file, reinterpret_cast(m_coltype), m_colcnt) || + my_b_safe_write(file, reinterpret_cast(mbuf), (size_t) (mbuf_end - mbuf)) || + my_b_safe_write(file, reinterpret_cast(m_field_metadata), m_field_metadata_size), + my_b_safe_write(file, reinterpret_cast(m_null_bits), (m_colcnt + 7) / 8)); } #endif diff --git a/sql/log_event.h b/sql/log_event.h index 4e43822cb38..0ac17e304ca 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -2048,6 +2048,8 @@ public: virtual int get_data_size() { return m_data_size; } #ifndef MYSQL_CLIENT + virtual const int calc_field_metadata_size(); + virtual int save_field_metadata(); virtual bool write_data_header(IO_CACHE *file); virtual bool write_data_body(IO_CACHE *file); virtual const char *get_db() { return m_dbnam; } @@ -2083,6 +2085,14 @@ private: flag_set m_flags; my_size_t m_data_size; + + uchar *m_field_metadata; // buffer for field metadata + /* + The size of field metadata buffer set by calling calc_field_metadata_size() + */ + ulong m_field_metadata_size; + uchar *m_null_bits; + gptr m_meta_memory; }; diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 4c6686cf446..d33d60300fd 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -16,6 +16,8 @@ #include "mysql_priv.h" #include "rpl_record.h" #include "slave.h" // Need to pull in slave_print_msg +#include "rpl_utility.h" +#include "rpl_rli.h" /** Pack a record of data for a table into a format suitable for @@ -190,7 +192,9 @@ unpack_row(RELAY_LOG_INFO const *rli, unsigned int null_mask= 1U; // The "current" null bits unsigned int null_bits= *null_ptr++; - for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr) + uint i= 0; + table_def *tabledef= ((RELAY_LOG_INFO*)rli)->get_tabledef(table); + for (field_ptr= begin_ptr ; field_ptr < end_ptr && *field_ptr ; ++field_ptr) { Field *const f= *field_ptr; @@ -219,14 +223,20 @@ unpack_row(RELAY_LOG_INFO const *rli, f->set_notnull(); /* - We only unpack the field if it was non-null - */ - pack_ptr= f->unpack(f->ptr, pack_ptr); + We only unpack the field if it was non-null. + Use the master's size information if available else call + normal unpack operation. + */ + if (tabledef && tabledef->field_metadata(i)) + pack_ptr= f->unpack(f->ptr, pack_ptr, tabledef->field_metadata(i)); + else + pack_ptr= f->unpack(f->ptr, pack_ptr); } bitmap_set_bit(rw_set, f->field_index); null_mask <<= 1; } + i++; } /* diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index fada45722f6..b30f8599f6a 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -19,6 +19,7 @@ #define MAX_SLAVE_ERRMSG 1024 #include "rpl_tblmap.h" +#include "rpl_utility.h" struct RPL_TABLE_LIST; @@ -305,6 +306,15 @@ typedef struct st_relay_log_info uint tables_to_lock_count; /* RBR: Count of tables to lock */ table_mapping m_table_map; /* RBR: Mapping table-id to table */ + inline table_def *get_tabledef(TABLE *tbl) + { + table_def *td= 0; + for (TABLE_LIST *ptr= tables_to_lock; ptr && !td; ptr= ptr->next_global) + if (ptr->table == tbl) + td= &((RPL_TABLE_LIST *)ptr)->m_tabledef; + return (td); + } + /* Last charset (6 bytes) seen by slave SQL thread is cached here; it helps the thread save 3 get_charset() per Query_log_event if the charset is not diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 1d7cc808f0c..143251991b5 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -15,17 +15,46 @@ #include "rpl_utility.h" -uint32 -field_length_from_packed(enum_field_types const field_type, - byte const *const data) + +/********************************************************************* + * table_def member definitions * + *********************************************************************/ + +/* + This function returns the field size in raw bytes based on the type + and the encoded field data from the master's raw data. +*/ +uint32 table_def::calc_field_size(uint col, uchar *master_data) { uint32 length; - switch (field_type) { - case MYSQL_TYPE_DECIMAL: + switch (type(col)) { case MYSQL_TYPE_NEWDECIMAL: - length= ~(uint32) 0; + length= my_decimal_get_binary_size(m_field_metadata[col] >> 8, + m_field_metadata[col] - ((m_field_metadata[col] >> 8) << 8)); break; + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + length= m_field_metadata[col]; + break; + case MYSQL_TYPE_SET: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_STRING: + { + if (((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_SET << 8)) || + ((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_ENUM << 8))) + length= m_field_metadata[col] & 0x00ff; + else + { + length= m_field_metadata[col] & 0x00ff; + if (length > 255) + length= uint2korr(master_data) + 2; + else + length= (uint) *master_data + 1; + } + break; + } case MYSQL_TYPE_YEAR: case MYSQL_TYPE_TINY: length= 1; @@ -44,12 +73,6 @@ field_length_from_packed(enum_field_types const field_type, length= 8; break; #endif - case MYSQL_TYPE_FLOAT: - length= sizeof(float); - break; - case MYSQL_TYPE_DOUBLE: - length= sizeof(double); - break; case MYSQL_TYPE_NULL: length= 0; break; @@ -57,8 +80,6 @@ field_length_from_packed(enum_field_types const field_type, length= 3; break; case MYSQL_TYPE_DATE: - length= 4; - break; case MYSQL_TYPE_TIME: length= 3; break; @@ -68,41 +89,33 @@ field_length_from_packed(enum_field_types const field_type, case MYSQL_TYPE_DATETIME: length= 8; break; - break; case MYSQL_TYPE_BIT: - length= ~(uint32) 0; + { + uint from_len= (m_field_metadata[col] >> 8U) & 0x00ff; + uint from_bit_len= m_field_metadata[col] & 0x00ff; + length= from_len + ((from_bit_len > 0) ? 1 : 0); break; - default: - /* This case should never be chosen */ - DBUG_ASSERT(0); - /* If something goes awfully wrong, it's better to get a string than die */ - case MYSQL_TYPE_STRING: - length= uint2korr(data); - break; - - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_VAR_STRING: + } case MYSQL_TYPE_VARCHAR: - length= ~(uint32) 0; // NYI + length= m_field_metadata[col] > 255 ? 2 : 1; // c&p of Field_varstring::data_length() + length+= length == 1 ? (uint32) *master_data : uint2korr(master_data); break; - case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_GEOMETRY: - length= ~(uint32) 0; // NYI + { + Field_blob fb(m_field_metadata[col]); + length= fb.get_packed_size(master_data); break; } - + default: + length= -1; + } return length; } -/********************************************************************* - * table_def member definitions * - *********************************************************************/ - /* Is the definition compatible with a table? @@ -135,8 +148,14 @@ table_def::compatible_with(RELAY_LOG_INFO const *rli_arg, TABLE *table) tsh->fields); } + /* + We now check for column type and size compatibility. + */ for (uint col= 0 ; col < cols_to_check ; ++col) { + /* + Checking types. + */ if (table->field[col]->type() != type(col)) { DBUG_ASSERT(col < size() && col < tsh->fields); diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 82992eec690..b4707a4c7bd 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -21,13 +21,11 @@ #endif #include "mysql_priv.h" +#include "my_bitmap.h" struct st_relay_log_info; typedef st_relay_log_info RELAY_LOG_INFO; -uint32 -field_length_from_packed(enum_field_types field_type, byte const *data); - /** A table definition from the master. @@ -57,19 +55,90 @@ public: @param types Array of types @param size Number of elements in array 'types' + @param field_metadata Array of extra information about fields + @param metadata_size Size of the field_metadata array + @param null_bitmap The bitmap of fields that can be null */ - table_def(field_type *types, my_size_t size) - : m_size(size), m_type(new unsigned char [size]) + table_def(field_type *types, ulong size, uchar *field_metadata, + int metadata_size, uchar *null_bitmap) + : m_size(size), m_type(0), + m_field_metadata(0), m_null_bits(0), m_memory(NULL) { + m_memory= my_multi_malloc(MYF(MY_WME), + &m_type, size, + &m_field_metadata, size * sizeof(short), + &m_null_bits, (m_size + 7) / 8, + NULL); if (m_type) memcpy(m_type, types, size); else m_size= 0; + /* + Extract the data from the table map into the field metadata array + iff there is field metadata. The variable metadata_size will be + 0 if we are replicating from an older version server since no field + metadata was written to the table map. This can also happen if + there were no fields in the master that needed extra metadata. + */ + if (m_size && metadata_size) + { + int index= 0; + for (unsigned int i= 0; i < m_size; i++) + { + switch (m_type[i]) { + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + { + /* + These types store a single byte. + */ + m_field_metadata[i]= (uchar)field_metadata[index]; + index++; + break; + } + case MYSQL_TYPE_SET: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_STRING: + { + short int x= field_metadata[index++] << 8U; // real_type + x = x + field_metadata[index++]; // pack or field length + m_field_metadata[i]= x; + break; + } + case MYSQL_TYPE_BIT: + case MYSQL_TYPE_VARCHAR: + { + /* + These types store two bytes. + */ + short int *x= (short int *)&field_metadata[index]; + m_field_metadata[i]= sint2korr(x); + index= index + sizeof(short int); + break; + } + case MYSQL_TYPE_NEWDECIMAL: + { + short int x= field_metadata[index++] << 8U; // precision + x = x + field_metadata[index++]; // decimals + m_field_metadata[i]= x; + break; + } + default: + m_field_metadata[i]= 0; + break; + } + } + } + if (m_size && null_bitmap) + memcpy(m_null_bits, null_bitmap, (m_size + 7) / 8); } ~table_def() { - if (m_type) - delete [] m_type; + my_free(m_memory, MYF(0)); #ifndef DBUG_OFF m_type= 0; m_size= 0; @@ -100,6 +169,47 @@ public: return m_type[index]; } + /* + This function allows callers to get the extra field data from the + table map for a given field. If there is no metadata for that field + or there is no extra metadata at all, the function returns 0. + + The function returns the value for the field metadata for column at + position indicated by index. As mentioned, if the field was a type + that stores field metadata, that value is returned else zero (0) is + returned. This method is used in the unpack() methods of the + corresponding fields to properly extract the data from the binary log + in the event that the master's field is smaller than the slave. + */ + uint16 field_metadata(uint index) const + { + DBUG_ASSERT(index < m_size); + if (m_field_metadata) + return m_field_metadata[index]; + else + return 0; + } + + /* + This function returns whether the field on the master can be null. + This value is derived from field->maybe_null(). + */ + my_bool maybe_null(uint index) const + { + DBUG_ASSERT(index < m_size); + return ((m_null_bits[(index / 8)] & + (1 << (index % 8))) == (1 << (index %8))); + } + + /* + This function returns the field size in raw bytes based on the type + and the encoded field data from the master's raw data. This method can + be used for situations where the slave needs to skip a column (e.g., + WL#3915) or needs to advance the pointer for the fields in the raw + data from the master to a specific column. + */ + uint32 calc_field_size(uint col, uchar *master_data); + /** Decide if the table definition is compatible with a table. @@ -122,6 +232,9 @@ public: private: my_size_t m_size; // Number of elements in the types array field_type *m_type; // Array of type descriptors + short int *m_field_metadata; + uchar *m_null_bits; + gptr m_memory; }; /** From 4375508a2dd1ff205cf47b268fce5330e59cb912 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 14:45:57 -0400 Subject: [PATCH 09/22] WL#3915 : (NDB) master's cols > slave Slave starts accepting and handling rows of master's tables which have more columns. The most important part of implementation is how to caclulate the amount of bytes to skip for unknown by slave column. To solve that issue this WL adopts results of WL#3228 which introduces an addon to table_map event that carries the necessary part of information about sizes of data of columns. mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test@stripped, 2007-07-26 21:31:54-04:00, cbell@mysql_cab_desk. +393 -0 WL#3915 master's cols > slave basic tests checking altering and skipping extra fields by slave. The fields can be of any possible types. mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: WL#3915 master's cols > slave Changed test to remove checks for error#1523 (more master cols than slave). This portion of the test is no longer needed. mysql-test/r/rpl_row_tabledefs_2myisam.result: WL#3915 master's cols > slave Corrected results from removal of checks for error#1523 (more master cols than slave). This portion of the test is no longer needed. mysql-test/r/rpl_row_tabledefs_3innodb.result: WL#3915 master's cols > slave Corrected results from removal of checks for error#1523 (more master cols than slave). This portion of the test is no longer needed. mysql-test/t/disabled.def: WL#3915 master's cols > slave Disabled the rpl_stm_extraColmaster_ndb test because statement-based replication is not supported in NDB at this time. It can be enabled when statement-based replication for NDB is released. sql/log_event.cc: WL#3915 master's cols > slave copying extra (slave's) fields returns early if master's table version is wider; removing assert in the way of master > slave cols. sql/rpl_record.cc: WL#3915 master's cols > slave adding a snippet that shift exectution curson donw the row skipping unknown by slave fields' data. sql/rpl_utility.cc: WL#3915 master's cols > slave Remove warning message for master's cols > slave. mysql-test/t/rpl_extraColmaster_innodb-master.opt: WL#3915 master's cols > slave option for innodb mysql-test/t/rpl_extraColmaster_innodb-slave.opt: WL#3915 master's cols > slave option for innodb mysql-test/t/rpl_extraColmaster_innodb.test: WL#3915 master's cols > slave Test of innodb. Test runs in both statement- and row-based replication. mysql-test/t/rpl_extraColmaster_myisam.test: WL#3915 master's cols > slave Test of myisam. Test runs in both statement- and row-based replication. mysql-test/t/rpl_row_extraColmaster_ndb.test: WL#3915 master's cols > slave Test of ndb. Test runs in row-based replication. mysql-test/r/rpl_extraColmaster_innodb.result: WL#3915 master's cols > slave new results mysql-test/t/rpl_stm_extraColmaster_ndb.test: WL#3915 master's cols > slave Test of ndb. Test runs in statement-based replication. mysql-test/r/rpl_extraColmaster_myisam.result: WL#3915 master's cols > slave new results mysql-test/r/rpl_row_extraColmaster_ndb.result: WL#3915 master's cols > slave new results mysql-test/r/rpl_stm_extraColmaster_ndb.result: WL#3915 master's cols > slave new results mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test: WL#3915 master's cols > slave basic tests checking altering and skipping extra fields by slave. The fields can be of any possible types. --- .../extra/rpl_tests/rpl_extraMaster_Col.test | 393 ++++++++++++++++++ .../extra/rpl_tests/rpl_row_tabledefs.test | 63 --- mysql-test/r/rpl_extraColmaster_innodb.result | Bin 0 -> 24444 bytes mysql-test/r/rpl_extraColmaster_myisam.result | Bin 0 -> 24444 bytes .../r/rpl_row_extraColmaster_ndb.result | Bin 0 -> 12256 bytes mysql-test/r/rpl_row_tabledefs_2myisam.result | 192 --------- mysql-test/r/rpl_row_tabledefs_3innodb.result | 192 --------- .../r/rpl_stm_extraColmaster_ndb.result | Bin 0 -> 12256 bytes mysql-test/t/disabled.def | 1 + .../t/rpl_extraColmaster_innodb-master.opt | 1 + .../t/rpl_extraColmaster_innodb-slave.opt | 1 + mysql-test/t/rpl_extraColmaster_innodb.test | 15 + mysql-test/t/rpl_extraColmaster_myisam.test | 13 + mysql-test/t/rpl_row_extraColmaster_ndb.test | 12 + mysql-test/t/rpl_stm_extraColmaster_ndb.test | 13 + sql/log_event.cc | 19 +- sql/rpl_record.cc | 25 +- sql/rpl_utility.cc | 15 - 18 files changed, 479 insertions(+), 476 deletions(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test create mode 100644 mysql-test/r/rpl_extraColmaster_innodb.result create mode 100644 mysql-test/r/rpl_extraColmaster_myisam.result create mode 100644 mysql-test/r/rpl_row_extraColmaster_ndb.result create mode 100644 mysql-test/r/rpl_stm_extraColmaster_ndb.result create mode 100644 mysql-test/t/rpl_extraColmaster_innodb-master.opt create mode 100644 mysql-test/t/rpl_extraColmaster_innodb-slave.opt create mode 100644 mysql-test/t/rpl_extraColmaster_innodb.test create mode 100644 mysql-test/t/rpl_extraColmaster_myisam.test create mode 100644 mysql-test/t/rpl_row_extraColmaster_ndb.test create mode 100644 mysql-test/t/rpl_stm_extraColmaster_ndb.test diff --git a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test new file mode 100644 index 00000000000..696bb74ec47 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test @@ -0,0 +1,393 @@ +############################################################# +# Purpose: To test having extra columns on the master WL#3915 +# engine inspecific sourced part +############################################################# + +# TODO: partition specific +# -- source include/have_partition.inc + +########### Clean up ################ +--disable_warnings +--disable_query_log +DROP TABLE IF EXISTS t1,t2,t3,t4,t31; + +--enable_query_log +--enable_warnings + +# +# Setup differently defined tables on master and slave +# + +# Def on master: t (f_1 type_m_1,... f_s type_m_s, f_s1, f_m) +# Def on slave: t (f_1 type_s_1,... f_s type_s_s) +# where type_mi,type_si (0 < i-1 &=nzFrWNCWw4U%c?|G=vUaU zBEM?*RnxCpe%1D?j$d_;+=7&(Ld&?UNFkqI%B!s6qLMYCY_HR7k>AdeyjaFnugKpY zxhLa6e>yEORp2z1ft;{2E6(Zw-5gaJApPWM_7l$(Shdea{t56_`qd#%R)zB@SoWq3a5dBZHr zPmjGLH(o$DivEYjvC&AHz6i8rpe+L(8R*JD7^qNq{qFW|3b*#I+ZM z`VXRl4 zJWopkB%f3fAMHgx;(uOsmlm|dh?kfzmh|BZmw4o^9_DdHXs1&_P8vPrWgvDQdVfa> zf|9TY!!suf0z|xlp^;QV(oKb4sl>dPgJ@hs??*=pxe{zZ-Ad$e};hcW}RlUW409nU#0>dp^x! zh~sKi9v!(8s()s~i`fKXi1VX+##GAe*SxHp5VsEk_=Pg|sw9O|3+_ zPx35-o|}zHRXjQ>#|ZSu>vTaJuBv_l)dDjeuFxHmcs>)wQL@Xtg!0E^5kJmUHa$Wo z(DH3zuUa-KH>`Rw%AflA1T;cb=|5N|{R)s*V$ z4TMkP|40{e%64;tU@sC!(D$=JQDnIjxbh({9Cvb`KFm%)HGrCeq`?Pr^IXqO9^xB1 zmRDJoE+AhvPpdS~obx;*B2sm*_DuUXkRv;pjAs4CB7aZjkWY_2>GKh-#a+hLonyoi zkPRaueSk@5MEyn{p><3fm9t}Vmu6BV)}lyj@`e;?@;IB20w&AsgmQ*T?L1kHS*cH| z+Pa26e_cDhxS~s>TBWpwZE${dw&%rEjZz)%-FW+GPLg=Fs1S{&E8OYe1QyWIUfA}# zT51S0hOLlv#XB3E4zJF{QrAVmbub>D?6rJYG!;L*&H<|-EP!k!4g=f}Yob^XVQog| z7gOLe8m(*nXRzCkRyxFJGMH{{*tNG|!TlpH=$tGMT@eCZ(`q;utBNjtMNHQ~wrV0U zLeNdVSS>T;C0!4}8VCjn3Tq=5edCd@z#_Wmb#u0lEW#9&SJLr#TmZlnb7%m#o z;`Tn%ZMeN2N}ASDN;L}nHY4vMuBIV53J}%Hi0Q9wdN~SJ??qUND$~)FMMM=K=dek& zgR%#rhUSHU8fNv5no6i~v%Qb_vlp@s@6uP;nJYD^TW#X!{ESiepr=( zRT)^7ft!*GR%KvS239?dRT&_-f^($Gh_K`msWKu}M%1jiftWi);Qvsco&6uN{~JB! zjV2ukcMj2#%+u8pmFfS8bT~n4Kw20ax@EqkYcs6McX0u}v*GJvt(H zNlhPNoCGv^OM#Sxrb3a(EYf$u`DLzdTUb%P`_$2NxuZ!-i?}HiP;YZfX_REw(vGCf z@;TPa3(X#Ec6YSPpvsY}bz^Ph8oRJ+gABAkA|K%4#jsfcZg^am4w%KvD}P1^Yqi>( z1H=YA`?X*t-5x%GNO12#N=xz%b}!0!xhi71tpY1R4`U#pvoeXAJr6=qwGC@})M`1y z>?SV?x(NW=H{=$ae`bgtQbE=ko0e%9XiL2@C7=oB{tp#Hu^U1+#b7T?F60RI#>5)H zZqb&DZKkP3zn%*rZ*x9ahG==xMA(oICSCg{_zOFNRyQI{`XAP`KXAUv#4rh=CDDPb z5T_It$P+rCl$Rh3*SmTq^`<6@I)gt#%^GGk?4HT6cl2z}m82U*dLC$pXnc%g9v`? z;!V&^ID?o=qU5VxytZAycX^OW4`wx%LwQ$RFRS)VGEmIv2*p2%sS-FfCG<|^GqU|ItL zf^%~YLXT@92 zdl6OX686d2D0wbVf$i)Kih7sLf~KaCKWVwe4K3&Mx*Y5+FUeO$btgLCDsw(;^nWG1 zT%5qgR_>;fH%9%OinYpo-Jw>QYjX1vWo~sj-Dm!0x*Wmgi#P-YHyhl}#Oh5=qUA)l zdQD3$%~0W$i|R(!}dd zF%L%cF5T3bq9={h6FraJC=l9>b)M)g?F`81D_9J;K!2AT1y)D?4LXu4HTPR@34GFK z!g?11%Z-fPunyWT#LII=UjidjgV|uT#>4@bPQ%2xp+kQR+_)WbQ)3tH#;%sD@uFO? z7r#^8X)7d%k2OkQ@K_k2e{9ExJpc%hdNC~Aa@fkOFo^Q-qSAT zsQZOQ-HVqQEb6{sD0>}LuR!4zb#GDk7Ip7g)V)RBix(kaYwATWI#|^GHWWVVQH#3Q z@C_hg1_}+Hb$}T>8fY?jwy1lHy4T)Zwy1l7lDDY)H8|R$?$_@Oe$vkU`ej3lx(D2R z&!X-rdfpzU>xbgnxwvM?n5VYSor@dxj-KtgOuA8|=dp+B|Cqyci@I0uqgvEGoP3&Z zP+8PHyy(V1yHtB)i~=U*Wl{GQJu0!I^hGdwOs DOB|dS literal 0 HcmV?d00001 diff --git a/mysql-test/r/rpl_extraColmaster_myisam.result b/mysql-test/r/rpl_extraColmaster_myisam.result new file mode 100644 index 0000000000000000000000000000000000000000..f4c258cd9eac1ca5863c0ad2988a15020f640117 GIT binary patch literal 24444 zcmeHPTW{OA5&=nzFrWNCWw4U%c?|G=vUaU zBEM?*RnxCpe%1D?j$d_;+=7&(Ld&?UNFkqI%B!s6qLMYCY_HR7k>AdeyjaFnugKpY zxhLa6e>yEORp2z1ft;{2E6(Zw-5gaJApPWM_7l$(Shdea{t56_`qd#%R)zB@SoWq3a5d1sHq zN&n0{a^nSbqv(HV925D*12HG;vk%6uZgnc#(QNH+Egt)b|9K_3$+J0Rf^G-y_whX~1roj693-L27bHVTkuOnoN6R}#NgmyX=B;8c#l}gNuIf%wJ^nP>%vg9P#Ng^j{I7!n#lv#O~zvt5& zhB&TP<93{KVODKO#7V+auWz!>c z0xjPb_Nry$RhFgMt@D9QkOdb~L4YYrDn$J#;9jJti7~W=i0r5s8P)(_> z-az;y{*QDqr))PT2=*dz1bsgn6h)Rhfh!;K!f_|}>BH;qa)^R!Cy%sJ09A|h1>YtOWQ139vj$!OMJEb{kc4*B%hlRh8OTHIw^-8n`a z0ogDj(g&D?M$~WQ5n9KzQ8_y%cWEX?Vl9faCT~cQCXcfTDPXe9PAF%n)XtODn3ejZ zs;z7I^VhZ0iz~WBs#Qu`*aqiUXM0{u)hN~B-i^19<|K(%iwe ztEGl8W7rBwSG=>q>G0}IEOlK3TnFRf$zIEcMN{#^>m0Be!UD)v;xNDsu_lTI5!PmO zelZ0uqtUw7e+Ik#Xr)7pCWGnLhFyCb7TiDLg3ihE&=n!jHLZqov8w3OSHyG;WUD3u zBLv;#i`6niUefgttbt&Vps+S_(KjBs+NgYoU2a-%jj!5YAD7~`DaDJ45#`=S z6Hs6yL8t8Vu!}@haKJ*7Y5(jJGT;y%&)XYrBtK9Z!_{P;%XX_qX1F8jF|q~rkA5o^z50j0j6Ekt!onWkk)I8;H3>1pW{8+1dXQ`@hjs z-e}T+aOV&$$vj;xQJMaaNQV=&2Bd|-p0qsI~%?(R=zIxG^tA|olTcJ zo7D6X#z{bvw-iW8Xetzm%p!dkoL}bZwuKetyH6cWmphuYw1}HR0rfVwltxK*E$v9! zET3b&ywL2yW_L%s45}QtS~u24uCWWNHpoExBk}3~_xyz*y+uvV+h zIY4Z{vtJ8V((T~`hy?c@q_iaOVE3Yom#ZSC+bXaE^e_ejIxCZ?+4CR-Rok$pN3E7K z%x?0cpql`&eM4@+`DcdcAr)kuv1yrxfwt5eQv#Y`?*C9R6uTjGQw;XPMZ%nKK z>=tdg*k+nq^y|40@;2v#Wr&t1O@s~kVA8dJg1@jMXmumPr2k<}`vd2zObn9{S`r<| z3UNwdfjprDN_h#waJ{Q%Qg3Ras5AH@)U07v!|s_3dq>aqTuHi7r00Qlhz1yTl1>7B zB1nYkq$hGASd(Zrl}RRf2s6t}q+Fo(vRi}!wt)s8HoJ$-&Ox`^6~u;(X5^rHIf&rL zF5U#)gfob_BubuZ)6OJ9Vy@C%1g140 zAV{RKT4&GpURiUV7_o|!S3xk+>{@CW)1rL6tW8F()L?AdpkU1Th?wAC{4WX z6!Tz2@6t`3DSFa4J<;>njRK+FSm%k}($0X4zJkSo3-ounQDAlC-=HI@QggrcmcS=% zCaiZMu-wSl4eOxoLcBa@^d&GdHJA-XYfKz~=`>878#?sIz>V7>H#K(AZtQBg8ZXKP zd+|Hfowh=P_*kO^29JdS`p0&B*aLt7sTae-Er+el3WF#QFPgokc}c`!)N8E~i;^1m z@H!pNRVAWPriVQS)e(3`IKz8N5-}2b^3j$ddh9_r;4<=_A4e!eWYhy-AT zsQZOQ-HVqQEb6{sD0>}LuR!4zb#GDk7Ip7g)V)RBix(kaYwATWI#|^GHWWVVQH#3Q z@C_hg1_}+Hb$}T>8fY?jwy1lHy4T)Zwy1l7lDDY)H8|R$?$_@Oe$vkU`ej3lx(D2R z&!X-rdfpzU>xbgnxwvM?n5VYSor@dxj-KtgOuA8|=dp+B|Cqyci@I0uqgvEGoP3&Z zP+8PHyy(V1yHtB)i~=U*Wl{GQJu0!I^hGdwOs D-KUy# literal 0 HcmV?d00001 diff --git a/mysql-test/r/rpl_row_extraColmaster_ndb.result b/mysql-test/r/rpl_row_extraColmaster_ndb.result new file mode 100644 index 0000000000000000000000000000000000000000..30332e9e7c8d3ee8084ec8aa2d8b8a9d3e1df72c GIT binary patch literal 12256 zcmeGiU2oes@?NFK1MZ#JeNa+pvl1nLCGdmexVy$WPR@3^S6~4{iK#@0BL$M&Huvjq zhF=yHJ9X3UwGXz_nj(iY=&^vLrZm)LPrObHLyW3$0@=D2p;;uQ20fVbl|nGOCkgGPspF2=u|jxJ8&!S~4N zaCXoPfNt#j6)VVr?-KFn#7SP1uvz~I<~dLIMS>5|TxP5E zmXRzbchTcxlCq+J5$6NTpGX{)gEmMkT4o;{HAj*-VGj}}S60OX4n;*x{FCF0L1?~)uT27+R? ze87iqO!35CJuae>A=B{|#9@~>Daf2dKHjmMk=XCT@hsSq0g%|BZwwVMbW@TydN9iu zAR5=e{on)y$%?5J2UZ+fal?w6R@}1UwiS0Q5IFef+tk9ZU@$b0wea&2TP@>ot$*;( zzpku*hVSga!Y}6?{N4lC;ODi-io5KixXf_GQMoEkPV6aanfdTyK7}4;{cN9e#WDXq zD@x0!ts@Vu@$CtV7IR4s!7j4`=ug-(dYbEL)s8AaW!@I_dS{bWnkMP3^_~@SyVHM<=GEQ_ zdt4?ru>bj4Ha|PHU=gZgc$;Q9^c$T3HA9WO0q|M>pUHB8Xg3c?^m1?nyq^#9Jk2c6 zRu5Tj+0*;vaoz{j0BQ<`2A|l?OPrfNMmKntS816nVP3jO$|Oszah5XKsTo{(M*e#0 zWT(^7ytiCtAK3!tReSqAaiX=p%c#7wj6MdkVRR&qa0!jBKiCuOj%%Z0e#-8WREfk| z6mcc*Sf0dB^C`>WvdsI485XtkWi@VP^-|fUQKMgP)Xpxh&^~GtRk3P=@zwc(6QLSK z9q!yXhh)LxXtgW}cB6Sa8}z|?jt=~m+o_EDaAUZ6M00mOI2&G_OFP#gfORk#_79pa zSWJzNu4jNL1nbAmu~qq^sp}E&RI)?_b<~1m942sEx)mzwnik z+TJdy-@t8#t%L814sVkXsRdeuoPl!=eQnX24bSnZLxh)&*VN-)I(LSvelq1=vvi^T zz&ss4l+S{o-;j?Ayh$J^7$No+nS$OLNjUA3`yC>eLOtG^&U)vUFoF8;IDRkJPbq&A zvuVH|Bn=vp_k-R9r!@4b!&zZRQ~3B?rP0><9C56zb!p(aEe_rxLOa87;1N{EgsZJ> z>NxN<_X4Wrl&fY$5un}^7&d8i(D48iRw573zI@$5LrXMmv<`{**oUyBtx*a6+Neat zC#bG#@lLQ6vkr5r(T$FC>UhGfcy^APj5rLqZ+~SZ=1K%Ugf;?|4VXu=f0+t0L1n<0?;YDk_JAfCjPYHR zL%eLnw^YZsBD%ydQU#c{2r$vzkq(K6!&?X<2#x|tVv=-i2zYsT+mfD>Yd;SzZ4q1| zwLrK(9!8j3s3FL%)J~ME@-|RvOC!2P}RxR*jPKca2Hf9kb%}`Cz+UgpeMjv|t|~V^Ks8t31L~3aI}sr2v4p zG7cJD2U@VS4F)}EHmzZLljS)E{*ba^w-E4i|MM6Hxr*3yNPVwj=Zz}?TQGAzD26fv zf>|&~ekm(XAQ>hN0RIWLe0cUuTm1SgLY&R>zy={bzBa(n<3{JW(LU;Q zIuh7$(2NQN7)iNRTAMstrNQ{MArDEq zDu_5eP`!q$D^Q7@3oeo}d4SwFKPAT&Bap)0ps07r5i}|q`HRdg4J$KW*5%-DIdQhi z%R9;Zy)qZahW~5f72*WJwT?Blym9E4RP0`vuNk^m<`ubljWXZsa?CA%H(gF3^CDk- zLYNI=N*4$k&1{PKdv z?PWGKbir=uYO}&u&4OI~i))86K8#8DK4ht#u_xSJ)8h7*_p9PQ{s3iwJQJkr4%N$x zMz>*pRFz@SZLX^n6*TSA^*Fp&RaJ~?-0$-899hE%@9>_31RMn4e6&;xUwdEzE@dCZ z>j+&18FZnTaYKsD3)@y-)!PIPxrtINuDE8rzM@t)S*xRjWgB&sK*4wpYtI2}qISU8 oRTZtjt6=fGH=PY8^UI6LY+tu13LH0=C+_POvG}n6t?L&52gvr;R{#J2 literal 0 HcmV?d00001 diff --git a/mysql-test/r/rpl_row_tabledefs_2myisam.result b/mysql-test/r/rpl_row_tabledefs_2myisam.result index e41f8be055b..864dfa3e910 100644 --- a/mysql-test/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/r/rpl_row_tabledefs_2myisam.result @@ -140,198 +140,6 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; -INSERT INTO t9 VALUES (2); -INSERT INTO t2 VALUES (2,4); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (4); -INSERT INTO t4 VALUES (4); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (5); -INSERT INTO t5 VALUES (5,10,25); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (6); -INSERT INTO t6 VALUES (6,12,36); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (6); -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 INSERT INTO t7 VALUES (1),(2),(3); INSERT INTO t8 VALUES (1),(2),(3); SELECT * FROM t7 ORDER BY a; diff --git a/mysql-test/r/rpl_row_tabledefs_3innodb.result b/mysql-test/r/rpl_row_tabledefs_3innodb.result index 72c088d5a6b..2850d709b83 100644 --- a/mysql-test/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/r/rpl_row_tabledefs_3innodb.result @@ -140,198 +140,6 @@ Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; -INSERT INTO t9 VALUES (2); -INSERT INTO t2 VALUES (2,4); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (4); -INSERT INTO t4 VALUES (4); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (5); -INSERT INTO t5 VALUES (5,10,25); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (6); -INSERT INTO t6 VALUES (6,12,36); -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 No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1523 -Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 -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 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (6); -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 INSERT INTO t7 VALUES (1),(2),(3); INSERT INTO t8 VALUES (1),(2),(3); SELECT * FROM t7 ORDER BY a; diff --git a/mysql-test/r/rpl_stm_extraColmaster_ndb.result b/mysql-test/r/rpl_stm_extraColmaster_ndb.result new file mode 100644 index 0000000000000000000000000000000000000000..30332e9e7c8d3ee8084ec8aa2d8b8a9d3e1df72c GIT binary patch literal 12256 zcmeGiU2oes@?NFK1MZ#JeNa+pvl1nLCGdmexVy$WPR@3^S6~4{iK#@0BL$M&Huvjq zhF=yHJ9X3UwGXz_nj(iY=&^vLrZm)LPrObHLyW3$0@=D2p;;uQ20fVbl|nGOCkgGPspF2=u|jxJ8&!S~4N zaCXoPfNt#j6)VVr?-KFn#7SP1uvz~I<~dLIMS>5|TxP5E zmXRzbchTcxlCq+J5$6NTpGX{)gEmMkT4o;{HAj*-VGj}}S60OX4n;*x{FCF0L1?~)uT27+R? ze87iqO!35CJuae>A=B{|#9@~>Daf2dKHjmMk=XCT@hsSq0g%|BZwwVMbW@TydN9iu zAR5=e{on)y$%?5J2UZ+fal?w6R@}1UwiS0Q5IFef+tk9ZU@$b0wea&2TP@>ot$*;( zzpku*hVSga!Y}6?{N4lC;ODi-io5KixXf_GQMoEkPV6aanfdTyK7}4;{cN9e#WDXq zD@x0!ts@Vu@$CtV7IR4s!7j4`=ug-(dYbEL)s8AaW!@I_dS{bWnkMP3^_~@SyVHM<=GEQ_ zdt4?ru>bj4Ha|PHU=gZgc$;Q9^c$T3HA9WO0q|M>pUHB8Xg3c?^m1?nyq^#9Jk2c6 zRu5Tj+0*;vaoz{j0BQ<`2A|l?OPrfNMmKntS816nVP3jO$|Oszah5XKsTo{(M*e#0 zWT(^7ytiCtAK3!tReSqAaiX=p%c#7wj6MdkVRR&qa0!jBKiCuOj%%Z0e#-8WREfk| z6mcc*Sf0dB^C`>WvdsI485XtkWi@VP^-|fUQKMgP)Xpxh&^~GtRk3P=@zwc(6QLSK z9q!yXhh)LxXtgW}cB6Sa8}z|?jt=~m+o_EDaAUZ6M00mOI2&G_OFP#gfORk#_79pa zSWJzNu4jNL1nbAmu~qq^sp}E&RI)?_b<~1m942sEx)mzwnik z+TJdy-@t8#t%L814sVkXsRdeuoPl!=eQnX24bSnZLxh)&*VN-)I(LSvelq1=vvi^T zz&ss4l+S{o-;j?Ayh$J^7$No+nS$OLNjUA3`yC>eLOtG^&U)vUFoF8;IDRkJPbq&A zvuVH|Bn=vp_k-R9r!@4b!&zZRQ~3B?rP0><9C56zb!p(aEe_rxLOa87;1N{EgsZJ> z>NxN<_X4Wrl&fY$5un}^7&d8i(D48iRw573zI@$5LrXMmv<`{**oUyBtx*a6+Neat zC#bG#@lLQ6vkr5r(T$FC>UhGfcy^APj5rLqZ+~SZ=1K%Ugf;?|4VXu=f0+t0L1n<0?;YDk_JAfCjPYHR zL%eLnw^YZsBD%ydQU#c{2r$vzkq(K6!&?X<2#x|tVv=-i2zYsT+mfD>Yd;SzZ4q1| zwLrK(9!8j3s3FL%)J~ME@-|RvOC!2P}RxR*jPKca2Hf9kb%}`Cz+UgpeMjv|t|~V^Ks8t31L~3aI}sr2v4p zG7cJD2U@VS4F)}EHmzZLljS)E{*ba^w-E4i|MM6Hxr*3yNPVwj=Zz}?TQGAzD26fv zf>|&~ekm(XAQ>hN0RIWLe0cUuTm1SgLY&R>zy={bzBa(n<3{JW(LU;Q zIuh7$(2NQN7)iNRTAMstrNQ{MArDEq zDu_5eP`!q$D^Q7@3oeo}d4SwFKPAT&Bap)0ps07r5i}|q`HRdg4J$KW*5%-DIdQhi z%R9;Zy)qZahW~5f72*WJwT?Blym9E4RP0`vuNk^m<`ubljWXZsa?CA%H(gF3^CDk- zLYNI=N*4$k&1{PKdv z?PWGKbir=uYO}&u&4OI~i))86K8#8DK4ht#u_xSJ)8h7*_p9PQ{s3iwJQJkr4%N$x zMz>*pRFz@SZLX^n6*TSA^*Fp&RaJ~?-0$-899hE%@9>_31RMn4e6&;xUwdEzE@dCZ z>j+&18FZnTaYKsD3)@y-)!PIPxrtINuDE8rzM@t)S*xRjWgB&sK*4wpYtI2}qISU8 oRTZtjt6=fGH=PY8^UI6LY+tu13LH0=C+_POvG}n6t?L&52gvr;R{#J2 literal 0 HcmV?d00001 diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 0b17e47fead..a2358294a83 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -32,6 +32,7 @@ rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb faile rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly synchronization : Bug#24529 Test 'synchronization' fails on Mac pushbuild; Also on Linux 64 bit. rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset +rpl_stm_extraColmaster_ndb : WL#3915 : Statement-based replication not supported in ndb. Enable test when supported. # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events diff --git a/mysql-test/t/rpl_extraColmaster_innodb-master.opt b/mysql-test/t/rpl_extraColmaster_innodb-master.opt new file mode 100644 index 00000000000..627becdbfb5 --- /dev/null +++ b/mysql-test/t/rpl_extraColmaster_innodb-master.opt @@ -0,0 +1 @@ +--innodb diff --git a/mysql-test/t/rpl_extraColmaster_innodb-slave.opt b/mysql-test/t/rpl_extraColmaster_innodb-slave.opt new file mode 100644 index 00000000000..1338b6eba04 --- /dev/null +++ b/mysql-test/t/rpl_extraColmaster_innodb-slave.opt @@ -0,0 +1 @@ + --innodb diff --git a/mysql-test/t/rpl_extraColmaster_innodb.test b/mysql-test/t/rpl_extraColmaster_innodb.test new file mode 100644 index 00000000000..082c22329fa --- /dev/null +++ b/mysql-test/t/rpl_extraColmaster_innodb.test @@ -0,0 +1,15 @@ +############################################################# +# Purpose: To test having extra columns on the master WL#3915 +############################################################# +-- source include/master-slave.inc +-- source include/have_innodb.inc + +let $engine_type = 'InnoDB'; + +set binlog_format=row; +-- source extra/rpl_tests/rpl_extraMaster_Col.test + +set binlog_format=statement; +-- source extra/rpl_tests/rpl_extraMaster_Col.test + + diff --git a/mysql-test/t/rpl_extraColmaster_myisam.test b/mysql-test/t/rpl_extraColmaster_myisam.test new file mode 100644 index 00000000000..5bbd7953294 --- /dev/null +++ b/mysql-test/t/rpl_extraColmaster_myisam.test @@ -0,0 +1,13 @@ +############################################################# +# Purpose: To test having extra columns on the master WL#3915 +############################################################# +-- source include/master-slave.inc + +let $engine_type = 'MyISAM'; + +set binlog_format=row; +-- source extra/rpl_tests/rpl_extraMaster_Col.test + +set binlog_format=statement; +-- source extra/rpl_tests/rpl_extraMaster_Col.test + diff --git a/mysql-test/t/rpl_row_extraColmaster_ndb.test b/mysql-test/t/rpl_row_extraColmaster_ndb.test new file mode 100644 index 00000000000..b91947e52e2 --- /dev/null +++ b/mysql-test/t/rpl_row_extraColmaster_ndb.test @@ -0,0 +1,12 @@ +########################################### +# Purpose: Wrapper for rpl_extraMaster_Col.test +# Using NDB +########################################### +-- source include/have_ndb.inc +-- source include/ndb_master-slave.inc +-- source include/have_binlog_format_row.inc + +let $engine_type = 'NDB'; + +-- source extra/rpl_tests/rpl_extraMaster_Col.test + diff --git a/mysql-test/t/rpl_stm_extraColmaster_ndb.test b/mysql-test/t/rpl_stm_extraColmaster_ndb.test new file mode 100644 index 00000000000..84734204439 --- /dev/null +++ b/mysql-test/t/rpl_stm_extraColmaster_ndb.test @@ -0,0 +1,13 @@ +########################################### +# Purpose: Wrapper for rpl_extraMaster_Col.test +# Using NDB +########################################### +-- source include/have_ndb.inc +-- source include/ndb_master-slave.inc +-- source include/have_binlog_format_statement.inc + +let $engine_type = 'NDB'; + +-- source extra/rpl_tests/rpl_extraMaster_Col.test + + diff --git a/sql/log_event.cc b/sql/log_event.cc index eb1f6aeeaf9..c9980634476 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7067,6 +7067,7 @@ copy_extra_record_fields(TABLE *table, my_size_t master_reclength, my_ptrdiff_t master_fields) { + DBUG_ENTER("copy_extra_record_fields(table, master_reclen, master_fields)"); DBUG_PRINT("info", ("Copying to 0x%lx " "from field %lu at offset %lu " "to field %d at offset %lu", @@ -7077,6 +7078,10 @@ copy_extra_record_fields(TABLE *table, Copying the extra fields of the slave that does not exist on master into record[0] (which are basically the default values). */ + + if (table->s->fields < (uint) master_fields) + DBUG_RETURN(0); + DBUG_ASSERT(master_reclength <= table->s->reclength); if (master_reclength < table->s->reclength) bmove_align(table->record[0] + master_reclength, @@ -7134,7 +7139,7 @@ copy_extra_record_fields(TABLE *table, } } } - return 0; // All OK + DBUG_RETURN(0); // All OK } #define DBUG_PRINT_BITSET(N,FRM,BS) \ @@ -7723,12 +7728,6 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, { int error; DBUG_ASSERT(row_start && row_end); - /* - This assertion actually checks that there is at least as many - columns on the slave as on the master. - */ - DBUG_ASSERT(table->s->fields >= m_width); - error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, &m_master_reclength, table->read_set, DELETE_ROWS_EVENT); /* @@ -7897,12 +7896,6 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, { int error; DBUG_ASSERT(row_start && row_end); - /* - This assertion actually checks that there is at least as many - columns on the slave as on the master. - */ - DBUG_ASSERT(table->s->fields >= m_width); - /* We need to perform some juggling below since unpack_row() always unpacks into table->record[0]. For more information, see the diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index d33d60300fd..db79a5dfd77 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -144,7 +144,8 @@ pack_row(TABLE *table, MY_BITMAP const* cols, @param rli Relay log info @param table Table to unpack into @param colcnt Number of columns to read from record - @param row Packed row data + @param row_data + Packed row data @param cols Pointer to columns data to fill in @param row_end Pointer to variable that will hold the value of the one-after-end position for the row @@ -239,6 +240,28 @@ unpack_row(RELAY_LOG_INFO const *rli, i++; } + /* + throw away master's extra fields + */ + uint max_cols= min(tabledef->size(), cols->n_bits); + for (; i < max_cols; i++) + { + if (bitmap_is_set(cols, i)) + { + if ((null_mask & 0xFF) == 0) + { + DBUG_ASSERT(null_ptr < row_data + master_null_byte_count); + null_mask= 1U; + null_bits= *null_ptr++; + } + DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set + + if (!((null_bits & null_mask) && tabledef->maybe_null(i))) + pack_ptr+= tabledef->calc_field_size(i, (uchar *) pack_ptr); + null_mask <<= 1; + } + } + /* We should now have read all the null bytes, otherwise something is really wrong. diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 143251991b5..91d045b040b 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -133,21 +133,6 @@ table_def::compatible_with(RELAY_LOG_INFO const *rli_arg, TABLE *table) TABLE_SHARE const *const tsh= table->s; - /* - To get proper error reporting for all columns of the table, we - both check the width and iterate over all columns. - */ - if (tsh->fields < size()) - { - DBUG_ASSERT(tsh->db.str && tsh->table_name.str); - error= 1; - slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF, - "Table width mismatch - " - "received %u columns, %s.%s has %u columns", - (uint) size(), tsh->db.str, tsh->table_name.str, - tsh->fields); - } - /* We now check for column type and size compatibility. */ From 4352ec45d7a5811dab9b5e95b1fb842cb1f9292b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 16:58:23 -0400 Subject: [PATCH 10/22] WL#3915 : (NDB) master's cols > slave Minor change to fix compile problems on 64-bit. --- sql/field.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.h b/sql/field.h index 545e34bd551..d66d9538139 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1343,7 +1343,7 @@ public: @retval The length in the row plus the size of the data. */ uint32 get_packed_size(const uchar *ptr) - {return packlength + get_length((uint)ptr);} + {return packlength + get_length((const char *)ptr);} inline uint32 get_length(uint row_offset=0) { return get_length(ptr+row_offset); } From 372c9a7743c1a2f450587de1b9d0494287f4d03e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2007 23:11:36 -0400 Subject: [PATCH 11/22] WL#3915 : (NDB) master's cols > slave Patch corrects minor test anomolies and build warnings. mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test: WL#3915 : (NDB) master's cols > slave Patch masks out the port number in the show slave status results. mysql-test/r/rpl_extraColmaster_innodb.result: WL#3915 : (NDB) master's cols > slave New result file from changed test. mysql-test/r/rpl_extraColmaster_myisam.result: WL#3915 : (NDB) master's cols > slave New result file from changed test. mysql-test/r/rpl_row_extraColmaster_ndb.result: WL#3915 : (NDB) master's cols > slave New result file from changed test. sql/field.cc: WL#3915 : (NDB) master's cols > slave Removed warning for unused parameter. Parameter was include for assertion and future changes to string class. --- .../extra/rpl_tests/rpl_extraMaster_Col.test | 4 ++-- mysql-test/r/rpl_extraColmaster_innodb.result | Bin 24444 -> 24418 bytes mysql-test/r/rpl_extraColmaster_myisam.result | Bin 24444 -> 24418 bytes .../r/rpl_row_extraColmaster_ndb.result | Bin 12256 -> 12243 bytes sql/field.cc | 3 ++- 5 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test index 696bb74ec47..29ff93986d5 100644 --- a/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test +++ b/mysql-test/extra/rpl_tests/rpl_extraMaster_Col.test @@ -99,7 +99,7 @@ connection master; #connection slave; sync_slave_with_master; ---replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # --query_vertical show slave status; select * from t1 order by f3; @@ -373,7 +373,7 @@ connection master; select * from t31; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # --query_vertical show slave status; #### Clean Up #### diff --git a/mysql-test/r/rpl_extraColmaster_innodb.result b/mysql-test/r/rpl_extraColmaster_innodb.result index 231732de7e062e6cd4ef2cc6909b0eae2384f390..27d6592a7ad79b6c3fb6c62a1071a720e92d7ed1 100644 GIT binary patch delta 47 lcmeyfkMYqy#tkP~7?n3q)GcS)yvxi<4a{E0h9OkS1OUrJ5n%uT delta 78 zcmaE~kMYkw#tkP~SS*bV%r?J`DP`Jh&+eke?dupE;u;hm;2#tM5&fxeNl+00g}@vp diff --git a/mysql-test/r/rpl_extraColmaster_myisam.result b/mysql-test/r/rpl_extraColmaster_myisam.result index f4c258cd9eac1ca5863c0ad2988a15020f640117..9a77ae6ca195834d9decf422c054230dc783f3b5 100644 GIT binary patch delta 47 lcmeyfkMYqy#tkP~7?n3q)GcS)yvxi<4a{E0h9OkS1OUrJ5n%uT delta 78 zcmaE~kMYkw#tkP~SS*bV%r?J`DP`Jh&+eke?dupE;u;hm;2#tM5&fxeNl+00g}@vp diff --git a/mysql-test/r/rpl_row_extraColmaster_ndb.result b/mysql-test/r/rpl_row_extraColmaster_ndb.result index 30332e9e7c8d3ee8084ec8aa2d8b8a9d3e1df72c..230b880e46f76449988aeb95120343d4606e376d 100644 GIT binary patch delta 26 ccmaD5e>r}`dKO0I&Dpx8Oq(^>E!3cF0F8YJ;Q#;t delta 34 ocmcZ{{~&(DdKMN-V*|6z8(7wAaQiw2hqwmC2lxkt00l~!0O)iKKmY&$ diff --git a/sql/field.cc b/sql/field.cc index d9aa822b93f..0d081f45dbf 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6404,7 +6404,8 @@ const char *Field_string::unpack(char *to, { uint from_len= param_data & 0x00ff; // length. uint length= 0; - uint f_length= (from_len < field_length) ? from_len : field_length; + uint f_length; + f_length= (from_len < field_length) ? from_len : field_length; DBUG_ASSERT(f_length <= 255); length= (uint) *from++; bitmap_set_bit(table->write_set,field_index); From 259fd485607cf3eeee90ebc7500f0267d28c07d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Jul 2007 11:30:50 -0400 Subject: [PATCH 12/22] WL#3228 (NDB) : RBR using different table defs on slave/master Patch for PB testing errors. sql/rpl_utility.h: WL#3228 (NDB) : RBR using different table defs on slave/master This patch corrects a problem detected on 64-bit platforms with BIT and VARCHAR fields. --- sql/rpl_utility.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index b4707a4c7bd..b94d0510a20 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -110,13 +110,19 @@ public: break; } case MYSQL_TYPE_BIT: + { + short int x= field_metadata[index++]; + x = x + (field_metadata[index++] << 8U); + m_field_metadata[i]= x; + break; + } case MYSQL_TYPE_VARCHAR: { /* These types store two bytes. */ - short int *x= (short int *)&field_metadata[index]; - m_field_metadata[i]= sint2korr(x); + uint16 *x= (uint16 *)&field_metadata[index]; + m_field_metadata[i]= *x; index= index + sizeof(short int); break; } From 3c631d7b7be1651295ec486066aa1a9027a571ce Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Jul 2007 18:46:21 -0400 Subject: [PATCH 13/22] WL#3228 (NDB) : RBR using different table defs on slave/master This patch changes the code to comply with different word order on Solaris --- sql/rpl_utility.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index b94d0510a20..e4f9690cf61 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -122,8 +122,12 @@ public: These types store two bytes. */ uint16 *x= (uint16 *)&field_metadata[index]; +#ifdef WORDS_BIGENDIAN + m_field_metadata[i]= sint2korr(x); +#else m_field_metadata[i]= *x; - index= index + sizeof(short int); +#endif + index= index + sizeof(short); break; } case MYSQL_TYPE_NEWDECIMAL: From 6b0015635fddd58a846a751d61928e522f24e81b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Jul 2007 14:06:11 -0400 Subject: [PATCH 14/22] WL#3228 (NDB) : RBR using different table defs on slave/master This patch corrects a incorrect type conversion during encoding and decoding the length for VARCHAR fields. sql/log_event.cc: WL#3228 (NDB) : RBR using different table defs on slave/master This patch changes the encoding of the 16-bit length value for VARCHAR field correcting an undetected type conflict. sql/rpl_utility.h: WL#3228 (NDB) : RBR using different table defs on slave/master This patch changes the decoding of the 16-bit length value for VARCHAR field correcting an undetected type conflict. --- sql/log_event.cc | 4 ++-- sql/rpl_utility.h | 10 +++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index c9980634476..2ca915b0999 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6449,8 +6449,8 @@ int Table_map_log_event::save_field_metadata() } case MYSQL_TYPE_VARCHAR: { - short int *x= (short int *)&m_field_metadata[index]; - int2store(x, m_table->s->field[i]->field_length); + char *ptr= (char *)&m_field_metadata[index]; + int2store(ptr, m_table->s->field[i]->field_length); index= index + sizeof(short int); break; } diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index e4f9690cf61..0cf077f6481 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -121,13 +121,9 @@ public: /* These types store two bytes. */ - uint16 *x= (uint16 *)&field_metadata[index]; -#ifdef WORDS_BIGENDIAN - m_field_metadata[i]= sint2korr(x); -#else - m_field_metadata[i]= *x; -#endif - index= index + sizeof(short); + char *ptr= (char *)&field_metadata[index]; + m_field_metadata[i]= sint2korr(ptr); + index= index + sizeof(short int); break; } case MYSQL_TYPE_NEWDECIMAL: From 7c915116f474933974817fb44ed31e846733d73a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Aug 2007 19:16:06 +0200 Subject: [PATCH 15/22] Bug#26793 mysqld crashes when doing specific query on information_schema - Drop the newly created user user1@localhost - Cleanup testcase mysql-test/r/ndb_bug26793.result: Update test result mysql-test/t/ndb_bug26793.test: - Remove the drop/restore of anonymous users - there are no such users by default anymore(if there were, they would probably be in mysql.user) - Switch back to default connection before cleanup - Drop user1@localhost as part of cleanup --- mysql-test/r/ndb_bug26793.result | 7 +------ mysql-test/t/ndb_bug26793.test | 21 +++++++++------------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/ndb_bug26793.result b/mysql-test/r/ndb_bug26793.result index 31f9763dd6b..a9a8a798546 100644 --- a/mysql-test/r/ndb_bug26793.result +++ b/mysql-test/r/ndb_bug26793.result @@ -3,11 +3,6 @@ CREATE TABLE `test` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `t` VARCHAR( 10 ) NOT NULL ) ENGINE = ndbcluster; -create table test.db_temp as select * from mysql.db where user=''; -delete from mysql.db where user=''; -flush privileges; GRANT USAGE ON *.* TO user1@localhost IDENTIFIED BY 'pass'; DROP TABLE `test`.`test`; -insert into mysql.db select * from test.db_temp; -drop table db_temp; -flush privileges; +drop user user1@localhost; diff --git a/mysql-test/t/ndb_bug26793.test b/mysql-test/t/ndb_bug26793.test index 4f5a78fdca4..f35d8808c1a 100644 --- a/mysql-test/t/ndb_bug26793.test +++ b/mysql-test/t/ndb_bug26793.test @@ -9,15 +9,12 @@ CREATE TABLE `test` ( `t` VARCHAR( 10 ) NOT NULL ) ENGINE = ndbcluster; -create table test.db_temp as select * from mysql.db where user=''; -delete from mysql.db where user=''; - -flush privileges; - +# Add user1@localhost with a specific password +# and connect as that user GRANT USAGE ON *.* TO user1@localhost IDENTIFIED BY 'pass'; - connect (user1,localhost,user1,pass,*NO-ONE*); +# Run the query 100 times disable_query_log; disable_result_log; let $i= 100; @@ -29,10 +26,10 @@ dec $i; enable_query_log; enable_result_log; -connect (root,localhost,root,,test); -connection root; -DROP TABLE `test`.`test`; -insert into mysql.db select * from test.db_temp; -drop table db_temp; -flush privileges; +disconnect user1; + +# Switch back to the default connection and cleanup +connection default; +DROP TABLE `test`.`test`; +drop user user1@localhost; From c1b89b85ce24583d2bd9d48b3a951b956bb2a368 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Aug 2007 11:36:30 +0200 Subject: [PATCH 16/22] bug#30337 DELETE ... WHERE PK IN (..) and AFTER DELETE trigger crashes API node: Disable multi_read_range if there are after delete/update triggers --- sql/ha_ndbcluster.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 03b6bcf3242..c7ad51596cf 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6464,7 +6464,8 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, if (uses_blob_value(m_retrieve_all_fields) || (cur_index_type == UNIQUE_INDEX && has_null_in_unique_index(active_index) && - null_value_index_search(ranges, ranges+range_count, buffer))) + null_value_index_search(ranges, ranges+range_count, buffer)) + || m_delete_cannot_batch || m_update_cannot_batch) { m_disable_multi_read= TRUE; DBUG_RETURN(handler::read_multi_range_first(found_range_p, From a40202e6965d8c508defa223e6f1a13fd39051d4 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 13 Aug 2007 15:59:08 +0200 Subject: [PATCH 17/22] bug#30337 DELETE ... WHERE PK IN (..) and AFTER DELETE trigger crashes API node: Added testcase --- mysql-test/r/ndb_read_multi_range.result | 19 +++++++++++++++++++ mysql-test/t/ndb_read_multi_range.test | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/mysql-test/r/ndb_read_multi_range.result b/mysql-test/r/ndb_read_multi_range.result index 64a6749bed1..d18f4c1e65a 100644 --- a/mysql-test/r/ndb_read_multi_range.result +++ b/mysql-test/r/ndb_read_multi_range.result @@ -405,3 +405,22 @@ a b 1 1 10 10 drop table t2; +create table t1 (id int primary key) engine ndb; +insert into t1 values (1), (2), (3); +create table t2 (id int primary key) engine ndb; +insert into t2 select id from t1; +create trigger kaboom after delete on t1 +for each row begin +delete from t2 where id=old.id; +end| +select * from t1 order by id; +id +1 +2 +3 +delete from t1 where id in (1,2); +select * from t2 order by id; +id +3 +drop trigger kaboom; +drop table t1; diff --git a/mysql-test/t/ndb_read_multi_range.test b/mysql-test/t/ndb_read_multi_range.test index e1f1dfc1150..1d1d5f26552 100644 --- a/mysql-test/t/ndb_read_multi_range.test +++ b/mysql-test/t/ndb_read_multi_range.test @@ -291,3 +291,25 @@ insert into t2 values (1,1), (10,10); select * from t2 use index (ab) where a in(1,10) order by a; drop table t2; + +#bug#30337 + +create table t1 (id int primary key) engine ndb; +insert into t1 values (1), (2), (3); + +create table t2 (id int primary key) engine ndb; +insert into t2 select id from t1; + +delimiter |; +create trigger kaboom after delete on t1 +for each row begin + delete from t2 where id=old.id; +end| +delimiter ;| + +select * from t1 order by id; +delete from t1 where id in (1,2); +select * from t2 order by id; + +drop trigger kaboom; +drop table t1; From 6656d39c7216cc07b457f090d5432168e668582d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Aug 2007 15:07:17 +1000 Subject: [PATCH 18/22] Backport Magnus' fix from 5.1 ChangeSet@1.2575, 2007-08-07 19:16:06+02:00, msvensson@pilot.(none) +2 -0 Bug#26793 mysqld crashes when doing specific query on information_schema - Drop the newly created user user1@localhost - Cleanup testcase mysql-test/r/ndb_bug26793.result: mysql-test/r/ndb_bug26793.result@1.3, 2007-08-07 19:16:04+02:00, msvensson@pilot.(none) +1 -6 Update test result mysql-test/t/ndb_bug26793.test: mysql-test/t/ndb_bug26793.test@1.3, 2007-08-07 19:16:04+02:00, msvensson@pilot.(none) +8 -11 - Remove the drop/restore of anonymous users - there are no such users by default anymore(if there were, they would probably be in mysql.user) - Switch back to default connection before cleanup - Drop user1@localhost as part of cleanup --- mysql-test/r/ndb_bug26793.result | 7 +------ mysql-test/t/ndb_bug26793.test | 21 +++++++++------------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/ndb_bug26793.result b/mysql-test/r/ndb_bug26793.result index 31f9763dd6b..a9a8a798546 100644 --- a/mysql-test/r/ndb_bug26793.result +++ b/mysql-test/r/ndb_bug26793.result @@ -3,11 +3,6 @@ CREATE TABLE `test` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `t` VARCHAR( 10 ) NOT NULL ) ENGINE = ndbcluster; -create table test.db_temp as select * from mysql.db where user=''; -delete from mysql.db where user=''; -flush privileges; GRANT USAGE ON *.* TO user1@localhost IDENTIFIED BY 'pass'; DROP TABLE `test`.`test`; -insert into mysql.db select * from test.db_temp; -drop table db_temp; -flush privileges; +drop user user1@localhost; diff --git a/mysql-test/t/ndb_bug26793.test b/mysql-test/t/ndb_bug26793.test index 4f5a78fdca4..f35d8808c1a 100644 --- a/mysql-test/t/ndb_bug26793.test +++ b/mysql-test/t/ndb_bug26793.test @@ -9,15 +9,12 @@ CREATE TABLE `test` ( `t` VARCHAR( 10 ) NOT NULL ) ENGINE = ndbcluster; -create table test.db_temp as select * from mysql.db where user=''; -delete from mysql.db where user=''; - -flush privileges; - +# Add user1@localhost with a specific password +# and connect as that user GRANT USAGE ON *.* TO user1@localhost IDENTIFIED BY 'pass'; - connect (user1,localhost,user1,pass,*NO-ONE*); +# Run the query 100 times disable_query_log; disable_result_log; let $i= 100; @@ -29,10 +26,10 @@ dec $i; enable_query_log; enable_result_log; -connect (root,localhost,root,,test); -connection root; -DROP TABLE `test`.`test`; -insert into mysql.db select * from test.db_temp; -drop table db_temp; -flush privileges; +disconnect user1; + +# Switch back to the default connection and cleanup +connection default; +DROP TABLE `test`.`test`; +drop user user1@localhost; From 1b14d027799a9218dedb2ff42cffeb06280151b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Aug 2007 10:29:00 +0200 Subject: [PATCH 19/22] bug#30337 DELETE ... WHERE PK IN (..) and AFTER DELETE trigger crashes API node: Regenerated result --- mysql-test/r/ndb_read_multi_range.result | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mysql-test/r/ndb_read_multi_range.result b/mysql-test/r/ndb_read_multi_range.result index aef009212a4..b7e72117d13 100644 --- a/mysql-test/r/ndb_read_multi_range.result +++ b/mysql-test/r/ndb_read_multi_range.result @@ -473,3 +473,22 @@ a b 1 1 10 10 drop table t1, t2; +create table t1 (id int primary key) engine ndb; +insert into t1 values (1), (2), (3); +create table t2 (id int primary key) engine ndb; +insert into t2 select id from t1; +create trigger kaboom after delete on t1 +for each row begin +delete from t2 where id=old.id; +end| +select * from t1 order by id; +id +1 +2 +3 +delete from t1 where id in (1,2); +select * from t2 order by id; +id +3 +drop trigger kaboom; +drop table t1; From 57c6daa952a6ab17c3f947a056bc15ce3387bf80 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Aug 2007 12:12:31 +1000 Subject: [PATCH 20/22] [PATCH] BUG#28683 - ndb_size.pl should support more than one database Patch by: Monty Taylor Fixes by: Stewart Smith Added the ability to run ndb_size.pl on mulitple databases and also to exclude lists of databases and tables from analysis. --- Added schema name information to index table calculations as well. --- Made database an optional parameter, the exclusion of which causes all databases to be examined. If selecting from information_schema fails, attempt to fall back to show tables from --- Added support for setting an optional "real_table_name" for a table to deal with unique indexe size calcs. --- Fixed report title for the case where we are using operating on more than one database. --- Fixed some perl style concerns timothy had. Cull the list of databases in perl rather than passing both an in and a not in list to MySQL Get this full list of databases from show databases if needed. storage/ndb/tools/ndb_size.pl@stripped, 2007-05-25 13:45:44-07:00, mtaylor@qualinost.(none) +102 -28 Added the ability to run ndb_size.pl on mulitple databases and also to exclude lists of databases and tables from analysis. --- Added schema name information to index table calculations as well. --- Made database an optional parameter, the exclusion of which causes all databases to be examined. If selecting from information_schema fails, attempt to fall back to show tables from --- Added support for setting an optional "real_table_name" for a table to deal with unique indexe size calcs. --- Fixed report title for the case where we are using operating on more than one database. --- Fixed some perl style concerns timothy had. Cull the list of databases in perl rather than passing both an in and a not in list to MySQL Get this full list of databases from show databases if needed. Index: ndb-work/storage/ndb/tools/ndb_size.pl =================================================================== storage/ndb/tools/ndb_size.pl: BUG#28683 - ndb_size.pl should support more than one database --- storage/ndb/tools/ndb_size.pl | 139 +++++++++++++++++++++++++++------- 1 file changed, 110 insertions(+), 29 deletions(-) diff --git a/storage/ndb/tools/ndb_size.pl b/storage/ndb/tools/ndb_size.pl index 4ecdc297cd3..709e2eb3d5c 100644 --- a/storage/ndb/tools/ndb_size.pl +++ b/storage/ndb/tools/ndb_size.pl @@ -169,7 +169,9 @@ use Class::MethodMaker [ vdm_versions ddm_versions ) ], scalar => [ qw( name - rows ) ], + rows + schema + real_table_name) ], hash => [ qw( columns indexes indexed_columns @@ -198,6 +200,16 @@ use Class::MethodMaker [ scalar => [ { -default=> 4 },'align'], ]; +sub table_name +{ + my ($self) = @_; + if ($self->real_table_name) { + return $self->real_table_name; + }else { + return $self->name; + } +} + sub compute_row_size { my ($self, $releases) = @_; @@ -391,7 +403,7 @@ sub compute_estimate package main; -my ($dbh,$database,$hostname,$user,$password,$help,$savequeries,$loadqueries,$debug,$format); +my ($dbh,$database,$hostname,$user,$password,$help,$savequeries,$loadqueries,$debug,$format,$excludetables,$excludedbs); GetOptions('database|d=s'=>\$database, 'hostname=s'=>\$hostname, @@ -399,6 +411,8 @@ GetOptions('database|d=s'=>\$database, 'password|p=s'=>\$password, 'savequeries|s=s'=>\$savequeries, 'loadqueries|l=s'=>\$loadqueries, + 'excludetables=s'=>\$excludetables, + 'excludedbs=s'=>\$excludedbs, 'help|usage|h!'=>\$help, 'debug'=>\$debug, 'format|f=s'=>\$format, @@ -406,32 +420,73 @@ GetOptions('database|d=s'=>\$database, my $report= new MySQL::NDB::Size::Report; -if($help || !$database) +if($help) { print STDERR "Usage:\n"; - print STDERR "\tndb_size.pl --database= [--hostname=]" + print STDERR "\tndb_size.pl --database=|ALL [--hostname=]" ."[--user=] [--password=] [--help|-h] [--format=(html|text)] [--loadqueries=] [--savequeries=]\n\n"; + print STDERR "\t--database= ALL may be specified to examine all " + ."databases\n"; print STDERR "\t--hostname=: can be used to designate a " ."specific port\n"; print STDERR "\t--hostname defaults to localhost\n"; print STDERR "\t--user and --password default to empty string\n"; print STDERR "\t--format=(html|text) Output format\n"; + print STDERR "\t--excludetables Comma separated list of table names to skip\n"; + print STDERR "\t--excludedbs Comma separated list of database names to skip\n"; print STDERR "\t--savequeries= saves all queries to the DB into \n"; print STDERR "\t--loadqueries= loads query results from . Doesn't connect to DB.\n"; exit(1); } + $hostname= 'localhost' unless $hostname; my %queries; # used for loadqueries/savequeries if(!$loadqueries) { - my $dsn = "DBI:mysql:database=$database;host=$hostname"; + my $dsn = "DBI:mysql:host=$hostname"; $dbh= DBI->connect($dsn, $user, $password) or exit(1); - $report->database($database); $report->dsn($dsn); } + +my @dbs; +if ($database && !($database =~ /^ALL$/i)) +{ + @dbs = split(',', $database); +} +else +{ + # Do all databases + @dbs = map { $_->[0] } @{ $dbh->selectall_arrayref("show databases") }; +} + +my %withdb = map {$_ => 1} @dbs; +foreach (split ",", $excludedbs || '') +{ + delete $withdb{$_}; +} +delete $withdb{'mysql'}; +delete $withdb{'INFORMATION_SCHEMA'}; +delete $withdb{'information_schema'}; + +my $dblist = join (',', map { $dbh->quote($_) } keys %withdb ); + +$excludetables = join (',', map { $dbh->quote($_) } split ',', $excludetables ) + if $excludetables; + +if(!$loadqueries) +{ + if (scalar(keys %withdb)>1) + { + $report->database("databases: $dblist"); + } + else + { + $report->database("database: $dblist"); + } +} else { open Q,"< $loadqueries"; @@ -441,7 +496,6 @@ else %queries= %$e; close Q; $report->database("file:$loadqueries"); - $report->dsn("file:$loadqueries"); } $report->versions('4.1','5.0','5.1'); @@ -454,7 +508,25 @@ if($loadqueries) } else { - $tables= $dbh->selectall_arrayref("show tables"); + my $sql= "select t.TABLE_NAME,t.TABLE_SCHEMA " . + " from information_schema.TABLES t " . + " where t.TABLE_SCHEMA in ( $dblist ) "; + + $sql.=" and t.TABLE_NAME not in " . + " ( $excludetables )" + if ($excludetables); + + $tables= $dbh->selectall_arrayref($sql); + + if (!$tables) { + print "WARNING: problem selecing from INFORMATION SCHEMA ($sql)\n"; + if ($#dbs>0) { + print "\t attempting to fallback to show tables from $database"; + $tables= $dbh->selectall_arrayref("show tables from $database\n"); + } else { + print "All Databases not supported in 4.1. Please specify --database=\n"; + } + } $queries{"show tables"}= $tables; } @@ -543,9 +615,10 @@ sub do_table { $col->dm($fixed); if(!$col->Key()) # currently keys must be non varsized { - my $sql= "select avg(length(`" - .$colname - ."`)) from `".$t->name().'`'; + my $sql= sprintf("select avg(length(`%s`)) " . + " from `%s`.`%s` " , + $colname, $t->schema(), $t->table_name()); + my @dynamic; if($loadqueries) { @@ -573,9 +646,11 @@ sub do_table { $blobhunk= 8000 if $type=~ /longblob/; $blobhunk= 4000 if $type=~ /mediumblob/; - my $sql= "select SUM(CEILING(". - "length(`$colname`)/$blobhunk))" - ."from `".$t->name."`"; + my $sql= sprintf("select SUM(CEILING(length(`%s`)/%s)) " . + " from `%s`.`%s`" , + $colname, $blobhunk, + $t->schema(), $t->table_name() ); + my @blobsize; if($loadqueries) { @@ -589,11 +664,12 @@ sub do_table { $blobsize[0]=0 if !defined($blobsize[0]); # Is a supporting table, add it to the lists: - $report->supporting_tables_set($t->name()."\$BLOB_$colname" => 1); - $t->supporting_tables_push($t->name()."\$BLOB_$colname"); + $report->supporting_tables_set($t->schema().".".$t->name()."\$BLOB_$colname" => 1); + $t->supporting_tables_push($t->schema().".".$t->name()."\$BLOB_$colname"); my $st= new MySQL::NDB::Size::Table(name => $t->name()."\$BLOB_$colname", + schema => $t->schema(), rows => $blobsize[0], row_dm_overhead => { '4.1' => 12, @@ -632,7 +708,9 @@ sub do_table { $col->size($size); $t->columns_set( $colname => $col ); } - $report->tables_set( $t->name => $t ); + #print "setting tables: ",$t->schema(), $t->table_name(), $t->name, $t->real_table_name || "" , "\n"; + # Use $t->name here instead of $t->table_name() to avoid namespace conflicts + $report->tables_set( $t->schema().".".$t->name() => $t ); # And now... the IndexMemory usage. # @@ -727,14 +805,16 @@ sub do_table { # Is a supporting table, add it to the lists: my $idxname= $t->name().'_'.join('_',@{$indexes{$index}{columns}}). "\$unique"; - $report->supporting_tables_set($idxname => 1); - $t->supporting_tables_push($idxname); + $report->supporting_tables_set($t->schema().".".$idxname => 1); + $t->supporting_tables_push($t->schema().".".$idxname); $t->indexed_columns_set($_ => 1) foreach @{$indexes{$index}{columns}}; my $st= new MySQL::NDB::Size::Table(name => $idxname, + real_table_name => $t->table_name(), rows => $count[0], + schema => $t->schema(), row_dm_overhead => { '4.1' => 12, '5.0' => 12, @@ -745,7 +825,6 @@ sub do_table { row_ddm_overhead => { '5.1' => 8 }, ); - do_table($st, \%idxcols, { @@ -766,9 +845,10 @@ sub do_table { foreach(@{$tables}) { my $table= @{$_}[0]; + my $schema = @{$_}[1] || $database; my $info; { - my $sql= 'describe `'.$table.'`'; + my $sql= 'describe `'.$schema.'`.`'.$table.'`'; if($loadqueries) { $info= $queries{$sql}; @@ -781,7 +861,7 @@ foreach(@{$tables}) } my @count; { - my $sql= 'select count(*) from `'.$table.'`'; + my $sql= 'select count(*) from `'.$schema.'`.`'.$table.'`'; if($loadqueries) { @count= @{$queries{$sql}}; @@ -797,7 +877,7 @@ foreach(@{$tables}) { my @show_indexes; { - my $sql= "show index from `".$table.'`'; + my $sql= "show index from `".$schema.'`.`'.$table.'`'; if($loadqueries) { @show_indexes= @{$queries{$sql}}; @@ -826,6 +906,7 @@ foreach(@{$tables}) } } my $t= new MySQL::NDB::Size::Table(name => $table, + schema => $schema, rows => $count[0], row_dm_overhead => { '4.1' => 12, @@ -1008,7 +1089,7 @@ sub output my $self= shift; my $r= $self->{report}; - print $self->ul("ndb_size.pl report for database ". $r->database(). + print $self->ul("ndb_size.pl report for ". $r->database(). " (".(($r->tables_count()||0)-($r->supporting_tables_count()||0)). " tables)"); @@ -1188,8 +1269,8 @@ sub output my $st= $r->tables->{$_}; foreach(@{$st->indexes_keys()}) { - printf $f, $st->name() if $_ eq 'PRIMARY'; - printf $f, $st->name().$_ if $_ ne 'PRIMARY'; + printf $f, $st->schema().".".$st->name() if $_ eq 'PRIMARY'; + printf $f, $st->schema().".".$st->name().$_ if $_ ne 'PRIMARY'; my $sti= $st->indexes->{$_}; printf $v, ($sti->ver_im_exists($_)) ?$sti->ver_im->{$_} @@ -1367,7 +1448,7 @@ print < ENDHTML - print $self->h1("ndb_size.pl report for database ". $r->database(). + print $self->h1("ndb_size.pl report for ". $r->database(). " (".(($r->tables_count()||0)-($r->supporting_tables_count()||0)). " tables)"); @@ -1579,8 +1660,8 @@ ENDHTML foreach(@{$st->indexes_keys()}) { my @r; - push @r, $st->name() if $_ eq 'PRIMARY'; - push @r, $st->name().$_ if $_ ne 'PRIMARY'; + push @r, $st->schema().".".$st->name() if $_ eq 'PRIMARY'; + push @r, $st->schema().".".$st->name().$_ if $_ ne 'PRIMARY'; my $sti= $st->indexes->{$_}; push @r, ($sti->ver_im_exists($_)) ?$sti->ver_im->{$_} From 71a1f16014d7164e94582abe640aca07a060d37a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Aug 2007 12:12:46 +1000 Subject: [PATCH 21/22] [PATCH] Bug#29228 ndb_size.pl borks on float columns with comma in () Index: ndb-work/storage/ndb/tools/ndb_size.pl =================================================================== storage/ndb/tools/ndb_size.pl: Bug#29228 ndb_size.pl borks on float columns with comma in () --- storage/ndb/tools/ndb_size.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/storage/ndb/tools/ndb_size.pl b/storage/ndb/tools/ndb_size.pl index 709e2eb3d5c..8f6395443ba 100644 --- a/storage/ndb/tools/ndb_size.pl +++ b/storage/ndb/tools/ndb_size.pl @@ -582,6 +582,8 @@ sub do_table { {$col->dm(4)} elsif($type =~ /float/) { + my @sz= split ',', $size; + $size= $sz[0]+$sz[1]; if(!defined($size) || $size<=24) {$col->dm(4)} else From b0ac87dc443f4b7b704d49f906f7673562541352 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Aug 2007 12:12:59 +1000 Subject: [PATCH 22/22] [PATCH] BUG#28253 ndb_size.pl: cannot set socket Index: ndb-work/storage/ndb/tools/ndb_size.pl =================================================================== storage/ndb/tools/ndb_size.pl: BUG#28253 ndb_size.pl: cannot set socket --- storage/ndb/tools/ndb_size.pl | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/storage/ndb/tools/ndb_size.pl b/storage/ndb/tools/ndb_size.pl index 8f6395443ba..3537a9e8490 100644 --- a/storage/ndb/tools/ndb_size.pl +++ b/storage/ndb/tools/ndb_size.pl @@ -403,10 +403,24 @@ sub compute_estimate package main; -my ($dbh,$database,$hostname,$user,$password,$help,$savequeries,$loadqueries,$debug,$format,$excludetables,$excludedbs); +my ($dbh, + $database, + $socket, + $hostname, + $user, + $password); + +my ($help, + $savequeries, + $loadqueries, + $debug, + $format, + $excludetables, + $excludedbs); GetOptions('database|d=s'=>\$database, 'hostname=s'=>\$hostname, + 'socket=s'=>\$socket, 'user|u=s'=>\$user, 'password|p=s'=>\$password, 'savequeries|s=s'=>\$savequeries, @@ -423,7 +437,8 @@ my $report= new MySQL::NDB::Size::Report; if($help) { print STDERR "Usage:\n"; - print STDERR "\tndb_size.pl --database=|ALL [--hostname=]" + print STDERR "\tndb_size.pl --database=|ALL [--hostname=] " + ."[--socket=] " ."[--user=] [--password=] [--help|-h] [--format=(html|text)] [--loadqueries=] [--savequeries=]\n\n"; print STDERR "\t--database= ALL may be specified to examine all " ."databases\n"; @@ -447,6 +462,7 @@ my %queries; # used for loadqueries/savequeries if(!$loadqueries) { my $dsn = "DBI:mysql:host=$hostname"; + $dsn.= ";mysql_socket=$socket" if ($socket); $dbh= DBI->connect($dsn, $user, $password) or exit(1); $report->dsn($dsn); } @@ -1057,6 +1073,8 @@ if($debug) eval 'print STDERR Dumper($report)'; } +$format= "text" unless $format; + if($format eq 'text') { my $text_out= new MySQL::NDB::Size::Output::Text($report); @@ -1067,12 +1085,6 @@ elsif($format eq 'html') my $html_out= new MySQL::NDB::Size::Output::HTML($report); $html_out->output(); } -else -{ - # default to text output - my $text_out= new MySQL::NDB::Size::Output::Text($report); - $text_out->output(); -} package MySQL::NDB::Size::Output::Text; use Data::Dumper;