diff --git a/client/mysql.cc b/client/mysql.cc index caed22b8a9548..d58abdb1cb8ac 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2018, Oracle and/or its affiliates. - Copyright (c) 2009, 2021, MariaDB Corporation. + Copyright (c) 2009, 2022, 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 @@ -3788,7 +3788,6 @@ print_table_data(MYSQL_RES *result) { String separator(256); MYSQL_ROW cur; - MYSQL_FIELD *field; bool *num_flag; num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result)); @@ -3800,7 +3799,7 @@ print_table_data(MYSQL_RES *result) mysql_field_seek(result,0); } separator.copy("+",1,charset_info); - while ((field = mysql_fetch_field(result))) + while (MYSQL_FIELD *field= mysql_fetch_field(result)) { uint length= column_names ? field->name_length : 0; if (quick) @@ -3822,7 +3821,7 @@ print_table_data(MYSQL_RES *result) { mysql_field_seek(result,0); (void) tee_fputs("|", PAGER); - for (uint off=0; (field = mysql_fetch_field(result)) ; off++) + while (MYSQL_FIELD *field= mysql_fetch_field(result)) { size_t name_length= (uint) strlen(field->name); size_t numcells= charset_info->numcells(field->name, @@ -3864,7 +3863,7 @@ print_table_data(MYSQL_RES *result) data_length= (uint) lengths[off]; } - field= mysql_fetch_field(result); + MYSQL_FIELD *field= mysql_fetch_field(result); field_max_length= field->max_length; /* diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index eb063765a3797..8a0dc3cb91cdc 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB + Copyright (c) 2010, 2012, MariaDB 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 @@ -1061,7 +1061,6 @@ static void print_result() char prev[(NAME_LEN+9)*3+2]; char prev_alter[MAX_ALTER_STR_SIZE]; size_t length_of_db= strlen(sock->db); - uint i; my_bool found_error=0, table_rebuild=0; DYNAMIC_ARRAY *array4repair= &tables4repair; DBUG_ENTER("print_result"); @@ -1070,7 +1069,7 @@ static void print_result() prev[0] = '\0'; prev_alter[0]= 0; - for (i = 0; (row = mysql_fetch_row(res)); i++) + while ((row = mysql_fetch_row(res))) { int changed = strcmp(prev, row[0]); my_bool status = !strcmp(row[2], "status"); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 5813107732162..720616c5d5a58 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -1,6 +1,6 @@ /* Copyright (c) 2005, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB + Copyright (c) 2010, 2022, MariaDB 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 @@ -1897,12 +1897,11 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit) pthread_handler_t run_task(void *p) { - ulonglong counter= 0, queries; + ulonglong queries; ulonglong detach_counter; unsigned int commit_counter; MYSQL *mysql; MYSQL_RES *result; - MYSQL_ROW row; statement *ptr; thread_context *con= (thread_context *)p; @@ -2023,8 +2022,7 @@ pthread_handler_t run_task(void *p) my_progname, mysql_errno(mysql), mysql_error(mysql)); else { - while ((row= mysql_fetch_row(result))) - counter++; + while (mysql_fetch_row(result)) {} mysql_free_result(result); } } @@ -2034,7 +2032,7 @@ pthread_handler_t run_task(void *p) if (commit_rate && (++commit_counter == commit_rate)) { commit_counter= 0; - run_query(mysql, "COMMIT", strlen("COMMIT")); + run_query(mysql, C_STRING_WITH_LEN("COMMIT")); } if (con->limit && queries == con->limit) @@ -2046,7 +2044,7 @@ pthread_handler_t run_task(void *p) end: if (commit_rate) - run_query(mysql, "COMMIT", strlen("COMMIT")); + run_query(mysql, C_STRING_WITH_LEN("COMMIT")); mysql_close(mysql); diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index a0ee64523b09f..25b7a2dd04508 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -1,5 +1,5 @@ # Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2011, 2021, MariaDB Corporation. +# Copyright (c) 2011, 2022, 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 diff --git a/dbug/my_main.c b/dbug/my_main.c index 2b3e92b53cc2e..80db4d82e06cb 100644 --- a/dbug/my_main.c +++ b/dbug/my_main.c @@ -7,9 +7,7 @@ #include #include -int main (argc, argv) -int argc; -char *argv[]; +int main (int argc, char **argv) { register int result, ix; extern int factorial(int); diff --git a/extra/replace.c b/extra/replace.c index 7e94bfc36c382..8b20f812be005 100644 --- a/extra/replace.c +++ b/extra/replace.c @@ -148,9 +148,7 @@ int main(int argc, char *argv[]) /* reads options */ /* Initiates DEBUG - but no debugging here ! */ -static int static_get_options(argc,argv) -register int *argc; -register char **argv[]; +static int static_get_options(int *argc, char***argv) { int help,version; char *pos; @@ -218,10 +216,9 @@ register char **argv[]; } /* static_get_options */ -static int get_replace_strings(argc,argv,from_array,to_array) -register int *argc; -register char **argv[]; -POINTER_ARRAY *from_array,*to_array; +static int get_replace_strings(int *argc, char ***argv, + POINTER_ARRAY *from_array, + POINTER_ARRAY *to_array) { char *pos; @@ -974,9 +971,7 @@ static void free_buffer() bytes read from disk. */ -static int fill_buffer_retaining(fd,n) -File fd; -int n; +static int fill_buffer_retaining(File fd, int n) { int i; @@ -1019,9 +1014,7 @@ int n; /* Return 0 if convert is ok */ /* Global variable update is set if something was changed */ -static int convert_pipe(rep,in,out) -REPLACE *rep; -FILE *in,*out; +static int convert_pipe(REPLACE *rep, FILE *in, FILE *out) { int retain,error; uint length; diff --git a/libmariadb b/libmariadb index 4fc7903cf3b76..485a3ad68c93f 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 4fc7903cf3b761492243b5562ba4141a1c02651c +Subproject commit 485a3ad68c93fd43acde8a0fe39a348292f1cf2d diff --git a/mysql-test/main/information_schema_tables.test b/mysql-test/main/information_schema_tables.test index bc4f269a3fb46..ee277276b52a7 100644 --- a/mysql-test/main/information_schema_tables.test +++ b/mysql-test/main/information_schema_tables.test @@ -37,7 +37,9 @@ SELECT v.* FROM v JOIN INFORMATION_SCHEMA.TABLES WHERE DATA_LENGTH = -1; --eval KILL $conid --disconnect con1 --connection default +--disable_warnings DROP VIEW IF EXISTS vv; +--enable_warnings DROP VIEW v; DROP FUNCTION f; DROP TABLE t; diff --git a/mysql-test/suite/funcs_1/t/myisam_views-big.test b/mysql-test/suite/funcs_1/t/myisam_views-big.test index bf499ee789aca..60fe1b8eaba33 100644 --- a/mysql-test/suite/funcs_1/t/myisam_views-big.test +++ b/mysql-test/suite/funcs_1/t/myisam_views-big.test @@ -4,6 +4,8 @@ # because of a pair of slow Solaris Sparc machines in pb2, # this test is marked as big: --source include/big_test.inc +# This test often times out with MSAN +--source include/not_msan.inc # MyISAM tables should be used # diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug.result b/mysql-test/suite/gcol/r/innodb_virtual_debug.result index 80b2bde6ca56a..9cac55c25e31f 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_debug.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug.result @@ -124,3 +124,24 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +# +# MDEV-28806 Assertion `flag == 1' failure in +# row_build_index_entry_low upon concurrent ALTER and UPDATE +# +CREATE TABLE t1(a CHAR(8), b INT, c INT AS (b), KEY(a)) ENGINE=InnoDB; +INSERT INTO t1(b) VALUES (1),(2); +connect con1,localhost,root,,test; +SET DEBUG_SYNC="alter_table_inplace_before_lock_upgrade SIGNAL dml_start WAIT_FOR dml_commit"; +ALTER TABLE t1 ADD KEY ind (c); +connection default; +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +UPDATE t1 SET a ='foo'; +SET DEBUG_SYNC="now SIGNAL dml_commit"; +connection con1; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +disconnect con1; +connection default; +SET DEBUG_SYNC=RESET; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug.test b/mysql-test/suite/gcol/t/innodb_virtual_debug.test index 5ebc90dac19c1..cd2b860400ce4 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_debug.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug.test @@ -312,4 +312,30 @@ SELECT * FROM t1; CHECK TABLE t1; DROP TABLE t1; +--echo # +--echo # MDEV-28806 Assertion `flag == 1' failure in +--echo # row_build_index_entry_low upon concurrent ALTER and UPDATE +--echo # + +CREATE TABLE t1(a CHAR(8), b INT, c INT AS (b), KEY(a)) ENGINE=InnoDB; +INSERT INTO t1(b) VALUES (1),(2); + +--connect (con1,localhost,root,,test) +SET DEBUG_SYNC="alter_table_inplace_before_lock_upgrade SIGNAL dml_start WAIT_FOR dml_commit"; +send ALTER TABLE t1 ADD KEY ind (c); + +--connection default +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +UPDATE t1 SET a ='foo'; +SET DEBUG_SYNC="now SIGNAL dml_commit"; + +# Cleanup +--connection con1 +--reap +CHECK TABLE t1; +DROP TABLE t1; +--disconnect con1 +connection default; +SET DEBUG_SYNC=RESET; + --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/r/instant_alter_import.result b/mysql-test/suite/innodb/r/instant_alter_import.result index 3fff0d50b3693..c65ffb3ad4cc5 100644 --- a/mysql-test/suite/innodb/r/instant_alter_import.result +++ b/mysql-test/suite/innodb/r/instant_alter_import.result @@ -130,3 +130,32 @@ UNLOCK TABLES; ALTER TABLE t2 IMPORT TABLESPACE; ERROR HY000: Index for table 't2' is corrupt; try to repair it DROP TABLE t1, t2; +# +# MDEV-28919 Assertion `(((core_null) + 7) >> 3) == +# oindex.n_core_null_bytes || !not_redundant()' failed +# +call mtr.add_suppression(" InnoDB: Tablespace for table `test`.`t` is set as discarded"); +CREATE TABLE t (a INTEGER, b INTEGER as (a) VIRTUAL, +c INTEGER)engine=innodb; +ALTER TABLE t DISCARD TABLESPACE; +FLUSH TABLES; +ALTER TABLE t DROP COLUMN b, algorithm=instant; +Warnings: +Warning 1814 Tablespace has been discarded for table `t` +ALTER TABLE t DROP COLUMN c, algorithm=instant; +Warnings: +Warning 1814 Tablespace has been discarded for table `t` +CREATE TABLE t1(a INTEGER)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); +FLUSH TABLE t1 FOR EXPORT; +unlock tables; +ALTER TABLE t IMPORT tablespace; +Warnings: +Warning 1814 Tablespace has been discarded for table `t` +check table t; +Table Op Msg_type Msg_text +test.t check status OK +select * from t; +a +1 +DROP TABLE t, t1; diff --git a/mysql-test/suite/innodb/t/alter_copy.test b/mysql-test/suite/innodb/t/alter_copy.test index 6b6a0151de49a..90f2171d10bc4 100644 --- a/mysql-test/suite/innodb/t/alter_copy.test +++ b/mysql-test/suite/innodb/t/alter_copy.test @@ -2,8 +2,7 @@ --source include/have_debug.inc --source include/have_debug_sync.inc --source include/not_embedded.inc -# Valgrind gives leaks from the first shutdown which confuses mtr -#--source include/not_valgrind.inc +--source include/no_valgrind_without_big.inc --echo # --echo # MDEV-11415 AVOID INTERMEDIATE COMMIT WHILE DOING diff --git a/mysql-test/suite/innodb/t/blob-crash.test b/mysql-test/suite/innodb/t/blob-crash.test index beb500553eada..5d52905974246 100644 --- a/mysql-test/suite/innodb/t/blob-crash.test +++ b/mysql-test/suite/innodb/t/blob-crash.test @@ -1,5 +1,6 @@ --source include/maybe_debug.inc --source include/innodb_page_size_small.inc +--source include/no_valgrind_without_big.inc --echo # --echo # Bug #16963396 INNODB: USE OF LARGE EXTERNALLY-STORED FIELDS MAKES diff --git a/mysql-test/suite/innodb/t/instant_alter_import.test b/mysql-test/suite/innodb/t/instant_alter_import.test index 3ffbe01f77e83..3a811def17018 100644 --- a/mysql-test/suite/innodb/t/instant_alter_import.test +++ b/mysql-test/suite/innodb/t/instant_alter_import.test @@ -208,3 +208,28 @@ UNLOCK TABLES; ALTER TABLE t2 IMPORT TABLESPACE; DROP TABLE t1, t2; + +--echo # +--echo # MDEV-28919 Assertion `(((core_null) + 7) >> 3) == +--echo # oindex.n_core_null_bytes || !not_redundant()' failed +--echo # +call mtr.add_suppression(" InnoDB: Tablespace for table `test`.`t` is set as discarded"); +CREATE TABLE t (a INTEGER, b INTEGER as (a) VIRTUAL, + c INTEGER)engine=innodb; +ALTER TABLE t DISCARD TABLESPACE; +FLUSH TABLES; +# Table does reload +ALTER TABLE t DROP COLUMN b, algorithm=instant; +ALTER TABLE t DROP COLUMN c, algorithm=instant; + +CREATE TABLE t1(a INTEGER)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); +FLUSH TABLE t1 FOR EXPORT; +--let $MYSQLD_DATADIR= `select @@datadir` +--move_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t.cfg +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t.ibd +unlock tables; +ALTER TABLE t IMPORT tablespace; +check table t; +select * from t; +DROP TABLE t, t1; diff --git a/mysql-test/suite/innodb/t/read_only_recover_committed.test b/mysql-test/suite/innodb/t/read_only_recover_committed.test index 6252c774a2590..1d2270315c529 100644 --- a/mysql-test/suite/innodb/t/read_only_recover_committed.test +++ b/mysql-test/suite/innodb/t/read_only_recover_committed.test @@ -3,6 +3,7 @@ --source include/have_debug_sync.inc # need to restart server --source include/not_embedded.inc +--source include/no_valgrind_without_big.inc --disable_query_log # Ignore messages from the innodb_force_recovery=5 startup. diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test index 380052b9db666..d36e71b797a60 100644 --- a/mysql-test/suite/innodb/t/table_flags.test +++ b/mysql-test/suite/innodb/t/table_flags.test @@ -1,6 +1,7 @@ --source include/innodb_page_size.inc # Embedded server tests do not support restarting --source include/not_embedded.inc +--source include/no_valgrind_without_big.inc --disable_query_log call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found"); diff --git a/mysql-test/suite/innodb/t/xa_recovery.test b/mysql-test/suite/innodb/t/xa_recovery.test index 7a67cd8e8b763..cfb8224018732 100644 --- a/mysql-test/suite/innodb/t/xa_recovery.test +++ b/mysql-test/suite/innodb/t/xa_recovery.test @@ -1,6 +1,7 @@ --source include/have_innodb.inc # Embedded server does not support restarting. --source include/not_embedded.inc +--source include/no_valgrind_without_big.inc # MDEV-8841 - close tables opened by previous tests, # so they don't get marked crashed when the server gets crashed diff --git a/mysql-test/suite/innodb_fts/r/crash_recovery.result b/mysql-test/suite/innodb_fts/r/crash_recovery.result index e8305cbb2f10f..83e5ddaea90b3 100644 --- a/mysql-test/suite/innodb_fts/r/crash_recovery.result +++ b/mysql-test/suite/innodb_fts/r/crash_recovery.result @@ -157,5 +157,18 @@ id title body 1 MySQL Tutorial DBMS stands for Database... 2 MariaDB Tutorial DB means Database ... DROP TABLE mdev19073, mdev19073_2; +# +# MDEV-28706 Redundant InnoDB table fails during alter +# +SET @@global.innodb_file_per_table = 0; +CREATE TABLE t1 ( +col_int INTEGER, col_text TEXT, +col_text_1 TEXT +) ENGINE = InnoDB ROW_FORMAT = Redundant ; +ALTER TABLE t1 ADD FULLTEXT KEY `ftidx` ( col_text ) ; +INSERT INTO t1 VALUES ( 1255, "mariadb", "InnoDB"); +# restart +ALTER TABLE t1 ADD FULLTEXT(col_text_1); +DROP TABLE t1; SELECT * FROM information_schema.innodb_sys_tables WHERE name LIKE 'test/%'; TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE diff --git a/mysql-test/suite/innodb_fts/r/fulltext2.result b/mysql-test/suite/innodb_fts/r/fulltext2.result index b210b3bd87457..7ec2df8ee46c9 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext2.result +++ b/mysql-test/suite/innodb_fts/r/fulltext2.result @@ -272,3 +272,10 @@ fts_doc_id first_name last_name score 6 Ned Flanders 0 7 Nelson Muntz 0 DROP TABLE t1; +CREATE TABLE t1(a INT, b TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, +KEY FTS_DOC_ID_INDEX(FTS_DOC_ID))ENGINE=InnoDB; +ALTER TABLE t1 ADD COLUMN c INT as (a) VIRTUAL; +ALTER TABLE t1 ADD d INT NULL; +ALTER TABLE t1 ADD FULLTEXT(b); +ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/crash_recovery.test b/mysql-test/suite/innodb_fts/t/crash_recovery.test index 702aaefad830a..b8da55a8ba6b0 100644 --- a/mysql-test/suite/innodb_fts/t/crash_recovery.test +++ b/mysql-test/suite/innodb_fts/t/crash_recovery.test @@ -255,4 +255,21 @@ SELECT * FROM mdev19073_2 WHERE MATCH (title, body) AGAINST ('Database' IN NATURAL LANGUAGE MODE); DROP TABLE mdev19073, mdev19073_2; +let $shutdown_timeout=; + +--echo # +--echo # MDEV-28706 Redundant InnoDB table fails during alter +--echo # + +SET @@global.innodb_file_per_table = 0; +CREATE TABLE t1 ( + col_int INTEGER, col_text TEXT, + col_text_1 TEXT +) ENGINE = InnoDB ROW_FORMAT = Redundant ; +ALTER TABLE t1 ADD FULLTEXT KEY `ftidx` ( col_text ) ; +INSERT INTO t1 VALUES ( 1255, "mariadb", "InnoDB"); +--source include/restart_mysqld.inc +ALTER TABLE t1 ADD FULLTEXT(col_text_1); +DROP TABLE t1; + SELECT * FROM information_schema.innodb_sys_tables WHERE name LIKE 'test/%'; diff --git a/mysql-test/suite/innodb_fts/t/fulltext2.test b/mysql-test/suite/innodb_fts/t/fulltext2.test index 4dd2c78827f7f..1e3894644a012 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext2.test +++ b/mysql-test/suite/innodb_fts/t/fulltext2.test @@ -257,3 +257,14 @@ INSERT INTO t1 (id, first_name, last_name) VALUES analyze table t1; SELECT fts_doc_id, first_name, last_name, MATCH(first_name) AGAINST('Homer' IN BOOLEAN MODE) AS score FROM t1; DROP TABLE t1; + +# +# MDEV-28912 NON-UNIQUE FTS_DOC_ID mistaken as FTS_DOC_ID_INDEX +# +CREATE TABLE t1(a INT, b TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL, + KEY FTS_DOC_ID_INDEX(FTS_DOC_ID))ENGINE=InnoDB; +ALTER TABLE t1 ADD COLUMN c INT as (a) VIRTUAL; +ALTER TABLE t1 ADD d INT NULL; +--error ER_INNODB_FT_WRONG_DOCID_INDEX +ALTER TABLE t1 ADD FULLTEXT(b); +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_gis/t/multi_pk.test b/mysql-test/suite/innodb_gis/t/multi_pk.test index c90f794fe159d..1be919d165a1f 100644 --- a/mysql-test/suite/innodb_gis/t/multi_pk.test +++ b/mysql-test/suite/innodb_gis/t/multi_pk.test @@ -8,6 +8,8 @@ --source include/have_debug.inc --source include/big_test.inc --source include/not_valgrind.inc +# This test often times out with MSAN +--source include/not_msan.inc # Create table with R-tree index. create table t1 (c1 int, c2 varchar(255), c3 geometry not null, primary key(c1, c2), spatial index (c3))engine=innodb; diff --git a/mysql-test/suite/innodb_gis/t/rtree_purge.test b/mysql-test/suite/innodb_gis/t/rtree_purge.test index 60ecbe2e53a82..fc5ce2e14bcca 100644 --- a/mysql-test/suite/innodb_gis/t/rtree_purge.test +++ b/mysql-test/suite/innodb_gis/t/rtree_purge.test @@ -3,6 +3,8 @@ --source include/innodb_page_size.inc --source include/have_sequence.inc --source include/not_valgrind.inc +# This test often times out with MSAN +--source include/not_msan.inc SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; diff --git a/mysql-test/suite/multi_source/multi_parallel.test b/mysql-test/suite/multi_source/multi_parallel.test index a1385198b61aa..2bbb344378c6f 100644 --- a/mysql-test/suite/multi_source/multi_parallel.test +++ b/mysql-test/suite/multi_source/multi_parallel.test @@ -2,6 +2,7 @@ # Slave_non_transactional_groups, Slave_transactional_groups --source include/not_embedded.inc --source include/have_innodb.inc +--source include/no_valgrind_without_big.inc --let $rpl_server_count= 0 --connect (master1,127.0.0.1,root,,,$SERVER_MYPORT_1) diff --git a/mysql-test/suite/parts/inc/partition_auto_increment.inc b/mysql-test/suite/parts/inc/partition_auto_increment.inc index b9746ec110f12..b19a8cd7749b0 100644 --- a/mysql-test/suite/parts/inc/partition_auto_increment.inc +++ b/mysql-test/suite/parts/inc/partition_auto_increment.inc @@ -873,6 +873,8 @@ SELECT LAST_INSERT_ID(); SELECT * FROM t1; DROP TABLE t1; } +--echo ############################################################################## +} if (!$skip_update) { @@ -880,13 +882,13 @@ if (!$skip_update) --echo # MDEV-19622 Assertion failures in --echo # ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table --echo # -CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a); +eval CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=$engine PARTITION BY HASH(a); INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; } -if (!$skip_update) +if (!$skip_delete) { --echo # --echo # MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' @@ -897,5 +899,14 @@ REPLACE INTO t1 PARTITION (p0) VALUES (3); DROP TABLE t1; } ---echo ############################################################################## +if (!$skip_truncate) +{ +--echo # +--echo # MDEV-21310 AUTO_INCREMENT column throws range error on INSERT in partitioned table | +--echo # Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' failed. +--echo # +eval CREATE TABLE t1 (c INT AUTO_INCREMENT KEY) ENGINE=$engine PARTITION BY LIST (c) (PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +ALTER TABLE t1 TRUNCATE PARTITION p1; +INSERT INTO t1 PARTITION (p1) (c) SELECT 1; +DROP TABLE t1; } diff --git a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result index 0276385dc2969..c017aadcbab78 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result @@ -695,3 +695,26 @@ PARTITIONS 2 SELECT * FROM t1 ORDER BY c1; c1 DROP TABLE t1; +# +# MDEV-19622 Assertion failures in +# ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table +# +CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE='Blackhole' PARTITION BY HASH(a); +INSERT INTO t1 VALUES (1,1),(2,2); +UPDATE t1 SET pk = 0; +DROP TABLE t1; +# +# MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +# ha_partition::set_auto_increment_if_higher +# +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='Blackhole' PARTITION BY HASH (a) PARTITIONS 3; +REPLACE INTO t1 PARTITION (p0) VALUES (3); +DROP TABLE t1; +# +# MDEV-21310 AUTO_INCREMENT column throws range error on INSERT in partitioned table | +# Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' failed. +# +CREATE TABLE t1 (c INT AUTO_INCREMENT KEY) ENGINE='Blackhole' PARTITION BY LIST (c) (PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +ALTER TABLE t1 TRUNCATE PARTITION p1; +INSERT INTO t1 PARTITION (p1) (c) SELECT 1; +DROP TABLE t1; diff --git a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result index ce1e3562d4c11..f0f0ff2182451 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result @@ -1116,11 +1116,12 @@ SELECT * FROM t1; a 0 DROP TABLE t1; +############################################################################## # # MDEV-19622 Assertion failures in # ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table # -CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a); +CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE='InnoDB' PARTITION BY HASH(a); INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; @@ -1131,4 +1132,11 @@ DROP TABLE t1; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='InnoDB' PARTITION BY HASH (a) PARTITIONS 3; REPLACE INTO t1 PARTITION (p0) VALUES (3); DROP TABLE t1; -############################################################################## +# +# MDEV-21310 AUTO_INCREMENT column throws range error on INSERT in partitioned table | +# Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' failed. +# +CREATE TABLE t1 (c INT AUTO_INCREMENT KEY) ENGINE='InnoDB' PARTITION BY LIST (c) (PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +ALTER TABLE t1 TRUNCATE PARTITION p1; +INSERT INTO t1 PARTITION (p1) (c) SELECT 1; +DROP TABLE t1; diff --git a/mysql-test/suite/parts/r/partition_auto_increment_maria.result b/mysql-test/suite/parts/r/partition_auto_increment_maria.result index ad041735ebbdf..8c063958b27c5 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_maria.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_maria.result @@ -1148,11 +1148,12 @@ SELECT * FROM t1; a 0 DROP TABLE t1; +############################################################################## # # MDEV-19622 Assertion failures in # ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table # -CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a); +CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE='Aria' PARTITION BY HASH(a); INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; @@ -1163,4 +1164,11 @@ DROP TABLE t1; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='Aria' PARTITION BY HASH (a) PARTITIONS 3; REPLACE INTO t1 PARTITION (p0) VALUES (3); DROP TABLE t1; -############################################################################## +# +# MDEV-21310 AUTO_INCREMENT column throws range error on INSERT in partitioned table | +# Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' failed. +# +CREATE TABLE t1 (c INT AUTO_INCREMENT KEY) ENGINE='Aria' PARTITION BY LIST (c) (PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +ALTER TABLE t1 TRUNCATE PARTITION p1; +INSERT INTO t1 PARTITION (p1) (c) SELECT 1; +DROP TABLE t1; diff --git a/mysql-test/suite/parts/r/partition_auto_increment_memory.result b/mysql-test/suite/parts/r/partition_auto_increment_memory.result index d2d1fb6831c4a..3461f8b13c5d8 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_memory.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_memory.result @@ -1129,11 +1129,12 @@ SELECT * FROM t1; a 0 DROP TABLE t1; +############################################################################## # # MDEV-19622 Assertion failures in # ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table # -CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a); +CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE='Memory' PARTITION BY HASH(a); INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; @@ -1144,4 +1145,11 @@ DROP TABLE t1; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='Memory' PARTITION BY HASH (a) PARTITIONS 3; REPLACE INTO t1 PARTITION (p0) VALUES (3); DROP TABLE t1; -############################################################################## +# +# MDEV-21310 AUTO_INCREMENT column throws range error on INSERT in partitioned table | +# Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' failed. +# +CREATE TABLE t1 (c INT AUTO_INCREMENT KEY) ENGINE='Memory' PARTITION BY LIST (c) (PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +ALTER TABLE t1 TRUNCATE PARTITION p1; +INSERT INTO t1 PARTITION (p1) (c) SELECT 1; +DROP TABLE t1; diff --git a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result index f92a6ed18c6aa..525f47bdbd787 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result @@ -1148,11 +1148,12 @@ SELECT * FROM t1; a 0 DROP TABLE t1; +############################################################################## # # MDEV-19622 Assertion failures in # ha_partition::set_auto_increment_if_higher upon UPDATE on Aria table # -CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=myisam PARTITION BY HASH(a); +CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE='MyISAM' PARTITION BY HASH(a); INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; @@ -1163,4 +1164,11 @@ DROP TABLE t1; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='MyISAM' PARTITION BY HASH (a) PARTITIONS 3; REPLACE INTO t1 PARTITION (p0) VALUES (3); DROP TABLE t1; -############################################################################## +# +# MDEV-21310 AUTO_INCREMENT column throws range error on INSERT in partitioned table | +# Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' failed. +# +CREATE TABLE t1 (c INT AUTO_INCREMENT KEY) ENGINE='MyISAM' PARTITION BY LIST (c) (PARTITION p1 VALUES IN (1), PARTITION p2 VALUES IN (2)); +ALTER TABLE t1 TRUNCATE PARTITION p1; +INSERT INTO t1 PARTITION (p1) (c) SELECT 1; +DROP TABLE t1; diff --git a/scripts/comp_sql.c b/scripts/comp_sql.c index 1ce7889a90f59..f72fdcb0ae35c 100644 --- a/scripts/comp_sql.c +++ b/scripts/comp_sql.c @@ -1,5 +1,5 @@ /* Copyright (c) 2004, 2010, Oracle and/or its affiliates. - Copyright (c) 2012, 2014, Monty Program Ab + Copyright (c) 2012, 2022, 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 @@ -84,7 +84,7 @@ static void print_query(FILE *out, const char *query) fprintf(out, "\""); while (*ptr) { - if(column >= MAX_COLUMN) + if (column >= MAX_COLUMN) { /* Wrap to the next line, tabulated. */ fprintf(out, "\"\n \""); diff --git a/sql/field.cc b/sql/field.cc index 5af799a6dcc59..71bb22c05e5fb 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2008, 2021, MariaDB + Copyright (c) 2008, 2022, MariaDB 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 @@ -10011,7 +10011,7 @@ int Field_bit::cmp_prefix(const uchar *a, const uchar *b, } -int Field_bit::key_cmp(const uchar *str, uint length) const +int Field_bit::key_cmp(const uchar *str, uint) const { if (bit_len) { @@ -10020,7 +10020,6 @@ int Field_bit::key_cmp(const uchar *str, uint length) const if ((flag= (int) (bits - *str))) return flag; str++; - length--; } return memcmp(ptr, str, bytes_in_rec); } diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 60505fce48d05..37eba2457fc63 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2447,7 +2447,6 @@ uint ha_partition::del_ren_table(const char *from, const char *to) char *name_buffer_ptr; const char *from_path; const char *to_path= NULL; - uint i; handler **file, **abort_file; THD *thd= ha_thd(); DBUG_ENTER("ha_partition::del_ren_table"); @@ -2487,7 +2486,6 @@ uint ha_partition::del_ren_table(const char *from, const char *to) from_path= get_canonical_filename(*file, from, from_lc_buff); if (to != NULL) to_path= get_canonical_filename(*file, to, to_lc_buff); - i= 0; do { if (unlikely((error= create_partition_name(from_buff, sizeof(from_buff), @@ -2512,7 +2510,6 @@ uint ha_partition::del_ren_table(const char *from, const char *to) name_buffer_ptr= strend(name_buffer_ptr) + 1; if (unlikely(error)) save_error= error; - i++; } while (*(++file)); if (to != NULL) { diff --git a/sql/ha_partition.h b/sql/ha_partition.h index ce29f73d64693..c064f7662ce4a 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1413,7 +1413,8 @@ class ha_partition final :public handler unless we already did it. */ if (!part_share->auto_inc_initialized && - (ha_thd()->lex->sql_command == SQLCOM_INSERT || + (ha_thd()->lex->sql_command == SQLCOM_INSERT || + ha_thd()->lex->sql_command == SQLCOM_INSERT_SELECT || ha_thd()->lex->sql_command == SQLCOM_REPLACE) && table->found_next_number_field) bitmap_set_all(&m_part_info->read_partitions); diff --git a/sql/mdl.cc b/sql/mdl.cc index bb764d04a4231..13b01da36d1f5 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2007, 2012, Oracle and/or its affiliates. - Copyright (c) 2020, 2021, MariaDB + Copyright (c) 2020, 2022, MariaDB 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 @@ -247,25 +247,32 @@ class Deadlock_detection_visitor: public MDL_wait_for_graph_visitor Print a list of all locks to DBUG trace to help with debugging */ +const char *dbug_print_mdl(MDL_ticket *mdl_ticket) +{ + thread_local char buffer[256]; + MDL_key *mdl_key= mdl_ticket->get_key(); + my_snprintf(buffer, sizeof(buffer) - 1, "%.*s/%.*s (%s)", + (int) mdl_key->db_name_length(), mdl_key->db_name(), + (int) mdl_key->name_length(), mdl_key->name(), + mdl_ticket->get_type_name()->str); + return buffer; +} + + static int mdl_dbug_print_lock(MDL_ticket *mdl_ticket, void *arg, bool granted) { String *tmp= (String*) arg; - char buffer[128]; - MDL_key *mdl_key= mdl_ticket->get_key(); - size_t length; - length= my_snprintf(buffer, sizeof(buffer)-1, - "\nname: %s db: %.*s key_name: %.*s (%s)", - mdl_ticket->get_type_name()->str, - (int) mdl_key->db_name_length(), mdl_key->db_name(), - (int) mdl_key->name_length(), mdl_key->name(), - granted ? "granted" : "waiting"); + char buffer[256]; + size_t length= my_snprintf(buffer, sizeof(buffer) - 1, + "\n %s (%s)", dbug_print_mdl(mdl_ticket), + granted ? "granted" : "waiting"); tmp->append(buffer, length); return 0; } const char *mdl_dbug_print_locks() { - static String tmp; + thread_local String tmp; mdl_iterate(mdl_dbug_print_lock, (void*) &tmp); return tmp.c_ptr(); } @@ -2271,13 +2278,19 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) MDL_ticket *ticket; MDL_wait::enum_wait_status wait_status; DBUG_ENTER("MDL_context::acquire_lock"); +#ifndef DBUG_OFF + const char *mdl_lock_name= get_mdl_lock_name( + mdl_request->key.mdl_namespace(), mdl_request->type)->str; +#endif DBUG_PRINT("enter", ("lock_type: %s timeout: %f", - get_mdl_lock_name(mdl_request->key.mdl_namespace(), - mdl_request->type)->str, + mdl_lock_name, lock_wait_timeout)); if (try_acquire_lock_impl(mdl_request, &ticket)) + { + DBUG_PRINT("mdl", ("OOM: %s", mdl_lock_name)); DBUG_RETURN(TRUE); + } if (mdl_request->ticket) { @@ -2287,9 +2300,14 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) accordingly, so we can simply return success. */ DBUG_PRINT("info", ("Got lock without waiting")); + DBUG_PRINT("mdl", ("Seized: %s", dbug_print_mdl(mdl_request->ticket))); DBUG_RETURN(FALSE); } +#ifndef DBUG_OFF + const char *ticket_msg= dbug_print_mdl(ticket); +#endif + /* Our attempt to acquire lock without waiting has failed. As a result of this attempt we got MDL_ticket with m_lock @@ -2300,6 +2318,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) if (lock_wait_timeout == 0) { + DBUG_PRINT("mdl", ("Nowait: %s", ticket_msg)); mysql_prlock_unlock(&lock->m_rwlock); MDL_ticket::destroy(ticket); my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); @@ -2360,6 +2379,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) locker= PSI_CALL_start_metadata_wait(&state, ticket->m_psi, __FILE__, __LINE__); #endif + DBUG_PRINT("mdl", ("Waiting: %s", ticket_msg)); will_wait_for(ticket); /* There is a shared or exclusive lock on the object. */ @@ -2417,15 +2437,16 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) switch (wait_status) { case MDL_wait::VICTIM: - DBUG_LOCK_FILE; - DBUG_PRINT("mdl_locks", ("%s", mdl_dbug_print_locks())); - DBUG_UNLOCK_FILE; + DBUG_PRINT("mdl", ("Deadlock: %s", ticket_msg)); + DBUG_PRINT("mdl_locks", ("Existing locks:%s", mdl_dbug_print_locks())); my_error(ER_LOCK_DEADLOCK, MYF(0)); break; case MDL_wait::TIMEOUT: + DBUG_PRINT("mdl", ("Timeout: %s", ticket_msg)); my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); break; case MDL_wait::KILLED: + DBUG_PRINT("mdl", ("Killed: %s", ticket_msg)); get_thd()->send_kill_message(); break; default: @@ -2449,6 +2470,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) mysql_mdl_set_status(ticket->m_psi, MDL_ticket::GRANTED); + DBUG_PRINT("mdl", ("Acquired: %s", ticket_msg)); DBUG_RETURN(FALSE); } @@ -2870,6 +2892,7 @@ void MDL_context::release_lock(enum_mdl_duration duration, MDL_ticket *ticket) lock->key.db_name(), lock->key.name())); DBUG_ASSERT(this == ticket->get_ctx()); + DBUG_PRINT("mdl", ("Released: %s", dbug_print_mdl(ticket))); lock->remove_ticket(m_pins, &MDL_lock::m_granted, ticket); diff --git a/sql/partition_info.cc b/sql/partition_info.cc index b287440bafb6a..091c065194ab2 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2006, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2020, MariaDB Corporation. + Copyright (c) 2010, 2022, 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 @@ -1526,7 +1526,6 @@ bool partition_info::set_up_charset_field_preps(THD *thd) uchar **char_ptrs; unsigned i; size_t size; - uint tot_fields= 0; uint tot_part_fields= 0; uint tot_subpart_fields= 0; DBUG_ENTER("set_up_charset_field_preps"); @@ -1538,13 +1537,8 @@ bool partition_info::set_up_charset_field_preps(THD *thd) ptr= part_field_array; /* Set up arrays and buffers for those fields */ while ((field= *(ptr++))) - { if (field_is_partition_charset(field)) - { tot_part_fields++; - tot_fields++; - } - } size= tot_part_fields * sizeof(char*); if (!(char_ptrs= (uchar**)thd->calloc(size))) goto error; @@ -1578,13 +1572,8 @@ bool partition_info::set_up_charset_field_preps(THD *thd) /* Set up arrays and buffers for those fields */ ptr= subpart_field_array; while ((field= *(ptr++))) - { if (field_is_partition_charset(field)) - { tot_subpart_fields++; - tot_fields++; - } - } size= tot_subpart_fields * sizeof(char*); if (!(char_ptrs= (uchar**) thd->calloc(size))) goto error; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7ab1dbe989995..bc32b3b7f7afe 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2811,7 +2811,6 @@ int Lex_input_stream::scan_ident_delimited(THD *thd, uchar quote_char) { CHARSET_INFO *const cs= thd->charset(); - uint double_quotes= 0; uchar c; DBUG_ASSERT(m_ptr == m_tok_start + 1); @@ -2836,7 +2835,6 @@ int Lex_input_stream::scan_ident_delimited(THD *thd, if (yyPeek() != quote_char) break; c= yyGet(); - double_quotes++; continue; } } diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 84d0902193b75..40760c1e2ebb6 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1,5 +1,5 @@ /* Copyright (C) 2009 MySQL AB - Copyright (c) 2019, 2020, MariaDB Corporation. + Copyright (c) 2019, 2022, 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 @@ -2623,7 +2623,6 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index) { int rc= 0; KEY *key_info= &table->key_info[index]; - ha_rows rows= 0; DBUG_ENTER("collect_statistics_for_index"); @@ -2658,7 +2657,6 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index) if (rc) break; - rows++; index_prefix_calc.add(); rc= table->file->ha_index_next(table->record[0]); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index de3222aaa333c..9238d169fee08 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1297,7 +1297,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, StringBuffer<160> unknown_tables(system_charset_info); DDL_LOG_STATE local_ddl_log_state; const char *comment_start; - uint not_found_errors= 0, table_count= 0, non_temp_tables_count= 0; + uint table_count= 0, non_temp_tables_count= 0; int error= 0; uint32 comment_len; bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; @@ -1428,7 +1428,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, unknown_tables.append(&table_name); unknown_tables.append(','); error= ENOENT; - not_found_errors++; continue; } @@ -1511,7 +1510,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, unknown_tables.append(&table_name); unknown_tables.append(','); error= ENOENT; - not_found_errors++; continue; } @@ -1757,7 +1755,6 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, } else { - not_found_errors++; if (unknown_tables.append(tbl_name) || unknown_tables.append(',')) { error= 1; @@ -2947,7 +2944,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, List_iterator key_iterator(alter_info->key_list); List_iterator key_iterator2(alter_info->key_list); - uint key_parts=0, fk_key_count=0; + uint key_parts=0; bool primary_key=0,unique_key=0; Key *key, *key2; uint tmp, key_number; @@ -2963,7 +2960,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, "(none)" , key->type)); if (key->type == Key::FOREIGN_KEY) { - fk_key_count++; Foreign_key *fk_key= (Foreign_key*) key; if (fk_key->validate(alter_info->create_list)) DBUG_RETURN(TRUE); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 9f9ef6335f367..6dedd5e85bed5 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -699,11 +699,9 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, if (lex->view_list.elements) { List_iterator_fast names(lex->view_list); - LEX_CSTRING *name; - int i; - + buff.append('('); - for (i= 0; (name= names++); i++) + while (LEX_CSTRING *name= names++) { append_identifier(thd, &buff, name); buff.append(", ", 2); diff --git a/sql/threadpool_winsockets.cc b/sql/threadpool_winsockets.cc index 41167781283d1..a214cda2a5c96 100644 --- a/sql/threadpool_winsockets.cc +++ b/sql/threadpool_winsockets.cc @@ -114,8 +114,17 @@ void AIO_buffer_cache::clear() if (!m_base) return; - /* Check that all items are returned to the cache. */ - DBUG_ASSERT(m_cache.size() == m_elements); + std::unique_lock lk(m_mtx, std::defer_lock); + for(;;) + { + if (lk.try_lock()) + { + if (m_cache.size() == m_elements) + break; + lk.unlock(); + } + Sleep(100); + } VirtualFree(m_base, 0, MEM_RELEASE); m_cache.clear(); m_base= 0; diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index 7af5f862aab0e..c56df29cbbc62 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -370,7 +370,6 @@ inline void PageBulk::finishPage() ut_ad((fmt != REDUNDANT) == m_is_comp); ulint count= 0; - ulint n_recs= 0; byte *slot= my_assume_aligned<2>(m_page + srv_page_size - (PAGE_DIR + PAGE_DIR_SLOT_SIZE)); const page_dir_slot_t *const slot0 = slot; @@ -386,7 +385,6 @@ inline void PageBulk::finishPage() ut_ad(offset >= PAGE_NEW_SUPREMUM); ut_ad(offset < page_offset(slot)); count++; - n_recs++; if (count == (PAGE_DIR_SLOT_MAX_N_OWNED + 1) / 2) { @@ -440,7 +438,6 @@ inline void PageBulk::finishPage() while (insert_rec != m_page + PAGE_OLD_SUPREMUM) { count++; - n_recs++; if (count == (PAGE_DIR_SLOT_MAX_N_OWNED + 1) / 2) { diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 9b26c038b2b8e..aaf85570616a5 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -806,7 +806,10 @@ void buf_page_print(const byte *read_buf, ulint zip_size) byte row[64]; for (byte *r= row; r != &row[64]; r+= 2, read_buf++) - r[0]= hex_to_ascii(*read_buf >> 4), r[1]= hex_to_ascii(*read_buf & 15); + { + r[0]= hex_to_ascii(byte(*read_buf >> 4)); + r[1]= hex_to_ascii(*read_buf & 15); + } sql_print_information("InnoDB: %.*s", 64, row); } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 4e695d5368111..d23d49f3cd71c 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1354,6 +1354,7 @@ dict_load_columns( if (table->fts == NULL) { table->fts = fts_create(table); table->fts->cache = fts_cache_create(table); + DICT_TF2_FLAG_SET(table, DICT_TF2_FTS_AUX_HEX_NAME); } ut_a(table->fts->doc_col == ULINT_UNDEFINED); @@ -2101,8 +2102,11 @@ dict_load_indexes( ut_ad(table->fts_doc_id_index == NULL); if (table->fts != NULL) { - table->fts_doc_id_index = dict_table_get_index_on_name( + dict_index_t *idx = dict_table_get_index_on_name( table, FTS_DOC_ID_INDEX_NAME); + if (idx && dict_index_is_unique(idx)) { + table->fts_doc_id_index = idx; + } } /* If the table contains FTS indexes, populate table->fts->indexes */ diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 7b01d994ff32d..0a2026efa33e9 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1343,7 +1343,7 @@ inline bool fil_space_t::acquire_if_not_stopped() return true; if (UNIV_UNLIKELY(n & STOPPING)) return false; - return UNIV_LIKELY(!(n & CLOSING)) || prepare(true); + return UNIV_LIKELY(!(n & CLOSING)) || prepare_acquired(); } bool fil_crypt_must_default_encrypt() @@ -1459,7 +1459,7 @@ space_list_t::iterator fil_space_t::next(space_list_t::iterator space, const uint32_t n= space->acquire_low(); if (UNIV_LIKELY(!(n & (STOPPING | CLOSING)))) break; - if (!(n & STOPPING) && space->prepare(true)) + if (!(n & STOPPING) && space->prepare_acquired()) break; } } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 08aad0df1cbbc..bfdc7bc0c7bf3 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -649,11 +649,9 @@ fil_space_extend_must_retry( } /** @return whether the file is usable for io() */ -ATTRIBUTE_COLD bool fil_space_t::prepare(bool have_mutex) +ATTRIBUTE_COLD bool fil_space_t::prepare_acquired() { ut_ad(referenced()); - if (!have_mutex) - mysql_mutex_lock(&fil_system.mutex); mysql_mutex_assert_owner(&fil_system.mutex); fil_node_t *node= UT_LIST_GET_LAST(chain); ut_ad(!id || purpose == FIL_TYPE_TEMPORARY || @@ -698,8 +696,16 @@ ATTRIBUTE_COLD bool fil_space_t::prepare(bool have_mutex) clear: clear_closing(); - if (!have_mutex) - mysql_mutex_unlock(&fil_system.mutex); + return is_open; +} + +/** @return whether the file is usable for io() */ +ATTRIBUTE_COLD bool fil_space_t::acquire_and_prepare() +{ + mysql_mutex_lock(&fil_system.mutex); + const auto flags= acquire_low() & (STOPPING | CLOSING); + const bool is_open= !flags || (flags == CLOSING && prepare_acquired()); + mysql_mutex_unlock(&fil_system.mutex); return is_open; } @@ -1396,13 +1402,13 @@ fil_space_t *fil_space_t::get(uint32_t id) mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_get_by_id(id); const uint32_t n= space ? space->acquire_low() : 0; - mysql_mutex_unlock(&fil_system.mutex); if (n & STOPPING) space= nullptr; - else if ((n & CLOSING) && !space->prepare()) + else if ((n & CLOSING) && !space->prepare_acquired()) space= nullptr; + mysql_mutex_unlock(&fil_system.mutex); return space; } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index b840c82a7da18..ff36fe32b867a 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -227,7 +227,7 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old, If that is the case, the instant ALTER TABLE would keep the InnoDB table in its current format. */ - const dict_index_t& oindex = *old.indexes.start; + dict_index_t& oindex = *old.indexes.start; dict_index_t& index = *indexes.start; first_alter_pos = 0; @@ -373,6 +373,15 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old, goto found_nullable; } } + + /* In case of discarded tablespace, InnoDB can't + read the root page. So assign the null bytes based + on nullabled fields */ + if (!oindex.table->space) { + oindex.n_core_null_bytes = static_cast( + UT_BITS_IN_BYTES(unsigned(oindex.n_nullable))); + } + /* The n_core_null_bytes only matters for ROW_FORMAT=COMPACT and ROW_FORMAT=DYNAMIC tables. */ ut_ad(UT_BITS_IN_BYTES(core_null) == oindex.n_core_null_bytes @@ -9235,16 +9244,14 @@ innobase_rename_columns_try( const char* table_name) { uint i = 0; - ulint num_v = 0; DBUG_ASSERT(ctx->need_rebuild()); DBUG_ASSERT(ha_alter_info->handler_flags & ALTER_COLUMN_NAME); for (Field** fp = table->field; *fp; fp++, i++) { - const bool is_virtual = !(*fp)->stored_in_db(); if (!((*fp)->flags & FIELD_IS_RENAMED)) { - goto processed_field; + continue; } for (const Create_field& cf : @@ -9262,10 +9269,6 @@ innobase_rename_columns_try( ut_error; processed_field: - if (is_virtual) { - num_v++; - } - continue; } diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index d4115f7be16cd..3c67de2f6e54f 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -57,6 +57,7 @@ Created July 18, 2007 Vasil Dimov #include "dict0crea.h" #include "fts0vlc.h" #include "scope.h" +#include "log.h" /** The latest successfully looked up innodb_fts_aux_table */ table_id_t innodb_ft_aux_table_id; @@ -168,19 +169,37 @@ time_t MYSQL_TYPE_DATETIME --------------------------------- */ -/*******************************************************************//** +/** Common function to fill any of the dynamic tables: INFORMATION_SCHEMA.innodb_trx INFORMATION_SCHEMA.innodb_locks INFORMATION_SCHEMA.innodb_lock_waits -@return 0 on success */ -static -int -trx_i_s_common_fill_table( -/*======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - Item* ); /*!< in: condition (not used) */ +@retval false if access to the table is blocked +@retval true if something should be filled in */ +static bool trx_i_s_common_fill_table(THD *thd, TABLE_LIST *tables) +{ + DBUG_ENTER("trx_i_s_common_fill_table"); + + /* deny access to non-superusers */ + if (check_global_access(thd, PROCESS_ACL)) + DBUG_RETURN(false); + + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str); + + /* update the cache */ + trx_i_s_cache_start_write(trx_i_s_cache); + trx_i_s_possibly_fetch_data_into_cache(trx_i_s_cache); + trx_i_s_cache_end_write(trx_i_s_cache); + + if (trx_i_s_cache_is_truncated(trx_i_s_cache)) + sql_print_warning("InnoDB: Data in %.*s truncated due to memory limit" + " of %u bytes", + int(tables->schema_table_name.length), + tables->schema_table_name.str, + TRX_I_S_MEM_LIMIT); + + DBUG_RETURN(true); +} /*******************************************************************//** Unbind a dynamic INFORMATION_SCHEMA table. @@ -343,26 +362,29 @@ static ST_FIELD_INFO innodb_trx_fields_info[]= /*******************************************************************//** Read data from cache buffer and fill the INFORMATION_SCHEMA.innodb_trx table with it. -@return 0 on success */ -static -int -fill_innodb_trx_from_cache( -/*=======================*/ - trx_i_s_cache_t* cache, /*!< in: cache to read from */ - THD* thd, /*!< in: used to call - schema_table_store_record() */ - TABLE* table) /*!< in/out: fill this table */ +@retval 0 on success +@retval 1 on failure */ +static int fill_innodb_trx_from_cache(THD *thd, TABLE_LIST *tables, Item*) { - Field** fields; ulint rows_num; char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; ulint i; DBUG_ENTER("fill_innodb_trx_from_cache"); - fields = table->field; + if (!trx_i_s_common_fill_table(thd, tables)) { + DBUG_RETURN(0); + } + + struct cache + { + cache() { trx_i_s_cache_start_read(trx_i_s_cache); } + ~cache() { trx_i_s_cache_end_read(trx_i_s_cache); } + } c; + + Field** fields = tables->table->field; - rows_num = trx_i_s_cache_get_rows_used(cache, + rows_num = trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_TRX); for (i = 0; i < rows_num; i++) { @@ -371,7 +393,7 @@ fill_innodb_trx_from_cache( row = (i_s_trx_row_t*) trx_i_s_cache_get_nth_row( - cache, I_S_INNODB_TRX, i); + trx_i_s_cache, I_S_INNODB_TRX, i); /* trx_id */ OK(fields[IDX_TRX_ID]->store(row->trx_id, true)); @@ -480,7 +502,7 @@ fill_innodb_trx_from_cache( OK(fields[IDX_TRX_AUTOCOMMIT_NON_LOCKING]->store( row->trx_is_autocommit_non_locking, true)); - OK(schema_table_store_record(thd, table)); + OK(schema_table_store_record(thd, tables->table)); } DBUG_RETURN(0); @@ -502,7 +524,7 @@ innodb_trx_init( schema = (ST_SCHEMA_TABLE*) p; schema->fields_info = Show::innodb_trx_fields_info; - schema->fill_table = trx_i_s_common_fill_table; + schema->fill_table = fill_innodb_trx_from_cache; DBUG_RETURN(0); } @@ -629,20 +651,29 @@ static int fill_innodb_locks_from_cache( /*=========================*/ - trx_i_s_cache_t* cache, /*!< in: cache to read from */ THD* thd, /*!< in: MySQL client connection */ - TABLE* table) /*!< in/out: fill this table */ + TABLE_LIST* tables, /*!< in/out: fill this table */ + Item*) { - Field** fields; ulint rows_num; char lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; ulint i; DBUG_ENTER("fill_innodb_locks_from_cache"); - fields = table->field; + if (!trx_i_s_common_fill_table(thd, tables)) { + DBUG_RETURN(0); + } + + struct cache + { + cache() { trx_i_s_cache_start_read(trx_i_s_cache); } + ~cache() { trx_i_s_cache_end_read(trx_i_s_cache); } + } c; + + Field** fields = tables->table->field; - rows_num = trx_i_s_cache_get_rows_used(cache, + rows_num = trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_LOCKS); for (i = 0; i < rows_num; i++) { @@ -653,7 +684,7 @@ fill_innodb_locks_from_cache( row = (i_s_locks_row_t*) trx_i_s_cache_get_nth_row( - cache, I_S_INNODB_LOCKS, i); + trx_i_s_cache, I_S_INNODB_LOCKS, i); /* lock_id */ trx_i_s_create_lock_id(row, lock_id, sizeof(lock_id)); @@ -700,7 +731,7 @@ fill_innodb_locks_from_cache( fields[IDX_LOCK_DATA]->set_null(); } - OK(schema_table_store_record(thd, table)); + OK(schema_table_store_record(thd, tables->table)); } DBUG_RETURN(0); @@ -722,7 +753,7 @@ innodb_locks_init( schema = (ST_SCHEMA_TABLE*) p; schema->fields_info = Show::innodb_locks_fields_info; - schema->fill_table = trx_i_s_common_fill_table; + schema->fill_table = fill_innodb_locks_from_cache; DBUG_RETURN(0); } @@ -804,12 +835,11 @@ static int fill_innodb_lock_waits_from_cache( /*==============================*/ - trx_i_s_cache_t* cache, /*!< in: cache to read from */ THD* thd, /*!< in: used to call schema_table_store_record() */ - TABLE* table) /*!< in/out: fill this table */ + TABLE_LIST* tables, /*!< in/out: fill this table */ + Item*) { - Field** fields; ulint rows_num; char requested_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; char blocking_lock_id[TRX_I_S_LOCK_ID_MAX_LEN + 1]; @@ -817,9 +847,19 @@ fill_innodb_lock_waits_from_cache( DBUG_ENTER("fill_innodb_lock_waits_from_cache"); - fields = table->field; + if (!trx_i_s_common_fill_table(thd, tables)) { + DBUG_RETURN(0); + } + + struct cache + { + cache() { trx_i_s_cache_start_read(trx_i_s_cache); } + ~cache() { trx_i_s_cache_end_read(trx_i_s_cache); } + } c; - rows_num = trx_i_s_cache_get_rows_used(cache, + Field** fields = tables->table->field; + + rows_num = trx_i_s_cache_get_rows_used(trx_i_s_cache, I_S_INNODB_LOCK_WAITS); for (i = 0; i < rows_num; i++) { @@ -828,7 +868,7 @@ fill_innodb_lock_waits_from_cache( row = (i_s_lock_waits_row_t*) trx_i_s_cache_get_nth_row( - cache, I_S_INNODB_LOCK_WAITS, i); + trx_i_s_cache, I_S_INNODB_LOCK_WAITS, i); /* requesting_trx_id */ OK(fields[IDX_REQUESTING_TRX_ID]->store( @@ -854,7 +894,7 @@ fill_innodb_lock_waits_from_cache( blocking_lock_id, sizeof(blocking_lock_id)))); - OK(schema_table_store_record(thd, table)); + OK(schema_table_store_record(thd, tables->table)); } DBUG_RETURN(0); @@ -876,7 +916,7 @@ innodb_lock_waits_init( schema = (ST_SCHEMA_TABLE*) p; schema->fields_info = Show::innodb_lock_waits_fields_info; - schema->fill_table = trx_i_s_common_fill_table; + schema->fill_table = fill_innodb_lock_waits_from_cache; DBUG_RETURN(0); } @@ -930,105 +970,6 @@ struct st_maria_plugin i_s_innodb_lock_waits = MariaDB_PLUGIN_MATURITY_STABLE, }; -/*******************************************************************//** -Common function to fill any of the dynamic tables: -INFORMATION_SCHEMA.innodb_trx -INFORMATION_SCHEMA.innodb_locks -INFORMATION_SCHEMA.innodb_lock_waits -@return 0 on success */ -static -int -trx_i_s_common_fill_table( -/*======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - Item* ) /*!< in: condition (not used) */ -{ - LEX_CSTRING table_name; - int ret; - trx_i_s_cache_t* cache; - - DBUG_ENTER("trx_i_s_common_fill_table"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - /* minimize the number of places where global variables are - referenced */ - cache = trx_i_s_cache; - - /* which table we have to fill? */ - table_name = tables->schema_table_name; - /* or table_name = tables->schema_table->table_name; */ - - RETURN_IF_INNODB_NOT_STARTED(table_name.str); - - /* update the cache */ - trx_i_s_cache_start_write(cache); - trx_i_s_possibly_fetch_data_into_cache(cache); - trx_i_s_cache_end_write(cache); - - if (trx_i_s_cache_is_truncated(cache)) { - - ib::warn() << "Data in " << table_name.str << " truncated due to" - " memory limit of " << TRX_I_S_MEM_LIMIT << " bytes"; - } - - ret = 0; - - trx_i_s_cache_start_read(cache); - - if (innobase_strcasecmp(table_name.str, "innodb_trx") == 0) { - - if (fill_innodb_trx_from_cache( - cache, thd, tables->table) != 0) { - - ret = 1; - } - - } else if (innobase_strcasecmp(table_name.str, "innodb_locks") == 0) { - - if (fill_innodb_locks_from_cache( - cache, thd, tables->table) != 0) { - - ret = 1; - } - - } else if (innobase_strcasecmp(table_name.str, "innodb_lock_waits") == 0) { - - if (fill_innodb_lock_waits_from_cache( - cache, thd, tables->table) != 0) { - - ret = 1; - } - - } else { - ib::error() << "trx_i_s_common_fill_table() was" - " called to fill unknown table: " << table_name.str << "." - " This function only knows how to fill" - " innodb_trx, innodb_locks and" - " innodb_lock_waits tables."; - - ret = 1; - } - - trx_i_s_cache_end_read(cache); - -#if 0 - DBUG_RETURN(ret); -#else - /* if this function returns something else than 0 then a - deadlock occurs between the mysqld server and mysql client, - see http://bugs.mysql.com/29900 ; when that bug is resolved - we can enable the DBUG_RETURN(ret) above */ - ret++; // silence a gcc46 warning - DBUG_RETURN(0); -#endif -} - namespace Show { /* Fields of the dynamic table information_schema.innodb_cmp. */ static ST_FIELD_INFO i_s_cmp_fields_info[] = diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index d6c7e07eaf519..4a569c15a53d2 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -536,15 +536,16 @@ struct fil_space_t final private: MY_ATTRIBUTE((warn_unused_result)) - /** Try to acquire a tablespace reference. - @return the old reference count (if STOPPING is set, it was not acquired) */ - uint32_t acquire_low() + /** Try to acquire a tablespace reference (increment referenced()). + @param avoid when these flags are set, nothing will be acquired + @return the old reference count */ + uint32_t acquire_low(uint32_t avoid= STOPPING) { uint32_t n= 0; while (!n_pending.compare_exchange_strong(n, n + 1, std::memory_order_acquire, std::memory_order_relaxed) && - !(n & STOPPING)); + !(n & avoid)); return n; } public: @@ -558,10 +559,8 @@ struct fil_space_t final @return whether the file is usable */ bool acquire() { - uint32_t n= acquire_low(); - if (UNIV_LIKELY(!(n & (STOPPING | CLOSING)))) - return true; - return UNIV_LIKELY(!(n & STOPPING)) && prepare(); + const auto flags= acquire_low(STOPPING | CLOSING) & (STOPPING | CLOSING); + return UNIV_LIKELY(!flags) || (flags == CLOSING && acquire_and_prepare()); } /** Acquire another tablespace reference for I/O. */ @@ -1031,7 +1030,9 @@ struct fil_space_t final private: /** @return whether the file is usable for io() */ - ATTRIBUTE_COLD bool prepare(bool have_mutex= false); + ATTRIBUTE_COLD bool prepare_acquired(); + /** @return whether the file is usable for io() */ + ATTRIBUTE_COLD bool acquire_and_prepare(); #endif /*!UNIV_INNOCHECKSUM */ }; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 3e391f4bce4e4..729cecc94dc1f 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -4061,6 +4061,11 @@ void UndorecApplier::log_update(const dtuple_t &tuple, { if (is_update) { + /* Ignore the index if the update doesn't affect the index */ + if (!row_upd_changes_ord_field_binary(index, update, + nullptr, + row, new_ext)) + goto next_index; dtuple_t *old_entry= row_build_index_entry_low( old_row, old_ext, index, heap, ROW_BUILD_NORMAL); @@ -4080,6 +4085,7 @@ void UndorecApplier::log_update(const dtuple_t &tuple, success= row_log_online_op(index, old_entry, 0); } } +next_index: index->lock.s_unlock(); if (!success) { diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index b4d11053623d2..ccedd5699b49e 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -121,7 +121,6 @@ class index_tuple_info_t { rec_offs* ins_offsets = NULL; dberr_t error = DB_SUCCESS; dtuple_t* dtuple; - ulint count = 0; const ulint flag = BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG | BTR_CREATE_FLAG; @@ -236,7 +235,6 @@ class index_tuple_info_t { mtr_commit(&mtr); rtr_clean_rtr_info(&rtr_info, true); - count++; } m_dtuple_vec->clear(); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index b53416e29768a..a2eacaf8e1294 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1261,9 +1261,6 @@ row_upd_changes_ord_field_binary_func( ulint i; const dict_index_t* clust_index; - ut_ad(thr); - ut_ad(thr->graph); - ut_ad(thr->graph->trx); ut_ad(!index->table->skip_alter_undo); n_unique = dict_index_get_n_unique(index); @@ -1463,9 +1460,11 @@ row_upd_changes_ord_field_binary_func( trx_rollback_recovered() when the server had crashed before storing the field. */ - ut_ad(thr->graph->trx->is_recovered); - ut_ad(thr->graph->trx - == trx_roll_crash_recv_trx); + ut_ad(!thr + || thr->graph->trx->is_recovered); + ut_ad(!thr + || thr->graph->trx + == trx_roll_crash_recv_trx); return(TRUE); } diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 9f4b68bb993fb..7309c0499f2ae 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -1025,10 +1025,8 @@ int ha_spider::external_lock( backup_error_status(); DBUG_ENTER("ha_spider::external_lock"); - DBUG_PRINT("info",("spider this=%p", this)); - DBUG_PRINT("info",("spider lock_type=%x", lock_type)); - DBUG_PRINT("info", ("spider sql_command=%d", thd_sql_command(thd))); + /* Beginning of wide_handler setup */ if (wide_handler->stage == SPD_HND_STAGE_EXTERNAL_LOCK) { /* Only the stage executor deals with table locks. */ @@ -1039,7 +1037,7 @@ int ha_spider::external_lock( } else { - /* Update the stage executor when the stage changes */ + /* Update the stage executor when the stage changes. */ wide_handler->stage= SPD_HND_STAGE_EXTERNAL_LOCK; wide_handler->stage_executor= this; } @@ -1048,35 +1046,30 @@ int ha_spider::external_lock( wide_handler->external_lock_type= lock_type; wide_handler->sql_command = thd_sql_command(thd); - /* We treat BEGIN as if UNLOCK TABLE. */ - if (wide_handler->sql_command == SQLCOM_BEGIN) - { - wide_handler->sql_command = SQLCOM_UNLOCK_TABLES; - } - if (lock_type == F_UNLCK && - wide_handler->sql_command != SQLCOM_UNLOCK_TABLES) - { - DBUG_RETURN(0); - } - - trx = spider_get_trx(thd, TRUE, &error_num); + trx= spider_get_trx(thd, TRUE, &error_num); if (error_num) { DBUG_RETURN(error_num); } - wide_handler->trx = trx; + wide_handler->trx= trx; + /* End of wide_handler setup */ - /* Question: Why the following if block is necessary? Why here? */ if (store_error_num) { DBUG_RETURN(store_error_num); } - DBUG_ASSERT(wide_handler->sql_command != SQLCOM_RENAME_TABLE && - wide_handler->sql_command != SQLCOM_DROP_DB); + /* We treat BEGIN as if UNLOCK TABLE. */ + if (wide_handler->sql_command == SQLCOM_BEGIN) + { + wide_handler->sql_command = SQLCOM_UNLOCK_TABLES; + } + const uint sql_command= wide_handler->sql_command; + + DBUG_ASSERT(sql_command != SQLCOM_RENAME_TABLE && + sql_command != SQLCOM_DROP_DB); - if (wide_handler->sql_command == SQLCOM_DROP_TABLE || - wide_handler->sql_command == SQLCOM_ALTER_TABLE) + if (sql_command == SQLCOM_DROP_TABLE || sql_command == SQLCOM_ALTER_TABLE) { if (trx->locked_connections) { @@ -1087,44 +1080,41 @@ int ha_spider::external_lock( DBUG_RETURN(0); } - if (lock_type != F_UNLCK) + if (lock_type == F_UNLCK) + { + if (sql_command != SQLCOM_UNLOCK_TABLES) + { + DBUG_RETURN(0); /* Unlock remote tables only by UNLOCK TABLES. */ + } + if (!trx->locked_connections) + { + DBUG_RETURN(0); /* No remote table actually locked by Spider */ + } + } + else { if (unlikely((error_num= spider_internal_start_trx(this)))) { DBUG_RETURN(error_num); } - if (wide_handler->sql_command != SQLCOM_SELECT && - wide_handler->sql_command != SQLCOM_HA_READ) + if (sql_command != SQLCOM_SELECT && sql_command != SQLCOM_HA_READ) { trx->updated_in_this_trx= TRUE; - DBUG_PRINT("info", ("spider trx->updated_in_this_trx=TRUE")); + } + if (!wide_handler->lock_table_type) + { + DBUG_RETURN(0); /* No need to actually lock remote tables. */ } } - if (wide_handler->lock_table_type > 0 || - wide_handler->sql_command == SQLCOM_UNLOCK_TABLES) + if (!partition_handler || !partition_handler->handlers) { - if (wide_handler->sql_command == SQLCOM_UNLOCK_TABLES) - { - /* lock tables does not call reset() */ - /* unlock tables does not call store_lock() */ - wide_handler->lock_table_type = 0; - } + DBUG_RETURN(lock_tables()); /* Non-partitioned table */ + } - /* lock/unlock tables */ - if (partition_handler && partition_handler->handlers) - { - for (uint roop_count= 0; roop_count < partition_handler->no_parts; - ++roop_count) - { - if (unlikely((error_num = - partition_handler->handlers[roop_count]->lock_tables()))) - { - DBUG_RETURN(error_num); - } - } - } - else if (unlikely((error_num= lock_tables()))) + for (uint i= 0; i < partition_handler->no_parts; ++i) + { + if (unlikely((error_num= partition_handler->handlers[i]->lock_tables()))) { DBUG_RETURN(error_num); } diff --git a/storage/spider/mysql-test/spider/bugfix/disabled.def b/storage/spider/mysql-test/spider/bugfix/disabled.def index 68de2b6bfdeca..e19ea07b76bbb 100644 --- a/storage/spider/mysql-test/spider/bugfix/disabled.def +++ b/storage/spider/mysql-test/spider/bugfix/disabled.def @@ -1,2 +1 @@ wait_timeout : MDEV-26045 -mdev_27239 : failed with ASAN build diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_24343.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_24343.result new file mode 100644 index 0000000000000..1d154daa8ecd5 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_24343.result @@ -0,0 +1,75 @@ +# +# MDEV-24343 Spider Left join failed Unknown column 't0.ID' in 'on clause' +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +`id` int(10) unsigned NOT NULL AUTO_INCREMENT, +`first_name` varchar(255) DEFAULT NULL, +PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO `tbl_a` VALUES (1,'RICHARD'), (2,'STEPHANE'), (3,'ALAIN'); +CREATE TABLE `tbl_b` ( +`id` int(10) unsigned NOT NULL AUTO_INCREMENT, +`last_name` varchar(255) DEFAULT NULL, +PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO `tbl_b` VALUES (1,'DEMONGEOT'),(2,'VAROQUI'); +CREATE TABLE `tbl_c` ( +`id` int(10) unsigned NOT NULL AUTO_INCREMENT, +`surname` varchar(255) DEFAULT NULL, +PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO `tbl_c` VALUES (1,'CON'),(2,'MOYEN'),(3,'MOYEN2'); +SELECT * from tbl_b JOIN tbl_c ON tbl_b.id = tbl_c.id LEFT OUTER JOIN tbl_a ON tbl_a.id = tbl_b.id; +id last_name id surname id first_name +1 DEMONGEOT 1 CON 1 RICHARD +2 VAROQUI 2 MOYEN 2 STEPHANE +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +`id` int(10) unsigned NOT NULL AUTO_INCREMENT, +`first_name` varchar(255) DEFAULT NULL, +PRIMARY KEY (`id`) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a"' +PARTITION BY LIST COLUMNS(`id`) ( +PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); +CREATE TABLE `tbl_b` ( +`id` int(10) unsigned NOT NULL AUTO_INCREMENT, +`last_name` varchar(255) DEFAULT NULL, +PRIMARY KEY (`id`) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_b"' +PARTITION BY LIST COLUMNS(`id`) ( +PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); +CREATE TABLE `tbl_c` ( +`id` int(10) unsigned NOT NULL AUTO_INCREMENT, +`surname` varchar(255) DEFAULT NULL, +PRIMARY KEY (`id`) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_c"' +PARTITION BY LIST COLUMNS(`id`) ( +PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); +SELECT * from tbl_b JOIN tbl_c ON tbl_b.id = tbl_c.id LEFT OUTER JOIN tbl_a ON tbl_a.id = tbl_b.id; +id last_name id surname id first_name +1 DEMONGEOT 1 CON 1 RICHARD +2 VAROQUI 2 MOYEN 2 STEPHANE +connection master_1; +DROP DATABASE auto_test_local; +connection child2_1; +DROP DATABASE auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_24343.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_24343.cnf new file mode 100644 index 0000000000000..05dfd8a0bcea9 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24343.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_24343.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_24343.test new file mode 100644 index 0000000000000..5756cbac993d0 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_24343.test @@ -0,0 +1,84 @@ +--echo # +--echo # MDEV-24343 Spider Left join failed Unknown column 't0.ID' in 'on clause' +--echo # + +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE tbl_a ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `first_name` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO `tbl_a` VALUES (1,'RICHARD'), (2,'STEPHANE'), (3,'ALAIN'); + +eval CREATE TABLE `tbl_b` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `last_name` varchar(255) DEFAULT NULL, + PRIMARY KEY (`ID`) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO `tbl_b` VALUES (1,'DEMONGEOT'),(2,'VAROQUI'); + +eval CREATE TABLE `tbl_c` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `surname` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO `tbl_c` VALUES (1,'CON'),(2,'MOYEN'),(3,'MOYEN2'); + +SELECT * from tbl_b JOIN tbl_c ON tbl_b.id = tbl_c.id LEFT OUTER JOIN tbl_a ON tbl_a.id = tbl_b.id; + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +eval CREATE TABLE tbl_a ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `first_name` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a"' +PARTITION BY LIST COLUMNS(`id`) ( + PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); + +eval CREATE TABLE `tbl_b` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `last_name` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_b"' +PARTITION BY LIST COLUMNS(`id`) ( + PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); + +eval CREATE TABLE `tbl_c` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `surname` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_c"' +PARTITION BY LIST COLUMNS(`id`) ( + PARTITION `pt1` DEFAULT COMMENT = 'srv "s_2_1"' +); + +SELECT * from tbl_b JOIN tbl_c ON tbl_b.id = tbl_c.id LEFT OUTER JOIN tbl_a ON tbl_a.id = tbl_b.id; + +--connection master_1 +DROP DATABASE auto_test_local; + +--connection child2_1 +DROP DATABASE auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/r/direct_join.result b/storage/spider/mysql-test/spider/r/direct_join.result index 4f0db23107925..4b2c3e04bfdee 100644 --- a/storage/spider/mysql-test/spider/r/direct_join.result +++ b/storage/spider/mysql-test/spider/r/direct_join.result @@ -76,7 +76,7 @@ a b c connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0,`auto_test_remote`.`ta_r_3` t1,`auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc limit 1,2 +select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc limit 1,2 SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/mysql-test/spider/r/direct_join_using.result b/storage/spider/mysql-test/spider/r/direct_join_using.result index 1bb1b4c1cd2e4..facfabfe384b7 100644 --- a/storage/spider/mysql-test/spider/r/direct_join_using.result +++ b/storage/spider/mysql-test/spider/r/direct_join_using.result @@ -79,7 +79,7 @@ a b c connection child2_1; SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %'; argument -select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0,`auto_test_remote`.`ta_r_3` t1,`auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc +select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc SELECT argument FROM mysql.general_log WHERE command_type != 'Execute' AND argument LIKE '%select %' SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a; a b date_format(c, '%Y-%m-%d %H:%i:%s') diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 0c3fe4aadab22..d92b3fca8702e 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -7162,25 +7162,13 @@ int spider_db_mbase_util::append_table( } else if (*current_pos > 0 && !first) { DBUG_PRINT("info",("spider no condition")); - if (top_down) + if (str) { - if (str) + if (str->reserve(SPIDER_SQL_JOIN_LEN)) { - if (str->reserve(SPIDER_SQL_JOIN_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_JOIN_STR, SPIDER_SQL_JOIN_LEN); - } - } else { - if (str) - { - if (str->reserve(SPIDER_SQL_COMMA_LEN)) - { - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - } - str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); + DBUG_RETURN(HA_ERR_OUT_OF_MEM); } + str->q_append(SPIDER_SQL_JOIN_STR, SPIDER_SQL_JOIN_LEN); } } diff --git a/storage/spider/spd_trx.cc b/storage/spider/spd_trx.cc index e321673906516..900109ac64f86 100644 --- a/storage/spider/spd_trx.cc +++ b/storage/spider/spd_trx.cc @@ -93,43 +93,51 @@ uchar *spider_trx_ha_get_key( DBUG_RETURN((uchar*) trx_ha->table_name); } -int spider_free_trx_conn( - SPIDER_TRX *trx, - bool trx_free -) { - int roop_count; +/* + Try to free the connections held by the given transaction. +*/ +int spider_free_trx_conn(SPIDER_TRX *trx, bool trx_free) +{ + int loop_count= 0; SPIDER_CONN *conn; + HASH *conn_hash= &trx->trx_conn_hash; + DBUG_ENTER("spider_free_trx_conn"); - roop_count = 0; - if ( - trx_free || - spider_param_conn_recycle_mode(trx->thd) != 2 - ) { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash, - roop_count))) + DBUG_ASSERT(!trx_free || !trx->locked_connections); + + /* Clear the connection queues in any case. */ + while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count))) + { + spider_conn_clear_queue_at_commit(conn); + loop_count++; + } + + if (trx_free || spider_param_conn_recycle_mode(trx->thd) != 2) + { + /* Free connections only when no connection is locked. */ + if (!trx->locked_connections) { - spider_conn_clear_queue_at_commit(conn); - if (conn->table_lock) + loop_count= 0; + while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count))) { - DBUG_ASSERT(!trx_free); - roop_count++; - } else - spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &roop_count); + spider_free_conn_from_trx(trx, conn, FALSE, trx_free, &loop_count); + } } trx->trx_conn_adjustment++; - } else { - while ((conn = (SPIDER_CONN*) my_hash_element(&trx->trx_conn_hash, - roop_count))) + + DBUG_RETURN(0); + } + + loop_count= 0; + while ((conn= (SPIDER_CONN *) my_hash_element(conn_hash, loop_count))) + { + if (!conn->table_lock) { - spider_conn_clear_queue_at_commit(conn); - if (conn->table_lock) - { - DBUG_ASSERT(!trx_free); - } else - conn->error_mode = 1; - roop_count++; + conn->error_mode= 1; } + loop_count++; } + DBUG_RETURN(0); } @@ -3278,6 +3286,12 @@ int spider_commit( trx->bulk_access_conn_first = NULL; #endif + /* + We do (almost) nothing if the following two conditions are both met: + + * This is just the end of a statement, not an explicit commit. + * The autocommit is OFF or we are in an explicit transaction. + */ if (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { if (trx->trx_start)