summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2023-04-04 04:19:35 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2023-05-06 00:00:26 +0300
commitae43b81d5f8b188b2ef578ac1258883d8351143e (patch)
treee29ff73602de17ce8810d79ef44cdfa3a215c45a
parent667d0eaffa1f3cc459ce7ad412b65e2bffbddf5a (diff)
downloadmariadb-git-ae43b81d5f8b188b2ef578ac1258883d8351143e.tar.gz
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.
-rw-r--r--mysql-test/suite/rpl/include/rpl_row_blob.test18
-rw-r--r--mysql-test/suite/rpl/r/rpl_alter_extra_persistent.result12
-rw-r--r--mysql-test/suite/rpl/r/rpl_geometry.result10
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_blob_innodb.result15
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_blob_myisam.result15
-rw-r--r--mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test15
-rw-r--r--mysql-test/suite/rpl/t/rpl_geometry.test13
-rw-r--r--sql/log_event_server.cc3
8 files changed, 100 insertions, 1 deletions
diff --git a/mysql-test/suite/rpl/include/rpl_row_blob.test b/mysql-test/suite/rpl/include/rpl_row_blob.test
index 5cd7b6b4b29..408a23519e6 100644
--- a/mysql-test/suite/rpl/include/rpl_row_blob.test
+++ b/mysql-test/suite/rpl/include/rpl_row_blob.test
@@ -173,3 +173,21 @@ DROP TABLE IF EXISTS test.t1;
DROP TABLE IF EXISTS test.t2;
# ensure cleanup on slave as well:
--sync_slave_with_master
+
+--echo #
+--echo # MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
+--echo #
+--connection master
+CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt));
+INSERT INTO t () VALUES (),(),();
+DELETE FROM t;
+
+DROP TABLE t;
+--sync_slave_with_master
+--connection master
+CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt) STORED);
+INSERT INTO t () VALUES (),(),();
+DELETE FROM t;
+
+DROP TABLE t;
+--sync_slave_with_master
diff --git a/mysql-test/suite/rpl/r/rpl_alter_extra_persistent.result b/mysql-test/suite/rpl/r/rpl_alter_extra_persistent.result
index 39db0add6e1..b1b728304f5 100644
--- a/mysql-test/suite/rpl/r/rpl_alter_extra_persistent.result
+++ b/mysql-test/suite/rpl/r/rpl_alter_extra_persistent.result
@@ -361,4 +361,16 @@ connection master;
connection slave;
connection master;
drop table t;
+#
+# MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
+#
+create table t(geo geometrycollection default st_geomfromtext('point(1 1)'));
+insert into t () values (),(),();
+connection slave;
+alter table t add vcol9 point as (geo), add key(vcol9);
+connection master;
+delete from t;
+connection slave;
+connection master;
+drop table t;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_geometry.result b/mysql-test/suite/rpl/r/rpl_geometry.result
index 01dad7b00a0..b2c9503f26c 100644
--- a/mysql-test/suite/rpl/r/rpl_geometry.result
+++ b/mysql-test/suite/rpl/r/rpl_geometry.result
@@ -14,4 +14,14 @@ insert into t2(c) values (null);
connection slave;
connection master;
drop table t1, t2;
+#
+# MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
+#
+create table t(geo geometrycollection default st_geomfromtext('point(1 1)'),
+vc point as (geo));
+insert into t () values (),(),();
+delete from t;
+connection slave;
+connection master;
+drop table t;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_row_blob_innodb.result b/mysql-test/suite/rpl/r/rpl_row_blob_innodb.result
index 084089078cc..9959854a07c 100644
--- a/mysql-test/suite/rpl/r/rpl_row_blob_innodb.result
+++ b/mysql-test/suite/rpl/r/rpl_row_blob_innodb.result
@@ -160,4 +160,19 @@ connection master;
DROP TABLE IF EXISTS test.t1;
DROP TABLE IF EXISTS test.t2;
connection slave;
+#
+# MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
+#
+connection master;
+CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt));
+INSERT INTO t () VALUES (),(),();
+DELETE FROM t;
+DROP TABLE t;
+connection slave;
+connection master;
+CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt) STORED);
+INSERT INTO t () VALUES (),(),();
+DELETE FROM t;
+DROP TABLE t;
+connection slave;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_row_blob_myisam.result b/mysql-test/suite/rpl/r/rpl_row_blob_myisam.result
index 084089078cc..9959854a07c 100644
--- a/mysql-test/suite/rpl/r/rpl_row_blob_myisam.result
+++ b/mysql-test/suite/rpl/r/rpl_row_blob_myisam.result
@@ -160,4 +160,19 @@ connection master;
DROP TABLE IF EXISTS test.t1;
DROP TABLE IF EXISTS test.t2;
connection slave;
+#
+# MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
+#
+connection master;
+CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt));
+INSERT INTO t () VALUES (),(),();
+DELETE FROM t;
+DROP TABLE t;
+connection slave;
+connection master;
+CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt) STORED);
+INSERT INTO t () VALUES (),(),();
+DELETE FROM t;
+DROP TABLE t;
+connection slave;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test b/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
index 3f668911551..e61d05029f1 100644
--- a/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
+++ b/mysql-test/suite/rpl/t/rpl_alter_extra_persistent.test
@@ -261,4 +261,19 @@ select * from t;
--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
diff --git a/mysql-test/suite/rpl/t/rpl_geometry.test b/mysql-test/suite/rpl/t/rpl_geometry.test
index 415732a0228..664979ebe0e 100644
--- a/mysql-test/suite/rpl/t/rpl_geometry.test
+++ b/mysql-test/suite/rpl/t/rpl_geometry.test
@@ -23,4 +23,17 @@ sync_slave_with_master;
connection master;
drop table t1, t2;
+
+--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)'),
+ vc point as (geo));
+insert into t () values (),(),();
+delete from t;
+
+sync_slave_with_master;
+connection master;
+drop table t;
+
--source include/rpl_end.inc
diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
index 4ca2a6327fe..f33df8dd143 100644
--- a/sql/log_event_server.cc
+++ b/sql/log_event_server.cc
@@ -7012,7 +7012,8 @@ static bool record_compare(TABLE *table)
goto record_compare_differ;
}
- if (!f->is_null() && f->cmp_binary_offset(table->s->rec_buff_length))
+ if (!f->is_null() && !f->vcol_info &&
+ f->cmp_binary_offset(table->s->rec_buff_length))
goto record_compare_differ;
}