iDB是如何運轉的 一

鄭昀 建立於2015/12/2 最後更新於2015/12/4 html

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


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

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

 

0x00,普通DBA和文藝DBA怎麼作SQL審覈

不管是 DDL 操做,仍是數據訂正(也被稱爲 DML 操做),都涉及 SQL 審覈、預執行和數據備份及回滾。 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-數據庫自動化運維平臺

相關文章
相關標籤/搜索