Skip to content

Commit cf10f4a

Browse files
author
Libing Song
committed
WL#10956 Binlog Storage Access API - Step1 Output Stream
Output stream means a place(object) where bytes data can be written into. - Basic_ostream It is the basic output stream interface, which only defines write() operation for writing bytes into somewhere. Basic_ostream interface is used in below functions of Log_event class and its children classes to replace IO_CACHE. - Log_event::write_header(Basic_ostream ostream, ...) - Log_event::write_footer(Basic_ostream ostream) - Log_event::write_data_header(Basic_ostream ostream) - Log_event::write_data_body(Basic_ostream ostream) - Log_event::write(Basic_ostream *ostream) and a few other write functions as well. With this change, binary events could be written anywhere we want. Below classes derives from Basic_ostream and implement the interface. - class Binlog_cache - class Binlog_ofile - class StringBuffer_ostream - class Transaction_message So binary events could be written into binlog cache or binary log directly. They also could be written into a memory buffer(StringBuffer_ostream) or a group replication Transaction_message. Because of StringBuffer_ostream and Transaction_message, Some IO_CACHEs and a IO_CACHE list(IO_CACHE_unused_list) is able removed from group replication code. - Binlog_ofile It defines a logical binlog file which wraps and hides the real storage layer operations. It provides the operations for controlling binlog files, like open, close, write, flush etc. When opening Binlog_file, it initializes the real storage. When writing an event to Binlog_file, it writes the event into the real storage. MYSQL_BIN_LOG code operates on a plain binlogs. It doesn't need to know/care the detail of low level storage operates(e.g. if it is encrypted or not). It derives from Basic_ostream, so events can be written into it directly. - Binlog_cache It defines a binlog cache container for store binlog events. It provides a few elegant interfaces for writing or reading binlog events into or from the container. It hides the detail of level storage details which binlog code doesn't need to know. It is derived from Basic_ostream, So we can pass it as argument to Xxx_log_evnet::write() for writing events into binlog cache.
1 parent 20f2e84 commit cf10f4a

32 files changed

+1604
-1556
lines changed

include/mysql/group_replication_priv.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -29,6 +29,7 @@
2929

3030
#include "my_sys.h"
3131
#include "my_thread.h"
32+
#include "sql/binlog_ostream.h"
3233
#include "sql/debug_sync.h"
3334
#include "sql/log_event.h"
3435
#include "sql/replication.h"

libbinlogevents/include/binlog_event.h

+1-6
Original file line numberDiff line numberDiff line change
@@ -613,12 +613,7 @@ class Log_event_header {
613613
/*
614614
The offset in the log where this event originally appeared (it is
615615
preserved in relay logs, making SHOW SLAVE STATUS able to print
616-
coordinates of the event in the master's binlog). Note: when a
617-
transaction is written by the master to its binlog (wrapped in
618-
BEGIN/COMMIT) the log_pos of all the queries it contains is the
619-
one of the BEGIN (this way, when one does SHOW SLAVE STATUS it
620-
sees the offset of the BEGIN, which is logical as rollback may
621-
occur), except the COMMIT query which has its real offset.
616+
coordinates of the event in the master's binlog).
622617
*/
623618
unsigned long long log_pos;
624619

Original file line numberDiff line numberDiff line change
@@ -1,65 +1,88 @@
11
call mtr.add_suppression("An error occurred during flush stage of the commit");
22
call mtr.add_suppression("Attempting backtrace. You can use the following information to find out*");
3+
call mtr.add_suppression(".*Error writing file.*");
34
RESET MASTER;
4-
CREATE TABLE t1(i INT);
5+
CREATE TABLE t1(c1 varchar(8192));
6+
CREATE TABLE t2(c1 varchar(8192));
7+
CREATE TABLE t3(c1 varchar(8192));
8+
SET GLOBAL binlog_cache_size = 4096;
59

6-
# Case 1 (binlog_error_action = ABORT_SERVER)
7-
8-
SET GLOBAL binlog_error_action = ABORT_SERVER;
9-
10-
# Case 1.1 CLIENT DISCONNECTION
10+
# Case 1 Simulate my_b_flush_io_cache failure when truncating binlog
11+
# cache. ROLLBACK TO triggers binlog cache truncation process.
12+
include/save_binlog_position.inc
1113
BEGIN;
12-
INSERT INTO t1 VALUES (1);
13-
SET SESSION debug= "+d,simulate_tmpdir_partition_full";
14-
INSERT INTO t1 VALUES (2);
15-
INSERT INTO t1 VALUES (3);
16-
ERROR HY000: Error writing file <tmp_file_name> (Errcode: ##)
17-
SET SESSION debug= "-d,simulate_tmpdir_partition_full";
14+
INSERT INTO t1 VALUES (repeat('a', 2048));
15+
SAVEPOINT sp1;
16+
INSERT INTO t2 VALUES (repeat('a', 4096));
17+
INSERT INTO t3 VALUES (repeat('b', 4096));
18+
SET SESSION debug = "+d,simulate_error_during_flush_cache_to_file";
19+
ROLLBACK TO sp1;
20+
SET SESSION debug = "-d,simulate_error_during_flush_cache_to_file";
21+
INSERT INTO t1 VALUES (repeat('c', 8192));
22+
COMMIT;
23+
include/show_binlog_events.inc
24+
Log_name Pos Event_type Server_id End_log_pos Info
25+
binlog.000001 # Query # # BEGIN
26+
binlog.000001 # Table_map # # table_id: # (test.t1)
27+
binlog.000001 # Write_rows # # table_id: # flags: STMT_END_F
28+
binlog.000001 # Query # # SAVEPOINT `sp1`
29+
binlog.000001 # Table_map # # table_id: # (test.t1)
30+
binlog.000001 # Write_rows # # table_id: # flags: STMT_END_F
31+
binlog.000001 # Xid # # COMMIT /* XID */
1832

19-
# Case 1.2 ROLLBACK
33+
# Case 2 Simulate my_b_flush_io_cache failure when reseting binlog cache
34+
# in ROLLBACK statement
2035
BEGIN;
21-
INSERT INTO t1 VALUES (1);
22-
SET SESSION debug= "+d,simulate_tmpdir_partition_full";
23-
INSERT INTO t1 VALUES (2);
24-
INSERT INTO t1 VALUES (3);
25-
ERROR HY000: Error writing file <tmp_file_name> (Errcode: ##)
36+
INSERT INTO t1 VALUES (repeat('a', 8192));
37+
SET SESSION debug = "+d,simulate_error_during_flush_cache_to_file";
2638
ROLLBACK;
27-
SET SESSION debug= "-d,simulate_tmpdir_partition_full";
39+
SET SESSION debug = "-d,simulate_error_during_flush_cache_to_file";
2840

29-
# Case 1.3 COMMIT
41+
# Case 3 CLIENT DISCONNECT. it is same to ROLLBACK
3042
BEGIN;
31-
INSERT INTO t1 VALUES (1);
32-
SET SESSION debug= "+d,simulate_tmpdir_partition_full";
33-
INSERT INTO t1 VALUES (2);
34-
INSERT INTO t1 VALUES (3);
35-
ERROR HY000: Error writing file <tmp_file_name> (Errcode: ##)
36-
COMMIT;
37-
ERROR HY000: Binary logging not possible. Message: An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'ABORT_SERVER'. Hence aborting the server.
38-
include/assert_grep.inc [An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'ABORT_SERVER'.]
39-
include/assert.inc [Count of elements in t1 should be 0.]
40-
include/assert.inc [Query is not binlogged as expected.]
41-
TRUNCATE TABLE t1;
42-
43-
# Case 2 (binlog_error_action = IGNORE_ERROR)
43+
INSERT INTO t1 VALUES (repeat('a', 8192));
44+
SET SESSION debug = "+d,simulate_error_during_flush_cache_to_file";
4445

45-
RESET MASTER;
46-
SET GLOBAL binlog_error_action= IGNORE_ERROR;
46+
# Case 4 Simulate write failure when reinitializing binlog cache for
47+
# copying to binlog. The error should be ignored and cache
48+
# is cleared correctly if binlog_error_action is IGNORE_ERROR
49+
#
50+
TRUNCATE t1;
51+
include/save_binlog_position.inc
52+
SET GLOBAL binlog_error_action = IGNORE_ERROR;
4753
BEGIN;
48-
INSERT INTO t1 VALUES (1);
49-
SET SESSION debug= "+d,simulate_tmpdir_partition_full";
50-
INSERT INTO t1 VALUES (2);
51-
INSERT INTO t1 VALUES (3);
52-
ERROR HY000: Error writing file <tmp_file_name> (Errcode: ##)
54+
INSERT INTO t1 VALUES (repeat('a', 8192));
55+
SET SESSION debug = "+d,simulate_tmpdir_partition_full";
5356
COMMIT;
5457
Warnings:
55-
Error 3 Error writing file MYSQLTEST_VARDIR/tmp/temp_file (Errcode: ##)
56-
Error 1026 Error writing file MYSQLTEST_VARDIR/tmp/temp_file (Errcode: ##)
57-
SET SESSION debug= "-d,simulate_tmpdir_partition_full";
58-
include/assert.inc [Count of elements in t1 should be 2.]
59-
SHOW BINARY LOGS;
60-
ERROR HY000: You are not using binary logging
58+
Error 3 Error writing file <tmp_file_name> (Errcode: ##)
59+
Error 1026 Error writing file <tmp_file_name> (Errcode: ##)
60+
SET SESSION debug = "-d,simulate_tmpdir_partition_full";
6161
include/assert_grep.inc [An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'IGNORE_ERROR'.]
6262
# restart
63-
include/assert.inc [Count of elements in t1 should be 2.]
64-
DROP TABLE t1;
63+
include/show_binlog_events.inc
64+
Log_name Pos Event_type Server_id End_log_pos Info
65+
binlog.000001 # Stop # #
66+
67+
# Case 5 Simulate write failure when reinitializing binlog cache for
68+
# copying to binlog with ABORT_SERVER
69+
#
70+
SET GLOBAL binlog_cache_size = 4096;
71+
select @@global.binlog_cache_size;
72+
@@global.binlog_cache_size
73+
4096
74+
TRUNCATE t2;
75+
include/save_binlog_position.inc
76+
SET GLOBAL binlog_error_action = ABORT_SERVER;
77+
BEGIN;
78+
INSERT INTO t2 VALUES (repeat('b', 8192));
79+
SET SESSION debug = "+d,simulate_tmpdir_partition_full";
80+
COMMIT;
81+
ERROR HY000: Binary logging not possible. Message: An error occurred during flush stage of the commit. 'binlog_error_action' is set to 'ABORT_SERVER'. Hence aborting the server.
82+
# restart
83+
select * from t2;
84+
c1
85+
include/assert.inc [Count of elements in t2 should be 0.]
86+
include/show_binlog_events.inc
87+
DROP TABLE t1, t2, t3;
6588
RESET MASTER;

mysql-test/suite/binlog/r/binlog_rotate_bgc_sync.result

+8-24
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,19 @@
11
[connection conn1]
2-
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
3-
SET DEBUG_SYNC= 'before_sync_binlog_file SIGNAL holding_before_bgc_sync_binlog_file WAIT_FOR continue_bgc_sync_binlog_file';
2+
CREATE TABLE t1 (c1 INT) ENGINE = MyISAM;
3+
SET DEBUG_SYNC= 'bgc_between_flush_and_sync SIGNAL
4+
holding_between_flush_and_sync WAIT_FOR continue_between_flush_and_sync';
45
INSERT INTO t1 VALUES (1);
56
[connection conn2]
6-
SET DEBUG_SYNC= 'NOW WAIT_FOR holding_before_bgc_sync_binlog_file';
7-
SET DEBUG_SYNC= 'before_rotate_binlog_file SIGNAL holding_before_rotate_binlog_file WAIT_FOR continue_rotate_binlog_file';
7+
SET DEBUG_SYNC= 'now WAIT_FOR holding_between_flush_and_sync';
8+
SET DEBUG_SYNC= 'binlog_rotate_between_close_and_open SIGNAL
9+
holding_between_close_and_open WAIT_FOR continue_rotate_binlog_file';
810
FLUSH LOGS;
911
[connection default]
10-
SET DEBUG_SYNC= 'now WAIT_FOR holding_before_rotate_binlog_file';
11-
SET DEBUG_SYNC= 'now SIGNAL continue_bgc_sync_binlog_file';
12-
SET DEBUG_SYNC= 'before_rotate_binlog_file CLEAR';
13-
SET DEBUG_SYNC = 'now SIGNAL continue_rotate_binlog_file';
14-
[connection conn1]
15-
[connection conn2]
16-
[connection default]
17-
DROP TABLE t1;
18-
SET DEBUG_SYNC= 'RESET';
12+
SET DEBUG_SYNC= 'now WAIT_FOR holding_between_close_and_open';
13+
SET DEBUG_SYNC= 'now SIGNAL continue_between_flush_and_sync';
1914
[connection conn1]
20-
CREATE TABLE t1 (c1 INT) ENGINE=InnoDB;
21-
SET DEBUG_SYNC= 'before_sync_binlog_file SIGNAL holding_before_bgc_sync_binlog_file WAIT_FOR continue_bgc_sync_binlog_file';
22-
INSERT INTO t1 VALUES (1);
23-
[connection conn2]
24-
SET DEBUG_SYNC= 'NOW WAIT_FOR holding_before_bgc_sync_binlog_file';
25-
SET DEBUG_SYNC= 'before_rotate_binlog_file SIGNAL holding_before_rotate_binlog_file WAIT_FOR continue_rotate_binlog_file';
26-
FLUSH LOGS;
2715
[connection default]
28-
SET DEBUG_SYNC= 'now WAIT_FOR holding_before_rotate_binlog_file';
29-
SET DEBUG_SYNC= 'now SIGNAL continue_bgc_sync_binlog_file';
30-
SET DEBUG_SYNC= 'before_rotate_binlog_file CLEAR';
3116
SET DEBUG_SYNC = 'now SIGNAL continue_rotate_binlog_file';
32-
[connection conn1]
3317
[connection conn2]
3418
[connection default]
3519
DROP TABLE t1;

0 commit comments

Comments
 (0)