簡體   English   中英

如何在零停機時間的情況下向生產 PostgreSQL 的表中添加列?

[英]How to add a column to a table on production PostgreSQL with zero downtime?

這里https://stackoverflow.com/a/53016193/10894456是為 Oracle 11g 提供的答案,我的問題是一樣的:

當該表包含一百萬條記錄並且它處於活動狀態時,在生產 oracle 數據庫中添加具有默認值的非 null 列的最佳方法是什么。 如果我們創建列,添加默認值並在單個語句中使其不是 null,它會創建任何鎖嗎?

但是對於 PostgreSQL?

這個先前的答案基本上回答了您的查詢。

相關 PostgreSQL 文檔與上述答案中提到的 AlterTableGetLockLevel 的AlterTableGetLockLevel源代碼交叉引用表明ALTER TABLE... ADD COLUMN將始終獲得一個ACCESS EXCLUSIVE表鎖,從而阻止任何其他事務在ADD COLUMN的持續時間內訪問該表手術。 對於任何ADD COLUMN變體,都會獲得相同的排他鎖; IE。 添加NULL列(帶或不帶DEFAULT )或具有默認值的NOT NULL都沒有關系。

但是,如上面鏈接的答案中所述,添加沒有DEFAULTNULL列應該非常快,因為此操作只會更新目錄。

相反,添加帶有DEFAULT說明符的列需要在 PostgreSQL 10 或更少中重寫整個表。 此操作可能會在您的 1M 記錄表上花費相當長的時間。 根據鏈接的答案, PostgreSQL >= 11 不需要這樣的重寫來添加這樣的列,因此應該與非DEFAULT情況更相似。

我應該補充一點,對於 PostgreSQL 11 及更高版本, ALTER TABLE文檔指出,只有非易失性DEFAULT說明符才能避免表重寫:

當使用 ADD COLUMN 添加列並指定非易失性 DEFAULT 時,會在執行語句時評估默認值,並將結果存儲在表的元數據中。 該值將用於所有現有行的列。 如果未指定 DEFAULT,則使用 NULL。 在這兩種情況下都不需要重寫表。

添加具有 volatile DEFAULT [...] 的列將需要重寫整個表及其索引。 [...] 表和/或索引重建可能需要大量時間來處理大型表; 並且將暫時需要兩倍的磁盤空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM