使用 pt-online-schema-change 實如今線DDL

 

問題背景

平時進行修改表的結構,更改字段,新增字段,更改字段名稱通常都是經過ALTER TABLE  語法進行修改的。對於小表或者併發訪問不是很大的狀況是OK。可是若是是在線大表,那就很麻煩。因爲表數據量大,複製表須要比較長的時間,在這個時間段裏面,表是被加了鎖的(寫鎖),加寫鎖時其餘用戶只能select表不能update、insert表。表數據量越大,耗時越長。html

mysql在線ddl(加字段、加索引等修改表結構之類的操做)過程以下:mysql

  1. 對錶加鎖(表此時只讀)
  2. 複製原表物理結構
  3. 修改表的物理結構
  4. 把原表數據導入中間表中,數據同步完後,鎖定中間表,並刪除原表
  5. rename中間表爲原表
  6. 刷新數據字典,並釋放鎖

可見,在這個過程當中會鎖表。形成當前操做的表沒法寫入數據,影響用戶使用。因爲須要複製原表的數據到中間表,因此表的數據量越大,等待的時候越長,卡死在那裏(用戶被拒絕執行update和insert操做,表現就是延遲了一直在等待)。sql

 

對於DDL操做一個基本的想法:它的變化是就地執行仍是執行表拷貝, 在命令結束以後看看顯示「rows affected 「的值。例如,這裏您可能會看到在作不一樣類型的DDL操做: 修改列默認值(超級快,不影響表的全部數據): Query OK, 0 rows affected (0.07 sec) 添加索引 (須要時間, 但0 rows affected 代表表沒有被複制): Query OK, 0 rows affected (21.42 sec) 改變列的數據類型(須要大量的時間和須要重建表中的全部行): Query OK, 1671168 rows affected (1 min 35.54 sec) 例如, 在一個大表運行一個DDL操做以前,你可能會檢查操做是將快仍是慢,以下所示: 克隆表結構。 用少許數據填充克隆的表。 在克隆的表運行DDL操做。 檢查 「行受影響」的值是否爲零或不是。一個非零值意味着操做須要重建整個表,這可能須要特殊的規劃。例如,你可能在計劃停機期間作DDL操做,或在複製每一個從服務器。服務器

 

 

解決方案

percona 的 pt-online-schema-change 工具原理:併發

一、若是存在外鍵,根據alter-foreign-keys-method參數的值,檢測外鍵相關的表,作相應設置的處理。
二、建立一個新的表,表結構爲修改後的數據表,用於從源數據表向新表中導入數據。
三、建立觸發器,用於記錄從拷貝數據開始以後,對源數據表繼續進行數據修改的操做記錄下來,用於數據拷貝結束後,執行這些操做,保證數據不會丟失。
四、拷貝數據,從源數據表中拷貝數據到新表中。
五、修改外鍵相關的子表,根據修改後的數據,修改外鍵關聯的子表。
六、rename源數據表爲old表,把新表rename爲源表名,並將old表刪除。
七、刪除觸發器。工具

 

可見,複製表的時候無需加鎖,不影響原表繼續接受寫請求;htm

相關文章
相關標籤/搜索