summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsjaakola <seppo.jaakola@iki.fi>2021-09-29 11:24:18 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2021-09-30 11:19:34 +0300
commitd5a15f04f4ab0738b0a5f993b208bcfaad522fd4 (patch)
tree0a3a1644b6030133c3647105e9b4af826229b500
parentb2a5e0f28232b56c5c36e65a457d41d819b279bf (diff)
downloadmariadb-git-d5a15f04f4ab0738b0a5f993b208bcfaad522fd4.tar.gz
MDEV-24978 crash with transaction on table with no PK and long fulltext columnbb-10.2-MDEV-24978-galera
If a table has no unique indexes, write set key information will be collected on all columns in the table. The write set key information has space only for max 3500 bytes for individual column, and if a varchar colummn of such non-primary key table is longer than this limit, currently a crash follows. The fix in this commit, is to truncate key values extracted from such long varhar columns to max 3500 bytes. This may potentially lead to false positive certification failures for transactions, which operate on separate cluster nodes, and update/insert/delete table rows, which differ only in the part of such long columns after 3500 bytes border. Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
-rw-r--r--mysql-test/suite/galera/r/galera_fulltext.result56
-rw-r--r--mysql-test/suite/galera/t/galera_fulltext.test64
-rw-r--r--storage/innobase/handler/ha_innodb.cc10
3 files changed, 106 insertions, 24 deletions
diff --git a/mysql-test/suite/galera/r/galera_fulltext.result b/mysql-test/suite/galera/r/galera_fulltext.result
index 18e3bff40fc..bb482b7f4f7 100644
--- a/mysql-test/suite/galera/r/galera_fulltext.result
+++ b/mysql-test/suite/galera/r/galera_fulltext.result
@@ -34,3 +34,59 @@ COUNT(f1) = 1000
1
DROP TABLE t1;
DROP TABLE ten;
+connection node_1;
+SET @value=REPEAT (1,5001);
+CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb;
+INSERT IGNORE INTO t VALUES(@value);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_2;
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_1;
+DROP TABLE t;
+CREATE TABLE t (a VARCHAR(5000)) engine=innodb;
+INSERT IGNORE INTO t VALUES(@value);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_2;
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_1;
+DROP TABLE t;
+connection node_1;
+SET @value=REPEAT (1,5001);
+CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8;
+INSERT IGNORE INTO t VALUES(@value);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_2;
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_1;
+DROP TABLE t;
+CREATE TABLE t (a VARCHAR(5000)) engine=innodb DEFAULT CHARSET=utf8;
+INSERT IGNORE INTO t VALUES(@value);
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_2;
+SELECT COUNT(*) FROM t;
+COUNT(*)
+1
+connection node_1;
+DROP TABLE t;
diff --git a/mysql-test/suite/galera/t/galera_fulltext.test b/mysql-test/suite/galera/t/galera_fulltext.test
index 7e2fc5e581d..beb6a1b8f6f 100644
--- a/mysql-test/suite/galera/t/galera_fulltext.test
+++ b/mysql-test/suite/galera/t/galera_fulltext.test
@@ -58,28 +58,50 @@ SELECT COUNT(f1) = 1000 FROM t1 WHERE MATCH(f1) AGAINST ('abcdefjhk');
DROP TABLE t1;
DROP TABLE ten;
-
-#
-# Case 2: UTF-8
-# TODO: MDEV-24978
#
-#--connection node_1
-#SET @value=REPEAT (1,5001);
-#CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8;
-#INSERT IGNORE INTO t VALUES(@value);
-#SELECT COUNT(*) FROM t;
+# MDEV-24978 : SIGABRT in __libc_message
#
-#--connection node_2
-#SELECT COUNT(*) FROM t;
-#
-#--connection node_1
-#DROP TABLE t;
-#CREATE TABLE t (a VARCHAR(5000)) engine=innodb DEFAULT CHARSET=utf8;
-#INSERT IGNORE INTO t VALUES(@value);
-#SELECT COUNT(*) FROM t;
+--connection node_1
+SET @value=REPEAT (1,5001);
+CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb;
+INSERT IGNORE INTO t VALUES(@value);
+SELECT COUNT(*) FROM t;
+
+--connection node_2
+SELECT COUNT(*) FROM t;
+
+--connection node_1
+DROP TABLE t;
+CREATE TABLE t (a VARCHAR(5000)) engine=innodb;
+INSERT IGNORE INTO t VALUES(@value);
+SELECT COUNT(*) FROM t;
+
+--connection node_2
+SELECT COUNT(*) FROM t;
+
+--connection node_1
+DROP TABLE t;
+
#
-#--connection node_2
-#SELECT COUNT(*) FROM t;
+# Case 2: UTF-8
#
-#--connection node_1
-#DROP TABLE t;
+--connection node_1
+SET @value=REPEAT (1,5001);
+CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8;
+INSERT IGNORE INTO t VALUES(@value);
+SELECT COUNT(*) FROM t;
+
+--connection node_2
+SELECT COUNT(*) FROM t;
+
+--connection node_1
+DROP TABLE t;
+CREATE TABLE t (a VARCHAR(5000)) engine=innodb DEFAULT CHARSET=utf8;
+INSERT IGNORE INTO t VALUES(@value);
+SELECT COUNT(*) FROM t;
+
+--connection node_2
+SELECT COUNT(*) FROM t;
+
+--connection node_1
+DROP TABLE t;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a42e8e3699c..fefd0bdde00 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -7218,10 +7218,14 @@ wsrep_store_key_val_for_row(
/* In a column prefix index, we may need to truncate
the stored value: */
-
if (true_len > key_len) {
true_len = key_len;
}
+ /* cannot exceed max column lenght either, we may need to truncate
+ the stored value: */
+ if (true_len > sizeof(sorted)) {
+ true_len = sizeof(sorted);
+ }
memcpy(sorted, data, true_len);
true_len = wsrep_innobase_mysql_sort(
@@ -7234,8 +7238,8 @@ wsrep_store_key_val_for_row(
actual data. The rest of the space was reset to zero
in the bzero() call above. */
if (true_len > buff_space) {
- fprintf (stderr,
- "WSREP: key truncated: %s\n",
+ WSREP_DEBUG (
+ "write set key truncated for: %s\n",
wsrep_thd_query(thd));
true_len = buff_space;
}