如何疑難排解 Amazon RDS for PostgreSQL 和 Aurora for PostgreSQL 中的主要版本升級問題?

5 分的閱讀內容
0

Amazon Relational Database Service (Amazon RDS) for PostgreSQL 或 Amazon Aurora PostgreSQL 的引擎版本升級停滯或失敗。

簡短說明

當 Amazon RDS 支援新版資料庫引擎時,您可將資料庫執行個體升級至新版本。您可執行資料庫執行個體的次要版本等級或主要版本升級。

次要版本升級可用來修補安全漏洞並修復錯誤。這些升級通常不會新增任何新功能,也不會變更內部儲存格式。這些升級始終與相同主要版本的較早和更新的次要版本相容。然而,主要版本升級包含無法與現有應用程式舊版相容的資料庫變更。這些升級可能會變更系統表格、資料檔案和資料儲存的內部格式。Amazon RDS 使用 PostgreSQL 公用程式 pg_upgrade 來執行主要版本升級。

在 PostgreSQL 執行個體進行主要版本升級期間,Amazon RDS 會執行預先檢查程序。此程序會識別可能導致升級失敗的任何問題。預先檢查程序會檢查所有資料庫的潛在不相容狀況。如果 Amazon RDS 在預先檢查程序期間發現問題,就會為失敗的預先檢查建立日誌事件。如需有關所有資料庫之預先檢查程序的詳細資訊,請查看 pg_upgrade_precheck.log 升級日誌。Amazon RDS 會在檔案名稱上附加時間戳記。RDS 事件也可能提供升級失敗的原因。但是,對於特定引擎的問題,您必須檢查資料庫日誌檔。

如需詳細資訊,請參閱檢視及列出 RDS for PostgreSQL 的資料庫日誌檔。或者,請參閱檢視和列出 Aurora for PostgreSQL 的資料庫日誌檔

於主要版本升級期間,RDS 會完成這些步驟:

  1. 在升級之前建立執行個體的快照。僅當您將資料庫執行個體的備份保留期設定為大於零的數字時,才會發生這種情況。
  2. 關閉執行個體。
  3. 使用 pg_upgrade 公用程式,在執行個體上執行升級任務。
  4. 升級後,建立執行個體快照。

解決方案

雖然 Amazon RDS 會管理這些升級,但您可能會在版本升級期間遇到下列問題:

  • 升級需要更長的時間。
  • 升級失敗。

升級需要很長時間

**擱置中的維護活動:**任何擱置中的維護活動都會隨引擎版本升級自動套用。這可能包括在 RDS 執行個體上套用作業系統修補程式。在此情況下,會先套用作業系統修補程式,然後再升級引擎版本。所以,執行作業系統維護活動會增加完成升級所需的時間。

此外,若 RDS 執行個體處於多可用區部署中,則作業系統維護會造成容錯移轉。於多可用區域中設定執行個體時,通常會在次要執行個體上建立執行個體的備份。若發生容錯移轉,則於升級後在新的次要執行個體上建立備份。這個在新次要執行個體上的備份可能不是最新的備份。所以可能會觸發完整備份,而非增量備份。建立完整備份可能需要很長時間,特別是在資料庫非常龐大的狀況下。

若要避免此問題,請在 RDS 主控台的 Pending maintenance (擱置中的維護) 部分尋找 pending maintenance activities (擱置中的維護活動)。針對 Aurora for PostgreSQL,請參閱檢視擱置中的維護

或者,使用執行個體上的 AWS Command Line Interface (AWS CLI) 命令 describe-pending-maintenance-actions

aws rds describe-pending-maintenance-actions --resource-identifier example-arn

注意:執行資料庫引擎版本升級之前,請完成這些維護活動。

**升級前未建立快照:**最佳實務是在執行升級之前建立 RDS 的快照或 Aurora for PostgreSQL 叢集快照。若您已開啟執行個體的備份,則會在升級程序中自動建立快照。在升級前建立快照可縮短完成升級程序所需的時間。這是因為在此情況下,只會在升級程序期間建立增量備份。

**RDS for PostgreSQL 僅供讀取複本升級:**執行主要資料庫執行個體的主要版本升級時,相同區域中的所有僅供讀取複本會自動升級。升級工作流程啟動後,僅供讀取複本會等待在主資料庫執行個體上順利完成的 pg_upgrade。然後,主要執行個體升級會等待僅供讀取複本升級完成。在完成所有升級之前,您會遇到中斷的情況。如果升級的停機時間範圍有限,您可以提升或刪除複本執行個體。然後,在升級完成後重新建立僅供讀取複本

為了安全地升級組成叢集的資料庫執行個體,Aurora for PostgreSQL 使用 pg_upgrade 公用程式。寫入器升級完成後,每個讀取器執行個體在升級至新的主要版本時,都會遭遇短暫中斷。

**升級前長期執行的交易或高工作負載:**升級前長期執行的交易或高工作負載可能會增加關閉資料庫所需的時間,並增加升級時間。

執行此查詢以識別長期執行的交易:

SQL>SELECT pid, datname, application_name, state, 
age(query_start, clock_timestamp()), usename, query 
FROM pg_stat_activity 
WHERE query NOT ILIKE '%pg_stat_activity%' AND 
usename!='rdsadmin' 
ORDER BY query_start desc;

**運算容量不足:**pg_upgrade 公用程式為密集型運算。因此,最佳實務是在升級生產資料庫之前執行試執行升級。您可還原生產執行個體的快照,並使用與生產資料庫相同的執行個體類別執行試執行。

升級失敗

**不支援的資料庫執行個體類別:**若資料庫執行個體的執行個體類別與您要升級的 PostgreSQL 版本不相容,則升級可能會失敗。請務必檢查執行個體類別與引擎版本的相容性。如需詳細資訊,請參閱 RDS for PostgreSQL 的資料庫執行個體類別支援的資料庫引擎。或者,請檢閱 Aurora for PostgreSQL 的資料庫執行個體類別支援的資料庫引擎

**開啟備妥的交易:**在資料庫上開啟的備妥交易可能會造成升級失敗。於開始升級之前,請務必確認或回復所有開啟的備妥交易。

執行此查詢檢查執行個體上是否有開啟的備妥交易:

SELECT count(*) FROM pg_catalog.pg_prepared_xacts;

於此情況下,pg_upgrade.log 檔案中的錯誤看起來與此內容相似:

------------------------------------------------------------------------
Upgrade could not be run on Wed Apr 4 18:30:52 2018
-------------------------------------------------------------------------
The instance could not be upgraded from 9.6.11 to 10.6 for the following reasons.
Please take appropriate action on databases that have usage incompatible with 
the requested major engine version upgrade and try the upgrade again.

*There are uncommitted prepared transactions. Please commit or rollback 
all prepared transactions.*

**不支援的資料類型:**若您嘗試使用不支援的資料類型來升級資料庫,則升級會失敗並顯示錯誤,如下所示:

  • regcollation
  • regconfig
  • regdictionary
  • regnamespace
  • regoper
  • regoperator
  • regproc
  • regprocedure

**注意:**支援的資料類型為 regclass、regrole 和 regtype。

PostgreSQL 升級公用程式 pg_upgrade 並不支援升級包含使用 reg* OID 參照系統資料類型之資料表欄的資料庫。在嘗試升級之前,請移除 reg* 資料類型的所有用法,regclass、regrole 和 regtype 除外。

執行此查詢,以驗證不受支援之 reg* 資料類型的使用狀況:

SELECT count(*) FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n, pg_catalog.pg_attribute a
  WHERE c.oid = a.attrelid
      AND NOT a.attisdropped
      AND a.atttypid IN ('pg_catalog.regproc'::pg_catalog.regtype,
                         'pg_catalog.regprocedure'::pg_catalog.regtype,
                         'pg_catalog.regoper'::pg_catalog.regtype,
                         'pg_catalog.regoperator'::pg_catalog.regtype,
                         'pg_catalog.regconfig'::pg_catalog.regtype,
                         'pg_catalog.regdictionary'::pg_catalog.regtype)
      AND c.relnamespace = n.oid
      AND n.nspname NOT IN ('pg_catalog', 'information_schema');

**邏輯複寫插槽:**若您的執行個體備有任何邏輯複寫插槽,則無法進行升級。邏輯複寫插槽通常用於 AWS Database Migration Service (AWS DMS) 遷移。邏輯複寫插槽也可用於將資料庫中的資料表複製到資料湖、商業智慧工具和其他目標。升級之前,請確保您知道正在使用的邏輯複寫插槽用途,並確認可將其刪除。

若邏輯複寫插槽仍在使用中,您無法將其刪除。於此狀況下,您無法繼續進行升級。

pg_upgrade 日誌檔中的相關錯誤看起來與此內容相似:

"The instance could not be upgraded because one or more databases have logical replication slots. Please drop all logical replication slots and try again."

若不需要邏輯複寫插槽,請執行這些查詢以將其刪除:

SELECT * FROM pg_replication_slots;
SELECT pg_drop_replication_slot(slot_name);

**儲存問題:**當 pg_upgrade 指令碼執行時,執行個體可能會空間不足。這會造成指令碼失敗,而且您會看到類似下此內容的錯誤訊息:

pg_restore: [archiver (db)] Error while PROCESSING TOC: 
pg_restore: [archiver (db)] could not execute query: ERROR: could not create file "base/12345/12345678": No space keyword" left  on device

若要解決此問題,請確定執行個體有足夠的可用儲存空間,然後再開始升級。

未知的資料類型:PostgreSQL 版本 10 及更新版本不支援未知的資料類型。若 PostgreSQL 9.6 版資料庫使用未知的資料類型,升級至版本 10 會顯示類似此內容的錯誤訊息:

"The instance could not be upgraded because the 'unknown' data type is used in user tables. Please remove all usages of the 'unknown' data type and try again."

此為 PostgreSQL 限制,RDS 自動化不會修改使用未知的資料類型欄。您可能需要在升級之前手動修改這些欄。

執行此查詢,於資料庫中尋找具未知資料類型的欄:

SELECT DISTINCT data_type FROM information_schema.columns WHERE data_type ILIKE 'unknown';

識別欄之後,您可移除這些欄或將其修改為支援的資料類型。

**僅供讀取複本升級失敗 (僅限 RDS for PostgreSQL):**PostgreSQL 執行個體具有僅供讀取複本,然後僅供讀取複本升級失敗可能會導致主要執行個體升級停滯。僅供讀取複本升級失敗也可能造成主執行個體升級失敗。失敗的僅供讀取複本會處於 incompatible-restore 狀態,並在資料庫執行個體上停止複寫。

僅供讀取複本升級可能會因下列其中一項原因而失敗:

  • 即使在等待時間之後,僅供讀取複本仍無法掌握主要資料庫執行個體。
  • 僅供讀取複本處於終端機或不相容的生命週期狀態,例如 storage-full 或 incompatible-restore。
  • 主資料庫執行個體升級開始後,僅供讀取複本上正在執行個別的次要版本升級。
  • 僅供讀取複本使用不相容的參數。
  • 僅供讀取複本無法與主資料庫執行個體通訊以同步資料的資料夾。

若要解決此問題,請刪除僅供讀取複本。然後,在主要執行個體升級後,根據升級後的主要執行個體重新建立新的僅供讀取複本。

**不正確的主要使用者名稱:**若主要使用者名稱以 "pg_" 開頭,則升級會失敗,而且您會看到下列錯誤訊息:

PreUpgrade checks failed: The instance could not be upgraded because one or more role names start with 'pg_'. Please rename  all roles with names that start with 'pg_' and try again

如要解決此問題,請建立另一個具有 rds_superuser 角色的使用者。您可聯絡 AWS Support,將此使用者更新為新的主要使用者。

**不相容的參數錯誤:**若將記憶體相關參數 (例如 shared_bufferwork_memory) 設定為較高的值,則會發生此錯誤。這可能會導致升級指令碼失敗。如要修正此問題,請減少這些參數的值,然後嘗試再次執行升級。

**擴充功能並未在升級前更新:**主要版本升級不會升級任何 PostgreSQL 擴充功能。若您在執行主要版本升級之前並未更新擴充功能,則會在 pg_upgrade.log 檔案中看到此錯誤:

The Logs indicates that the RDS instance ''xxxx'' has older version of PostGIS extension or its dependent extensions (address_standardizer,address_standardizer_data_us, postgis_tiger_geocoder, postgis_topology, postgis_raster) installed as against the current version required for the upgrade.

此錯誤訊息表示 PostGIS 擴充功能有問題。

執行此查詢,以檢查 PostGIS 及其相關擴充功能的預設和安裝版本:

SELECT name, default_version, installed_version
FROM pg_available_extensions WHERE installed_version IS NOT NULL AND
name LIKE 'postgis%' OR name LIKE 'address%';

如果 installed_version 的值小於 default_version 的值,則您必須將 PostGIS 更新為預設版本。若要這樣做,請執行此查詢:

ALTER EXTENSION extension_name UPDATE TO 'default_version_number';

如需詳細資訊,請參閱升級 RDS for PostgreSQL 的 PostgreSQL 擴充功能升級 Aurora PostgreSQL 的 PostgreSQL 擴充功能

**因目標版本的系統目錄發生變更造成檢視中的問題:**特定檢視中的欄會因不同的 PostgreSQL 版本而有所不同。

例如,您可能會看到這樣的錯誤訊息:

PreUpgrade checks failed: The instance could not be upgraded because one or more databases have views or materialized views which depend on 'pg_stat_activity'. Please drop them and try again.

當您將資料庫從 9.5 版升級至 9.6 時,就會發生此錯誤。此錯誤是由於 pg_stat_activity 檢視所造成,因為於 9.6 版中,waiting (等待) 欄將為 wait_event_typewait_event 欄所取代。

pg_restore: from TOC entry xxx; xxx xxxx VIEW sys_user_constraints art 
pg_restore: error: could not execute query: ERROR: column c.consrc does not exist LINE 18: "c"."consrc" AS "search_condition", ^ HINT: Perhaps you meant to reference the column "c.conkey" or the column "c.conbin".

之所以發生此錯誤,是因為目錄 pg_constraint 的結構已於 PostgreSQL 版本 12 中變更。

您可以藉由依目標版本的系統目錄捨棄檢視來解決這些問題。

**注意:**捨棄這些檢視時請小心。請務必諮詢您的 DBA。

其他考量

  • pg_upgrade 公用程式會產生兩個日誌:pg_upgrade_internal.logpg_upgrade_server.log。Amazon RDS 會在這些日誌的檔案名稱上附加時間戳記。檢視這些日誌,可取得有關升級期間所遇到問題和錯誤的詳細資訊。如需詳細資訊,請參閱監控 RDS for PostgreSQL 的 Amazon RDS 日誌檔監控 Aurora for PostgreSQL 的 Amazon Aurora 日誌檔
  • 升級完成後,請在所有使用者資料庫上執行 ANALYZE 來升級 pg_statistics 表格。主要升級不會將 pg_statistics 表格內容移至新版本。略過此步驟可能會造成查詢執行緩慢。
  • 如果您升級到 PostgreSQL 版本 10,請在您擁有的任何雜湊索引上執行 REINDEX。雜湊索引在版本 10 中已變更,且必須重建。若要尋找無效的雜湊索引,請針對每個包含雜湊索引的資料庫執行此 SQL:
SELECT idx.indrelid::regclass AS table_name, 
   idx.indexrelid::regclass AS index_name 
FROM pg_catalog.pg_index idx
   JOIN pg_catalog.pg_class cls ON cls.oid = idx.indexrelid 
   JOIN pg_catalog.pg_am am ON am.oid = cls.relam 
WHERE am.amname = 'hash' 
AND NOT idx.indisvalid;

相關資訊

升級 PostgreSQL 概觀

Aurora PostgreSQL 升級程序概觀

AWS 官方
AWS 官方已更新 1 年前