From d5a15f04f4ab0738b0a5f993b208bcfaad522fd4 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Wed, 29 Sep 2021 11:24:18 +0300 Subject: [PATCH 1/3] MDEV-24978 crash with transaction on table with no PK and long fulltext column MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../suite/galera/r/galera_fulltext.result | 56 ++++++++++++++++ .../suite/galera/t/galera_fulltext.test | 64 +++++++++++++------ storage/innobase/handler/ha_innodb.cc | 10 ++- 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; +# +# MDEV-24978 : SIGABRT in __libc_message +# +--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; + # # 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; -# -#--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; +--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; } From d28b118d7b186391be8d091c00d9cf889c863f1a Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 3 Oct 2021 16:49:54 +0200 Subject: [PATCH 2/3] Fix MSVC warning with bison 3.8.2 --- sql/sql_yacc.yy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0f6773c899d..312ea682975 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -69,7 +69,8 @@ /* this is to get the bison compilation windows warnings out */ #ifdef _MSC_VER /* warning C4065: switch statement contains 'default' but no 'case' labels */ -#pragma warning (disable : 4065) +/* warning C4102: 'yyexhaustedlab': unreferenced label */ +#pragma warning (disable : 4065 4102) #endif #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wunused-label" /* yyexhaustedlab: */ From d836f8a50d62865024d5facebeacb9c491d57adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 4 Oct 2021 11:28:57 +0300 Subject: [PATCH 3/3] Work around MDEV-26754 main.sp test fails for embedded server --- mysql-test/main/sp.result | 3 --- mysql-test/main/sp.test | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result index 694c7bcd20e..3f14c9bec3e 100644 --- a/mysql-test/main/sp.result +++ b/mysql-test/main/sp.result @@ -8911,8 +8911,5 @@ SELECT 1 latin1 latin1_swedish_ci latin1_swedish_ci SELECT VARIABLE_VALUE-@local_mem_used FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='MEMORY_USED'; VARIABLE_VALUE-@local_mem_used 0 -SELECT VARIABLE_VALUE-@global_mem_used FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='MEMORY_USED'; -VARIABLE_VALUE-@global_mem_used -0 DROP PROCEDURE sp1; # End of 10.3 tests diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test index 50ae78c8431..b066f0d00ed 100644 --- a/mysql-test/main/sp.test +++ b/mysql-test/main/sp.test @@ -10446,6 +10446,7 @@ SELECT VARIABLE_VALUE into @local_mem_used FROM INFORMATION_SCHEMA.SESSION_STATU CREATE PROCEDURE sp1() SELECT 1; SHOW CREATE PROCEDURE sp1; SELECT VARIABLE_VALUE-@local_mem_used FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='MEMORY_USED'; -SELECT VARIABLE_VALUE-@global_mem_used FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='MEMORY_USED'; +# FIXME: MDEV-26754 main.sp test fails for embedded server +#SELECT VARIABLE_VALUE-@global_mem_used FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='MEMORY_USED'; DROP PROCEDURE sp1; --echo # End of 10.3 tests