-
Libing Song authored
PROBLEMS ======== * Dump threads acquired LOCK_log when reading each event. In fact, it is not necessary in most of the cases. * The code was too complex and mysql_binlog_send() was too huge. It was very difficult to maintain. * There was some code never used. * Deadlock on semi-synchronous replication WL#6355 introduces a feature that semi-synchronous waits for ACK from slave when the transaction's events is written to disc but before the transaction is committed. It introduced a three way deadlock. SESSION 1(Rotate) SESSION 2(Trx Commit) DUMP THREAD --------- --------- ----------- 1 Flush Stage Signal update 2 Rotate(hold LOCK_log) WAITING for Session2 to commit 3 Sync Stage WAITING for Session1 to release LOCK_log 4 semisync WAITING for ACK Session1 had to hold LOCK_log to block other sessions appending new events. It also blocked dump threads reading events. DESIGN AND IMPLEMENTATION ========================= Binary events can only be appended at the end of the active file. So it is safe to read both inactive and active binlog files without lock. The only problem is that dump thread may read an incomplete event at the end of active log file. To solve the problem, MYSQL_BIN_LOG needs a variable which records the end position of the last event in active file. * MYSQL_BIN_LOG::binlog_end_pos The end position of active file. It is safe to read all events before it without any lock. It should be updated after appending events but before broadcasting update signal. * MYSQL_BIN_LOG::LOCK_binlog_end_pos It is used to protect binlog_end_pos. The lock is required when both writing and reading binlog_end_pos. * Binlog_sender class The class is designed to make the code of mysql_binlog_send() has better modularity and readability. All code of original mysql_binlog_send is moved to the class. Now mysql_binlog_send just need to call Binlog_sender.
Libing Song authoredPROBLEMS ======== * Dump threads acquired LOCK_log when reading each event. In fact, it is not necessary in most of the cases. * The code was too complex and mysql_binlog_send() was too huge. It was very difficult to maintain. * There was some code never used. * Deadlock on semi-synchronous replication WL#6355 introduces a feature that semi-synchronous waits for ACK from slave when the transaction's events is written to disc but before the transaction is committed. It introduced a three way deadlock. SESSION 1(Rotate) SESSION 2(Trx Commit) DUMP THREAD --------- --------- ----------- 1 Flush Stage Signal update 2 Rotate(hold LOCK_log) WAITING for Session2 to commit 3 Sync Stage WAITING for Session1 to release LOCK_log 4 semisync WAITING for ACK Session1 had to hold LOCK_log to block other sessions appending new events. It also blocked dump threads reading events. DESIGN AND IMPLEMENTATION ========================= Binary events can only be appended at the end of the active file. So it is safe to read both inactive and active binlog files without lock. The only problem is that dump thread may read an incomplete event at the end of active log file. To solve the problem, MYSQL_BIN_LOG needs a variable which records the end position of the last event in active file. * MYSQL_BIN_LOG::binlog_end_pos The end position of active file. It is safe to read all events before it without any lock. It should be updated after appending events but before broadcasting update signal. * MYSQL_BIN_LOG::LOCK_binlog_end_pos It is used to protect binlog_end_pos. The lock is required when both writing and reading binlog_end_pos. * Binlog_sender class The class is designed to make the code of mysql_binlog_send() has better modularity and readability. All code of original mysql_binlog_send is moved to the class. Now mysql_binlog_send just need to call Binlog_sender.
Loading