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..29ff93986d5 --- /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 $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/suite/rpl/r/rpl_colSize.result b/mysql-test/suite/rpl/r/rpl_colSize.result new file mode 100644 index 00000000000..91456742833 --- /dev/null +++ b/mysql-test/suite/rpl/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/suite/rpl/r/rpl_extraColmaster_innodb.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result new file mode 100644 index 00000000000..95ef9d549c0 Binary files /dev/null and b/mysql-test/suite/rpl/r/rpl_extraColmaster_innodb.result differ diff --git a/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result new file mode 100644 index 00000000000..5161bbc89b1 Binary files /dev/null and b/mysql-test/suite/rpl/r/rpl_extraColmaster_myisam.result differ diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result b/mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result index ca9ba023b1d..7dc9926522b 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_11bugs.result +++ b/mysql-test/suite/rpl/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/suite/rpl/r/rpl_row_create_table.result b/mysql-test/suite/rpl/r/rpl_row_create_table.result index f22881bd4a9..e5ed4464b2f 100644 --- a/mysql-test/suite/rpl/r/rpl_row_create_table.result +++ b/mysql-test/suite/rpl/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 # 468 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 # 470 use `test`; CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 468 Table_map # 507 table_id: # (test.t2) -# 507 Write_rows # 551 table_id: # flags: STMT_END_F -# 551 Xid # 578 COMMIT /* XID */ -# 578 Query # 646 use `test`; BEGIN -# 646 Query # 771 use `test`; CREATE TABLE `t3` ( +# 470 Table_map # 511 table_id: # (test.t2) +# 511 Write_rows # 555 table_id: # flags: STMT_END_F +# 555 Xid # 582 COMMIT /* XID */ +# 582 Query # 650 use `test`; BEGIN +# 650 Query # 775 use `test`; CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 771 Table_map # 810 table_id: # (test.t3) -# 810 Write_rows # 854 table_id: # flags: STMT_END_F -# 854 Xid # 881 COMMIT /* XID */ -# 881 Query # 949 use `test`; BEGIN -# 949 Query # 1074 use `test`; CREATE TABLE `t4` ( +# 775 Table_map # 816 table_id: # (test.t3) +# 816 Write_rows # 860 table_id: # flags: STMT_END_F +# 860 Xid # 887 COMMIT /* XID */ +# 887 Query # 955 use `test`; BEGIN +# 955 Query # 1080 use `test`; CREATE TABLE `t4` ( `a` int(11) DEFAULT NULL ) ENGINE=InnoDB -# 1074 Table_map # 1113 table_id: # (test.t4) -# 1113 Write_rows # 1157 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 # 1121 table_id: # (test.t4) +# 1121 Write_rows # 1165 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 # 482 table_id: # (test.t2) -# 482 Write_rows # 526 table_id: # flags: STMT_END_F -# 526 Table_map # 565 table_id: # (test.t2) -# 565 Write_rows # 604 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 # 486 table_id: # (test.t2) +# 486 Write_rows # 530 table_id: # flags: STMT_END_F +# 530 Table_map # 571 table_id: # (test.t2) +# 571 Write_rows # 610 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 # 711 use `test`; TRUNCATE TABLE t2 -# 711 Xid # 738 COMMIT /* XID */ +# 637 Query # 717 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/suite/rpl/r/rpl_row_extraColmaster_ndb.result b/mysql-test/suite/rpl/r/rpl_row_extraColmaster_ndb.result new file mode 100644 index 00000000000..7701a83127a Binary files /dev/null and b/mysql-test/suite/rpl/r/rpl_row_extraColmaster_ndb.result differ diff --git a/mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result b/mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result index 942a6b83bf6..072f15cbbd3 100644 --- a/mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result +++ b/mysql-test/suite/rpl/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/suite/rpl/r/rpl_row_inexist_tbl.result b/mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result index 14fb01bb0d8..70e923bc4f4 100644 --- a/mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result +++ b/mysql-test/suite/rpl/r/rpl_row_inexist_tbl.result @@ -24,7 +24,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 597 +Read_Master_Log_Pos 605 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -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/suite/rpl/r/rpl_row_log.result b/mysql-test/suite/rpl/r/rpl_row_log.result index 351accaf3af..33a6c3b9781 100644 --- a/mysql-test/suite/rpl/r/rpl_row_log.result +++ b/mysql-test/suite/rpl/r/rpl_row_log.result @@ -208,13 +208,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 @@ -240,7 +240,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000002 -Read_Master_Log_Pos 377 +Read_Master_Log_Pos 379 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000002 @@ -255,7 +255,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 377 +Exec_Master_Log_Pos 379 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result index b500d7660dc..9ed35f34dc5 100644 --- a/mysql-test/suite/rpl/r/rpl_row_log_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_log_innodb.result @@ -213,13 +213,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 @@ -248,7 +248,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000002 -Read_Master_Log_Pos 404 +Read_Master_Log_Pos 406 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000002 @@ -263,7 +263,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 404 +Exec_Master_Log_Pos 406 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result b/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result index 3a8b3a78438..06266f1de82 100644 --- a/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result +++ b/mysql-test/suite/rpl/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 @@ -78,7 +78,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 @@ -93,7 +93,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 @@ -126,7 +126,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 @@ -141,7 +141,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 @@ -217,7 +217,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 @@ -232,7 +232,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 @@ -261,7 +261,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 @@ -276,7 +276,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/suite/rpl/r/rpl_row_tabledefs_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result index 18243dce40b..3d07faf14d9 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_2myisam.result @@ -146,187 +146,17 @@ SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (2); INSERT INTO t2 VALUES (2,4); +"Failed while waiting for slave SQL thread to stop" SHOW SLAVE STATUS; -Slave_IO_State # +Slave_IO_State Waiting for master to send event Master_Host 127.0.0.1 Master_User root -Master_Port MASTER_PORT +Master_Port 9306 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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Table width mismatch - received 2 columns, test.t2 has 1 columns -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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 -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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 -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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 -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 # +Read_Master_Log_Pos 2829 +Relay_Log_File slave-relay-bin.000007 +Relay_Log_Pos 252 Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes @@ -339,8 +169,8 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos # -Relay_Log_Space # +Exec_Master_Log_Pos 2829 +Relay_Log_Space 553 Until_Condition None Until_Log_File Until_Log_Pos 0 @@ -350,64 +180,9 @@ Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key -Seconds_Behind_Master # +Seconds_Behind_Master 0 Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error Last_SQL_Errno 0 Last_SQL_Error -INSERT INTO t7 VALUES (1),(2),(3); -INSERT INTO t8 VALUES (1),(2),(3); -SELECT * FROM t7 ORDER BY a; -a -1 -2 -3 -SELECT * FROM t8 ORDER BY a; -a -1 -2 -3 -SELECT * FROM t7 ORDER BY a; -a e1 e2 e3 e4 e5 e6 e7 e8 -1 NULL NULL NULL NULL NULL NULL NULL NULL -2 NULL NULL NULL NULL NULL NULL NULL NULL -3 NULL NULL NULL NULL NULL NULL NULL NULL -SELECT * FROM t8 ORDER BY a; -a e1 e2 e3 e4 e5 e6 e7 e8 -1 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 -3 0 0 0 0 0 0 0 0 -**** On Master **** -TRUNCATE t1_nodef; -SET SQL_LOG_BIN=0; -INSERT INTO t1_nodef VALUES (1,2); -INSERT INTO t1_nodef VALUES (2,4); -SET SQL_LOG_BIN=1; -**** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); -**** On Master **** -UPDATE t1_nodef SET b=2*b WHERE a=1; -SELECT * FROM t1_nodef ORDER BY a; -a b -1 4 -2 4 -**** On Slave **** -SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 -**** On Master **** -DELETE FROM t1_nodef WHERE a=2; -SELECT * FROM t1_nodef ORDER BY a; -a b -1 4 -**** On Slave **** -SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -**** Cleanup **** -DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; -DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; -SET @@global.sql_mode= @my_sql_mode; diff --git a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result index ef07db1c47d..ba3051c703f 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_tabledefs_3innodb.result @@ -146,187 +146,17 @@ SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; INSERT INTO t9 VALUES (2); INSERT INTO t2 VALUES (2,4); +"Failed while waiting for slave SQL thread to stop" SHOW SLAVE STATUS; -Slave_IO_State # +Slave_IO_State Waiting for master to send event Master_Host 127.0.0.1 Master_User root -Master_Port MASTER_PORT +Master_Port 9306 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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Table width mismatch - received 2 columns, test.t2 has 1 columns -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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 3, test.t4 has type 4 -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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Column 1 type mismatch - received type 3, test.t5 has type 4 -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 1532 -Last_Error Table definition on master and slave does not match: 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 -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 1532 -Last_SQL_Error Table definition on master and slave does not match: Column 2 type mismatch - received type 3, test.t6 has type 4 -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 # +Read_Master_Log_Pos 3180 +Relay_Log_File slave-relay-bin.000007 +Relay_Log_Pos 252 Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes @@ -339,8 +169,8 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos # -Relay_Log_Space # +Exec_Master_Log_Pos 3180 +Relay_Log_Space 553 Until_Condition None Until_Log_File Until_Log_Pos 0 @@ -350,64 +180,9 @@ Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key -Seconds_Behind_Master # +Seconds_Behind_Master 0 Master_SSL_Verify_Server_Cert No Last_IO_Errno 0 Last_IO_Error Last_SQL_Errno 0 Last_SQL_Error -INSERT INTO t7 VALUES (1),(2),(3); -INSERT INTO t8 VALUES (1),(2),(3); -SELECT * FROM t7 ORDER BY a; -a -1 -2 -3 -SELECT * FROM t8 ORDER BY a; -a -1 -2 -3 -SELECT * FROM t7 ORDER BY a; -a e1 e2 e3 e4 e5 e6 e7 e8 -1 NULL NULL NULL NULL NULL NULL NULL NULL -2 NULL NULL NULL NULL NULL NULL NULL NULL -3 NULL NULL NULL NULL NULL NULL NULL NULL -SELECT * FROM t8 ORDER BY a; -a e1 e2 e3 e4 e5 e6 e7 e8 -1 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 -3 0 0 0 0 0 0 0 0 -**** On Master **** -TRUNCATE t1_nodef; -SET SQL_LOG_BIN=0; -INSERT INTO t1_nodef VALUES (1,2); -INSERT INTO t1_nodef VALUES (2,4); -SET SQL_LOG_BIN=1; -**** On Slave **** -INSERT INTO t1_nodef VALUES (1,2,3); -INSERT INTO t1_nodef VALUES (2,4,6); -**** On Master **** -UPDATE t1_nodef SET b=2*b WHERE a=1; -SELECT * FROM t1_nodef ORDER BY a; -a b -1 4 -2 4 -**** On Slave **** -SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -2 4 6 -**** On Master **** -DELETE FROM t1_nodef WHERE a=2; -SELECT * FROM t1_nodef ORDER BY a; -a b -1 4 -**** On Slave **** -SELECT * FROM t1_nodef ORDER BY a; -a b x -1 4 3 -**** Cleanup **** -DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; -DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; -SET @@global.sql_mode= @my_sql_mode; diff --git a/mysql-test/suite/rpl/r/rpl_row_until.result b/mysql-test/suite/rpl/r/rpl_row_until.result index d802fce8193..383d1a03a22 100644 --- a/mysql-test/suite/rpl/r/rpl_row_until.result +++ b/mysql-test/suite/rpl/r/rpl_row_until.result @@ -26,7 +26,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 744 +Read_Master_Log_Pos 750 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -41,7 +41,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 315 +Exec_Master_Log_Pos 317 Relay_Log_Space # Until_Condition Master Until_Log_File master-bin.000001 @@ -72,7 +72,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 744 +Read_Master_Log_Pos 750 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -87,7 +87,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 315 +Exec_Master_Log_Pos 317 Relay_Log_Space # Until_Condition Master Until_Log_File master-no-such-bin.000001 @@ -116,7 +116,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 744 +Read_Master_Log_Pos 750 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -131,7 +131,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 590 +Exec_Master_Log_Pos 594 Relay_Log_Space # Until_Condition Relay Until_Log_File slave-relay-bin.000004 @@ -158,7 +158,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 744 +Read_Master_Log_Pos 750 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -173,7 +173,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 744 +Exec_Master_Log_Pos 750 Relay_Log_Space # Until_Condition Master Until_Log_File master-bin.000001 diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index 92402153c76..525909387b3 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -32,5 +32,5 @@ a 3 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 776 # # master-bin.000001 Yes Yes 0 0 776 # None 0 No # No 0 0 +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 786 # # master-bin.000001 Yes Yes 0 0 786 # None 0 No # No 0 0 drop table t1; diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 473e2fbf3e8..2207e869154 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -15,3 +15,4 @@ rpl_innodb_mixed_ddl : Bug #29363 rpl.rpl_innodb_mixed_* test failures rpl_innodb_mixed_dml : Bug #29363 rpl.rpl_innodb_mixed_* test failures rpl_invoked_features : BUG#29020 2007-06-21 Lars Non-deterministic test case rpl_auto_increment_11932 : Bug#29809 2007-07-16 ingo Slave SQL errors in warnings file +rpl_stm_extraColmaster_ndb : WL#3915 : Statement-based replication not supported in ndb. Enable test when supported. diff --git a/mysql-test/suite/rpl/t/rpl_colSize.test b/mysql-test/suite/rpl/t/rpl_colSize.test new file mode 100644 index 00000000000..44fb878d4d2 --- /dev/null +++ b/mysql-test/suite/rpl/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/suite/rpl/t/rpl_extraColmaster_innodb-master.opt b/mysql-test/suite/rpl/t/rpl_extraColmaster_innodb-master.opt new file mode 100644 index 00000000000..627becdbfb5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_extraColmaster_innodb-master.opt @@ -0,0 +1 @@ +--innodb diff --git a/mysql-test/suite/rpl/t/rpl_extraColmaster_innodb-slave.opt b/mysql-test/suite/rpl/t/rpl_extraColmaster_innodb-slave.opt new file mode 100644 index 00000000000..1338b6eba04 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_extraColmaster_innodb-slave.opt @@ -0,0 +1 @@ + --innodb diff --git a/mysql-test/suite/rpl/t/rpl_extraColmaster_innodb.test b/mysql-test/suite/rpl/t/rpl_extraColmaster_innodb.test new file mode 100644 index 00000000000..082c22329fa --- /dev/null +++ b/mysql-test/suite/rpl/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/suite/rpl/t/rpl_extraColmaster_myisam.test b/mysql-test/suite/rpl/t/rpl_extraColmaster_myisam.test new file mode 100644 index 00000000000..5bbd7953294 --- /dev/null +++ b/mysql-test/suite/rpl/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/suite/rpl/t/rpl_row_create_table.test b/mysql-test/suite/rpl/t/rpl_row_create_table.test index be10d48b757..32a6299f28b 100644 --- a/mysql-test/suite/rpl/t/rpl_row_create_table.test +++ b/mysql-test/suite/rpl/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/suite/rpl/t/rpl_row_extraColmaster_ndb.test b/mysql-test/suite/rpl/t/rpl_row_extraColmaster_ndb.test new file mode 100644 index 00000000000..b91947e52e2 --- /dev/null +++ b/mysql-test/suite/rpl/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/suite/rpl/t/rpl_row_flsh_tbls.test b/mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test index a2f9e31fc5d..bfa356fbfb4 100644 --- a/mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test +++ b/mysql-test/suite/rpl/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/mysql-test/suite/rpl/t/rpl_stm_extraColmaster_ndb.test b/mysql-test/suite/rpl/t/rpl_stm_extraColmaster_ndb.test new file mode 100644 index 00000000000..84734204439 --- /dev/null +++ b/mysql-test/suite/rpl/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/mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result index 355c7c16ae2..326506b0396 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result @@ -228,12 +228,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 1746 -master-bin.000002 617 +master-bin.000001 1760 +master-bin.000002 623 start slave; show binary logs; Log_name File_size -slave-bin.000001 1841 +slave-bin.000001 1855 slave-bin.000002 202 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id End_log_pos Info @@ -272,7 +272,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000002 -Read_Master_Log_Pos 617 +Read_Master_Log_Pos 623 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000002 @@ -287,7 +287,7 @@ Replicate_Wild_Ignore_Table Last_Errno 0 Last_Error Skip_Counter 0 -Exec_Master_Log_Pos 617 +Exec_Master_Log_Pos 623 Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/suite/rpl_ndb/r/rpl_truncate_7ndb.result b/mysql-test/suite/rpl_ndb/r/rpl_truncate_7ndb.result index f19105b35cf..d6c57aed41b 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_truncate_7ndb.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_truncate_7ndb.result @@ -32,13 +32,13 @@ 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 327 table_id: # (test.t1) -master-bin.000001 327 Table_map 1 385 table_id: # (mysql.ndb_apply_status) -master-bin.000001 385 Write_rows 1 444 table_id: # -master-bin.000001 444 Write_rows 1 491 table_id: # flags: STMT_END_F -master-bin.000001 491 Query 1 556 COMMIT -master-bin.000001 556 Query 1 636 use `test`; TRUNCATE TABLE t1 -master-bin.000001 636 Query 1 712 use `test`; DROP TABLE t1 +master-bin.000001 287 Table_map 1 330 table_id: # (test.t1) +master-bin.000001 330 Table_map 1 392 table_id: # (mysql.ndb_apply_status) +master-bin.000001 392 Write_rows 1 451 table_id: # +master-bin.000001 451 Write_rows 1 498 table_id: # flags: STMT_END_F +master-bin.000001 498 Query 1 563 COMMIT +master-bin.000001 563 Query 1 643 use `test`; TRUNCATE TABLE t1 +master-bin.000001 643 Query 1 719 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); @@ -68,24 +68,24 @@ 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 327 table_id: # (test.t1) -master-bin.000001 327 Table_map 1 385 table_id: # (mysql.ndb_apply_status) -master-bin.000001 385 Write_rows 1 444 table_id: # -master-bin.000001 444 Write_rows 1 491 table_id: # flags: STMT_END_F -master-bin.000001 491 Query 1 556 COMMIT -master-bin.000001 556 Query 1 636 use `test`; TRUNCATE TABLE t1 -master-bin.000001 636 Query 1 712 use `test`; DROP TABLE t1 -master-bin.000001 712 Query 1 829 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB -master-bin.000001 829 Query 1 893 BEGIN -master-bin.000001 893 Table_map 1 933 table_id: # (test.t1) -master-bin.000001 933 Table_map 1 991 table_id: # (mysql.ndb_apply_status) -master-bin.000001 991 Write_rows 1 1050 table_id: # -master-bin.000001 1050 Write_rows 1 1097 table_id: # flags: STMT_END_F -master-bin.000001 1097 Query 1 1162 COMMIT -master-bin.000001 1162 Query 1 1226 BEGIN -master-bin.000001 1226 Table_map 1 1266 table_id: # (test.t1) -master-bin.000001 1266 Table_map 1 1324 table_id: # (mysql.ndb_apply_status) -master-bin.000001 1324 Write_rows 1 1383 table_id: # -master-bin.000001 1383 Delete_rows 1 1422 table_id: # flags: STMT_END_F -master-bin.000001 1422 Query 1 1487 COMMIT -master-bin.000001 1487 Query 1 1563 use `test`; DROP TABLE t1 +master-bin.000001 287 Table_map 1 330 table_id: # (test.t1) +master-bin.000001 330 Table_map 1 392 table_id: # (mysql.ndb_apply_status) +master-bin.000001 392 Write_rows 1 451 table_id: # +master-bin.000001 451 Write_rows 1 498 table_id: # flags: STMT_END_F +master-bin.000001 498 Query 1 563 COMMIT +master-bin.000001 563 Query 1 643 use `test`; TRUNCATE TABLE t1 +master-bin.000001 643 Query 1 719 use `test`; DROP TABLE t1 +master-bin.000001 719 Query 1 836 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB +master-bin.000001 836 Query 1 900 BEGIN +master-bin.000001 900 Table_map 1 943 table_id: # (test.t1) +master-bin.000001 943 Table_map 1 1005 table_id: # (mysql.ndb_apply_status) +master-bin.000001 1005 Write_rows 1 1064 table_id: # +master-bin.000001 1064 Write_rows 1 1111 table_id: # flags: STMT_END_F +master-bin.000001 1111 Query 1 1176 COMMIT +master-bin.000001 1176 Query 1 1240 BEGIN +master-bin.000001 1240 Table_map 1 1283 table_id: # (test.t1) +master-bin.000001 1283 Table_map 1 1345 table_id: # (mysql.ndb_apply_status) +master-bin.000001 1345 Write_rows 1 1404 table_id: # +master-bin.000001 1404 Delete_rows 1 1443 table_id: # flags: STMT_END_F +master-bin.000001 1443 Query 1 1508 COMMIT +master-bin.000001 1508 Query 1 1584 use `test`; DROP TABLE t1 diff --git a/sql/field.cc b/sql/field.cc index a970a6e4318..49433deca74 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1372,6 +1372,51 @@ int Field::store(const char *to, uint length, CHARSET_INFO *cs, } +/** + 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 uchar *Field::unpack(uchar* to, + const uchar *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 */ @@ -2657,6 +2702,52 @@ uint Field_new_decimal::is_equal(Create_field *new_field) } +/** + 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 uchar *Field_new_decimal::unpack(uchar* to, + const uchar *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((uchar *)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 ****************************************************************************/ @@ -6306,6 +6397,38 @@ uchar *Field_string::pack(uchar *to, const uchar *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 uchar *Field_string::unpack(uchar *to, + const uchar *from, + uint param_data) +{ + uint from_len= param_data & 0x00ff; // length. + uint length= 0; + 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); + store((const char *)from, length, system_charset_info); + return from+length; +} + + const uchar *Field_string::unpack(uchar *to, const uchar *from) { uint length; @@ -6797,6 +6920,44 @@ uchar *Field_varstring::pack_key_from_key_image(uchar *to, const uchar *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 uchar *Field_varstring::unpack(uchar *to, + const uchar *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() */ @@ -7493,6 +7654,29 @@ uchar *Field_blob::pack(uchar *to, const uchar *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 uchar *Field_blob::unpack(uchar *to, + const uchar *from, + uint param_data) +{ + return unpack(to, from); +} + + const uchar *Field_blob::unpack(uchar *to, const uchar *from) { memcpy(to,from,packlength); @@ -8540,6 +8724,58 @@ uchar *Field_bit::pack(uchar *to, const uchar *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 uchar *Field_bit::unpack(uchar *to, + const uchar *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 uchar *Field_bit::unpack(uchar *to, const uchar *from) { if (bit_len > 0) diff --git a/sql/field.h b/sql/field.h index 8bf087c7ebd..c1130d53569 100644 --- a/sql/field.h +++ b/sql/field.h @@ -345,6 +345,7 @@ public: memcpy(to,from,length); return to+length; } + virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); virtual const uchar *unpack(uchar* to, const uchar *from) { uint length=pack_length(); @@ -628,6 +629,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 uchar *unpack(uchar* to, const uchar *from, uint param_data); }; @@ -1164,6 +1166,7 @@ public: void sort_string(uchar *buff,uint length); void sql_type(String &str) const; uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); + virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); const uchar *unpack(uchar* to, const uchar *from); int pack_cmp(const uchar *a,const uchar *b,uint key_length, my_bool insert_or_update); @@ -1240,6 +1243,7 @@ public: uchar *pack_key(uchar *to, const uchar *from, uint max_length); uchar *pack_key_from_key_image(uchar* to, const uchar *from, uint max_length); + virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); const uchar *unpack(uchar* to, const uchar *from); const uchar *unpack_key(uchar* to, const uchar *from, uint max_length); int pack_cmp(const uchar *a, const uchar *b, uint key_length, @@ -1295,6 +1299,9 @@ public: l_char_length <= 16777215 ? 3 : 4; } } + Field_blob(uint32 packlength_arg) + :Field_longstr((uchar*) 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; } @@ -1316,6 +1323,17 @@ public: void sort_string(uchar *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 { @@ -1331,7 +1349,18 @@ 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((const uchar *)ptr);} + inline uint32 get_length(uint row_offset=0) { return get_length(ptr+row_offset); } uint32 get_length(const uchar *ptr); @@ -1379,6 +1408,7 @@ public: uchar *pack_key(uchar *to, const uchar *from, uint max_length); uchar *pack_key_from_key_image(uchar* to, const uchar *from, uint max_length); + virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data); const uchar *unpack(uchar *to, const uchar *from); const uchar *unpack_key(uchar* to, const uchar *from, uint max_length); int pack_cmp(const uchar *a, const uchar *b, uint key_length, @@ -1554,6 +1584,7 @@ public: uint32 pack_length_in_rec() const { return bytes_in_rec; } void sql_type(String &str) const; uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); + virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data); const uchar *unpack(uchar* to, const uchar *from); virtual void set_default(); diff --git a/sql/log_event.cc b/sql/log_event.cc index dc492d08c10..22b5a96753d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6028,11 +6028,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) @@ -6128,6 +6125,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 */ rli->report(ERROR_LEVEL, thd->net.last_errno, @@ -6378,6 +6382,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: + { + char *ptr= (char *)&m_field_metadata[index]; + int2store(ptr, 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 @@ -6392,9 +6553,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); /* @@ -6413,6 +6573,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= (uchar*) my_malloc(m_colcnt, MYF(MY_WME)))) @@ -6421,6 +6591,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= (uchar *)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) */ @@ -6436,8 +6628,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; @@ -6508,6 +6702,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= (uchar *)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; @@ -6516,6 +6726,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)); } @@ -6646,7 +6857,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; /* @@ -6718,12 +6930,22 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file) uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt); DBUG_ASSERT(static_cast(cbuf_end - cbuf) <= sizeof(cbuf)); + /* + Store the size of the field metadata. + */ + uchar mbuf[sizeof(m_field_metadata_size)]; + uchar *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 uchar*)m_dbnam, m_dblen+1) || my_b_safe_write(file, tbuf, sizeof(tbuf)) || my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) || my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) || - my_b_safe_write(file, m_coltype, m_colcnt)); + my_b_safe_write(file, m_coltype, m_colcnt) || + my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) || + my_b_safe_write(file, m_field_metadata, m_field_metadata_size), + my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8)); } #endif @@ -6946,6 +7168,7 @@ copy_extra_record_fields(TABLE *table, 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", @@ -6956,7 +7179,11 @@ 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). */ - DBUG_ASSERT(master_reclength <= table->s->reclength); + + 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, table->record[1] + master_reclength, @@ -7013,7 +7240,7 @@ copy_extra_record_fields(TABLE *table, } } } - return 0; // All OK + DBUG_RETURN(0); // All OK } #define DBUG_PRINT_BITSET(N,FRM,BS) \ @@ -7603,12 +7830,6 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, uchar const **const row_end) { 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); - if (int error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end, &m_master_reclength, table->read_set, DELETE_ROWS_EVENT)) { @@ -7786,12 +8007,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/log_event.h b/sql/log_event.h index 6787aa08016..e22a9785736 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -2049,6 +2049,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; } @@ -2085,6 +2087,14 @@ private: flag_set m_flags; 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; + uchar *m_meta_memory; }; diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 94778948bf9..094ccbcdd7d 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -17,6 +17,8 @@ #include "rpl_rli.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 @@ -143,7 +145,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 @@ -191,7 +194,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; @@ -220,14 +225,42 @@ 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++; + } + + /* + 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; + } } /* diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index c458318594a..7ae21897e3f 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -18,6 +18,7 @@ #include "rpl_tblmap.h" #include "rpl_reporting.h" +#include "rpl_utility.h" struct RPL_TABLE_LIST; @@ -301,6 +302,15 @@ typedef struct st_relay_log_info : public Slave_reporting_capability 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 a04bcd1fab9..2a124c7b14e 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -16,17 +16,45 @@ #include "rpl_utility.h" #include "rpl_rli.h" -uint32 -field_length_from_packed(enum_field_types const field_type, - uchar 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; @@ -45,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; @@ -58,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; @@ -69,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? @@ -121,23 +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; - char buf[256]; - my_snprintf(buf, sizeof(buf), "Table width mismatch - " - "received %u columns, %s.%s has %u columns", - (uint) size(), tsh->db.str, tsh->table_name.str, - tsh->fields); - rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF, - ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf); - } - for (uint col= 0 ; col < cols_to_check ; ++col) { if (table->field[col]->type() != type(col)) diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 79e69aecaeb..c91113c9e2a 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -25,8 +25,6 @@ struct st_relay_log_info; typedef st_relay_log_info RELAY_LOG_INFO; -uint32 -field_length_from_packed(enum_field_types field_type, uchar const *data); /** A table definition from the master. @@ -57,19 +55,96 @@ 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, ulong 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= (uchar *)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: + { + 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. + */ + char *ptr= (char *)&field_metadata[index]; + m_field_metadata[i]= sint2korr(ptr); + 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; @@ -99,6 +174,48 @@ 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. @@ -121,6 +238,9 @@ public: private: ulong 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; + uchar *m_memory; }; /**