既然mysql是先做數(shù)據(jù)操作、再寫binlog,如果寫binlog的時(shí)候失敗,mysql又crash,數(shù)據(jù)怎么辦?
答案是由存儲引擎決定數(shù)據(jù)。 可以把mysql和它的存儲引擎分開看,因?yàn)閙ysql只是一個(gè)框架,而不是一個(gè)實(shí)現(xiàn)。 binlog是mysql自己的日志,而事務(wù)是由存儲引擎本身保證的。 以update為例,mysql做的事情簡單分為: 1. 修改數(shù)據(jù)update 2. 寫binlog 3. 如果當(dāng)前處理的表是一個(gè)事務(wù)性的表,則commit或rollback,注意此處的update和commit/rollback都由存儲引擎實(shí)現(xiàn),mysql只是站在邏輯的高度上理解這些操作。
對于事務(wù)型的引擎innodb,它本身有日志保證數(shù)據(jù)的一致性。在innodb的實(shí)現(xiàn)中,update修改數(shù)據(jù)之前,會新建一個(gè)事務(wù),并建立一個(gè)回滾點(diǎn)。而在innodb提供的commit/rollback接口會提交/回滾事務(wù)。 因此對innodb而言,每條SQL語句的事務(wù),其實(shí)包含了binlog的寫操作。然而即使是這樣,innodb仍然無法保證binlog和數(shù)據(jù)的一致性,因?yàn)閕nnodb在寫commit成功后crash,回滾操作不會回滾binlog。按照手冊上的說法,把--innodb-support-xa設(shè)置為1,同時(shí)保證sync_binlog=1,才能保證innodb的binlog和數(shù)據(jù)一致。 對于非事務(wù)型的引擎myisam,沒有commit/rollback的機(jī)會,因此在異常情況下,數(shù)據(jù)會和binlog不一致。 那么新的問題出現(xiàn)了:myisam如何處理這個(gè)不一致呢?
|