生產系統數據丟失恢復案例

今天發一篇與以往不一樣的內容,這是一篇來自生產實踐的記錄。我只是作了一下編輯和修訂的工做。python

劉老師經過記錄真實的案例的形式,對故障排除的過程進行總結和反思。文中不但描述了劉老師解決問題的思路,還清晰的記載瞭解決問題的方法。仔細閱讀此文,你會發現劉老師對故障的排除和修復有着清晰的思路和嚴謹的執行方法。另外,經過此文,還能夠發現劉老師的一大愛好,去GitHub查找資源,並加以利用。這一舉動不但體現了開源軟件的優點,也體現了開源愛好者的理念。接下來,讓咱們閱讀劉老師的原文。mysql

做者:劉寶珍 git

崗位:架構師,目前就任於大型資產管理公司的科技子公司,擁有多年的大型私有云的規劃和設計工做經驗,熟悉軟件的開發流程,目前醉心於研究基於DDD和敏捷的軟件的開發模式,對分佈式架構有深刻的理解,同時也但願同各位朋友交流軟件架構和雲計算架構的經驗,在此也感謝徐老師對於本文的審覈和修訂。github

生產系統數據丟失後的恢復

1、背景和大概的思路

2020年2月25日,微信的朋友圈大量轉載微盟遭遇了系統重大故障,36小時內還沒有恢復核心生產數據,從而想到本人在兩週前處理的一個案例,開發人員誤刪除了生產數據,本人恢復的一個過程,同時給這個故障的處理過程作一個總結,也對學過的知識作一個梳理,但願對運維的同窗們有一個警示做用。sql

2.13日23:00接到微信通知,可否幫忙恢復數據。數據庫

系統環境信息以下:服務器

操做系統:RHEL7.5微信

工做流平臺:開源activity架構

業務應用:調用activity,生成該應用的流程數據。運維

工做流使用的數據庫:MYSQL 5.7 社區版,一主兩備。

23:05,開始介入數據丟失的故障。

確認一個大概解決問題的思路:

1. 找到是什麼人在什麼時間點作了什麼操做?

 2. 這個操做對系統的影響有多大,是否對其餘系統有影響?確認這個操做是否是正常業務體現?

 3. 確認數據庫裏受到影響的日誌的時間段。

 4. 在仿真環境覆盤整個故障。

 5. 制定技術恢復方案,在仿真環境驗證數據恢復方案。

 6. 在仿真環境驗證數據恢復後應用是否正常。

 7. 備份生產環境數據,應用數據恢復方案到生產環境。

 8. 生產環境綠燈測試,無誤後,恢復完成。

因爲恢復生產數據是重大的數據調整,須要報請領導批准,須要有完備的數據回退方案。

2、數據恢復過程以及技術分析

用了5分鐘理清了處理這個問題思路,接下來就是考慮具體的數據恢復了。在處理這個問題過程當中,有兩個難點須要解決。

  1. 確認要恢復的binlog的開始和結束。

  2. 根據binlog的開始和結束,確認數據恢復方案,以及是否須要須要排除在這個時間段發生的其餘干擾數據。

首先解決第一個問題:

  1. 詢問開發人員,開發人員給出晚間大概20:20左右操做rest接口,調用了activity(如下簡稱工做流)平臺刪除流程模板的操做,致使該流程模板下全部的流程實例所有被刪除,在該流程模板下有5個在途的流程還沒有處理完成。

  2. 根據開發人員的描述,登陸到工做流平臺的數據庫,查看數據庫在20:20左右的binlog 文件,並對11號binlog文件進行備份。

  3. 將binlog拷貝到一個開發的服務器,經過mysqlbinlog進行解析。解析命令爲:mysqlbinlog -v --base64-output=decode-rows --skip-gtids=true --start-datetime='2020-02-13 20:10:00' --stop-datetime='2020-02-13 21:30:00' -d {$DBNAME} mysql-bin.000011 >>aa.log dbname作了脫敏處理。

  4. 觀察解析後的sql,在20:20分並未發現大量的刪除操做,確認開發人員的話不可信,作故障診斷的第一原則:任何人的話都不能全信,也不可能不信,帶着疑問來找到論據證實他的說法。

  5. 繼續翻看解析的binlog,20:30開始出現大量的delete和update等操做,開始懷疑這一點是否是有問題的時間段。

  6. 將這一段的sql進行概括總結,概括須要操做幾個表,對這個幾個表的操做類型,以及操做的數據的類別(業務ID)。同工做流平臺的同事進行確認,刪除一個工做流的模板,是否是涉及到這些表的變動,工做流平臺的同事確認是這個過程,數據恢復的但願誕生了!

  7. 根據之前的經驗積累,github上有個開源項目binlog2sql,能夠將binlog的event翻譯成sql語句,也能夠翻譯成反向sql,頓時以爲這個問題應該很「容易」解決了。

  8. 根據以上思考,開始在仿真環境裏安裝binlog2sql工具,該工具就是一個python的程序,須要安裝好python環境以及須要的三方庫便可,具體的使用方式請參考:https://github.com/danfengcao/binlog2sql,同時也再次感謝工具的做者曹老師

  9. 在仿真環境裏,恢復生產環境有問題的實例,同時在工做流平臺將應用的jdbc的url指向新的恢復好的實例。

以上幾個過程,已經解決了第一個問題,接下來咱們要解決第二個問題。

  1. 在以上的步驟裏,已經在仿真環境覆盤了生產環境的故障,同時在也仿真環境裏裏安裝了binlog轉成sql的工具。

  2. 使用binlog2sql的工具,解析出來錯誤執行的sql,讓工做流的平臺的同時進行確認,同時讓工做流的同事,確認在這個時間段內沒有其餘的應用也在操做這個數據庫。

  3. 工做流的同事確認sql所有爲誤操做產生的sql。具體的確認方式以下:

(a) 在仿真環境模擬建立一個工做流模板。

(b) 在這個模板上建立幾個測試實例

(c) 經過接口去刪除這個工做流模板,觀察應用產生的sql,以此來確認本人提供的sql是否正確。

同時,工做流平臺確認在問題時間段內無其餘應用操做,感受勝利在望了,該問題能夠輕鬆解決了。

  1. 經過binlog2sql生產反向sql,把sql應用於仿真環境,問題就能解決了,仔細觀察反向sql文件,發現裏面有一些亂碼,查看亂碼字段所在的表,發現表的定義是這樣的。

生產系統數據丟失恢復案例

表中有個字段爲longblob字段,產生的insert的sql沒法執行,這個問題該怎麼處理?

  1. 這個問題到這裏陷入了僵局,眼看立刻就能解決的問題,發現有一個表數據沒法經過sql進行插入,詢問工做流平臺同事,這個表是否很重要,獲得答覆,沒有這個表的數據,系統沒法運轉。

  2. 換個思路考慮一下,既然sql是經過二進制的binlog生成的,能夠考慮生成反向的二進制binlog,而後把這一段反向的binlog應用到數據庫,這個問題就解決了。

  3. 帶着這個思路,去github裏翻看了項目。果真還真有一個:https://github.com/Meituan-Dianping/MyFlash 再次很是感謝美團點評開源的myflash項目。

  4. 利用myflash生成了反向二進制文件,把文件應用到數據庫,工做流平臺在仿真環境測試,數據完美再現。

3、問題的反思

經過以上分析,基本上就能夠輕鬆解決這個問題。對本身提出幾個問題:

  1. 爲何不用備份恢復的方式進行數據庫恢復?

在這個系統上,數據已經備份了,天天都有全備,不能使用這個恢復的緣由,工做流平臺裏有不少應用的流程引擎,一旦作了基於時間點恢復,別的應用的系統數據一塊被恢復了,將會致使別的系統會丟失一部分數據。

  1. 爲何不基於表的數據恢復?

由於工做流平臺是一個開源的平臺,數據模型之間的關聯性特別強,若是基於表的恢復,容易致使數據的約束出現問題。

反思:

  1. 爲何在生產環境出現丟失數據的狀況?

開發人員在生產上線過程越過了仿真環境,直接上生產,對生產上線過程並不嚴謹,雖然有管理流程,可是對流程的過程執行不力。

  1. 研發人員的技術能力,研發人員對activity並不熟悉,對於修改流程模板的流程也不熟悉,提升研發人員的技術能力必需要提上日程。

4、後續問題

結合以上分析過程,須要指定一些輔助策略來完善發佈流程。

  1. 發佈流程自動化,應用代碼發佈自動化發佈,儘可能避免人爲參與。

  2. 應用發佈流程標準化,全部的腳本和上線的新的應用的步驟必須通過驗證才能上線。

全文至此結束。

相關文章
相關標籤/搜索