mysql数据迁移数据一致性检教6_如何在数据库迁移中保证数据一致性?
原標題:如何在數據庫遷移中保證數據一致性?
作者 | 王斌
譯者 | 平川
策劃 | 萬佳
在分布式系統中,保持數據一致非常困難,而且很容易出錯。在本文中,我們將探索一種在遷移期間保持數據一致性的方法,并且這種方法的停機時間較短。
當一個系統存在很長一段時間后,經常會使用更新的技術來提高性能、可維護性或添加新特性。其中一個變化可能會是使用哪個數據庫。這可能是最困難的改變。在遷移過程中,有兩個數據源,這使得該系統成為一個分布式系統。在分布式系統中,保持數據一致非常困難,而且很容易出錯。在本文中,我們將探索一種在遷移期間保持數據一致性的方法,并且這種方法的停機時間較短。
1前提條件
為了使用本文描述的方法,需要滿足一些要求:
源數據庫支持捕獲數據更改(CDC)的方法,如 MySQL 的 bin log。
源數據庫可以導出一致的數據,并且可以在數據更改日志中標記位置。
目標數據庫支持 ACID 事務。
源和目標數據庫都支持讀寫權限控制。
2步驟
制定以下遷移步驟的兩個基本想法:
在給定的時間點上,客戶端只向其中一個數據庫寫入,從而避免了分布式事務易出錯、處理速度慢的問題。
通過設置數據庫權限來實現數據庫切換。這比從客戶端代碼切換要快,而且更容易確保所有客戶端都切換。
下面是具體步驟。
1. 將源數據庫轉儲到目標數據庫
首先,我們需要源數據庫可以導出一致的數據。標記好已轉儲的位置。例如,在 MySQL 中,可以在使用 mysqldump 轉儲數據庫時帶上 --master-data 選項,這樣生成的文件中就會記錄 bin log 日志的位置(使用文檔)。從源數據庫獲得所有數據后,可以將它們插入目標數據庫。
https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html#option_mysqldump_master-data
因為這是第一步,所以即使失敗了也很容易處理:重新開始即可。因此,重要的是,在導入轉儲數據時,任何錯誤都要捕獲。
2. 捕獲源數據庫的更改
下一步是捕獲源數據庫的更改。例如,在 MySQL 中,可以使用 bin log 捕獲更改并將其插入到目標數據庫中。因為上一步記錄了開始位置,所以我們知道從哪里開始解析和導入更改。
在導入時保持更改順序非常重要。所以最好是只使用一個進程來解析和導入更改。這個步驟非常具有挑戰性:這一步性能很重要。同步所有更改的時間就是遷移所需的停機時間。
我們還需要確保,即使出現系統故障,也不會錯過任何更改或多次導入任何更改。因此,記錄更改日志的位置非常重要。我們可以使用與導入數據相同的事務將位置寫入目標數據庫,這非常方便。這樣,位置就可以與我們導入的數據保持同步。
3. 拒絕客戶端到目標數據庫的寫操作
使用單一數據源是一種保持數據一致性的簡單方法。到目前為止,我們使用源數據庫作為單一數據源,并將更改同步到目標數據庫。我們不想讓其他寫操作把目標數據庫搞亂。因此,我們需要設置目標數據庫的權限來拒絕來自客戶端的所有寫操作。例如,在 MySQL 中,只向客戶端授予表的 select 權限,并拒絕其他操作。我們允許讀取權限,這樣在下一步中就可以比較讀取結果。
4. 修改客戶端,同時對兩個數據庫進行讀取和寫入
下一步是讓客戶端同時對源和目標數據庫進行讀取和寫入。
我們希望首先讀 / 寫源數據庫。如果沒有權限錯誤,則使用此結果,否則使用來自目標數據庫的讀 / 寫結果。
對目標數據庫的讀 / 寫操作有兩個目的:
在切換到目標數據庫之前,我們可以通過比較讀結果和寫操作來驗證目標數據庫是否按預期工作。注意,目標數據庫可能存在同步延遲,因此結果可能會不同。但是我們可以根據相同結果的百分比來理解其正確性。
在我們切換到目標數據庫之后,讀 / 寫結果將被視為真實結果。
如果你想確保目標數據庫能夠處理這些負載,那么在一段時間內允許對目標數據庫進行讀 / 寫操作是個好主意,但這只是作為一個驗證,在那之后,目標數據庫中的數據會不一致。因此,在我們驗證了目標數據庫能夠處理系統流量之后,我們需要清理目標數據庫,并再次從步驟 1 開始。(在這些步驟中,我們不需要修改客戶端代碼)。
對于錯誤處理,有兩個關鍵點:
如果源數據庫有權限錯誤,則只使用目標數據庫的結果。拋出源數據庫的其他錯誤。
如果沒有使用這個結果,則忽略目標數據庫的錯誤,但要確保記錄這些錯誤,以便它不會影響當前操作,同時還要確保切換之前沒有錯誤。
客戶端代碼如下:
db_operation{
2try {
3source_result = source_db_operation
4} catch (PermissionException e) {
5return target_db_operation
6}
7async {
8// 以下操作異步進行,這樣不會影響性能
9try {
10target_result = target_db_operation
11compare_result(source_result, target_result)
12} catch (Exception e) {
13log_error(e)
14}
15}
16return source_result
17}
5. 拒絕客戶端對源數據庫的訪問,并等待更改同步
在對目標數據庫的讀寫操作有信心之后,就可以進行切換了。我們通過更改數據庫權限來切換數據庫。首先,我們拒絕客戶端對源數據庫的所有訪問。然后等待更改完全同步到目標數據庫。在此期間,系統是停機的。因此,從源數據庫到目標數據庫的更改同步速度決定了它的停機時間。
6. 允許寫入目標數據庫
在目標數據庫完全同步之后,我們可以為所有客戶端賦予目標數據庫權限。在此之后,系統就再次在線了,數據庫已完全切換。
7. 可選:如果出現任何錯誤,則回退到源數據庫
如果到目前為止一切順利,那就太好了。但情況并非總是如此。也許目標數據庫無法處理新的流量(這就是我們說步驟 4 的測試很重要的原因),在這種情況下,我們就需要回退到源數據庫。
如果是在遷移期間丟失了提交的數據,那不是什么大問題,回退也比較簡單:
允許訪問源數據庫。在此之后,客戶端應該再次使用源數據庫。
清理目標數據庫,并重新從頭開始。
如果保存提交的數據并保持一致性非常重要,那么在第 5 步之前,我們應該設置一種機制來捕獲從目標數據庫到源數據庫的更改,并在第 6 步之后標記更改位置。那么,回退步驟將是下面這樣:
拒絕對目標數據庫的所有寫操作。
從目標數據庫向源數據庫同步(在同步完成之后停止同步程序)。
允許訪問源數據庫。
清理目標數據庫并重新開始。
從目標數據庫到源數據庫的同步非常危險且難以測試,因此,在步驟 4 中測試目標數據庫能否處理新的流量就非常重要。
8. 清理客戶端代碼
切換到目標數據庫之后,我們就可以清除訪問源數據庫的代碼了。這樣,數據庫遷移就大功告成了!
原文鏈接:
https://www.binwang.me/2020-11-29-Keep-Data-Consistency-During-Database-Migration.html返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的mysql数据迁移数据一致性检教6_如何在数据库迁移中保证数据一致性?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql两者之间_sql betwee
- 下一篇: mysql搭建测试环境的步骤_如何搭建测