mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.1-new-rpl
into janus.mylan:/usr/home/serg/Abk/mysql-maria mysql-test/mysql-test-run.pl: Auto merged sql/log_event.cc: Auto merged sql/slave.cc: Auto merged sql/slave.h: Auto merged sql/share/errmsg.txt: Auto merged include/my_base.h: merged
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -434,13 +434,15 @@ enum ha_base_keytype {
|
||||
#define HA_ERR_RECORD_IS_THE_SAME 169
|
||||
/* It is not possible to log this statement */
|
||||
#define HA_ERR_LOGGING_IMPOSSIBLE 170
|
||||
#define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to
|
||||
illegal data being read */
|
||||
#define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to */
|
||||
/* illegal data being read */
|
||||
#define HA_ERR_NEW_FILE 172 /* New file format */
|
||||
#define HA_ERR_INITIALIZATION 173 /* Error during initialization */
|
||||
#define HA_ERR_FILE_TOO_SHORT 174 /* File too short */
|
||||
#define HA_ERR_WRONG_CRC 175 /* Wrong CRC on page */
|
||||
#define HA_ERR_LAST 175 /* Copy of last error nr */
|
||||
#define HA_ERR_ROWS_EVENT_APPLY 176 /* The event could not be processed */
|
||||
/* no other hanlder error happened */
|
||||
#define HA_ERR_LAST 176 /* Copy of last error nr */
|
||||
|
||||
/* Number of different errors */
|
||||
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
||||
|
@ -342,5 +342,6 @@ SHOW CREATE TABLE t1;
|
||||
--echo --- Do Cleanup ---
|
||||
|
||||
DROP TABLE IF EXISTS t1;
|
||||
sync_slave_with_master;
|
||||
|
||||
# End of 5.1 test case
|
||||
|
@ -46,7 +46,7 @@ ALTER TABLE t1_bit
|
||||
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
|
||||
# ... and add one non-nullable INT column last in table 't1_text'
|
||||
# with no default,
|
||||
ALTER TABLE t1_nodef ADD x INT NOT NULL;
|
||||
ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL;
|
||||
# ... and remove the last column in t2
|
||||
ALTER TABLE t2 DROP b;
|
||||
# ... change the type of the single column in table 't4'
|
||||
@ -222,8 +222,8 @@ sync_slave_with_master;
|
||||
|
||||
--echo **** On Slave ****
|
||||
connection slave;
|
||||
INSERT INTO t1_nodef VALUES (1,2,3);
|
||||
INSERT INTO t1_nodef VALUES (2,4,6);
|
||||
INSERT INTO t1_nodef VALUES (1,2,3,4,5);
|
||||
INSERT INTO t1_nodef VALUES (2,4,6,8,10);
|
||||
|
||||
--echo **** On Master ****
|
||||
connection master;
|
||||
|
@ -3898,14 +3898,6 @@ sub mysqld_arguments ($$$$) {
|
||||
mtr_add_arg($args, "%s--user=root");
|
||||
}
|
||||
|
||||
# When mysqld is run by a root user(euid is 0), it will fail
|
||||
# to start unless we specify what user to run as, see BUG#30630
|
||||
my $euid= $>;
|
||||
if (!$glob_win32 and $euid == 0 and
|
||||
(grep(/^--user/, @$extra_opt, @opt_extra_mysqld_opt)) == 0) {
|
||||
mtr_add_arg($args, "%s--user=root", $prefix);
|
||||
}
|
||||
|
||||
if ( $opt_valgrind_mysqld )
|
||||
{
|
||||
mtr_add_arg($args, "%s--skip-safemalloc", $prefix);
|
||||
|
@ -40,8 +40,13 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq
|
||||
SET @@session.sql_mode=0/*!*/;
|
||||
/*!\C latin1 *//*!*/;
|
||||
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
|
||||
create table t1 (a int) engine= myisam/*!*/;
|
||||
create table t1 (a int) engine= myisam
|
||||
/*!*/;
|
||||
# at 203
|
||||
DELIMITER ;
|
||||
# End of log file
|
||||
ROLLBACK /* added by mysqlbinlog */;
|
||||
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
|
||||
==== Test non-matching FD event and Row event ====
|
||||
BINLOG '
|
||||
4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA
|
||||
|
@ -29,6 +29,16 @@ SELECT COUNT(*) FROM t3;
|
||||
COUNT(*)
|
||||
17920
|
||||
DROP TABLE t1, t2, t3;
|
||||
==== Read binlog from version 4.1 ====
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
0 last_insert_id
|
||||
4 four
|
||||
190243 random
|
||||
SELECT COUNT(*) FROM t3;
|
||||
COUNT(*)
|
||||
17920
|
||||
DROP TABLE t1, t3;
|
||||
==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ====
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b
|
||||
|
BIN
mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001
Normal file
BIN
mysql-test/suite/binlog/std_data/binlog_old_version_4_1.000001
Normal file
Binary file not shown.
@ -6,6 +6,10 @@
|
||||
# See also BUG#32407.
|
||||
|
||||
|
||||
# BINLOG statement does not work in embedded mode.
|
||||
source include/not_embedded.inc;
|
||||
|
||||
|
||||
# Test to show BUG#32407. This reads a binlog created with the
|
||||
# mysql-5.1-telco-6.1 tree, specifically at the tag
|
||||
# mysql-5.1.15-ndb-6.1.23, and applies it to the database. The test
|
||||
@ -15,7 +19,7 @@
|
||||
# The binlog contains row events equivalent to:
|
||||
# CREATE TABLE t1 (a int) engine = myisam
|
||||
# INSERT INTO t1 VALUES (1), (1)
|
||||
exec $MYSQL_BINLOG suite/binlog/std_data/binlog-bug32407.000001 | $MYSQL;
|
||||
exec $MYSQL_BINLOG suite/binlog/std_data/bug32407.001 | $MYSQL;
|
||||
# The above line should succeed and t1 should contain two ones
|
||||
select * from t1;
|
||||
|
||||
@ -68,7 +72,7 @@ select * from t1;
|
||||
# mysqlbinlog should fail
|
||||
--replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] .*/#/
|
||||
error 1;
|
||||
exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/binlog-bug32407.000001;
|
||||
exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/bug32407.001;
|
||||
# the above line should output the query log event and then stop
|
||||
|
||||
|
||||
@ -78,7 +82,7 @@ exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/binlog-bug32407.0
|
||||
--echo ==== Test non-matching FD event and Row event ====
|
||||
|
||||
# This is the Format_description_log_event from
|
||||
# binlog-bug32407.000001, encoded in base64. It contains only the old
|
||||
# bug32407.001, encoded in base64. It contains only the old
|
||||
# row events (number of event types is 22)
|
||||
BINLOG '
|
||||
4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA
|
||||
|
@ -39,7 +39,7 @@ connection con2;
|
||||
reap;
|
||||
let $rows= `select count(*) from t2 /* must be 2 or 0 */`;
|
||||
|
||||
--exec $MYSQL_BINLOG --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog
|
||||
--exec $MYSQL_BINLOG --force-if-open --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
eval select
|
||||
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog"))
|
||||
@ -250,7 +250,7 @@ source include/show_binlog_events.inc;
|
||||
|
||||
# a proof the query is binlogged with an error
|
||||
|
||||
--exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
eval select
|
||||
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
|
||||
@ -296,7 +296,7 @@ source include/show_binlog_events.inc;
|
||||
|
||||
# a proof the query is binlogged with an error
|
||||
|
||||
--exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
eval select
|
||||
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
|
||||
|
@ -23,7 +23,7 @@ update t1 set a=2 /* will be "killed" after work has been done */;
|
||||
#todo: introduce a suite private macro that provides numeric values
|
||||
# for some constants like the offset of the first real event
|
||||
# that is different between severs versions.
|
||||
--exec $MYSQL_BINLOG --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--exec $MYSQL_BINLOG --force-if-open --start-position=106 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
eval select
|
||||
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
|
||||
@ -51,7 +51,7 @@ load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "kil
|
||||
|
||||
source include/show_binlog_events.inc;
|
||||
|
||||
--exec $MYSQL_BINLOG --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--exec $MYSQL_BINLOG --force-if-open --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
eval select
|
||||
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
|
||||
|
@ -31,7 +31,7 @@ DROP TABLE IF EXISTS t1, t2, t3;
|
||||
--echo ==== Read modern binlog (version 5.1.23) ====
|
||||
|
||||
# Read binlog.
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_23.000001 | $MYSQL --local-infile=1
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1_23.001 | $MYSQL --local-infile=1
|
||||
# Show result.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
@ -43,7 +43,7 @@ DROP TABLE t1, t2, t3;
|
||||
--echo ==== Read binlog from version 5.1.17 ====
|
||||
|
||||
# Read binlog.
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1_17.000001 | $MYSQL --local-infile=1
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1_17.001 | $MYSQL --local-infile=1
|
||||
# Show result.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
@ -52,6 +52,21 @@ SELECT COUNT(*) FROM t3;
|
||||
DROP TABLE t1, t2, t3;
|
||||
|
||||
|
||||
--echo ==== Read binlog from version 4.1 ====
|
||||
|
||||
# In this version, neither row-based binlogging nor Xid events
|
||||
# existed, so the binlog was generated without the "row-based tests"
|
||||
# part and the "get xid event" part, and it does not create table t2.
|
||||
|
||||
# Read binlog.
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_4_1.000001 | $MYSQL --local-infile=1
|
||||
# Show result.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT COUNT(*) FROM t3;
|
||||
# Reset.
|
||||
DROP TABLE t1, t3;
|
||||
|
||||
|
||||
--echo ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ====
|
||||
|
||||
# In this version, it was not possible to switch between row-based and
|
||||
@ -60,9 +75,9 @@ DROP TABLE t1, t2, t3;
|
||||
# replication.
|
||||
|
||||
# Read rbr binlog.
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_row.000001 | $MYSQL --local-infile=1
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_r.001 | $MYSQL --local-infile=1
|
||||
# Read stm binlog.
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-wl2325_stm.000001 | $MYSQL --local-infile=1
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_s.001 | $MYSQL --local-infile=1
|
||||
# Show result.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
@ -74,7 +89,7 @@ DROP TABLE t1, t2, t3;
|
||||
--echo ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ====
|
||||
|
||||
# Read binlog.
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/binlog_old_version_5_1-telco.000001 | $MYSQL --local-infile=1
|
||||
--exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-telco.001 | $MYSQL --local-infile=1
|
||||
# Show resulting tablea.
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
SELECT * FROM t2 ORDER BY a;
|
||||
|
@ -10,4 +10,3 @@
|
||||
#
|
||||
##############################################################################
|
||||
binlog_multi_engine : Bug#32663 binlog_multi_engine.test fails randomly
|
||||
binlog_base64_flag : BUG#33247 2007-12-14 Sven: mysqlbinlog does not clean up after itself on termination. When compiled in debug mode, this test generates lots of warnings for memory leaks.
|
||||
|
3
mysql-test/suite/bugs/data/rpl_bug12691.dat
Normal file
3
mysql-test/suite/bugs/data/rpl_bug12691.dat
Normal file
@ -0,0 +1,3 @@
|
||||
a
|
||||
b
|
||||
c
|
34
mysql-test/suite/bugs/r/rpl_bug12691.result
Normal file
34
mysql-test/suite/bugs/r/rpl_bug12691.result
Normal file
@ -0,0 +1,34 @@
|
||||
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;
|
||||
|
||||
**** On Master ****
|
||||
CREATE TABLE t1 (b CHAR(10));
|
||||
|
||||
**** On Slave ****
|
||||
STOP SLAVE;
|
||||
|
||||
**** On Master ****
|
||||
LOAD DATA INFILE FILENAME
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
3
|
||||
SHOW BINLOG EVENTS;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Format_desc 1 # Server ver: #
|
||||
master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1 (b CHAR(10))
|
||||
master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=#
|
||||
master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE FILENAME ;file_id=#
|
||||
|
||||
**** On Slave ****
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
0
|
||||
|
||||
**** On Master ****
|
||||
DROP TABLE t1;
|
53
mysql-test/suite/bugs/t/rpl_bug12691.test
Normal file
53
mysql-test/suite/bugs/t/rpl_bug12691.test
Normal file
@ -0,0 +1,53 @@
|
||||
# Bug#12691: Exec_master_log_pos corrupted with SQL_SLAVE_SKIP_COUNTER
|
||||
# Date: 01/31/2008
|
||||
# Added: Serge Kozlov <skozlov@mysql.com>
|
||||
|
||||
--source include/master-slave.inc
|
||||
--connection master
|
||||
--source include/have_binlog_format_mixed_or_statement.inc
|
||||
|
||||
--echo
|
||||
--echo **** On Master ****
|
||||
CREATE TABLE t1 (b CHAR(10));
|
||||
--echo
|
||||
--echo **** On Slave ****
|
||||
--sync_slave_with_master
|
||||
STOP SLAVE;
|
||||
--source include/wait_for_slave_to_stop.inc
|
||||
|
||||
--connection master
|
||||
|
||||
--echo
|
||||
--echo **** On Master ****
|
||||
--exec cp $MYSQL_TEST_DIR/suite/bugs/data/rpl_bug12691.dat $MYSQLTEST_VARDIR/tmp/
|
||||
--echo LOAD DATA INFILE FILENAME
|
||||
--disable_query_log
|
||||
--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat' INTO TABLE t1 FIELDS TERMINATED BY '|'
|
||||
--enable_query_log
|
||||
--remove_file $MYSQLTEST_VARDIR/tmp/rpl_bug12691.dat
|
||||
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
--replace_column 2 # 5 #
|
||||
--replace_regex /Server ver: .+/Server ver: #/ /table_id: [0-9]+/table_id: #/ /COMMIT.+xid=[0-9]+.+/#/ /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ /'.+'/FILENAME/
|
||||
SHOW BINLOG EVENTS;
|
||||
|
||||
--save_master_pos
|
||||
|
||||
--connection slave
|
||||
--echo
|
||||
--echo **** On Slave ****
|
||||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
|
||||
START SLAVE;
|
||||
--source include/wait_for_slave_to_start.inc
|
||||
--sync_with_master
|
||||
|
||||
SELECT COUNT(*) FROM t1;
|
||||
|
||||
# Clean up
|
||||
--connection master
|
||||
--echo
|
||||
--echo **** On Master ****
|
||||
DROP TABLE t1;
|
||||
--sync_slave_with_master
|
||||
|
@ -12,13 +12,13 @@ load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2;
|
||||
select count(*) from t2 /* 5 000 */;
|
||||
count(*)
|
||||
5000
|
||||
show binlog events in 'master-bin.000002' from 106;
|
||||
show binlog events in 'master-bin.000002' from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000002 106 Query 1 # use `test`; create table t2 (id int not null primary key auto_increment)
|
||||
master-bin.000002 229 Begin_load_query 1 # ;file_id=#;block_len=8192
|
||||
master-bin.000002 8444 Append_block 1 # ;file_id=#;block_len=8192
|
||||
master-bin.000002 16659 Append_block 1 # ;file_id=#;block_len=7509
|
||||
master-bin.000002 24191 Execute_load_query 1 # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=#
|
||||
master-bin.000002 # Query # # use `test`; create table t2 (id int not null primary key auto_increment)
|
||||
master-bin.000002 # Begin_load_query # # ;file_id=#;block_len=#
|
||||
master-bin.000002 # Append_block # # ;file_id=#;block_len=#
|
||||
master-bin.000002 # Append_block # # ;file_id=#;block_len=#
|
||||
master-bin.000002 # Execute_load_query # # use `test`; load data infile 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' into table t2 ;file_id=#
|
||||
select count(*) from t2 /* 5 000 */;
|
||||
count(*)
|
||||
5000
|
||||
|
@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011',
|
||||
ADD y BIT(5) DEFAULT b'10101',
|
||||
ADD z BIT(2) DEFAULT b'10';
|
||||
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
|
||||
ALTER TABLE t1_nodef ADD x INT NOT NULL;
|
||||
ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL;
|
||||
ALTER TABLE t2 DROP b;
|
||||
ALTER TABLE t4 MODIFY a FLOAT;
|
||||
ALTER TABLE t5 MODIFY b FLOAT;
|
||||
@ -393,8 +393,8 @@ 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);
|
||||
INSERT INTO t1_nodef VALUES (1,2,3,4,5);
|
||||
INSERT INTO t1_nodef VALUES (2,4,6,8,10);
|
||||
**** On Master ****
|
||||
UPDATE t1_nodef SET b=2*b WHERE a=1;
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
@ -403,9 +403,9 @@ a b
|
||||
2 4
|
||||
**** On Slave ****
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
a b x
|
||||
1 4 3
|
||||
2 4 6
|
||||
a b x y z
|
||||
1 4 3 4 5
|
||||
2 4 6 8 10
|
||||
**** On Master ****
|
||||
DELETE FROM t1_nodef WHERE a=2;
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
@ -413,8 +413,8 @@ a b
|
||||
1 4
|
||||
**** On Slave ****
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
a b x
|
||||
1 4 3
|
||||
a b x y z
|
||||
1 4 3 4 5
|
||||
**** 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;
|
||||
|
@ -26,7 +26,7 @@ ADD x BIT(3) DEFAULT b'011',
|
||||
ADD y BIT(5) DEFAULT b'10101',
|
||||
ADD z BIT(2) DEFAULT b'10';
|
||||
ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
|
||||
ALTER TABLE t1_nodef ADD x INT NOT NULL;
|
||||
ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL, ADD z INT NOT NULL;
|
||||
ALTER TABLE t2 DROP b;
|
||||
ALTER TABLE t4 MODIFY a FLOAT;
|
||||
ALTER TABLE t5 MODIFY b FLOAT;
|
||||
@ -393,8 +393,8 @@ 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);
|
||||
INSERT INTO t1_nodef VALUES (1,2,3,4,5);
|
||||
INSERT INTO t1_nodef VALUES (2,4,6,8,10);
|
||||
**** On Master ****
|
||||
UPDATE t1_nodef SET b=2*b WHERE a=1;
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
@ -403,9 +403,9 @@ a b
|
||||
2 4
|
||||
**** On Slave ****
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
a b x
|
||||
1 4 3
|
||||
2 4 6
|
||||
a b x y z
|
||||
1 4 3 4 5
|
||||
2 4 6 8 10
|
||||
**** On Master ****
|
||||
DELETE FROM t1_nodef WHERE a=2;
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
@ -413,8 +413,8 @@ a b
|
||||
1 4
|
||||
**** On Slave ****
|
||||
SELECT * FROM t1_nodef ORDER BY a;
|
||||
a b x
|
||||
1 4 3
|
||||
a b x y z
|
||||
1 4 3 4 5
|
||||
**** 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;
|
||||
|
@ -7,6 +7,7 @@
|
||||
# BUG#33413 show binlog events fails if binlog has event size of close
|
||||
# to max_allowed_packet
|
||||
|
||||
source include/have_binlog_format_mixed_or_statement.inc;
|
||||
source include/master-slave.inc;
|
||||
source include/have_innodb.inc;
|
||||
source include/have_binlog_format_mixed_or_statement.inc;
|
||||
@ -35,9 +36,9 @@ select count(*) from t2 /* 5 000 */;
|
||||
|
||||
# the binglog will show fragmented Append_block events
|
||||
--let $binlog_start=106
|
||||
--replace_column 5 #
|
||||
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
--replace_column 2 # 4 # 5 #
|
||||
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR $binlog_start <binlog_start>
|
||||
--eval show binlog events in 'master-bin.000002' from $binlog_start
|
||||
|
||||
|
||||
|
141
sql/log_event.cc
141
sql/log_event.cc
@ -99,27 +99,51 @@ static const char *HA_ERR(int i)
|
||||
case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
|
||||
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
|
||||
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
|
||||
case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
macro to call from different branches of Rows_log_event::do_apply_event
|
||||
Error reporting facility for Rows_log_event::do_apply_event
|
||||
|
||||
@param level error, warning or info
|
||||
@param ha_error HA_ERR_ code
|
||||
@param rli pointer to the active Relay_log_info instance
|
||||
@param thd pointer to the slave thread's thd
|
||||
@param table pointer to the event's table object
|
||||
@param type the type of the event
|
||||
@param log_name the master binlog file name
|
||||
@param pos the master binlog file pos (the next after the event)
|
||||
|
||||
*/
|
||||
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
|
||||
Relay_log_info const *rli, THD *thd,
|
||||
TABLE *table, const char * type,
|
||||
const char *log_name, ulong pos)
|
||||
{
|
||||
const char *handler_error= HA_ERR(ha_error);
|
||||
const char *handler_error= HA_ERR(ha_error);
|
||||
char buff[MAX_SLAVE_ERRMSG], *slider;
|
||||
const char *buff_end= buff + sizeof(buff);
|
||||
uint len;
|
||||
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
|
||||
MYSQL_ERROR *err;
|
||||
buff[0]= 0;
|
||||
|
||||
for (err= it++, slider= buff; err && slider < buff_end - 1;
|
||||
slider += len, err= it++)
|
||||
{
|
||||
len= my_snprintf(slider, buff_end - slider,
|
||||
" %s, Error_code: %d;", err->msg, err->code);
|
||||
}
|
||||
|
||||
rli->report(level, thd->net.client_last_errno,
|
||||
"Could not execute %s event on table %s.%s;"
|
||||
"%s%s handler error %s; "
|
||||
"%s handler error %s; "
|
||||
"the event's master log %s, end_log_pos %lu",
|
||||
type, table->s->db.str,
|
||||
table->s->table_name.str,
|
||||
thd->net.client_last_error[0] != 0 ? thd->net.client_last_error : "",
|
||||
thd->net.client_last_error[0] != 0 ? ";" : "",
|
||||
buff,
|
||||
handler_error == NULL? "<unknown>" : handler_error,
|
||||
log_name, pos);
|
||||
}
|
||||
@ -212,9 +236,9 @@ uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
|
||||
*/
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
static void pretty_print_str(IO_CACHE* cache, char* str, int len)
|
||||
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
|
||||
{
|
||||
char* end = str + len;
|
||||
const char* end = str + len;
|
||||
my_b_printf(cache, "\'");
|
||||
while (str < end)
|
||||
{
|
||||
@ -277,9 +301,9 @@ inline int ignored_error_code(int err_code)
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
static char *pretty_print_str(char *packet, char *str, int len)
|
||||
static char *pretty_print_str(char *packet, const char *str, int len)
|
||||
{
|
||||
char *end= str + len;
|
||||
const char *end= str + len;
|
||||
char *pos= packet;
|
||||
*pos++= '\'';
|
||||
while (str < end)
|
||||
@ -385,7 +409,7 @@ static void cleanup_load_tmpdir()
|
||||
write_str()
|
||||
*/
|
||||
|
||||
static bool write_str(IO_CACHE *file, char *str, uint length)
|
||||
static bool write_str(IO_CACHE *file, const char *str, uint length)
|
||||
{
|
||||
uchar tmp[1];
|
||||
tmp[0]= (uchar) length;
|
||||
@ -2957,18 +2981,63 @@ Format_description_log_event(const char* buf,
|
||||
If post_header_len is null, it means malloc failed, and is_valid
|
||||
will fail, so there is no need to do anything.
|
||||
|
||||
The trees which have wrong event id's are:
|
||||
mysql-5.1-wl2325-5.0-drop6p13-alpha, mysql-5.1-wl2325-5.0-drop6,
|
||||
mysql-5.1-wl2325-5.0, mysql-5.1-wl2325-no-dd (`grep -C2
|
||||
BEGIN_LOAD_QUERY_EVENT /home/bk/ * /sql/log_event.h`). The
|
||||
corresponding version (`grep mysql, configure.in` in those trees)
|
||||
strings are 5.2.2-a_drop6p13-alpha, 5.2.2-a_drop6p13c,
|
||||
5.1.5-a_drop5p20, 5.1.2-a_drop5p5.
|
||||
The trees in which events have wrong id's are:
|
||||
|
||||
mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
|
||||
mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
|
||||
mysql-5.1-wl2325-no-dd
|
||||
|
||||
(this was found by grepping for two lines in sequence where the
|
||||
first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
|
||||
"TABLE_MAP_EVENT," in log_event.h in all trees)
|
||||
|
||||
In these trees, the following server_versions existed since
|
||||
TABLE_MAP_EVENT was introduced:
|
||||
|
||||
5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha
|
||||
5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12
|
||||
5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15
|
||||
5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c
|
||||
5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5
|
||||
5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8
|
||||
5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b
|
||||
5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19
|
||||
5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1
|
||||
5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3
|
||||
5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6
|
||||
5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12
|
||||
5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8
|
||||
5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
|
||||
5.2.2-a_drop6p13c
|
||||
|
||||
(this was found by grepping for "mysql," in all historical
|
||||
versions of configure.in in the trees listed above).
|
||||
|
||||
There are 5.1.1-alpha versions that use the new event id's, so we
|
||||
do not test that version string. So replication from 5.1.1-alpha
|
||||
with the other event id's to a new version does not work.
|
||||
Moreover, we can safely ignore the part after drop[56]. This
|
||||
allows us to simplify the big list above to the following regexes:
|
||||
|
||||
5\.1\.[1-5]-a_drop5.*
|
||||
5\.1\.4-a_drop6.*
|
||||
5\.2\.[0-2]-a_drop6.*
|
||||
|
||||
This is what we test for in the 'if' below.
|
||||
*/
|
||||
if (post_header_len &&
|
||||
(strncmp(server_version, "5.1.2-a_drop5", 13) == 0 ||
|
||||
strncmp(server_version, "5.1.5-a_drop5", 13) == 0 ||
|
||||
strncmp(server_version, "5.2.2-a_drop6", 13) == 0))
|
||||
server_version[0] == '5' && server_version[1] == '.' &&
|
||||
server_version[3] == '.' &&
|
||||
strncmp(server_version + 5, "-a_drop", 7) == 0 &&
|
||||
((server_version[2] == '1' &&
|
||||
server_version[4] >= '1' && server_version[4] <= '5' &&
|
||||
server_version[12] == '5') ||
|
||||
(server_version[2] == '1' &&
|
||||
server_version[4] == '4' &&
|
||||
server_version[12] == '6') ||
|
||||
(server_version[2] == '2' &&
|
||||
server_version[4] >= '0' && server_version[4] <= '2' &&
|
||||
server_version[12] == '6')))
|
||||
{
|
||||
if (number_of_event_types != 22)
|
||||
{
|
||||
@ -6026,7 +6095,8 @@ bool sql_ex_info::write_data(IO_CACHE* file)
|
||||
sql_ex_info::init()
|
||||
*/
|
||||
|
||||
char *sql_ex_info::init(char *buf, char *buf_end, bool use_new_format)
|
||||
const char *sql_ex_info::init(const char *buf, const char *buf_end,
|
||||
bool use_new_format)
|
||||
{
|
||||
cached_new_format = use_new_format;
|
||||
if (use_new_format)
|
||||
@ -6039,12 +6109,11 @@ char *sql_ex_info::init(char *buf, char *buf_end, bool use_new_format)
|
||||
the case when we have old format because we will be reusing net buffer
|
||||
to read the actual file before we write out the Create_file event.
|
||||
*/
|
||||
const char *ptr= buf;
|
||||
if (read_str(&ptr, buf_end, (const char **) &field_term, &field_term_len) ||
|
||||
read_str(&ptr, buf_end, (const char **) &enclosed, &enclosed_len) ||
|
||||
read_str(&ptr, buf_end, (const char **) &line_term, &line_term_len) ||
|
||||
read_str(&ptr, buf_end, (const char **) &line_start, &line_start_len) ||
|
||||
read_str(&ptr, buf_end, (const char **) &escaped, &escaped_len))
|
||||
if (read_str(&buf, buf_end, &field_term, &field_term_len) ||
|
||||
read_str(&buf, buf_end, &enclosed, &enclosed_len) ||
|
||||
read_str(&buf, buf_end, &line_term, &line_term_len) ||
|
||||
read_str(&buf, buf_end, &line_start, &line_start_len) ||
|
||||
read_str(&buf, buf_end, &escaped, &escaped_len))
|
||||
return 0;
|
||||
opt_flags = *buf++;
|
||||
}
|
||||
@ -7646,7 +7715,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
|
||||
|
||||
/* fill table->record[0] with default values */
|
||||
|
||||
if ((error= prepare_record(rli, table, m_width,
|
||||
if ((error= prepare_record(table, m_width,
|
||||
TRUE /* check if columns have def. values */)))
|
||||
DBUG_RETURN(error);
|
||||
|
||||
@ -7964,13 +8033,17 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
|
||||
DBUG_ASSERT(m_table && m_table->in_use != NULL);
|
||||
|
||||
TABLE *table= m_table;
|
||||
int error;
|
||||
int error= 0;
|
||||
|
||||
/* unpack row - missing fields get default values */
|
||||
|
||||
// TODO: shall we check and report errors here?
|
||||
prepare_record(NULL,table,m_width,FALSE /* don't check errors */);
|
||||
error= unpack_current_row(rli);
|
||||
/*
|
||||
rpl_row_tabledefs.test specifies that
|
||||
if the extra field on the slave does not have a default value
|
||||
and this is okay with Delete or Update events.
|
||||
Todo: fix wl3228 hld that requires defauls for all types of events
|
||||
*/
|
||||
|
||||
prepare_record(table, m_width, FALSE);
|
||||
error= unpack_current_row(rli);
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_PRINT("info",("looking for the following record"));
|
||||
|
627
sql/log_event.h
627
sql/log_event.h
@ -152,11 +152,11 @@ struct old_sql_ex
|
||||
struct sql_ex_info
|
||||
{
|
||||
sql_ex_info() {} /* Remove gcc warning */
|
||||
char* field_term;
|
||||
char* enclosed;
|
||||
char* line_term;
|
||||
char* line_start;
|
||||
char* escaped;
|
||||
const char* field_term;
|
||||
const char* enclosed;
|
||||
const char* line_term;
|
||||
const char* line_start;
|
||||
const char* escaped;
|
||||
int cached_new_format;
|
||||
uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len;
|
||||
char opt_flags;
|
||||
@ -171,7 +171,7 @@ struct sql_ex_info
|
||||
line_start_len + escaped_len + 6 : 7);
|
||||
}
|
||||
bool write_data(IO_CACHE* file);
|
||||
char* init(char* buf,char* buf_end,bool use_new_format);
|
||||
const char* init(const char* buf, const char* buf_end, bool use_new_format);
|
||||
bool new_format()
|
||||
{
|
||||
return ((cached_new_format != -1) ? cached_new_format :
|
||||
@ -667,34 +667,35 @@ typedef struct st_print_event_info
|
||||
|
||||
@section Log_event_binary_format Binary Format
|
||||
|
||||
Any Log_event saved on disk consists of the following three
|
||||
Any @c Log_event saved on disk consists of the following three
|
||||
components.
|
||||
|
||||
@li Common-Header
|
||||
@li Post-Header
|
||||
@li Body
|
||||
* Common-Header
|
||||
* Post-Header
|
||||
* Body
|
||||
|
||||
The Common-Header, documented below, always has the same form and
|
||||
length within one version of MySQL. Each event type specifies a
|
||||
form and length of the Post-Header common to all events of the type.
|
||||
The Body may be of different form and length even for different
|
||||
events of the same type. The binary formats of Post-Header and Body
|
||||
are documented separately in each subclass. The binary format of
|
||||
Common-Header is as follows.
|
||||
The Common-Header, documented in the table @ref Table_common_header
|
||||
"below", always has the same form and length within one version of
|
||||
MySQL. Each event type specifies a form and length of the
|
||||
Post-Header common to all events of the type. The Body may be of
|
||||
different form and length even for different events of the same
|
||||
type. The binary formats of Post-Header and Body are documented
|
||||
separately in each subclass. The binary format of Common-Header is
|
||||
as follows.
|
||||
|
||||
<table>
|
||||
<caption>Common-Header</caption>
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Format<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>timestamp</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>The number of seconds since 1970.
|
||||
<td>The time when the query started, in seconds since 1970.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -705,14 +706,14 @@ typedef struct st_print_event_info
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>master_id</td>
|
||||
<td>4 byte integer</td>
|
||||
<td>server_id</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>Server ID of the server that created the event.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>total_size</td>
|
||||
<td>4 byte integer</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>The total size of this event, in bytes. In other words, this
|
||||
is the sum of the sizes of Common-Header, Post-Header, and Body.
|
||||
</td>
|
||||
@ -720,9 +721,12 @@ typedef struct st_print_event_info
|
||||
|
||||
<tr>
|
||||
<td>master_position</td>
|
||||
<td>4 byte integer</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>The position of the next event in the master binary log, in
|
||||
bytes from the beginning of the file.
|
||||
bytes from the beginning of the file. In a binlog that is not a
|
||||
relay log, this is just the position of the next event, in bytes
|
||||
from the beginning of the file. In a relay log, this is
|
||||
the position of the next event in the master's binlog.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -736,13 +740,55 @@ typedef struct st_print_event_info
|
||||
Summing up the numbers above, we see that the total size of the
|
||||
common header is 19 bytes.
|
||||
|
||||
@subsection Log_event_endianness_and_string_formats Endianness and String Formats
|
||||
@subsection Log_event_format_of_atomic_primitives Format of Atomic Primitives
|
||||
|
||||
All numbers, whether they are 16-, 32-, or 64-bit, are stored in
|
||||
little endian, i.e., the least significant byte first.
|
||||
- All numbers, whether they are 16-, 24-, 32-, or 64-bit numbers,
|
||||
are stored in little endian, i.e., the least significant byte first,
|
||||
unless otherwise specified.
|
||||
|
||||
Strings are stored in various formats. The format of each string is
|
||||
documented separately.
|
||||
@anchor packed_integer
|
||||
- Some events use a special format for efficient representation of
|
||||
unsigned integers, called Packed Integer. A Packed Integer has the
|
||||
capacity of storing up to 8-byte integers, while small integers
|
||||
still can use 1, 3, or 4 bytes. The first byte indicates how many
|
||||
bytes are used by the integer, according to the following table:
|
||||
|
||||
<table>
|
||||
<caption>Format of Packed Integer</caption>
|
||||
|
||||
<tr>
|
||||
<th>First byte</th>
|
||||
<th>Format</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>0-250</td>
|
||||
<td>The first byte is the number (in range 0-250), and no more
|
||||
bytes are used.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>252</td>
|
||||
<td>Two more bytes are used. The number is in the range
|
||||
251-0xffff.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>253</td>
|
||||
<td>Three more bytes are used. The number is in the range
|
||||
0xffff-0xffffff.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>254</td>
|
||||
<td>Eight more bytes are used. The number is in the range
|
||||
0xffffff-0xffffffffffffffff.</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
- Strings are stored in various formats. The format of each string
|
||||
is documented separately.
|
||||
*/
|
||||
class Log_event
|
||||
{
|
||||
@ -1123,7 +1169,8 @@ protected:
|
||||
/**
|
||||
@class Query_log_event
|
||||
|
||||
Logs SQL queries.
|
||||
A @c Query_log_event is created for each query that modifies the
|
||||
database, unless the query is logged row-based.
|
||||
|
||||
@section Query_log_event_binary_format Binary format
|
||||
|
||||
@ -1134,60 +1181,49 @@ protected:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>slave_proxy_id</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>An integer identifying the client thread, which is unique on
|
||||
the server. (Note, however, that two threads on different servers
|
||||
may have the same slave_proxy_id.) This is used when a client
|
||||
thread creates a temporary table. Temporary tables are local to
|
||||
the client, and the slave_proxy_id is used to distinguish
|
||||
temporary tables belonging to different clients.
|
||||
<td>An integer identifying the client thread that issued the
|
||||
query. The id is unique per server. (Note, however, that two
|
||||
threads on different servers may have the same slave_proxy_id.)
|
||||
This is used when a client thread creates a temporary table local
|
||||
to the client. The slave_proxy_id is used to distinguish
|
||||
temporary tables that belong to different clients.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>exec_time</td>
|
||||
<td>4 byte integer</td>
|
||||
<td>???TODO</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>The time from when the query started to when it was logged in
|
||||
the binlog, in seconds.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>db_len</td>
|
||||
<td>1 byte integer</td>
|
||||
<td>The length of the name of the currently selected
|
||||
database.
|
||||
</td>
|
||||
<td>The length of the name of the currently selected database.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>error_code</td>
|
||||
<td>2 byte integer</td>
|
||||
<td>2 byte unsigned integer</td>
|
||||
<td>Error code generated by the master. If the master fails, the
|
||||
slave will fail with the same error code, except for the error
|
||||
codes ER_DB_CREATE_EXISTS==1007 and ER_DB_DROP_EXISTS==1008.
|
||||
codes ER_DB_CREATE_EXISTS == 1007 and ER_DB_DROP_EXISTS == 1008.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>status_vars_len</td>
|
||||
<td>2 byte integer</td>
|
||||
<td>2 byte unsigned integer</td>
|
||||
<td>The length of the status_vars block of the Body, in bytes. See
|
||||
<a href="#query_log_event_status_vars">below</a>.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Post-Header-For-Derived</td>
|
||||
<td>0 bytes</td>
|
||||
<td>This field is only written by the subclass
|
||||
Execute_load_query_log_event. In this base class, it takes 0
|
||||
bytes. See separate documentation for
|
||||
Execute_load_query_log_event.
|
||||
@ref query_log_event_status_vars "below".
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -1199,19 +1235,19 @@ protected:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a name="query_log_event_status_vars" /> status_vars</td>
|
||||
<td>variable length</td>
|
||||
<td>@anchor query_log_event_status_vars status_vars</td>
|
||||
<td>status_vars_len bytes</td>
|
||||
<td>Zero or more status variables. Each status variable consists
|
||||
of one byte identifying the variable stored, followed by the value
|
||||
of the variable. The possible variables are listed separately in
|
||||
the table below. MySQL always writes events in the order defined
|
||||
below; however, it is capable of reading them in any order.
|
||||
</td>
|
||||
the table @ref Table_query_log_event_status_vars "below". MySQL
|
||||
always writes events in the order defined below; however, it is
|
||||
capable of reading them in any order. </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@ -1237,13 +1273,14 @@ protected:
|
||||
The following table lists the status variables that may appear in
|
||||
the status_vars field.
|
||||
|
||||
@anchor Table_query_log_event_status_vars
|
||||
<table>
|
||||
<caption>Status variables for Query_log_event</caption>
|
||||
|
||||
<tr>
|
||||
<th>Status variable</th>
|
||||
<th>1-byte identifier</th>
|
||||
<th>Size<br/></th>
|
||||
<th>1 byte identifier</th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
@ -1251,13 +1288,13 @@ protected:
|
||||
<td>flags2</td>
|
||||
<td>Q_FLAGS2_CODE == 0</td>
|
||||
<td>4 byte bitfield</td>
|
||||
<td>The flags in thd->options, binary AND-ed with
|
||||
OPTIONS_WRITTEN_TO_BIN_LOG. The thd->options bitfield contains
|
||||
options for SELECT. OPTIONS_WRITTEN identifies those options that
|
||||
need to be written to the binlog (not all do). Specifically,
|
||||
OPTIONS_WRITTEN_TO_BIN_LOG equals (OPTION_AUTO_IS_NULL |
|
||||
OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS |
|
||||
OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex.
|
||||
<td>The flags in @c thd->options, binary AND-ed with @c
|
||||
OPTIONS_WRITTEN_TO_BIN_LOG. The @c thd->options bitfield contains
|
||||
options for "SELECT". @c OPTIONS_WRITTEN identifies those options
|
||||
that need to be written to the binlog (not all do). Specifically,
|
||||
@c OPTIONS_WRITTEN_TO_BIN_LOG equals (@c OPTION_AUTO_IS_NULL | @c
|
||||
OPTION_NO_FOREIGN_KEY_CHECKS | @c OPTION_RELAXED_UNIQUE_CHECKS |
|
||||
@c OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex.
|
||||
|
||||
These flags correspond to the SQL variables SQL_AUTO_IS_NULL,
|
||||
FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, and AUTOCOMMIT, documented in
|
||||
@ -1271,8 +1308,8 @@ protected:
|
||||
<tr>
|
||||
<td>sql_mode</td>
|
||||
<td>Q_SQL_MODE_CODE == 1</td>
|
||||
<td>8 byte integer</td>
|
||||
<td>The sql_mode variable. See the section "SQL Modes" in the
|
||||
<td>8 byte bitfield</td>
|
||||
<td>The @c sql_mode variable. See the section "SQL Modes" in the
|
||||
MySQL manual, and see mysql_priv.h for a list of the possible
|
||||
flags. Currently (2007-10-04), the following flags are available:
|
||||
<pre>
|
||||
@ -1310,10 +1347,10 @@ protected:
|
||||
MODE_PAD_CHAR_TO_FULL_LENGTH==0x80000000
|
||||
</pre>
|
||||
All these flags are replicated from the server. However, all
|
||||
flags except MODE_NO_DIR_IN_CREATE are honored by the slave; the
|
||||
slave always preserves its old value of MODE_NO_DIR_IN_CREATE.
|
||||
For a rationale, see comment in Query_log_event::do_apply_event in
|
||||
log_event.cc.
|
||||
flags except @c MODE_NO_DIR_IN_CREATE are honored by the slave;
|
||||
the slave always preserves its old value of @c
|
||||
MODE_NO_DIR_IN_CREATE. For a rationale, see comment in
|
||||
@c Query_log_event::do_apply_event in @c log_event.cc.
|
||||
|
||||
This field is always written to the binlog.
|
||||
</td>
|
||||
@ -1327,7 +1364,7 @@ protected:
|
||||
</td>
|
||||
<td>Stores the client's current catalog. Every database belongs
|
||||
to a catalog, the same way that every table belongs to a
|
||||
database. Currently, there is only one catalog, 'std'.
|
||||
database. Currently, there is only one catalog, "std".
|
||||
|
||||
This field is written if the length of the catalog is > 0;
|
||||
otherwise it is not written.
|
||||
@ -1343,7 +1380,7 @@ protected:
|
||||
auto_increment_offset, in that order. For more information, see
|
||||
"System variables" in the MySQL manual.
|
||||
|
||||
This field is written if auto_increment>1; otherwise it is not
|
||||
This field is written if auto_increment > 1. Otherwise, it is not
|
||||
written.
|
||||
</td>
|
||||
</tr>
|
||||
@ -1351,14 +1388,14 @@ protected:
|
||||
<tr>
|
||||
<td>charset</td>
|
||||
<td>Q_CHARSET_CODE == 4</td>
|
||||
<td>three 2-byte unsigned integers (i.e., 6 bytes)</td>
|
||||
<td>three 2 byte unsigned integers, totally 2+2+2=6 bytes</td>
|
||||
<td>The three variables character_set_client,
|
||||
collation_connection, and collation_server, in that order.
|
||||
`character_set_client' is a code identifying the character set and
|
||||
character_set_client is a code identifying the character set and
|
||||
collation used by the client to encode the query.
|
||||
`collation_connection' identifies the character set and collation
|
||||
collation_connection identifies the character set and collation
|
||||
that the master converts the query to when it receives it; this is
|
||||
useful when comparing literal strings. `collation_server' is the
|
||||
useful when comparing literal strings. collation_server is the
|
||||
default character set and collation used when a new database is
|
||||
created.
|
||||
|
||||
@ -1396,9 +1433,9 @@ protected:
|
||||
<td>Q_LC_TIME_NAMES_CODE == 7</td>
|
||||
<td>2 byte integer</td>
|
||||
<td>A code identifying a table of month and day names. The
|
||||
mapping from codes to languages is defined in sql_locale.cc.
|
||||
mapping from codes to languages is defined in @c sql_locale.cc.
|
||||
|
||||
This field is written if it is != 0, i.e., if the locale is not
|
||||
This field is written if it is not 0, i.e., if the locale is not
|
||||
en_US.
|
||||
</td>
|
||||
</tr>
|
||||
@ -1409,14 +1446,14 @@ protected:
|
||||
<td>2 byte integer</td>
|
||||
|
||||
<td>The value of the collation_database system variable (in the
|
||||
source code stored in thd->variables.collation_database), which
|
||||
source code stored in @c thd->variables.collation_database), which
|
||||
holds the code for a (character set, collation) pair as described
|
||||
above (see Q_CHARSET_CODE).
|
||||
|
||||
`collation_database' was used in old versions (???WHEN). Its
|
||||
value was loaded when issuing a "use db" command and could be
|
||||
changed by issuing a "SET collation_database=xxx" command. It
|
||||
used to affect the "LOAD DATA INFILE" and "CREATE TABLE" commands.
|
||||
collation_database was used in old versions (???WHEN). Its value
|
||||
was loaded when issuing a "use db" query and could be changed by
|
||||
issuing a "SET collation_database=xxx" query. It used to affect
|
||||
the "LOAD DATA INFILE" and "CREATE TABLE" commands.
|
||||
|
||||
In newer versions, "CREATE TABLE" has been changed to take the
|
||||
character set from the database of the created table, rather than
|
||||
@ -1433,17 +1470,17 @@ protected:
|
||||
|
||||
@subsection Query_log_event_notes_on_previous_versions Notes on Previous Versions
|
||||
|
||||
@li Status vars were introduced in version 5.0. To read earlier
|
||||
* Status vars were introduced in version 5.0. To read earlier
|
||||
versions correctly, check the length of the Post-Header.
|
||||
|
||||
@li The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x,
|
||||
* The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x,
|
||||
where 0<=x<=3. It was identical to Q_CATALOG_CODE, except that the
|
||||
string had a trailing '\0'. The '\0' was removed in 5.0.4 since it
|
||||
was redundant (the string length is stored before the string). The
|
||||
Q_CATALOG_CODE will never be written by a new master, but can still
|
||||
be understood by a new slave.
|
||||
|
||||
@li See Q_CHARSET_DATABASE_NUMBER in the table above.
|
||||
* See Q_CHARSET_DATABASE_NUMBER in the table above.
|
||||
|
||||
*/
|
||||
class Query_log_event: public Log_event
|
||||
@ -1576,7 +1613,8 @@ public: /* !!! Public in this patch to allow old usage */
|
||||
/**
|
||||
@class Muted_query_log_event
|
||||
|
||||
Pretends to log SQL queries, but doesn't actually do so.
|
||||
Pretends to log SQL queries, but doesn't actually do so. This is
|
||||
used internally only and never written to any binlog.
|
||||
|
||||
@section Muted_query_log_event_binary_format Binary Format
|
||||
|
||||
@ -1603,7 +1641,7 @@ public:
|
||||
@class Slave_log_event
|
||||
|
||||
Note that this class is currently not used at all; no code writes a
|
||||
Slave_log_event (though some code in repl_failsafe.cc reads
|
||||
@c Slave_log_event (though some code in @c repl_failsafe.cc reads @c
|
||||
Slave_log_event). So it's not a problem if this code is not
|
||||
maintained.
|
||||
|
||||
@ -1617,7 +1655,7 @@ public:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
@ -1717,26 +1755,27 @@ private:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>slave_proxy_id</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>An integer identifying the client thread, which is unique on
|
||||
the server. (Note, however, that the same slave_proxy_id may
|
||||
appear on different servers.) This is used when a client thread
|
||||
creates a temporary table. Temporary tables are local to the
|
||||
client, and the slave_proxy_id is used to distinguish temporary
|
||||
tables belonging to different clients.
|
||||
<td>An integer identifying the client thread that issued the
|
||||
query. The id is unique per server. (Note, however, that two
|
||||
threads on different servers may have the same slave_proxy_id.)
|
||||
This is used when a client thread creates a temporary table local
|
||||
to the client. The slave_proxy_id is used to distinguish
|
||||
temporary tables that belong to different clients.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>exec_time</td>
|
||||
<td>4 byte unsigned integer</td>
|
||||
<td>???TODO</td>
|
||||
<td>The time from when the query started to when it was logged in
|
||||
the binlog, in seconds.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@ -1773,7 +1812,7 @@ private:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
@ -1813,7 +1852,7 @@ private:
|
||||
<li> In the old format, we know that each string has length 0 or
|
||||
1. Therefore, only the first byte of each string is stored. The
|
||||
order of the strings is the same as in the new format. These five
|
||||
bytes are followed by the same 1-byte bitfield as in the new
|
||||
bytes are followed by the same 1 byte bitfield as in the new
|
||||
format. Finally, a 1 byte bitfield called empty_flags is stored.
|
||||
The low 5 bits of empty_flags indicate which of the five strings
|
||||
have length 0. For each of the following flags that is set, the
|
||||
@ -1831,7 +1870,7 @@ private:
|
||||
|
||||
<tr>
|
||||
<td>field_lens</td>
|
||||
<td>num_fields 1-byte unsigned integers</td>
|
||||
<td>num_fields 1 byte unsigned integers</td>
|
||||
<td>An array of num_fields integers representing the length of
|
||||
each field in the query. (num_fields is from the Post-Header).
|
||||
</td>
|
||||
@ -1992,11 +2031,13 @@ extern char server_version[SERVER_VERSION_LENGTH];
|
||||
|
||||
Start_log_event_v3 is the Start_log_event of binlog format 3 (MySQL 3.23 and
|
||||
4.x).
|
||||
Format_description_log_event derives from Start_log_event_v3; it is the
|
||||
Start_log_event of binlog format 4 (MySQL 5.0), that is, the event that
|
||||
describes the other events' header/postheader lengths. This event is sent by
|
||||
MySQL 5.0 whenever it starts sending a new binlog if the requested position
|
||||
is >4 (otherwise if ==4 the event will be sent naturally).
|
||||
|
||||
Format_description_log_event derives from Start_log_event_v3; it is
|
||||
the Start_log_event of binlog format 4 (MySQL 5.0), that is, the
|
||||
event that describes the other events' Common-Header/Post-Header
|
||||
lengths. This event is sent by MySQL 5.0 whenever it starts sending
|
||||
a new binlog if the requested position is >4 (otherwise if ==4 the
|
||||
event will be sent naturally).
|
||||
|
||||
@section Start_log_event_v3_binary_format Binary Format
|
||||
*/
|
||||
@ -2150,7 +2191,9 @@ protected:
|
||||
/**
|
||||
@class Intvar_log_event
|
||||
|
||||
Logs special variables related to auto_increment values.
|
||||
An Intvar_log_event will be created just before a Query_log_event,
|
||||
if the query uses one of the variables LAST_INSERT_ID or INSERT_ID.
|
||||
Each Intvar_log_event holds the value of one of these variables.
|
||||
|
||||
@section Intvar_log_event_binary_format Binary Format
|
||||
|
||||
@ -2161,12 +2204,12 @@ protected:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td>type</td>
|
||||
<td>1 byte enumeration</td>
|
||||
<td>One byte identifying the type of variable stored. Currently,
|
||||
two identifiers are supported: LAST_INSERT_ID_EVENT==1 and
|
||||
@ -2182,7 +2225,6 @@ protected:
|
||||
|
||||
</table>
|
||||
*/
|
||||
|
||||
class Intvar_log_event: public Log_event
|
||||
{
|
||||
public:
|
||||
@ -2228,15 +2270,34 @@ private:
|
||||
written in 4.1.1 for PASSWORD() (but the fact that it is written is just a
|
||||
waste, it does not cause bugs).
|
||||
|
||||
The state of the random number generation consists of 128 bits,
|
||||
which are stored internally as two 64-bit numbers.
|
||||
|
||||
@section Rand_log_event_binary_format Binary Format
|
||||
This event type has no Post-Header. The Body of this event type has
|
||||
two components:
|
||||
|
||||
@li seed1 (8 bytes): 64 bit random seed1.
|
||||
@li seed2 (8 bytes): 64 bit random seed2.
|
||||
<table>
|
||||
<caption>Post-Header for Intvar_log_event</caption>
|
||||
|
||||
The state of the random number generation consists of 128 bits,
|
||||
which are stored internally as two 64-bit numbers.
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>seed1</td>
|
||||
<td>8 byte unsigned integer</td>
|
||||
<td>64 bit random seed1.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>seed2</td>
|
||||
<td>8 byte unsigned integer</td>
|
||||
<td>64 bit random seed2.</td>
|
||||
</tr>
|
||||
</table>
|
||||
*/
|
||||
|
||||
class Rand_log_event: public Log_event
|
||||
@ -2423,14 +2484,14 @@ private:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>pos</td>
|
||||
<td>position</td>
|
||||
<td>8 byte integer</td>
|
||||
<td>???TODO</td>
|
||||
<td>The position within the binlog to rotate to.</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
@ -2442,17 +2503,17 @@ private:
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size<br/></th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>new_log_ident</td>
|
||||
<td>new_log</td>
|
||||
<td>variable length string without trailing zero, extending to the
|
||||
end of the event (determined by the length field of the
|
||||
Common-Header)
|
||||
</td>
|
||||
<td>???TODO</td>
|
||||
<td>Name of the binlog to rotate to.</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
@ -2841,10 +2902,316 @@ char *str_to_hex(char *to, const char *from, uint len);
|
||||
/**
|
||||
@class Table_map_log_event
|
||||
|
||||
Create a mapping from a (database name, table name) couple to a table
|
||||
identifier (an integer number).
|
||||
In row-based mode, every row operation event is preceded by a
|
||||
Table_map_log_event which maps a table definition to a number. The
|
||||
table definition consists of database name, table name, and column
|
||||
definitions.
|
||||
|
||||
@section Table_map_log_event_binary_format Binary Format
|
||||
|
||||
The Post-Header has the following components:
|
||||
|
||||
<table>
|
||||
<caption>Post-Header for Table_map_log_event</caption>
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>table_id</td>
|
||||
<td>6 bytes unsigned integer</td>
|
||||
<td>The number that identifies the table.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>flags</td>
|
||||
<td>2 byte bitfield</td>
|
||||
<td>Reserved for future use; currently always 0.</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
The Body has the following components:
|
||||
|
||||
<table>
|
||||
<caption>Body for Table_map_log_event</caption>
|
||||
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>database_name</td>
|
||||
<td>one byte string length, followed by null-terminated string</td>
|
||||
<td>The name of the database in which the table resides. The name
|
||||
is represented as a one byte unsigned integer representing the
|
||||
number of bytes in the name, followed by length bytes containing
|
||||
the database name, followed by a terminating 0 byte. (Note the
|
||||
redundancy in the representation of the length.) </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>table_name</td>
|
||||
<td>one byte string length, followed by null-terminated string</td>
|
||||
<td>The name of the table, encoded the same way as the database
|
||||
name above.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>column_count</td>
|
||||
<td>@ref packed_integer "Packed Integer"</td>
|
||||
<td>The number of columns in the table, represented as a packed
|
||||
variable-length integer.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>column_type</td>
|
||||
<td>List of column_count 1 byte enumeration values</td>
|
||||
<td>The type of each column in the table, listed from left to
|
||||
right. Each byte is mapped to a column type according to the
|
||||
enumeration type enum_field_types defined in mysql_com.h. The
|
||||
mapping of types to numbers is listed in the table @ref
|
||||
Table_table_map_log_event_column_types "below" (along with
|
||||
description of the associated metadata field). </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>metadata_length</td>
|
||||
<td>@ref packed_integer "Packed Integer"</td>
|
||||
<td>The length of the following metadata block</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>metadata</td>
|
||||
<td>list of metadata for each column</td>
|
||||
<td>For each column from left to right, a chunk of data who's
|
||||
length and semantics depends on the type of the column. The
|
||||
length and semantics for the metadata for each column are listed
|
||||
in the table @ref Table_table_map_log_event_column_types
|
||||
"below".</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>null_bits</td>
|
||||
<td>column_count bits, rounded up to nearest byte</td>
|
||||
<td>For each column, a bit indicating whether data in the column
|
||||
can be NULL or not. The number of bytes needed for this is
|
||||
int((column_count+7)/8). The flag for the first column from the
|
||||
left is in the least-significant bit of the first byte, the second
|
||||
is in the second least significant bit of the first byte, the
|
||||
ninth is in the least significant bit of the second byte, and so
|
||||
on. </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
The table below lists all column types, along with the numerical
|
||||
identifier for it and the size and interpretation of meta-data used
|
||||
to describe the type.
|
||||
|
||||
@anchor Table_table_map_log_event_column_types
|
||||
<table>
|
||||
<caption>Table_map_log_event column types: numerical identifier and
|
||||
metadata</caption>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Identifier</th>
|
||||
<th>Size of metadata in bytes</th>
|
||||
<th>Description of metadata</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_DECIMAL</td><td>0</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_TINY</td><td>1</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_SHORT</td><td>2</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_LONG</td><td>3</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_FLOAT</td><td>4</td>
|
||||
<td>1 byte</td>
|
||||
<td>1 byte unsigned integer, representing the "pack_length", which
|
||||
is equal to sizeof(float) on the server from which the event
|
||||
originates.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_DOUBLE</td><td>5</td>
|
||||
<td>1 byte</td>
|
||||
<td>1 byte unsigned integer, representing the "pack_length", which
|
||||
is equal to sizeof(double) on the server from which the event
|
||||
originates.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_NULL</td><td>6</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_TIMESTAMP</td><td>7</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_LONGLONG</td><td>8</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_INT24</td><td>9</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_DATE</td><td>10</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_TIME</td><td>11</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_DATETIME</td><td>12</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_YEAR</td><td>13</td>
|
||||
<td>0</td>
|
||||
<td>No column metadata.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><i>MYSQL_TYPE_NEWDATE</i></td><td><i>14</i></td>
|
||||
<td>–</td>
|
||||
<td><i>This enumeration value is only used internally and cannot
|
||||
exist in a binlog.</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_VARCHAR</td><td>15</td>
|
||||
<td>2 bytes</td>
|
||||
<td>2 byte unsigned integer representing the maximum length of
|
||||
the string.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_BIT</td><td>16</td>
|
||||
<td>2 bytes</td>
|
||||
<td>A 1 byte unsigned int representing the length in bits of the
|
||||
bitfield (0 to 64), followed by a 1 byte unsigned int
|
||||
representing the number of bytes occupied by the bitfield. The
|
||||
number of bytes is either int((length+7)/8) or int(length/8).</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_NEWDECIMAL</td><td>246</td>
|
||||
<td>2 bytes</td>
|
||||
<td>A 1 byte unsigned int representing the precision, followed
|
||||
by a 1 byte unsigned int representing the number of decimals.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><i>MYSQL_TYPE_ENUM</i></td><td><i>247</i></td>
|
||||
<td>–</td>
|
||||
<td><i>This enumeration value is only used internally and cannot
|
||||
exist in a binlog.</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><i>MYSQL_TYPE_SET</i></td><td><i>248</i></td>
|
||||
<td>–</td>
|
||||
<td><i>This enumeration value is only used internally and cannot
|
||||
exist in a binlog.</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_TINY_BLOB</td><td>249</td>
|
||||
<td>–</td>
|
||||
<td><i>This enumeration value is only used internally and cannot
|
||||
exist in a binlog.</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><i>MYSQL_TYPE_MEDIUM_BLOB</i></td><td><i>250</i></td>
|
||||
<td>–</td>
|
||||
<td><i>This enumeration value is only used internally and cannot
|
||||
exist in a binlog.</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><i>MYSQL_TYPE_LONG_BLOB</i></td><td><i>251</i></td>
|
||||
<td>–</td>
|
||||
<td><i>This enumeration value is only used internally and cannot
|
||||
exist in a binlog.</i></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_BLOB</td><td>252</td>
|
||||
<td>1 byte</td>
|
||||
<td>The pack length, i.e., the number of bytes needed to represent
|
||||
the length of the blob: 1, 2, 3, or 4.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_VAR_STRING</td><td>253</td>
|
||||
<td>2 bytes</td>
|
||||
<td>This is used to store both strings and enumeration values.
|
||||
The first byte is a enumeration value storing the <i>real
|
||||
type</i>, which may be either MYSQL_TYPE_VAR_STRING or
|
||||
MYSQL_TYPE_ENUM. The second byte is a 1 byte unsigned integer
|
||||
representing the field size, i.e., the number of bytes needed to
|
||||
store the length of the string.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_STRING</td><td>254</td>
|
||||
<td>2 bytes</td>
|
||||
<td>The first byte is always MYSQL_TYPE_VAR_STRING (i.e., 253).
|
||||
The second byte is the field size, i.e., the number of bytes in
|
||||
the representation of size of the string: 3 or 4.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>MYSQL_TYPE_GEOMETRY</td><td>255</td>
|
||||
<td>1 byte</td>
|
||||
<td>The pack length, i.e., the number of bytes needed to represent
|
||||
the length of the geometry: 1, 2, 3, or 4.</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
*/
|
||||
class Table_map_log_event : public Log_event
|
||||
{
|
||||
@ -3131,6 +3498,8 @@ protected:
|
||||
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
|
||||
int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
|
||||
&m_curr_row_end, &m_master_reclength);
|
||||
if (m_curr_row_end > m_rows_end)
|
||||
my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
|
||||
ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
|
||||
return result;
|
||||
}
|
||||
@ -3408,7 +3777,7 @@ protected:
|
||||
<caption>Incident event format</caption>
|
||||
<tr>
|
||||
<th>Symbol</th>
|
||||
<th>Size<br/>(bytes)</th>
|
||||
<th>Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -2078,7 +2078,7 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli,
|
||||
|
||||
/* fill table->record[0] with default values */
|
||||
|
||||
if ((error= prepare_record(rli, table, m_width,
|
||||
if ((error= prepare_record(table, m_width,
|
||||
TRUE /* check if columns have def. values */)))
|
||||
DBUG_RETURN(error);
|
||||
|
||||
@ -2289,7 +2289,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
|
||||
/* unpack row - missing fields get default values */
|
||||
|
||||
// TODO: shall we check and report errors here?
|
||||
prepare_record(NULL,table,m_width,FALSE /* don't check errors */);
|
||||
prepare_record(table, m_width, FALSE /* don't check errors */);
|
||||
error= unpack_current_row(rli);
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
|
@ -307,17 +307,15 @@ unpack_row(Relay_log_info const *rli,
|
||||
If @c check is true, fields are explicitly initialized only if they have
|
||||
default value or can be NULL. Otherwise error is reported.
|
||||
|
||||
@param log Used to report errors.
|
||||
@param table Table whose record[0] buffer is prepared.
|
||||
@param skip Number of columns for which default value initialization
|
||||
should be skipped.
|
||||
@param check Indicates if errors should be checked when setting default
|
||||
values.
|
||||
|
||||
@returns 0 on success.
|
||||
@returns 0 on success or a handler level error code
|
||||
*/
|
||||
int prepare_record(const Slave_reporting_capability *const log,
|
||||
TABLE *const table,
|
||||
int prepare_record(TABLE *const table,
|
||||
const uint skip, const bool check)
|
||||
{
|
||||
DBUG_ENTER("prepare_record");
|
||||
@ -337,14 +335,8 @@ int prepare_record(const Slave_reporting_capability *const log,
|
||||
|
||||
if (check && ((f->flags & mask) == mask))
|
||||
{
|
||||
DBUG_ASSERT(log);
|
||||
error= ER_NO_DEFAULT_FOR_FIELD;
|
||||
log->report(ERROR_LEVEL, error,
|
||||
"Field `%s` of table `%s`.`%s` "
|
||||
"has no default value and cannot be NULL",
|
||||
f->field_name, table->s->db.str,
|
||||
table->s->table_name.str);
|
||||
my_error(error, MYF(0), f->field_name);
|
||||
my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
|
||||
error = HA_ERR_ROWS_EVENT_APPLY;
|
||||
}
|
||||
else
|
||||
f->set_default();
|
||||
|
@ -30,8 +30,7 @@ int unpack_row(Relay_log_info const *rli,
|
||||
uchar const **const row_end, ulong *const master_reclength);
|
||||
|
||||
// Fill table's record[0] with default values.
|
||||
int prepare_record(const Slave_reporting_capability *const, TABLE *const,
|
||||
const uint =0, const bool =FALSE);
|
||||
int prepare_record(TABLE *const, const uint =0, const bool =FALSE);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -33,7 +33,10 @@ Relay_log_info::Relay_log_info()
|
||||
:Slave_reporting_capability("SQL"),
|
||||
no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id),
|
||||
info_fd(-1), cur_log_fd(-1), save_temporary_tables(0),
|
||||
group_relay_log_pos(0),
|
||||
group_relay_log_pos(0), event_relay_log_pos(0),
|
||||
#if HAVE_purify
|
||||
is_fake(FALSE),
|
||||
#endif
|
||||
cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0),
|
||||
ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
|
||||
abort_pos_wait(0), slave_run_id(0), sql_thd(0),
|
||||
|
@ -154,6 +154,10 @@ public:
|
||||
ulonglong event_relay_log_pos;
|
||||
ulonglong future_event_relay_log_pos;
|
||||
|
||||
#ifdef HAVE_purify
|
||||
bool is_fake; /* Mark that this is a fake relay log info structure */
|
||||
#endif
|
||||
|
||||
/*
|
||||
Original log name and position of the group we're currently executing
|
||||
(whose coordinates are group_relay_log_name/pos in the relay log)
|
||||
|
@ -6119,3 +6119,5 @@ ER_SLAVE_AMBIGOUS_EXEC_MODE
|
||||
|
||||
ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT
|
||||
eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement."
|
||||
ER_SLAVE_CORRUPT_EVENT
|
||||
eng "Corrupted replication event was detected"
|
||||
|
35
sql/slave.cc
35
sql/slave.cc
@ -1337,14 +1337,15 @@ bool show_master_info(THD* thd, Master_info* mi)
|
||||
protocol->prepare_for_resend();
|
||||
|
||||
/*
|
||||
TODO: we read slave_running without run_lock, whereas these variables
|
||||
are updated under run_lock and not data_lock. In 5.0 we should lock
|
||||
run_lock on top of data_lock (with good order).
|
||||
slave_running can be accessed without run_lock but not other
|
||||
non-volotile members like mi->io_thd, which is guarded by the mutex.
|
||||
*/
|
||||
pthread_mutex_lock(&mi->run_lock);
|
||||
protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
|
||||
pthread_mutex_unlock(&mi->run_lock);
|
||||
|
||||
pthread_mutex_lock(&mi->data_lock);
|
||||
pthread_mutex_lock(&mi->rli.data_lock);
|
||||
|
||||
protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
|
||||
protocol->store(mi->host, &my_charset_bin);
|
||||
protocol->store(mi->user, &my_charset_bin);
|
||||
protocol->store((uint32) mi->port);
|
||||
@ -1892,14 +1893,21 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
|
||||
if (exec_res == 0)
|
||||
{
|
||||
int error= ev->update_pos(rli);
|
||||
char buf[22];
|
||||
DBUG_PRINT("info", ("update_pos error = %d", error));
|
||||
DBUG_PRINT("info", ("group %s %s",
|
||||
llstr(rli->group_relay_log_pos, buf),
|
||||
rli->group_relay_log_name));
|
||||
DBUG_PRINT("info", ("event %s %s",
|
||||
llstr(rli->event_relay_log_pos, buf),
|
||||
rli->event_relay_log_name));
|
||||
#ifdef HAVE_purify
|
||||
if (!rli->is_fake)
|
||||
#endif
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
char buf[22];
|
||||
#endif
|
||||
DBUG_PRINT("info", ("update_pos error = %d", error));
|
||||
DBUG_PRINT("info", ("group %s %s",
|
||||
llstr(rli->group_relay_log_pos, buf),
|
||||
rli->group_relay_log_name));
|
||||
DBUG_PRINT("info", ("event %s %s",
|
||||
llstr(rli->event_relay_log_pos, buf),
|
||||
rli->event_relay_log_name));
|
||||
}
|
||||
/*
|
||||
The update should not fail, so print an error message and
|
||||
return an error code.
|
||||
@ -1909,6 +1917,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
|
||||
*/
|
||||
if (error)
|
||||
{
|
||||
char buf[22];
|
||||
rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
|
||||
"It was not possible to update the positions"
|
||||
" of the relay log information: the slave may"
|
||||
|
@ -80,8 +80,8 @@ class Master_info;
|
||||
mi->rli does not either.
|
||||
|
||||
In Master_info: run_lock, data_lock
|
||||
run_lock protects all information about the run state: slave_running, and the
|
||||
existence of the I/O thread (to stop/start it, you need this mutex).
|
||||
run_lock protects all information about the run state: slave_running, thd
|
||||
and the existence of the I/O thread to stop/start it, you need this mutex).
|
||||
data_lock protects some moving members of the struct: counters (log name,
|
||||
position) and relay log (MYSQL_BIN_LOG object).
|
||||
|
||||
|
@ -56,6 +56,9 @@ void mysql_client_binlog_statement(THD* thd)
|
||||
if (!thd->rli_fake)
|
||||
{
|
||||
thd->rli_fake= new Relay_log_info;
|
||||
#ifdef HAVE_purify
|
||||
thd->rli_fake->is_fake= TRUE;
|
||||
#endif
|
||||
have_fd_event= FALSE;
|
||||
}
|
||||
if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec)
|
||||
@ -152,14 +155,13 @@ void mysql_client_binlog_statement(THD* thd)
|
||||
*/
|
||||
if (!have_fd_event)
|
||||
{
|
||||
if (bufptr[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT)
|
||||
int type = bufptr[EVENT_TYPE_OFFSET];
|
||||
if (type == FORMAT_DESCRIPTION_EVENT || type == START_EVENT_V3)
|
||||
have_fd_event= TRUE;
|
||||
else
|
||||
{
|
||||
my_error(ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT,
|
||||
MYF(0),
|
||||
Log_event::get_type_str(
|
||||
(Log_event_type)bufptr[EVENT_TYPE_OFFSET]));
|
||||
MYF(0), Log_event::get_type_str((Log_event_type)type));
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user