pt-online-change 工具這麼多,哪一個是你的菜?
前言
今天在 ② 羣看到有位同志提到了這樣一個問題:
把 numeric(20,2) 改成 numeric(20,4) 會鎖表嗎?
首先會鎖表肯定是毋庸置疑的,並且是最重的 8 級鎖,其次我們關心的重點應該是,表是否會發生重寫?即改類型是否會導致全表重寫?廢話不多說,一圖勝千言!
在 PostgreSQL 中,大多數操作都是 online 的,不會發生重寫,只會獲取短暫的 8 級鎖,但是始終還是有那麼些例子會導致重寫,比如這位羣友提到的
-
(x,z) to numeric(y,z) when y>=x, or to numeric without specifier,當標度發生變化時(小數點後面的位數),不管精度有沒有變化表都需要重寫。
-
timestamp to text、varchar、varchar(n),char(n)
-
timestamp(x) to text、varchar、varchar(n)、char(n),n>=x
-
text to char、char(x)、varchar(n)
-
int to bigint
以上種種,都會導致表發生重寫。那問題來了,有類似的 pt-online-change 工具可以實現 "無鎖" 轉換嗎?Sure,並且還不少。
pg_migrate
首先是 pg_migrate — Perform schema changes in PostgreSQL with minimal locks,我之前也寫過文章進行介紹,此工具的原理和 pg_repack 異曲同工,創建一個副本,然後捕獲增量變更,最後完成交換,可以參照之前的文章 👉🏻 不要再吐槽沒有 online DDL 了!
pg_osc
pg_osc 的靈感同樣源自於 pg_repack,工作原理也是類似,不過 pg_osc 的安裝編譯教 pg_migrate 要稍複雜一些。
pg-osc
uses the concept of shadow table to perform schema changes. At a high level, it creates a shadow table that looks structurally the same as the primary table, performs the schema change on the shadow table, copies contents from the primary table to the shadow table
另外 pg_osc 支持調整回放的速度,這一點對於高峯期的業務來說,還是很重要的。根據官方文檔
-
Create an audit table to record changes made to the parent table.
-
Acquire a brief
ACCESS EXCLUSIVE
lock to add a trigger on the parent table (for inserts, updates, deletes) to the audit table. -
Create a new shadow table and run ALTER/migration on the shadow table.
-
Copy all rows from the old table.
-
Build indexes on the new table.
-
Replay all changes accumulated in the audit table against the shadow table.
- Delete rows in the audit table as they are replayed.
- Once the delta (remaining rows) is ~20 rows, acquire an ACCESS EXCLUSIVE lock against the parent table within a transaction and:
-
swap table names (shadow table <> parent table).
-
update references in other tables (FKs) by dropping and re-creating the FKs with a
NOT VALID
.
-
Runs
ANALYZE
on the new table. -
Validates all FKs that were added with
NOT VALID
. -
Drop parent (now old) table (OPTIONAL).
可以看到基本就和 pg_migrate 一模一樣,另外,第 9 點的技巧可以推廣到分區表的創建上,十分實用。
pgroll
這一款工具不同於前面兩款,pgroll 的工作原理是在物理表上使用視圖創建虛擬模式。這允許執行遷移所需的所有必要更改,而不會影響現有客戶端,旨在實現無痛的數據庫遷移,確保業務連續性,並且能迅速恢復至前一穩定狀態,降低風險。
其功能更加強大,其設計初衷在於:
-
Locking issues (e.g. on a busy table, in a fast a migration can wait at an exclusive lock and cause downtime)
-
Constraints might require data back-filling (if you add a NOT NULL + UNIQUE column, how do you fill the data?),一些操作需要回填
-
Backwards incompatible changes require a multiple step process (e.g. renames)
首先執行所有非破壞性變更(如添加列、表等),然後在不影響現有應用訪問的前提下,逐步引入破壞性變更,並通過回填操作保持數據一致性。
小結
對於 PostgreSQL 來說,大多數的操作都是 online 的,必要的時候可以藉助以上幾款工具實現 "無鎖" 修改。
最後,設個小小的思考題🤔,pgroll 篇章中提到的回填 (backfill) 是什麼意思?
參考
https://github.com/phillbaker/pg_migrate
https://github.com/shayonj/pg-osc
https://github.com/xataio/pgroll
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/7wyiiBk4rLk8Fo5x5lm0Kg