pt-online-schema-change 如何確保數據複製期間的一致性
我已閱讀
pt-online-schema-change
文件並了解它通過在塊時間秒內創建觸發器和複製數據塊(預設為 0.5 秒)來工作讓我們考慮以下情況。
> > 我們有一個 5 GB 的表 TBL1,正在使用 PT-ONLINE-SCHEMA-CHANGE 進行更改 > > >
PT-ONLINE-SCHEMA-CHANGE 創建了具有所需更改的新表,在 TBL1 上添加了觸發器並開始複製。
> > 複製了 10 個數據塊並開始複製第 11 個數據塊,大小為“X”MB。根據工具,此塊最多可在 500 毫秒或 0.5 秒內複製 > > >
在第 11 個塊複製期間,應用程序發出了一個 UPDATE,它必須修改作為第 11 個數據塊一部分的效果行。
我的問題是現在發生了以下哪些事情。現在的原始表?
A) Update will be blocked till the chunk be copied and then applied on original table which gets updated through triggers on new one. B) Update will be performed on original table and data chunk will be re copied all over again.
如果選項 A 是答案,那麼如何 PT-ONLINE-SCHEMA-CHANGE 可以無鎖?
如果選項 B 是答案,它如何知道被複製的塊被修改了?
提前致謝。
pt-online-schema-change 利用了關係數據庫在表級別的一致性特性。讓我們看看當我們寫入原始表時會發生什麼,這是三種情況之一:
- 該塊已被複製。沒問題,觸發器會覆蓋事務中附件表的值
- 該塊尚未被複製。**
IGNORE
**觸發器可能會失敗,但由於觸發器上的選項,原始修改將完成INSERT/UPDATE/DELETE
。沒問題,當 pt-osc 程序到達它時,它會複製較新的值。- 你的問題。正在複製該塊。有 2 個子情況,具體取決於哪個過程首先開始。
a) 如果原始表的修改首先開始,則整個表(在 MyISAM 的情況下)或行集(在 InnoDB 的情況下)將被鎖定以進行其他修改,因此 pt-osc 將不得不等待寫入完成。您應該避免在此工具工作時非常耗時的寫入操作,或者在負載過高時依靠它來暫停,但不幸的是,您正在同時進行另一個大型更新,會話變數
innodb_lock_wait_timout
(由pt-osc 的參數lock-wait-timeout
,預設為 1 秒)應該啟動並恢復/中止該塊的副本。在這種情況下,該工具將再次重試該塊--retries
次(預設值,3),否則整個過程將在理論上優雅地中止。在大多數情況下,一旦鎖消失(因為並發寫入完成),您將基本上處於案例 2。b) 如果 pt-osc 先啟動,它本質上會再次鎖定整個表(在 MyISAM 中)或那些特定的行(在 InnoDB 中)以進行寫入(讀鎖),防止並發寫入。理想情況下,這最多只能保持 0.5 秒,因為已經計算了塊大小,因此塊複製不應超過此時間。完成後,您基本上處於案例 1 中。
所以,是的,沒有 100% 無鎖的工具,但是如果你想保證一致性,就不存在這樣的工具。即使重命名表過程也需要幾微秒(畢竟,必須在磁碟上重命名一個/幾個文件),並且對於這些微秒,表將被鎖定。這個想法是有最小數量的鎖定。對於 MyISAM,每次寫入一行(並發插入除外)時,整個表都會被鎖定,而對於 InnoDB,至少是該特定行(有時更多)。除非您犧牲更改的原子性和持久性,否則您無法更改它。但是,您可以考慮一些技巧來最大程度地減少其問題:
- 使用 InnoDB 而不是 MyISAM 以獲得額外的寫入並發性
- 避免在復製過程中對該表進行慢速/大型寫入事務
- 降低塊時間參數的值。在極端情況下,您可以將塊大小設置為 1,一次複製並鎖定一行,但這會非常慢。當您碰巧寫入當時正在複製的確切行時,塊時間將是最大鎖定時間的啟發式最壞情況。
- MySQL 5.6 允許在某些 DDL 執行時進行並發寫入。它不太靈活,但它應該可以更快地工作,因為它可以訪問底層邏輯。在某些情況下,這可能會更好,但在執行太多並發寫入時會遇到類似的問題(因為這些會被緩衝)。
閱讀該工具的程式碼並不難,我邀請您閱讀它以獲取更多資訊。