Bug#19995 (Extreneous table maps generated for statements that do not generate rows):
Switched to writing out table maps for tables that are locked when the first row in a statement is seen. mysql-test/include/master-slave.inc: Moved code to reset master and slave into separate file. mysql-test/r/binlog_row_blackhole.result: Result change mysql-test/r/binlog_row_mix_innodb_myisam.result: Result change mysql-test/r/ndb_binlog_ignore_db.result: Result change mysql-test/r/rpl_ndb_charset.result: Result change mysql-test/r/rpl_row_basic_11bugs.result: Result change mysql-test/r/rpl_row_charset.result: Result change mysql-test/r/rpl_row_create_table.result: Result change mysql-test/t/rpl_row_basic_11bugs.test: Added test to check that no events are generated when no rows are changed. mysql-test/t/rpl_row_create_table.test: Master log position changed sql/handler.cc: Adding function write_locked_table_maps() that will write table maps for all tables locked for write. Using "table->in_use" instead of "current_thd" since tables are now locked when the function is called. Removing old code to write table map. sql/log_event.cc: Added assertion sql/sql_class.cc: Removing code to write "dummy termination event". sql/sql_class.h: Adding getter for binlog_table_maps. sql/sql_insert.cc: Setting thd->lock before calling write_record for the execution of CREATE-SELECT and INSERT-SELECT since they keep multiple locks in the air at the same time. mysql-test/include/master-slave-reset.inc: New BitKeeper file ``mysql-test/include/master-slave-reset.inc''
This commit is contained in:
parent
39b6d186e8
commit
e9b5cafa8b
22
mysql-test/include/master-slave-reset.inc
Normal file
22
mysql-test/include/master-slave-reset.inc
Normal file
@ -0,0 +1,22 @@
|
||||
connection slave;
|
||||
#we expect STOP SLAVE to produce a warning as the slave is stopped
|
||||
#(the server was started with skip-slave-start)
|
||||
--disable_warnings
|
||||
stop slave;
|
||||
--wait_for_slave_to_stop
|
||||
--enable_warnings
|
||||
connection master;
|
||||
--disable_warnings
|
||||
--disable_query_log
|
||||
use test;
|
||||
--enable_query_log
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
--enable_warnings
|
||||
reset master;
|
||||
connection slave;
|
||||
reset slave;
|
||||
# Clean up old test tables
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
--enable_warnings
|
||||
start slave;
|
@ -2,28 +2,8 @@ connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
|
||||
connect (master1,127.0.0.1,root,,test,$MASTER_MYPORT,);
|
||||
connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
|
||||
connect (slave1,127.0.0.1,root,,test,$SLAVE_MYPORT,);
|
||||
connection slave;
|
||||
#we expect STOP SLAVE to produce a warning as the slave is stopped
|
||||
#(the server was started with skip-slave-start)
|
||||
--disable_warnings
|
||||
stop slave;
|
||||
--enable_warnings
|
||||
--require r/slave-stopped.result
|
||||
show status like 'Slave_running';
|
||||
connection master;
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
--enable_warnings
|
||||
reset master;
|
||||
connection slave;
|
||||
reset slave;
|
||||
# Clean up old test tables
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
--enable_warnings
|
||||
start slave;
|
||||
--require r/slave-running.result
|
||||
show status like 'Slave_running';
|
||||
|
||||
-- source include/master-slave-reset.inc
|
||||
|
||||
# Set the default connection to 'master'
|
||||
connection master;
|
||||
|
@ -118,12 +118,6 @@ master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 (a varchar(200)) engine=blackhole
|
||||
master-bin.000001 # Table_map 1 # table_id: # (test.t2)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
@ -131,12 +125,6 @@ master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t1 add b int
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t1 drop b
|
||||
master-bin.000001 # Query 1 # use `test`; create table t3 like t1
|
||||
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # use `test`; COMMIT
|
||||
drop table t1,t2,t3;
|
||||
reset master;
|
||||
create table t1 (a int) engine=blackhole;
|
||||
|
@ -262,27 +262,23 @@ master-bin.000001 209 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 243 Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 282 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 316 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 343 Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 382 Query 1 # use `test`; delete from t1
|
||||
master-bin.000001 459 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 486 Table_map 1 # table_id: # (test.t2)
|
||||
master-bin.000001 525 Query 1 # use `test`; delete from t2
|
||||
master-bin.000001 602 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 629 Query 1 # use `test`; alter table t2 engine=MyISAM
|
||||
master-bin.000001 720 Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 759 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 793 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 820 Query 1 # use `test`; BEGIN
|
||||
master-bin.000001 888 Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 927 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 956 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 983 Query 1 # use `test`; drop table t1,t2
|
||||
master-bin.000001 1062 Query 1 # use `test`; create table t0 (n int)
|
||||
master-bin.000001 1148 Table_map 1 # table_id: # (test.t0)
|
||||
master-bin.000001 1187 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 1221 Table_map 1 # table_id: # (test.t0)
|
||||
master-bin.000001 1260 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 1294 Query 1 # use `test`; create table t2 (n int) engine=innodb
|
||||
master-bin.000001 343 Query 1 # use `test`; delete from t1
|
||||
master-bin.000001 420 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 447 Query 1 # use `test`; delete from t2
|
||||
master-bin.000001 524 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 551 Query 1 # use `test`; alter table t2 engine=MyISAM
|
||||
master-bin.000001 642 Table_map 1 # table_id: # (test.t1)
|
||||
master-bin.000001 681 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 715 Xid 1 # COMMIT /* xid= */
|
||||
master-bin.000001 742 Table_map 1 # table_id: # (test.t2)
|
||||
master-bin.000001 781 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 815 Query 1 # use `test`; drop table t1,t2
|
||||
master-bin.000001 894 Query 1 # use `test`; create table t0 (n int)
|
||||
master-bin.000001 980 Table_map 1 # table_id: # (test.t0)
|
||||
master-bin.000001 1019 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 1053 Table_map 1 # table_id: # (test.t0)
|
||||
master-bin.000001 1092 Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 1126 Query 1 # use `test`; create table t2 (n int) engine=innodb
|
||||
do release_lock("lock1");
|
||||
drop table t0,t2;
|
||||
reset master;
|
||||
|
@ -7,6 +7,4 @@ insert into t1 values (1, 1);
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query # # use `test`; drop table if exists t1
|
||||
master-bin.000001 # Table_map # # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
drop database mysqltest;
|
||||
|
@ -112,16 +112,10 @@ drop database mysqltest3;
|
||||
show binlog events from 102;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # drop database if exists mysqltest2
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # drop database if exists mysqltest3
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # create database mysqltest2 character set latin2
|
||||
master-bin.000001 # Query 1 # create database mysqltest3
|
||||
master-bin.000001 # Query 1 # drop database mysqltest3
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # create database mysqltest3
|
||||
master-bin.000001 # Query 1 # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100))
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysqltest2.t1)
|
||||
@ -147,11 +141,7 @@ master-bin.000001 # Query 1 # use `mysqltest2`; truncate table t1
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysqltest2.t1)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # drop database mysqltest2
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # drop database mysqltest3
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
select "--- --global--" as "";
|
||||
|
||||
--- --global--
|
||||
|
@ -44,3 +44,20 @@ t1
|
||||
USE test_ignore;
|
||||
ERROR 42000: Unknown database 'test_ignore'
|
||||
DROP DATABASE test_ignore;
|
||||
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;
|
||||
CREATE TABLE t1 (a INT);
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
DELETE FROM t1 WHERE a = 0;
|
||||
UPDATE t1 SET a=99 WHERE a = 0;
|
||||
SHOW BINLOG EVENTS;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 4 Format_desc 1 102 Server ver: 5.1.11-beta-debug-log, Binlog ver: 4
|
||||
master-bin.000001 102 Query 1 188 use `test`; CREATE TABLE t1 (a INT)
|
||||
master-bin.000001 188 Query 1 265 use `test`; DELETE FROM t1
|
||||
master-bin.000001 265 Table_map 1 304 table_id: # (test.t1)
|
||||
master-bin.000001 304 Write_rows 1 343 table_id: # flags: STMT_END_F
|
||||
|
@ -112,16 +112,10 @@ drop database mysqltest3;
|
||||
show binlog events from 102;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # drop database if exists mysqltest2
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # drop database if exists mysqltest3
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # create database mysqltest2 character set latin2
|
||||
master-bin.000001 # Query 1 # create database mysqltest3
|
||||
master-bin.000001 # Query 1 # drop database mysqltest3
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # create database mysqltest3
|
||||
master-bin.000001 # Query 1 # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100))
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysqltest2.t1)
|
||||
@ -147,11 +141,7 @@ master-bin.000001 # Query 1 # use `mysqltest2`; truncate table t1
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysqltest2.t1)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # drop database mysqltest2
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query 1 # drop database mysqltest3
|
||||
master-bin.000001 # Table_map 1 # table_id: # (mysql.proc)
|
||||
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
|
||||
select "--- --global--" as "";
|
||||
|
||||
--- --global--
|
||||
|
@ -127,7 +127,7 @@ NULL 5 10
|
||||
NULL 6 12
|
||||
CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
|
||||
ERROR 23000: Duplicate entry '2' for key 'b'
|
||||
SHOW BINLOG EVENTS FROM 1326;
|
||||
SHOW BINLOG EVENTS FROM 1256;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
CREATE TABLE t7 (a INT, b INT UNIQUE);
|
||||
INSERT INTO t7 SELECT a,b FROM tt3;
|
||||
@ -137,11 +137,11 @@ a b
|
||||
1 2
|
||||
2 4
|
||||
3 6
|
||||
SHOW BINLOG EVENTS FROM 1326;
|
||||
SHOW BINLOG EVENTS FROM 1256;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 1326 Query 1 1426 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
|
||||
master-bin.000001 1426 Table_map 1 1466 table_id: # (test.t7)
|
||||
master-bin.000001 1466 Write_rows 1 1522 table_id: # flags: STMT_END_F
|
||||
master-bin.000001 1256 Query 1 1356 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
|
||||
master-bin.000001 1356 Table_map 1 1396 table_id: # (test.t7)
|
||||
master-bin.000001 1396 Write_rows 1 1452 table_id: # flags: STMT_END_F
|
||||
SELECT * FROM t7 ORDER BY a,b;
|
||||
a b
|
||||
1 2
|
||||
@ -154,10 +154,10 @@ INSERT INTO t7 SELECT a,b FROM tt4;
|
||||
ROLLBACK;
|
||||
Warnings:
|
||||
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||
SHOW BINLOG EVENTS FROM 1522;
|
||||
SHOW BINLOG EVENTS FROM 1452;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 1522 Table_map 1 1562 table_id: # (test.t7)
|
||||
master-bin.000001 1562 Write_rows 1 1618 table_id: # flags: STMT_END_F
|
||||
master-bin.000001 1452 Table_map 1 1492 table_id: # (test.t7)
|
||||
master-bin.000001 1492 Write_rows 1 1548 table_id: # flags: STMT_END_F
|
||||
SELECT * FROM t7 ORDER BY a,b;
|
||||
a b
|
||||
1 2
|
||||
@ -191,10 +191,10 @@ Create Table CREATE TABLE `t9` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW BINLOG EVENTS FROM 1618;
|
||||
SHOW BINLOG EVENTS FROM 1548;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 1618 Query 1 1704 use `test`; CREATE TABLE t8 LIKE t4
|
||||
master-bin.000001 1704 Query 1 1843 use `test`; CREATE TABLE `t9` (
|
||||
master-bin.000001 1548 Query 1 1634 use `test`; CREATE TABLE t8 LIKE t4
|
||||
master-bin.000001 1634 Query 1 1773 use `test`; CREATE TABLE `t9` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL
|
||||
)
|
||||
|
@ -36,3 +36,18 @@ USE test_ignore;
|
||||
connection master;
|
||||
DROP DATABASE test_ignore;
|
||||
sync_slave_with_master;
|
||||
|
||||
# Bug#19995: Extreneous table maps generated for statements that does
|
||||
# not generate rows
|
||||
--disable_query_log
|
||||
--source include/master-slave-reset.inc
|
||||
--enable_query_log
|
||||
|
||||
connection master;
|
||||
CREATE TABLE t1 (a INT);
|
||||
DELETE FROM t1;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
DELETE FROM t1 WHERE a = 0;
|
||||
UPDATE t1 SET a=99 WHERE a = 0;
|
||||
--replace_regex /table_id: [0-9]+/table_id: #/
|
||||
SHOW BINLOG EVENTS;
|
||||
|
@ -67,7 +67,7 @@ connection master;
|
||||
CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
|
||||
# Shouldn't be written to the binary log
|
||||
--replace_regex /table_id: [0-9]+/table_id: #/
|
||||
SHOW BINLOG EVENTS FROM 1326;
|
||||
SHOW BINLOG EVENTS FROM 1256;
|
||||
|
||||
# Test that INSERT-SELECT works the same way as for SBR.
|
||||
CREATE TABLE t7 (a INT, b INT UNIQUE);
|
||||
@ -76,7 +76,7 @@ INSERT INTO t7 SELECT a,b FROM tt3;
|
||||
SELECT * FROM t7 ORDER BY a,b;
|
||||
# Should be written to the binary log
|
||||
--replace_regex /table_id: [0-9]+/table_id: #/
|
||||
SHOW BINLOG EVENTS FROM 1326;
|
||||
SHOW BINLOG EVENTS FROM 1256;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t7 ORDER BY a,b;
|
||||
|
||||
@ -87,7 +87,7 @@ BEGIN;
|
||||
INSERT INTO t7 SELECT a,b FROM tt4;
|
||||
ROLLBACK;
|
||||
--replace_regex /table_id: [0-9]+/table_id: #/
|
||||
SHOW BINLOG EVENTS FROM 1522;
|
||||
SHOW BINLOG EVENTS FROM 1452;
|
||||
SELECT * FROM t7 ORDER BY a,b;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t7 ORDER BY a,b;
|
||||
@ -101,7 +101,7 @@ CREATE TEMPORARY TABLE tt6 LIKE tt4;
|
||||
--query_vertical SHOW CREATE TABLE t8
|
||||
--query_vertical SHOW CREATE TABLE t9
|
||||
--replace_regex /table_id: [0-9]+/table_id: #/
|
||||
SHOW BINLOG EVENTS FROM 1618;
|
||||
SHOW BINLOG EVENTS FROM 1548;
|
||||
sync_slave_with_master;
|
||||
--echo **** On Slave ****
|
||||
--query_vertical SHOW CREATE TABLE t8
|
||||
|
@ -3199,6 +3199,58 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Write table maps for all (manually or automatically) locked tables
|
||||
to the binary log.
|
||||
|
||||
This function will generate and write table maps for all tables
|
||||
that are locked by the thread 'thd'. Either manually locked
|
||||
(stored in THD::locked_tables) and automatically locked (stored in
|
||||
THD::lock) are considered.
|
||||
|
||||
See THD::lock and THD::locked_tables for more information.
|
||||
*/
|
||||
static int
|
||||
write_locked_table_maps(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("write_locked_table_maps");
|
||||
DBUG_PRINT("enter", ("thd=%p, thd->lock=%p, thd->locked_tables=%p",
|
||||
thd, thd->lock, thd->locked_tables));
|
||||
|
||||
if (thd->get_binlog_table_maps() == 0)
|
||||
{
|
||||
/*
|
||||
Exactly one table has to be locked, otherwise this code is not
|
||||
guaranteed to work.
|
||||
*/
|
||||
DBUG_ASSERT((thd->lock != NULL) + (thd->locked_tables != NULL) == 1);
|
||||
|
||||
MYSQL_LOCK *lock= thd->lock ? thd->lock : thd->locked_tables;
|
||||
DBUG_ASSERT(lock->table_count > 0);
|
||||
TABLE **const end_ptr= lock->table + lock->table_count;
|
||||
for (TABLE **table_ptr= lock->table ;
|
||||
table_ptr != end_ptr ;
|
||||
++table_ptr)
|
||||
{
|
||||
TABLE *const table= *table_ptr;
|
||||
DBUG_PRINT("info", ("Checking table %s", table->s->table_name));
|
||||
if (table->current_lock == F_WRLCK &&
|
||||
check_table_binlog_row_based(thd, table))
|
||||
{
|
||||
int const has_trans= table->file->has_transactions();
|
||||
int const error= thd->binlog_write_table_map(table, has_trans);
|
||||
/*
|
||||
If an error occurs, it is the responsibility of the caller to
|
||||
roll back the transaction.
|
||||
*/
|
||||
if (unlikely(error))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
template<class RowsEventT> int binlog_log_row(TABLE* table,
|
||||
const byte *before_record,
|
||||
const byte *after_record)
|
||||
@ -3206,7 +3258,7 @@ template<class RowsEventT> int binlog_log_row(TABLE* table,
|
||||
if (table->file->is_injective())
|
||||
return 0;
|
||||
bool error= 0;
|
||||
THD *const thd= current_thd;
|
||||
THD *const thd= table->in_use;
|
||||
|
||||
if (check_table_binlog_row_based(thd, table))
|
||||
{
|
||||
@ -3215,17 +3267,26 @@ template<class RowsEventT> int binlog_log_row(TABLE* table,
|
||||
uint32 bitbuf[BITMAP_STACKBUF_SIZE/sizeof(uint32)];
|
||||
uint n_fields= table->s->fields;
|
||||
my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
|
||||
|
||||
/*
|
||||
If there are no table maps written to the binary log, this is
|
||||
the first row handled in this statement. In that case, we need
|
||||
to write table maps for all locked tables to the binary log.
|
||||
*/
|
||||
if (likely(!(error= bitmap_init(&cols,
|
||||
use_bitbuf ? bitbuf : NULL,
|
||||
(n_fields + 7) & ~7UL,
|
||||
false))))
|
||||
{
|
||||
bitmap_set_all(&cols);
|
||||
if (likely(!(error= write_locked_table_maps(thd))))
|
||||
{
|
||||
error=
|
||||
RowsEventT::binlog_row_logging_function(thd, table,
|
||||
table->file->has_transactions(),
|
||||
&cols, table->s->fields,
|
||||
before_record, after_record);
|
||||
}
|
||||
if (!use_bitbuf)
|
||||
bitmap_free(&cols);
|
||||
}
|
||||
@ -3251,41 +3312,6 @@ int handler::ha_external_lock(THD *thd, int lock_type)
|
||||
int error;
|
||||
if (unlikely(error= external_lock(thd, lock_type)))
|
||||
DBUG_RETURN(error);
|
||||
#ifdef HAVE_ROW_BASED_REPLICATION
|
||||
if (table->file->is_injective())
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/*
|
||||
There is a number of statements that are logged statement-based
|
||||
but call external lock. For these, we do not need to generate a
|
||||
table map.
|
||||
|
||||
TODO: The need for this switch is an indication that the model for
|
||||
locking combined with row-based replication needs to be looked
|
||||
over. Ideally, no such special handling should be needed.
|
||||
*/
|
||||
switch (thd->lex->sql_command) {
|
||||
case SQLCOM_TRUNCATE:
|
||||
case SQLCOM_ALTER_TABLE:
|
||||
case SQLCOM_OPTIMIZE:
|
||||
case SQLCOM_REPAIR:
|
||||
DBUG_RETURN(0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
If we are locking a table for writing, we generate a table map.
|
||||
For all other kinds of locks, we don't do anything.
|
||||
*/
|
||||
if (lock_type == F_WRLCK && check_table_binlog_row_based(thd, table))
|
||||
{
|
||||
int const has_trans= table->file->has_transactions();
|
||||
error= thd->binlog_write_table_map(table, has_trans);
|
||||
if (unlikely(error))
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
#endif
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -5602,6 +5602,7 @@ int Rows_log_event::exec_event(st_relay_log_info *rli)
|
||||
bool Rows_log_event::write_data_header(IO_CACHE *file)
|
||||
{
|
||||
byte buf[ROWS_HEADER_LEN]; // No need to init the buffer
|
||||
DBUG_ASSERT(m_table_id != ~0UL);
|
||||
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
|
||||
{
|
||||
int4store(buf + 0, m_table_id);
|
||||
|
@ -2624,31 +2624,6 @@ int THD::binlog_flush_pending_rows_event(bool stmt_end)
|
||||
|
||||
error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0);
|
||||
}
|
||||
else if (stmt_end && binlog_table_maps > 0)
|
||||
{ /* there is no pending event at this point */
|
||||
/*
|
||||
If pending is null and we are going to end the statement, we
|
||||
have to write an extra, empty, binrow event so that the slave
|
||||
knows to discard the tables it has received. Otherwise, the
|
||||
table maps written this far will be included in the table maps
|
||||
for the following statement.
|
||||
|
||||
TODO: Remove the need for a dummy event altogether. It can be
|
||||
fixed if we can write table maps to a memory buffer before
|
||||
writing the first binrow event. We can then flush and clear the
|
||||
memory buffer with table map events before writing the first
|
||||
binrow event. In the event of a crash, nothing is lost since
|
||||
the table maps are only needed if there are binrow events.
|
||||
*/
|
||||
|
||||
Rows_log_event *ev=
|
||||
new Write_rows_log_event(this, 0, ~0UL, 0, FALSE);
|
||||
ev->set_flags(Rows_log_event::STMT_END_F);
|
||||
binlog_set_pending_rows_event(ev);
|
||||
|
||||
error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0);
|
||||
binlog_table_maps= 0;
|
||||
}
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
@ -941,16 +941,18 @@ public:
|
||||
int binlog_flush_pending_rows_event(bool stmt_end);
|
||||
void binlog_delete_pending_rows_event();
|
||||
|
||||
private:
|
||||
#ifdef HAVE_ROW_BASED_REPLICATION
|
||||
private:
|
||||
uint binlog_table_maps; // Number of table maps currently in the binlog
|
||||
#endif /* HAVE_ROW_BASED_REPLICATION */
|
||||
|
||||
public:
|
||||
|
||||
uint get_binlog_table_maps() const {
|
||||
return binlog_table_maps;
|
||||
}
|
||||
#endif /* HAVE_ROW_BASED_REPLICATION */
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
public:
|
||||
enum enum_binlog_query_type {
|
||||
/*
|
||||
The query can be logged row-based or statement-based
|
||||
@ -1572,6 +1574,9 @@ class select_insert :public select_result_interceptor {
|
||||
bool send_eof();
|
||||
/* not implemented: select_insert is never re-used in prepared statements */
|
||||
void cleanup();
|
||||
|
||||
protected:
|
||||
MYSQL_LOCK *lock;
|
||||
};
|
||||
|
||||
|
||||
@ -1581,7 +1586,6 @@ class select_create: public select_insert {
|
||||
List<create_field> *extra_fields;
|
||||
List<Key> *keys;
|
||||
HA_CREATE_INFO *create_info;
|
||||
MYSQL_LOCK *lock;
|
||||
Field **field;
|
||||
public:
|
||||
select_create (TABLE_LIST *table,
|
||||
@ -1590,8 +1594,7 @@ public:
|
||||
List<Key> &keys_par,
|
||||
List<Item> &select_fields,enum_duplicates duplic, bool ignore)
|
||||
:select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), create_table(table),
|
||||
extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par),
|
||||
lock(0)
|
||||
extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par)
|
||||
{}
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
|
||||
|
@ -2152,6 +2152,7 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par,
|
||||
bool ignore_check_option_errors)
|
||||
:table_list(table_list_par), table(table_par), fields(fields_par),
|
||||
last_insert_id(0),
|
||||
lock(0),
|
||||
insert_into_view(table_list_par && table_list_par->view != 0)
|
||||
{
|
||||
bzero((char*) &info,sizeof(info));
|
||||
@ -2348,7 +2349,36 @@ bool select_insert::send_data(List<Item> &values)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
if (!(error= write_record(thd, table, &info)))
|
||||
|
||||
/*
|
||||
The thd->lock lock contain the locks for the select part of the
|
||||
statement and the 'lock' variable contain the write lock for the
|
||||
currently locked table that is being created or inserted
|
||||
into. However, the row-based replication will investigate the
|
||||
thd->lock to decide what table maps are to be written, so this one
|
||||
has to contain the tables locked for writing. To be able to write
|
||||
table map for the table being created, we temporarily set
|
||||
THD::lock to select_insert::lock while writing the record to the
|
||||
storage engine. We cannot set this elsewhere, since the execution
|
||||
of a stored function inside the select expression might cause the
|
||||
lock structures to be NULL.
|
||||
*/
|
||||
|
||||
{
|
||||
MYSQL_LOCK *saved_lock= NULL;
|
||||
if (lock)
|
||||
{
|
||||
saved_lock= thd->lock;
|
||||
thd->lock= lock;
|
||||
}
|
||||
|
||||
error= write_record(thd, table, &info);
|
||||
|
||||
if (lock)
|
||||
thd->lock= saved_lock;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
{
|
||||
if (table->triggers || info.handle_duplicates == DUP_UPDATE)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user