Skip to content

Commit e45b85e

Browse files
committed
SQL: replication from unversioned to versioned [fixes #94]
1 parent ef10ef9 commit e45b85e

File tree

5 files changed

+232
-8
lines changed

5 files changed

+232
-8
lines changed

mysql-test/suite/versioning/r/rpl_row.result

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,77 @@ x
3737
3
3838
2
3939
connection master;
40+
create or replace table t1 (x int primary key) engine = innodb;
41+
connection slave;
42+
alter table t1 with system versioning;
43+
connection master;
44+
insert into t1 values (1);
45+
update t1 set x= 2 where x = 1;
46+
connection slave;
47+
select * from t1;
48+
x
49+
2
50+
select * from t1 for system_time all;
51+
x
52+
1
53+
2
54+
connection master;
55+
delete from t1;
56+
connection slave;
57+
select * from t1;
58+
x
59+
select * from t1 for system_time all;
60+
x
61+
1
62+
2
63+
connection master;
64+
create or replace table t1 (x int) engine = innodb;
65+
connection slave;
66+
alter table t1 with system versioning;
67+
connection master;
68+
insert into t1 values (1);
69+
update t1 set x= 2 where x = 1;
70+
connection slave;
71+
select * from t1;
72+
x
73+
2
74+
select * from t1 for system_time all;
75+
x
76+
2
77+
1
78+
connection master;
79+
delete from t1;
80+
connection slave;
81+
select * from t1;
82+
x
83+
select * from t1 for system_time all;
84+
x
85+
2
86+
1
87+
connection master;
88+
create or replace table t1 (x int primary key) with system versioning engine = innodb;
89+
connection slave;
90+
alter table t1 without system versioning;
91+
connection master;
92+
insert into t1 values (1);
93+
update t1 set x= 2 where x = 1;
94+
select * from t1 for system_time all;
95+
x
96+
1
97+
2
98+
connection slave;
99+
select * from t1;
100+
x
101+
2
102+
connection master;
103+
delete from t1;
104+
select * from t1 for system_time all;
105+
x
106+
1
107+
2
108+
connection slave;
109+
select * from t1;
110+
x
111+
connection master;
40112
drop table t1;
41113
include/rpl_end.inc

mysql-test/suite/versioning/r/rpl_stmt.result

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,77 @@ x
3737
3
3838
2
3939
connection master;
40+
create or replace table t1 (x int primary key) engine = innodb;
41+
connection slave;
42+
alter table t1 with system versioning;
43+
connection master;
44+
insert into t1 values (1);
45+
update t1 set x= 2 where x = 1;
46+
connection slave;
47+
select * from t1;
48+
x
49+
2
50+
select * from t1 for system_time all;
51+
x
52+
1
53+
2
54+
connection master;
55+
delete from t1;
56+
connection slave;
57+
select * from t1;
58+
x
59+
select * from t1 for system_time all;
60+
x
61+
1
62+
2
63+
connection master;
64+
create or replace table t1 (x int) engine = innodb;
65+
connection slave;
66+
alter table t1 with system versioning;
67+
connection master;
68+
insert into t1 values (1);
69+
update t1 set x= 2 where x = 1;
70+
connection slave;
71+
select * from t1;
72+
x
73+
2
74+
select * from t1 for system_time all;
75+
x
76+
2
77+
1
78+
connection master;
79+
delete from t1;
80+
connection slave;
81+
select * from t1;
82+
x
83+
select * from t1 for system_time all;
84+
x
85+
2
86+
1
87+
connection master;
88+
create or replace table t1 (x int primary key) with system versioning engine = innodb;
89+
connection slave;
90+
alter table t1 without system versioning;
91+
connection master;
92+
insert into t1 values (1);
93+
update t1 set x= 2 where x = 1;
94+
select * from t1 for system_time all;
95+
x
96+
1
97+
2
98+
connection slave;
99+
select * from t1;
100+
x
101+
2
102+
connection master;
103+
delete from t1;
104+
select * from t1 for system_time all;
105+
x
106+
1
107+
2
108+
connection slave;
109+
select * from t1;
110+
x
111+
connection master;
40112
drop table t1;
41113
include/rpl_end.inc

mysql-test/suite/versioning/t/rpl_test.inc

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,62 @@ sync_slave_with_master;
2929
select * from t1;
3030
select * from t1 for system_time all;
3131

32+
# check unversioned -> versioned replication
33+
connection master;
34+
create or replace table t1 (x int primary key) engine = innodb;
35+
sync_slave_with_master;
36+
alter table t1 with system versioning;
37+
38+
connection master;
39+
insert into t1 values (1);
40+
update t1 set x= 2 where x = 1;
41+
sync_slave_with_master;
42+
select * from t1;
43+
select * from t1 for system_time all;
44+
45+
connection master;
46+
delete from t1;
47+
sync_slave_with_master;
48+
select * from t1;
49+
select * from t1 for system_time all;
50+
51+
# same thing (UPDATE, DELETE), but without PK
52+
connection master;
53+
create or replace table t1 (x int) engine = innodb;
54+
sync_slave_with_master;
55+
alter table t1 with system versioning;
56+
57+
connection master;
58+
insert into t1 values (1);
59+
update t1 set x= 2 where x = 1;
60+
sync_slave_with_master;
61+
select * from t1;
62+
select * from t1 for system_time all;
63+
64+
connection master;
65+
delete from t1;
66+
sync_slave_with_master;
67+
select * from t1;
68+
select * from t1 for system_time all;
69+
70+
# same thing, but reverse: versioned -> unversioned
71+
connection master;
72+
create or replace table t1 (x int primary key) with system versioning engine = innodb;
73+
sync_slave_with_master;
74+
alter table t1 without system versioning;
75+
76+
connection master;
77+
insert into t1 values (1);
78+
update t1 set x= 2 where x = 1;
79+
select * from t1 for system_time all;
80+
sync_slave_with_master;
81+
select * from t1;
82+
83+
connection master;
84+
delete from t1;
85+
select * from t1 for system_time all;
86+
sync_slave_with_master;
87+
select * from t1;
88+
3289
connection master;
3390
drop table t1;

sql/handler.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6003,8 +6003,8 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data)
60036003
DBUG_ASSERT(new_data == table->record[0]);
60046004
DBUG_ASSERT(old_data == table->record[1]);
60056005

6006-
// InnoDB changes sys_trx_end to curr_trx_id and we need to restore MAX_TRX
6007-
if (table->file->check_table_binlog_row_based(1))
6006+
// it is important to keep 'old_data' intact for versioning to work correctly on slave side
6007+
if (table->file->check_table_binlog_row_based(1) && table->versioned())
60086008
memcpy(table->record[2], table->record[1], table->s->reclength);
60096009
MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
60106010
mark_trx_read_write();
@@ -6017,8 +6017,10 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data)
60176017
if (likely(!error) && !row_already_logged)
60186018
{
60196019
rows_changed++;
6020-
if (table->file->check_table_binlog_row_based(1)) {
6021-
memcpy(table->record[1], table->record[2], table->s->reclength);
6020+
if (table->file->check_table_binlog_row_based(1))
6021+
{
6022+
if (table->versioned())
6023+
memcpy(table->record[1], table->record[2], table->s->reclength);
60226024
error= binlog_log_row(table, old_data, new_data, log_func);
60236025
}
60246026
}

sql/log_event.cc

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12766,7 +12766,7 @@ uint8 Write_rows_log_event::get_trg_event_map()
1276612766
1276712767
Returns TRUE if different.
1276812768
*/
12769-
static bool record_compare(TABLE *table)
12769+
static bool record_compare(TABLE *table, bool skip_sys_start)
1277012770
{
1277112771
bool result= FALSE;
1277212772
/**
@@ -12799,7 +12799,10 @@ static bool record_compare(TABLE *table)
1279912799
/* Compare fields */
1280012800
for (Field **ptr=table->field ; *ptr ; ptr++)
1280112801
{
12802-
12802+
if (skip_sys_start && *ptr == table->vers_start_field())
12803+
{
12804+
continue;
12805+
}
1280312806
/**
1280412807
We only compare field contents that are not null.
1280512808
NULL fields (i.e., their null bits) were compared
@@ -12994,6 +12997,24 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
1299412997
prepare_record(table, m_width, FALSE);
1299512998
error= unpack_current_row(rgi);
1299612999

13000+
bool skip_sys_start= false;
13001+
13002+
if (table->versioned())
13003+
{
13004+
Field *sys_trx_end= table->vers_end_field();
13005+
DBUG_ASSERT(table->read_set);
13006+
bitmap_set_bit(table->read_set, sys_trx_end->field_index);
13007+
// master table is unversioned
13008+
if (sys_trx_end->val_int() == 0)
13009+
{
13010+
DBUG_ASSERT(table->write_set);
13011+
bitmap_set_bit(table->write_set, sys_trx_end->field_index);
13012+
sys_trx_end->set_max();
13013+
table->vers_start_field()->set_notnull();
13014+
skip_sys_start= true;
13015+
}
13016+
}
13017+
1299713018
DBUG_PRINT("info",("looking for the following record"));
1299813019
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
1299913020

@@ -13169,7 +13190,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
1316913190
/* We use this to test that the correct key is used in test cases. */
1317013191
DBUG_EXECUTE_IF("slave_crash_if_index_scan", abort(););
1317113192

13172-
while (record_compare(table))
13193+
while (record_compare(table, skip_sys_start))
1317313194
{
1317413195
while ((error= table->file->ha_index_next(table->record[0])))
1317513196
{
@@ -13233,7 +13254,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
1323313254
goto end;
1323413255
}
1323513256
}
13236-
while (record_compare(table));
13257+
while (record_compare(table, skip_sys_start));
1323713258

1323813259
/*
1323913260
Note: above record_compare will take into accout all record fields

0 commit comments

Comments
 (0)