From a19cb3884f443e68eecfa7b96ea109768a0a6188 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 20 Aug 2020 15:32:35 +0300 Subject: [PATCH 1/2] MDEV-23511 shutdown_server 10 times out, causing server kill at shutdown Shutdown of mtr tests may be too impatient, esp on CI environment where 10 seconds of `arg` of `shutdown_server arg` may not be enough for the clean shutdown to complete. This is fixed to remove explicit non-zero timeout argument to `shutdown_server` from all mtr tests. mysqltest computes 60 seconds default value for the timeout for the argless `shutdown_server` command. This policy is additionally ensured with a compile time assert. --- client/mysqltest.cc | 6 ++++-- mysql-test/include/restart_mysqld.inc | 2 +- mysql-test/include/rpl_stop_server.inc | 4 ++-- mysql-test/include/search_pattern_in_file.inc | 2 +- mysql-test/include/shutdown_mysqld.inc | 2 +- .../suite/binlog/t/binlog_max_extension.test | 4 ++-- .../suite/binlog_encryption/restart_server.inc | 2 +- mysql-test/suite/encryption/t/innochecksum.test | 2 +- .../suite/innodb/t/innodb-corrupted-table.test | 2 +- mysql-test/suite/innodb/t/innodb_bug60196.test | 4 ++-- mysql-test/suite/multi_source/info_logs.test | 2 +- ...percona_slow_extended-slave_innodb_stats.test | 2 +- mysql-test/suite/roles/acl_load_mutex-5170.test | 2 +- mysql-test/suite/rpl/t/rpl_gtid_crash.test | 2 +- mysql-test/suite/rpl/t/rpl_gtid_stop_start.test | 16 ++++++++-------- mysql-test/suite/rpl/t/rpl_mdev382.test | 2 +- .../suite/rpl/t/rpl_parallel_partition.test | 2 +- .../suite/storage_engine/alter_tablespace.test | 2 +- .../suite/storage_engine/trx/xa_recovery.test | 2 +- mysql-test/t/empty_server_name-8224.test | 2 +- mysql-test/t/host_cache_size_functionality.test | 4 ++-- mysql-test/t/init_file_set_password-7656.test | 2 +- mysql-test/t/log_errchk.test | 2 +- .../include/restart_mysqld_with_option.inc | 2 +- .../rocksdb/t/check_ignore_unknown_options.test | 2 +- .../rocksdb/t/insert_optimized_config.test | 4 ++-- .../rocksdb/mysql-test/rocksdb/t/mysqldump2.test | 2 +- .../mysql-test/rocksdb/t/optimize_table.test | 2 +- .../mysql-test/rocksdb/t/persistent_cache.test | 4 ++-- .../rocksdb/mysql-test/rocksdb/t/shutdown.test | 2 +- .../mysql-test/rocksdb/t/validate_datadic.test | 8 ++++---- ...rocksdb_rate_limiter_bytes_per_sec_basic.test | 4 ++-- 32 files changed, 52 insertions(+), 50 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 7d2b4b3b0a7b0..2a9560e8903fd 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -185,7 +185,7 @@ static uint opt_tail_lines= 0; static uint opt_connect_timeout= 0; static uint opt_wait_for_pos_timeout= 0; - +static const uint default_wait_for_pos_timeout= 300; static char delimiter[MAX_DELIMITER_LENGTH]= ";"; static uint delimiter_length= 1; @@ -5074,6 +5074,8 @@ void do_shutdown_server(struct st_command *command) }; DBUG_ENTER("do_shutdown_server"); + /* the wait-for-pos' default based value of 'timeout' must fit to MDEV-23511 */ + compile_time_assert(default_wait_for_pos_timeout / 5 >= 60); check_command_args(command, command->first_argument, shutdown_args, sizeof(shutdown_args)/sizeof(struct command_arg), ' '); @@ -7058,7 +7060,7 @@ static struct my_option my_long_options[] = {"wait_for_pos_timeout", 0, "Number of seconds to wait for master_pos_wait", &opt_wait_for_pos_timeout, &opt_wait_for_pos_timeout, 0, GET_UINT, - REQUIRED_ARG, 300, 0, 3600 * 12, 0, 0, 0}, + REQUIRED_ARG, default_wait_for_pos_timeout, 0, 3600 * 12, 0, 0, 0}, {"plugin_dir", 0, "Directory for client-side plugins.", &opt_plugin_dir, &opt_plugin_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/mysql-test/include/restart_mysqld.inc b/mysql-test/include/restart_mysqld.inc index 3d3e55db4acea..689f3b8cc1f17 100644 --- a/mysql-test/include/restart_mysqld.inc +++ b/mysql-test/include/restart_mysqld.inc @@ -1,6 +1,6 @@ # ==== Usage ==== # -# [--let $shutdown_timeout= 30] +# [--let $shutdown_timeout= 60] # [--let $allow_rpl_inited= 1] # --source include/restart_mysqld.inc diff --git a/mysql-test/include/rpl_stop_server.inc b/mysql-test/include/rpl_stop_server.inc index 978cfec18856a..049c3d5bbd22f 100644 --- a/mysql-test/include/rpl_stop_server.inc +++ b/mysql-test/include/rpl_stop_server.inc @@ -47,8 +47,8 @@ if ($rpl_debug) --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect # Send shutdown to the connected server and give -# it 60 seconds to die before zapping it -shutdown_server 60; +# it 60 seconds (of mysqltest's default) to die before zapping it +shutdown_server; --source include/wait_until_disconnected.inc diff --git a/mysql-test/include/search_pattern_in_file.inc b/mysql-test/include/search_pattern_in_file.inc index 6bead628fb005..5e66bbb7db060 100644 --- a/mysql-test/include/search_pattern_in_file.inc +++ b/mysql-test/include/search_pattern_in_file.inc @@ -36,7 +36,7 @@ # # Stop the server # let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; # --exec echo "wait" > $restart_file -# --shutdown_server 10 +# --shutdown_server # --source include/wait_until_disconnected.inc # # --error 1 diff --git a/mysql-test/include/shutdown_mysqld.inc b/mysql-test/include/shutdown_mysqld.inc index c8ab6d00f0d9f..74a3028946dd1 100644 --- a/mysql-test/include/shutdown_mysqld.inc +++ b/mysql-test/include/shutdown_mysqld.inc @@ -1,6 +1,6 @@ # ==== Usage ==== # -# [--let $shutdown_timeout= 30] +# [--let $shutdown_timeout= 60] # [--let $allow_rpl_inited= 1] # --source include/shutdown_mysqld.inc diff --git a/mysql-test/suite/binlog/t/binlog_max_extension.test b/mysql-test/suite/binlog/t/binlog_max_extension.test index 199a31ea05ca7..81e357448f6d7 100644 --- a/mysql-test/suite/binlog/t/binlog_max_extension.test +++ b/mysql-test/suite/binlog/t/binlog_max_extension.test @@ -41,7 +41,7 @@ RESET MASTER; # 1. Stop master server -- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --- shutdown_server 10 +-- shutdown_server -- source include/wait_until_disconnected.inc # 2. Prepare log and index file @@ -70,7 +70,7 @@ FLUSH LOGS; # 1. Stop the server -- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --- shutdown_server 10 +-- shutdown_server -- source include/wait_until_disconnected.inc # 2. Undo changes to index and log files diff --git a/mysql-test/suite/binlog_encryption/restart_server.inc b/mysql-test/suite/binlog_encryption/restart_server.inc index 6cd0788cf4390..8f0fe7d89707b 100644 --- a/mysql-test/suite/binlog_encryption/restart_server.inc +++ b/mysql-test/suite/binlog_encryption/restart_server.inc @@ -22,7 +22,7 @@ --enable_reconnect --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.$rpl_server_number.expect -shutdown_server 10; +shutdown_server; --source include/wait_until_disconnected.inc diff --git a/mysql-test/suite/encryption/t/innochecksum.test b/mysql-test/suite/encryption/t/innochecksum.test index 47da8525130d2..5423a70f5d98d 100644 --- a/mysql-test/suite/encryption/t/innochecksum.test +++ b/mysql-test/suite/encryption/t/innochecksum.test @@ -63,7 +63,7 @@ let MYSQLD_DATADIR=`select @@datadir`; --echo # We give 30 seconds to do a clean shutdown because we do not want --echo # to redo apply the pages of t1.ibd at the time of recovery. --echo # We want SQL to initiate the first access to t1.ibd. -shutdown_server 30; +shutdown_server; --echo # Wait until disconnected. --source include/wait_until_disconnected.inc diff --git a/mysql-test/suite/innodb/t/innodb-corrupted-table.test b/mysql-test/suite/innodb/t/innodb-corrupted-table.test index a7f4ad4afd4ff..a81235a9dd4d2 100644 --- a/mysql-test/suite/innodb/t/innodb-corrupted-table.test +++ b/mysql-test/suite/innodb/t/innodb-corrupted-table.test @@ -24,7 +24,7 @@ alter table t1 add primary key (pk); --echo # Stop the server, replace the frm with the old one and restart the server --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc --remove_file $datadir/test/t1.frm diff --git a/mysql-test/suite/innodb/t/innodb_bug60196.test b/mysql-test/suite/innodb/t/innodb_bug60196.test index e479b8d6b82a9..7f1f5c40585c7 100644 --- a/mysql-test/suite/innodb/t/innodb_bug60196.test +++ b/mysql-test/suite/innodb/t/innodb_bug60196.test @@ -50,7 +50,7 @@ SELECT * FROM bug_60196; -- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Send a shutdown request to the server --- shutdown_server 10 +-- shutdown_server # Call script that will poll the server waiting for it to disapear -- source include/wait_until_disconnected.inc @@ -124,7 +124,7 @@ SELECT * FROM Bug_60309; -- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect # Send a shutdown request to the server --- shutdown_server 10 +-- shutdown_server # Call script that will poll the server waiting for it to disapear -- source include/wait_until_disconnected.inc diff --git a/mysql-test/suite/multi_source/info_logs.test b/mysql-test/suite/multi_source/info_logs.test index ef504e06a2fa1..234e317e5ce14 100644 --- a/mysql-test/suite/multi_source/info_logs.test +++ b/mysql-test/suite/multi_source/info_logs.test @@ -150,7 +150,7 @@ show all slaves status; --append_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect restart EOF ---shutdown_server 60 +--shutdown_server --source include/wait_until_connected_again.inc --source include/wait_for_slave_to_start.inc set default_master_connection = 'MASTER 2.2'; diff --git a/mysql-test/suite/percona/slow_extended.patch/percona_slow_extended-slave_innodb_stats.test b/mysql-test/suite/percona/slow_extended.patch/percona_slow_extended-slave_innodb_stats.test index b0a6c98870c3d..43af046011870 100644 --- a/mysql-test/suite/percona/slow_extended.patch/percona_slow_extended-slave_innodb_stats.test +++ b/mysql-test/suite/percona/slow_extended.patch/percona_slow_extended-slave_innodb_stats.test @@ -23,7 +23,7 @@ STOP SLAVE; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect wait EOF ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc --append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect restart diff --git a/mysql-test/suite/roles/acl_load_mutex-5170.test b/mysql-test/suite/roles/acl_load_mutex-5170.test index 22b9dffb5fd26..76d817be055b9 100644 --- a/mysql-test/suite/roles/acl_load_mutex-5170.test +++ b/mysql-test/suite/roles/acl_load_mutex-5170.test @@ -10,7 +10,7 @@ flush tables; --append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect wait EOF ---shutdown_server 60 +--shutdown_server --source include/wait_until_disconnected.inc --enable_reconnect --append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test index b81cbd38cd353..cf749dd8d6562 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_crash.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test @@ -624,7 +624,7 @@ SELECT * FROM t1 WHERE a >= 30 ORDER BY a; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect wait EOF -shutdown_server 10; +shutdown_server; --source include/wait_until_disconnected.inc --remove_file $datadir/master-bin.state diff --git a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test index 09b35011f1ff5..3d605f3f2132a 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_stop_start.test @@ -29,7 +29,7 @@ CHANGE MASTER TO master_use_gtid=current_pos; wait EOF FLUSH LOGS; ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --connection server_1 @@ -70,7 +70,7 @@ SHOW BINLOG EVENTS IN 'master-bin.000004' LIMIT 1,1; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect @@ -103,7 +103,7 @@ SELECT * FROM t1 ORDER BY a; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect @@ -148,7 +148,7 @@ SELECT * FROM t1 ORDER BY a; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect @@ -191,7 +191,7 @@ SET sql_log_bin= 1; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect @@ -221,7 +221,7 @@ SELECT * FROM t1 ORDER BY a; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect @@ -259,7 +259,7 @@ SELECT domain_id, COUNT(*) FROM mysql.gtid_slave_pos GROUP BY domain_id; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect @@ -291,7 +291,7 @@ SET sql_log_bin=1; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc # Let the slave mysqld server start again. diff --git a/mysql-test/suite/rpl/t/rpl_mdev382.test b/mysql-test/suite/rpl/t/rpl_mdev382.test index cb67052b47d17..606508ccde1e6 100644 --- a/mysql-test/suite/rpl/t/rpl_mdev382.test +++ b/mysql-test/suite/rpl/t/rpl_mdev382.test @@ -212,7 +212,7 @@ SELECT * FROM `db1``; select 'oops!'`.`t``1` ORDER BY 1; wait-rpl_mdev382.test EOF ---shutdown_server 30 +--shutdown_server --append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect restart-rpl_mdev382.test diff --git a/mysql-test/suite/rpl/t/rpl_parallel_partition.test b/mysql-test/suite/rpl/t/rpl_parallel_partition.test index 37dce9fef8088..ea6c5dca6be3a 100644 --- a/mysql-test/suite/rpl/t/rpl_parallel_partition.test +++ b/mysql-test/suite/rpl/t/rpl_parallel_partition.test @@ -42,7 +42,7 @@ ALTER TABLE `E` REMOVE PARTITIONING; --write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect wait EOF ---shutdown_server 30 +--shutdown_server --source include/wait_until_disconnected.inc --connection default --source include/wait_until_disconnected.inc diff --git a/mysql-test/suite/storage_engine/alter_tablespace.test b/mysql-test/suite/storage_engine/alter_tablespace.test index 3c4910069a071..1899da28320b0 100644 --- a/mysql-test/suite/storage_engine/alter_tablespace.test +++ b/mysql-test/suite/storage_engine/alter_tablespace.test @@ -46,7 +46,7 @@ wait EOF --enable_reconnect - --shutdown_server 60 + --shutdown_server --source include/wait_until_disconnected.inc diff --git a/mysql-test/suite/storage_engine/trx/xa_recovery.test b/mysql-test/suite/storage_engine/trx/xa_recovery.test index e17bb9d2ea4e6..f53640578cdef 100644 --- a/mysql-test/suite/storage_engine/trx/xa_recovery.test +++ b/mysql-test/suite/storage_engine/trx/xa_recovery.test @@ -12,7 +12,7 @@ --append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect restart EOF ---shutdown_server 60 +--shutdown_server --source include/wait_until_connected_again.inc diff --git a/mysql-test/t/empty_server_name-8224.test b/mysql-test/t/empty_server_name-8224.test index b15e9d82eb842..5c5140be2e07a 100644 --- a/mysql-test/t/empty_server_name-8224.test +++ b/mysql-test/t/empty_server_name-8224.test @@ -4,7 +4,7 @@ --source include/not_embedded.inc create server '' foreign data wrapper w2 options (host '127.0.0.1'); --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect diff --git a/mysql-test/t/host_cache_size_functionality.test b/mysql-test/t/host_cache_size_functionality.test index db4f64fd4930d..9ec26010ab6f8 100644 --- a/mysql-test/t/host_cache_size_functionality.test +++ b/mysql-test/t/host_cache_size_functionality.test @@ -44,7 +44,7 @@ select @@global.Host_Cache_Size > 0; let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; --exec echo "wait" > $restart_file ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc -- exec echo "restart:--host_cache_size=1 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect @@ -143,7 +143,7 @@ SELECT Host_Cache_Size = @@SESSION.Host_Cache_Size; #let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; #--exec echo "wait" > $restart_file -#--shutdown_server 10 +#--shutdown_server #--source include/wait_until_disconnected.inc #-- exec echo "restart:--bind-address=$bind_ip " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect #-- enable_reconnect diff --git a/mysql-test/t/init_file_set_password-7656.test b/mysql-test/t/init_file_set_password-7656.test index ecee392435593..b3c785a28d95e 100644 --- a/mysql-test/t/init_file_set_password-7656.test +++ b/mysql-test/t/init_file_set_password-7656.test @@ -15,7 +15,7 @@ EOF --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc --exec echo "restart:--init-file=$MYSQLTEST_VARDIR/init.file " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect diff --git a/mysql-test/t/log_errchk.test b/mysql-test/t/log_errchk.test index 2808458e9f166..1afc0e29f3a85 100644 --- a/mysql-test/t/log_errchk.test +++ b/mysql-test/t/log_errchk.test @@ -31,7 +31,7 @@ --echo # and slow query log file. # Restart server with fifo file as general log file. --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---shutdown_server 60 +--shutdown_server --source include/wait_until_disconnected.inc --enable_reconnect # Write file to make mysql-test-run.pl start up the server again diff --git a/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc b/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc index 4250b368b1a8b..81cd2200ae06c 100644 --- a/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc +++ b/storage/rocksdb/mysql-test/rocksdb/include/restart_mysqld_with_option.inc @@ -15,7 +15,7 @@ if ($rpl_inited) # Send shutdown to the connected server and give # it 10 seconds to die before zapping it -shutdown_server 10; +shutdown_server; # Write file to make mysql-test-run.pl start up the server again --exec echo "restart:$_mysqld_option" > $_expect_file_name diff --git a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test index c8c12626139bc..15a7d319c0450 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test @@ -41,7 +41,7 @@ perl; EOF --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---shutdown_server 10 +--shutdown_server --error 1 --exec $MYSQLD_CMD --plugin_load=$HA_ROCKSDB_SO --rocksdb_ignore_unknown_options=0 --log-error=$error_log diff --git a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test index 46ea7f0eb0ac7..a24851d9d8c6a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/insert_optimized_config.test @@ -8,7 +8,7 @@ DROP TABLE IF EXISTS t1; # reload with load optimized config let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; --exec echo "wait" > $restart_file ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc -- exec echo "restart:--rocksdb_write_disable_wal=1 --rocksdb_flush_log_at_trx_commit=0 --rocksdb_default_cf_options=write_buffer_size=16k;target_file_size_base=16k;level0_file_num_compaction_trigger=4;level0_slowdown_writes_trigger=256;level0_stop_writes_trigger=256;max_write_buffer_number=16;compression_per_level=kNoCompression;memtable=vector:1024 --rocksdb_override_cf_options=__system__={memtable=skip_list:16} --rocksdb_compaction_sequential_deletes=0 --rocksdb_compaction_sequential_deletes_window=0 --rocksdb_allow_concurrent_memtable_write=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect @@ -39,7 +39,7 @@ select count(*), sum(id), sum(i1), sum(i2) from t1; # reload without load optimized config let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; --exec echo "wait" > $restart_file ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc -- exec echo "restart:--rocksdb_write_disable_wal=0 --rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect diff --git a/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test b/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test index ca9eb5d2ecf0b..4f4f5ed092b04 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/mysqldump2.test @@ -21,7 +21,7 @@ optimize table t1; #wiping block cache let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; --exec echo "wait" > $restart_file ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc -- exec echo "restart:--rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;disable_auto_compactions=true;level0_stop_writes_trigger=1000 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect diff --git a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test index 7a8f4fc708578..50df3f9c102f8 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/optimize_table.test @@ -32,7 +32,7 @@ while ($t <= 6) { # Disable auto compaction so that effects of optimize table are stable let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; --exec echo "wait" > $restart_file ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc -- exec echo "restart:--rocksdb_default_cf_options=write_buffer_size=64k;target_file_size_base=64k;max_bytes_for_level_base=1m;compression_per_level=kNoCompression;disable_auto_compactions=true;level0_stop_writes_trigger=1000 " > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect diff --git a/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test b/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test index 03d1d0a60bc30..49e5e5c11726f 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/persistent_cache.test @@ -10,7 +10,7 @@ DROP TABLE IF EXISTS t1; --exec echo "wait" >$_expect_file_name # restart server with correct parameters -shutdown_server 10; +shutdown_server; --exec echo "restart:--rocksdb_persistent_cache_path=$_cache_file_name --rocksdb_persistent_cache_size_mb=100" >$_expect_file_name --sleep 5 --enable_reconnect @@ -28,7 +28,7 @@ select * from t1 where a = 1; # restart server to re-read cache --exec echo "wait" >$_expect_file_name -shutdown_server 10; +shutdown_server; --exec echo "restart:--rocksdb_persistent_cache_path=$_cache_file_name --rocksdb_persistent_cache_size_mb=100" >$_expect_file_name --sleep 5 --enable_reconnect diff --git a/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test b/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test index ba625deb5141b..f76bc9f615383 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/shutdown.test @@ -23,7 +23,7 @@ while ($i <= $max) { # Restart the server let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; --exec echo "wait" > $restart_file ---shutdown_server 10 +--shutdown_server --source include/wait_until_disconnected.inc -- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -- enable_reconnect diff --git a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test index ec48dc03ec8ae..e7ab37d2658be 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/validate_datadic.test @@ -25,7 +25,7 @@ CREATE TABLE t2 (pk int primary key) ENGINE=ROCKSDB PARTITION BY KEY(pk) PARTITI # Send shutdown to the connected server and give it 10 seconds to die before # zapping it -shutdown_server 10; +shutdown_server; # Write file to make mysql-test-run.pl start up the server again --exec echo "restart" >$_expect_file_name @@ -42,7 +42,7 @@ shutdown_server 10; # Now shut down again and rename one of the .frm files --exec echo "wait" >$_expect_file_name -shutdown_server 10; +shutdown_server; # Rename the file --move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp @@ -70,7 +70,7 @@ shutdown_server 10; # Now shut down again and rename one the .frm file back and make a copy of it --exec echo "wait" >$_expect_file_name -shutdown_server 10; +shutdown_server; --remove_file $LOG # Rename the file --move_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm.tmp $MYSQLTEST_VARDIR/mysqld.1/data/test/t1.frm @@ -92,7 +92,7 @@ shutdown_server 10; # Shut down an clean up --exec echo "wait" >$_expect_file_name -shutdown_server 10; +shutdown_server; --remove_file $MYSQLTEST_VARDIR/mysqld.1/data/test/t1_dummy.frm --exec echo "restart" >$_expect_file_name --enable_reconnect diff --git a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test index 8277011831a70..743f942af9cd2 100644 --- a/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test +++ b/storage/rocksdb/mysql-test/rocksdb_sys_vars/t/rocksdb_rate_limiter_bytes_per_sec_basic.test @@ -13,7 +13,7 @@ SET @@global.rocksdb_rate_limiter_bytes_per_sec = 10000; # Send shutdown to the connected server and give it 10 seconds to die before # zapping it -shutdown_server 10; +shutdown_server; # Attempt to restart the server with the rate limiter on --exec echo "restart:--rocksdb_rate_limiter_bytes_per_sec=10000" >$_expect_file_name @@ -53,7 +53,7 @@ SET @@global.rocksdb_rate_limiter_bytes_per_sec = -1; # Restart the server without the rate limiter --exec echo "wait" >$_expect_file_name -shutdown_server 10; +shutdown_server; --exec echo "restart" >$_expect_file_name --sleep 5 From f3160ee44f8f3ae4e5eeea768e289ec40253f35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 21 Aug 2020 18:22:55 +0300 Subject: [PATCH 2/2] MDEV-22782 AddressSanitizer race condition in trx_free() In trx_free() we used to declare the entire trx_t unaccessible and then declare that some data members are accessible. This involves a race condition with other threads that may concurrently access the data members that must remain accessible. One type of error is "AddressSanitizer: unknown-crash", whose exact cause we have not determined. Another type of error (reported in MDEV-23472) is "use-after-poison", where the reported shadow bytes would in fact be 00, indicating that the memory was no longer poisoned. The poison-access-unpoison race condition was confirmed by "rr replay". We eliminate the race condition by invoking MEM_NOACCESS on each individual data member of trx_t before freeing the memory to the pool. The memory would not be unpoisoned until the pool is freed or the memory is being reused for another allocation. trx_t::free(): Replaces trx_free(). trx_t::active_commit_ordered: Changed to bool, so that MEM_NOACCESS can be invoked. Removed some accessor functions. Pool: Remove all MEM_ instrumentation. TrxFactory: Move the MEM_ instrumentation from Pool. TrxFactory::debug(): Removed. Moved to trx_t::free(). Because the memory was already marked unaccessible in trx_t::free(), the Factory::debug() call in Pool::putl() would be unable to access it. trx_allocate_for_background(): Replaces trx_create_low(). trx_t::free(): Perform all consistency checks while avoiding duplication, and declare most data members unaccessible. --- storage/innobase/fts/fts0fts.cc | 4 +- storage/innobase/handler/ha_innodb.cc | 38 +--- storage/innobase/include/trx0trx.h | 15 +- storage/innobase/include/ut0pool.h | 30 ---- storage/innobase/trx/trx0trx.cc | 238 ++++++++++++++------------ 5 files changed, 149 insertions(+), 176 deletions(-) diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 980c4c9ad5ffc..683104695e38d 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -4234,7 +4234,7 @@ fts_sync_commit( << " ins/sec"; } - /* Avoid assertion in trx_free(). */ + /* Avoid assertion in trx_t::free(). */ trx->dict_operation_lock_mode = 0; trx_free_for_background(trx); @@ -4288,7 +4288,7 @@ fts_sync_rollback( fts_sql_rollback(trx); - /* Avoid assertion in trx_free(). */ + /* Avoid assertion in trx_t::free(). */ trx->dict_operation_lock_mode = 0; trx_free_for_background(trx); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4db7f58b5131a..3ab1e9c7cc26f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2800,18 +2800,6 @@ trx_is_registered_for_2pc( return(trx->is_registered == 1); } -/*********************************************************************//** -Note that innobase_commit_ordered() was run. */ -static inline -void -trx_set_active_commit_ordered( -/*==========================*/ - trx_t* trx) /* in: transaction */ -{ - ut_a(trx_is_registered_for_2pc(trx)); - trx->active_commit_ordered = 1; -} - /*********************************************************************//** Note that a transaction has been registered with MySQL 2PC coordinator. */ static inline @@ -2821,7 +2809,7 @@ trx_register_for_2pc( trx_t* trx) /* in: transaction */ { trx->is_registered = 1; - ut_ad(trx->active_commit_ordered == 0); + ut_ad(!trx->active_commit_ordered); } /*********************************************************************//** @@ -2832,19 +2820,8 @@ trx_deregister_from_2pc( /*====================*/ trx_t* trx) /* in: transaction */ { - trx->is_registered = 0; - trx->active_commit_ordered = 0; -} - -/*********************************************************************//** -Check whether a transaction has active_commit_ordered set */ -static inline -bool -trx_is_active_commit_ordered( -/*=========================*/ - const trx_t* trx) /* in: transaction */ -{ - return(trx->active_commit_ordered == 1); + trx->is_registered= false; + trx->active_commit_ordered= false; } /*********************************************************************//** @@ -4617,8 +4594,7 @@ innobase_commit_ordered( (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))); innobase_commit_ordered_2(trx, thd); - - trx_set_active_commit_ordered(trx); + trx->active_commit_ordered = true; DBUG_VOID_RETURN; } @@ -4671,7 +4647,7 @@ innobase_commit( DBUG_SUICIDE();); /* Run the fast part of commit if we did not already. */ - if (!trx_is_active_commit_ordered(trx)) { + if (!trx->active_commit_ordered) { innobase_commit_ordered_2(trx, thd); } @@ -5185,12 +5161,12 @@ static void innobase_kill_query(handlerton*, THD* thd, enum thd_kill_levels) trx_mutex_enter(trx); /* It is possible that innobase_close_connection() is concurrently being executed on our victim. In that case, trx->mysql_thd would - be reset before invoking trx_free(). Even if the trx object is later + be reset before invoking trx_t::free(). Even if the trx object is later reused for another client connection or a background transaction, its trx->mysql_thd will differ from our thd. If trx never performed any changes, nothing is really protecting - the trx_free() call or the changes of trx_t::state when the + the trx_t::free() call or the changes of trx_t::state when the transaction is being rolled back and trx_commit_low() is being executed. diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 57ecf7717d1d8..4161d4d856301 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -73,12 +73,9 @@ Creates a transaction object for MySQL. trx_t* trx_allocate_for_mysql(void); /*========================*/ -/********************************************************************//** -Creates a transaction object for background operations by the master thread. -@return own: transaction object */ -trx_t* -trx_allocate_for_background(void); -/*=============================*/ + +/** @return allocated transaction object for internal operations */ +trx_t *trx_allocate_for_background(); /** Frees and initialize a transaction object instantinated during recovery. @param trx trx object to free and initialize during recovery */ @@ -917,7 +914,8 @@ struct trx_t { the coordinator using the XA API, and is set to false after commit or rollback. */ - unsigned active_commit_ordered:1;/* 1 if owns prepare mutex */ + /** whether this is holding the prepare mutex */ + bool active_commit_ordered; /*------------------------------*/ bool check_unique_secondary; /*!< normally TRUE, but if the user @@ -1204,6 +1202,9 @@ struct trx_t { ut_ad(old_n_ref > 0); } + /** Free the memory to trx_pools */ + inline void free(); + private: /** Assign a rollback segment for modifying temporary tables. diff --git a/storage/innobase/include/ut0pool.h b/storage/innobase/include/ut0pool.h index 957157fa8153f..749c4188edfc4 100644 --- a/storage/innobase/include/ut0pool.h +++ b/storage/innobase/include/ut0pool.h @@ -87,15 +87,6 @@ struct Pool { for (Element* elem = m_start; elem != m_last; ++elem) { ut_ad(elem->m_pool == this); -#ifdef __SANITIZE_ADDRESS__ - /* Unpoison the memory for AddressSanitizer */ - MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type); -#endif -#ifdef HAVE_valgrind - /* Declare the contents as initialized for Valgrind; - we checked this in mem_free(). */ - MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type); -#endif Factory::destroy(&elem->m_type); } @@ -130,22 +121,6 @@ struct Pool { elem = NULL; } -#if defined HAVE_valgrind || defined __SANITIZE_ADDRESS__ - if (elem) { -# ifdef __SANITIZE_ADDRESS__ - /* Unpoison the memory for AddressSanitizer */ - MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type); -# endif -# ifdef HAVE_valgrind - /* Declare the memory initialized for Valgrind. - The trx_t that are released to the pool are - actually initialized; we checked that by - MEM_CHECK_DEFINED() in mem_free() below. */ -# endif - MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type); - } -#endif - m_lock_strategy.exit(); return elem ? &elem->m_type : NULL; } @@ -158,12 +133,10 @@ struct Pool { byte* p = reinterpret_cast(ptr + 1); elem = reinterpret_cast(p - sizeof(*elem)); - MEM_CHECK_DEFINED(&elem->m_type, sizeof elem->m_type); elem->m_pool->m_lock_strategy.enter(); elem->m_pool->putl(elem); - MEM_NOACCESS(&elem->m_type, sizeof elem->m_type); elem->m_pool->m_lock_strategy.exit(); } @@ -186,9 +159,6 @@ struct Pool { void putl(Element* elem) { ut_ad(elem >= m_start && elem < m_last); - - ut_ad(Factory::debug(&elem->m_type)); - m_pqueue.push(elem); } diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index d4cd020b32154..13b4efb973b49 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -105,7 +105,7 @@ trx_init( trx->op_info = ""; - trx->active_commit_ordered = 0; + trx->active_commit_ordered = false; trx->isolation_level = TRX_ISO_REPEATABLE_READ; @@ -202,6 +202,15 @@ struct TrxFactory { @param trx the transaction for which to release resources */ static void destroy(trx_t* trx) { +#ifdef __SANITIZE_ADDRESS__ + /* Unpoison the memory for AddressSanitizer */ + MEM_UNDEFINED(trx, sizeof *trx); +#else + /* Declare the contents as initialized for Valgrind; + we checked this in trx_t::free(). */ + MEM_MAKE_DEFINED(trx, sizeof *trx); +#endif + ut_a(trx->magic_n == TRX_MAGIC_N); ut_ad(!trx->in_rw_trx_list); ut_ad(!trx->in_mysql_trx_list); @@ -229,39 +238,6 @@ struct TrxFactory { trx->lock.table_locks.~lock_list(); } - - /** Enforce any invariants here, this is called before the transaction - is added to the pool. - @return true if all OK */ - static bool debug(const trx_t* trx) - { - ut_a(trx->error_state == DB_SUCCESS); - - ut_a(trx->magic_n == TRX_MAGIC_N); - - ut_ad(!trx->read_only); - - ut_ad(trx->state == TRX_STATE_NOT_STARTED); - - ut_ad(trx->dict_operation == TRX_DICT_OP_NONE); - - ut_ad(trx->mysql_thd == 0); - - ut_ad(!trx->in_rw_trx_list); - ut_ad(!trx->in_mysql_trx_list); - - ut_a(trx->lock.wait_thr == NULL); - ut_a(trx->lock.wait_lock == NULL); - ut_a(trx->dict_operation_lock_mode == 0); - - ut_a(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0); - - ut_ad(trx->autoinc_locks == NULL); - - ut_ad(trx->lock.table_locks.empty()); - - return(true); - } }; /** The lock strategy for TrxPool */ @@ -338,13 +314,23 @@ trx_pool_close() trx_pools = 0; } -/** @return a trx_t instance from trx_pools. */ -static -trx_t* -trx_create_low() +/** @return allocated transaction object for internal operations */ +trx_t *trx_allocate_for_background() { trx_t* trx = trx_pools->get(); +#ifdef __SANITIZE_ADDRESS__ + /* Unpoison the memory for AddressSanitizer. + It may have been poisoned in trx_t::free().*/ + MEM_UNDEFINED(trx, sizeof *trx); +#else + /* Declare the memory initialized for Valgrind. + The trx_t that are released to the pool are + actually initialized; we checked that by + MEM_CHECK_DEFINED() in trx_t::free(). */ + MEM_MAKE_DEFINED(trx, sizeof *trx); +#endif + assert_trx_is_free(trx); mem_heap_t* heap; @@ -360,14 +346,9 @@ trx_create_low() alloc = ib_heap_allocator_create(heap); - /* Remember to free the vector explicitly in trx_free(). */ trx->autoinc_locks = ib_vector_create(alloc, sizeof(void**), 4); - /* Should have been either just initialized or .clear()ed by - trx_free(). */ ut_ad(trx->mod_tables.empty()); - ut_ad(trx->lock.table_locks.empty()); - ut_ad(UT_LIST_GET_LEN(trx->lock.trx_locks) == 0); ut_ad(trx->lock.n_rec_locks == 0); ut_ad(trx->lock.table_cached == 0); ut_ad(trx->lock.rec_cached == 0); @@ -379,71 +360,119 @@ trx_create_low() return(trx); } -/** -Release a trx_t instance back to the pool. -@param trx the instance to release. */ -static -void -trx_free(trx_t*& trx) +/** Free the memory to trx_pools */ +inline void trx_t::free() { - assert_trx_is_free(trx); + assert_trx_is_inactive(this); - trx->mysql_thd = 0; - trx->mysql_log_file_name = 0; + MEM_CHECK_DEFINED(this, sizeof *this); - // FIXME: We need to avoid this heap free/alloc for each commit. - if (trx->autoinc_locks != NULL) { - ut_ad(ib_vector_is_empty(trx->autoinc_locks)); - /* We allocated a dedicated heap for the vector. */ - ib_vector_free(trx->autoinc_locks); - trx->autoinc_locks = NULL; - } + ut_ad(!read_view); + ut_ad(!will_lock); + ut_ad(error_state == DB_SUCCESS); + ut_ad(magic_n == TRX_MAGIC_N); + ut_ad(!read_only); + ut_ad(!in_mysql_trx_list); + ut_ad(!lock.wait_lock); - trx->mod_tables.clear(); + mysql_thd= NULL; + mysql_log_file_name= NULL; - ut_ad(trx->read_view == NULL); + // FIXME: We need to avoid this heap free/alloc for each commit. + if (autoinc_locks) + { + ut_ad(ib_vector_is_empty(autoinc_locks)); + /* We allocated a dedicated heap for the vector. */ + ib_vector_free(autoinc_locks); + autoinc_locks= NULL; + } - /* trx locking state should have been reset before returning trx - to pool */ - ut_ad(trx->will_lock == 0); + mod_tables.clear(); - trx_pools->mem_free(trx); -#ifdef __SANITIZE_ADDRESS__ - /* Unpoison the memory for innodb_monitor_set_option; - it is operating also on the freed transaction objects. */ - MEM_UNDEFINED(&trx->mutex, sizeof trx->mutex); - MEM_UNDEFINED(&trx->undo_mutex, sizeof trx->undo_mutex); - /* For innobase_kill_connection() */ - MEM_UNDEFINED(&trx->state, sizeof trx->state); - MEM_UNDEFINED(&trx->mysql_thd, sizeof trx->mysql_thd); -#endif -#ifdef HAVE_valgrind_or_MSAN - /* Unpoison the memory for innodb_monitor_set_option; - it is operating also on the freed transaction objects. - We checked that these were initialized in - trx_pools->mem_free(trx). */ - MEM_MAKE_DEFINED(&trx->mutex, sizeof trx->mutex); - MEM_MAKE_DEFINED(&trx->undo_mutex, sizeof trx->undo_mutex); - /* For innobase_kill_connection() */ - MEM_MAKE_DEFINED(&trx->state, sizeof trx->state); - MEM_MAKE_DEFINED(&trx->mysql_thd, sizeof trx->mysql_thd); + MEM_NOACCESS(&n_ref, sizeof n_ref); + /* do not poison mutex */ + MEM_NOACCESS(&id, sizeof id); + MEM_NOACCESS(&no, sizeof no); + /* state is accessed by innobase_kill_connection() */ + MEM_NOACCESS(&is_recovered, sizeof is_recovered); +#ifdef WITH_WSREP + MEM_NOACCESS(&wsrep, sizeof wsrep); #endif - - trx = NULL; -} - -/********************************************************************//** -Creates a transaction object for background operations by the master thread. -@return own: transaction object */ -trx_t* -trx_allocate_for_background(void) -/*=============================*/ -{ - trx_t* trx; - - trx = trx_create_low(); - - return(trx); + MEM_NOACCESS(&read_view, sizeof read_view); + MEM_NOACCESS(&trx_list, sizeof trx_list); + MEM_NOACCESS(&no_list, sizeof no_list); + MEM_NOACCESS(&lock, sizeof lock); + MEM_NOACCESS(&op_info, sizeof op_info); + MEM_NOACCESS(&isolation_level, sizeof isolation_level); + MEM_NOACCESS(&check_foreigns, sizeof check_foreigns); + MEM_NOACCESS(&is_registered, sizeof is_registered); + MEM_NOACCESS(&active_commit_ordered, sizeof active_commit_ordered); + MEM_NOACCESS(&check_unique_secondary, sizeof check_unique_secondary); + MEM_NOACCESS(&flush_log_later, sizeof flush_log_later); + MEM_NOACCESS(&must_flush_log_later, sizeof must_flush_log_later); + MEM_NOACCESS(&duplicates, sizeof duplicates); + MEM_NOACCESS(&dict_operation, sizeof dict_operation); + MEM_NOACCESS(&declared_to_be_inside_innodb, sizeof declared_to_be_inside_innodb); + MEM_NOACCESS(&n_tickets_to_enter_innodb, sizeof n_tickets_to_enter_innodb); + MEM_NOACCESS(&dict_operation_lock_mode, sizeof dict_operation_lock_mode); + MEM_NOACCESS(&start_time, sizeof start_time); + MEM_NOACCESS(&start_time_micro, sizeof start_time_micro); + MEM_NOACCESS(&commit_lsn, sizeof commit_lsn); + MEM_NOACCESS(&table_id, sizeof table_id); + /* mysql_thd is accessed by innobase_kill_connection() */ + MEM_NOACCESS(&mysql_log_file_name, sizeof mysql_log_file_name); + MEM_NOACCESS(&mysql_log_offset, sizeof mysql_log_offset); + MEM_NOACCESS(&n_mysql_tables_in_use, sizeof n_mysql_tables_in_use); + MEM_NOACCESS(&mysql_n_tables_locked, sizeof mysql_n_tables_locked); +#ifdef UNIV_DEBUG + MEM_NOACCESS(&in_rw_trx_list, sizeof in_rw_trx_list); +#endif /* UNIV_DEBUG */ + MEM_NOACCESS(&mysql_trx_list, sizeof mysql_trx_list); +#ifdef UNIV_DEBUG + MEM_NOACCESS(&in_mysql_trx_list, sizeof in_mysql_trx_list); +#endif /* UNIV_DEBUG */ + MEM_NOACCESS(&error_state, sizeof error_state); + MEM_NOACCESS(&error_info, sizeof error_info); + MEM_NOACCESS(&error_key_num, sizeof error_key_num); + MEM_NOACCESS(&graph, sizeof graph); + MEM_NOACCESS(&trx_savepoints, sizeof trx_savepoints); + /* do not poison undo_mutex */ + MEM_NOACCESS(&undo_no, sizeof undo_no); + MEM_NOACCESS(&undo_rseg_space, sizeof undo_rseg_space); + MEM_NOACCESS(&last_sql_stat_start, sizeof last_sql_stat_start); + MEM_NOACCESS(&rsegs, sizeof rsegs); + MEM_NOACCESS(&roll_limit, sizeof roll_limit); +#ifdef UNIV_DEBUG + MEM_NOACCESS(&in_rollback, sizeof in_rollback); +#endif /* UNIV_DEBUG */ + MEM_NOACCESS(&pages_undone, sizeof pages_undone); + MEM_NOACCESS(&n_autoinc_rows, sizeof n_autoinc_rows); + MEM_NOACCESS(&autoinc_locks, sizeof autoinc_locks); + MEM_NOACCESS(&read_only, sizeof read_only); + MEM_NOACCESS(&auto_commit, sizeof auto_commit); + MEM_NOACCESS(&will_lock, sizeof will_lock); + MEM_NOACCESS(&fts_trx, sizeof fts_trx); + MEM_NOACCESS(&fts_next_doc_id, sizeof fts_next_doc_id); + MEM_NOACCESS(&flush_tables, sizeof flush_tables); + MEM_NOACCESS(&ddl, sizeof ddl); + MEM_NOACCESS(&internal, sizeof internal); +#ifdef UNIV_DEBUG + MEM_NOACCESS(&start_line, sizeof start_line); + MEM_NOACCESS(&start_file, sizeof start_file); +#endif /* UNIV_DEBUG */ + MEM_NOACCESS(&xid, sizeof xid); + MEM_NOACCESS(&mod_tables, sizeof mod_tables); + MEM_NOACCESS(&detailed_error, sizeof detailed_error); + MEM_NOACCESS(&flush_observer, sizeof flush_observer); + MEM_NOACCESS(&n_rec_lock_waits, sizeof n_rec_lock_waits); + MEM_NOACCESS(&n_table_lock_waits, sizeof n_table_lock_waits); + MEM_NOACCESS(&total_rec_lock_wait_time, sizeof total_rec_lock_wait_time); + MEM_NOACCESS(&total_table_lock_wait_time, sizeof total_table_lock_wait_time); +#ifdef WITH_WSREP + MEM_NOACCESS(&wsrep_event, sizeof wsrep_event); +#endif /* WITH_WSREP */ + MEM_NOACCESS(&magic_n, sizeof magic_n); + trx_pools->mem_free(this); } /********************************************************************//** @@ -517,8 +546,7 @@ trx_free_resurrected(trx_t* trx) trx_validate_state_before_free(trx); trx_init(trx); - - trx_free(trx); + trx->free(); } /** Free a transaction that was allocated by background or user threads. @@ -527,8 +555,7 @@ void trx_free_for_background(trx_t* trx) { trx_validate_state_before_free(trx); - - trx_free(trx); + trx->free(); } /** Transition to committed state, to release implicit locks. */ @@ -617,8 +644,7 @@ trx_free_prepared( trx->state = TRX_STATE_NOT_STARTED; ut_ad(!UT_LIST_GET_LEN(trx->lock.trx_locks)); trx->id = 0; - - trx_free(trx); + trx->free(); } /** Disconnect a transaction from MySQL and optionally mark it as if