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
|
We should now have read all the null bytes, otherwise something is
|
||||||
really wrong.
|
really wrong.
|
||||||
@ -461,5 +467,30 @@ int prepare_record(TABLE *const table, const uint skip, const bool check)
|
|||||||
|
|
||||||
DBUG_RETURN(0);
|
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
|
#endif // HAVE_REPLICATION
|
||||||
|
@ -38,6 +38,7 @@ int unpack_row(rpl_group_info *rgi,
|
|||||||
|
|
||||||
// Fill table's record[0] with default values.
|
// Fill table's record[0] with default values.
|
||||||
int prepare_record(TABLE *const table, const uint skip, const bool check);
|
int prepare_record(TABLE *const table, const uint skip, const bool check);
|
||||||
|
int fill_extra_persistent_columns(TABLE *table, int master_cols);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user