Semisynchronous Replication
Overview
In semisynchronous replication, after executing the transaction committed by the client, the primary database does not immediately return the result to the client. Instead, the primary database calls the dump thread to notify the secondary database of the new transaction. The secondary database calls the I/O thread to write the binlog obtained from the primary database to the relay log and returns the ACK packet to the primary database. In addition, the secondary database calls the SQL thread to replay the relay log and writes the update to the local drive. The primary database determines that the transaction is successfully executed only after receiving the ACK packet from the secondary database by calling the dump thread, and then returns the result to the client. MySQL 5.5 and later versions provide the semisynchronous replication plugin. When the primary database is faulty, the secondary database can have a complete data copy. Therefore, semisynchronous replication solves the problem of primary/secondary data inconsistency in asynchronous replication. However, semisynchronous replication may cause a certain delay, which will affect service performance.
Service Process
- The client calls the user thread to initiate a data update request. The primary database performs the update and writes the update to the binlog. When starting the dump thread, the primary database calls the add_slave() function to add all secondary databases to a monitoring queue. When sending packets to secondary databases, the primary database calls the updateSyncHeader() function to update the semi-sync flag in the packet header.
- After obtaining the binlog of the primary database by calling the I/O thread, the secondary database calls the slaveReadSyncHeader() function to check whether the packet header contains the semi-sync flag. If the packet header contains the semi-sync flag, the secondary database writes the received binlog into the relay log and calls the slaveReplay() function to return an ACK packet to the primary database. The secondary database calls the SQL thread to replay the relay log, that is, write the update to the local drive.
- The primary database calls the ack_receiver thread to monitor all secondary databases, and calls the handleAck() function to record the current position in the binlog to the ack_array. When receiving the response from one secondary database (rpl_semi_sync_master_wait_for_slave_count == 1), the primary database calls the reportReplyBinlog() function to wake up the working thread and return a success message to the client.
Processing Logic in the Transaction Commit Stage
The processing logic in the transaction commit stage is classified into after_sync and after_commit. after_sync is recommended for higher reliability.
- after_sync means that the primary database waits for ACK packets from secondary databases after the user thread calls binlog sync. After receiving an ACK packet from any secondary database, the primary database starts the engine commit process. The after_sync mode will trigger transaction accumulation, which facilitates group commit and improves the engine commit performance.
Figure 2 Logic process of after_sync
- after_commit means that engine commit is executed before the ACK packet is received from the secondary database, but the execution result is not returned to the client. The primary database returns the execution result to the client after receiving the ACK packet from the secondary database. If engine commit is executed before the ACK packet is received from the secondary database, other clients will read the committed transaction. If the secondary database does not read the transaction and the primary database breaks down, manually switch the primary database to the secondary database. In this case, the previously read transaction disappears, that is, phantom read occurs.
Figure 3 Logic process of after_commit
Application Scenarios
Semisynchronous replication ensures zero data loss but has long latency. Therefore, it is suitable for scenarios that have low requirements on network latency and cannot tolerate any data loss.