Postgresql

在將 PostgreSQL 從 9.4 升級到 12 時消除 OID

  • October 20, 2021

我目前在我的生產環境中執行 PostgreSQL 9.4,但我們正在伺服器上進行作業系統升級,所以我認為可能是時候將我們的 PostgreSQL 版本升級到最新版本 (12),這樣我就有可能利用一些可用的新功能。但是,各種數據庫中的一些表是在很久以前建構的(例如在 2008 年之前,至少在某些情況下很可能在 2000 年之前)。這些數據庫包含許多使用 OID 的表(WITH OIDS=TRUE在定義中)。

此外,我已經對大部分程式碼庫進行了搜尋,以查找對任何表中 OID 列的引用,並發現了幾個實例,其中存在顯式呼叫 OID 列的查詢。幸運的是,這些案例並不,而且大多數都引用了系統表(即SELECT oid FROM pg_namespace, ...FROM pg_class)。

pg_upgrade對從我們的 9.4 數據庫轉儲的數據執行該過程在此過程中停止,並明確表示在數據庫沒有 OID 之前它不會繼續。我知道他們在過去的幾個版本中一直在慢慢地逐步淘汰這些,並且 12 使它們基本上無關緊要,但來自的建議pg_upgrade是在繼續之前完全刪除 OID 列。我認為這對於一個幾乎不相關的專欄來說是“矯枉過正”。

在這一點上 - 我欣然承認我還沒有考慮到這一點 - 我想知道是否足以簡單地“翻轉”WITH OIDS受影響的表定義中的開關FALSE以便能夠繼續升級?如果翻轉,現有的 OID 列是否仍是數據庫結構的一部分(我認為它們會,但自動升級可以做一些有趣的事情)?

我意識到,在理想情況下,我希望最終從數據庫中完全消除 OID。但是,作為一個單人 IT 部門,這將不得不“列入”名單以供以後評估。現在,我只想讓數據庫在最新的 PostgreSQL 版本上啟動並執行,同時我有機會這樣做,而不會立即影響操作。

如果oid程式碼中引用了表的 s,則不能簡單地擺脫它們。可能舊程式碼依賴於oid自動生成的標識符。這些列上是否有任何主鍵或其他索引?

oid在升級過程中保留 s 的一種方法是:

  • 升級前,在舊數據庫上:
ALTER TABLE has_oids ADD newoid bigint NOT NULL;
UPDATE has_oids SET newoid = oid;
ALTER TABLE has_oids SET WITHOUT OIDS;
  • 升級後,在新數據庫上:
ALTER TABLE has_oids RENAME newoid TO oid;
CREATE SEQUENCE has_oids_oid_seq OWNED BY has_oids.oid;
ALTER TABLE has_oids ALTER oid SET DEFAULT nextval('has_oids_oid_seq');
SELECT setval('has_oids_oid_seq', ???);

這裡,???是一個高於oid表中最高值的數字。

您還必須處理oid列上的索引或約束。

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