Postgresql

轉換 postgres varchar到文本無需停機

  • June 9, 2021

正如我在研究這個問題時發現的那樣,將列從 轉換varchar(100)[]text[]需要表重寫和重建索引。

有沒有一種方法可以管理這種轉換,而無需像這個問題中使用的那樣通過一些目錄詭計進行鎖定和重寫?如果可能的話,對第 10 版特別感興趣

應該適用於簡單的目錄修改,因為textvarchar是相同的:

UPDATE pg_attribute
SET atttypid = 'text[]'::regtype, atttypmod = -1
WHERE attrelid = 'mytable'::regclass AND attname = 'mycolumn';

但是,如您所知,目錄修改不受支持,如果我忘記了某些內容並且它損壞了,您可能會遇到麻煩。

RDS 不支持目錄修改,因此必須手動執行此操作 :( 以下是要遵循的步驟,改編自這篇文章。從orig_column更改varchar(100)[] not nulltext[] not null

  1. 至少升級到版本 12
  2. 創建一個text[]名為 的列new_column,它允許空值
  3. 創建BEFORE UPDATEBEFORE INSERT触發器複製orig_columnnew_column和復製orig_columnold_column(見底部的程式碼)
  4. 更新現有行以new_column填寫orig_column
  5. 使用創建任何索引的副本,orig_column但同時使用new_column
  6. 添加 CHECK 約束(new_column IS NOT NULL),延遲驗證
  7. 驗證約束
  8. 更新new_columnNOT NULL
  9. 刪除 CHECK 約束
  10. 在表上鎖定的 trxACCESS EXCLUSIVE中,將列重命名為old_columnorig_column
  11. 設置old_column為可為空
  12. 放下觸發器
  13. 刪除old_column 同時引用的索引
  14. 降低old_column
  15. (可選)重命名索引以匹配以前的命名約定

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;

引用自:https://dba.stackexchange.com/questions/293906