From fdc4b7a6b222ffdcbe355255b40e500d339fbf3b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 15 Dec 2020 16:28:42 +0530 Subject: [PATCH 01/27] MDEV-21478 Inplace ALTER fails to report error when FTS_DOC_ID with wrong data type is added Inplace alter fails to report error when fts_doc_id column with wrong data type is added. prepare_inplace_alter_table_dict(): Should check whether the column is fts_doc_id. It should be of bigint type, should accept non null data type and it should be in capital letters. --- .../suite/innodb_fts/r/innodb-fts-ddl.result | 32 +++++++++++++++ .../suite/innodb_fts/t/innodb-fts-ddl.test | 41 +++++++++++++++++++ storage/innobase/handler/handler0alter.cc | 17 ++++++++ 3 files changed, 90 insertions(+) diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result index f23813aed48..f1e625037f3 100644 --- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result +++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result @@ -234,3 +234,35 @@ CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY, f1 VARCHAR(200),FULLTEXT fidx(f1))engine=innodb; ALTER TABLE t1 DROP index fidx, ADD FULLTEXT INDEX(f1); DROP TABLE t1; +# +# MDEV-21478 Inplace alter fails to report error when +# FTS_DOC_ID is added +SET NAMES utf8; +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; +ALTER TABLE t1 DROP COLUMN FTS_DOC_ıD; +ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; +DROP TABLE t1; +CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; +ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; +ERROR 42000: Incorrect column name 'FTS_DOC_İD' +ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; +ERROR 42000: Incorrect column name 'FTS_DOC_İD' +ALTER TABLE t1 ADD fts_doc_id INT, ALGORITHM=COPY; +ERROR 42000: Incorrect column name 'fts_doc_id' +ALTER TABLE t1 ADD fts_doc_id INT, ALGORITHM=INPLACE; +ERROR 42000: Incorrect column name 'fts_doc_id' +ALTER TABLE t1 ADD fts_doc_id BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; +ERROR 42000: Incorrect column name 'fts_doc_id' +ALTER TABLE t1 ADD fts_doc_id BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; +ERROR 42000: Incorrect column name 'fts_doc_id' +ALTER TABLE t1 ADD FTS_DOC_ID INT UNSIGNED NOT NULL, ALGORITHM=COPY; +ERROR 42000: Incorrect column name 'FTS_DOC_ID' +ALTER TABLE t1 ADD FTS_DOC_ID INT UNSIGNED NOT NULL, ALGORITHM=INPLACE; +ERROR 42000: Incorrect column name 'FTS_DOC_ID' +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test index cd292803fb3..e055acc4968 100644 --- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test +++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test @@ -278,3 +278,44 @@ CREATE TABLE t1 (FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY, f1 VARCHAR(200),FULLTEXT fidx(f1))engine=innodb; ALTER TABLE t1 DROP index fidx, ADD FULLTEXT INDEX(f1); DROP TABLE t1; + +--echo # +--echo # MDEV-21478 Inplace alter fails to report error when +--echo # FTS_DOC_ID is added + +SET NAMES utf8; + +CREATE TABLE t1(f1 INT NOT NULL)ENGINE=InnoDB; +ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; +ALTER TABLE t1 DROP COLUMN FTS_DOC_ıD; +ALTER TABLE t1 ADD FTS_DOC_ıD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; +DROP TABLE t1; + +CREATE TABLE t1 (f1 INT NOT NULL)ENGINE=InnoDB; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD FTS_DOC_İD BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD fts_doc_id INT, ALGORITHM=COPY; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD fts_doc_id INT, ALGORITHM=INPLACE; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD fts_doc_id BIGINT UNSIGNED NOT NULL, ALGORITHM=COPY; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD fts_doc_id BIGINT UNSIGNED NOT NULL, ALGORITHM=INPLACE; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD FTS_DOC_ID INT UNSIGNED NOT NULL, ALGORITHM=COPY; + +--error ER_WRONG_COLUMN_NAME +ALTER TABLE t1 ADD FTS_DOC_ID INT UNSIGNED NOT NULL, ALGORITHM=INPLACE; + +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 0bd11d74b09..7655b93e736 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4663,6 +4663,23 @@ prepare_inplace_alter_table_dict( goto new_clustered_failed; } + /** Note the FTS_DOC_ID name is case sensitive due + to internal query parser. + FTS_DOC_ID column must be of BIGINT NOT NULL type + and it should be in all capitalized characters */ + if (!innobase_strcasecmp(field->field_name, + FTS_DOC_ID_COL_NAME)) { + if (col_type != DATA_INT + || field->real_maybe_null() + || col_len != sizeof(doc_id_t) + || strcmp(field->field_name, + FTS_DOC_ID_COL_NAME)) { + my_error(ER_WRONG_COLUMN_NAME, MYF(0), + field->field_name); + goto new_clustered_failed; + } + } + if (is_virtual) { dict_mem_table_add_v_col( ctx->new_table, ctx->heap, From 1be707286ef13041a67e6e6ca30125470245a898 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 12 Jan 2021 11:38:26 +0530 Subject: [PATCH 02/27] Added the test case for MDEV-23804 --- mysql-test/main/derived_cond_pushdown.result | 70 ++++++++++++++++++++ mysql-test/main/derived_cond_pushdown.test | 13 ++++ 2 files changed, 83 insertions(+) diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 1be7897d3af..27ffffd7581 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -17064,4 +17064,74 @@ id 2 3 DROP TABLE t; +# +# MDEV-23804: Server crashes in st_select_lex::collect_grouping_fields_for_derived +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (3),(4); +CREATE VIEW v1 AS SELECT a FROM t1 UNION VALUES (3),(4); +ANALYZE FORMAT=JSON SELECT * from v1 WHERE a=3; +ANALYZE +{ + "query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "table": { + "table_name": "", + "access_type": "ALL", + "r_loops": 1, + "rows": 4, + "r_rows": 2, + "r_total_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 50, + "attached_condition": "v1.a = 3", + "materialized": { + "query_block": { + "union_result": { + "table_name": "", + "access_type": "ALL", + "r_loops": 1, + "r_rows": 2, + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "table": { + "table_name": "t1", + "access_type": "ALL", + "r_loops": 1, + "rows": 2, + "r_rows": 2, + "r_total_time_ms": "REPLACED", + "filtered": 100, + "r_filtered": 50, + "attached_condition": "t1.a = 3" + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "table": { + "message": "No tables used" + } + } + } + ] + } + } + } + } + } +} +SELECT * from v1 WHERE a=3; +a +3 +DROP VIEW v1; +DROP TABLE t1; # End of 10.3 tests diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index 1b980fd3685..12d34a8326a 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -3466,4 +3466,17 @@ eval set statement optimizer_switch='split_materialized=on' for $q; DROP TABLE t; +--echo # +--echo # MDEV-23804: Server crashes in st_select_lex::collect_grouping_fields_for_derived +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (3),(4); +CREATE VIEW v1 AS SELECT a FROM t1 UNION VALUES (3),(4); +--source include/analyze-format.inc +ANALYZE FORMAT=JSON SELECT * from v1 WHERE a=3; +SELECT * from v1 WHERE a=3; +DROP VIEW v1; +DROP TABLE t1; + --echo # End of 10.3 tests From ffc384e044d8e312cad13b67b9ae27878804336c Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 12 Jan 2021 11:50:31 +0530 Subject: [PATCH 03/27] MDEV-23804: Server crashes in st_select_lex::collect_grouping_fields_for_derived The issue here was we were trying to push an extracted condition for a view into the underlying table value constructor inside the view. The fix would be to not push conditions into table value constructors. --- sql/sql_derived.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index dc079ba6f16..500cb43339e 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1453,6 +1453,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) for (; sl; sl= sl->next_select()) { Item *extracted_cond_copy; + if (!sl->cond_pushdown_is_allowed()) + continue; /* For each select of the unit except the last one create a clone of extracted_cond From 69c86abb646361c607a248f079f8fd4e600dcada Mon Sep 17 00:00:00 2001 From: Kentoku SHIBA Date: Wed, 15 Apr 2020 23:19:10 +0900 Subject: [PATCH 04/27] MDEV-20502 Queries against spider tables return wrong values for columns following constant declarations. When executing a query like "select id, 0 as const, val from ...", there are 3 columns(items) in Query->select at handlerton->create_group_by(). After that, MariaDB makes a temporary table with 2 columns. The skipped items are const item, so fixing Spider to skip const items for items at Query->select. --- .../bugfix/include/mdev_20502_deinit.inc | 11 +++ .../spider/bugfix/include/mdev_20502_init.inc | 25 +++++++ .../spider/bugfix/r/mdev_20502.result | 61 ++++++++++++++++ .../mysql-test/spider/bugfix/t/mdev_20502.cnf | 3 + .../spider/bugfix/t/mdev_20502.test | 71 +++++++++++++++++++ .../mysql-test/spider/r/timestamp.result | 2 +- storage/spider/spd_db_conn.cc | 3 + storage/spider/spd_db_mysql.cc | 20 +++++- storage/spider/spd_db_oracle.cc | 19 ++++- storage/spider/spd_group_by_handler.cc | 5 ++ 10 files changed, 216 insertions(+), 4 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/include/mdev_20502_deinit.inc create mode 100644 storage/spider/mysql-test/spider/bugfix/include/mdev_20502_init.inc create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_20502.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_20502_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_20502_deinit.inc new file mode 100644 index 00000000000..76b7582abfe --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_20502_deinit.inc @@ -0,0 +1,11 @@ +--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP +--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP +--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP +--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_result_log +--enable_query_log +--enable_warnings diff --git a/storage/spider/mysql-test/spider/bugfix/include/mdev_20502_init.inc b/storage/spider/mysql-test/spider/bugfix/include/mdev_20502_init.inc new file mode 100644 index 00000000000..fd8cc0d8170 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/mdev_20502_init.inc @@ -0,0 +1,25 @@ +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_result_log +--enable_query_log +--enable_warnings +--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1 +let $MASTER_1_COMMENT_2_1= + COMMENT='table "tbl_a", srv "s_2_1"'; +--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES +let $CHILD2_1_DROP_TABLES= + DROP TABLE IF EXISTS tbl_a; +--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES +let $CHILD2_1_CREATE_TABLES= + CREATE TABLE tbl_a ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + val int(10) unsigned DEFAULT NULL, + PRIMARY KEY (id) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES +let $CHILD2_1_SELECT_TABLES= + SELECT id, val FROM tbl_a ORDER BY id; +let $CHILD2_1_SELECT_ARGUMENT1= + SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result new file mode 100644 index 00000000000..284f62e522e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result @@ -0,0 +1,61 @@ +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +this test is for MDEV-20502 + +drop and create databases +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +connection child2_1; +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +create table and insert +connection child2_1; +CHILD2_1_CREATE_TABLES +TRUNCATE TABLE mysql.general_log; +connection master_1; +CREATE TABLE tbl_a ( +id int(10) unsigned NOT NULL AUTO_INCREMENT, +val int(10) unsigned DEFAULT NULL, +PRIMARY KEY(id) +) ENGINE=Spider COMMENT='table "tbl_a", srv "s_2_1"' +INSERT INTO tbl_a (val) VALUES (1); + +test 1 +connection child2_1; +TRUNCATE TABLE mysql.general_log; +connection master_1; +SELECT id, 0 AS const, val FROM tbl_a; +id const val +1 0 1 +connection child2_1; +SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; +argument +select t0.`id` `id`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0 +SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %' +SELECT id, val FROM tbl_a ORDER BY id; +id val +1 1 + +deinit +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +end of test diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test new file mode 100644 index 00000000000..4693f2f7409 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test @@ -0,0 +1,71 @@ +--source ../include/mdev_20502_init.inc +--echo +--echo this test is for MDEV-20502 +--echo +--echo drop and create databases + +--connection master_1 +--disable_warnings +CREATE DATABASE auto_test_local; +USE auto_test_local; + +--connection child2_1 +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +--enable_warnings + +--echo +--echo create table and insert + +--connection child2_1 +--disable_query_log +echo CHILD2_1_CREATE_TABLES; +eval $CHILD2_1_CREATE_TABLES; +--enable_query_log +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +--disable_query_log +echo CREATE TABLE tbl_a ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + val int(10) unsigned DEFAULT NULL, + PRIMARY KEY(id) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_2_1; +eval CREATE TABLE tbl_a ( + id int(10) unsigned NOT NULL AUTO_INCREMENT, + val int(10) unsigned DEFAULT NULL, + PRIMARY KEY(id) +) $MASTER_1_ENGINE $MASTER_1_COMMENT_2_1; +--enable_query_log +INSERT INTO tbl_a (val) VALUES (1); + +--echo +--echo test 1 + +--connection child2_1 +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +SELECT id, 0 AS const, val FROM tbl_a; + +--connection child2_1 +eval $CHILD2_1_SELECT_ARGUMENT1; +eval $CHILD2_1_SELECT_TABLES; + +--echo +--echo deinit +--disable_warnings + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; + +--enable_warnings +--source ../include/mdev_20502_deinit.inc +--echo +--echo end of test diff --git a/storage/spider/mysql-test/spider/r/timestamp.result b/storage/spider/mysql-test/spider/r/timestamp.result index bd1f442d462..4e4badccc41 100644 --- a/storage/spider/mysql-test/spider/r/timestamp.result +++ b/storage/spider/mysql-test/spider/r/timestamp.result @@ -396,7 +396,7 @@ select t0.`col_d` `col_d`,t0.`col_t` `col_t` from `ts_test_remote`.`tbl_f` t0 select (timestamp(t0.`col_d` , t0.`col_t`)) `TIMESTAMP(col_d, col_t)` from `ts_test_remote`.`tbl_f` t0 select (timestamp('2018-06-25' , t0.`col_t`)) `TIMESTAMP('2018-06-25', col_t)` from `ts_test_remote`.`tbl_f` t0 select (timestamp(t0.`col_d` , '10:43:21')) `TIMESTAMP(col_d, '10:43:21')` from `ts_test_remote`.`tbl_f` t0 -select (timestamp('2018-06-25' , '10:43:21')) `TIMESTAMP('2018-06-25', '10:43:21')` from `ts_test_remote`.`tbl_f` t0 +select 1 from `ts_test_remote`.`tbl_f` t0 SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %' SELECT col_d, col_t FROM tbl_f; col_d col_t diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index e87321f896d..cea85b46657 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -3013,6 +3013,9 @@ int spider_db_fetch_table( #ifndef DBUG_OFF dbug_tmp_restore_column_map(table->write_set, tmp_map); #endif + } else { + DBUG_PRINT("info", ("spider bitmap is not set %s", + SPIDER_field_name_str(*field))); } row->next(); } diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 128cd494e7f..cac6b063ad0 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -14277,15 +14277,21 @@ int spider_mbase_handler::append_list_item_select( spider_fields *fields ) { int error_num; - uint32 length; + uint32 length, begin; List_iterator_fast it(*select); Item *item; Field *field; const char *item_name; DBUG_ENTER("spider_mbase_handler::append_list_item_select"); DBUG_PRINT("info",("spider this=%p", this)); + begin = str->length(); while ((item = it++)) { + if (item->const_item()) + { + DBUG_PRINT("info",("spider const item")); + continue; + } if ((error_num = spider_db_print_item_type(item, NULL, spider, str, alias, alias_length, dbton_id, use_fields, fields))) { @@ -14313,7 +14319,17 @@ int spider_mbase_handler::append_list_item_select( } str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); + if (begin == str->length()) + { + /* no columns */ + if (str->reserve(SPIDER_SQL_ONE_LEN)) + { + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + str->q_append(SPIDER_SQL_ONE_STR, SPIDER_SQL_ONE_LEN); + } else { + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + } DBUG_RETURN(0); } diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc index d3147c19f2f..b7e8100e480 100644 --- a/storage/spider/spd_db_oracle.cc +++ b/storage/spider/spd_db_oracle.cc @@ -12739,14 +12739,21 @@ int spider_oracle_handler::append_list_item_select( ) { int error_num; uint dbton_id = spider_dbton_oracle.dbton_id, length; + uint32 begin; List_iterator_fast it(*select); Item *item; Field *field; const char *item_name; DBUG_ENTER("spider_oracle_handler::append_list_item_select"); DBUG_PRINT("info",("spider this=%p", this)); + begin = str->length(); while ((item = it++)) { + if (item->const_item()) + { + DBUG_PRINT("info",("spider const item")); + continue; + } if ((error_num = spider_db_print_item_type(item, NULL, spider, str, alias, alias_length, dbton_id, use_fields, fields))) { @@ -12774,7 +12781,17 @@ int spider_oracle_handler::append_list_item_select( } str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); } - str->length(str->length() - SPIDER_SQL_COMMA_LEN); + if (begin == str->length()) + { + /* no columns */ + if (str->reserve(SPIDER_SQL_ONE_LEN)) + { + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + str->q_append(SPIDER_SQL_ONE_STR, SPIDER_SQL_ONE_LEN); + } else { + str->length(str->length() - SPIDER_SQL_COMMA_LEN); + } DBUG_RETURN(0); } diff --git a/storage/spider/spd_group_by_handler.cc b/storage/spider/spd_group_by_handler.cc index c83ee753e5b..8bd0eca507f 100644 --- a/storage/spider/spd_group_by_handler.cc +++ b/storage/spider/spd_group_by_handler.cc @@ -1794,6 +1794,11 @@ group_by_handler *spider_create_group_by_handler( while ((item = it++)) { DBUG_PRINT("info",("spider select item=%p", item)); + if (item->const_item()) + { + DBUG_PRINT("info",("spider const item")); + continue; + } if (spider_db_print_item_type(item, NULL, spider, NULL, NULL, 0, roop_count, TRUE, fields_arg)) { From de5e5ab2106fe37b857eed424f12d197d2c32082 Mon Sep 17 00:00:00 2001 From: Kentoku SHIBA Date: Tue, 5 May 2020 22:41:10 +0900 Subject: [PATCH 05/27] MDEV-20502 Queries against spider tables return wrong values for columns following constant declarations. Add test cases. --- .../spider/bugfix/r/mdev_20502.result | 24 +++++++++++++++++++ .../spider/bugfix/t/mdev_20502.test | 7 ++++++ 2 files changed, 31 insertions(+) diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result index 284f62e522e..e5f16b81329 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result @@ -36,14 +36,38 @@ connection master_1; SELECT id, 0 AS const, val FROM tbl_a; id const val 1 0 1 +SELECT 1+2, id, 0 AS const, val, val+10, (SELECT tbl_a.val+1 FROM tbl_a) AS sq +FROM tbl_a; +1+2 id const val val+10 sq +3 1 0 1 11 2 +INSERT INTO tbl_a (val) VALUES (2), (1); +SELECT val+10, 0 AS const, val, (SELECT tbl_a.val+1 FROM tbl_a LIMIT 1) AS sq +FROM tbl_a GROUP BY val; +val+10 const val sq +11 0 1 2 +12 0 2 2 +SELECT MAX(id) AS m, 0 AS const, val, (SELECT tbl_a.val+1 FROM tbl_a LIMIT 1) AS sq +FROM tbl_a GROUP BY val; +m const val sq +3 0 1 2 +2 0 2 2 connection child2_1; SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; argument select t0.`id` `id`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0 +select t0.`id` `id`,t0.`val` `val`,(t0.`val` + 10) `val+10` from `auto_test_remote`.`tbl_a` t0 +select (t0.`val` + 1) `tbl_a.val+1` from `auto_test_remote`.`tbl_a` t0 +select `id`,`val` from `auto_test_remote`.`tbl_a` order by `id` desc limit 1 for update +select (t0.`val` + 10) `val+10`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0 group by t0.`val` order by t0.`val` +select (t0.`val` + 1) `tbl_a.val+1` from `auto_test_remote`.`tbl_a` t0 limit 1 +select max(t0.`id`) `m`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0 group by t0.`val` order by t0.`val` +select (t0.`val` + 1) `tbl_a.val+1` from `auto_test_remote`.`tbl_a` t0 limit 1 SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %' SELECT id, val FROM tbl_a ORDER BY id; id val 1 1 +2 2 +3 1 deinit connection master_1; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test index 4693f2f7409..2d6ff5b4663 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_20502.test @@ -49,6 +49,13 @@ TRUNCATE TABLE mysql.general_log; --connection master_1 SELECT id, 0 AS const, val FROM tbl_a; +SELECT 1+2, id, 0 AS const, val, val+10, (SELECT tbl_a.val+1 FROM tbl_a) AS sq +FROM tbl_a; +INSERT INTO tbl_a (val) VALUES (2), (1); +SELECT val+10, 0 AS const, val, (SELECT tbl_a.val+1 FROM tbl_a LIMIT 1) AS sq +FROM tbl_a GROUP BY val; +SELECT MAX(id) AS m, 0 AS const, val, (SELECT tbl_a.val+1 FROM tbl_a LIMIT 1) AS sq +FROM tbl_a GROUP BY val; --connection child2_1 eval $CHILD2_1_SELECT_ARGUMENT1; From f7ff8f5dd9e99aa480bc7d56dff1a2a642f12b77 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Jan 2021 12:35:52 +0100 Subject: [PATCH 06/27] MDEV-24524 Assertion `ls->length < 0xFFFFFFFFL && ((ls->length == 0 && !ls->str) || ls->length == strlen(ls->str))' failed in String::append on SELECT from I_S don't expect return type of a stored function to be valid. it's read from a table, so can be messed with. it even can contain \0 bytes in the middle of the type name --- mysql-test/main/sp-ucs2.result | 8 +++++++- mysql-test/main/sp-ucs2.test | 14 +++++++++++--- sql/sp.cc | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/sp-ucs2.result b/mysql-test/main/sp-ucs2.result index ca448efa535..0f5624314d7 100644 --- a/mysql-test/main/sp-ucs2.result +++ b/mysql-test/main/sp-ucs2.result @@ -115,7 +115,6 @@ RETURN 'str'; END| ERROR 42000: COLLATION 'ucs2_unicode_ci' is not valid for CHARACTER SET 'latin1' SET NAMES utf8; -DROP FUNCTION IF EXISTS bug48766; CREATE FUNCTION bug48766 () RETURNS ENUM( 'w' ) CHARACTER SET ucs2 RETURN 0; @@ -140,3 +139,10 @@ WHERE ROUTINE_NAME='bug48766'; DTD_IDENTIFIER enum('а','б','в','г') DROP FUNCTION bug48766; +call mtr.add_suppression('invalid value in column mysql.proc.'); +set collation_connection=ucs2_general_ci; +insert into mysql.proc (db, name, type, specific_name, language, sql_data_access, is_deterministic, security_type, param_list, returns, body, definer, created, modified, sql_mode, comment, character_set_client, collation_connection, db_collation, body_utf8 ) values ( 'a', 'a', 'function', 'bug14233_1', 'sql', 'reads_sql_data', 'no', 'definer', '', 'int(10)', 'select * from mysql.user', 'root@localhost', now(), '0000-00-00 00:00:00', '', '', '', '', '', 'select * from mysql.user' ); +select * from information_schema.routines where routine_name='a'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +set collation_connection=default; +delete from mysql.proc where name='a'; diff --git a/mysql-test/main/sp-ucs2.test b/mysql-test/main/sp-ucs2.test index a1aec8071b4..004d62f4cc5 100644 --- a/mysql-test/main/sp-ucs2.test +++ b/mysql-test/main/sp-ucs2.test @@ -151,9 +151,6 @@ delimiter ;| # Bug#48766 SHOW CREATE FUNCTION returns extra data in return clause # SET NAMES utf8; ---disable_warnings -DROP FUNCTION IF EXISTS bug48766; ---enable_warnings # # Test that Latin letters are not prepended with extra '\0'. # @@ -175,3 +172,14 @@ SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME='bug48766'; DROP FUNCTION bug48766; + +# +# +# +call mtr.add_suppression('invalid value in column mysql.proc.'); +set collation_connection=ucs2_general_ci; +insert into mysql.proc (db, name, type, specific_name, language, sql_data_access, is_deterministic, security_type, param_list, returns, body, definer, created, modified, sql_mode, comment, character_set_client, collation_connection, db_collation, body_utf8 ) values ( 'a', 'a', 'function', 'bug14233_1', 'sql', 'reads_sql_data', 'no', 'definer', '', 'int(10)', 'select * from mysql.user', 'root@localhost', now(), '0000-00-00 00:00:00', '', '', '', '', '', 'select * from mysql.user' ); +--error ER_PARSE_ERROR +select * from information_schema.routines where routine_name='a'; +set collation_connection=default; +delete from mysql.proc where name='a'; diff --git a/sql/sp.cc b/sql/sp.cc index 98e94ac06cf..a4c4ca58414 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -2948,7 +2948,7 @@ Sp_handler::show_create_sp(THD *thd, String *buf, buf->append(STRING_WITH_LEN(" RETURN ")); else buf->append(STRING_WITH_LEN(" RETURNS ")); - buf->append(&returns); + buf->append(returns.str, returns.length); // Not \0 terminated } buf->append('\n'); switch (chistics.daccess) { From d463677f7e4226e15ec3814860164cf4c7229e5f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Jan 2021 15:39:36 +0100 Subject: [PATCH 07/27] failing to parse an SP should not abort information_schema.routines --- mysql-test/main/sp-ucs2.result | 7 +++++-- mysql-test/main/sp-ucs2.test | 3 +-- sql/sql_show.cc | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/sp-ucs2.result b/mysql-test/main/sp-ucs2.result index 0f5624314d7..389fa946ad5 100644 --- a/mysql-test/main/sp-ucs2.result +++ b/mysql-test/main/sp-ucs2.result @@ -142,7 +142,10 @@ DROP FUNCTION bug48766; call mtr.add_suppression('invalid value in column mysql.proc.'); set collation_connection=ucs2_general_ci; insert into mysql.proc (db, name, type, specific_name, language, sql_data_access, is_deterministic, security_type, param_list, returns, body, definer, created, modified, sql_mode, comment, character_set_client, collation_connection, db_collation, body_utf8 ) values ( 'a', 'a', 'function', 'bug14233_1', 'sql', 'reads_sql_data', 'no', 'definer', '', 'int(10)', 'select * from mysql.user', 'root@localhost', now(), '0000-00-00 00:00:00', '', '', '', '', '', 'select * from mysql.user' ); -select * from information_schema.routines where routine_name='a'; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +select routine_name from information_schema.routines where routine_name='a'; +routine_name +a +Warnings: +Warning 1601 Creation context of stored routine `a`.`a` is invalid set collation_connection=default; delete from mysql.proc where name='a'; diff --git a/mysql-test/main/sp-ucs2.test b/mysql-test/main/sp-ucs2.test index 004d62f4cc5..3276da3e257 100644 --- a/mysql-test/main/sp-ucs2.test +++ b/mysql-test/main/sp-ucs2.test @@ -179,7 +179,6 @@ DROP FUNCTION bug48766; call mtr.add_suppression('invalid value in column mysql.proc.'); set collation_connection=ucs2_general_ci; insert into mysql.proc (db, name, type, specific_name, language, sql_data_access, is_deterministic, security_type, param_list, returns, body, definer, created, modified, sql_mode, comment, character_set_client, collation_connection, db_collation, body_utf8 ) values ( 'a', 'a', 'function', 'bug14233_1', 'sql', 'reads_sql_data', 'no', 'definer', '', 'int(10)', 'select * from mysql.user', 'root@localhost', now(), '0000-00-00 00:00:00', '', '', '', '', '', 'select * from mysql.user' ); ---error ER_PARSE_ERROR -select * from information_schema.routines where routine_name='a'; +select routine_name from information_schema.routines where routine_name='a'; set collation_connection=default; delete from mysql.proc where name='a'; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index aef07fa4425..f25a8861bc1 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5059,7 +5059,8 @@ public: Sql_condition::enum_warning_level *level, const char* msg, Sql_condition ** cond_hdl) { - if (sql_errno == ER_TRG_NO_DEFINER || sql_errno == ER_TRG_NO_CREATION_CTX) + if (sql_errno == ER_TRG_NO_DEFINER || sql_errno == ER_TRG_NO_CREATION_CTX + || sql_errno == ER_PARSE_ERROR) return true; if (*level != Sql_condition::WARN_LEVEL_ERROR) From 83bbe36831e11adb8253132b5715b4b843e9bf09 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 4 Jan 2021 23:59:00 +0100 Subject: [PATCH 08/27] fix sporadic failures of main.processlist_notembedded the test was doing --replace_result $con_id con_id eval SHOW EXPLAIN FOR $con_id; with the intention of replacing the variable part of the statement in the result log. But actually replace_result replaces everything that matches. In particular, when $con_id is 100, the warning Note 1003 select sleep(100000) becomes Note con_id3 select sleep(con_id000) --- .../main/processlist_notembedded.result | 16 +++++++++------ mysql-test/main/processlist_notembedded.test | 20 +++++++++---------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/mysql-test/main/processlist_notembedded.result b/mysql-test/main/processlist_notembedded.result index ddde45f3031..26ca4ef8d0d 100644 --- a/mysql-test/main/processlist_notembedded.result +++ b/mysql-test/main/processlist_notembedded.result @@ -1,7 +1,7 @@ # # MDEV-20466: SHOW PROCESSLIST truncates query text on \0 bytes # -connect con1,localhost,root,,; +connect con1,localhost,root; connection con1; SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync WAIT_FOR go'; connection default; @@ -13,17 +13,21 @@ user disconnect con1; connection default; SET DEBUG_SYNC = 'RESET'; -End of 5.5 tests +# +# End of 5.5 tests +# # # MDEV-23752: SHOW EXPLAIN FOR thd waits for sleep # -connect con1,localhost,root,,; -select sleep(100000);; +connect con1,localhost,root; +select sleep(100000); connection default; -SHOW EXPLAIN FOR con_id; +SHOW EXPLAIN FOR $con_id; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select sleep(100000) -KILL QUERY con_id; +KILL QUERY $con_id; +# # End of 10.2 tests +# diff --git a/mysql-test/main/processlist_notembedded.test b/mysql-test/main/processlist_notembedded.test index 26021040c39..cc577200368 100644 --- a/mysql-test/main/processlist_notembedded.test +++ b/mysql-test/main/processlist_notembedded.test @@ -7,7 +7,7 @@ source include/count_sessions.inc; --echo # MDEV-20466: SHOW PROCESSLIST truncates query text on \0 bytes --echo # -connect (con1,localhost,root,,); +connect con1,localhost,root; connection con1; @@ -39,22 +39,22 @@ SET DEBUG_SYNC = 'RESET'; source include/wait_until_count_sessions.inc; ---echo End of 5.5 tests +--echo # +--echo # End of 5.5 tests +--echo # --echo # --echo # MDEV-23752: SHOW EXPLAIN FOR thd waits for sleep --echo # ---connect (con1,localhost,root,,) +--connect con1,localhost,root --let $con_id = `SELECT CONNECTION_ID()` ---send select sleep(100000); +--send select sleep(100000) --connection default +evalp SHOW EXPLAIN FOR $con_id; +evalp KILL QUERY $con_id; ---replace_result $con_id con_id -eval SHOW EXPLAIN FOR $con_id; - ---replace_result $con_id con_id -eval KILL QUERY $con_id; - +--echo # --echo # End of 10.2 tests +--echo # From f144ce2cfa086182fbd2b44408c70bd3456408f2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 5 Jan 2021 11:42:34 +0100 Subject: [PATCH 09/27] MDEV-20763 Table corruption or Assertion `btr_validate_index(index, 0, false)' failed in row_upd_sec_index_entry with virtual column and EMPTY_STRING_IS_NULL SQL mode unset empty_string_is_null mode when parsing generated columns in a table, this mode affects pasring. --- mysql-test/main/empty_string_literal.result | 29 +++++++++++++++++++++ mysql-test/main/empty_string_literal.test | 19 ++++++++++++++ sql/table.cc | 2 +- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/empty_string_literal.result b/mysql-test/main/empty_string_literal.result index 2ca491a7dd8..bbcf27cf993 100644 --- a/mysql-test/main/empty_string_literal.result +++ b/mysql-test/main/empty_string_literal.result @@ -179,3 +179,32 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select NULL AS `NULL` +# +# MDEV-20763 Table corruption or Assertion `btr_validate_index(index, 0, false)' failed in row_upd_sec_index_entry with virtual column and EMPTY_STRING_IS_NULL SQL mode +# +create table t1 (a int, b binary(1) generated always as (''), key(a,b)); +insert into t1 (a) values (1); +set sql_mode= default; +flush tables; +update t1 set a = 2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` binary(1) GENERATED ALWAYS AS (NULL) VIRTUAL, + KEY `a` (`a`,`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (a int, b binary(1) generated always as (''), key(a,b)); +insert into t1 (a) values (1); +set sql_mode= 'empty_string_is_null'; +flush tables; +update t1 set a = 2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` binary(1) GENERATED ALWAYS AS ('') VIRTUAL, + KEY `a` (`a`,`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/main/empty_string_literal.test b/mysql-test/main/empty_string_literal.test index 71e98d872bb..9174a7714a2 100644 --- a/mysql-test/main/empty_string_literal.test +++ b/mysql-test/main/empty_string_literal.test @@ -6,3 +6,22 @@ USE test; set @mode='EMPTY_STRING_IS_NULL'; --source include/empty_string_literal.inc + +--echo # +--echo # MDEV-20763 Table corruption or Assertion `btr_validate_index(index, 0, false)' failed in row_upd_sec_index_entry with virtual column and EMPTY_STRING_IS_NULL SQL mode +--echo # +create table t1 (a int, b binary(1) generated always as (''), key(a,b)); +insert into t1 (a) values (1); +set sql_mode= default; +flush tables; +update t1 set a = 2; +show create table t1; +drop table t1; + +create table t1 (a int, b binary(1) generated always as (''), key(a,b)); +insert into t1 (a) values (1); +set sql_mode= 'empty_string_is_null'; +flush tables; +update t1 set a = 2; +show create table t1; +drop table t1; diff --git a/sql/table.cc b/sql/table.cc index 403b68551a0..22cf3357ac7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1051,7 +1051,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, thd->stmt_arena= table->expr_arena; thd->update_charset(&my_charset_utf8mb4_general_ci, table->s->table_charset); expr_str.append(&parse_vcol_keyword); - thd->variables.sql_mode &= ~MODE_NO_BACKSLASH_ESCAPES; + thd->variables.sql_mode &= ~(MODE_NO_BACKSLASH_ESCAPES | MODE_EMPTY_STRING_IS_NULL); while (pos < end) { From 0ee086838d4b4497599d4e0822343269b682f913 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 10 Jan 2021 21:25:17 +0100 Subject: [PATCH 10/27] MDEV-16735 mysql_upgrade failed force alter_algorithm=DEFAULT in mysql_system_tables_fix.sql, in case my.cnf sets it to something incompatible --- scripts/mysql_system_tables_fix.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 0c39e62cc9a..0a10253c5b3 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -27,6 +27,7 @@ set sql_mode=''; set storage_engine=MyISAM; set enforce_storage_engine=NULL; +set alter_algorithm=DEFAULT; ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; From 3ffd5f28f04a34aadabb1966b861e6bc89f7fc73 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 10 Jan 2021 21:51:36 +0100 Subject: [PATCH 11/27] MDEV-17227 Server crash in TABLE_SHARE::init_from_sql_statement_string upon table discovery with non-existent database * failed init_from_binary_frm_image can clear share->db_plugin, don't use it on the error path * cleanup the test a bit --- .../suite/federated/assisted_discovery.result | 15 +++++++++---- .../suite/federated/assisted_discovery.test | 21 +++++++++++-------- sql/table.cc | 5 ++--- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/mysql-test/suite/federated/assisted_discovery.result b/mysql-test/suite/federated/assisted_discovery.result index 4818ff7bb02..e8d6663e9bc 100644 --- a/mysql-test/suite/federated/assisted_discovery.result +++ b/mysql-test/suite/federated/assisted_discovery.result @@ -13,8 +13,7 @@ CREATE TABLE t1 ( `name` varchar(32) default 'name') DEFAULT CHARSET=latin1; connection master; -CREATE TABLE t1 ENGINE=FEDERATED -CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +CREATE TABLE t1 ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -38,6 +37,9 @@ id group a\\b a\\ name 1 1 2 NULL foo 2 1 2 NULL fee DROP TABLE t1; +# +# MDEV-11311 Create federated table does not work as expected +# create table t1 ( a bigint(20) not null auto_increment, b bigint(20) not null, @@ -57,8 +59,7 @@ t1 CREATE TABLE `t1` ( KEY `b` (`b`,`c`,`d`(255)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 connection master; -create table t1 engine=federated -connection='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +create table t1 engine=federated connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -72,6 +73,12 @@ t1 CREATE TABLE `t1` ( drop table t1; connection slave; drop table t1; +# +# MDEV-17227 Server crash in TABLE_SHARE::init_from_sql_statement_string upon table discovery with non-existent database +# +connection master; +create table t1 engine=federated connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +ERROR HY000: Unable to connect to foreign data source: Table 'test.t1' doesn't exist connection master; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/assisted_discovery.test b/mysql-test/suite/federated/assisted_discovery.test index fa83a2a8e19..bd32878f811 100644 --- a/mysql-test/suite/federated/assisted_discovery.test +++ b/mysql-test/suite/federated/assisted_discovery.test @@ -13,9 +13,7 @@ CREATE TABLE t1 ( connection master; ---replace_result $SLAVE_MYPORT SLAVE_PORT -eval CREATE TABLE t1 ENGINE=FEDERATED - CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +evalp CREATE TABLE t1 ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; --replace_result $SLAVE_MYPORT SLAVE_PORT SHOW CREATE TABLE t1; @@ -30,9 +28,9 @@ connection slave; SELECT * FROM t1; DROP TABLE t1; -# -# -# +--echo # +--echo # MDEV-11311 Create federated table does not work as expected +--echo # create table t1 ( a bigint(20) not null auto_increment, b bigint(20) not null, @@ -44,9 +42,7 @@ create table t1 ( show create table t1; connection master; ---replace_result $SLAVE_MYPORT SLAVE_PORT -eval create table t1 engine=federated - connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +evalp create table t1 engine=federated connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; --replace_result $SLAVE_MYPORT SLAVE_PORT show create table t1; drop table t1; @@ -54,5 +50,12 @@ drop table t1; connection slave; drop table t1; +--echo # +--echo # MDEV-17227 Server crash in TABLE_SHARE::init_from_sql_statement_string upon table discovery with non-existent database +--echo # +connection master; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +evalp create table t1 engine=federated connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; + source include/federated_cleanup.inc; diff --git a/sql/table.cc b/sql/table.cc index 22cf3357ac7..254e2265633 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2869,9 +2869,8 @@ ret: if (unlikely(thd->is_error() || error)) { thd->clear_error(); - my_error(ER_SQL_DISCOVER_ERROR, MYF(0), - plugin_name(db_plugin)->str, db.str, table_name.str, - sql_copy); + my_error(ER_SQL_DISCOVER_ERROR, MYF(0), hton_name(hton)->str, + db.str, table_name.str, sql_copy); DBUG_RETURN(HA_ERR_GENERIC); } /* Treat the table as normal table from binary logging point of view */ From 778972684334d9881dbf735912f979caece50e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 12 Jan 2021 13:01:07 +0200 Subject: [PATCH 12/27] MDEV-24447 : galera.galera_toi_lock_shared MTR failed: WSREP: ALTER TABLE isolation failure Add wait_condition so that INSERT is replicated before ALTER and ALTER is replicated before we try to INSERT with new number of columns. --- .../galera/r/galera_toi_lock_shared.result | 21 +++++++++++++------ .../galera/t/galera_toi_lock_shared.test | 14 ++++++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_toi_lock_shared.result b/mysql-test/suite/galera/r/galera_toi_lock_shared.result index fe1c88075d5..ec54d1019e9 100644 --- a/mysql-test/suite/galera/r/galera_toi_lock_shared.result +++ b/mysql-test/suite/galera/r/galera_toi_lock_shared.result @@ -6,12 +6,21 @@ connection node_2; ALTER TABLE t1 ADD COLUMN f2 INTEGER, LOCK=SHARED; connection node_1; INSERT INTO t1 VALUES (2, 2); -SELECT COUNT(*) = 2 FROM t1; -COUNT(*) = 2 -1 +SELECT COUNT(*) AS EXPECT_2 FROM t1; +EXPECT_2 +2 +SELECT * FROM t1; +id f2 +1 NULL +2 2 connection node_2; INSERT INTO t1 VALUES (3, 3); -SELECT COUNT(*) = 3 FROM t1; -COUNT(*) = 3 -1 +SELECT COUNT(*) AS EXPECT_3 FROM t1; +EXPECT_3 +3 +SELECT * FROM t1; +id f2 +1 NULL +2 2 +3 3 DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_toi_lock_shared.test b/mysql-test/suite/galera/t/galera_toi_lock_shared.test index 6b7feec6031..566bc721926 100644 --- a/mysql-test/suite/galera/t/galera_toi_lock_shared.test +++ b/mysql-test/suite/galera/t/galera_toi_lock_shared.test @@ -10,17 +10,25 @@ CREATE TABLE t1 (id INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); --connection node_2 ---let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1'; +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1' +--source include/wait_condition.inc +--let $wait_condition = SELECT COUNT(*) = 1 FROM t1 --source include/wait_condition.inc ALTER TABLE t1 ADD COLUMN f2 INTEGER, LOCK=SHARED; --connection node_1 +--let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +--source include/wait_condition.inc INSERT INTO t1 VALUES (2, 2); -SELECT COUNT(*) = 2 FROM t1; +SELECT COUNT(*) AS EXPECT_2 FROM t1; +SELECT * FROM t1; --connection node_2 +--let $wait_condition = SELECT COUNT(*) = 2 FROM t1 +--source include/wait_condition.inc INSERT INTO t1 VALUES (3, 3); -SELECT COUNT(*) = 3 FROM t1; +SELECT COUNT(*) AS EXPECT_3 FROM t1; +SELECT * FROM t1; DROP TABLE t1; From 59998d3480f2a472cfc79208be4ee32ff5eff1ed Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 12 Jan 2021 18:44:24 +0300 Subject: [PATCH 13/27] MDEV-23446 Missed error code fix --- sql/sql_update.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index f24706fba19..3c40b003a3c 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2461,7 +2461,7 @@ error: if (has_vers_fields && table->versioned(VERS_TIMESTAMP)) { store_record(table, record[2]); - if (vers_insert_history_row(table)) + if (unlikely(error= vers_insert_history_row(table))) { restore_record(table, record[2]); goto error; From 403818f466ffbecca6d2ee2591f4eb93dd4b144b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 13 Jan 2021 08:45:03 +0200 Subject: [PATCH 14/27] MDEV-21523 : galera.MDEV-16509 MTR failed: timeout after 900 seconds: Can't connect to local MySQL server Test uses Galera debug sync. --- mysql-test/suite/galera/t/MDEV-16509.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/galera/t/MDEV-16509.test b/mysql-test/suite/galera/t/MDEV-16509.test index a17d7899939..ea4430d5e3f 100644 --- a/mysql-test/suite/galera/t/MDEV-16509.test +++ b/mysql-test/suite/galera/t/MDEV-16509.test @@ -5,7 +5,7 @@ --source include/galera_cluster.inc --source include/have_debug.inc --source include/have_debug_sync.inc - +--source include/galera_have_debug_sync.inc CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB; From 4afab3c7256e71a73ea95dd2c364454e57fceaeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 13 Jan 2021 13:08:07 +0200 Subject: [PATCH 15/27] MDEV-18542 : galera_sr.galera-features#56: Test failure: signal 6; mysqltest: Can't connect to local MySQL server Make test faster --- mysql-test/suite/galera_sr/disabled.def | 2 +- mysql-test/suite/galera_sr/r/galera-features#56.result | 10 +++++----- mysql-test/suite/galera_sr/t/galera-features#56.test | 9 +++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/mysql-test/suite/galera_sr/disabled.def b/mysql-test/suite/galera_sr/disabled.def index c0e5857d6bc..27b1d0768ae 100644 --- a/mysql-test/suite/galera_sr/disabled.def +++ b/mysql-test/suite/galera_sr/disabled.def @@ -11,5 +11,5 @@ ############################################################################## GCF-1060 : MDEV-20848 galera_sr.GCF_1060 -galera-features#56 : MDEV-18542 galera_sr.galera-features#56 + diff --git a/mysql-test/suite/galera_sr/r/galera-features#56.result b/mysql-test/suite/galera_sr/r/galera-features#56.result index a4264739cbf..15fcb475acb 100644 --- a/mysql-test/suite/galera_sr/r/galera-features#56.result +++ b/mysql-test/suite/galera_sr/r/galera-features#56.result @@ -18,21 +18,21 @@ set session wsrep_sync_wait=0; SET GLOBAL wsrep_slave_threads = 4; SET SESSION wsrep_trx_fragment_size = 1; connection node_1; -INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;; +INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2;; connection node_1a; -INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;; +INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2;; connection node_2; -INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;; +INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2;; connection node_1; connection node_1a; connection node_2; set session wsrep_sync_wait=15; SELECT COUNT(*) FROM t1; COUNT(*) -30000 +300 SELECT COUNT(DISTINCT f1) FROM t1; COUNT(DISTINCT f1) -30000 +300 connection default; DROP TABLE t1; DROP TABLE ten; diff --git a/mysql-test/suite/galera_sr/t/galera-features#56.test b/mysql-test/suite/galera_sr/t/galera-features#56.test index 4d46a3bf853..ac73c2efe3d 100644 --- a/mysql-test/suite/galera_sr/t/galera-features#56.test +++ b/mysql-test/suite/galera_sr/t/galera-features#56.test @@ -3,8 +3,6 @@ ## --source include/galera_cluster.inc ---source include/have_innodb.inc ---source include/big_test.inc # Create a second connection to node1 so that we can run transactions concurrently --let $galera_connection_name = node_1a @@ -19,7 +17,6 @@ INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 INTEGER) Engine=InnoDB; SET SESSION wsrep_trx_fragment_size = 1; - --connection node_2 set session wsrep_sync_wait=15; SELECT COUNT(*) from ten; @@ -35,13 +32,13 @@ SET GLOBAL wsrep_slave_threads = 4; SET SESSION wsrep_trx_fragment_size = 1; --connection node_1 ---send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4; +--send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2; --connection node_1a ---send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4; +--send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2; --connection node_2 ---send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4; +--send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2; --connection node_1 --reap From fb9a9599bc9faed7b2f4860cb5e2bc8c597aacef Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Tue, 12 Jan 2021 13:31:57 +0530 Subject: [PATCH 16/27] MDEV-24387: Wrong number of decimal digits in certain UNION/Subqery constellation Analysis: The decimals is set to NOT_FIXED_DEC for Field_str even if it is NULL. Unsigned has decimals=0. So Type_std_attributes::decimals is set to 39 (maximum between 0 and 39). This results in incorrect number of decimals when we have union of unsigned and NULL type. Fix: Check if the field is created from NULL value. If yes, set decimals to 0 otherwise set it to NOT_FIXED_DEC. --- mysql-test/main/union.result | 34 ++++++++++++++++++++++++++++++++++ mysql-test/main/union.test | 18 ++++++++++++++++++ sql/field.h | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index ea16e621e17..a892f6c9e40 100644 --- a/mysql-test/main/union.result +++ b/mysql-test/main/union.result @@ -2601,5 +2601,39 @@ Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where `test`.`t2`.`a` < 5 except /* select#2 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where `test`.`t3`.`a` < 5 union all /* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 drop table t1,t2,t3; # +# MDEV-24387: Wrong number of decimal digits in certain UNION/Subqery +# constellation +# +SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT * from (SELECT NULL) t; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def CAST(1 AS UNSIGNED) 246 2 1 Y 32896 0 63 +CAST(1 AS UNSIGNED) +1 +NULL +SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT NULL) t; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def CAST(1 AS SIGNED) 3 2 1 Y 32896 0 63 +CAST(1 AS SIGNED) +1 +NULL +SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT CAST(1 AS UNSIGNED)) t; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def CAST(1 AS SIGNED) 246 11 1 N 32897 0 63 +CAST(1 AS SIGNED) +1 +1 +SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT NULL; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def CAST(1 AS UNSIGNED) 246 2 1 Y 32896 0 63 +CAST(1 AS UNSIGNED) +1 +NULL +SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT CAST(1 AS SIGNED); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def CAST(1 AS UNSIGNED) 246 2 1 N 32897 0 63 +CAST(1 AS UNSIGNED) +1 +1 +# # End of 10.3 tests # diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test index 714b6abe131..ab629ce076d 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -1855,6 +1855,24 @@ select * from t1 where a > 4; drop table t1,t2,t3; +--echo # +--echo # MDEV-24387: Wrong number of decimal digits in certain UNION/Subqery +--echo # constellation +--echo # + +--disable_ps_protocol +--enable_metadata + +SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT * from (SELECT NULL) t; +SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT NULL) t; +SELECT CAST(1 AS SIGNED) UNION ALL SELECT * from (SELECT CAST(1 AS UNSIGNED)) t; + +SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT NULL; +SELECT CAST(1 AS UNSIGNED) UNION ALL SELECT CAST(1 AS SIGNED); + +--disable_metadata +--enable_ps_protocol + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/field.h b/sql/field.h index be3a648617b..1344774c189 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1762,7 +1762,7 @@ public: uchar null_bit_arg, utype unireg_check_arg, const LEX_CSTRING *field_name_arg, const DTCollation &collation); - uint decimals() const { return NOT_FIXED_DEC; } + uint decimals() const { return is_created_from_null_item ? 0 : NOT_FIXED_DEC; } int save_in_field(Field *to) { return save_in_field_str(to); } bool memcpy_field_possible(const Field *from) const { From f130adbf35b5b8ef7ed091549ed764982801480c Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Thu, 14 Jan 2021 14:31:20 +0700 Subject: [PATCH 17/27] MDEV-23666: Assertion `m_cpp_buf <= ptr && ptr <= m_cpp_buf + m_buf_length' failed in Lex_input_stream::body_utf8_append On parsing statements for which a starting backtick (`) delimiter doesn't have a corresponding ending backtick, a current pointer to a position inside a pre-processed buffer could go beyond the end of the buffer. This bug report caused by the commit d4967659032b18a5504198b41dd3d0a1813d79ef "MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds". In order to fix the issue both pointers m_ptr and m_cpp_ptr must be rolled back to previous position in raw input and pre-processed input streams correspondingly in case end of query reached during parsing. --- mysql-test/main/parser.result | 9 +++++++++ mysql-test/main/parser.test | 15 +++++++++++++++ sql/sql_lex.cc | 2 ++ 3 files changed, 26 insertions(+) diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 1c58c7379e4..658c26ae3e2 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -1784,4 +1784,13 @@ EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST'; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`systeminfo /FO LIST' at line 1 EXECUTE IMMEDIATE 'if(`systeminfo'; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`systeminfo' at line 1 +# +# MDEV-23666 Assertion failed in Lex_input_stream::body_utf8_append +# +SET @@sql_mode='ANSI_QUOTES'; +EXECUTE IMMEDIATE 'CREATE PROCEDURE p() UPDATE t SET c=\'\'"'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"' at line 1 +EXECUTE IMMEDIATE 'CREATE PROCEDURE p() UPDATE t SET c=\'\'"abc'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"abc' at line 1 +SET @@sql_mode=@save_sql_mode; # End of 10.3 tests diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test index 9fb68b92b8f..738ddf5c3b1 100644 --- a/mysql-test/main/parser.test +++ b/mysql-test/main/parser.test @@ -1561,4 +1561,19 @@ EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST'; --error ER_PARSE_ERROR EXECUTE IMMEDIATE 'if(`systeminfo'; +--echo # +--echo # MDEV-23666 Assertion failed in Lex_input_stream::body_utf8_append +--echo # +SET @@sql_mode='ANSI_QUOTES'; + +# Without a patch execution of the following statements results in assertion +# in Lex_input_stream::body_utf8_append on parsing the statement +--error ER_PARSE_ERROR +EXECUTE IMMEDIATE 'CREATE PROCEDURE p() UPDATE t SET c=\'\'"'; + +--error ER_PARSE_ERROR +EXECUTE IMMEDIATE 'CREATE PROCEDURE p() UPDATE t SET c=\'\'"abc'; + +SET @@sql_mode=@save_sql_mode; + --echo # End of 10.3 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 6116dee6e7e..b8f6610e066 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2215,6 +2215,8 @@ int Lex_input_stream::scan_ident_delimited(THD *thd, Return the quote character, to have the parser fail on syntax error. */ m_ptr= (char *) m_tok_start + 1; + if (m_echo) + m_cpp_ptr= (char *) m_cpp_tok_start + 1; return quote_char; } int var_length= my_charlen(cs, get_ptr() - 1, get_end_of_query()); From b87828b6c8d4f20e23e0c69132cb5c8a4232fbee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 14 Jan 2021 11:26:28 +0200 Subject: [PATCH 18/27] MDEV-22285 : Assertion `xid_seqno > wsrep_seqno' failed in trx_rseg_update_wsrep_checkpoint on SET @@global.wsrep_start_position Actual assertion mentioned on MDEV seems to be already fixed but setting seqno to -2 will trigger a different assertion mysqld: /home/jan/mysql/10.4-bugs/wsrep-lib/src/server_state.cpp:702: void wsrep::server_state::sst_received(wsrep::client_service&, int): Assertion `state_ == s_joiner || state_ == s_initialized' failed. Fixed this by not allowing user to set seqno < -1 (-1 is special seqno meaning undefined and seqno is initialized to it). MariaDB releases 10.2 and 10.3 already do not allow to set seqno < -1. --- .../r/wsrep_start_position_basic.result | 57 ++++++++++++++++--- .../t/wsrep_start_position_basic.test | 28 +++++++-- sql/wsrep_var.cc | 7 ++- 3 files changed, 78 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/wsrep_start_position_basic.result b/mysql-test/suite/sys_vars/r/wsrep_start_position_basic.result index a49e6135d47..255d8239530 100644 --- a/mysql-test/suite/sys_vars/r/wsrep_start_position_basic.result +++ b/mysql-test/suite/sys_vars/r/wsrep_start_position_basic.result @@ -1,7 +1,6 @@ # # wsrep_start_position # -# save the initial value SET @wsrep_start_position_global_saved = @@global.wsrep_start_position; # default SELECT @@global.wsrep_start_position; @@ -11,46 +10,90 @@ SELECT @@global.wsrep_start_position; # scope SELECT @@session.wsrep_start_position; ERROR HY000: Variable 'wsrep_start_position' is a GLOBAL variable -SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-1'; SELECT @@global.wsrep_start_position; @@global.wsrep_start_position 00000000-0000-0000-0000-000000000000:-1 # valid values -SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2'; -SELECT @@global.wsrep_start_position; -@@global.wsrep_start_position -00000000-0000-0000-0000-000000000000:-2 SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; SELECT @@global.wsrep_start_position; @@global.wsrep_start_position 12345678-1234-1234-1234-123456789012:100 -SET @@global.wsrep_start_position=default; +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0'; +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:0 +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-1'; SELECT @@global.wsrep_start_position; @@global.wsrep_start_position 00000000-0000-0000-0000-000000000000:-1 # invalid values +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '00000000-0000-0000-0000-000000000000:-2' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2A'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '00000000-0000-0000-0000-000000000000:-2A' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0A'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '00000000-0000-0000-0000-000000000000:0A' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='000000000000000-0000-0000-0000-000000000000:-1'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '000000000000000-0000-0000-0000-000000000000:-1' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='12345678-1234-1234-12345-123456789012:100'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-12345-123456789012:100' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='12345678-1234-123-12345-123456789012:0'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-123-12345-123456789012:0' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:_99999'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:_99999' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:a'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:a' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='OFF'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of 'OFF' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position=ON; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of 'ON' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position=''; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position=NULL; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of 'NULL' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='junk'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of 'junk' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 # restore the initial value SET @@global.wsrep_start_position = @wsrep_start_position_global_saved; diff --git a/mysql-test/suite/sys_vars/t/wsrep_start_position_basic.test b/mysql-test/suite/sys_vars/t/wsrep_start_position_basic.test index 3e57cfa6da2..4bac87bdc84 100644 --- a/mysql-test/suite/sys_vars/t/wsrep_start_position_basic.test +++ b/mysql-test/suite/sys_vars/t/wsrep_start_position_basic.test @@ -4,7 +4,6 @@ --echo # wsrep_start_position --echo # ---echo # save the initial value SET @wsrep_start_position_global_saved = @@global.wsrep_start_position; --echo # default @@ -14,40 +13,59 @@ SELECT @@global.wsrep_start_position; --echo # scope --error ER_INCORRECT_GLOBAL_LOCAL_VAR SELECT @@session.wsrep_start_position; -SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-1'; SELECT @@global.wsrep_start_position; + --echo --echo # valid values -SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2'; -SELECT @@global.wsrep_start_position; SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; SELECT @@global.wsrep_start_position; -SET @@global.wsrep_start_position=default; +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0'; +SELECT @@global.wsrep_start_position; +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-1'; SELECT @@global.wsrep_start_position; --echo --echo # invalid values --error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2'; +SELECT @@global.wsrep_start_position; +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2A'; +SELECT @@global.wsrep_start_position; +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0A'; +SELECT @@global.wsrep_start_position; +--error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='000000000000000-0000-0000-0000-000000000000:-1'; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='12345678-1234-1234-12345-123456789012:100'; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='12345678-1234-123-12345-123456789012:0'; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:_99999'; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:a'; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='OFF'; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position=ON; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position=''; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position=NULL; +SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='junk'; +SELECT @@global.wsrep_start_position; --echo --echo # restore the initial value diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 5336bc9f508..727750ea794 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -212,8 +212,11 @@ bool wsrep_start_position_verify (const char* start_str) return true; char* endptr; - wsrep_seqno_t const seqno __attribute__((unused)) // to avoid GCC warnings - (strtoll(&start_str[uuid_len + 1], &endptr, 10)); + wsrep_seqno_t const seqno(strtoll(&start_str[uuid_len + 1], &endptr, 10)); + + // Do not allow seqno < -1 + if (*endptr == '\0' && seqno < -1) + return true; // Remaining string was seqno. if (*endptr == '\0') return false; From 8bcddb02b7ba9399677e866a01d86279047beae1 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Tue, 19 Jan 2021 16:08:46 +0700 Subject: [PATCH 19/27] MDEV-24577: Fix warnings generated during compilation of plugin/auth_pam/testing/pam_mariadb_mtr.c on FreeBSD Compiler warnings generated on building MariaDB server for BSD has the same reason as in case building is performed on MacOS. Both platforms do use clang as a C/C++ compiler. So, fix the compiler warnings in case the compiler is clang doesn't matter what kind of building platform do we use for building. This is a follow-up patch for the following bug reports: MDEV-23564: CMAKE failing due to deprecated Apple GSS method MDEV-23935: Fix warnings generated during compilation of plugin/auth_pam/testing/pam_mariadb_mtr.c on MacOS --- libmariadb | 2 +- plugin/auth_gssapi/CMakeLists.txt | 2 +- plugin/auth_pam/testing/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libmariadb b/libmariadb index e3824422064..018663324bf 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit e38244220646a7e95c9be22576460aa7a4eb715f +Subproject commit 018663324bf9cbe11b0b2191c6fb6c10564bb4e5 diff --git a/plugin/auth_gssapi/CMakeLists.txt b/plugin/auth_gssapi/CMakeLists.txt index 4d3718dd471..3205a58ebbe 100644 --- a/plugin/auth_gssapi/CMakeLists.txt +++ b/plugin/auth_gssapi/CMakeLists.txt @@ -18,7 +18,7 @@ ELSE() SET(GSSAPI_SERVER gssapi_server.cc) SET(GSSAPI_ERRMSG gssapi_errmsg.cc) - IF(APPLE) + IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") SET_SOURCE_FILES_PROPERTIES( ${GSSAPI_CLIENT} ${GSSAPI_SERVER} ${GSSAPI_ERRMSG} PROPERTY COMPILE_FLAGS "-Wno-deprecated-declarations") diff --git a/plugin/auth_pam/testing/CMakeLists.txt b/plugin/auth_pam/testing/CMakeLists.txt index c8d2e3cbb97..151823b9419 100644 --- a/plugin/auth_pam/testing/CMakeLists.txt +++ b/plugin/auth_pam/testing/CMakeLists.txt @@ -4,7 +4,7 @@ ADD_LIBRARY(pam_mariadb_mtr MODULE pam_mariadb_mtr.c) SET_TARGET_PROPERTIES (pam_mariadb_mtr PROPERTIES PREFIX "") TARGET_LINK_LIBRARIES(pam_mariadb_mtr pam) -IF(APPLE) +IF(CMAKE_C_COMPILER_ID MATCHES "Clang") SET_SOURCE_FILES_PROPERTIES( pam_mariadb_mtr.c PROPERTY COMPILE_FLAGS "-Wno-incompatible-pointer-types-discards-qualifiers") From 7d04ce6a2d42770fcc765d257c0058a859180b80 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Thu, 14 Jan 2021 18:18:06 +0200 Subject: [PATCH 20/27] MDEV-21153 Replica nodes crash due to indexed virtual columns and FK cascading delete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix for MDEV-23033 fixes a problem in replication applying of transactions, which contain cascading foreign key delete for a table, which has indexed virtual column. This fix adds slave_fk_event_map flag for table, to mark when the prelocking is needed for applying of a transaction. See commit 608b0ee52ef3e854ce14a407e64e936adbbeba23 for more details. However, this fix is targeted for async replication only, Rows_log_event::do_apply_event() has condition to rule out galera replication from the fix domain, and use cases suffering from MDEV-23033 and related MDEV-21153 will fail in galera cluster. The fix in this commit removes the condition to rule out the setting of slave_fk_event_map flag from galera replication, and makes the fix in MDEV-23033 effective for galera replication as well. Finally, a mtr test for virtual column support has been added. galera.galera_virtual_column.test has as first test a scenario from MDEV-21153 Reviewed-by: Jan Lindström --- .../galera/r/galera_virtual_column.result | 17 ++++++++ .../suite/galera/t/galera_virtual_column.test | 42 +++++++++++++++++++ sql/log_event.cc | 2 +- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_virtual_column.result create mode 100644 mysql-test/suite/galera/t/galera_virtual_column.test diff --git a/mysql-test/suite/galera/r/galera_virtual_column.result b/mysql-test/suite/galera/r/galera_virtual_column.result new file mode 100644 index 00000000000..c4b425964c5 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_virtual_column.result @@ -0,0 +1,17 @@ +connection node_1; +CREATE TABLE p (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT) ENGINE = InnoDB; +CREATE TABLE c (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, pid INT UNSIGNED, bitmap TINYINT UNSIGNED NOT NULL DEFAULT 0, bitmap5 TINYINT UNSIGNED GENERATED ALWAYS AS (bitmap&(1<<5)) VIRTUAL, FOREIGN KEY (pid) REFERENCES p (id) ON DELETE CASCADE ON UPDATE CASCADE); +CREATE INDEX bitmap5 ON c(bitmap5) USING BTREE; +INSERT INTO p VALUES(1); +INSERT INTO c(pid) VALUES(1); +connection node_2; +connection node_1; +DELETE FROM p WHERE id=1; +SELECT * FROM p; +id +SELECT * FROM c; +id pid bitmap bitmap5 +connection node_2; +connection node_1; +DROP TABLE c; +DROP TABLE p; diff --git a/mysql-test/suite/galera/t/galera_virtual_column.test b/mysql-test/suite/galera/t/galera_virtual_column.test new file mode 100644 index 00000000000..84e1da024f1 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_virtual_column.test @@ -0,0 +1,42 @@ +# +# This test is for testing virtual columnm support in galera cluster +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# test case for verifying that cascaded delete in a table with virtual column does not crash slave node +# + +--connection node_1 + +CREATE TABLE p (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT) ENGINE = InnoDB; +CREATE TABLE c (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, pid INT UNSIGNED, bitmap TINYINT UNSIGNED NOT NULL DEFAULT 0, bitmap5 TINYINT UNSIGNED GENERATED ALWAYS AS (bitmap&(1<<5)) VIRTUAL, FOREIGN KEY (pid) REFERENCES p (id) ON DELETE CASCADE ON UPDATE CASCADE); + +# not sure of this index is needed for the test +CREATE INDEX bitmap5 ON c(bitmap5) USING BTREE; + +INSERT INTO p VALUES(1); +INSERT INTO c(pid) VALUES(1); + + +--connection node_2 +# wait until both INSERTS have arrived in node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM c +--source include/wait_condition.inc + +--connection node_1 +# delete from parent table, it will cascade into child table +# node_2 might have problem in applying this cascaded delete +DELETE FROM p WHERE id=1; + +SELECT * FROM p; +SELECT * FROM c; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM c; +--source include/wait_condition.inc + +--connection node_1 +DROP TABLE c; +DROP TABLE p; diff --git a/sql/log_event.cc b/sql/log_event.cc index 48a25c8ba3d..e344fc8894f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11357,7 +11357,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) tables->trg_event_map= new_trg_event_map; lex->query_tables_last= &tables->next_global; } - else if (!WSREP_ON) + else { tables->slave_fk_event_map= new_trg_event_map; lex->query_tables_last= &tables->next_global; From 9377e9ba0c8c2b6a89d47e545eb292a6973ad2fb Mon Sep 17 00:00:00 2001 From: sjaakola Date: Thu, 14 Jan 2021 18:18:06 +0200 Subject: [PATCH 21/27] MDEV-21153 Replica nodes crash due to indexed virtual columns and FK cascading delete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix for MDEV-23033 fixes a problem in replication applying of transactions, which contain cascading foreign key delete for a table, which has indexed virtual column. This fix adds slave_fk_event_map flag for table, to mark when the prelocking is needed for applying of a transaction. See commit 608b0ee52ef3e854ce14a407e64e936adbbeba23 for more details. However, this fix is targeted for async replication only, Rows_log_event::do_apply_event() has condition to rule out galera replication from the fix domain, and use cases suffering from MDEV-23033 and related MDEV-21153 will fail in galera cluster. The fix in this commit removes the condition to rule out the setting of slave_fk_event_map flag from galera replication, and makes the fix in MDEV-23033 effective for galera replication as well. However, the above fix has caused regressions for some galera_sr suite tests, which run tests for streaming replication. This regression can be observed e.g. by: /mtr galera_sr.galera_sr_multirow_rollback --mysqld=--slave_run_triggers_for_rbr=yes These galera_sr suite tests were failing in last phase of replication applying, where actual transaction is already applied, and streaming replication related meta data needs to be updated in wsrep system tables. Opening the wsrep system tables failed for corrupt data in THD::lex:query_tables_list. The fix in this commit uses back query table list for the duration of fragment update operation. Finally, a mtr test for virtual column support has been added. galera.galera_virtual_column.test has as first test a scenario from MDEV-21153 new fix Reviewed-by: Jan Lindström --- .../galera/r/galera_virtual_column.result | 19 +++++++++ .../suite/galera/t/galera_virtual_column.test | 42 +++++++++++++++++++ sql/log_event.cc | 2 +- sql/wsrep_schema.cc | 21 ++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/galera/r/galera_virtual_column.result create mode 100644 mysql-test/suite/galera/t/galera_virtual_column.test diff --git a/mysql-test/suite/galera/r/galera_virtual_column.result b/mysql-test/suite/galera/r/galera_virtual_column.result new file mode 100644 index 00000000000..71820ed8225 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_virtual_column.result @@ -0,0 +1,19 @@ +connection node_2; +connection node_1; +connection node_1; +CREATE TABLE p (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT) ENGINE = InnoDB; +CREATE TABLE c (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, pid INT UNSIGNED, bitmap TINYINT UNSIGNED NOT NULL DEFAULT 0, bitmap5 TINYINT UNSIGNED GENERATED ALWAYS AS (bitmap&(1<<5)) VIRTUAL, FOREIGN KEY (pid) REFERENCES p (id) ON DELETE CASCADE ON UPDATE CASCADE); +CREATE INDEX bitmap5 ON c(bitmap5) USING BTREE; +INSERT INTO p VALUES(1); +INSERT INTO c(pid) VALUES(1); +connection node_2; +connection node_1; +DELETE FROM p WHERE id=1; +SELECT * FROM p; +id +SELECT * FROM c; +id pid bitmap bitmap5 +connection node_2; +connection node_1; +DROP TABLE c; +DROP TABLE p; diff --git a/mysql-test/suite/galera/t/galera_virtual_column.test b/mysql-test/suite/galera/t/galera_virtual_column.test new file mode 100644 index 00000000000..84e1da024f1 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_virtual_column.test @@ -0,0 +1,42 @@ +# +# This test is for testing virtual columnm support in galera cluster +# +--source include/galera_cluster.inc +--source include/have_innodb.inc + +# +# test case for verifying that cascaded delete in a table with virtual column does not crash slave node +# + +--connection node_1 + +CREATE TABLE p (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT) ENGINE = InnoDB; +CREATE TABLE c (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, pid INT UNSIGNED, bitmap TINYINT UNSIGNED NOT NULL DEFAULT 0, bitmap5 TINYINT UNSIGNED GENERATED ALWAYS AS (bitmap&(1<<5)) VIRTUAL, FOREIGN KEY (pid) REFERENCES p (id) ON DELETE CASCADE ON UPDATE CASCADE); + +# not sure of this index is needed for the test +CREATE INDEX bitmap5 ON c(bitmap5) USING BTREE; + +INSERT INTO p VALUES(1); +INSERT INTO c(pid) VALUES(1); + + +--connection node_2 +# wait until both INSERTS have arrived in node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM c +--source include/wait_condition.inc + +--connection node_1 +# delete from parent table, it will cascade into child table +# node_2 might have problem in applying this cascaded delete +DELETE FROM p WHERE id=1; + +SELECT * FROM p; +SELECT * FROM c; + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 0 FROM c; +--source include/wait_condition.inc + +--connection node_1 +DROP TABLE c; +DROP TABLE p; diff --git a/sql/log_event.cc b/sql/log_event.cc index e3079c5f9b9..20a41dc8aee 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11392,7 +11392,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) tables->trg_event_map= new_trg_event_map; lex->query_tables_last= &tables->next_global; } - else if (!WSREP_ON) + else { tables->slave_fk_event_map= new_trg_event_map; lex->query_tables_last= &tables->next_global; diff --git a/sql/wsrep_schema.cc b/sql/wsrep_schema.cc index 8a47bbec9b0..9a09fbc8902 100644 --- a/sql/wsrep_schema.cc +++ b/sql/wsrep_schema.cc @@ -899,6 +899,13 @@ int Wsrep_schema::append_fragment(THD* thd, thd->thread_id, os.str().c_str(), transaction_id.get()); + /* use private query table list for the duration of fragment storing, + populated query table list from "parent DML" may cause problems .e.g + for virtual column handling + */ + Query_tables_list query_tables_list_backup; + thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup); + Wsrep_schema_impl::binlog_off binlog_off(thd); Wsrep_schema_impl::init_stmt(thd); @@ -906,6 +913,7 @@ int Wsrep_schema::append_fragment(THD* thd, if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table)) { trans_rollback_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } @@ -919,9 +927,11 @@ int Wsrep_schema::append_fragment(THD* thd, if ((error= Wsrep_schema_impl::insert(frag_table))) { WSREP_ERROR("Failed to write to frag table: %d", error); trans_rollback_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(0); } @@ -938,6 +948,13 @@ int Wsrep_schema::update_fragment_meta(THD* thd, ws_meta.seqno().get()); DBUG_ASSERT(ws_meta.seqno().is_undefined() == false); + /* use private query table list for the duration of fragment storing, + populated query table list from "parent DML" may cause problems .e.g + for virtual column handling + */ + Query_tables_list query_tables_list_backup; + thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup); + Wsrep_schema_impl::binlog_off binlog_off(thd); int error; uchar key[MAX_KEY_LENGTH+MAX_FIELD_WIDTH]; @@ -947,6 +964,7 @@ int Wsrep_schema::update_fragment_meta(THD* thd, Wsrep_schema_impl::init_stmt(thd); if (Wsrep_schema_impl::open_for_write(thd, sr_table_str.c_str(), &frag_table)) { + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } @@ -967,6 +985,7 @@ int Wsrep_schema::update_fragment_meta(THD* thd, error); } Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } @@ -982,11 +1001,13 @@ int Wsrep_schema::update_fragment_meta(THD* thd, frag_table->s->table_name.str, error); Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(1); } int ret= Wsrep_schema_impl::end_index_scan(frag_table); Wsrep_schema_impl::finish_stmt(thd); + thd->lex->restore_backup_query_tables_list(&query_tables_list_backup); DBUG_RETURN(ret); } From be5fce16a0d4104b216818438ca624bfaa19497a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 19 Jan 2021 10:00:05 +0200 Subject: [PATCH 22/27] MDEV-24596 : Assertion `state_ == s_exec || state_ == s_quitting' failed in wsrep::client_state::disable_streaming There were multiple problems here * wsrep_trx_fragment_size should not be set when wsrep is disabled or provider is not loaded * wsrep_trx_fragment_unit should not be set when wsrep is disabled or provider is not loaded * wsrep_debug has no effect if wsrep is disabled or provider is not loaded * wsrep_start_position should not be set when wsrep is disabled or provider is not loaded any other value than default * wsrep_start_position should be changed only when we are joiner or initialized * wsrep_start_position should be allowed to set only a value that exits, thus we need to add error handling to wsrep_sst_complete --- mysql-test/suite/galera/disabled.def | 3 + .../r/galera_var_wsrep_start_position.result} | 21 +++-- .../t/galera_var_wsrep_start_position.test} | 16 ++-- .../suite/sys_vars/r/wsrep_debug_basic.result | 8 +- .../r/wsrep_variables_no_provider.result | 44 +++++++++++ .../wsrep/r/wsrep_variables_wsrep_off.result | 39 ++++++++++ .../wsrep/t/wsrep_variables_no_provider.cnf | 12 +++ .../wsrep/t/wsrep_variables_no_provider.test | 38 +++++++++ .../wsrep/t/wsrep_variables_wsrep_off.cnf | 12 +++ .../wsrep/t/wsrep_variables_wsrep_off.test | 30 +++++++ sql/wsrep_priv.h | 2 +- sql/wsrep_sst.cc | 41 ++++++++-- sql/wsrep_var.cc | 78 +++++++++++++++---- 13 files changed, 306 insertions(+), 38 deletions(-) rename mysql-test/suite/{sys_vars/r/wsrep_start_position_basic.result => galera/r/galera_var_wsrep_start_position.result} (91%) rename mysql-test/suite/{sys_vars/t/wsrep_start_position_basic.test => galera/t/galera_var_wsrep_start_position.test} (94%) create mode 100644 mysql-test/suite/wsrep/r/wsrep_variables_no_provider.result create mode 100644 mysql-test/suite/wsrep/r/wsrep_variables_wsrep_off.result create mode 100644 mysql-test/suite/wsrep/t/wsrep_variables_no_provider.cnf create mode 100644 mysql-test/suite/wsrep/t/wsrep_variables_no_provider.test create mode 100644 mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.cnf create mode 100644 mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.test diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 046feac5566..509841a823b 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -23,6 +23,7 @@ galera_binlog_stmt_autoinc : MDEV-19959 Galera test failure on galera_binlog_stm galera_encrypt_tmp_files : Get error failed to enable encryption of temporary files galera_ftwrl : MDEV-21525 galera.galera_ftwrl galera_gcache_recover_manytrx : MDEV-18834 Galera test failure +galera_ist_mysqldump : MDEV-24463 galera.galera_sst_mysqldump_with_key MTR failed: 'INSERT failed: 1213: Deadlock found when trying to get lock galera_kill_largechanges : MDEV-18179 Galera test failure on galera.galera_kill_largechanges galera_kill_nochanges : MDEV-18280 Galera test failure on galera_split_brain and galera_kill_nochanges galera_many_tables_nopk : MDEV-18182 Galera test failure on galera.galera_many_tables_nopk @@ -33,6 +34,8 @@ galera_shutdown_nonprim : MDEV-21493 galera.galera_shutdown_nonprim galera_split_brain : MDEV-18280 Galera test failure on galera_split_brain and galera_kill_nochanges galera_ssl_upgrade : MDEV-19950 Galera test failure on galera_ssl_upgrade galera_sst_mariabackup_encrypt_with_key : MDEV-21484 galera_sst_mariabackup_encrypt_with_key +galera_sst_mysqldump : MDEV-24463 galera.galera_sst_mysqldump_with_key MTR failed: 'INSERT failed: 1213: Deadlock found when trying to get lock +galera_sst_mysqldump_with_key : MDEV-24463 galera.galera_sst_mysqldump_with_key MTR failed: 'INSERT failed: 1213: Deadlock found when trying to get lock galera_toi_ddl_nonconflicting : MDEV-21518 galera.galera_toi_ddl_nonconflicting galera_toi_truncate : MDEV-22996 Hang on galera_toi_truncate test case galera_var_node_address : MDEV-20485 Galera test failure diff --git a/mysql-test/suite/sys_vars/r/wsrep_start_position_basic.result b/mysql-test/suite/galera/r/galera_var_wsrep_start_position.result similarity index 91% rename from mysql-test/suite/sys_vars/r/wsrep_start_position_basic.result rename to mysql-test/suite/galera/r/galera_var_wsrep_start_position.result index 255d8239530..3d409f90eac 100644 --- a/mysql-test/suite/sys_vars/r/wsrep_start_position_basic.result +++ b/mysql-test/suite/galera/r/galera_var_wsrep_start_position.result @@ -1,6 +1,9 @@ +connection node_2; +connection node_1; # # wsrep_start_position # +CALL mtr.add_suppression("WSREP: SST failed for position .*"); SET @wsrep_start_position_global_saved = @@global.wsrep_start_position; # default SELECT @@global.wsrep_start_position; @@ -15,20 +18,22 @@ SELECT @@global.wsrep_start_position; 00000000-0000-0000-0000-000000000000:-1 # valid values -SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; -SELECT @@global.wsrep_start_position; -@@global.wsrep_start_position -12345678-1234-1234-1234-123456789012:100 -SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0'; -SELECT @@global.wsrep_start_position; -@@global.wsrep_start_position -00000000-0000-0000-0000-000000000000:0 SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-1'; SELECT @@global.wsrep_start_position; @@global.wsrep_start_position 00000000-0000-0000-0000-000000000000:-1 +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '00000000-0000-0000-0000-000000000000:0' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 # invalid values +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2'; ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '00000000-0000-0000-0000-000000000000:-2' SELECT @@global.wsrep_start_position; diff --git a/mysql-test/suite/sys_vars/t/wsrep_start_position_basic.test b/mysql-test/suite/galera/t/galera_var_wsrep_start_position.test similarity index 94% rename from mysql-test/suite/sys_vars/t/wsrep_start_position_basic.test rename to mysql-test/suite/galera/t/galera_var_wsrep_start_position.test index 4bac87bdc84..43fd09b902c 100644 --- a/mysql-test/suite/sys_vars/t/wsrep_start_position_basic.test +++ b/mysql-test/suite/galera/t/galera_var_wsrep_start_position.test @@ -1,11 +1,12 @@ ---source include/have_wsrep.inc +--source include/galera_cluster.inc --echo # --echo # wsrep_start_position --echo # -SET @wsrep_start_position_global_saved = @@global.wsrep_start_position; +CALL mtr.add_suppression("WSREP: SST failed for position .*"); +SET @wsrep_start_position_global_saved = @@global.wsrep_start_position; --echo # default SELECT @@global.wsrep_start_position; @@ -15,19 +16,20 @@ SELECT @@global.wsrep_start_position; SELECT @@session.wsrep_start_position; SELECT @@global.wsrep_start_position; - --echo --echo # valid values -SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; -SELECT @@global.wsrep_start_position; -SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0'; -SELECT @@global.wsrep_start_position; SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-1'; SELECT @@global.wsrep_start_position; --echo +--error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:0'; +SELECT @@global.wsrep_start_position; --echo # invalid values --error ER_WRONG_VALUE_FOR_VAR +SET @@global.wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; +SELECT @@global.wsrep_start_position; +--error ER_WRONG_VALUE_FOR_VAR SET @@global.wsrep_start_position='00000000-0000-0000-0000-000000000000:-2'; SELECT @@global.wsrep_start_position; --error ER_WRONG_VALUE_FOR_VAR diff --git a/mysql-test/suite/sys_vars/r/wsrep_debug_basic.result b/mysql-test/suite/sys_vars/r/wsrep_debug_basic.result index 47d00f5dede..1c9c2ddf3a3 100644 --- a/mysql-test/suite/sys_vars/r/wsrep_debug_basic.result +++ b/mysql-test/suite/sys_vars/r/wsrep_debug_basic.result @@ -16,9 +16,11 @@ SELECT @@global.wsrep_debug; @@global.wsrep_debug NONE SET @@global.wsrep_debug=1; +Warnings: +Warning 1231 Setting 'wsrep_debug' has no effect because wsrep is switched off SELECT @@global.wsrep_debug; @@global.wsrep_debug -SERVER +NONE # valid values SET @@global.wsrep_debug=NONE; @@ -26,9 +28,11 @@ SELECT @@global.wsrep_debug; @@global.wsrep_debug NONE SET @@global.wsrep_debug=SERVER; +Warnings: +Warning 1231 Setting 'wsrep_debug' has no effect because wsrep is switched off SELECT @@global.wsrep_debug; @@global.wsrep_debug -SERVER +NONE SET @@global.wsrep_debug=default; SELECT @@global.wsrep_debug; @@global.wsrep_debug diff --git a/mysql-test/suite/wsrep/r/wsrep_variables_no_provider.result b/mysql-test/suite/wsrep/r/wsrep_variables_no_provider.result new file mode 100644 index 00000000000..ad35dc8dbcd --- /dev/null +++ b/mysql-test/suite/wsrep/r/wsrep_variables_no_provider.result @@ -0,0 +1,44 @@ +SELECT @@wsrep_on; +@@wsrep_on +1 +SET @wsrep_slave_threads_global_saved = @@global.wsrep_slave_threads; +SET @wsrep_debug_saved = @@global.wsrep_debug; +SET @wsrep_provider_options_saved= @@global.wsrep_provider_options; +SET @wsrep_cluster_address_saved= @@global.wsrep_cluster_address; +SET GLOBAL wsrep_provider=none; +SET SESSION wsrep_trx_fragment_size=DEFAULT; +ERROR HY000: Incorrect arguments to SET +SELECT @@session.wsrep_trx_fragment_size; +@@session.wsrep_trx_fragment_size +0 +SET GLOBAL wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100' +SHOW WARNINGS; +Level Code Message +Warning 1231 Cannot set 'wsrep_start_position' because wsrep is switched off or provider is not loaded +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 +SET GLOBAL wsrep_debug=1; +Warnings: +Warning 1231 Setting 'wsrep_debug' has no effect because wsrep is switched off +SELECT @@global.wsrep_debug; +@@global.wsrep_debug +NONE +SET GLOBAL wsrep_slave_threads=5; +SELECT @@global.wsrep_slave_threads; +@@global.wsrep_slave_threads +5 +SET GLOBAL wsrep_desync=1; +ERROR HY000: WSREP (galera) not started +SELECT @@global.wsrep_desync; +@@global.wsrep_desync +0 +SET SESSION wsrep_trx_fragment_unit='rows'; +ERROR HY000: Incorrect arguments to SET +SELECT @@session.wsrep_trx_fragment_unit; +@@session.wsrep_trx_fragment_unit +rows +SET @@global.wsrep_slave_threads = @wsrep_slave_threads_global_saved; +SET @@global.wsrep_debug = @wsrep_debug_saved; diff --git a/mysql-test/suite/wsrep/r/wsrep_variables_wsrep_off.result b/mysql-test/suite/wsrep/r/wsrep_variables_wsrep_off.result new file mode 100644 index 00000000000..7cae89eae8e --- /dev/null +++ b/mysql-test/suite/wsrep/r/wsrep_variables_wsrep_off.result @@ -0,0 +1,39 @@ +SELECT @@wsrep_on; +@@wsrep_on +0 +SET @wsrep_slave_threads_global_saved = @@global.wsrep_slave_threads; +SET @wsrep_debug_saved = @@global.wsrep_debug; +SET SESSION wsrep_trx_fragment_size=DEFAULT; +ERROR HY000: Incorrect arguments to SET +SELECT @@session.wsrep_trx_fragment_size; +@@session.wsrep_trx_fragment_size +0 +SET GLOBAL wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; +ERROR 42000: Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100' +SHOW WARNINGS; +Level Code Message +Warning 1231 Cannot set 'wsrep_start_position' because wsrep is switched off or provider is not loaded +Error 1231 Variable 'wsrep_start_position' can't be set to the value of '12345678-1234-1234-1234-123456789012:100' +SELECT @@global.wsrep_start_position; +@@global.wsrep_start_position +00000000-0000-0000-0000-000000000000:-1 +SET GLOBAL wsrep_debug=1; +Warnings: +Warning 1231 Setting 'wsrep_debug' has no effect because wsrep is switched off +SELECT @@global.wsrep_debug; +@@global.wsrep_debug +NONE +SET GLOBAL wsrep_slave_threads=5; +SELECT @@global.wsrep_slave_threads; +@@global.wsrep_slave_threads +5 +SET GLOBAL wsrep_desync=1; +ERROR HY000: WSREP (galera) not started +SELECT @@global.wsrep_desync; +@@global.wsrep_desync +0 +SET SESSION wsrep_trx_fragment_unit='rows'; +ERROR HY000: Incorrect arguments to SET +SELECT @@session.wsrep_trx_fragment_unit; +@@session.wsrep_trx_fragment_unit +rows diff --git a/mysql-test/suite/wsrep/t/wsrep_variables_no_provider.cnf b/mysql-test/suite/wsrep/t/wsrep_variables_no_provider.cnf new file mode 100644 index 00000000000..b73146d26e7 --- /dev/null +++ b/mysql-test/suite/wsrep/t/wsrep_variables_no_provider.cnf @@ -0,0 +1,12 @@ +# Use default setting for mysqld processes +!include include/default_mysqld.cnf + +[mysqld.1] +wsrep-on=ON +binlog-format=ROW +wsrep-provider=@ENV.WSREP_PROVIDER +wsrep-cluster-address='gcomm://' +#galera_port=@OPT.port +#ist_port=@OPT.port +#sst_port=@OPT.port + diff --git a/mysql-test/suite/wsrep/t/wsrep_variables_no_provider.test b/mysql-test/suite/wsrep/t/wsrep_variables_no_provider.test new file mode 100644 index 00000000000..b44c9c5ebc8 --- /dev/null +++ b/mysql-test/suite/wsrep/t/wsrep_variables_no_provider.test @@ -0,0 +1,38 @@ +--source include/have_wsrep.inc +--source include/have_innodb.inc + +SELECT @@wsrep_on; + +SET @wsrep_slave_threads_global_saved = @@global.wsrep_slave_threads; +SET @wsrep_debug_saved = @@global.wsrep_debug; +SET @wsrep_provider_options_saved= @@global.wsrep_provider_options; +SET @wsrep_cluster_address_saved= @@global.wsrep_cluster_address; + +SET GLOBAL wsrep_provider=none; + +--error ER_WRONG_ARGUMENTS +SET SESSION wsrep_trx_fragment_size=DEFAULT; +SELECT @@session.wsrep_trx_fragment_size; +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; +SHOW WARNINGS; +SELECT @@global.wsrep_start_position; +SET GLOBAL wsrep_debug=1; +SELECT @@global.wsrep_debug; +SET GLOBAL wsrep_slave_threads=5; +SELECT @@global.wsrep_slave_threads; +--error ER_WRONG_ARGUMENTS +SET GLOBAL wsrep_desync=1; +SELECT @@global.wsrep_desync; +--error ER_WRONG_ARGUMENTS +SET SESSION wsrep_trx_fragment_unit='rows'; +SELECT @@session.wsrep_trx_fragment_unit; + +--disable_query_log +eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER'; +SET GLOBAL wsrep_cluster_address= @wsrep_cluster_address_saved; +SET GLOBAL wsrep_provider_options= @wsrep_provider_options_saved; +--source include/galera_wait_ready.inc +SET @@global.wsrep_slave_threads = @wsrep_slave_threads_global_saved; +SET @@global.wsrep_debug = @wsrep_debug_saved; +--enable_query_log diff --git a/mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.cnf b/mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.cnf new file mode 100644 index 00000000000..2e66b1ef23c --- /dev/null +++ b/mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.cnf @@ -0,0 +1,12 @@ +# Use default setting for mysqld processes +!include include/default_mysqld.cnf + +[mysqld] +wsrep-on=OFF + +[mysqld.1] +wsrep-on=OFF +#galera_port=@OPT.port +#ist_port=@OPT.port +#sst_port=@OPT.port + diff --git a/mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.test b/mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.test new file mode 100644 index 00000000000..4a9cd2bad5f --- /dev/null +++ b/mysql-test/suite/wsrep/t/wsrep_variables_wsrep_off.test @@ -0,0 +1,30 @@ +--source include/have_wsrep.inc +--source include/have_innodb.inc + +SELECT @@wsrep_on; + +SET @wsrep_slave_threads_global_saved = @@global.wsrep_slave_threads; +SET @wsrep_debug_saved = @@global.wsrep_debug; + +--error ER_WRONG_ARGUMENTS +SET SESSION wsrep_trx_fragment_size=DEFAULT; +SELECT @@session.wsrep_trx_fragment_size; +--error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL wsrep_start_position='12345678-1234-1234-1234-123456789012:100'; +SHOW WARNINGS; +SELECT @@global.wsrep_start_position; +SET GLOBAL wsrep_debug=1; +SELECT @@global.wsrep_debug; +SET GLOBAL wsrep_slave_threads=5; +SELECT @@global.wsrep_slave_threads; +--error ER_WRONG_ARGUMENTS +SET GLOBAL wsrep_desync=1; +SELECT @@global.wsrep_desync; +--error ER_WRONG_ARGUMENTS +SET SESSION wsrep_trx_fragment_unit='rows'; +SELECT @@session.wsrep_trx_fragment_unit; + +--disable_query_log +SET @@global.wsrep_slave_threads = @wsrep_slave_threads_global_saved; +SET @@global.wsrep_debug = @wsrep_debug_saved; +--enable_query_log diff --git a/sql/wsrep_priv.h b/sql/wsrep_priv.h index e480331ba65..fb8467adc9d 100644 --- a/sql/wsrep_priv.h +++ b/sql/wsrep_priv.h @@ -42,7 +42,7 @@ extern wsrep_seqno_t local_seqno; extern Wsrep_schema* wsrep_schema; // a helper function -void wsrep_sst_received(THD*, const wsrep_uuid_t&, wsrep_seqno_t, +bool wsrep_sst_received(THD*, const wsrep_uuid_t&, wsrep_seqno_t, const void*, size_t); void wsrep_notify_status(enum wsrep::server_state::state status, diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index c024f08dd22..227cd6b4769 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -308,12 +308,37 @@ bool wsrep_before_SE() } // Signal end of SST -static void wsrep_sst_complete (THD* thd, - int const rcode) +static bool wsrep_sst_complete (THD* thd, + int const rcode, + wsrep::gtid const sst_gtid) { Wsrep_client_service client_service(thd, thd->wsrep_cs()); - Wsrep_server_state::instance().sst_received(client_service, rcode); + Wsrep_server_state& server_state= Wsrep_server_state::instance(); + enum wsrep::server_state::state state= server_state.state(); + bool failed= false; + + // Do not call sst_received if we are not in joiner or + // initialized state on server. This is because it + // assumes we are on those states. Give error if we are + // in incorrect state. + if ((state == Wsrep_server_state::s_joiner || + state == Wsrep_server_state::s_initialized)) + Wsrep_server_state::instance().sst_received(client_service, + rcode); + else + { + char start_pos_buf[FN_REFLEN]; + ssize_t len= wsrep::print_to_c_str(sst_gtid, start_pos_buf, FN_REFLEN-1); + start_pos_buf[len]='\0'; + WSREP_ERROR("SST failed for position %s initialized %d server_state %s", + start_pos_buf, + server_state.is_initialized(), + wsrep::to_c_string(state)); + failed= true; + } + wsrep_joiner_monitor_end(); + return failed; } /* @@ -325,13 +350,15 @@ static void wsrep_sst_complete (THD* thd, @param seqno [IN] Initial state sequence number @param state [IN] Always NULL, also ignored by wsrep provider (?) @param state_len [IN] Always 0, also ignored by wsrep provider (?) + @return true when successful, false if error */ -void wsrep_sst_received (THD* thd, +bool wsrep_sst_received (THD* thd, const wsrep_uuid_t& uuid, wsrep_seqno_t const seqno, const void* const state, size_t const state_len) { + bool error= false; /* To keep track of whether the local uuid:seqno should be updated. Also, note that local state (uuid:seqno) is updated/checkpointed only after we get an @@ -371,8 +398,10 @@ void wsrep_sst_received (THD* thd, if (WSREP_ON) { int const rcode(seqno < 0 ? seqno : 0); - wsrep_sst_complete(thd,rcode); + error= wsrep_sst_complete(thd,rcode, sst_gtid); } + + return error; } static int sst_scan_uuid_seqno (const char* str, @@ -653,7 +682,7 @@ err: /* Read committed isolation to avoid gap locking */ thd->variables.tx_isolation= ISO_READ_COMMITTED; - wsrep_sst_complete (thd, -err); + wsrep_sst_complete (thd, -err, ret_gtid); delete thd; my_thread_end(); diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 727750ea794..266ff9459ac 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -234,7 +234,7 @@ bool wsrep_set_local_position(THD* thd, const char* const value, wsrep_seqno_t const seqno= strtoll(value + uuid_len + 1, NULL, 10); if (sst) { - wsrep_sst_received (thd, uuid, seqno, NULL, 0); + return (wsrep_sst_received (thd, uuid, seqno, NULL, 0)); } else { local_uuid= uuid; local_seqno= seqno; @@ -258,15 +258,28 @@ bool wsrep_start_position_check (sys_var *self, THD* thd, set_var* var) // Verify the format. if (wsrep_start_position_verify(start_pos_buf)) return true; + // Give error if position is updated when wsrep is not enabled or + // provider is not loaded. + if ((!WSREP_ON || !Wsrep_server_state::instance().is_provider_loaded()) + && strcmp(start_pos_buf, WSREP_START_POSITION_ZERO)) + { + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_start_position' because " + "wsrep is switched off or provider is not loaded"); + goto err; + } + /* As part of further verification, we try to update the value and catch - errors (if any). + errors (if any) only when value actually has been changed. */ - if (wsrep_set_local_position(thd, var->save_result.string_value.str, + if (strcmp(start_pos_buf, wsrep_start_position)) + { + if (wsrep_set_local_position(thd, var->save_result.string_value.str, var->save_result.string_value.length, true)) - { - goto err; + goto err; } return false; @@ -289,7 +302,7 @@ bool wsrep_start_position_init (const char* val) { if (NULL == val || wsrep_start_position_verify (val)) { - WSREP_ERROR("Bad initial value for wsrep_start_position: %s", + WSREP_ERROR("Bad initial value for wsrep_start_position: %s", (val ? val : "")); return true; } @@ -403,8 +416,8 @@ bool wsrep_provider_update (sys_var *self, THD* thd, enum_var_type type) void wsrep_provider_init (const char* value) { - WSREP_DEBUG("wsrep_provider_init: %s -> %s", - (wsrep_provider) ? wsrep_provider : "null", + WSREP_DEBUG("wsrep_provider_init: %s -> %s", + (wsrep_provider) ? wsrep_provider : "null", (value) ? value : "null"); if (NULL == value || wsrep_provider_verify (value)) { @@ -443,7 +456,7 @@ bool wsrep_provider_options_update(sys_var *self, THD* thd, enum_var_type type) void wsrep_provider_options_init(const char* value) { - if (wsrep_provider_options && wsrep_provider_options != value) + if (wsrep_provider_options && wsrep_provider_options != value) my_free((void *)wsrep_provider_options); wsrep_provider_options= (value) ? my_strdup(value, MYF(0)) : NULL; } @@ -472,8 +485,21 @@ bool wsrep_reject_queries_update(sys_var *self, THD* thd, enum_var_type type) bool wsrep_debug_update(sys_var *self, THD* thd, enum_var_type type) { + // Give warnings if wsrep_debug is set and wsrep is disabled or + // provider is not loaded, it will not have any effect + if ((!WSREP_ON || !Wsrep_server_state::instance().is_provider_loaded()) + && wsrep_debug) + { + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Setting 'wsrep_debug' has no effect because " + "wsrep is switched off"); + wsrep_debug= 0; + } + else Wsrep_server_state::instance().debug_log_level(wsrep_debug); - return false; + + return false; } static int wsrep_cluster_address_verify (const char* cluster_address_str) @@ -511,11 +537,11 @@ bool wsrep_cluster_address_update (sys_var *self, THD* thd, enum_var_type type) return false; } - /* stop replication is heavy operation, and includes closing all client + /* stop replication is heavy operation, and includes closing all client connections. Closing clients may need to get LOCK_global_system_variables at least in MariaDB. - Note: releasing LOCK_global_system_variables may cause race condition, if + Note: releasing LOCK_global_system_variables may cause race condition, if there can be several concurrent clients changing wsrep_provider */ WSREP_DEBUG("wsrep_cluster_address_update: %s", wsrep_cluster_address); @@ -544,8 +570,8 @@ bool wsrep_cluster_address_update (sys_var *self, THD* thd, enum_var_type type) void wsrep_cluster_address_init (const char* value) { - WSREP_DEBUG("wsrep_cluster_address_init: %s -> %s", - (wsrep_cluster_address) ? wsrep_cluster_address : "null", + WSREP_DEBUG("wsrep_cluster_address_init: %s -> %s", + (wsrep_cluster_address) ? wsrep_cluster_address : "null", (value) ? value : "null"); my_free((void*) wsrep_cluster_address); @@ -745,6 +771,18 @@ bool wsrep_trx_fragment_size_update(sys_var* self, THD *thd, enum_var_type) { WSREP_DEBUG("wsrep_trx_fragment_size_update: %llu", thd->variables.wsrep_trx_fragment_size); + + // Give error if wsrep_trx_fragment_size is set and wsrep is disabled or + // provider is not loaded + if (!WSREP_ON || !Wsrep_server_state::instance().is_provider_loaded()) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_trx_fragment_size' because " + "wsrep is switched off"); + return true; + } + if (thd->variables.wsrep_trx_fragment_size) { return thd->wsrep_cs().enable_streaming( @@ -762,6 +800,18 @@ bool wsrep_trx_fragment_unit_update(sys_var* self, THD *thd, enum_var_type) { WSREP_DEBUG("wsrep_trx_fragment_unit_update: %lu", thd->variables.wsrep_trx_fragment_unit); + + // Give error if wsrep_trx_fragment_unit is set and wsrep is disabled or + // provider is not loaded + if (!WSREP_ON || !Wsrep_server_state::instance().is_provider_loaded()) + { + push_warning (thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Cannot set 'wsrep_trx_fragment_unit' because " + "wsrep is switched off"); + return true; + } + if (thd->variables.wsrep_trx_fragment_size) { return thd->wsrep_cs().enable_streaming( From 61feb568bbbfc3ea68060bf9f59b4c3eeb999ca0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 21 Jan 2021 15:30:19 +0100 Subject: [PATCH 23/27] remove now-unused rdiff file --- mysql-test/main/information_schema,debug.rdiff | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 mysql-test/main/information_schema,debug.rdiff diff --git a/mysql-test/main/information_schema,debug.rdiff b/mysql-test/main/information_schema,debug.rdiff deleted file mode 100644 index c4ef0a41547..00000000000 --- a/mysql-test/main/information_schema,debug.rdiff +++ /dev/null @@ -1,11 +0,0 @@ ---- mysql-test/main/information_schema.result -+++ mysql-test/main/information_schema.result -@@ -2210,7 +2210,7 @@ - SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` LIMIT ROWS EXAMINED 10; - TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT IS_GENERATED GENERATION_EXPRESSION - Warnings: --Warning 1931 Query execution was interrupted. The query examined at least 671 rows, which exceeds LIMIT ROWS EXAMINED (10). The query result may be incomplete -+Warning 1931 Query execution was interrupted. The query examined at least 12 rows, which exceeds LIMIT ROWS EXAMINED (10). The query result may be incomplete - # - # End of 10.2 Test - # From 4e503aec7feaeb2297035f565ca92c98d4557577 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 21 Jan 2021 16:40:36 +0100 Subject: [PATCH 24/27] MDEV-24593 Signal 11 when group by primary key of table joined to information_schema.columns I_S tables were materialized too late, an attempt to use table statistics before the table was created caused a crash. Let's move table creation up. it only needs read_set to be calculated properly, this happens in JOIN::optimize_inner(), after semijoin transformation. Note that tables are not populated at that point, so most of the statistics would make no sense anyway. But at least field sizes will be correct. And it won't crash. --- mysql-test/main/information_schema.result | 9 ++ mysql-test/main/information_schema.test | 10 +++ sql/sql_select.cc | 6 +- sql/sql_show.cc | 102 ++++++++++++---------- sql/sql_show.h | 1 + storage/heap/ha_heap.cc | 3 - storage/maria/ha_maria.cc | 3 - 7 files changed, 79 insertions(+), 55 deletions(-) diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 7aa7a075eb0..dc8a23bf511 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -2282,5 +2282,14 @@ create table t2 (n int); insert into t1 set n = (select table_rows from information_schema.tables where table_name='t2'); drop table t1, t2; # +# MDEV-24593 Signal 11 when group by primary key of table joined to information_schema.columns +# +create table t1 (f varchar(64) primary key); +select f from information_schema.columns i +inner join t1 on f=i.column_name +group by f; +f +drop table t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test index 97e5fe6b0bd..018a10be255 100644 --- a/mysql-test/main/information_schema.test +++ b/mysql-test/main/information_schema.test @@ -2007,6 +2007,16 @@ create table t2 (n int); insert into t1 set n = (select table_rows from information_schema.tables where table_name='t2'); drop table t1, t2; + +--echo # +--echo # MDEV-24593 Signal 11 when group by primary key of table joined to information_schema.columns +--echo # +create table t1 (f varchar(64) primary key); +select f from information_schema.columns i +inner join t1 on f=i.column_name +group by f; +drop table t1; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 203422f0b43..8baac124b71 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1556,7 +1556,7 @@ int JOIN::init_join_caches() int JOIN::optimize_inner() { - DBUG_ENTER("JOIN::optimize"); + DBUG_ENTER("JOIN::optimize_inner"); subq_exit_fl= false; do_send_rows = (unit->select_limit_cnt) ? 1 : 0; @@ -1624,6 +1624,10 @@ JOIN::optimize_inner() table_count= select_lex->leaf_tables.elements; + if (select_lex->options & OPTION_SCHEMA_TABLE && + optimize_schema_tables_memory_usage(select_lex->leaf_tables)) + DBUG_RETURN(1); + if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ DBUG_RETURN(-1); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index f25a8861bc1..9a5141fa414 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -8658,55 +8658,64 @@ end: } -static int optimize_schema_tables_memory_usage(TABLE_LIST *table_list) +bool optimize_schema_tables_memory_usage(List &tables) { - TABLE *table= table_list->table; - THD *thd=table->in_use; - if (!table->is_created()) + List_iterator tli(tables); + + while (TABLE_LIST *table_list= tli++) { - TMP_TABLE_PARAM *p= table_list->schema_table_param; - TMP_ENGINE_COLUMNDEF *from_recinfo, *to_recinfo; - DBUG_ASSERT(table->s->keys == 0); - DBUG_ASSERT(table->s->uniques == 0); + TABLE *table= table_list->table; + THD *thd=table->in_use; - uchar *cur= table->field[0]->ptr; - /* first recinfo could be a NULL bitmap, not an actual Field */ - from_recinfo= to_recinfo= p->start_recinfo + (cur != table->record[0]); - for (uint i=0; i < table->s->fields; i++, from_recinfo++) - { - Field *field= table->field[i]; - DBUG_ASSERT(field->vcol_info == 0); - DBUG_ASSERT(from_recinfo->length); - DBUG_ASSERT(from_recinfo->length == field->pack_length_in_rec()); - if (bitmap_is_set(table->read_set, i)) - { - field->move_field(cur); - *to_recinfo++= *from_recinfo; - cur+= from_recinfo->length; - } - else - { - field= new (thd->mem_root) Field_string(cur, 0, field->null_ptr, - field->null_bit, Field::NONE, - &field->field_name, field->dtcollation()); - field->init(table); - field->field_index= i; - DBUG_ASSERT(field->pack_length_in_rec() == 0); - table->field[i]= field; - } - } - if ((table->s->reclength= (ulong)(cur - table->record[0])) == 0) - { - /* all fields were optimized away. Force a non-0-length row */ - table->s->reclength= to_recinfo->length= 1; - to_recinfo++; - } - p->recinfo= to_recinfo; + if (!table_list->schema_table || !thd->fill_information_schema_tables()) + continue; - // TODO switch from Aria to Memory if all blobs were optimized away? - if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo, - table_list->select_lex->options | thd->variables.option_bits)) - return 1; + if (!table->is_created()) + { + TMP_TABLE_PARAM *p= table_list->schema_table_param; + TMP_ENGINE_COLUMNDEF *from_recinfo, *to_recinfo; + DBUG_ASSERT(table->s->keys == 0); + DBUG_ASSERT(table->s->uniques == 0); + + uchar *cur= table->field[0]->ptr; + /* first recinfo could be a NULL bitmap, not an actual Field */ + from_recinfo= to_recinfo= p->start_recinfo + (cur != table->record[0]); + for (uint i=0; i < table->s->fields; i++, from_recinfo++) + { + Field *field= table->field[i]; + DBUG_ASSERT(field->vcol_info == 0); + DBUG_ASSERT(from_recinfo->length); + DBUG_ASSERT(from_recinfo->length == field->pack_length_in_rec()); + if (bitmap_is_set(table->read_set, i)) + { + field->move_field(cur); + *to_recinfo++= *from_recinfo; + cur+= from_recinfo->length; + } + else + { + field= new (thd->mem_root) Field_string(cur, 0, field->null_ptr, + field->null_bit, Field::NONE, + &field->field_name, field->dtcollation()); + field->init(table); + field->field_index= i; + DBUG_ASSERT(field->pack_length_in_rec() == 0); + table->field[i]= field; + } + } + if ((table->s->reclength= (ulong)(cur - table->record[0])) == 0) + { + /* all fields were optimized away. Force a non-0-length row */ + table->s->reclength= to_recinfo->length= 1; + to_recinfo++; + } + p->recinfo= to_recinfo; + + // TODO switch from Aria to Memory if all blobs were optimized away? + if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo, + table_list->select_lex->options | thd->variables.option_bits)) + return 1; + } } return 0; } @@ -8732,9 +8741,6 @@ bool optimize_schema_tables_reads(JOIN *join) TABLE_LIST *table_list= tab->table->pos_in_table_list; if (table_list->schema_table && thd->fill_information_schema_tables()) { - if (optimize_schema_tables_memory_usage(table_list)) - DBUG_RETURN(1); - /* A value of 0 indicates a dummy implementation */ if (table_list->schema_table->fill_table == 0) continue; diff --git a/sql/sql_show.h b/sql/sql_show.h index 39cbc35230a..c1845d8c1b3 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -238,6 +238,7 @@ public: }; bool optimize_schema_tables_reads(JOIN *join); +bool optimize_schema_tables_memory_usage(List &tables); /* Handle the ignored database directories list for SHOW/I_S. */ bool ignore_db_dirs_init(); diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index a40f4b8a464..5af68f098a4 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -363,9 +363,6 @@ int ha_heap::info(uint flag) { HEAPINFO hp_info; - if (!table) - return 0; - (void) heap_info(file,&hp_info,flag); errkey= hp_info.errkey; diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 23d2becbb04..c0163473f3a 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2440,9 +2440,6 @@ int ha_maria::info(uint flag) MARIA_INFO maria_info; char name_buff[FN_REFLEN]; - if (!table) - return 0; - (void) maria_status(file, &maria_info, flag); if (flag & HA_STATUS_VARIABLE) { From ce141d0714207afb70911abce21c2a4055b8a9e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 22 Jan 2021 12:12:42 +0200 Subject: [PATCH 25/27] MDEV-24463 : galera.galera_sst_mysqldump_with_key MTR failed: 'INSERT failed: 1213: Deadlock found when trying to get lock We need to complete SST if both new and old start positions are not same as initial positions. If they are initial positions just set local uuid and seqno. --- mysql-test/suite/galera/disabled.def | 3 --- sql/wsrep_sst.cc | 9 +++++--- sql/wsrep_var.cc | 34 ++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 509841a823b..046feac5566 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -23,7 +23,6 @@ galera_binlog_stmt_autoinc : MDEV-19959 Galera test failure on galera_binlog_stm galera_encrypt_tmp_files : Get error failed to enable encryption of temporary files galera_ftwrl : MDEV-21525 galera.galera_ftwrl galera_gcache_recover_manytrx : MDEV-18834 Galera test failure -galera_ist_mysqldump : MDEV-24463 galera.galera_sst_mysqldump_with_key MTR failed: 'INSERT failed: 1213: Deadlock found when trying to get lock galera_kill_largechanges : MDEV-18179 Galera test failure on galera.galera_kill_largechanges galera_kill_nochanges : MDEV-18280 Galera test failure on galera_split_brain and galera_kill_nochanges galera_many_tables_nopk : MDEV-18182 Galera test failure on galera.galera_many_tables_nopk @@ -34,8 +33,6 @@ galera_shutdown_nonprim : MDEV-21493 galera.galera_shutdown_nonprim galera_split_brain : MDEV-18280 Galera test failure on galera_split_brain and galera_kill_nochanges galera_ssl_upgrade : MDEV-19950 Galera test failure on galera_ssl_upgrade galera_sst_mariabackup_encrypt_with_key : MDEV-21484 galera_sst_mariabackup_encrypt_with_key -galera_sst_mysqldump : MDEV-24463 galera.galera_sst_mysqldump_with_key MTR failed: 'INSERT failed: 1213: Deadlock found when trying to get lock -galera_sst_mysqldump_with_key : MDEV-24463 galera.galera_sst_mysqldump_with_key MTR failed: 'INSERT failed: 1213: Deadlock found when trying to get lock galera_toi_ddl_nonconflicting : MDEV-21518 galera.galera_toi_ddl_nonconflicting galera_toi_truncate : MDEV-22996 Hang on galera_toi_truncate test case galera_var_node_address : MDEV-20485 Galera test failure diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 227cd6b4769..b7a7dadf0dc 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -316,6 +316,9 @@ static bool wsrep_sst_complete (THD* thd, Wsrep_server_state& server_state= Wsrep_server_state::instance(); enum wsrep::server_state::state state= server_state.state(); bool failed= false; + char start_pos_buf[FN_REFLEN]; + ssize_t len= wsrep::print_to_c_str(sst_gtid, start_pos_buf, FN_REFLEN-1); + start_pos_buf[len]='\0'; // Do not call sst_received if we are not in joiner or // initialized state on server. This is because it @@ -323,13 +326,13 @@ static bool wsrep_sst_complete (THD* thd, // in incorrect state. if ((state == Wsrep_server_state::s_joiner || state == Wsrep_server_state::s_initialized)) + { Wsrep_server_state::instance().sst_received(client_service, rcode); + WSREP_INFO("SST succeeded for position %s", start_pos_buf); + } else { - char start_pos_buf[FN_REFLEN]; - ssize_t len= wsrep::print_to_c_str(sst_gtid, start_pos_buf, FN_REFLEN-1); - start_pos_buf[len]='\0'; WSREP_ERROR("SST failed for position %s initialized %d server_state %s", start_pos_buf, server_state.is_initialized(), diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 266ff9459ac..dea388d30de 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -233,12 +233,24 @@ bool wsrep_set_local_position(THD* thd, const char* const value, size_t const uuid_len= wsrep_uuid_scan(value, length, &uuid); wsrep_seqno_t const seqno= strtoll(value + uuid_len + 1, NULL, 10); - if (sst) { + char start_pos_buf[FN_REFLEN]; + memcpy(start_pos_buf, value, length); + start_pos_buf[length]='\0'; + + // If both are same as WSREP_START_POSITION_ZERO just set local + if (!strcmp(start_pos_buf, WSREP_START_POSITION_ZERO) && + !strcmp(wsrep_start_position, WSREP_START_POSITION_ZERO)) + goto set; + else + WSREP_INFO("SST setting local position to %s current %s", start_pos_buf, wsrep_start_position); + + if (sst) return (wsrep_sst_received (thd, uuid, seqno, NULL, 0)); - } else { - local_uuid= uuid; - local_seqno= seqno; - } + +set: + local_uuid= uuid; + local_seqno= seqno; + return false; } @@ -255,9 +267,14 @@ bool wsrep_start_position_check (sys_var *self, THD* thd, set_var* var) var->save_result.string_value.length); start_pos_buf[var->save_result.string_value.length]= 0; + + WSREP_DEBUG("SST wsrep_start_position check for new position %s old %s", + start_pos_buf, wsrep_start_position); + // Verify the format. if (wsrep_start_position_verify(start_pos_buf)) return true; + // Give error if position is updated when wsrep is not enabled or // provider is not loaded. if ((!WSREP_ON || !Wsrep_server_state::instance().is_provider_loaded()) @@ -274,13 +291,10 @@ bool wsrep_start_position_check (sys_var *self, THD* thd, set_var* var) As part of further verification, we try to update the value and catch errors (if any) only when value actually has been changed. */ - if (strcmp(start_pos_buf, wsrep_start_position)) - { - if (wsrep_set_local_position(thd, var->save_result.string_value.str, + if (wsrep_set_local_position(thd, var->save_result.string_value.str, var->save_result.string_value.length, true)) - goto err; - } + goto err; return false; From 0e10d7ea14cf795ada8aee7fe1afc590ef6de32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 22 Jan 2021 16:44:17 +0200 Subject: [PATCH 26/27] MDEV-22351 InnoDB may recover wrong information after RESET MASTER Ever since commit 947efe17ed8188ca4feef6deb0c2831a246b5c8f InnoDB no longer writes binlog position in one place. It will not at all be written to the TRX_SYS page, and instead it will be written to the undo log header page that changes the transaction state. trx_rseg_mem_restore(): Recover the information from the latest written page. --- storage/innobase/include/trx0sys.h | 6 ++-- storage/innobase/trx/trx0rseg.cc | 48 +++++++++++++----------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index b8ccb2726b2..30ee5f5833d 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -857,8 +857,10 @@ public: #endif /** Latest recovered binlog offset */ uint64_t recovered_binlog_offset; - /** Latest recovred binlog file name */ + /** Latest recovered binlog file name */ char recovered_binlog_filename[TRX_SYS_MYSQL_LOG_NAME_LEN]; + /** FIL_PAGE_LSN of the page with the latest recovered binlog metadata */ + lsn_t recovered_binlog_lsn; /** diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index dfc8e5cbcca..d6720979716 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -439,8 +439,14 @@ static void trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr) { - trx_rsegf_t* rseg_header = trx_rsegf_get_new( - rseg->space->id, rseg->page_no, mtr); + /* This is based on trx_rsegf_get_new(). + We need to access buf_block_t. */ + buf_block_t *block = buf_page_get( + page_id_t(rseg->space->id, rseg->page_no), + univ_page_size, RW_S_LATCH, mtr); + buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW); + + const trx_rsegf_t* rseg_header = TRX_RSEG + block->frame; if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT) == 0) { trx_id_t id = mach_read_from_8(rseg_header @@ -451,32 +457,20 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr) } if (rseg_header[TRX_RSEG_BINLOG_NAME]) { - const char* binlog_name = reinterpret_cast - (rseg_header) + TRX_RSEG_BINLOG_NAME; + lsn_t lsn = std::max(block->page.newest_modification, + mach_read_from_8(FIL_PAGE_LSN + + block->frame)); compile_time_assert(TRX_RSEG_BINLOG_NAME_LEN == sizeof trx_sys.recovered_binlog_filename); - - int cmp = *trx_sys.recovered_binlog_filename - ? strncmp(binlog_name, - trx_sys.recovered_binlog_filename, - TRX_RSEG_BINLOG_NAME_LEN) - : 1; - - if (cmp >= 0) { - uint64_t binlog_offset = mach_read_from_8( - rseg_header + TRX_RSEG_BINLOG_OFFSET); - if (cmp) { - memcpy(trx_sys. - recovered_binlog_filename, - binlog_name, - TRX_RSEG_BINLOG_NAME_LEN); - trx_sys.recovered_binlog_offset - = binlog_offset; - } else if (binlog_offset > - trx_sys.recovered_binlog_offset) { - trx_sys.recovered_binlog_offset - = binlog_offset; - } + if (lsn > trx_sys.recovered_binlog_lsn) { + trx_sys.recovered_binlog_lsn = lsn; + trx_sys.recovered_binlog_offset + = mach_read_from_8( + rseg_header + + TRX_RSEG_BINLOG_OFFSET); + memcpy(trx_sys.recovered_binlog_filename, + rseg_header + TRX_RSEG_BINLOG_NAME, + TRX_RSEG_BINLOG_NAME_LEN); } #ifdef WITH_WSREP From eaeb8ec4b87882711ecb8e1c7476a6e410d5d2a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 25 Jan 2021 10:24:35 +0200 Subject: [PATCH 27/27] MDEV-24653 Assertion block->page.id.page_no() == index->page failed in innobase_add_instant_try() We may end up with an empty leaf page (containing only an ADD COLUMN metadata record) that is not the root page. innobase_add_instant_try(): Disable an optimization for a non-canonical empty table that contains a metadata record somewhere else than in the root page. btr_pcur_store_position(): Tolerate a non-canonical empty table. --- .../suite/innodb/r/instant_alter_debug.result | 19 +++++++++++++- .../suite/innodb/t/instant_alter_debug.test | 25 +++++++++++++++++-- storage/innobase/btr/btr0pcur.cc | 19 +++++++++++--- storage/innobase/handler/handler0alter.cc | 8 +++--- 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result index 49365b6e9be..230097f47c7 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug.result +++ b/mysql-test/suite/innodb/r/instant_alter_debug.result @@ -263,7 +263,6 @@ a b vb 4 NULL NULL 5 NULL NULL DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; # # MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col # @@ -282,3 +281,21 @@ connection default; SET DEBUG_SYNC='RESET'; disconnect con2; DROP TABLE t1; +# +# MDEV-24653 Assertion block->page.id.page_no() == index->page failed +# in innobase_add_instant_try() +# +SET @saved_limit = @@GLOBAL.innodb_limit_optimistic_insert_debug; +SET GLOBAL innodb_limit_optimistic_insert_debug = 2; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3),(4); +ALTER TABLE t1 ADD COLUMN b INT; +DELETE FROM t1; +InnoDB 0 transactions not purged +ALTER TABLE t1 ADD COLUMN c INT; +SELECT * FROM t1; +a b c +DROP TABLE t1; +SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; +# End of 10.3 tests +SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test index cec7a05725b..d3aea85b243 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.test +++ b/mysql-test/suite/innodb/t/instant_alter_debug.test @@ -292,8 +292,6 @@ CHECK TABLE t1; SELECT * FROM t1; DROP TABLE t1; -SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; - --echo # --echo # MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col --echo # @@ -319,3 +317,26 @@ SET DEBUG_SYNC='now SIGNAL update'; SET DEBUG_SYNC='RESET'; --disconnect con2 DROP TABLE t1; + +--echo # +--echo # MDEV-24653 Assertion block->page.id.page_no() == index->page failed +--echo # in innobase_add_instant_try() +--echo # + +SET @saved_limit = @@GLOBAL.innodb_limit_optimistic_insert_debug; +SET GLOBAL innodb_limit_optimistic_insert_debug = 2; + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3),(4); +ALTER TABLE t1 ADD COLUMN b INT; +DELETE FROM t1; +--source include/wait_all_purged.inc +ALTER TABLE t1 ADD COLUMN c INT; + +SELECT * FROM t1; +DROP TABLE t1; +SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit; + +--echo # End of 10.3 tests + +SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index 019369d997d..8faa6c626ff 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. +Copyright (c) 2016, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -128,13 +128,14 @@ btr_pcur_store_position( cursor->old_stored = true; if (page_is_empty(block->frame)) { + ut_ad(block->page.id.page_no() == index->page); +empty_table: /* It must be an empty index tree; NOTE that in this case we do not store the modify_clock, but always do a search if we restore the cursor position */ ut_a(!page_has_siblings(block->frame)); ut_ad(page_is_leaf(block->frame)); - ut_ad(block->page.id.page_no() == index->page); if (page_rec_is_supremum_low(offs)) { cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE; @@ -150,7 +151,15 @@ before_first: rec = page_rec_get_prev(rec); ut_ad(!page_rec_is_infimum(rec)); - ut_ad(!rec_is_metadata(rec, index)); + + if (UNIV_UNLIKELY(rec_is_metadata(rec, index))) { + /* The table may be empty such that it only + contains a metadata record, in a leaf page + that is not the root page. */ + ut_ad(index->is_primary()); + ut_ad(block->page.id.page_no() != index->page); + goto empty_table; + } cursor->rel_pos = BTR_PCUR_AFTER; } else if (page_rec_is_infimum_low(offs)) { @@ -160,7 +169,9 @@ before_first: ut_ad(!page_has_prev(block->frame)); rec = page_rec_get_next(rec); if (page_rec_is_supremum(rec)) { - ut_ad(page_has_next(block->frame)); + ut_ad(page_has_next(block->frame) + || block->page.id.page_no() + != index->page); goto before_first; } } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 574b29a261e..6d4e545248a 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -4482,11 +4482,13 @@ innobase_add_instant_try( const rec_t* rec = btr_pcur_get_rec(&pcur); que_thr_t* thr = pars_complete_graph_for_exec( NULL, trx, ctx->heap, NULL); + const bool is_root = block->page.id.page_no() == index->page; dberr_t err; if (rec_is_metadata(rec, index)) { ut_ad(page_rec_is_user_rec(rec)); - if (!page_has_next(block->frame) + if (is_root + && !page_has_next(block->frame) && page_rec_is_last(rec, block->frame)) { goto empty_table; } @@ -4528,7 +4530,7 @@ innobase_add_instant_try( } btr_pcur_close(&pcur); goto func_exit; - } else if (page_rec_is_supremum(rec)) { + } else if (is_root && page_rec_is_supremum(rec)) { empty_table: /* The table is empty. */ ut_ad(fil_page_index_page_check(block->frame));