2016-12-30 10:29:57 |
xjxia |
description |
When mysqldump use binlog_snapshot_file, binlog_snapshot_pos instead of show master status to get master binlog information, There is a very small probability to get a wrong position and lead to inconsistent。
I found this bug by debug other features,and is difficult for reproduce by a testcase,So I describe it by some fake code as follows(NB:binlog_order_commits is ON):
First,describe two function's process
----------------------------------------
In function2: MYSQL_BIN_LOG::ordered_commit
#step 1
lock(LOCK_log)
flushing transactions to binary log
....
unlock(LOCK_log)
#step 2
lock(LOCK_sync);
Syncing binary log file to disk
.....
unlock(LOCK_SYNC)
#step 3
lock(LOCK_commit)
Commit all transactions in order.
....
unlock(&LOCK_commit)
In function2: ha_start_consistent_snapshot
lock(LOCK_log)
lock(LOCK_commit)
get binlog filename, binlog pos
....
unlock(&LOCK_commit)
unlock(LOCK_log)
-----------------------------------------
For example, we do an insert, If function1 had flush and sync binlog to disk(thus, binlog file,pos info had modified)at step1, step2, but not lock LOCK_commit and not commit yet at step 3;At the same time, other session(i.e. mysqldump) do function2, and got the newest binlog_file,pos which had include the latest record, but InnoDB not commit yet,so under this snapshot,select can't see the uncommitted record and backup not。 |
When mysqldump use binlog_snapshot_file, binlog_snapshot_pos instead of show master status to get master binlog information, There is a very small probability to get a wrong position and lead to inconsistent。
I found this bug by debug other features,and is difficult for reproduce by a testcase,So I describe it by some fake code as follows(NB:binlog_order_commits is ON):
First,describe two function's process
----------------------------------------
In function2: MYSQL_BIN_LOG::ordered_commit
#step 1
lock(LOCK_log)
flushing transactions to binary log
....
unlock(LOCK_log)
#step 2
lock(LOCK_sync);
Syncing binary log file to disk
.....
unlock(LOCK_SYNC)
#step 3
lock(LOCK_commit)
Commit all transactions in order.
....
unlock(&LOCK_commit)
In function2: ha_start_consistent_snapshot
lock(LOCK_log)
lock(LOCK_commit)
get binlog filename, binlog pos
....
unlock(&LOCK_commit)
unlock(LOCK_log)
-----------------------------------------
For example, we do an insert, If function1 had flush and sync binlog to disk(thus, binlog file,pos info had modified)at step1, step2, but not lock LOCK_commit and not commit yet at step 3;At the same time, other session(i.e. mysqldump) do function2, and got the newest binlog_file,pos which had include the latest record, but InnoDB not commit yet,so under this snapshot,select can't see the uncommitted record and backup not。
Fix suggest:
when do MYSQL_BIN_LOG::ordered_commit, introduce an alone share to lock flush、sync binlog,commit trx(step1,step2,step3), and when do ha_start_consistent_snapshot, we get an exclusive on the same lock. |
|