mariadb/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
Nikita Malyavin 5f206259e5 MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
The bug is inherent for row-based replication as well.
To reproduce, a virtual (not stored) field of a blob type computed from
another field of a different blob type is required.

The following happens during an update or delete row event:
1. A row is unpacked.
2. Virtual fields are updated. Field b1 stores the pointer in
   Field_blob::value and references it in table->record[0].
3. record[0] is stored to record[1] in Rows_log_event::find_row.
4. A new record is fetched from handler. (e.g. ha_rnd_next)
5. Virtual columns are updated (only non-stored).
6. Field b1 receives new value. Old value is deallocated
   (Field_blob::val_str).
7. record_compare is called. record[0] and record[1] are compared.
8. record[1] contains a reference to a freed value.

record_compare is used in replication to find a matching record for update
or delete. Virtual columns that are not stored should be definitely skipped
both for correctness, and for this bug fix.

STORED virtual columns, on the other hand, may be required and shouldn't be
skipped. Stored columns are not affected, since they are not updated after
handler's fetch.
2023-08-15 10:16:13 +02:00

279 lines
6.2 KiB
Text

--source include/have_binlog_format_row.inc
--source include/master-slave.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;
alter table t1 add column z3 int default(a+2);
--connection master
insert into t1 values(7);
insert into t1 values(8);
--sync_slave_with_master
select * from t1 order by a;
--connection master
delete from t1 where a > 6;
--echo #UPDATE query
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;
--sync_slave_with_master
--connection master
set binlog_row_image=minimal;
create table t1(a int primary key auto_increment, b int unique);
insert into t1 values(1, 1);
insert into t1 values(2, 2);
insert into t1 values(3, 3);
insert into t1 values(4, 4);
insert into t1 values(5, 5);
--sync_slave_with_master
alter table t1 add column d1 int default (b),
add column z1 int as (b+1) virtual,
add column z2 int as (b+2) persistent;
--connection master
insert into t1 values(6, 6);
update t1 set a = 11 where a = 1;
update t1 set b = 12 where b = 2;
delete from t1 where a = 3;
delete from t1 where b = 5;
update t1 set b = 16 where a = 6;
--sync_slave_with_master
select * from t1;
--echo # Cleanup
--connection master
drop table t1;
--sync_slave_with_master
--connection master
set binlog_row_image=minimal;
--echo #
--echo # MDEV-29069 ER_KEY_NOT_FOUND upon online autoinc addition and
--echo # concurrent DELETE
--echo #
create or replace table t (a int);
insert into t values (10),(20),(30);
--sync_slave_with_master
alter table t add pk int auto_increment primary key;
--connection master
delete from t where a = 20;
update t set a = a + 1 where a = 10;
--sync_slave_with_master
select * from t;
--connection master
--echo #
--echo # Add clumsy DEFAULT
--echo #
create or replace table t (a int);
insert into t values (10),(20),(30);
--sync_slave_with_master
alter table t add b int default(RAND() * 20), add key(b),
algorithm=copy, lock=none;
--connection master
delete from t where a = 20;
update t set a = a + 1 where a = 10;
--sync_slave_with_master
select a from t;
--connection master
--echo # CURRENT_TIMESTAMP
create or replace table t (a int);
insert into t values (10),(20),(30);
--sync_slave_with_master
alter table t add b timestamp default CURRENT_TIMESTAMP, add key(b);
--connection master
delete from t where a = 20;
update t set a = a + 1 where a = 10;
--sync_slave_with_master
select a from t;
--connection master
--echo # CURRENT_TIMESTAMP, mixed key
create or replace table t (a int);
insert into t values (10),(20),(30);
--sync_slave_with_master
alter table t add b timestamp default CURRENT_TIMESTAMP, add key(a, b);
--connection master
delete from t where a = 20;
update t set a = a + 1 where a = 10;
--sync_slave_with_master
select a from t;
--connection master
--echo # Mixed primary key
create or replace table t (a int);
insert into t values (10),(20),(30);
--sync_slave_with_master
alter table t add b int default (1), add primary key(b, a);
--connection master
delete from t where a = 20;
update t set a = a + 1 where a = 10;
--sync_slave_with_master
select a from t;
--connection master
--echo #
--echo # Normal row, could be used as a key
--echo #
create or replace table t (a int);
insert into t values (10),(20),(30);
--sync_slave_with_master
alter table t add b int as (a * 10) unique;
--connection master
delete from t where a = 20;
update t set a = a + 1 where a = 10;
--sync_slave_with_master
select * from t;
--connection master
--echo #
--echo # Add key for old row
--echo #
create or replace table t (a int);
insert into t values (10),(20),(30);
--sync_slave_with_master
alter table t add unique(a);
--connection master
delete from t where a = 20;
update t set a = a + 1 where a = 10;
--sync_slave_with_master
select * from t;
--echo # Cleanup
--connection master
--sync_slave_with_master
--connection master
drop table t;
--echo #
--echo # MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
--echo #
create table t(geo geometrycollection default st_geomfromtext('point(1 1)'));
insert into t () values (),(),();
--sync_slave_with_master
alter table t add vcol9 point as (geo), add key(vcol9);
--connection master
delete from t;
--sync_slave_with_master
--connection master
drop table t;
--source include/rpl_end.inc