Skip to content

Commit 440d8c3

Browse files
committed
Bug#33945038: SQL mode is sometimes over-written in row based replication
Merge branch 'mysql-8.0' into mysql-trunk
2 parents 6c30699 + 5ef8fe8 commit 440d8c3

File tree

3 files changed

+137
-1
lines changed

3 files changed

+137
-1
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
include/master-slave.inc
2+
Warnings:
3+
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4+
Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
5+
[connection master]
6+
7+
##############################################################
8+
# 1. Create a table where a generated column has the type TIME
9+
[connection master]
10+
CREATE TABLE t1 (
11+
first DOUBLE,
12+
gen_col TIME(1) GENERATED ALWAYS AS (`first`) VIRTUAL,
13+
KEY (gen_col)
14+
) ENGINE=InnoDB;
15+
16+
##############################################################
17+
# 2. Change the source SQL mode to 'TIME_TRUNCATE_FRACTIONAL'
18+
SET sql_mode='TIME_TRUNCATE_FRACTIONAL';
19+
20+
##############################################################
21+
# 3. Insert data on the source being the value of the generated column dependent on the SQL mode
22+
INSERT INTO t1 (first) VALUES(1.55);
23+
24+
##############################################################
25+
# 4. Delete the row on the source and verify it was deleted on the replica
26+
DELETE FROM t1 WHERE gen_col="00:00:01.5";
27+
include/sync_slave_sql_with_master.inc
28+
[connection slave]
29+
include/assert.inc [The data on the replica was deleted]
30+
31+
##############################################################
32+
# 5. Cleanup
33+
[connection master]
34+
DROP TABLE t1;
35+
include/rpl_end.inc
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# === Purpose ===
2+
#
3+
# This test verifies that changes to the SQL mode are also replicated
4+
# ensuring the replica has the same data as the source
5+
#
6+
# ==== Requirements ====
7+
#
8+
# R1. When use row based replication, the SQL mode from the source should also
9+
# be used on the replica
10+
#
11+
# === Implementation ====
12+
#
13+
# 1. Create a table where a generated column has the type TIME
14+
# 2. Change the source SQL mode to 'TIME_TRUNCATE_FRACTIONAL'
15+
# 3. Insert data on the source being the value of the generated column dependent on the SQL mode
16+
# 4. Delete the row on the source and verify it was deleted on the replica
17+
# 5. Cleanup
18+
#
19+
# === References ===
20+
#
21+
# Bug #33945038: SQL mode is sometimes over-written in row based replication
22+
#
23+
24+
--source include/have_binlog_format_row.inc
25+
--source include/master-slave.inc
26+
27+
--echo
28+
--echo ##############################################################
29+
--echo # 1. Create a table where a generated column has the type TIME
30+
31+
--source include/rpl_connection_master.inc
32+
33+
CREATE TABLE t1 (
34+
first DOUBLE,
35+
gen_col TIME(1) GENERATED ALWAYS AS (`first`) VIRTUAL,
36+
KEY (gen_col)
37+
) ENGINE=InnoDB;
38+
39+
40+
--echo
41+
--echo ##############################################################
42+
--echo # 2. Change the source SQL mode to 'TIME_TRUNCATE_FRACTIONAL'
43+
44+
#
45+
# To understand what is the effect of this mode, here is the docs example
46+
#
47+
# CREATE TABLE t (id INT, tval TIME(1));
48+
# SET sql_mode='';
49+
# INSERT INTO t (id, tval) VALUES(1, 1.55);
50+
# SET sql_mode='TIME_TRUNCATE_FRACTIONAL';
51+
# INSERT INTO t (id, tval) VALUES(2, 1.55);
52+
#
53+
# mysql> SELECT id, tval FROM t ORDER BY id;
54+
# +------+------------+
55+
# | id | tval |
56+
# +------+------------+
57+
# | 1 | 00:00:01.6 |
58+
# | 2 | 00:00:01.5 |
59+
# +------+------------+
60+
#
61+
62+
SET sql_mode='TIME_TRUNCATE_FRACTIONAL';
63+
64+
--echo
65+
--echo ##############################################################
66+
--echo # 3. Insert data on the source being the value of the generated column dependent on the SQL mode
67+
68+
INSERT INTO t1 (first) VALUES(1.55);
69+
70+
--echo
71+
--echo ##############################################################
72+
--echo # 4. Delete the row on the source and verify it was deleted on the replica
73+
74+
DELETE FROM t1 WHERE gen_col="00:00:01.5";
75+
76+
--source include/sync_slave_sql_with_master.inc
77+
78+
--source include/rpl_connection_slave.inc
79+
80+
#
81+
# To understand what divergences in SQL mode would do:
82+
# When inserted in the replica the row will be indexed to the value of `gen_col`
83+
#`When deleted, the replica will search for the value of "00:00:01.5", but
84+
# the table index would have the value "00:00:01.6" if the sql mode was different.
85+
# The delete would not find the row and no data would be removed in the replica.
86+
#
87+
88+
--let $table_data_count = `SELECT COUNT(*) FROM t1`
89+
--let $assert_text= The data on the replica was deleted
90+
--let $assert_cond= $table_data_count = 0
91+
--source include/assert.inc
92+
93+
--echo
94+
--echo ##############################################################
95+
--echo # 5. Cleanup
96+
97+
--source include/rpl_connection_master.inc
98+
99+
DROP TABLE t1;
100+
101+
--source include/rpl_end.inc

sql/log_event.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9931,7 +9931,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) {
99319931
*/
99329932
sql_mode_t saved_sql_mode = thd->variables.sql_mode;
99339933
if (!is_auto_inc_in_extra_columns())
9934-
thd->variables.sql_mode = MODE_NO_AUTO_VALUE_ON_ZERO;
9934+
thd->variables.sql_mode |= MODE_NO_AUTO_VALUE_ON_ZERO;
99359935

99369936
// row processing loop
99379937

0 commit comments

Comments
 (0)