WL#3228 (NDB) : RBR using different table defs on slave/master

This patch adds the ability to store extra field metadata in the table
map event. This data can include pack_length() or field_lenght() for
fields such as CHAR or VARCHAR enabling developers to add code that
can check for compatibilty between master and slave columns. More 
importantly, the extra field metadata can be used to store data from the
master correctly should a VARCHAR field on the master be <= 255 bytes 
while the same field on the slave is > 255 bytes. 

The patch also includes the needed changes to unpack to ensure that data
which is smaller on the master can be unpacked correctly on the slave.

WL#3915 : (NDB) master's cols > slave

Slave starts accepting and handling rows of master's tables which have more columns.
The most important part of implementation is how to caclulate the amount of bytes to
skip for unknown by slave column.
parent 8f01f9d0
#############################################################
# 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 <s1) pairs are compatible types (WL#3228)
# Arbitrary paramaters of the test are:
# 1. the tables type
# 2. the types of the extra master's column f_s1,..., f_m
# 3. the numbers of common columns `s'
# 4. and extra columns `m' are par
#
# optionally
#
# 5. vary the common columns type within compatible ranges.
#
# constant size column type:
#BIGINT
#BLOB
#DATE
#DATETIME
#FLOAT
#INT, INTEGER
#LONGBLOB
#LONGTEXT
#MEDIUMBLOB
#MEDIUMINT
#MEDIUMTEXT
#REAL
#SMALLINT
#TEXT
#TIME
#TIMESTAMP
#TINYBLOB
#TINYINT
#TINYTEXT
#YEAR
# variable size column types:
#BINARY(M)
#BIT(M)
#CHAR(M)
#DECIMAL(M,D)
#DOUBLE[P]
#ENUM
#FLOAT(p)
#NUMERIC(M,D)
#SET
#VARBINARY(M)
#VARCHAR(M)
#
connection master;
eval CREATE TABLE t1 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */
f5 FLOAT DEFAULT '2.00',
f6 CHAR(4) DEFAULT 'TEST',
f7 INT DEFAULT '0',
f8 TEXT,
f9 LONGBLOB,
f10 BIT(63),
f11 VARBINARY(64))
ENGINE=$engine_type;
#connection slave;
sync_slave_with_master;
alter table t1 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11;
connection master;
INSERT into t1 values (1, 1, 1, 'first', 1.0, 'yksi', 1, 'lounge of happiness', 'very fat blob', b'01010101010101', 0x123456);
INSERT into t1 values (2, 2, 2, 'second', 2.0, 'kaks', 2, 'got stolen from the paradise', 'very fat blob', b'01010101010101', 0x123456), (3, 3, 3, 'third', 3.0, 'kolm', 3, 'got stolen from the paradise', 'very fat blob', b'01010101010101', 0x123456);
update t1 set f4= 'next' where f1=1;
delete from t1 where f1=1;
select * from t1 order by f3;
#connection slave;
sync_slave_with_master;
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
select * from t1 order by f3;
### Altering table def scenario
connection master;
eval CREATE TABLE t2 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */
f5 DOUBLE DEFAULT '2.00',
f6 ENUM('a', 'b', 'c') default 'a',
f7 DECIMAL(17,9) default '1000.00',
f8 MEDIUMBLOB,
f9 NUMERIC(6,4) default '2000.00',
f10 VARCHAR(1024),
f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
f12 SET('a', 'b', 'c') default 'b')
ENGINE=$engine_type;
eval CREATE TABLE t3 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */
f5 DOUBLE DEFAULT '2.00',
f6 ENUM('a', 'b', 'c') default 'a',
f8 MEDIUMBLOB,
f10 VARCHAR(1024),
f11 BINARY(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
f12 SET('a', 'b', 'c') default 'b')
ENGINE=$engine_type;
# no ENUM and SET
eval CREATE TABLE t4 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */
f5 DOUBLE DEFAULT '2.00',
f6 DECIMAL(17,9) default '1000.00',
f7 MEDIUMBLOB,
f8 NUMERIC(6,4) default '2000.00',
f9 VARCHAR(1024),
f10 BINARY(20) not null default '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
f11 CHAR(255))
ENGINE=$engine_type;
eval CREATE TABLE t31 (f1 INT, f2 INT, f3 INT PRIMARY KEY, f4 CHAR(20),
/* extra */
f5 BIGINT,
f6 BLOB,
f7 DATE,
f8 DATETIME,
f9 FLOAT,
f10 INT,
f11 LONGBLOB,
f12 LONGTEXT,
f13 MEDIUMBLOB,
f14 MEDIUMINT,
f15 MEDIUMTEXT,
f16 REAL,
f17 SMALLINT,
f18 TEXT,
f19 TIME,
f20 TIMESTAMP,
f21 TINYBLOB,
f22 TINYINT,
f23 TINYTEXT,
f24 YEAR,
f25 BINARY(255),
f26 BIT(64),
f27 CHAR(255),
f28 DECIMAL(30,7),
f29 DOUBLE,
f30 ENUM ('a','b', 'c') default 'a',
f31 FLOAT,
f32 NUMERIC(17,9),
f33 SET ('a', 'b', 'c') default 'b',
f34 VARBINARY(1025),
f35 VARCHAR(257)
) ENGINE=$engine_type;
#connection slave;
sync_slave_with_master;
alter table t2 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11, drop
f12;
alter table t3 drop f5, drop f6, drop f8, drop f10, drop f11, drop f12;
alter table t4 drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11;
alter table t31
drop f5, drop f6, drop f7, drop f8, drop f9, drop f10, drop f11,
drop f12, drop f13, drop f14, drop f15, drop f16, drop f17, drop f18,
drop f19, drop f20, drop f21, drop f22, drop f23, drop f24, drop f25,
drop f26, drop f27, drop f28, drop f29, drop f30, drop f31, drop f32,
drop f33, drop f34, drop f35;
connection master;
INSERT into t2 set f1=1, f2=1, f3=1, f4='first', f8='f8: medium size blob', f10='f10:
some var char';
INSERT into t2 values (2, 2, 2, 'second',
2.0, 'b', 2000.0002, 'f8: medium size blob', 2000, 'f10: some var char',
'01234567', 'c'),
(3, 3, 3, 'third',
3.0, 'b', 3000.0003, 'f8: medium size blob', 3000, 'f10: some var char',
'01234567', 'c');
INSERT into t3 set f1=1, f2=1, f3=1, f4='first', f10='f10: some var char';
INSERT into t4 set f1=1, f2=1, f3=1, f4='first', f7='f7: medium size blob', f10='f10:
binary data';
INSERT into t31 set f1=1, f2=1, f3=1, f4='first';
INSERT into t31 set f1=1, f2=1, f3=2, f4='second',
f9=2.2, f10='seven samurai', f28=222.222, f35='222';
INSERT into t31 values (1, 1, 3, 'third',
/* f5 BIGINT, */ 333333333333333333333333,
/* f6 BLOB, */ '3333333333333333333333',
/* f7 DATE, */ '2007-07-18',
/* f8 DATETIME, */ "2007-07-18",
/* f9 FLOAT, */ 3.33333333,
/* f10 INT, */ 333333333,
/* f11 LONGBLOB, */ '3333333333333333333',
/* f12 LONGTEXT, */ '3333333333333333333',
/* f13 MEDIUMBLOB, */ '3333333333333333333',
/* f14 MEDIUMINT, */ 33,
/* f15 MEDIUMTEXT, */ 3.3,
/* f16 REAL, */ 3.3,
/* f17 SMALLINT, */ 3,
/* f18 TEXT, */ '33',
/* f19 TIME, */ '2:59:58.999',
/* f20 TIMESTAMP, */ 20000303000000,
/* f21 TINYBLOB, */ '3333',
/* f22 TINYINT, */ 3,
/* f23 TINYTEXT, */ '3',
/* f24 YEAR, */ 3000,
/* f25 BINARY(255), */ 'three_33333',
/* f26 BIT(64), */ b'011',
/* f27 CHAR(255), */ 'three',
/* f28 DECIMAL(30,7), */ 3.333,
/* f29 DOUBLE, */ 3.333333333333333333333333333,
/* f30 ENUM ('a','b','c')*/ 'c',
/* f31 FLOAT, */ 3.0,
/* f32 NUMERIC(17,9), */ 3.3333,
/* f33 SET ('a','b','c'),*/ 'c',
/*f34 VARBINARY(1025),*/ '3333 minus 3',
/*f35 VARCHAR(257),*/ 'three times three'
);
INSERT into t31 values (1, 1, 4, 'fourth',
/* f5 BIGINT, */ 333333333333333333333333,
/* f6 BLOB, */ '3333333333333333333333',
/* f7 DATE, */ '2007-07-18',
/* f8 DATETIME, */ "2007-07-18",
/* f9 FLOAT, */ 3.33333333,
/* f10 INT, */ 333333333,
/* f11 LONGBLOB, */ '3333333333333333333',
/* f12 LONGTEXT, */ '3333333333333333333',
/* f13 MEDIUMBLOB, */ '3333333333333333333',
/* f14 MEDIUMINT, */ 33,
/* f15 MEDIUMTEXT, */ 3.3,
/* f16 REAL, */ 3.3,
/* f17 SMALLINT, */ 3,
/* f18 TEXT, */ '33',
/* f19 TIME, */ '2:59:58.999',
/* f20 TIMESTAMP, */ 20000303000000,
/* f21 TINYBLOB, */ '3333',
/* f22 TINYINT, */ 3,
/* f23 TINYTEXT, */ '3',
/* f24 YEAR, */ 3000,
/* f25 BINARY(255), */ 'three_33333',
/* f26 BIT(64), */ b'011',
/* f27 CHAR(255), */ 'three',
/* f28 DECIMAL(30,7), */ 3.333,
/* f29 DOUBLE, */ 3.333333333333333333333333333,
/* f30 ENUM ('a','b','c')*/ 'c',
/* f31 FLOAT, */ 3.0,
/* f32 NUMERIC(17,9), */ 3.3333,
/* f33 SET ('a','b','c'),*/ 'c',
/*f34 VARBINARY(1025),*/ '3333 minus 3',
/*f35 VARCHAR(257),*/ 'three times three'
),
(1, 1, 5, 'fifth',
/* f5 BIGINT, */ 333333333333333333333333,
/* f6 BLOB, */ '3333333333333333333333',
/* f7 DATE, */ '2007-07-18',
/* f8 DATETIME, */ "2007-07-18",
/* f9 FLOAT, */ 3.33333333,
/* f10 INT, */ 333333333,
/* f11 LONGBLOB, */ '3333333333333333333',
/* f12 LONGTEXT, */ '3333333333333333333',
/* f13 MEDIUMBLOB, */ '3333333333333333333',
/* f14 MEDIUMINT, */ 33,
/* f15 MEDIUMTEXT, */ 3.3,
/* f16 REAL, */ 3.3,
/* f17 SMALLINT, */ 3,
/* f18 TEXT, */ '33',
/* f19 TIME, */ '2:59:58.999',
/* f20 TIMESTAMP, */ 20000303000000,
/* f21 TINYBLOB, */ '3333',
/* f22 TINYINT, */ 3,
/* f23 TINYTEXT, */ '3',
/* f24 YEAR, */ 3000,
/* f25 BINARY(255), */ 'three_33333',
/* f26 BIT(64), */ b'011',
/* f27 CHAR(255), */ 'three',
/* f28 DECIMAL(30,7), */ 3.333,
/* f29 DOUBLE, */ 3.333333333333333333333333333,
/* f30 ENUM ('a','b','c')*/ 'c',
/* f31 FLOAT, */ 3.0,
/* f32 NUMERIC(17,9), */ 3.3333,
/* f33 SET ('a','b','c'),*/ 'c',
/*f34 VARBINARY(1025),*/ '3333 minus 3',
/*f35 VARCHAR(257),*/ 'three times three'
),
(1, 1, 6, 'sixth',
/* f5 BIGINT, */ NULL,
/* f6 BLOB, */ '3333333333333333333333',
/* f7 DATE, */ '2007-07-18',
/* f8 DATETIME, */ "2007-07-18",
/* f9 FLOAT, */ 3.33333333,
/* f10 INT, */ 333333333,
/* f11 LONGBLOB, */ '3333333333333333333',
/* f12 LONGTEXT, */ '3333333333333333333',
/* f13 MEDIUMBLOB, */ '3333333333333333333',
/* f14 MEDIUMINT, */ 33,
/* f15 MEDIUMTEXT, */ 3.3,
/* f16 REAL, */ 3.3,
/* f17 SMALLINT, */ 3,
/* f18 TEXT, */ '33',
/* f19 TIME, */ '2:59:58.999',
/* f20 TIMESTAMP, */ 20000303000000,
/* f21 TINYBLOB, */ '3333',
/* f22 TINYINT, */ 3,
/* f23 TINYTEXT, */ '3',
/* f24 YEAR, */ 3000,
/* f25 BINARY(255), */ 'three_33333',
/* f26 BIT(64), */ b'011',
/* f27 CHAR(255), */ 'three',
/* f28 DECIMAL(30,7), */ 3.333,
/* f29 DOUBLE, */ 3.333333333333333333333333333,
/* f30 ENUM ('a','b','c')*/ 'c',
/* f31 FLOAT, */ 3.0,
/* f32 NUMERIC(17,9), */ 3.3333,
/* f33 SET ('a','b','c'),*/ 'c',
/*f34 VARBINARY(1025),*/ '3333 minus 3',
/*f35 VARCHAR(257),*/ NULL
);
#connection slave;
sync_slave_with_master;
select * from t1 order by f3;
select * from t2 order by f1;
select * from t3 order by f1;
select * from t4 order by f1;
select * from t31 order by f1;
connection master;
update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3;
delete from t1;
delete from t2;
delete from t3;
delete from t4;
delete from t31;
#connection slave;
sync_slave_with_master;
select * from t31;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical show slave status;
#### Clean Up ####
connection master;
--disable_warnings
--disable_query_log
DROP TABLE t1,t2,t3,t4,t31;
#connection slave;
sync_slave_with_master;
--enable_query_log
--enable_warnings
# END of the tests
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
# ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction # ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction
# and does not make slave to stop) # and does not make slave to stop)
flush logs; flush logs;
--exec $MYSQL_BINLOG --start-position=520 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output --exec $MYSQL_BINLOG --start-position=524 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output")) (@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
......
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;
...@@ -56,8 +56,8 @@ SHOW BINLOG EVENTS; ...@@ -56,8 +56,8 @@ SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info 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 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 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 192 Table_map 1 233 table_id: # (test.t1)
master-bin.000001 231 Write_rows 1 270 table_id: # flags: STMT_END_F master-bin.000001 233 Write_rows 1 272 table_id: # flags: STMT_END_F
DROP TABLE t1; DROP TABLE t1;
================ Test for BUG#17620 ================ ================ Test for BUG#17620 ================
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
......
...@@ -127,7 +127,7 @@ NULL 5 10 ...@@ -127,7 +127,7 @@ NULL 5 10
NULL 6 12 NULL 6 12
CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
ERROR 23000: Duplicate entry '2' for key 'b' 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 Log_name Pos Event_type Server_id End_log_pos Info
CREATE TABLE t7 (a INT, b INT UNIQUE); CREATE TABLE t7 (a INT, b INT UNIQUE);
INSERT INTO t7 SELECT a,b FROM tt3; INSERT INTO t7 SELECT a,b FROM tt3;
...@@ -137,11 +137,11 @@ a b ...@@ -137,11 +137,11 @@ a b
1 2 1 2
2 4 2 4
3 6 3 6
SHOW BINLOG EVENTS FROM 1098; SHOW BINLOG EVENTS FROM 1100;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
# 1098 Query # 1198 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE) # 1100 Query # 1200 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
# 1198 Table_map # 1238 table_id: # (test.t7) # 1200 Table_map # 1242 table_id: # (test.t7)
# 1238 Write_rows # 1294 table_id: # flags: STMT_END_F # 1242 Write_rows # 1298 table_id: # flags: STMT_END_F
SELECT * FROM t7 ORDER BY a,b; SELECT * FROM t7 ORDER BY a,b;
a b a b
1 2 1 2
...@@ -154,10 +154,10 @@ INSERT INTO t7 SELECT a,b FROM tt4; ...@@ -154,10 +154,10 @@ INSERT INTO t7 SELECT a,b FROM tt4;
ROLLBACK; ROLLBACK;
Warnings: Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back 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 Log_name Pos Event_type Server_id End_log_pos Info
# 1294 Table_map # 1334 table_id: # (test.t7) # 1298 Table_map # 1340 table_id: # (test.t7)
# 1334 Write_rows # 1390 table_id: # flags: STMT_END_F # 1340 Write_rows # 1396 table_id: # flags: STMT_END_F
SELECT * FROM t7 ORDER BY a,b; SELECT * FROM t7 ORDER BY a,b;
a b a b
1 2 1 2
...@@ -192,10 +192,10 @@ Create Table CREATE TABLE `t9` ( ...@@ -192,10 +192,10 @@ Create Table CREATE TABLE `t9` (
`a` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL `b` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) 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 Log_name Pos Event_type Server_id End_log_pos Info
# 1390 Query # 1476 use `test`; CREATE TABLE t8 LIKE t4 # 1396 Query # 1482 use `test`; CREATE TABLE t8 LIKE t4
# 1476 Query # 1615 use `test`; CREATE TABLE `t9` ( # 1482 Query # 1621 use `test`; CREATE TABLE `t9` (
`a` int(11) DEFAULT NULL, `a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL `b` int(11) DEFAULT NULL
) )
...@@ -276,31 +276,31 @@ SHOW BINLOG EVENTS; ...@@ -276,31 +276,31 @@ SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
# 4 Format_desc # 106 Server ver: #, Binlog ver: # # 4 Format_desc # 106 Server ver: #, Binlog ver: #
# 106 Query # 192 use `test`; CREATE TABLE t1 (a INT) # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT)
# 192 Table_map # 231 table_id: # (test.t1) # 192 Table_map # 233 table_id: # (test.t1)
# 231 Write_rows # 275 table_id: # flags: STMT_END_F # 233 Write_rows # 277 table_id: # flags: STMT_END_F
# 275 Query # 343 use `test`; BEGIN # 277 Query # 345 use `test`; BEGIN
# 343 Query # 468 use `test`; CREATE TABLE `t2` ( # 345 Query # 470 use `test`; CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=InnoDB ) ENGINE=InnoDB
# 468 Table_map # 507 table_id: # (test.t2) # 470 Table_map # 511 table_id: # (test.t2)
# 507 Write_rows # 551 table_id: # flags: STMT_END_F # 511 Write_rows # 555 table_id: # flags: STMT_END_F
# 551 Xid # 578 COMMIT /* XID */ # 555 Xid # 582 COMMIT /* XID */
# 578 Query # 646 use `test`; BEGIN # 582 Query # 650 use `test`; BEGIN
# 646 Query # 771 use `test`; CREATE TABLE `t3` ( # 650 Query # 775 use `test`; CREATE TABLE `t3` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=InnoDB ) ENGINE=InnoDB
# 771 Table_map # 810 table_id: # (test.t3) # 775 Table_map # 816 table_id: # (test.t3)
# 810 Write_rows # 854 table_id: # flags: STMT_END_F # 816 Write_rows # 860 table_id: # flags: STMT_END_F
# 854 Xid # 881 COMMIT /* XID */ # 860 Xid # 887 COMMIT /* XID */
# 881 Query # 949 use `test`; BEGIN # 887 Query # 955 use `test`; BEGIN
# 949 Query # 1074 use `test`; CREATE TABLE `t4` ( # 955 Query # 1080 use `test`; CREATE TABLE `t4` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=InnoDB ) ENGINE=InnoDB
# 1074 Table_map # 1113 table_id: # (test.t4) # 1080 Table_map # 1121 table_id: # (test.t4)
# 1113 Write_rows # 1157 table_id: # flags: STMT_END_F # 1121 Write_rows # 1165 table_id: # flags: STMT_END_F
# 1157 Xid # 1184 COMMIT /* XID */ # 1165 Xid # 1192 COMMIT /* XID */
# 1184 Table_map # 1223 table_id: # (test.t1) # 1192 Table_map # 1233 table_id: # (test.t1)
# 1223 Write_rows # 1267 table_id: # flags: STMT_END_F # 1233 Write_rows # 1277 table_id: # flags: STMT_END_F
SHOW TABLES; SHOW TABLES;
Tables_in_test Tables_in_test
t1 t1
...@@ -367,15 +367,15 @@ SHOW BINLOG EVENTS; ...@@ -367,15 +367,15 @@ SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
# 4 Format_desc # 106 Server ver: #, Binlog ver: # # 4 Format_desc # 106 Server ver: #, Binlog ver: #
# 106 Query # 192 use `test`; CREATE TABLE t1 (a INT) # 106 Query # 192 use `test`; CREATE TABLE t1 (a INT)
# 192 Table_map # 231 table_id: # (test.t1) # 192 Table_map # 233 table_id: # (test.t1)
# 231 Write_rows # 275 table_id: # flags: STMT_END_F # 233 Write_rows # 277 table_id: # flags: STMT_END_F
# 275 Query # 375 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB # 277 Query # 377 use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB
# 375 Query # 443 use `test`; BEGIN # 377 Query # 445 use `test`; BEGIN
# 443 Table_map # 482 table_id: # (test.t2) # 445 Table_map # 486 table_id: # (test.t2)
# 482 Write_rows # 526 table_id: # flags: STMT_END_F # 486 Write_rows # 530 table_id: # flags: STMT_END_F
# 526 Table_map # 565 table_id: # (test.t2) # 530 Table_map # 571 table_id: # (test.t2)
# 565 Write_rows # 604 table_id: # flags: STMT_END_F # 571 Write_rows # 610 table_id: # flags: STMT_END_F
# 604 Xid # 631 COMMIT /* XID */ # 610 Xid # 637 COMMIT /* XID */
SELECT * FROM t2 ORDER BY a; SELECT * FROM t2 ORDER BY a;
a a
1 1
...@@ -394,10 +394,10 @@ INSERT INTO t2 SELECT a+2 FROM tt2; ...@@ -394,10 +394,10 @@ INSERT INTO t2 SELECT a+2 FROM tt2;
ROLLBACK; ROLLBACK;
SELECT * FROM t2 ORDER BY a; SELECT * FROM t2 ORDER BY a;
a a
SHOW BINLOG EVENTS FROM 631; SHOW BINLOG EVENTS FROM 637;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
# 631 Query # 711 use `test`; TRUNCATE TABLE t2 # 637 Query # 717 use `test`; TRUNCATE TABLE t2
# 711 Xid # 738 COMMIT /* XID */ # 717 Xid # 744 COMMIT /* XID */
SELECT * FROM t2 ORDER BY a; SELECT * FROM t2 ORDER BY a;
a a
DROP TABLE t1,t2; DROP TABLE t1,t2;
...@@ -12,13 +12,13 @@ create table t4 (a int); ...@@ -12,13 +12,13 @@ create table t4 (a int);
insert into t4 select * from t3; insert into t4 select * from t3;
rename table t1 to t5, t2 to t1; rename table t1 to t5, t2 to t1;
flush no_write_to_binlog tables; 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 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`; rename table t1 to t5, t2 to t1
select * from t3; select * from t3;
a a
flush tables; flush tables;
SHOW BINLOG EVENTS FROM 619 ; SHOW BINLOG EVENTS FROM 623 ;
Log_name Pos Event_type Server_id End_log_pos Info 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`; rename table t1 to t5, t2 to t1
master-bin.000001 # Query 1 # use `test`; flush tables master-bin.000001 # Query 1 # use `test`; flush tables
......
...@@ -24,7 +24,7 @@ Master_User root ...@@ -24,7 +24,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 597 Read_Master_Log_Pos 605
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -39,7 +39,7 @@ Replicate_Wild_Ignore_Table ...@@ -39,7 +39,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 1146 Last_Errno 1146
Last_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1` Last_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1`
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 524 Exec_Master_Log_Pos 530
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
......
...@@ -208,13 +208,13 @@ master-bin.000002 # Table_map 1 # table_id: # (test.t2) ...@@ -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 master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F
show binary logs; show binary logs;
Log_name File_size Log_name File_size
master-bin.000001 1260 master-bin.000001 1266
master-bin.000002 377 master-bin.000002 379
start slave; start slave;
show binary logs; show binary logs;
Log_name File_size Log_name File_size
slave-bin.000001 1358 slave-bin.000001 1364
slave-bin.000002 278 slave-bin.000002 280
show binlog events in 'slave-bin.000001' from 4; show binlog events in 'slave-bin.000001' from 4;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
...@@ -240,7 +240,7 @@ Master_User root ...@@ -240,7 +240,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000002 Master_Log_File master-bin.000002
Read_Master_Log_Pos 377 Read_Master_Log_Pos 379
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000002 Relay_Master_Log_File master-bin.000002
...@@ -255,7 +255,7 @@ Replicate_Wild_Ignore_Table ...@@ -255,7 +255,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 377 Exec_Master_Log_Pos 379
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
......
...@@ -213,13 +213,13 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F ...@@ -213,13 +213,13 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000002 # Xid 1 # COMMIT /* XID */ master-bin.000002 # Xid 1 # COMMIT /* XID */
show binary logs; show binary logs;
Log_name File_size Log_name File_size
master-bin.000001 1314 master-bin.000001 1320
master-bin.000002 404 master-bin.000002 406
start slave; start slave;
show binary logs; show binary logs;
Log_name File_size Log_name File_size
slave-bin.000001 1412 slave-bin.000001 1418
slave-bin.000002 305 slave-bin.000002 307
show binlog events in 'slave-bin.000001' from 4; show binlog events in 'slave-bin.000001' from 4;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4 slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
...@@ -248,7 +248,7 @@ Master_User root ...@@ -248,7 +248,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000002 Master_Log_File master-bin.000002
Read_Master_Log_Pos 404 Read_Master_Log_Pos 406
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000002 Relay_Master_Log_File master-bin.000002
...@@ -263,7 +263,7 @@ Replicate_Wild_Ignore_Table ...@@ -263,7 +263,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 404 Exec_Master_Log_Pos 406
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
......
...@@ -30,7 +30,7 @@ Master_User root ...@@ -30,7 +30,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 58668 Read_Master_Log_Pos 60268
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -45,7 +45,7 @@ Replicate_Wild_Ignore_Table ...@@ -45,7 +45,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 58668 Exec_Master_Log_Pos 60268
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
...@@ -78,7 +78,7 @@ Master_User root ...@@ -78,7 +78,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 58668 Read_Master_Log_Pos 60268
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -93,7 +93,7 @@ Replicate_Wild_Ignore_Table ...@@ -93,7 +93,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 58668 Exec_Master_Log_Pos 60268
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
...@@ -126,7 +126,7 @@ Master_User root ...@@ -126,7 +126,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 58668 Read_Master_Log_Pos 60268
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -141,7 +141,7 @@ Replicate_Wild_Ignore_Table ...@@ -141,7 +141,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 58668 Exec_Master_Log_Pos 60268
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
...@@ -217,7 +217,7 @@ Master_User root ...@@ -217,7 +217,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 58754 Read_Master_Log_Pos 60354
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -232,7 +232,7 @@ Replicate_Wild_Ignore_Table ...@@ -232,7 +232,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 58754 Exec_Master_Log_Pos 60354
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
...@@ -261,7 +261,7 @@ Master_User root ...@@ -261,7 +261,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 58830 Read_Master_Log_Pos 60430
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -276,7 +276,7 @@ Replicate_Wild_Ignore_Table ...@@ -276,7 +276,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 58830 Exec_Master_Log_Pos 60430
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
......
...@@ -146,187 +146,17 @@ SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; ...@@ -146,187 +146,17 @@ SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE; START SLAVE;
INSERT INTO t9 VALUES (2); INSERT INTO t9 VALUES (2);
INSERT INTO t2 VALUES (2,4); INSERT INTO t2 VALUES (2,4);
"Failed while waiting for slave SQL thread to stop"
SHOW SLAVE STATUS; 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
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_Host 127.0.0.1
Master_User root Master_User root
Master_Port MASTER_PORT Master_Port 9306
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos # Read_Master_Log_Pos 2829
Relay_Log_File # Relay_Log_File slave-relay-bin.000007
Relay_Log_Pos # Relay_Log_Pos 252
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 #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes Slave_IO_Running Yes
Slave_SQL_Running Yes Slave_SQL_Running Yes
...@@ -339,8 +169,8 @@ Replicate_Wild_Ignore_Table ...@@ -339,8 +169,8 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos # Exec_Master_Log_Pos 2829
Relay_Log_Space # Relay_Log_Space 553
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
Until_Log_Pos 0 Until_Log_Pos 0
...@@ -350,64 +180,9 @@ Master_SSL_CA_Path ...@@ -350,64 +180,9 @@ Master_SSL_CA_Path
Master_SSL_Cert Master_SSL_Cert
Master_SSL_Cipher Master_SSL_Cipher
Master_SSL_Key Master_SSL_Key
Seconds_Behind_Master # Seconds_Behind_Master 0
Master_SSL_Verify_Server_Cert No Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0 Last_IO_Errno 0
Last_IO_Error Last_IO_Error
Last_SQL_Errno 0 Last_SQL_Errno 0
Last_SQL_Error 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;
...@@ -146,187 +146,17 @@ SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; ...@@ -146,187 +146,17 @@ SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE; START SLAVE;
INSERT INTO t9 VALUES (2); INSERT INTO t9 VALUES (2);
INSERT INTO t2 VALUES (2,4); INSERT INTO t2 VALUES (2,4);
"Failed while waiting for slave SQL thread to stop"
SHOW SLAVE STATUS; 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
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_Host 127.0.0.1
Master_User root Master_User root
Master_Port MASTER_PORT Master_Port 9306
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos # Read_Master_Log_Pos 3180
Relay_Log_File # Relay_Log_File slave-relay-bin.000007
Relay_Log_Pos # Relay_Log_Pos 252
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 #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
Slave_IO_Running Yes Slave_IO_Running Yes
Slave_SQL_Running Yes Slave_SQL_Running Yes
...@@ -339,8 +169,8 @@ Replicate_Wild_Ignore_Table ...@@ -339,8 +169,8 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos # Exec_Master_Log_Pos 3180
Relay_Log_Space # Relay_Log_Space 553
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
Until_Log_Pos 0 Until_Log_Pos 0
...@@ -350,64 +180,9 @@ Master_SSL_CA_Path ...@@ -350,64 +180,9 @@ Master_SSL_CA_Path
Master_SSL_Cert Master_SSL_Cert
Master_SSL_Cipher Master_SSL_Cipher
Master_SSL_Key Master_SSL_Key
Seconds_Behind_Master # Seconds_Behind_Master 0
Master_SSL_Verify_Server_Cert No Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0 Last_IO_Errno 0
Last_IO_Error Last_IO_Error
Last_SQL_Errno 0 Last_SQL_Errno 0
Last_SQL_Error 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;
...@@ -26,7 +26,7 @@ Master_User root ...@@ -26,7 +26,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 744 Read_Master_Log_Pos 750
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -41,7 +41,7 @@ Replicate_Wild_Ignore_Table ...@@ -41,7 +41,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 315 Exec_Master_Log_Pos 317
Relay_Log_Space # Relay_Log_Space #
Until_Condition Master Until_Condition Master
Until_Log_File master-bin.000001 Until_Log_File master-bin.000001
...@@ -72,7 +72,7 @@ Master_User root ...@@ -72,7 +72,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 744 Read_Master_Log_Pos 750
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -87,7 +87,7 @@ Replicate_Wild_Ignore_Table ...@@ -87,7 +87,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 315 Exec_Master_Log_Pos 317
Relay_Log_Space # Relay_Log_Space #
Until_Condition Master Until_Condition Master
Until_Log_File master-no-such-bin.000001 Until_Log_File master-no-such-bin.000001
...@@ -116,7 +116,7 @@ Master_User root ...@@ -116,7 +116,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 744 Read_Master_Log_Pos 750
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -131,7 +131,7 @@ Replicate_Wild_Ignore_Table ...@@ -131,7 +131,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 590 Exec_Master_Log_Pos 594
Relay_Log_Space # Relay_Log_Space #
Until_Condition Relay Until_Condition Relay
Until_Log_File slave-relay-bin.000004 Until_Log_File slave-relay-bin.000004
...@@ -158,7 +158,7 @@ Master_User root ...@@ -158,7 +158,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000001 Master_Log_File master-bin.000001
Read_Master_Log_Pos 744 Read_Master_Log_Pos 750
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001 Relay_Master_Log_File master-bin.000001
...@@ -173,7 +173,7 @@ Replicate_Wild_Ignore_Table ...@@ -173,7 +173,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 744 Exec_Master_Log_Pos 750
Relay_Log_Space # Relay_Log_Space #
Until_Condition Master Until_Condition Master
Until_Log_File master-bin.000001 Until_Log_File master-bin.000001
......
...@@ -32,5 +32,5 @@ a ...@@ -32,5 +32,5 @@ a
3 3
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error 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; drop table t1;
...@@ -15,3 +15,4 @@ rpl_innodb_mixed_ddl : Bug #29363 rpl.rpl_innodb_mixed_* test failures ...@@ -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_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_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_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.
##################################################################
# 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
#############################################################
# 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
#############################################################
# 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
...@@ -72,7 +72,7 @@ CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3; ...@@ -72,7 +72,7 @@ CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
# Shouldn't be written to the binary log # Shouldn't be written to the binary log
--replace_column 1 # 4 # --replace_column 1 # 4 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ --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. # Test that INSERT-SELECT works the same way as for SBR.
CREATE TABLE t7 (a INT, b INT UNIQUE); CREATE TABLE t7 (a INT, b INT UNIQUE);
...@@ -82,7 +82,7 @@ SELECT * FROM t7 ORDER BY a,b; ...@@ -82,7 +82,7 @@ SELECT * FROM t7 ORDER BY a,b;
# Should be written to the binary log # Should be written to the binary log
--replace_column 1 # 4 # --replace_column 1 # 4 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
SHOW BINLOG EVENTS FROM 1098; SHOW BINLOG EVENTS FROM 1100;
sync_slave_with_master; sync_slave_with_master;
SELECT * FROM t7 ORDER BY a,b; SELECT * FROM t7 ORDER BY a,b;
...@@ -94,7 +94,7 @@ INSERT INTO t7 SELECT a,b FROM tt4; ...@@ -94,7 +94,7 @@ INSERT INTO t7 SELECT a,b FROM tt4;
ROLLBACK; ROLLBACK;
--replace_column 1 # 4 # --replace_column 1 # 4 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ --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; SELECT * FROM t7 ORDER BY a,b;
sync_slave_with_master; sync_slave_with_master;
SELECT * FROM t7 ORDER BY a,b; SELECT * FROM t7 ORDER BY a,b;
...@@ -110,7 +110,7 @@ CREATE TEMPORARY TABLE tt7 SELECT 1; ...@@ -110,7 +110,7 @@ CREATE TEMPORARY TABLE tt7 SELECT 1;
--query_vertical SHOW CREATE TABLE t9 --query_vertical SHOW CREATE TABLE t9
--replace_column 1 # 4 # --replace_column 1 # 4 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
SHOW BINLOG EVENTS FROM 1390; SHOW BINLOG EVENTS FROM 1396;
sync_slave_with_master; sync_slave_with_master;
--echo **** On Slave **** --echo **** On Slave ****
--query_vertical SHOW CREATE TABLE t8 --query_vertical SHOW CREATE TABLE t8
...@@ -227,7 +227,7 @@ ROLLBACK; ...@@ -227,7 +227,7 @@ ROLLBACK;
SELECT * FROM t2 ORDER BY a; SELECT * FROM t2 ORDER BY a;
--replace_column 1 # 4 # --replace_column 1 # 4 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/ --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; sync_slave_with_master;
SELECT * FROM t2 ORDER BY a; SELECT * FROM t2 ORDER BY a;
......
###########################################
# 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
# depends on the binlog output # depends on the binlog output
-- source include/have_binlog_format_row.inc -- 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 # 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 # The use of the ps protocol causes extra table maps in the binlog, so
......
###########################################
# 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
...@@ -228,12 +228,12 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F ...@@ -228,12 +228,12 @@ master-bin.000002 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000002 # Query 1 # COMMIT master-bin.000002 # Query 1 # COMMIT
show binary logs; show binary logs;
Log_name File_size Log_name File_size
master-bin.000001 1746 master-bin.000001 1760
master-bin.000002 617 master-bin.000002 623
start slave; start slave;
show binary logs; show binary logs;
Log_name File_size Log_name File_size
slave-bin.000001 1841 slave-bin.000001 1855
slave-bin.000002 202 slave-bin.000002 202
show binlog events in 'slave-bin.000001' from 4; show binlog events in 'slave-bin.000001' from 4;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
...@@ -272,7 +272,7 @@ Master_User root ...@@ -272,7 +272,7 @@ Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000002 Master_Log_File master-bin.000002
Read_Master_Log_Pos 617 Read_Master_Log_Pos 623
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
Relay_Master_Log_File master-bin.000002 Relay_Master_Log_File master-bin.000002
...@@ -287,7 +287,7 @@ Replicate_Wild_Ignore_Table ...@@ -287,7 +287,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0 Last_Errno 0
Last_Error Last_Error
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos 617 Exec_Master_Log_Pos 623
Relay_Log_Space # Relay_Log_Space #
Until_Condition None Until_Condition None
Until_Log_File Until_Log_File
......
...@@ -32,13 +32,13 @@ Log_name Pos Event_type Server_id End_log_pos Info ...@@ -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 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 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 223 Query 1 287 BEGIN
master-bin.000001 287 Table_map 1 327 table_id: # (test.t1) master-bin.000001 287 Table_map 1 330 table_id: # (test.t1)
master-bin.000001 327 Table_map 1 385 table_id: # (mysql.ndb_apply_status) master-bin.000001 330 Table_map 1 392 table_id: # (mysql.ndb_apply_status)
master-bin.000001 385 Write_rows 1 444 table_id: # master-bin.000001 392 Write_rows 1 451 table_id: #
master-bin.000001 444 Write_rows 1 491 table_id: # flags: STMT_END_F master-bin.000001 451 Write_rows 1 498 table_id: # flags: STMT_END_F
master-bin.000001 491 Query 1 556 COMMIT master-bin.000001 498 Query 1 563 COMMIT
master-bin.000001 556 Query 1 636 use `test`; TRUNCATE TABLE t1 master-bin.000001 563 Query 1 643 use `test`; TRUNCATE TABLE t1
master-bin.000001 636 Query 1 712 use `test`; DROP TABLE t1 master-bin.000001 643 Query 1 719 use `test`; DROP TABLE t1
**** On Master **** **** On Master ****
CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB;
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);
...@@ -68,24 +68,24 @@ Log_name Pos Event_type Server_id End_log_pos Info ...@@ -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 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 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 223 Query 1 287 BEGIN
master-bin.000001 287 Table_map 1 327 table_id: # (test.t1) master-bin.000001 287 Table_map 1 330 table_id: # (test.t1)
master-bin.000001 327 Table_map 1 385 table_id: # (mysql.ndb_apply_status) master-bin.000001 330 Table_map 1 392 table_id: # (mysql.ndb_apply_status)
master-bin.000001 385 Write_rows 1 444 table_id: # master-bin.000001 392 Write_rows 1 451 table_id: #
master-bin.000001 444 Write_rows 1 491 table_id: # flags: STMT_END_F master-bin.000001 451 Write_rows 1 498 table_id: # flags: STMT_END_F
master-bin.000001 491 Query 1 556 COMMIT master-bin.000001 498 Query 1 563 COMMIT
master-bin.000001 556 Query 1 636 use `test`; TRUNCATE TABLE t1 master-bin.000001 563 Query 1 643 use `test`; TRUNCATE TABLE t1
master-bin.000001 636 Query 1 712 use `test`; DROP TABLE t1 master-bin.000001 643 Query 1 719 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 719 Query 1 836 use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB
master-bin.000001 829 Query 1 893 BEGIN master-bin.000001 836 Query 1 900 BEGIN
master-bin.000001 893 Table_map 1 933 table_id: # (test.t1) master-bin.000001 900 Table_map 1 943 table_id: # (test.t1)
master-bin.000001 933 Table_map 1 991 table_id: # (mysql.ndb_apply_status) master-bin.000001 943 Table_map 1 1005 table_id: # (mysql.ndb_apply_status)
master-bin.000001 991 Write_rows 1 1050 table_id: # master-bin.000001 1005 Write_rows 1 1064 table_id: #
master-bin.000001 1050 Write_rows 1 1097 table_id: # flags: STMT_END_F master-bin.000001 1064 Write_rows 1 1111 table_id: # flags: STMT_END_F
master-bin.000001 1097 Query 1 1162 COMMIT master-bin.000001 1111 Query 1 1176 COMMIT
master-bin.000001 1162 Query 1 1226 BEGIN master-bin.000001 1176 Query 1 1240 BEGIN
master-bin.000001 1226 Table_map 1 1266 table_id: # (test.t1) master-bin.000001 1240 Table_map 1 1283 table_id: # (test.t1)
master-bin.000001 1266 Table_map 1 1324 table_id: # (mysql.ndb_apply_status) master-bin.000001 1283 Table_map 1 1345 table_id: # (mysql.ndb_apply_status)
master-bin.000001 1324 Write_rows 1 1383 table_id: # master-bin.000001 1345 Write_rows 1 1404 table_id: #
master-bin.000001 1383 Delete_rows 1 1422 table_id: # flags: STMT_END_F master-bin.000001 1404 Delete_rows 1 1443 table_id: # flags: STMT_END_F
master-bin.000001 1422 Query 1 1487 COMMIT master-bin.000001 1443 Query 1 1508 COMMIT
master-bin.000001 1487 Query 1 1563 use `test`; DROP TABLE t1 master-bin.000001 1508 Query 1 1584 use `test`; DROP TABLE t1
...@@ -1372,6 +1372,51 @@ int Field::store(const char *to, uint length, CHARSET_INFO *cs, ...@@ -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) my_decimal *Field::val_decimal(my_decimal *decimal)
{ {
/* This never have to be called */ /* This never have to be called */
...@@ -2657,6 +2702,52 @@ uint Field_new_decimal::is_equal(Create_field *new_field) ...@@ -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 ** tiny int
****************************************************************************/ ****************************************************************************/
...@@ -6306,6 +6397,38 @@ uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length) ...@@ -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) const uchar *Field_string::unpack(uchar *to, const uchar *from)
{ {
uint length; uint length;
...@@ -6797,6 +6920,44 @@ uchar *Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, ...@@ -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() unpack field packed with Field_varstring::pack()
*/ */
...@@ -7493,6 +7654,29 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length) ...@@ -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 <not used>
@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) const uchar *Field_blob::unpack(uchar *to, const uchar *from)
{ {
memcpy(to,from,packlength); memcpy(to,from,packlength);
...@@ -8540,6 +8724,58 @@ uchar *Field_bit::pack(uchar *to, const uchar *from, uint max_length) ...@@ -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) const uchar *Field_bit::unpack(uchar *to, const uchar *from)
{ {
if (bit_len > 0) if (bit_len > 0)
......
...@@ -345,6 +345,7 @@ public: ...@@ -345,6 +345,7 @@ public:
memcpy(to,from,length); memcpy(to,from,length);
return to+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) virtual const uchar *unpack(uchar* to, const uchar *from)
{ {
uint length=pack_length(); uint length=pack_length();
...@@ -628,6 +629,7 @@ public: ...@@ -628,6 +629,7 @@ public:
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
uint32 pack_length() const { return (uint32) bin_size; } uint32 pack_length() const { return (uint32) bin_size; }
uint is_equal(Create_field *new_field); uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data);
}; };
...@@ -1164,6 +1166,7 @@ public: ...@@ -1164,6 +1166,7 @@ public:
void sort_string(uchar *buff,uint length); void sort_string(uchar *buff,uint length);
void sql_type(String &str) const; void sql_type(String &str) const;
uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); 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); const uchar *unpack(uchar* to, const uchar *from);
int pack_cmp(const uchar *a,const uchar *b,uint key_length, int pack_cmp(const uchar *a,const uchar *b,uint key_length,
my_bool insert_or_update); my_bool insert_or_update);
...@@ -1240,6 +1243,7 @@ public: ...@@ -1240,6 +1243,7 @@ public:
uchar *pack_key(uchar *to, const uchar *from, uint max_length); uchar *pack_key(uchar *to, const uchar *from, uint max_length);
uchar *pack_key_from_key_image(uchar* to, const uchar *from, uchar *pack_key_from_key_image(uchar* to, const uchar *from,
uint max_length); 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(uchar* to, const uchar *from);
const uchar *unpack_key(uchar* to, const uchar *from, uint max_length); const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
int pack_cmp(const uchar *a, const uchar *b, uint key_length, int pack_cmp(const uchar *a, const uchar *b, uint key_length,
...@@ -1295,6 +1299,9 @@ public: ...@@ -1295,6 +1299,9 @@ public:
l_char_length <= 16777215 ? 3 : 4; 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_field_types type() const { return MYSQL_TYPE_BLOB;}
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
...@@ -1316,6 +1323,17 @@ public: ...@@ -1316,6 +1323,17 @@ public:
void sort_string(uchar *buff,uint length); void sort_string(uchar *buff,uint length);
uint32 pack_length() const uint32 pack_length() const
{ return (uint32) (packlength+table->s->blob_ptr_size); } { 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; uint32 sort_length() const;
inline uint32 max_data_length() const inline uint32 max_data_length() const
{ {
...@@ -1332,6 +1350,17 @@ public: ...@@ -1332,6 +1350,17 @@ public:
store_length(ptr, packlength, number); 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) inline uint32 get_length(uint row_offset=0)
{ return get_length(ptr+row_offset); } { return get_length(ptr+row_offset); }
uint32 get_length(const uchar *ptr); uint32 get_length(const uchar *ptr);
...@@ -1379,6 +1408,7 @@ public: ...@@ -1379,6 +1408,7 @@ public:
uchar *pack_key(uchar *to, const uchar *from, uint max_length); uchar *pack_key(uchar *to, const uchar *from, uint max_length);
uchar *pack_key_from_key_image(uchar* to, const uchar *from, uchar *pack_key_from_key_image(uchar* to, const uchar *from,
uint max_length); 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(uchar *to, const uchar *from);
const uchar *unpack_key(uchar* to, const uchar *from, uint max_length); const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
int pack_cmp(const uchar *a, const uchar *b, uint key_length, int pack_cmp(const uchar *a, const uchar *b, uint key_length,
...@@ -1554,6 +1584,7 @@ public: ...@@ -1554,6 +1584,7 @@ public:
uint32 pack_length_in_rec() const { return bytes_in_rec; } uint32 pack_length_in_rec() const { return bytes_in_rec; }
void sql_type(String &str) const; void sql_type(String &str) const;
uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); 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); const uchar *unpack(uchar* to, const uchar *from);
virtual void set_default(); virtual void set_default();
......
...@@ -6028,11 +6028,8 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) ...@@ -6028,11 +6028,8 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
query_cache.invalidate_locked_for_write(rli->tables_to_lock); query_cache.invalidate_locked_for_write(rli->tables_to_lock);
#endif #endif
const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
} }
DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count == 0);
TABLE* table= const_cast<RELAY_LOG_INFO*>(rli)->m_table_map.get_table(m_table_id); TABLE* table= const_cast<RELAY_LOG_INFO*>(rli)->m_table_map.get_table(m_table_id);
if (table) if (table)
...@@ -6128,6 +6125,13 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli) ...@@ -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<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
if (error) if (error)
{ /* error has occured during the transaction */ { /* error has occured during the transaction */
rli->report(ERROR_LEVEL, thd->net.last_errno, rli->report(ERROR_LEVEL, thd->net.last_errno,
...@@ -6378,6 +6382,163 @@ void Rows_log_event::print_helper(FILE *file, ...@@ -6378,6 +6382,163 @@ void Rows_log_event::print_helper(FILE *file,
Table_map_log_event member functions and support functions 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. 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 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, ...@@ -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_dblen(m_dbnam ? tbl->s->db.length : 0),
m_tblnam(tbl->s->table_name.str), m_tblnam(tbl->s->table_name.str),
m_tbllen(tbl->s->table_name.length), m_tbllen(tbl->s->table_name.length),
m_colcnt(tbl->s->fields), m_coltype(0), m_colcnt(tbl->s->fields), m_field_metadata(0),
m_table_id(tid), m_table_id(tid), m_null_bits(0), m_flags(flags)
m_flags(flags)
{ {
DBUG_ASSERT(m_table_id != ~0UL); DBUG_ASSERT(m_table_id != ~0UL);
/* /*
...@@ -6413,6 +6573,16 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, ...@@ -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_dblen + 2; // Include length and terminating \0
m_data_size+= m_tbllen + 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_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 malloc fails, catched in is_valid() */
if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME)))) 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, ...@@ -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) for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
m_coltype[i]= m_table->field[i]->type(); 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) */ #endif /* !defined(MYSQL_CLIENT) */
...@@ -6436,8 +6628,10 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, ...@@ -6436,8 +6628,10 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
m_table(NULL), m_table(NULL),
#endif #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,...)"); DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
uint8 common_header_len= description_event->common_header_len; 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, ...@@ -6508,6 +6702,22 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1); strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1);
strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1); strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
memcpy(m_coltype, ptr_after_colcnt, m_colcnt); 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; DBUG_VOID_RETURN;
...@@ -6516,6 +6726,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, ...@@ -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() 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)); 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) ...@@ -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 inside st_relay_log_info::clear_tables_to_lock() by calling the
table_def destructor explicitly. 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; table_list->m_tabledef_valid= TRUE;
/* /*
...@@ -6718,12 +6930,22 @@ bool Table_map_log_event::write_data_body(IO_CACHE *file) ...@@ -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); uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf)); DBUG_ASSERT(static_cast<size_t>(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)) || 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, (const uchar*)m_dbnam, m_dblen+1) ||
my_b_safe_write(file, tbuf, sizeof(tbuf)) || 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, (const uchar*)m_tblnam, m_tbllen+1) ||
my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) || 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 #endif
...@@ -6946,6 +7168,7 @@ copy_extra_record_fields(TABLE *table, ...@@ -6946,6 +7168,7 @@ copy_extra_record_fields(TABLE *table,
size_t master_reclength, size_t master_reclength,
my_ptrdiff_t master_fields) my_ptrdiff_t master_fields)
{ {
DBUG_ENTER("copy_extra_record_fields(table, master_reclen, master_fields)");
DBUG_PRINT("info", ("Copying to 0x%lx " DBUG_PRINT("info", ("Copying to 0x%lx "
"from field %lu at offset %lu " "from field %lu at offset %lu "
"to field %d at offset %lu", "to field %d at offset %lu",
...@@ -6956,6 +7179,10 @@ copy_extra_record_fields(TABLE *table, ...@@ -6956,6 +7179,10 @@ copy_extra_record_fields(TABLE *table,
Copying the extra fields of the slave that does not exist on Copying the extra fields of the slave that does not exist on
master into record[0] (which are basically the default values). master into record[0] (which are basically the default values).
*/ */
if (table->s->fields < (uint) master_fields)
DBUG_RETURN(0);
DBUG_ASSERT(master_reclength <= table->s->reclength); DBUG_ASSERT(master_reclength <= table->s->reclength);
if (master_reclength < table->s->reclength) if (master_reclength < table->s->reclength)
bmove_align(table->record[0] + master_reclength, bmove_align(table->record[0] + master_reclength,
...@@ -7013,7 +7240,7 @@ copy_extra_record_fields(TABLE *table, ...@@ -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) \ #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, ...@@ -7603,12 +7830,6 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli,
uchar const **const row_end) uchar const **const row_end)
{ {
DBUG_ASSERT(row_start && 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, if (int error= unpack_row(rli, table, m_width, row_start, &m_cols, row_end,
&m_master_reclength, table->read_set, DELETE_ROWS_EVENT)) &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, ...@@ -7786,12 +8007,6 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli,
{ {
int error; int error;
DBUG_ASSERT(row_start && 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);
/* /*
We need to perform some juggling below since unpack_row() always We need to perform some juggling below since unpack_row() always
unpacks into table->record[0]. For more information, see the unpacks into table->record[0]. For more information, see the
......
...@@ -2049,6 +2049,8 @@ public: ...@@ -2049,6 +2049,8 @@ public:
virtual int get_data_size() { return m_data_size; } virtual int get_data_size() { return m_data_size; }
#ifndef MYSQL_CLIENT #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_header(IO_CACHE *file);
virtual bool write_data_body(IO_CACHE *file); virtual bool write_data_body(IO_CACHE *file);
virtual const char *get_db() { return m_dbnam; } virtual const char *get_db() { return m_dbnam; }
...@@ -2085,6 +2087,14 @@ private: ...@@ -2085,6 +2087,14 @@ private:
flag_set m_flags; flag_set m_flags;
size_t m_data_size; 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;
}; };
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "rpl_rli.h" #include "rpl_rli.h"
#include "rpl_record.h" #include "rpl_record.h"
#include "slave.h" // Need to pull in slave_print_msg #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 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, ...@@ -143,7 +145,8 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
@param rli Relay log info @param rli Relay log info
@param table Table to unpack into @param table Table to unpack into
@param colcnt Number of columns to read from record @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 cols Pointer to columns data to fill in
@param row_end Pointer to variable that will hold the value of the @param row_end Pointer to variable that will hold the value of the
one-after-end position for the row one-after-end position for the row
...@@ -191,7 +194,9 @@ unpack_row(RELAY_LOG_INFO const *rli, ...@@ -191,7 +194,9 @@ unpack_row(RELAY_LOG_INFO const *rli,
unsigned int null_mask= 1U; unsigned int null_mask= 1U;
// The "current" null bits // The "current" null bits
unsigned int null_bits= *null_ptr++; 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; Field *const f= *field_ptr;
...@@ -220,14 +225,42 @@ unpack_row(RELAY_LOG_INFO const *rli, ...@@ -220,14 +225,42 @@ unpack_row(RELAY_LOG_INFO const *rli,
f->set_notnull(); f->set_notnull();
/* /*
We only unpack the field if it was non-null 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); pack_ptr= f->unpack(f->ptr, pack_ptr);
} }
bitmap_set_bit(rw_set, f->field_index); bitmap_set_bit(rw_set, f->field_index);
null_mask <<= 1; 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;
}
} }
/* /*
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "rpl_tblmap.h" #include "rpl_tblmap.h"
#include "rpl_reporting.h" #include "rpl_reporting.h"
#include "rpl_utility.h"
struct RPL_TABLE_LIST; struct RPL_TABLE_LIST;
...@@ -301,6 +302,15 @@ typedef struct st_relay_log_info : public Slave_reporting_capability ...@@ -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 */ uint tables_to_lock_count; /* RBR: Count of tables to lock */
table_mapping m_table_map; /* RBR: Mapping table-id to table */ 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 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 the thread save 3 get_charset() per Query_log_event if the charset is not
......
...@@ -16,17 +16,45 @@ ...@@ -16,17 +16,45 @@
#include "rpl_utility.h" #include "rpl_utility.h"
#include "rpl_rli.h" #include "rpl_rli.h"
uint32 /*********************************************************************
field_length_from_packed(enum_field_types const field_type, * table_def member definitions *
uchar const *const data) *********************************************************************/
/*
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; uint32 length;
switch (field_type) { switch (type(col)) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL: 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; 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_YEAR:
case MYSQL_TYPE_TINY: case MYSQL_TYPE_TINY:
length= 1; length= 1;
...@@ -45,12 +73,6 @@ field_length_from_packed(enum_field_types const field_type, ...@@ -45,12 +73,6 @@ field_length_from_packed(enum_field_types const field_type,
length= 8; length= 8;
break; break;
#endif #endif
case MYSQL_TYPE_FLOAT:
length= sizeof(float);
break;
case MYSQL_TYPE_DOUBLE:
length= sizeof(double);
break;
case MYSQL_TYPE_NULL: case MYSQL_TYPE_NULL:
length= 0; length= 0;
break; break;
...@@ -58,8 +80,6 @@ field_length_from_packed(enum_field_types const field_type, ...@@ -58,8 +80,6 @@ field_length_from_packed(enum_field_types const field_type,
length= 3; length= 3;
break; break;
case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATE:
length= 4;
break;
case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIME:
length= 3; length= 3;
break; break;
...@@ -69,41 +89,33 @@ field_length_from_packed(enum_field_types const field_type, ...@@ -69,41 +89,33 @@ field_length_from_packed(enum_field_types const field_type,
case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_DATETIME:
length= 8; length= 8;
break; break;
break;
case MYSQL_TYPE_BIT: case MYSQL_TYPE_BIT:
length= ~(uint32) 0; {
break; uint from_len= (m_field_metadata[col] >> 8U) & 0x00ff;
default: uint from_bit_len= m_field_metadata[col] & 0x00ff;
/* This case should never be chosen */ length= from_len + ((from_bit_len > 0) ? 1 : 0);
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; break;
}
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR: 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; break;
case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_GEOMETRY:
length= ~(uint32) 0; // NYI {
Field_blob fb(m_field_metadata[col]);
length= fb.get_packed_size(master_data);
break; break;
} }
default:
length= -1;
}
return length; return length;
} }
/*********************************************************************
* table_def member definitions *
*********************************************************************/
/* /*
Is the definition compatible with a table? Is the definition compatible with a table?
...@@ -121,23 +133,6 @@ table_def::compatible_with(RELAY_LOG_INFO const *rli_arg, TABLE *table) ...@@ -121,23 +133,6 @@ table_def::compatible_with(RELAY_LOG_INFO const *rli_arg, TABLE *table)
TABLE_SHARE const *const tsh= table->s; 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) for (uint col= 0 ; col < cols_to_check ; ++col)
{ {
if (table->field[col]->type() != type(col)) if (table->field[col]->type() != type(col))
......
...@@ -25,8 +25,6 @@ ...@@ -25,8 +25,6 @@
struct st_relay_log_info; struct st_relay_log_info;
typedef st_relay_log_info 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. A table definition from the master.
...@@ -57,19 +55,96 @@ public: ...@@ -57,19 +55,96 @@ public:
@param types Array of types @param types Array of types
@param size Number of elements in array '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) table_def(field_type *types, ulong size, uchar *field_metadata,
: m_size(size), m_type(new unsigned char [size]) 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) if (m_type)
memcpy(m_type, types, size); memcpy(m_type, types, size);
else else
m_size= 0; 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() { ~table_def() {
if (m_type) my_free(m_memory, MYF(0));
delete [] m_type;
#ifndef DBUG_OFF #ifndef DBUG_OFF
m_type= 0; m_type= 0;
m_size= 0; m_size= 0;
...@@ -99,6 +174,48 @@ public: ...@@ -99,6 +174,48 @@ public:
return m_type[index]; 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. Decide if the table definition is compatible with a table.
...@@ -121,6 +238,9 @@ public: ...@@ -121,6 +238,9 @@ public:
private: private:
ulong m_size; // Number of elements in the types array ulong m_size; // Number of elements in the types array
field_type *m_type; // Array of type descriptors field_type *m_type; // Array of type descriptors
short int *m_field_metadata;
uchar *m_null_bits;
uchar *m_memory;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment