Mysql

使用 InnoDB 執行 MySQL 將所有內容刷新到文件以允許文件級實時備份

  • November 10, 2021

客戶端具有文件級備份,其中關鍵網路伺服器的每個相關文件在凌晨 1 點左右同步到另一個網路伺服器。這包括該/var/lib/mysql伺服器的數據庫所在的目錄。

他們正在關閉備份伺服器上的 mysql,但不在主伺服器上(!)。

所以他們轉儲到仍在執行的 mysqld 的 mysql 文件中,並在備份伺服器上啟動 mysqld,就好像它剛剛在執行中崩潰一樣。

Mysql 通常會解決這個問題,但現在恰好在凌晨 1 點左右有更多活動,所以有時 mysql 拒絕在沒有顯式innodb_force_recovery = 2in的情況下啟動my.cnf

有什麼好方法可以告訴正在執行的 mysql 伺服器在備份之前將所有內容寫入文件?

我的客戶絕對需要文件級備份,所以不幸的是,像 mysqldump 這樣的正常東西不是一種選擇。

換句話說,如果我知道我的 mysqld 程序會在一分鐘內發出 SIGILL 信號,那麼如何在不關閉數據庫文件的情況下最大限度地減少對數據庫文件的損害?

我希望有類似的東西mysql -s innodb_flush_buffers_to_disk

更新:

正如 Bill Karwin 評論的那樣,mysql 不需要將所有內容都寫入磁碟來生成有效文件,InnoDB 已經以一種使每一步都有效的方式寫入。當文件在復製過程中發生更改時,就會出現問題。所以我最終讓客戶端將一個小型SSD放入伺服器,然後將mysql移到那裡並首先在本地複制。

我還顯著精簡了 mysql。

通過這種方式,複製操作被加速到幾乎是原子的。

副本損壞的可能性仍然不是 0,但老實說,這就是客戶應得的備份解決方案。

不,沒有辦法確保 InnoDB 將所有內容刷新到磁碟,除非徹底關閉 mysqld。

InnoDB 有一些後台執行緒繼續修改表空間中的頁面,即使全域鎖阻止了任何查詢活動。這些執行緒執行非同步工作,例如將修改的頁面刷新到儲存、清除撤消日誌以及將更改緩衝區合併到索引中。即使所有查詢活動都被阻止,這項工作也可以持續數小時。

如果您在此工作進行時執行簡單的文件系統備份,則文件很有可能在文件系統備份期間發生更改,並且備份不會自動讀取 InnoDB 表空間文件。也就是說,表空間文件從開始讀取到結束所花費的時間會發生變化。由於 InnoDB 表空間中的頁面充滿了指向其他頁面的指針,這很可能會導致文件損壞。

防止這種情況的唯一方法是關閉 mysqld。

這就是為什麼像Percona XtraBackup這樣的物理備份工具非常有用的原因。在 xtrabackup 複製表空間文件的同時,它也在逐步讀取 InnoDB 重做日誌 ( ib_logfile*),因此它可以將這些更改合併到表空間中,並且在日誌迴繞時不會錯過任何內容。這在正在執行的 MySQL 伺服器上是安全的。

因此,一種解決方案是在文件系統備份執行之前使用 xtrabackup 進行備份。然後,如果您需要從該文件系統備份中恢復,請使用 xtrabackup 的副本,並覆蓋 datadir 中的副本。

一個更好的替代方法是使用 LVM 快照備份文件系統,這是原子的。至少這樣你就不會面臨競爭條件的風險,所以你應該能夠對 InnoDB 表空間進行崩潰恢復並獲得可行的恢復。但是,如果客戶堅持使用簡單的文件系統複製命令,這可能也是客戶無法接受的。

引用自:https://dba.stackexchange.com/questions/302295