File: binlog_cache_write_failure.test

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (176 lines) | stat: -rw-r--r-- 6,041 bytes parent folder | download
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# === Purpose ===
#
# Verify that disk full/out of space errors generated during the flush
# stage of binlog commit are properly handled by the server.
#
# === Implementation ===
#
# Simulate tempoary file write failures in below  scenarios and verify the
# failures can be handled correctly.
# - Simulate binlog cache write failure in an INSERT which write data more than
#   cache size.
# - Simulate my_b_flush_io_cache failure in an ROLLBACK TO.
# - Simulate my_b_flush_io_cache failure when reseting binlog cache in a
#   ROLLBACK.
# - Simulate my_b_flush_io_cache failure when reseting binlog cache in a
#   COMMIT
# - Simulate write failure
# - Simulate my_b_flush_io_cache failure when reseting binlog cache in
#   disconnect
# - Simulate a binlog cache write failure when reinitializing it for
#   copying to binlog. It should cause server abort if binlog_error_action
#   is ABORT_SERVER
#
# === References ===
#
# Bug #27399620 BINLOG AND ENGINE BECOME INCONSISTENT WHEN BINLOG CACHE FILE
# GETS OUT OF SPACE

--source include/have_binlog_format_row.inc
--source include/have_log_bin.inc
--source include/have_debug.inc
# Don't test this under valgrind, memory leaks will occur
--source include/not_valgrind.inc
# Avoid CrashReporter popup on Mac
--source include/not_crashrep.inc

call mtr.add_suppression("An error occurred during flush stage of the commit");
call mtr.add_suppression("Attempting backtrace. You can use the following information to find out*");
call mtr.add_suppression(".*Error writing file.*");
RESET MASTER;
CREATE TABLE t1(c1 varchar(8192));
CREATE TABLE t2(c1 varchar(8192));
CREATE TABLE t3(c1 varchar(8192));

SET GLOBAL binlog_cache_size = 4096;
connect(con1,localhost,root,,);

--echo
--echo # Case 1 Simulate my_b_flush_io_cache failure when truncating binlog
--echo #        cache. ROLLBACK TO triggers binlog cache truncation process.
--source include/save_binlog_position.inc

BEGIN;
INSERT INTO t1 VALUES (repeat('a', 2048));

# Below statemens in sp1 should not be binlogged
SAVEPOINT sp1;
INSERT INTO t2 VALUES (repeat('a', 4096));
INSERT INTO t3 VALUES (repeat('b', 4096));

# ROLLBACK to savepoint should not call my_b_flush_io_cache which
# caused extra events were logged before the fix.
SET SESSION debug = "+d,simulate_error_during_flush_cache_to_file";
ROLLBACK TO sp1;
SET SESSION debug = "-d,simulate_error_during_flush_cache_to_file";

INSERT INTO t1 VALUES (repeat('c', 8192));
COMMIT;

# The transaction should be binlogged correctly
--let $binlog_start= $binlog_position
--source include/show_binlog_events.inc

--echo
--echo # Case 2 Simulate my_b_flush_io_cache failure when reseting binlog cache
--echo #        in ROLLBACK statement
BEGIN;
INSERT INTO t1 VALUES (repeat('a', 8192));

# When reseting binlog cache, it should not call my_b_flush_io_cache to flush
# data in binlog cache to temporary file. It caused assertion failure:
# binlog_cache_data::reset(): Assertion `is_binlog_empty()' before the fix.
SET SESSION debug = "+d,simulate_error_during_flush_cache_to_file";
ROLLBACK;
SET SESSION debug = "-d,simulate_error_during_flush_cache_to_file";

--echo
--echo # Case 3 CLIENT DISCONNECT. it is same to ROLLBACK
BEGIN;
INSERT INTO t1 VALUES (repeat('a', 8192));

SET SESSION debug = "+d,simulate_error_during_flush_cache_to_file";
--disconnect con1

--echo
--echo # Case 4 Simulate write failure when reinitializing binlog cache for
--echo #        copying to binlog. The error should be ignored and cache
--echo #        is cleared correctly if binlog_error_action is IGNORE_ERROR
--echo #
--connect(con1,localhost,root,,)
TRUNCATE t1;
--source include/save_binlog_position.inc

SET GLOBAL binlog_error_action = IGNORE_ERROR;
BEGIN;
INSERT INTO t1 VALUES (repeat('a', 8192));

SET SESSION debug = "+d,fault_injection_reinit_io_cache_while_flushing_to_file";
--replace_regex /.*Error writing file.*/Error writing file <tmp_file_name> (Errcode: ##)/
COMMIT;
SET SESSION debug = "-d,fault_injection_reinit_io_cache_while_flushing_to_file";

# Check that transaction is committed
--let $assert_cond = COUNT(*) = 1 FROM t1;
--let $assert_text = Count of elements in t1 should be 1.

# Check that error is present in error log
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_count = 1
--let $assert_select = An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'IGNORE_ERROR'.
--let $assert_text = An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'IGNORE_ERROR'.
--source include/assert_grep.inc

# Restart so that binary log is enabled again and we can do the below test
--disconnect con1
--connection default
--source include/restart_mysqld.inc

# Nothing should be logged
--let $binlog_start= $binlog_position
--source include/show_binlog_events.inc

--echo
--echo # Case 5 Simulate write failure when reinitializing binlog cache for
--echo #        copying to binlog with ABORT_SERVER
--echo #
SET GLOBAL binlog_cache_size = 4096;

--connect(con1,localhost,root,,)

select @@global.binlog_cache_size;
TRUNCATE t2;
--source include/save_binlog_position.inc

SET GLOBAL binlog_error_action = ABORT_SERVER;
BEGIN;
INSERT INTO t2 VALUES (repeat('b', 8192));

--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
SET SESSION debug = "+d,fault_injection_reinit_io_cache_while_flushing_to_file";
--error ER_BINLOG_LOGGING_IMPOSSIBLE
COMMIT;

--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--enable_reconnect
--source include/wait_until_connected_again.inc

# Restart so that binary log is enabled again and we can do the below test
--source include/restart_mysqld.inc
select * from t2;
# Check that transaction is not committed
--let $assert_cond = COUNT(*) = 0 FROM t2;
--let $assert_text = Count of elements in t2 should be 0.
--source include/assert.inc

# Nothing should be logged
--let $binlog_start= $binlog_position
--source include/show_binlog_events.inc

# Cleanup
--disconnect con1
--connection default
--enable_reconnect
DROP TABLE t1, t2, t3;
RESET MASTER;