Commit 81b1d712 authored by sven@riska.(none)'s avatar sven@riska.(none)

BUG#31168: @@hostname does not replicate

Problem: in mixed and statement mode, a query that refers to a
system variable will use the slave's value when replayed on
slave. So if the value of a system variable is inserted into a
table, the slave will differ from the master.
Fix: mark statements that refer to a system variable as "unsafe",
meaning they will be replicated by row in mixed mode and produce a warning
in statement mode. There are some exceptions: some variables are actually
replicated. Those should *not* be marked as unsafe.
BUG#34732: mysqlbinlog does not print default values for auto_increment variables
Problem: mysqlbinlog does not print default values for some variables,
including auto_increment_increment and others. So if a client executing
the output of mysqlbinlog has different default values, replication will
be wrong.
Fix: Always print default values for all variables that are replicated.
I need to fix the two bugs at the same time, because the test cases would
fail if I only fixed one of them.
parent 9c2ef837
...@@ -282,6 +282,7 @@ typedef struct charset_info_st ...@@ -282,6 +282,7 @@ typedef struct charset_info_st
MY_COLLATION_HANDLER *coll; MY_COLLATION_HANDLER *coll;
} CHARSET_INFO; } CHARSET_INFO;
#define ILLEGAL_CHARSET_INFO_NUMBER (~0U)
extern CHARSET_INFO my_charset_bin; extern CHARSET_INFO my_charset_bin;
......
...@@ -341,6 +341,14 @@ drop function if exists f1; ...@@ -341,6 +341,14 @@ drop function if exists f1;
drop procedure if exists p_verify_status_increment; drop procedure if exists p_verify_status_increment;
--enable_warnings --enable_warnings
# Save binlog_format in a user variable. References to system
# variables are "unsafe", meaning they are written as rows instead of
# as statements to the binlog, if the loggging mode is 'mixed'. But
# we don't want p_verify_status_increment to affect the logging mode.
# Hence, we save binlog_format in a user variable (which is not
# unsafe) and use that inside p_verify_status_increment.
set @binlog_format=@@global.binlog_format;
set sql_mode=no_engine_substitution; set sql_mode=no_engine_substitution;
create table t1 (a int unique); create table t1 (a int unique);
create table t2 (a int) engine=myisam; create table t2 (a int) engine=myisam;
...@@ -367,7 +375,7 @@ begin ...@@ -367,7 +375,7 @@ begin
where variable_name='Handler_commit' or variable_name='Handler_prepare' where variable_name='Handler_commit' or variable_name='Handler_prepare'
order by variable_name; order by variable_name;
if @@global.binlog_format = 'ROW' then if @binlog_format = 'ROW' then
set commit_inc= commit_inc_row; set commit_inc= commit_inc_row;
set prepare_inc= prepare_inc_row; set prepare_inc= prepare_inc_row;
else else
......
# ==== Purpose ====
#
# Check if the two given tables (possibly residing on different
# master/slave servers) are equal.
#
# ==== Usage ====
#
# The tables to check are given by the test language variables
# $diff_table_1 and $diff_table_2. They must be of the
# following form:
#
# [master:|slave:]database.table
#
# I.e., both database and table must be speicified. Optionally, you
# can prefix the name with 'master:' (to read the table on master) or
# with 'slave:' (to read the table on slave). If no prefix is given,
# reads the table from the current connection. If one of these
# variables has a prefix, both should have a prefix.
#
# ==== Side effects ====
#
# - Prints "Comparing tables $diff_table_1 and $diff_tables_2".
#
# - If the tables are different, prints the difference in a
# system-specific format (unified diff if supported) and generates
# an error.
#
# - If $diff_table_1 or $diff_table_2 begins with 'master:' or
# 'slave:', it will stay connected to one of those hosts after
# execution. The host is only guaranteed to remain unchanged if
# none of $diff_table_1 or $diff_table_2 begins with 'master:' or
# 'slave:'.
#
# ==== Bugs ====
#
# - It is currently not possible to use this for tables that are
# supposed to be different, because if the files are different:
# - 'diff' produces system-dependent output,
# - the output includes the absolute path of the compared files,
# - the output includes a timestamp.
# To fix that, we'd probably have to use SQL to compute the
# symmetric difference between the tables. I'm not sure how to do
# that efficiently. If we implement this, it would be nice to
# compare the table definitions too.
#
# - It actually compares the result of "SELECT * FROM table ORDER BY
# col1, col2, ..., colN INTO OUTFILE 'file'". Hence, it is assumed
# that the comparison orders for both tables are equal and that two
# rows that are equal in the comparison order cannot differ, e.g.,
# by character case.
# ==== Save both tables to file ====
--echo Comparing tables $diff_table_1 and $diff_table_2
disable_query_log;
--error 0,1
--remove_file $MYSQLTEST_VARDIR/tmp/diff_table_1
--error 0,1
--remove_file $MYSQLTEST_VARDIR/tmp/diff_table_2
let $_diff_table=$diff_table_2;
let $_diff_i=2;
while ($_diff_i) {
# Parse out any leading "master:" or "slave:" from the table
# specification and connect the appropriate server.
let $_diff_conn_master=`SELECT SUBSTR('$_diff_table', 1, 7) = 'master:'`;
if ($_diff_conn_master) {
let $_diff_table=`SELECT SUBSTR('$_diff_table', 8)`;
connection master;
}
let $_diff_conn_slave=`SELECT SUBSTR('$_diff_table', 1, 6) = 'slave:'`;
if ($_diff_conn_slave) {
let $_diff_table=`SELECT SUBSTR('$_diff_table', 7)`;
connection slave;
}
# Sanity-check the input.
let $_diff_error= `SELECT '$_diff_table' NOT LIKE '_%._%'`;
if ($_diff_error) {
--echo !!!ERROR IN TEST: \$diff_table_$_diff_i='$_diff_table' is not in the form database.table
exit;
}
# We need the output files to be sorted (so that diff_files does not
# think the files are different just because they are differently
# ordered). To this end, we first generate a query that sorts the
# table by all columns. Since ORDER BY accept column indices, we
# just generate a comma-separated list of all numbers from 1 to the
# number of columns in the table.
let $_diff_column_index=`SELECT MAX(ordinal_position)
FROM information_schema.columns
WHERE CONCAT(table_schema, '.', table_name) =
'$_diff_table'`;
let $_diff_column_list=$_diff_column_index;
dec $_diff_column_index;
while ($_diff_column_index) {
let $_diff_column_list=$_diff_column_index, $_diff_column_list;
dec $_diff_column_index;
}
# Now that we have the comma-separated list of columns, we can write
# the table to a file.
eval SELECT * FROM $_diff_table ORDER BY $_diff_column_list
INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/diff_table_$_diff_i';
# Do the same for $diff_table_1.
dec $_diff_i;
let $_diff_table=$diff_table_1;
}
# ==== Compare the generated files ====
diff_files $MYSQLTEST_VARDIR/tmp/diff_table_1 $MYSQLTEST_VARDIR/tmp/diff_table_2;
--remove_file $MYSQLTEST_VARDIR/tmp/diff_table_1
--remove_file $MYSQLTEST_VARDIR/tmp/diff_table_2
enable_query_log;
...@@ -331,6 +331,7 @@ drop table if exists t1; ...@@ -331,6 +331,7 @@ drop table if exists t1;
drop table if exists t2; drop table if exists t2;
drop function if exists f1; drop function if exists f1;
drop procedure if exists p_verify_status_increment; drop procedure if exists p_verify_status_increment;
set @binlog_format=@@global.binlog_format;
set sql_mode=no_engine_substitution; set sql_mode=no_engine_substitution;
create table t1 (a int unique); create table t1 (a int unique);
create table t2 (a int) engine=myisam; create table t2 (a int) engine=myisam;
...@@ -355,7 +356,7 @@ select variable_value ...@@ -355,7 +356,7 @@ select variable_value
from information_schema.session_status from information_schema.session_status
where variable_name='Handler_commit' or variable_name='Handler_prepare' where variable_name='Handler_commit' or variable_name='Handler_prepare'
order by variable_name; order by variable_name;
if @@global.binlog_format = 'ROW' then if @binlog_format = 'ROW' then
set commit_inc= commit_inc_row; set commit_inc= commit_inc_row;
set prepare_inc= prepare_inc_row; set prepare_inc= prepare_inc_row;
else else
......
...@@ -19,10 +19,14 @@ DELIMITER /*!*/; ...@@ -19,10 +19,14 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
drop table if exists t1,t2,t3,t4,t5,t03,t04 drop table if exists t1,t2,t3,t4,t5,t03,t04
/*!*/; /*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
...@@ -61,10 +65,14 @@ ROLLBACK /* added by mysqlbinlog */; ...@@ -61,10 +65,14 @@ ROLLBACK /* added by mysqlbinlog */;
DELIMITER /*!*/; DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
insert into t1 values ("Alas") insert into t1 values ("Alas")
/*!*/; /*!*/;
DELIMITER ; DELIMITER ;
...@@ -89,10 +97,14 @@ ROLLBACK /* added by mysqlbinlog */; ...@@ -89,10 +97,14 @@ ROLLBACK /* added by mysqlbinlog */;
DELIMITER /*!*/; DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
insert into t1 values ("Alas") insert into t1 values ("Alas")
/*!*/; /*!*/;
DELIMITER ; DELIMITER ;
...@@ -107,10 +119,14 @@ DELIMITER /*!*/; ...@@ -107,10 +119,14 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
drop table if exists t1,t2,t3,t4,t5,t03,t04 drop table if exists t1,t2,t3,t4,t5,t03,t04
/*!*/; /*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
...@@ -149,10 +165,14 @@ ROLLBACK /* added by mysqlbinlog */; ...@@ -149,10 +165,14 @@ ROLLBACK /* added by mysqlbinlog */;
DELIMITER /*!*/; DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
insert into t1 values ("Alas") insert into t1 values ("Alas")
/*!*/; /*!*/;
DELIMITER ; DELIMITER ;
...@@ -177,10 +197,14 @@ ROLLBACK /* added by mysqlbinlog */; ...@@ -177,10 +197,14 @@ ROLLBACK /* added by mysqlbinlog */;
DELIMITER /*!*/; DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
insert into t1 values ("Alas") insert into t1 values ("Alas")
/*!*/; /*!*/;
DELIMITER ; DELIMITER ;
...@@ -195,6 +219,10 @@ DELIMITER /*!*/; ...@@ -195,6 +219,10 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1108844556/*!*/; SET TIMESTAMP=1108844556/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN BEGIN
/*!*/; /*!*/;
SET TIMESTAMP=1108844555/*!*/; SET TIMESTAMP=1108844555/*!*/;
...@@ -209,6 +237,10 @@ ROLLBACK /* added by mysqlbinlog */; ...@@ -209,6 +237,10 @@ ROLLBACK /* added by mysqlbinlog */;
DELIMITER /*!*/; DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1108844556/*!*/; SET TIMESTAMP=1108844556/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN BEGIN
/*!*/; /*!*/;
SET TIMESTAMP=1108844555/*!*/; SET TIMESTAMP=1108844555/*!*/;
...@@ -265,10 +297,14 @@ ERROR 42000: PROCEDURE test.p1 does not exist ...@@ -265,10 +297,14 @@ ERROR 42000: PROCEDURE test.p1 does not exist
DELIMITER /*!*/; DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
CREATE DEFINER=`root`@`localhost` procedure p1() CREATE DEFINER=`root`@`localhost` procedure p1()
begin begin
select 1; select 1;
...@@ -311,10 +347,14 @@ flush logs; ...@@ -311,10 +347,14 @@ flush logs;
DELIMITER /*!*/; DELIMITER /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table t1 (a varchar(64) character set utf8) create table t1 (a varchar(64) character set utf8)
/*!*/; /*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
......
This diff is collapsed.
...@@ -21,10 +21,14 @@ ROLLBACK/*!*/; ...@@ -21,10 +21,14 @@ ROLLBACK/*!*/;
SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/; SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=10000/*!*/; SET TIMESTAMP=10000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
INSERT INTO t1 VALUES(@`a b`) INSERT INTO t1 VALUES(@`a b`)
/*!*/; /*!*/;
SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`/*!*/; SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`/*!*/;
......
...@@ -32,14 +32,17 @@ a ...@@ -32,14 +32,17 @@ a
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/; DELIMITER /*!*/;
# at 4 # at 4
#ROLLBACK/*!*/; <#>ROLLBACK/*!*/;
# at 102 # at 102
#use test/*!*/; <#>use test/*!*/;
SET TIMESTAMP=1196959712/*!*/; SET TIMESTAMP=1196959712/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; <#>SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table t1 (a int) engine= myisam create table t1 (a int) engine= myisam
/*!*/; /*!*/;
# at 203 # at 203
......
...@@ -15,10 +15,14 @@ ROLLBACK/*!*/; ...@@ -15,10 +15,14 @@ ROLLBACK/*!*/;
SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/; SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=10000/*!*/; SET TIMESTAMP=10000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
insert into t2 values (@v) insert into t2 values (@v)
/*!*/; /*!*/;
DELIMITER ; DELIMITER ;
......
SET BINLOG_FORMAT=STATEMENT; ==== Setup tables ====
CREATE TABLE t1 (a CHAR(40)); CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY); CREATE TABLE t2 (a CHAR(40));
CREATE TABLE t3 (b INT AUTO_INCREMENT PRIMARY KEY); CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY);
CREATE VIEW v1(a,b) AS SELECT a,b FROM t2,t3; CREATE TABLE trigger_table (a CHAR(7));
INSERT INTO t1 SELECT UUID(); CREATE TABLE trigger_table2 (a INT);
Warnings: ==== Non-deterministic statements ====
Warning 1592 Statement is not safe to log in statement format. INSERT DELAYED INTO t1 VALUES (5);
SHOW WARNINGS; ==== Some variables that *should* be unsafe ====
Level Warning ---- Insert directly ----
Code 1592 INSERT INTO t1 VALUES (@@global.sync_binlog);
Message Statement is not safe to log in statement format. Warnings:
DROP TABLE t1,t2,t3; Warning 1592 Statement is not safe to log in statement format.
INSERT INTO t1 VALUES (@@session.insert_id);
Warnings:
Warning 1592 Statement is not safe to log in statement format.
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
Warnings:
Warning 1592 Statement is not safe to log in statement format.
INSERT INTO t2 SELECT UUID();
Warnings:
Warning 1592 Statement is not safe to log in statement format.
INSERT INTO t2 VALUES (@@global.init_slave);
Warnings:
Warning 1592 Statement is not safe to log in statement format.
INSERT INTO t2 VALUES (@@hostname);
Warnings:
Warning 1592 Statement is not safe to log in statement format.
---- Insert from stored procedure ----
CREATE PROCEDURE proc()
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
CALL proc();
Warnings:
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
---- Insert from stored function ----
CREATE FUNCTION func()
RETURNS INT
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
RETURN 0;
END|
SELECT func();
func()
0
Warnings:
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
---- Insert from trigger ----
CREATE TRIGGER trig
BEFORE INSERT ON trigger_table
FOR EACH ROW
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
INSERT INTO trigger_table VALUES ('bye.');
Warnings:
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
---- Insert from prepared statement ----
PREPARE p1 FROM 'INSERT INTO t1 VALUES (@@global.sync_binlog)';
PREPARE p2 FROM 'INSERT INTO t1 VALUES (@@session.insert_id)';
PREPARE p3 FROM 'INSERT INTO t1 VALUES (@@global.auto_increment_increment)';
PREPARE p4 FROM 'INSERT INTO t2 SELECT UUID()';
PREPARE p5 FROM 'INSERT INTO t2 VALUES (@@global.init_slave)';
PREPARE p6 FROM 'INSERT INTO t2 VALUES (@@hostname)';
EXECUTE p1;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
EXECUTE p2;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
EXECUTE p3;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
EXECUTE p4;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
EXECUTE p5;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
EXECUTE p6;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
---- Insert from nested call of triggers / functions / procedures ----
CREATE PROCEDURE proc1()
INSERT INTO trigger_table VALUES ('ha!')|
CREATE FUNCTION func2()
RETURNS INT
BEGIN
CALL proc1();
RETURN 0;
END|
CREATE TRIGGER trig3
BEFORE INSERT ON trigger_table2
FOR EACH ROW
BEGIN
DECLARE tmp INT;
SELECT func2() INTO tmp;
END|
CREATE PROCEDURE proc4()
INSERT INTO trigger_table2 VALUES (1)|
CREATE FUNCTION func5()
RETURNS INT
BEGIN
CALL proc4;
RETURN 0;
END|
PREPARE prep6 FROM 'SELECT func5()'|
EXECUTE prep6;
func5()
0
Warnings:
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format.
==== Variables that should *not* be unsafe ====
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.foreign_key_checks);
INSERT INTO t1 VALUES (@@session.sql_auto_is_null);
INSERT INTO t1 VALUES (@@session.unique_checks);
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t1 VALUES (@@session.auto_increment_increment);
INSERT INTO t1 VALUES (@@session.auto_increment_offset);
INSERT INTO t2 VALUES (@@session.character_set_client);
INSERT INTO t2 VALUES (@@session.collation_connection);
INSERT INTO t2 VALUES (@@session.collation_server);
INSERT INTO t2 VALUES (@@session.time_zone);
INSERT INTO t2 VALUES (@@session.lc_time_names);
INSERT INTO t2 VALUES (@@session.collation_database);
INSERT INTO t2 VALUES (@@session.timestamp);
INSERT INTO t2 VALUES (@@session.last_insert_id);
SET @my_var= 4711;
INSERT INTO t1 VALUES (@my_var);
SET insert_id=12;
INSERT INTO t3 VALUES (NULL);
==== Clean up ====
DROP PROCEDURE proc;
DROP FUNCTION func;
DROP TRIGGER trig;
DROP PROCEDURE proc1;
DROP FUNCTION func2;
DROP TRIGGER trig3;
DROP PROCEDURE proc4;
DROP FUNCTION func5;
DROP PREPARE prep6;
DROP TABLE t1, t2, t3, trigger_table, trigger_table2;
DROP VIEW v1; DROP VIEW v1;
...@@ -70,7 +70,7 @@ select * from t1; ...@@ -70,7 +70,7 @@ select * from t1;
--echo ==== Test --base64-output=never on a binlog with row events ==== --echo ==== Test --base64-output=never on a binlog with row events ====
# mysqlbinlog should fail # mysqlbinlog should fail
--replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] .*/#/ --replace_regex /#[0-9][0-9][0-9][0-9][0-9][0-9] .*/<#>/ /SET \@\@session.pseudo_thread_id.*/<#>/
error 1; error 1;
exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/bug32407.001; exec $MYSQL_BINLOG --base64-output=never suite/binlog/std_data/bug32407.001;
# the above line should output the query log event and then stop # the above line should output the query log event and then stop
......
# Test to check that a warning is generated for unsafe statements # ==== Purpose ====
# executed under statement mode logging. #
# Some statements can not be written to the binlog in a safe manner
# with statement-based replication, either because they rely on
# features that are local to the server they are replicated from
# (e.g., @@variables), or because they include nondeterministic
# queries (e.g., LIMIT), or because the time at which the query is
# executed cannot be determined (e.g., INSERT DELAYED). Such
# statements should be marked unsafe. All unsafe statements should
# give a warning.
#
# This test verifies that a warning is generated for statements that
# should be unsafe, when they are executed under statement mode
# logging.
#
# All variables should be unsafe, with some exceptions. Therefore,
# this test also verifies that the exceptions do *not* generare a
# warning.
#
#
# ==== Method ====
#
# We try an INSERT DELAYED statement and verify that a warning is
# issued.
#
# We try to insert unsafe variables into a table in several ways:
# directly with an INSERT statement, from a stored procedure, from a
# stored function, from a trigger, from a prepared statement, and from
# a complicated nesting of triggers, functions, procedures, and
# prepared statements. In all cases, a warning should be issued.
#
# We try to insert the variables that should not be unsafe into a
# table, and verify that *no* warning is issued.
#
#
# ==== Related bugs and worklogs ====
#
# WL#3339: Issue warnings when statement-based replication may fail
# BUG#31168: @@hostname does not replicate
# BUG#34732: mysqlbinlog does not print default values for auto_increment variables
# BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed
#
#
# ==== Related test cases ====
#
# rpl.rpl_variables verifies that variables which cannot be replicated
# safely in statement mode are replicated correctly in mixed or row
# mode.
#
# rpl.rpl_variables_stm tests the small subset of variables that
# actually can be replicated safely in statement mode.
#
#
# ==== Todo ====
#
# There are several other ways to create unsafe statements: see, e.g.,
# WL#3339, BUG#34768.
source include/have_log_bin.inc; source include/have_log_bin.inc;
source include/have_binlog_format_statement.inc;
SET BINLOG_FORMAT=STATEMENT; --echo ==== Setup tables ====
CREATE TABLE t1 (a CHAR(40)); CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY); CREATE TABLE t2 (a CHAR(40));
CREATE TABLE t3 (b INT AUTO_INCREMENT PRIMARY KEY); CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY);
CREATE VIEW v1(a,b) AS SELECT a,b FROM t2,t3; CREATE TABLE trigger_table (a CHAR(7));
CREATE TABLE trigger_table2 (a INT);
INSERT INTO t1 SELECT UUID();
query_vertical SHOW WARNINGS;
DROP TABLE t1,t2,t3; --echo ==== Non-deterministic statements ====
DROP VIEW v1;
INSERT DELAYED INTO t1 VALUES (5);
--echo ==== Some variables that *should* be unsafe ====
--echo ---- Insert directly ----
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
--echo ---- Insert from stored procedure ----
DELIMITER |;
CREATE PROCEDURE proc()
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
DELIMITER ;|
CALL proc();
--echo ---- Insert from stored function ----
DELIMITER |;
CREATE FUNCTION func()
RETURNS INT
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
RETURN 0;
END|
DELIMITER ;|
SELECT func();
--echo ---- Insert from trigger ----
DELIMITER |;
CREATE TRIGGER trig
BEFORE INSERT ON trigger_table
FOR EACH ROW
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
DELIMITER ;|
INSERT INTO trigger_table VALUES ('bye.');
--echo ---- Insert from prepared statement ----
PREPARE p1 FROM 'INSERT INTO t1 VALUES (@@global.sync_binlog)';
PREPARE p2 FROM 'INSERT INTO t1 VALUES (@@session.insert_id)';
PREPARE p3 FROM 'INSERT INTO t1 VALUES (@@global.auto_increment_increment)';
PREPARE p4 FROM 'INSERT INTO t2 SELECT UUID()';
PREPARE p5 FROM 'INSERT INTO t2 VALUES (@@global.init_slave)';
PREPARE p6 FROM 'INSERT INTO t2 VALUES (@@hostname)';
EXECUTE p1; EXECUTE p2; EXECUTE p3; EXECUTE p4; EXECUTE p5; EXECUTE p6;
--echo ---- Insert from nested call of triggers / functions / procedures ----
DELIMITER |;
# proc1: cause trigger 'trig' above to be triggered.
CREATE PROCEDURE proc1()
INSERT INTO trigger_table VALUES ('ha!')|
# func2: call proc1 above.
CREATE FUNCTION func2()
RETURNS INT
BEGIN
CALL proc1();
RETURN 0;
END|
# trig3: call func2 above
CREATE TRIGGER trig3
BEFORE INSERT ON trigger_table2
FOR EACH ROW
BEGIN
DECLARE tmp INT;
SELECT func2() INTO tmp;
END|
# proc4: cause trig3 above to be triggered.
CREATE PROCEDURE proc4()
INSERT INTO trigger_table2 VALUES (1)|
# func5: call proc4 above.
CREATE FUNCTION func5()
RETURNS INT
BEGIN
CALL proc4;
RETURN 0;
END|
# prep6: call func5() above.
PREPARE prep6 FROM 'SELECT func5()'|
DELIMITER ;|
# try a complicated call path to trigger 'trig'.
EXECUTE prep6;
--echo ==== Variables that should *not* be unsafe ====
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.foreign_key_checks);
INSERT INTO t1 VALUES (@@session.sql_auto_is_null);
INSERT INTO t1 VALUES (@@session.unique_checks);
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t1 VALUES (@@session.auto_increment_increment);
INSERT INTO t1 VALUES (@@session.auto_increment_offset);
INSERT INTO t2 VALUES (@@session.character_set_client);
INSERT INTO t2 VALUES (@@session.collation_connection);
INSERT INTO t2 VALUES (@@session.collation_server);
INSERT INTO t2 VALUES (@@session.time_zone);
INSERT INTO t2 VALUES (@@session.lc_time_names);
INSERT INTO t2 VALUES (@@session.collation_database);
INSERT INTO t2 VALUES (@@session.timestamp);
INSERT INTO t2 VALUES (@@session.last_insert_id);
SET @my_var= 4711;
INSERT INTO t1 VALUES (@my_var);
# using insert_id implicitly should be ok.
SET insert_id=12;
INSERT INTO t3 VALUES (NULL);
--echo ==== Clean up ====
DROP PROCEDURE proc;
DROP FUNCTION func;
DROP TRIGGER trig;
DROP PROCEDURE proc1;
DROP FUNCTION func2;
DROP TRIGGER trig3;
DROP PROCEDURE proc4;
DROP FUNCTION func5;
DROP PREPARE prep6;
DROP TABLE t1, t2, t3, trigger_table, trigger_table2;
...@@ -158,10 +158,14 @@ DELIMITER /*!*/; ...@@ -158,10 +158,14 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT) CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT)
/*!*/; /*!*/;
DELIMITER ; DELIMITER ;
...@@ -176,10 +180,14 @@ DELIMITER /*!*/; ...@@ -176,10 +180,14 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
DROP TABLE IF EXISTS t1,t2,t3 DROP TABLE IF EXISTS t1,t2,t3
/*!*/; /*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
...@@ -281,10 +289,14 @@ DELIMITER /*!*/; ...@@ -281,10 +289,14 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
DROP TABLE IF EXISTS t1,t2,t3 DROP TABLE IF EXISTS t1,t2,t3
/*!*/; /*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
...@@ -308,10 +320,14 @@ DELIMITER /*!*/; ...@@ -308,10 +320,14 @@ DELIMITER /*!*/;
ROLLBACK/*!*/; ROLLBACK/*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
SET @@session.pseudo_thread_id=999999999/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/; SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/; /*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT) CREATE TABLE t3(c1 INT NOT NULL PRIMARY KEY, c2 LONGBLOB, c3 TIMESTAMP, c4 TEXT, c5 FLOAT)
/*!*/; /*!*/;
DELIMITER ; DELIMITER ;
......
...@@ -4,31 +4,33 @@ reset master; ...@@ -4,31 +4,33 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
==== Test Without sql_mode=strict_trans_tables ====
[on master]
create table t1 (n int not null primary key); create table t1 (n int not null primary key);
[on slave]
insert into t1 values (1); insert into t1 values (1);
[on master]
insert into t1 values (1); insert into t1 values (1);
insert into t1 values (2),(3); insert into t1 values (2),(3);
[on slave]
select * from t1 ORDER BY n; select * from t1 ORDER BY n;
n n
1 1
2 2
3 3
drop table t1; ==== Test With sql_mode=strict_trans_tables ====
create table t1(a int primary key); insert into t1 values (7), (8);
insert into t1 values (1),(2); [on master]
delete from t1 where @@server_id=1;
set sql_mode=strict_trans_tables; set sql_mode=strict_trans_tables;
select @@server_id; insert into t1 values (7), (8), (9);
@@server_id [on slave]
1
insert into t1 values (1),(2),(3);
select @@server_id;
@@server_id
2
select * from t1; select * from t1;
a n
1 1
2 2
3
7
8
SHOW SLAVE STATUS; SHOW SLAVE STATUS;
Slave_IO_State # Slave_IO_State #
Master_Host 127.0.0.1 Master_Host 127.0.0.1
...@@ -68,4 +70,5 @@ Last_IO_Errno # ...@@ -68,4 +70,5 @@ Last_IO_Errno #
Last_IO_Error # Last_IO_Error #
Last_SQL_Errno 0 Last_SQL_Errno 0
Last_SQL_Error Last_SQL_Error
==== Clean Up ====
drop table t1; drop table t1;
This diff is collapsed.
This diff is collapsed.
########################################## # ==== Purpose ====
# 2006-02-07 By JBM: Added order by #
######################################### # Verify that --slave-skip-errors works correctly. The error messages
# Note that errors are ignored by opt file. # specified by --slave-skip-errors on slave should be ignored. If
# such errors occur, they should not be reported and not cause the
# slave to stop.
#
# ==== Method ====
#
# We run the slave with --slave-skip-errors=1062 (the code for
# duplicate key). On slave, we insert value 1 in a table, and then,
# on master, we insert value 1 in the table. The error should be
# ignored on slave.
#
# ==== Related bugs ====
#
# BUG#28839: Errors in strict mode silently stop SQL thread if --slave-skip-errors exists
# bug in this test: BUG#30594: rpl.rpl_skip_error is nondeterministic
source include/master-slave.inc; source include/master-slave.inc;
source include/have_binlog_format_mixed_or_statement.inc; source include/have_binlog_format_mixed_or_statement.inc;
#
# Bug #30594
# Skipping error due to applying Row-based repliation events
# should be checked with another test file
# consider names like rpl_row_skip_error
#
--echo ==== Test Without sql_mode=strict_trans_tables ====
--echo [on master]
create table t1 (n int not null primary key); create table t1 (n int not null primary key);
save_master_pos;
connection slave; --echo [on slave]
sync_with_master; sync_slave_with_master;
insert into t1 values (1); insert into t1 values (1);
--echo [on master]
connection master; connection master;
# Here we expect (ignored) error, since 1 is already in slave table # Here we expect (ignored) error, since 1 is already in slave table
insert into t1 values (1); insert into t1 values (1);
# These should work fine # These should work fine
insert into t1 values (2),(3); insert into t1 values (2),(3);
save_master_pos; --echo [on slave]
connection slave; sync_slave_with_master;
sync_with_master;
select * from t1 ORDER BY n; select * from t1 ORDER BY n;
# Cleanup
connection master;
drop table t1;
sync_slave_with_master;
# End of 4.1 tests --echo ==== Test With sql_mode=strict_trans_tables ====
# insert into t1 values (7), (8);
# #28839 Errors in strict mode silently stop SQL thread if --slave-skip-errors exists
# --echo [on master]
connection master; connection master;
create table t1(a int primary key);
insert into t1 values (1),(2);
delete from t1 where @@server_id=1;
set sql_mode=strict_trans_tables; set sql_mode=strict_trans_tables;
select @@server_id; insert into t1 values (7), (8), (9);
insert into t1 values (1),(2),(3);
--echo [on slave]
sync_slave_with_master; sync_slave_with_master;
connection slave;
select @@server_id;
select * from t1; select * from t1;
source include/show_slave_status2.inc; source include/show_slave_status2.inc;
--echo ==== Clean Up ====
connection master; connection master;
drop table t1; drop table t1;
sync_with_master; sync_slave_with_master;
# End of 5.0 tests # End of 5.0 tests
This diff is collapsed.
This diff is collapsed.
...@@ -41,8 +41,7 @@ select "--- Local --" as ""; ...@@ -41,8 +41,7 @@ select "--- Local --" as "";
# be time dependent (the Start events). Better than nothing. # be time dependent (the Start events). Better than nothing.
# #
--replace_regex /[[:<:]][0-9]{6} [0-9 ][0-9]:[0-9]{2}:[0-9]{2}[[:>:]]/{yymmdd} {HH:MM:SS}/ /=[0-9]+ /={integer} / /# at [0-9]+/# at {pos}/ /(pos:?) [0-9]+/\1 {pos}/ /binlog v [0-9]+, server v [^ ]* created/binlog v #, server v ## created/ --exec $MYSQL_BINLOG --short-form --base64-output=never $MYSQLTEST_VARDIR/log/master-bin.000001
--exec $MYSQL_BINLOG --base64-output=never $MYSQLTEST_VARDIR/log/master-bin.000001
--disable_query_log --disable_query_log
select "--- offset --" as ""; select "--- offset --" as "";
......
...@@ -4789,6 +4789,12 @@ Item_func_get_system_var::fix_fields(THD *thd, Item **ref) ...@@ -4789,6 +4789,12 @@ Item_func_get_system_var::fix_fields(THD *thd, Item **ref)
} }
bool Item_func_get_system_var::is_written_to_binlog()
{
return var->is_written_to_binlog(var_type);
}
longlong Item_func_inet_aton::val_int() longlong Item_func_inet_aton::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
......
...@@ -1435,6 +1435,15 @@ public: ...@@ -1435,6 +1435,15 @@ public:
void fix_length_and_dec() { DBUG_ASSERT(0); } void fix_length_and_dec() { DBUG_ASSERT(0); }
/* TODO: fix to support views */ /* TODO: fix to support views */
const char *func_name() const { return "get_system_var"; } const char *func_name() const { return "get_system_var"; }
/**
Indicates whether this system variable is written to the binlog or not.
Variables are written to the binlog as part of "status_vars" in
Query_log_event, as an Intvar_log_event, or a Rand_log_event.
@return true if the variable is written to the binlog, false otherwise.
*/
bool is_written_to_binlog();
}; };
......
...@@ -14,7 +14,11 @@ ...@@ -14,7 +14,11 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef MYSQL_CLIENT #ifdef MYSQL_CLIENT
#include "mysql_priv.h"
#else
#ifdef USE_PRAGMA_IMPLEMENTATION #ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation #pragma implementation // gcc: Class implementation
...@@ -28,7 +32,9 @@ ...@@ -28,7 +32,9 @@
#include "rpl_utility.h" #include "rpl_utility.h"
#include "rpl_record.h" #include "rpl_record.h"
#include <my_dir.h> #include <my_dir.h>
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
#include <base64.h> #include <base64.h>
#include <my_bitmap.h> #include <my_bitmap.h>
...@@ -1589,7 +1595,7 @@ bool Query_log_event::write(IO_CACHE* file) ...@@ -1589,7 +1595,7 @@ bool Query_log_event::write(IO_CACHE* file)
recognize Q_CATALOG_CODE and have no problem. recognize Q_CATALOG_CODE and have no problem.
*/ */
} }
if (auto_increment_increment != 1) if (auto_increment_increment != 1 || auto_increment_offset != 1)
{ {
*start++= Q_AUTO_INCREMENT; *start++= Q_AUTO_INCREMENT;
int2store(start, auto_increment_increment); int2store(start, auto_increment_increment);
...@@ -2102,9 +2108,17 @@ void Query_log_event::print_query_header(IO_CACHE* file, ...@@ -2102,9 +2108,17 @@ void Query_log_event::print_query_header(IO_CACHE* file,
end= strmov(end, print_event_info->delimiter); end= strmov(end, print_event_info->delimiter);
*end++='\n'; *end++='\n';
my_b_write(file, (uchar*) buff, (uint) (end-buff)); my_b_write(file, (uchar*) buff, (uint) (end-buff));
if (flags & LOG_EVENT_THREAD_SPECIFIC_F) if ((!print_event_info->thread_id_printed ||
((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
thread_id != print_event_info->thread_id)))
{
// If --short-form, print deterministic value instead of pseudo_thread_id.
my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n", my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
(ulong)thread_id, print_event_info->delimiter); short_form ? 999999999 : (ulong)thread_id,
print_event_info->delimiter);
print_event_info->thread_id= thread_id;
print_event_info->thread_id_printed= 1;
}
/* /*
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
...@@ -2151,20 +2165,14 @@ void Query_log_event::print_query_header(IO_CACHE* file, ...@@ -2151,20 +2165,14 @@ void Query_log_event::print_query_header(IO_CACHE* file,
gracefully). So this code should always be good. gracefully). So this code should always be good.
*/ */
if (likely(sql_mode_inited)) if (likely(sql_mode_inited) &&
{ (unlikely(print_event_info->sql_mode != sql_mode ||
if (unlikely(!print_event_info->sql_mode_inited)) /* first Query event */ !print_event_info->sql_mode_inited)))
{
print_event_info->sql_mode_inited= 1;
/* force a difference to force write */
print_event_info->sql_mode= ~sql_mode;
}
if (unlikely(print_event_info->sql_mode != sql_mode))
{ {
my_b_printf(file,"SET @@session.sql_mode=%lu%s\n", my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
(ulong)sql_mode, print_event_info->delimiter); (ulong)sql_mode, print_event_info->delimiter);
print_event_info->sql_mode= sql_mode; print_event_info->sql_mode= sql_mode;
} print_event_info->sql_mode_inited= 1;
} }
if (print_event_info->auto_increment_increment != auto_increment_increment || if (print_event_info->auto_increment_increment != auto_increment_increment ||
print_event_info->auto_increment_offset != auto_increment_offset) print_event_info->auto_increment_offset != auto_increment_offset)
...@@ -2178,14 +2186,9 @@ void Query_log_event::print_query_header(IO_CACHE* file, ...@@ -2178,14 +2186,9 @@ void Query_log_event::print_query_header(IO_CACHE* file,
/* TODO: print the catalog when we feature SET CATALOG */ /* TODO: print the catalog when we feature SET CATALOG */
if (likely(charset_inited)) if (likely(charset_inited) &&
{ (unlikely(!print_event_info->charset_inited ||
if (unlikely(!print_event_info->charset_inited)) /* first Query event */ bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
{
print_event_info->charset_inited= 1;
print_event_info->charset[0]= ~charset[0]; // force a difference to force write
}
if (unlikely(bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6)))
{ {
CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME)); CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
if (cs_info) if (cs_info)
...@@ -2204,7 +2207,7 @@ void Query_log_event::print_query_header(IO_CACHE* file, ...@@ -2204,7 +2207,7 @@ void Query_log_event::print_query_header(IO_CACHE* file,
uint2korr(charset+4), uint2korr(charset+4),
print_event_info->delimiter); print_event_info->delimiter);
memcpy(print_event_info->charset, charset, 6); memcpy(print_event_info->charset, charset, 6);
} print_event_info->charset_inited= 1;
} }
if (time_zone_len) if (time_zone_len)
{ {
...@@ -8631,3 +8634,34 @@ Incident_log_event::write_data_body(IO_CACHE *file) ...@@ -8631,3 +8634,34 @@ Incident_log_event::write_data_body(IO_CACHE *file)
DBUG_ENTER("Incident_log_event::write_data_body"); DBUG_ENTER("Incident_log_event::write_data_body");
DBUG_RETURN(write_str(file, m_message.str, m_message.length)); DBUG_RETURN(write_str(file, m_message.str, m_message.length));
} }
#ifdef MYSQL_CLIENT
/**
The default values for these variables should be values that are
*incorrect*, i.e., values that cannot occur in an event. This way,
they will always be printed for the first event.
*/
st_print_event_info::st_print_event_info()
:flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
lc_time_names_number(~0),
charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
thread_id(0), thread_id_printed(false),
base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE)
{
/*
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
program's startup, but these explicit bzero() is for the day someone
creates dynamic instances.
*/
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
delimiter[0]= ';';
delimiter[1]= 0;
myf const flags = MYF(MY_WME | MY_NABP);
open_cached_file(&head_cache, NULL, NULL, 0, flags);
open_cached_file(&body_cache, NULL, NULL, 0, flags);
}
#endif
...@@ -592,7 +592,8 @@ typedef struct st_print_event_info ...@@ -592,7 +592,8 @@ typedef struct st_print_event_info
{ {
/* /*
Settings for database, sql_mode etc that comes from the last event Settings for database, sql_mode etc that comes from the last event
that was printed. that was printed. We cache these so that we don't have to print
them if they are unchanged.
*/ */
// TODO: have the last catalog here ?? // TODO: have the last catalog here ??
char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is
...@@ -606,26 +607,10 @@ typedef struct st_print_event_info ...@@ -606,26 +607,10 @@ typedef struct st_print_event_info
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
uint lc_time_names_number; uint lc_time_names_number;
uint charset_database_number; uint charset_database_number;
st_print_event_info() uint thread_id;
:flags2_inited(0), sql_mode_inited(0), bool thread_id_printed;
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0),
lc_time_names_number(0), charset_database_number(0), st_print_event_info();
base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE)
{
/*
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
program's startup, but these explicit bzero() is for the day someone
creates dynamic instances.
*/
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
delimiter[0]= ';';
delimiter[1]= 0;
myf const flags = MYF(MY_WME | MY_NABP);
open_cached_file(&head_cache, NULL, NULL, 0, flags);
open_cached_file(&body_cache, NULL, NULL, 0, flags);
}
~st_print_event_info() { ~st_print_event_info() {
close_cached_file(&head_cache); close_cached_file(&head_cache);
......
This diff is collapsed.
This diff is collapsed.
...@@ -7389,6 +7389,7 @@ variable_aux: ...@@ -7389,6 +7389,7 @@ variable_aux:
} }
| '@' opt_var_ident_type ident_or_text opt_component | '@' opt_var_ident_type ident_or_text opt_component
{ {
/* disallow "SELECT @@global.global.variable" */
if ($3.str && $4.str && check_reserved_words(&$3)) if ($3.str && $4.str && check_reserved_words(&$3))
{ {
my_parse_error(ER(ER_SYNTAX_ERROR)); my_parse_error(ER(ER_SYNTAX_ERROR));
...@@ -7396,6 +7397,8 @@ variable_aux: ...@@ -7396,6 +7397,8 @@ variable_aux:
} }
if (!($$= get_system_var(YYTHD, $2, $3, $4))) if (!($$= get_system_var(YYTHD, $2, $3, $4)))
MYSQL_YYABORT; MYSQL_YYABORT;
if (!((Item_func_get_system_var*) $$)->is_written_to_binlog())
Lex->set_stmt_unsafe();
} }
; ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment