iDB是如何運轉的 一


鄭昀 創建於2015/12/2 最后更新於2015/12/4

關鍵詞:數據庫,MySQL,自動化運維,DDL,DML,SQL審核,備份,回滾,Inception,osc

提綱:

  1. 普通DBA和文藝DBA怎么做SQL審核
  2. 預執行庫如何實操
  3. Inception對備份/回滾服務器的特殊處理

  每個大型互聯網公司都有一個數據庫自動化運維系統,比如 Qunar 有 Inception(已開源),美團也有,趕集網的3個 DBA 開發了一個變更自助發布系統,淘寶和新浪呢都叫 iDB,騰訊互動娛樂團隊有個 TMySQL。

  大家都做這件事,一定是因為當數據量大到一定程度,數據重要到一定程度時,online schema change 和刷庫不容有失,第一解決鎖表問題,不能影響線上業務,第二搞定操作回滾問題,第三解救 DBA 於倒懸。我們的實現請參考《#研發解決方案#iDB-數據庫自動化運維平台》。

 

0x00,普通DBA和文藝DBA怎么做SQL審核

無論是 DDL 操作,還是數據訂正(也被稱為 DML 操作),都涉及 SQL 審核、預執行和數據備份及回滾。

 

1,普通 DBA 青年的做法是:

  1. Dev 或 CM 給 DBA 發執行腳本,
  2. DBA 肉眼審核,
    • 語法錯誤/語義錯誤/不符合規范/……
  3. 駁回,修改,審核,再駁回,……,通過,
  4. DBA 執行前做一次全表備份,
    • 援引 Inception 文檔的原話:
    • 備份是必要的,因為語句在沒有執行時,都是想不到它影響會有多大,一般是不需要,而需要時,才知道備份是多么的重要,這也正是應了一句諺語:“書到用時方恨少,事非經過不知難。”,但這個工作也很讓人為難,應該備份全表呢?還是把影響的查出來備份呢?DBA在這個時候肯定是不願意這樣做的,但萬一出問題怎么辦?都懂得,不說了。』
  5. 執行,
  6. Dev 或 QA 檢查,
  7. 收兵,或許有問題,則備份還原。

 

2,稍微文藝一些的 DBA 青年的做法是:

  1. Dev 或 CM 登錄自動化運維系統,提交 SQL 腳本,
  2. SQL 審核組件對腳本自動審核,檢查語法,檢查規范,
  3. DBA 點擊預執行,腳本在測試數據庫上 explain 或直接執行,獲得第一手數據,
    • 影響行數,索引使用情況
    • 預估執行時間
  4. DBA 確認無誤后,審核通過,系統按時在生產庫上執行,執行前系統將生產庫數據備份。

或者援引 Inception 文檔里的這張圖示意:

Inception的架構

圖1 Inception的架構

 

0x01,預執行庫如何實操

我們雲縱對 iDB 的設想是,當審核 DDL 操作時,環境中部署一個預執行庫。當 iDB 上要做預執行時,iDB 程序調用命令行暫停預執行庫的同步,等預執行回滾之后恢復同步,避免因為表結構變化而同步停止。預執行庫不需要配置為 blackhole,因為我們需要真實數據來獲得執行耗時,來決定我們應以什么策略在線上自動執行。

 

下面展示一下預執行時審核詳情頁上點擊”生成執行明細“按鈕的效果:

審核詳情頁

 

我們可以在這里選一下“執行方式”,共有三種可選:

  • nobinlog:適合我們的 Cobar 庫,合並庫和主站庫。先執行從庫,再執行主庫。從庫執行之后,會給30分鍾時間確認是否執行主庫。
  • binlog:非 Cobar 庫操作。
  • osc:對應於 MySQL 的在線 schema 修改工具 pt-online-schema-change。它先創建一個 tmp 表作為原表導數據的臨時表,然后在原表上建立三個觸發器,對應 Insert、Update、Delete 三種操作,再拷貝原表數據到臨時表中,Rename 原表為 old 表,再把臨時表 Rename 為原表,最后清理以上過程中不再使用的數據,如 old 表。它強調的是”在線更改表結構“,適合於大表。我們看一下 Inception 怎么做的:Inception 有一個設置項 inception_osc_min_table_size,默認為 16MB,表示表空間占用大於 16MB 時自動選擇 osc 方式執行。

 

0x02,Inception 對備份/回滾服務器的特殊處理

Inception 在做 DML 操作時,會將所有當前語句修改的行備份下來,存儲到一個指定的庫中。Qunar 在這里有一些特殊設計,值得借鑒。

下面文字搬運自他們的文檔:

備份數據在備份機器的存儲,是與線上被修改庫一對一的。但因為機器多(線上機器有很多)對一(備份機器只有一台),所以為了防止庫名的沖突,備份機器的庫名組成是由線上機器的 IP 地址的點換成下划線,再加上端口號,再加上庫名三部分,這三部分也是通過下划線連接起來的。例如:

192_168_1_1_3310_inceptiondb

一個備份庫,里面的表與對應線上表都是一一對應的,也就是說線上庫 inceptiondb 中有什么表,在備份庫 192_168_1_1_3310_inceptiondb 中就有什么表,表名也完全相同,不同的只是表中的列不同而已,它是用來存儲所有對這個表修改的回滾語句的,對應的表包括的列主要有下面兩個:

rollback_statement text:這個列存儲的是針對當前這個表的某一行被修改后,生成的這行修改的回滾語句。因為 binlog 是 Row 模式的,所以不管是什么語句,產生的回滾語句都是針對一行的,同時有可能一條語句的修改影響了多行,那么這里就會有多個回滾語句,但對應的是同一個 SQL 語句。對應關於通過下面的列來關聯起來。

opid_time varchar(50):這個列存儲的是的被執行的 SQL 語句在執行時的一個序列號,這個序列號由三部分組成:timestamp(int 值,是語句被執行的時間點),線上服務器執行時所產生的 thread_id,當前這條語句在所有被執行的語句塊中的一個序號。產生結果類似下面的樣子:1413347135_136_3,針對同一個語句影響多行的情況,那么所產生的多行數據中,這個列的值都是相同的,這樣就可以找到一條語句對應的所有被影響數據的回滾語句。

於是線上庫表結果與備份庫表結構的對應關系為:

Inception的備份服務器

圖2 Inception的備份服務器

 

-未完待續-

參考資源:

1,Inception使用規范及說明文檔

2,2014,isadba,pt-online-schema-change工具文藝用法;

3,2014,博客園-王滔,mysql在線修改表結構大數據表的風險與解決辦法歸納

4,2011,楊挺,OSC 實現原理剖析

5,2015,鄭昀,#研發解決方案#iDB-數據庫自動化運維平台

歡迎訂閱我的微信訂閱號『老兵筆記』,請掃描二維碼關注:
老兵筆記訂閱號二維碼
轉載時請注明“轉載自旁觀者-博客園”或者給出本文的原始鏈接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM