Postgresql
轉換 postgres varchar到文本無需停機
正如我在研究這個問題時發現的那樣,將列從 轉換
varchar(100)[]
為text[]
需要表重寫和重建索引。有沒有一種方法可以管理這種轉換,而無需像這個問題中使用的那樣通過一些目錄詭計進行鎖定和重寫?如果可能的話,對第 10 版特別感興趣
這應該適用於簡單的目錄修改,因為
text
和varchar
是相同的:UPDATE pg_attribute SET atttypid = 'text[]'::regtype, atttypmod = -1 WHERE attrelid = 'mytable'::regclass AND attname = 'mycolumn';
但是,如您所知,目錄修改不受支持,如果我忘記了某些內容並且它損壞了,您可能會遇到麻煩。
RDS 不支持目錄修改,因此必須手動執行此操作 :( 以下是要遵循的步驟,改編自這篇文章。從
orig_column
更改varchar(100)[] not null
為text[] not null
:
- 至少升級到版本 12
- 創建一個
text[]
名為 的列new_column
,它允許空值- 創建
BEFORE UPDATE
和BEFORE INSERT
触發器複製orig_column
到new_column
和復製orig_column
到old_column
(見底部的程式碼)- 更新現有行以
new_column
填寫orig_column
- 使用創建任何索引的副本,
orig_column
但同時使用new_column
- 添加 CHECK 約束
(new_column IS NOT NULL)
,延遲驗證- 驗證約束
- 更新
new_column
為NOT NULL
- 刪除 CHECK 約束
- 在表上鎖定的 trx
ACCESS EXCLUSIVE
中,將列重命名為old_column
和orig_column
- 設置
old_column
為可為空- 放下觸發器
- 刪除
old_column
同時引用的索引- 降低
old_column
- (可選)重命名索引以匹配以前的命名約定
CREATE OR REPLACE FUNCTION some_function_name() RETURNS trigger AS $$ BEGIN IF (to_jsonb(NEW) ? 'new_column' AND NEW.new_column IS NULL) THEN NEW.new_column = NEW.orig_column; END IF; IF (to_jsonb(NEW) ? 'old_column' AND NEW.old_column IS NULL) THEN NEW.old_column = NEW.orig_column; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;