mirror of
https://github.com/MariaDB/server.git
synced 2025-11-30 05:23:50 +03:00
The sporadic test hangs happen because of mutex dealock between innodb background threads and two test connection executions. The test sets variable innodb_disallow_writes, which blocks all writes to filesyste. The test logic is to execute an INSERT, which should hang because of filesytstem writes are blocked, and through another session verify by SELECT that this hanging happens. The SELECT session will then release innodb_disallow_writes blocking. However, filesystem write blocking affects also innodb background threads and they may hang while keeping some other resources locked. As an example, in one test hang situation, buffer pool access was blocked. And, if buffer pool is blocked, the test connections will be blocked as well, and the SELECT session will not be able to continue to release the innodb_disallow_writes. The fix in this commit is refactoring of the test logic. The test will now set first innodb_disallow_writes blocking, and then record a hash of data directory's filesystem contents. This works as checksum of the state of data on the datadirectory. Then some SQL load is tried on both nodes, these sessions will be blocking due to frozen file system state. The test will have a short sleep to allow innodb background threads to loop and possibly encounter innodb_disallow_writes blocking as well. After the sleep, the test will record file system checksun for the second time, and then release the innodb_disallow-writes blocking. Finally, the two checksums are compared, they should be identical to verify that nothing was written on datadirectory during the test execution. The checksum is implemented by md5sum hash over all files found in datadirectory by find command. all these file hashes are hashed together by one more md5sum. The test therefore depends on md5sum and find. find may work differently with some OS distributions, e.g. freebsd may be problematic.
73 lines
2.1 KiB
Plaintext
73 lines
2.1 KiB
Plaintext
#
|
|
# This test checks that innodb_disallow_writes works as expected
|
|
#
|
|
# Note that we need to enable binlog for this test: If the commit
|
|
# to InnoDB is done in one phase, the transaction is committed in
|
|
# memory before it is persisted to disk. This means that the
|
|
# innodb_disallow_writes=ON may not prevent transaction to
|
|
# become visible to other readers. On the other hand, if the
|
|
# commit is two phase (as it is with binlog), the transaction
|
|
# will be blocked in prepare phase.
|
|
#
|
|
|
|
--source include/galera_cluster.inc
|
|
--source include/have_innodb.inc
|
|
--source include/have_log_bin.inc
|
|
|
|
--let $datadir= `SELECT @@datadir`
|
|
|
|
|
|
# Open a separate connection to be used to run SHOW PROCESSLIST
|
|
--let $galera_connection_name = node_1a
|
|
--let $galera_server_number = 1
|
|
--source include/galera_connect.inc
|
|
--connection node_1a
|
|
SET SESSION wsrep_sync_wait = 0;
|
|
|
|
--connection node_1
|
|
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
|
|
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
|
|
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
|
|
|
SET GLOBAL innodb_disallow_writes=ON;
|
|
--exec find $datadir -type f-exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_before
|
|
|
|
#
|
|
# This insert has no effect before innodb_disallow_writes is OFF
|
|
#
|
|
--send INSERT INTO t1 (f2) SELECT 'abcde ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
|
|
|
--connection node_2
|
|
INSERT INTO t1 (f2) SELECT 'fghij ' FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
|
SELECT COUNT(*) AS EXPECT_10000 FROM t1;
|
|
|
|
--connection node_1a
|
|
--sleep 5
|
|
|
|
--exec find $datadir -type f-exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_after
|
|
|
|
SET GLOBAL innodb_disallow_writes=OFF;
|
|
|
|
--connection node_1
|
|
--reap
|
|
--let $wait_condition = SELECT COUNT(*) = 20000 FROM t1;
|
|
--source include/wait_condition.inc
|
|
|
|
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
|
|
|
|
--connection node_2
|
|
--let $wait_condition = SELECT COUNT(*) = 20000 FROM t1;
|
|
--source include/wait_condition.inc
|
|
SELECT COUNT(*) AS EXPECT_20000 FROM t1;
|
|
|
|
--connection node_1
|
|
--diff_files $MYSQLTEST_VARDIR/tmp/innodb_before $MYSQLTEST_VARDIR/tmp/innodb_after
|
|
|
|
--connection node_2
|
|
|
|
DROP TABLE t1;
|
|
DROP TABLE ten;
|
|
|
|
--disconnect node_1a
|
|
|