Skip to content

Commit 8900da4

Browse files
committed
Merge branch 'mysql-5.6' into mysql-5.7
2 parents b120e22 + 78f25d2 commit 8900da4

7 files changed

+130
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
include/master-slave.inc
2+
Warnings:
3+
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4+
Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
5+
[connection master]
6+
CREATE TABLE t1 (i INT);
7+
include/sync_slave_sql_with_master.inc
8+
include/stop_slave_sql.inc
9+
SET GLOBAL debug='+d,wait_in_purge_index_entry';
10+
FLUSH LOCAL RELAY LOGS;
11+
START SLAVE SQL_THREAD;
12+
SET DEBUG_SYNC="now WAIT_FOR in_purge_index_entry";
13+
[connection master]
14+
INSERT INTO t1 VALUES (1);
15+
[connection slave]
16+
include/assert.inc [IO Thread is waiting for Relay_log_info::log_space_lock.]
17+
SET DEBUG_SYNC="now SIGNAL go_ahead_sql";
18+
[connection master]
19+
DROP TABLE t1;
20+
include/sync_slave_sql_with_master.inc
21+
SET GLOBAL debug='-d,wait_in_purge_index_entry';
22+
SET DEBUG_SYNC="RESET";
23+
include/rpl_end.inc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# === Purpose ===
2+
#
3+
# This test verifies that SQL and IO threads update the
4+
# rli->relay_log_space_total variable in a synchronized manner.
5+
#
6+
# === Implementation ===
7+
#
8+
# 1. On Slave, make the SQL thread to purge relay logs and halt
9+
# the SQL thread in MYSQL_BIN_LOG::purge_index_entry function
10+
# using debug sync utility.
11+
# 2. Do a DML on master so that IO thread calls queue_event and
12+
# updates rli->relay_log_space_total.
13+
# 3. Verify that IO thread is waiting rli->log_space_lock until it is released
14+
# by SQL thread.
15+
#
16+
# === References ===
17+
#
18+
# Bug#26997096 RELAY_LOG_SPACE IS INACCURATE AND LEAKS
19+
20+
# This test case is binlog_format agnostic
21+
--source include/have_binlog_format_row.inc
22+
# This test case uses debug_sync
23+
--source include/have_debug.inc
24+
--source include/have_debug_sync.inc
25+
--source include/master-slave.inc
26+
27+
CREATE TABLE t1 (i INT);
28+
29+
--source include/sync_slave_sql_with_master.inc
30+
--source include/stop_slave_sql.inc
31+
SET GLOBAL debug='+d,wait_in_purge_index_entry';
32+
33+
# Create a new relay log so the START SLAVE SQL_THREAD tries
34+
# to purge the old relay logs and hits the debug point.
35+
FLUSH LOCAL RELAY LOGS;
36+
START SLAVE SQL_THREAD;
37+
SET DEBUG_SYNC="now WAIT_FOR in_purge_index_entry";
38+
39+
# Do a DML on master so that IO thread calls queue_event and
40+
# updates rli->relay_log_space_total.
41+
--source include/rpl_connection_master.inc
42+
INSERT INTO t1 VALUES (1);
43+
--source include/rpl_connection_slave.inc
44+
45+
# Wait until IO thread tries to take a log_space_lock.
46+
--let $io_thread_id = `SELECT THREAD_ID FROM performance_schema.threads WHERE NAME like '%slave_io%'`
47+
--let $wait_condition= SELECT EVENT_NAME= 'wait/synch/mutex/sql/Relay_log_info::log_space_lock' FROM performance_schema.events_waits_current WHERE THREAD_ID=$io_thread_id
48+
--source include/wait_condition.inc
49+
50+
# Since SQL thread has taken the rli->log_space_lock, IO thread should wait until
51+
# the lock is released. Assert that IO thread is waiting for rli->log_space_lock.
52+
--let $assert_text= IO Thread is waiting for Relay_log_info::log_space_lock.
53+
--let $assert_cond= "[SELECT EVENT_NAME FROM performance_schema.events_waits_current WHERE THREAD_ID=$io_thread_id]" = "wait/synch/mutex/sql/Relay_log_info::log_space_lock"
54+
--source include/assert.inc
55+
56+
SET DEBUG_SYNC="now SIGNAL go_ahead_sql";
57+
58+
# Cleanup
59+
--source include/rpl_connection_master.inc
60+
DROP TABLE t1;
61+
--source include/sync_slave_sql_with_master.inc
62+
SET GLOBAL debug='-d,wait_in_purge_index_entry';
63+
SET DEBUG_SYNC="RESET";
64+
--source include/rpl_end.inc

sql/binlog.cc

+25
Original file line numberDiff line numberDiff line change
@@ -6656,6 +6656,13 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
66566656
DBUG_PRINT("info",("purging %s",log_info.log_file_name));
66576657
if (!mysql_file_delete(key_file_binlog, log_info.log_file_name, MYF(0)))
66586658
{
6659+
DBUG_EXECUTE_IF("wait_in_purge_index_entry",
6660+
{
6661+
const char action[] = "now SIGNAL in_purge_index_entry WAIT_FOR go_ahead_sql";
6662+
DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(action)));
6663+
DBUG_SET("-d,wait_in_purge_index_entry");
6664+
};);
6665+
66596666
if (decrease_log_space)
66606667
*decrease_log_space-= s.st_size;
66616668
}
@@ -8330,6 +8337,24 @@ void MYSQL_BIN_LOG::close(uint exiting, bool need_lock_log,
83308337
DBUG_VOID_RETURN;
83318338
}
83328339

8340+
void MYSQL_BIN_LOG::harvest_bytes_written(Relay_log_info* rli, bool need_log_space_lock)
8341+
{
8342+
#ifndef DBUG_OFF
8343+
char buf1[22],buf2[22];
8344+
#endif
8345+
DBUG_ENTER("harvest_bytes_written");
8346+
if (need_log_space_lock)
8347+
mysql_mutex_lock(&rli->log_space_lock);
8348+
else
8349+
mysql_mutex_assert_owner(&rli->log_space_lock);
8350+
rli->log_space_total+= bytes_written;
8351+
DBUG_PRINT("info",("relay_log_space: %s bytes_written: %s",
8352+
llstr(rli->log_space_total,buf1), llstr(bytes_written,buf2)));
8353+
bytes_written=0;
8354+
if (need_log_space_lock)
8355+
mysql_mutex_unlock(&rli->log_space_lock);
8356+
DBUG_VOID_RETURN;
8357+
}
83338358

83348359
void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg)
83358360
{

sql/binlog.h

+1-12
Original file line numberDiff line numberDiff line change
@@ -690,18 +690,7 @@ class MYSQL_BIN_LOG: public TC_LOG
690690
{
691691
bytes_written = 0;
692692
}
693-
void harvest_bytes_written(ulonglong* counter)
694-
{
695-
#ifndef DBUG_OFF
696-
char buf1[22],buf2[22];
697-
#endif
698-
DBUG_ENTER("harvest_bytes_written");
699-
(*counter)+=bytes_written;
700-
DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
701-
llstr(bytes_written,buf2)));
702-
bytes_written=0;
703-
DBUG_VOID_RETURN;
704-
}
693+
void harvest_bytes_written(Relay_log_info *rli, bool need_log_space_lock);
705694
void set_max_size(ulong max_size_arg);
706695
void signal_update()
707696
{

sql/rpl_rli.cc

+4-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "debug_sync.h"
3131
#include "pfs_file_provider.h"
3232
#include "mysql/psi/mysql_file.h"
33+
#include "mutex_lock.h" // Mutex_lock
3334

3435
#include <algorithm>
3536
using std::min;
@@ -399,6 +400,7 @@ static inline int add_relay_log(Relay_log_info* rli,LOG_INFO* linfo)
399400
{
400401
MY_STAT s;
401402
DBUG_ENTER("add_relay_log");
403+
mysql_mutex_assert_owner(&rli->log_space_lock);
402404
if (!mysql_file_stat(key_file_relaylog,
403405
linfo->log_file_name, &s, MYF(0)))
404406
{
@@ -418,6 +420,7 @@ int Relay_log_info::count_relay_log_space()
418420
{
419421
LOG_INFO flinfo;
420422
DBUG_ENTER("Relay_log_info::count_relay_log_space");
423+
Mutex_lock lock(&log_space_lock);
421424
log_space_total= 0;
422425
if (relay_log.find_log_pos(&flinfo, NullS, 1))
423426
{
@@ -2426,7 +2429,7 @@ void Relay_log_info::end_info()
24262429
relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT,
24272430
true/*need_lock_log=true*/,
24282431
true/*need_lock_index=true*/);
2429-
relay_log.harvest_bytes_written(&log_space_total);
2432+
relay_log.harvest_bytes_written(this, true/*need_log_space_lock=true*/);
24302433
/*
24312434
Delete the slave's temporary tables from memory.
24322435
In the future there will be other actions than this, to ensure persistance

sql/rpl_slave.cc

+12-12
Original file line numberDiff line numberDiff line change
@@ -3346,7 +3346,7 @@ static bool wait_for_relay_log_space(Relay_log_info* rli)
33463346
if (rli->sql_force_rotate_relay)
33473347
{
33483348
mysql_mutex_lock(&mi->data_lock);
3349-
rotate_relay_log(mi);
3349+
rotate_relay_log(mi, false/*need_log_space_lock=false*/);
33503350
mysql_mutex_unlock(&mi->data_lock);
33513351
rli->sql_force_rotate_relay= false;
33523352
}
@@ -3402,7 +3402,7 @@ static int write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
34023402
"failed to write a Rotate event"
34033403
" to the relay log, SHOW SLAVE STATUS may be"
34043404
" inaccurate");
3405-
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
3405+
rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
34063406
if (flush_master_info(mi, TRUE))
34073407
{
34083408
error= 1;
@@ -7725,7 +7725,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
77257725
"error writing Exec_load event to relay log");
77267726
goto err;
77277727
}
7728-
mi->rli->relay_log.harvest_bytes_written(&mi->rli->log_space_total);
7728+
mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
77297729
break;
77307730
}
77317731
if (unlikely(cev_not_written))
@@ -7740,7 +7740,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
77407740
goto err;
77417741
}
77427742
cev_not_written=0;
7743-
mi->rli->relay_log.harvest_bytes_written(&mi->rli->log_space_total);
7743+
mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
77447744
}
77457745
else
77467746
{
@@ -7754,7 +7754,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
77547754
"error writing Append_block event to relay log");
77557755
goto err;
77567756
}
7757-
mi->rli->relay_log.harvest_bytes_written(&mi->rli->log_space_total);
7757+
mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
77587758
}
77597759
}
77607760
}
@@ -7825,7 +7825,7 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
78257825
Rotate the relay log makes binlog format detection easier (at next slave
78267826
start or mysqlbinlog)
78277827
*/
7828-
int ret= rotate_relay_log(mi);
7828+
int ret= rotate_relay_log(mi, true/*need_log_space_lock=true*/);
78297829
DBUG_RETURN(ret);
78307830
}
78317831

@@ -7941,7 +7941,7 @@ static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
79417941
delete ev;
79427942
DBUG_RETURN(1);
79437943
}
7944-
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
7944+
rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
79457945
}
79467946
delete ev;
79477947
mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
@@ -7999,7 +7999,7 @@ static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
79997999
delete ev;
80008000
DBUG_RETURN(1);
80018001
}
8002-
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
8002+
rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
80038003
delete ev;
80048004
mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
80058005
err:
@@ -8660,7 +8660,7 @@ bool queue_event(Master_info* mi,const char* buf, ulong event_len)
86608660
{
86618661
mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
86628662
DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
8663-
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
8663+
rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
86648664

86658665
/*
86668666
If this event is GTID_LOG_EVENT we store its GTID to add to the
@@ -9579,7 +9579,7 @@ static Log_event* next_event(Relay_log_info* rli)
95799579
is void).
95809580
*/
95819581

9582-
int rotate_relay_log(Master_info* mi)
9582+
int rotate_relay_log(Master_info* mi, bool need_log_space_lock)
95839583
{
95849584
DBUG_ENTER("rotate_relay_log");
95859585

@@ -9617,7 +9617,7 @@ int rotate_relay_log(Master_info* mi)
96179617
If the log is closed, then this will just harvest the last writes, probably
96189618
0 as they probably have been harvested.
96199619
*/
9620-
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
9620+
rli->relay_log.harvest_bytes_written(rli, need_log_space_lock);
96219621
end:
96229622
DBUG_RETURN(error);
96239623
}
@@ -9640,7 +9640,7 @@ bool flush_relay_logs(Master_info *mi)
96409640
if (mi)
96419641
{
96429642
mysql_mutex_lock(&mi->data_lock);
9643-
if (rotate_relay_log(mi))
9643+
if (rotate_relay_log(mi, true/*need_log_space_lock=true*/))
96449644
error= true;
96459645
mysql_mutex_unlock(&mi->data_lock);
96469646
}

sql/rpl_slave.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ void init_thread_mask(int* mask,Master_info* mi,bool inverse);
429429
void set_slave_thread_options(THD* thd);
430430
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
431431
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
432-
int rotate_relay_log(Master_info* mi);
432+
int rotate_relay_log(Master_info* mi, bool need_log_space_lock);
433433
bool queue_event(Master_info* mi,const char* buf, ulong event_len);
434434

435435
extern "C" void *handle_slave_io(void *arg);

0 commit comments

Comments
 (0)