MDEV-11636 Extra persistent columns on slave always gets NULL in RBR
Problem:- In replication if slave has extra persistent column then these column are not computed while applying write-set from master. Solution:- While applying row events from server, we will generate values for extra persistent columns.
This commit is contained in:
parent
37f294fec2
commit
d02a77bc5f
220
mysql-test/suite/rpl/r/rpl_alter_extra_persistent.result
Normal file
220
mysql-test/suite/rpl/r/rpl_alter_extra_persistent.result
Normal file
@ -0,0 +1,220 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
connection master;
|
||||
create table t1(a int primary key);
|
||||
insert into t1 values(1);
|
||||
insert into t1 values(2);
|
||||
insert into t1 values(3);
|
||||
insert into t1 values(4);
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
alter table t1 add column z1 int as(a+1) virtual, add column z2 int as (a+2) persistent;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
3 4 5
|
||||
4 5 6
|
||||
connection master;
|
||||
insert into t1 values(5);
|
||||
insert into t1 values(6);
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
3 4 5
|
||||
4 5 6
|
||||
5 6 7
|
||||
6 7 8
|
||||
#UPDATE query
|
||||
connection master;
|
||||
update t1 set a = a+10;
|
||||
select * from t1 order by a;
|
||||
a
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
11 12 13
|
||||
12 13 14
|
||||
13 14 15
|
||||
14 15 16
|
||||
15 16 17
|
||||
16 17 18
|
||||
connection master;
|
||||
update t1 set a = a-10;
|
||||
select * from t1 order by a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
3 4 5
|
||||
4 5 6
|
||||
5 6 7
|
||||
6 7 8
|
||||
#DELETE quert
|
||||
connection master;
|
||||
delete from t1 where a > 2 and a < 4;
|
||||
select * from t1 order by a;
|
||||
a
|
||||
1
|
||||
2
|
||||
4
|
||||
5
|
||||
6
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
4 5 6
|
||||
5 6 7
|
||||
6 7 8
|
||||
#REPLACE query
|
||||
connection master;
|
||||
replace into t1 values(1);
|
||||
replace into t1 values(3);
|
||||
replace into t1 values(1);
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
3 4 5
|
||||
4 5 6
|
||||
5 6 7
|
||||
6 7 8
|
||||
#SELECT query
|
||||
connection master;
|
||||
select * from t1 where a > 2 and a < 4;
|
||||
a
|
||||
3
|
||||
connection slave;
|
||||
select * from t1 where a > 2 and a < 4;
|
||||
a z1 z2
|
||||
3 4 5
|
||||
#UPDATE with SELECT query
|
||||
connection master;
|
||||
update t1 set a = a + 10 where a > 2 and a < 4;
|
||||
select * from t1 order by a;
|
||||
a
|
||||
1
|
||||
2
|
||||
4
|
||||
5
|
||||
6
|
||||
13
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
4 5 6
|
||||
5 6 7
|
||||
6 7 8
|
||||
13 14 15
|
||||
connection master;
|
||||
update t1 set a = a - 10 where a = 13;
|
||||
select * from t1 order by a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
3 4 5
|
||||
4 5 6
|
||||
5 6 7
|
||||
6 7 8
|
||||
#Break Unique Constraint
|
||||
alter table t1 add column z4 int as (a % 6) persistent unique;
|
||||
connection master;
|
||||
#entering duplicate value for slave persistent column
|
||||
insert into t1 values(7);
|
||||
select * from t1 order by a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
connection slave;
|
||||
include/wait_for_slave_sql_error.inc [errno=1062]
|
||||
connection slave;
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2 z4
|
||||
1 2 3 1
|
||||
2 3 4 2
|
||||
3 4 5 3
|
||||
4 5 6 4
|
||||
5 6 7 5
|
||||
6 7 8 0
|
||||
alter table t1 drop column z4;
|
||||
start slave;
|
||||
include/wait_for_slave_sql_to_start.inc
|
||||
connection slave;
|
||||
connection slave;
|
||||
connection master;
|
||||
connection slave;
|
||||
select * from t1 order by a;
|
||||
a z1 z2
|
||||
1 2 3
|
||||
2 3 4
|
||||
3 4 5
|
||||
4 5 6
|
||||
5 6 7
|
||||
6 7 8
|
||||
7 8 9
|
||||
connection master;
|
||||
select * from t1 order by a;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
drop table t1;
|
||||
include/rpl_end.inc
|
||||
connection server_2;
|
||||
connection server_2;
|
||||
connection server_2;
|
||||
connection server_2;
|
||||
connection server_1;
|
||||
connection server_1;
|
||||
connection server_1;
|
||||
connection server_2;
|
||||
connection server_1;
|
||||
connection server_2;
|
||||
connection server_2;
|
||||
connection server_1;
|
||||
connection server_1;
|
106
mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
Normal file
106
mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
Normal file
@ -0,0 +1,106 @@
|
||||
--source include/master-slave.inc
|
||||
--source include/have_binlog_format_row.inc
|
||||
|
||||
--enable_connect_log
|
||||
--connection master
|
||||
create table t1(a int primary key);
|
||||
insert into t1 values(1);
|
||||
insert into t1 values(2);
|
||||
insert into t1 values(3);
|
||||
insert into t1 values(4);
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
alter table t1 add column z1 int as(a+1) virtual, add column z2 int as (a+2) persistent;
|
||||
select * from t1 order by a;
|
||||
|
||||
--connection master
|
||||
insert into t1 values(5);
|
||||
insert into t1 values(6);
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
|
||||
--echo #UPDATE query
|
||||
|
||||
--connection master
|
||||
update t1 set a = a+10;
|
||||
select * from t1 order by a;
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
--connection master
|
||||
update t1 set a = a-10;
|
||||
select * from t1 order by a;
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
--echo #DELETE quert
|
||||
--connection master
|
||||
delete from t1 where a > 2 and a < 4;
|
||||
select * from t1 order by a;
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
--echo #REPLACE query
|
||||
--connection master
|
||||
replace into t1 values(1);
|
||||
replace into t1 values(3);
|
||||
replace into t1 values(1);
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
--echo #SELECT query
|
||||
--connection master
|
||||
select * from t1 where a > 2 and a < 4;
|
||||
|
||||
--connection slave
|
||||
select * from t1 where a > 2 and a < 4;
|
||||
|
||||
--echo #UPDATE with SELECT query
|
||||
--connection master
|
||||
update t1 set a = a + 10 where a > 2 and a < 4;
|
||||
select * from t1 order by a;
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
--connection master
|
||||
update t1 set a = a - 10 where a = 13;
|
||||
select * from t1 order by a;
|
||||
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
--echo #Break Unique Constraint
|
||||
alter table t1 add column z4 int as (a % 6) persistent unique;
|
||||
|
||||
--connection master
|
||||
|
||||
--echo #entering duplicate value for slave persistent column
|
||||
insert into t1 values(7);
|
||||
select * from t1 order by a;
|
||||
|
||||
--connection slave
|
||||
--let $slave_sql_errno= 1062
|
||||
--source include/wait_for_slave_sql_error.inc
|
||||
select * from t1 order by a;
|
||||
alter table t1 drop column z4;
|
||||
start slave;
|
||||
|
||||
--source include/wait_for_slave_sql_to_start.inc
|
||||
|
||||
--connection master
|
||||
--sync_slave_with_master
|
||||
select * from t1 order by a;
|
||||
|
||||
--connection master
|
||||
select * from t1 order by a;
|
||||
drop table t1;
|
||||
|
||||
--source include/rpl_end.inc
|
@ -389,6 +389,12 @@ unpack_row(rpl_group_info *rgi,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Add Extra slave persistent columns
|
||||
*/
|
||||
if ((error= fill_extra_persistent_columns(table, cols->n_bits)))
|
||||
DBUG_RETURN(error);
|
||||
|
||||
/*
|
||||
We should now have read all the null bytes, otherwise something is
|
||||
really wrong.
|
||||
@ -461,5 +467,30 @@ int prepare_record(TABLE *const table, const uint skip, const bool check)
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/**
|
||||
Fills @c table->record[0] with computed values of extra persistent column which are present on slave but not on master.
|
||||
@param table Table whose record[0] buffer is prepared.
|
||||
@param master_cols No of columns on master
|
||||
@returns 0 on success
|
||||
*/
|
||||
int fill_extra_persistent_columns(TABLE *table, int master_cols)
|
||||
{
|
||||
int error= 0;
|
||||
Field **vfield_ptr, *vfield;
|
||||
|
||||
if (!table->vfield)
|
||||
return 0;
|
||||
for (vfield_ptr= table->vfield; *vfield_ptr; ++vfield_ptr)
|
||||
{
|
||||
vfield= *vfield_ptr;
|
||||
if (vfield->field_index >= master_cols && vfield->stored_in_db)
|
||||
{
|
||||
/*Set bitmap for writing*/
|
||||
bitmap_set_bit(table->vcol_set, vfield->field_index);
|
||||
error= vfield->vcol_info->expr_item->save_in_field(vfield,0);
|
||||
bitmap_clear_bit(table->vcol_set, vfield->field_index);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
#endif // HAVE_REPLICATION
|
||||
|
@ -38,6 +38,7 @@ int unpack_row(rpl_group_info *rgi,
|
||||
|
||||
// Fill table's record[0] with default values.
|
||||
int prepare_record(TABLE *const table, const uint skip, const bool check);
|
||||
int fill_extra_persistent_columns(TABLE *table, int master_cols);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user