summaryrefslogtreecommitdiff
path: root/mysql-test/suite/sys_vars/t/innodb_fatal_semaphore_wait_threshold.test
blob: 9493536bc5934eb8d88d3bbd659880d837e7534c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# Only test in debug mode since DBUG_EXECUTE_IF is used
--source include/have_debug.inc

# Can't test this with embedded server
--source include/not_embedded.inc

# Don't test this with valgrind
--source include/not_valgrind.inc

# Only test for innodb
--source include/have_innodb.inc

--echo # Establish connection con1 (user=root)
connect (con1,localhost,root,,);
--echo # Establish connection con2 (user=root)
connect (con2,localhost,root,,);

--disable_warnings
drop table if exists t1;
--enable_warnings

--echo # Switch to connection con1
connection con1;
eval create table t1 (id integer, x integer) engine = InnoDB;
insert into t1 values(0, 0);

# Enable the debug injection.
set DEBUG_DBUG='+d,fatal-semaphore-timeout';
set autocommit=0;

# The following query will hang for an hour since the debug injection
# code will sleep an hour after holding the lock table mutex
--echo # Sending query on con1,
--echo # the session will hold lock table mutex and sleep
--send
SELECT * from t1 where id = 0 FOR UPDATE;

# To make sure con1 holding the lock table mutex and sleeping
--sleep 2

--echo # Switch to connection con2
connection con2;
set autocommit=0;

# The following query will be blocked on the lock table mutex held by
# con1 so it will be put into sync array.
--echo # Sending query on con2,
--echo # the session will be blocked on the lock table mutex and
--echo # thus be put into sync arry
--send
SELECT * from t1 where id = 0 FOR UPDATE;

# Waitting for mysqld to abort due to fatal semaphore timeout.
# Please note that, in the master.opt file, the fatal timeout
# was set to 1 second, but in mysqld debug mode, this timeout
# value will be timed 10 because UNIV_DEBUG_VALGRIND is set
# (see sync_array_print_long_waits_low() in storage/innobase/sync/sync0arr.cc)
# so the actual timeout will be 1 * 10 = 10 seconds. Besides,
# mysqld will abort after detecting this fatal timeout 10 times in
# a loop with interval of 1 second (see srv_error_monitor_thread
# thread in torage/innobase/srv/srv0srv.cc), so mysqld will abort
# in 1 * 10 + 1 * 10 = 20 seconds after con2 being blocked on
# the lock table mutex.
#
# P.S. the default fatal sempahore timeout is 600 seconds,
# so mysqld will abort after 600 * 10 + 1 * 10 = 6010 seconds
# in debug mode and 600 + 1 * 10 = 610 seconds in release mode.

--echo # Switched to the default connection
connection default;

--disable_result_log
--disable_query_log

# Since this test generates lot of errors in log, suppress checking errors
call mtr.add_suppression(".*");

# The crash is expected
exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;

--echo # Waitting for mysqld to crash

# It will take 20 seconds to detect the long semaphore and mysqld to abort.
# This test will be treated as pass as long as mysqld crash/restart is dectected
# in 80 seconds.
let $counter= 80;
let $mysql_errno= 0;
while (!$mysql_errno)
{
  --error 0,1040,1053,2002,2003,2006,2013
  show status;

  dec $counter;
  if (!$counter)
  {
    # This will fail this test.
    --die Server failed to dissapear
  }
  --sleep 1
}

--echo # Mysqld crash was detected
--echo # Waitting for reconnect after mysqld restarts

enable_reconnect;
connection default;

--exec echo "restart:--log-error=$error_log" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect

# Call script that will poll the server waiting for it to be back online again
source include/wait_until_connected_again.inc;

--echo # Reconnected after mysqld was successfully restarted

--echo # Cleaning up before exit
--disable_warnings
drop table if exists t1;
--enable_warnings

--echo # Clean exit