Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions mysql-test/suite/rpl/r/rpl_default_functions_explicit_null.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
include/master-slave.inc
[connection master]
#
# Initialize test data
connection master;
create table t1 (a int primary key) engine=innodb;
create table t2 (a int primary key, b int default (a+10), c int default (a + 100), d int default (a + 1000)) engine=innodb;
include/rpl_sync.inc
connection master;
use test;
create function f_insert_defaults_first() returns integer
begin
insert into test.t2 (a) values(1);
insert into test.t2 (a, b) values(2, 10000);
insert into test.t2 (a, c) values(3, 10000);
insert into test.t2 (a, d) values(4, 10000);
insert into test.t2 values(5, 10000, NULL, NULL);
insert into test.t2 values(6, NULL, 10000, NULL);
insert into test.t2 values(7, NULL, NULL, 10000);
insert into test.t2 values(8, NULL, NULL, NULL);
return 1;
end//
create function f_insert_nulls_first() returns integer
begin
insert into test.t2 values(9, 20000, NULL, NULL);
insert into test.t2 values(10, NULL, 20000, NULL);
insert into test.t2 values(11, NULL, NULL, 20000);
insert into test.t2 values(12, NULL, NULL, NULL);
insert into test.t2 (a) values(13);
insert into test.t2 (a, b) values(14, 20000);
insert into test.t2 (a, c) values(15, 20000);
insert into test.t2 (a, d) values(16, 20000);
return 2;
end//
create function f_update() returns integer
begin
update test.t2 set b=b+1;
update test.t2 set c=c+1;
update test.t2 set d=d+1;
return 3;
end//
create function f_delete() returns integer
begin
delete from test.t2;
return 4;
end//
# Ensuring INSERT replicates with default functions (defaults first)
connection master;
insert into t1 values(f_insert_defaults_first());
include/rpl_sync.inc
include/diff_tables.inc [master:t1, slave:t1]
include/diff_tables.inc [master:t2, slave:t2]
# ..PASS
# Ensuring INSERT replicates with default functions (nulls first)
connection master;
insert into t1 values(f_insert_nulls_first());
include/rpl_sync.inc
include/diff_tables.inc [master:t1, slave:t1]
include/diff_tables.inc [master:t2, slave:t2]
# ..PASS
# Ensuring UPDATE replicates with default functions..
connection master;
insert into t1 values(f_update());
include/rpl_sync.inc
include/diff_tables.inc [master:t1, slave:t1]
include/diff_tables.inc [master:t2, slave:t2]
# ..PASS
connection master;
# Ensuring DELETE replicates with default functions..
connection master;
insert into t1 values(f_delete());
include/rpl_sync.inc
include/diff_tables.inc [master:t1, slave:t1]
include/diff_tables.inc [master:t2, slave:t2]
# ..PASS
#
# Cleanup
connection master;
drop table t1;
drop table t2;
drop function f_insert_defaults_first;
drop function f_insert_nulls_first;
drop function f_update;
drop function f_delete;
include/save_master_gtid.inc
connection slave;
include/sync_with_master_gtid.inc
include/rpl_end.inc
# End of rpl_default_functions_explicit_null.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
include/rpl_init.inc [topology=1->2->1]
#
# Initialize test data
connection server_1;
create table t1 ( id int, a int, b int) engine=innodb;
include/rpl_sync.inc
# Change table layouts between servers
connection server_1;
set session sql_log_bin=0;
alter table t1 add column m1col int after a;
set session sql_log_bin=1;
connection server_2;
set session sql_log_bin=0;
alter table t1 add column m2col int after a;
set session sql_log_bin=1;
# Populate data on different servers
connection server_1;
insert into t1 values(10,10,10,10);
insert into t1 values(11,11,11,11);
connection server_2;
insert into t1 values(20,20,20,20);
insert into t1 values(21,21,21,21);
include/rpl_sync.inc
# Server_1 should have full data rows for self-inserted rows, and
# replicated rows should have NULL for its mismatched column..
connection server_1;
# ..PASS
# Server_2 should have full data rows for self-inserted rows, and
# replicated rows should have NULL for its mismatched column..
connection server_2;
# ..PASS
#
# Test that UPDATE can replicate..
connection server_1;
update t1 set a=14 where m1col=10;
include/rpl_sync.inc
connection server_1;
# ..PASS
#
# Test that DELETE can replicate
connection server_1;
delete from t1 where m1col is NULL;
include/rpl_sync.inc
# ..PASS
#
# Cleanup
connection server_1;
drop table t1;
include/rpl_end.inc
12 changes: 12 additions & 0 deletions mysql-test/suite/rpl/t/rpl_default_functions_explicit_null.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
!include ../my.cnf

[mysqld.1]
log-warnings=9
binlog_row_metadata=FULL
binlog_row_image=full


[mysqld.2]
log-warnings=9
binlog_row_metadata=FULL
binlog_row_image=full
121 changes: 121 additions & 0 deletions mysql-test/suite/rpl/t/rpl_default_functions_explicit_null.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#
# Test ensures that tables with default functions replicate correctly when
# NULL values are explicitly provided. Test uses stored procedures to ensure
# multiple rows exist within the Row_log_event with differing NULL value
# placements.
#
# References:
# MDEV-36290: ALTER TABLE with multi-master can cause data loss
#
--source include/have_innodb.inc
--source include/have_binlog_format_row.inc
--source include/master-slave.inc

--echo #
--echo # Initialize test data
--connection master
create table t1 (a int primary key) engine=innodb;
create table t2 (a int primary key, b int default (a+10), c int default (a + 100), d int default (a + 1000)) engine=innodb;
--source include/rpl_sync.inc

--connection master
use test;
delimiter //;
create function f_insert_defaults_first() returns integer
begin
insert into test.t2 (a) values(1);
insert into test.t2 (a, b) values(2, 10000);
insert into test.t2 (a, c) values(3, 10000);
insert into test.t2 (a, d) values(4, 10000);
insert into test.t2 values(5, 10000, NULL, NULL);
insert into test.t2 values(6, NULL, 10000, NULL);
insert into test.t2 values(7, NULL, NULL, 10000);
insert into test.t2 values(8, NULL, NULL, NULL);
return 1;
end//

create function f_insert_nulls_first() returns integer
begin
insert into test.t2 values(9, 20000, NULL, NULL);
insert into test.t2 values(10, NULL, 20000, NULL);
insert into test.t2 values(11, NULL, NULL, 20000);
insert into test.t2 values(12, NULL, NULL, NULL);
insert into test.t2 (a) values(13);
insert into test.t2 (a, b) values(14, 20000);
insert into test.t2 (a, c) values(15, 20000);
insert into test.t2 (a, d) values(16, 20000);
return 2;
end//

create function f_update() returns integer
begin
update test.t2 set b=b+1;
update test.t2 set c=c+1;
update test.t2 set d=d+1;
return 3;
end//

create function f_delete() returns integer
begin
delete from test.t2;
return 4;
end//
delimiter ;//

--echo # Ensuring INSERT replicates with default functions (defaults first)
--connection master
insert into t1 values(f_insert_defaults_first());
--source include/rpl_sync.inc
--let $diff_tables= master:t1, slave:t1
--source include/diff_tables.inc
--let $diff_tables= master:t2, slave:t2
--source include/diff_tables.inc
--echo # ..PASS

--echo # Ensuring INSERT replicates with default functions (nulls first)
--connection master
insert into t1 values(f_insert_nulls_first());
--source include/rpl_sync.inc
--let $diff_tables= master:t1, slave:t1
--source include/diff_tables.inc
--let $diff_tables= master:t2, slave:t2
--source include/diff_tables.inc
--echo # ..PASS

--echo # Ensuring UPDATE replicates with default functions..
--connection master
insert into t1 values(f_update());
--source include/rpl_sync.inc
--let $diff_tables= master:t1, slave:t1
--source include/diff_tables.inc
--let $diff_tables= master:t2, slave:t2
--source include/diff_tables.inc
--echo # ..PASS
--connection master

--echo # Ensuring DELETE replicates with default functions..
--connection master
insert into t1 values(f_delete());
--source include/rpl_sync.inc
--let $diff_tables= master:t1, slave:t1
--source include/diff_tables.inc
--let $diff_tables= master:t2, slave:t2
--source include/diff_tables.inc
--echo # ..PASS

--echo #
--echo # Cleanup
--connection master
drop table t1;
drop table t2;
drop function f_insert_defaults_first;
drop function f_insert_nulls_first;
drop function f_update;
drop function f_delete;
--source include/save_master_gtid.inc

--connection slave
--source include/sync_with_master_gtid.inc

--source include/rpl_end.inc
--echo # End of rpl_default_functions_explicit_null.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
!include ../my.cnf

[mysqld.1]
gtid_domain_id=0
server_id=1
binlog_row_metadata=FULL

[mysqld.2]
gtid_domain_id=1
server_id=2
log_slave_updates
binlog_row_metadata=FULL
Loading