Skip to content

Commit e8e5ddb

Browse files
author
Venkatesh Duggirala
committed
Bug#24609402 MYSQLBINLOG --RAW DOES NOT GET ALL LATEST EVENTS
Problem: When mysqlbinlog is used with --raw option, output file is not getting flushed till the process is completed. With --stop-never option (mysqlbinlog process never completes), output file will never contain any events. Analysis & Fix: --read-from-remote-server is a mysqlbinlog tool option that allows the users to read the binlog from a MySQL server rather than reading a local file. The read binary log event will be processed and written to output files in text format. In this case, the output file is getting flushed after every event in copy_event_cache_to_file_and_reinit() function. By default, mysqlbinlog reads binary log files and writes events in text format. But the --raw option tells mysqlbinlog to write the events into output file directly in their original binary format. In this case, the output file is not getting flushed until mysqlbinlog downloads all the content. This will be more problematic if --stop-never option is used (which is used for "live" binlog backup) as the mysqlbinlog process will never stop, the output file will never get flushed. Fix: Flush the output file after every event is written to it (just like how we flush when --raw is not specified).
1 parent 8706743 commit e8e5ddb

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

client/mysqlbinlog.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -2490,6 +2490,8 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
24902490
ev->temp_buf=0;
24912491
delete ev;
24922492
}
2493+
/* Flush result_file after every event */
2494+
fflush(result_file);
24932495
}
24942496
else
24952497
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
RESET MASTER;
2+
include/stop_dump_threads.inc
3+
# Step-1: Execute some dummy statements.
4+
CREATE TABLE t1(i int);
5+
INSERT INTO t1 values (1);
6+
# Step-2: Execute MYSQL_BINLOG with --stop-never and --raw option.
7+
# Step-3: Wait till dump thread transfer is completed.
8+
# Step-4: copy binary log file that is downloaded till now before
9+
# stopping dump thread that is serving mysqlbinlog
10+
# --stop-never process.
11+
# Step-5: kill the dump thread serving the mysqlbinlog --stop-never process
12+
include/stop_dump_threads.inc
13+
# Step-6: Cleanup the data, so that it is ready for reapply.
14+
DROP TABLE t1;
15+
RESET MASTER;
16+
# Step-7: Apply the data that we got from --stop-never process.
17+
# Step-8: Check that the data is there.
18+
include/assert.inc [Check the table t1 exists and contains one tuple with value 1.]
19+
# Step-9: Cleanup
20+
DROP TABLE t1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
###############################################################################
2+
# Bug#24609402 MYSQLBINLOG --RAW DOES NOT GET ALL LATEST EVENTS
3+
#
4+
# Problem: When mysqlbinlog is used with --raw option, output file
5+
# is not getting flushed till the process is completed.
6+
# With --stop-never option (mysqlbinlog process never completes),
7+
# output file will never contain any event.
8+
#
9+
# Steps to reproduce:
10+
# 1) Execute some dummy statements(a create and an insert).
11+
# 2) Execute MYSQL_BINLOG with --stop-never and --raw option
12+
# and backup the binlog content.
13+
# 3) Wait till server dump thread transfers all the data.
14+
# 4) Copy binary log file that is downloaded till now before
15+
# stopping dump thread that is serving mysqlbinlog
16+
# --stop-never process.
17+
# 5) kill the dump thread (serving the mysqlbinlog process).
18+
# 6) Clean up the data on the server (a drop and a reset).
19+
# 7) Apply binlog content (binlog from Step-2).
20+
# 8) Check that table and the data in it exists (data from step-1).
21+
# 9) Cleanup the server.
22+
###############################################################################
23+
24+
# Test is not specific to any binlog format. Hence Running only for 'row'.
25+
--source include/have_binlog_format_row.inc
26+
27+
# binlog file name is needed in the test. To use master-bin.000001,
28+
# RESET MASTER is needed.
29+
RESET MASTER;
30+
# kill the dump threads if there any dump threads (may be from previous test)
31+
--source include/stop_dump_threads.inc
32+
33+
--echo # Step-1: Execute some dummy statements.
34+
CREATE TABLE t1(i int);
35+
INSERT INTO t1 values (1);
36+
37+
--echo # Step-2: Execute MYSQL_BINLOG with --stop-never and --raw option.
38+
--write_file $MYSQL_TMP_DIR/mysqlbinlog_raw.sh
39+
#!/bin/bash
40+
(`$MYSQL_BINLOG --raw --read-from-remote-server --stop-never --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --result-file=$MYSQL_TMP_DIR/ master-bin.000001`) < /dev/null > /dev/null 2>&1 &
41+
EOF
42+
--chmod 0755 $MYSQL_TMP_DIR/mysqlbinlog_raw.sh
43+
--exec $MYSQL_TMP_DIR/mysqlbinlog_raw.sh
44+
45+
--echo # Step-3: Wait till dump thread transfer is completed.
46+
let $wait_condition= SELECT id from information_schema.processlist where processlist.command like '%Binlog%' and state like '%Master has sent%';
47+
--source include/wait_condition.inc
48+
49+
--echo # Step-4: copy binary log file that is downloaded till now before
50+
--echo # stopping dump thread that is serving mysqlbinlog
51+
--echo # --stop-never process.
52+
--copy_file $MYSQL_TMP_DIR/master-bin.000001 $MYSQL_TMP_DIR/master-bin-back_up_file.000001
53+
54+
--echo # Step-5: kill the dump thread serving the mysqlbinlog --stop-never process
55+
--source include/stop_dump_threads.inc
56+
57+
--echo # Step-6: Cleanup the data, so that it is ready for reapply.
58+
DROP TABLE t1;
59+
RESET MASTER;
60+
61+
--echo # Step-7: Apply the data that we got from --stop-never process.
62+
--exec $MYSQL_BINLOG $MYSQL_TMP_DIR/master-bin-back_up_file.000001 | $MYSQL --user=root --protocol=tcp --host=127.0.0.1 --port=$MASTER_MYPORT
63+
64+
--echo # Step-8: Check that the data is there.
65+
--let $assert_text= Check the table t1 exists and contains one tuple with value 1.
66+
--let $assert_cond= [SELECT COUNT(*) AS Val FROM t1 WHERE i = 1, Val, 1] = 1
67+
--source include/assert.inc
68+
69+
--echo # Step-9: Cleanup
70+
DROP TABLE t1;
71+
--remove_file $MYSQL_TMP_DIR/mysqlbinlog_raw.sh
72+
--remove_file $MYSQL_TMP_DIR/master-bin.000001
73+
--remove_file $MYSQL_TMP_DIR/master-bin-back_up_file.000001

0 commit comments

Comments
 (0)