2010年4月24日 星期六

第五回 某物流業資料庫備份問題

這次是今年發生的事,因為專案的關係,我們協助某物流業建立備份程序,在這個客戶環境中,存在了一個將近 100G 的 MYSQL 資料庫。

原本 100G 的資料庫,無論是 MS 的 SQL ,或 Oracle Database ,Sybase , Informix 都不會有什麼問題,但是因為他是 MYSQL ,所以有一些限制存在,偏偏在事前我們並不知道這個限制,問題就是在使用 mysqldump 備份時,如果 table engine 是屬於 defulat 的 MYISAM 模式的話,會造成 table 在備份的過程中,發生 table lock ,所以任何有關 update , delete , insert 的 DML 將無法執行,在備份的 Script 排程下去後的當天凌晨,該客戶的 MYSQL 資料庫就這樣被 Lock 了一個小時無法運作。

在問題發生了之後,我們試過了各種方法,無論是用硬體 做 Disk snap,或 Linux 的LVM snap,在客戶的環境下運作都還是有問題,最後只能依造 MYSQL 的做法,建立一台 Replication Server ,但是這仍然是有問題的。

最主要還是在 MYSQL 架構上,MYISAM 下並沒有交易的機制,每一個 DML 就是一個獨立的交易,無法 Rollback ,所以如果正常執行下,Replication 機制是運作的,但是只要 Disk Crash ,File system Crash ,Power Outage 發生時,造成 Master 或 Slave 中任一 Database 有資料損壞,就會發生一件事,兩端的資料會原本的一致,變成有落差,而且如何去判別這些落差,哪些是你要的或不需要的,抱歉,DBA或系統管理人員並不是開發人員,不知道你程式怎麼執行的前提下,無法取得哪些資料是你不要的資訊。假設 Master 因為任何原因資料損壞修復後,Slave 端就會多出一些資料,而多了哪些資料,除非你把兩邊資料庫停下來做比較,不然無法得知。如果客戶無法忍受 RTO 太長而需要儘快的將資料庫啟動的話,是無法完成這件事的。

那假設把資料表轉換成另外一種 Engine Innodb 的話,看起來好像事情可以得到解決,因為有了 Transaction 機制,MYSQL 會記錄每一筆交易到 LOG 檔中,亦會將這些交易跟 Replication 用的 bin log 同步,所以 Replication 端會去讀取所有的交易記錄,不過我還是發現了問題,就是如果這回輪到 Slave 端斷電的話,一樣會不同步,只是還原的方法就比上面簡單多了。問題發生的原因跟上述的原因一樣,只是這次是發生在 Slave 端。

但是無論如何,Master 應該都會比 Slave 重要,個人覺得重要的資料庫還是需要開啟 Innodb 的,只是這樣就失去 Mysql 又小速度又快的特性了,可能為了要維持資料庫本身的一致性,而拖垮資料庫系統的效能。