就地升级数据库主要版本

本页面介绍了如何通过就地升级 Cloud SQL 实例而不是通过迁移数据来升级数据库主要版本。

简介

数据库软件提供商会定期发布包含新功能、性能改进和安全增强功能的新主要版本。Cloud SQL 会在新版本发布后进行提取。Cloud SQL 为新的主要版本提供支持后,您可以升级实例以使数据库保持最新。

您可以就地升级实例的数据库版本,也可以通过迁移数据。就地升级是较简单的升级实例主要版本的方法。您无需迁移数据或更改应用连接字符串。通过就地升级,您可以在升级后保留当前实例的名称、IP 地址和其他设置。就地升级不需要移动数据文件,可以更快地完成。在某些情况下,停机时间比迁移数据所需的短。

Cloud SQL for PostgreSQL 就地升级操作使用 pg_upgrade 实用程序。

规划主要版本升级

  1. 选择目标主要版本。

    gcloud

    如需了解如何安装和开始使用 gcloud CLI,请参阅安装 gcloud CLI。如需了解如何启动 Cloud Shell,请参阅使用 Cloud Shell

    如需检查可进行就地升级的目标数据库版本,请执行以下操作:

    1. 运行以下命令:
    2. gcloud sql instances describe INSTANCE_NAME
         

      INSTANCE_NAME 替换为实例名称。

    3. 在命令的输出中,找到标记为 upgradableDatabaseVersions 的部分。
    4. 每个子部分都会返回一个可升级的数据库版本。在每个子部分中,请查看以下字段。
      • majorVersion:可进行就地升级的目标主要版本。
      • name:包含主要版本的数据库版本字符串。
      • displayName:数据库版本的显示名称。

    REST v1

    如需检查哪些目标数据库版本可进行主要版本就地升级,请使用 Cloud SQL Admin API 的 instances.get 方法。

    在使用任何请求数据之前,请先进行以下替换:

    • INSTANCE_NAME:实例名称。

    HTTP 方法和网址:

    GET https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_NAME

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

    
    upgradableDatabaseVersions:
    
    {
      major_version: "POSTGRES_15_0"
      name: "POSTGRES_15_0"
      display_name: "PostgreSQL 15.0"
    }
    
    

    REST v1beta4

    如需检查哪些目标数据库版本可进行实例的主要版本就地升级,请使用 Cloud SQL Admin API 的 instances.get 方法。

    在使用任何请求数据之前,请先进行以下替换:

    • INSTANCE_NAME:实例名称。

    HTTP 方法和网址:

    GET https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_NAME

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

    
    upgradableDatabaseVersions:
    
    {
      major_version: "POSTGRES_15_0"
      name: "POSTGRES_15_0"
      display_name: "PostgreSQL 15.0"
    }
    
    

    如需查看 Cloud SQL 支持的数据库版本的完整列表,请参阅数据库版本和版本政策

  2. 请考虑每个数据库主要版本中提供的功能并解决不兼容问题。

    新的主要版本引入了不兼容的更改,可能需要您修改应用代码、架构或数据库设置。请先查看目标主要版本的版本说明,以确定您必须解决的不兼容问题,然后才能升级数据库实例。

  3. 通过试运行测试升级。

    在升级生产数据库之前,请先在测试环境中执行端到端升级流程的试运行。您可以克隆实例,创建用于测试升级过程的数据的相同副本。

    除了验证升级是否成功完成之外,运行测试还可以确保应用在升级后的数据库上按预期运行。

  4. 确定升级时间。

    升级要求实例在一段时间内不可用。计划在数据库活动较少的时间段内升级。

准备主要版本升级

在升级之前,请完成以下步骤。

  1. 检查 templatepostgres 数据库的 LC_COLLATE 值。每个数据库的字符集都必须是 en_US.UTF8

    如果 templatepostgres 数据库的 LC_COLLATE 值不是 en_US.UTF8,则主要版本升级将失败。如需解决此问题,如果任一数据库的字符集不是 en_US.UTF8,请在执行升级之前将 LC_COLLATE 值更改为 en_US.UTF8

    如需更改数据库的编码,请执行以下操作:

    1. 转储数据库。
    2. 删除数据库。
    3. 使用不同的编码(在此示例中为 en_US.UTF8)创建新数据库。
    4. 重新加载数据。

    另一种方法是重命名数据库:

    1. 关闭与数据库的所有连接。
    2. 重命名数据库。
    3. 更新应用配置以使用新的数据库名称。
    4. 使用默认编码创建一个新的空数据库。

    我们建议您先在克隆的实例上执行这些步骤,然后再将其应用于生产实例。

  2. 管理您的读取副本。

    Cloud SQL for PostgreSQL 不支持跨版本复制,这意味着,当主实例复制到读取副本时,您无法升级主实例。在升级之前,请为每个读取副本停用复制功能或删除读取副本。

  3. 如果 Cloud SQL 是逻辑复制源,请按如下方式停用 pglogical 扩展程序复制。您可以在升级后重新启用它。如果 Cloud SQL 是逻辑复制目标,则不需要执行这些步骤。
    1. 停用订阅,并使用以下命令断开副本与提供商之间的连接:
      SELECT * FROM pglogical.alter_subscription_disable(subscription_name name, immediate bool);

      name 替换为现有订阅的名称。

      如果需要立即停用订阅,请将 immediate 参数的值设置为 true。默认情况下,值为 false,并且订阅仅在当前事务结束后停用。

      例如:

      postgres=> SELECT * FROM pglogical.alter_subscription_disable('test_sub', true);
       alter_subscription_disable
      ----------------------------
       t
      (1 row)
    2. 通过连接到发布者或 Cloud SQL 主实例并运行以下命令来删除复制槽:
      SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots
        WHERE slot_name IN (SELECT slot_name FROM pg_replication_slots);

      例如:

      postgres=> SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots
      postgres->    WHERE slot_name IN (SELECT slot_name FROM pg_replication_slots);
      -[ RECORD 1 ]------------+-
      pg_drop_replication_slot |
      
      postgres=>
  4. 管理其余的 PostgreSQL 扩展程序

    大多数扩展程序适用于升级后的数据库主要版本。删除目标版本中不再受支持的任何扩展程序。例如,如果您要升级到 PostgreSQL 11 或更高版本,请删除 chkpass 扩展程序。

    您可以手动将 PostGIS 及其相关扩展程序升级到最新支持的版本。

    有时,如果从 PostGIS 2.x 版进行升级,可能会导致剩余数据对象未与 PostGIS 扩展程序关联的情况。这可能会阻止升级操作。如需了解如何解决此问题,请参阅修复损坏的 postgis 光栅安装

    有时,由于对象使用了已弃用的函数,因此升级到 PostGIS 3.1.7 版或更高版本无法完成。这可能会阻止升级操作。如需检查升级状态,请运行 SELECT PostGIS_full_version();。如果存在警告,请删除使用已弃用的函数的所有对象,并将 PostGIS 扩展程序更新到任何中间版本或更高版本。完成这些操作后,请再次运行 SELECT PostGIS_full_version(); 命令。验证系统是否未显示任何警告。然后,继续执行升级操作。

    如需详细了解如何升级 PostGIS 扩展程序,请参阅升级 PostGIS。如需了解与升级 PostGIS 相关的问题,请参阅检查 PostgreSQL 实例的版本
  5. 管理自定义数据库标志。检查您为 PostgreSQL 实例配置的任何自定义数据库标志的名称。如需了解与这些标志相关的问题,请参阅检查 PostgreSQL 实例的自定义标志
  6. 从一个主要版本升级到另一个主要版本时,请尝试连接到每个数据库,看看是否存在任何兼容性问题。确保数据库可以相互连接。检查每个数据库的 datallowconn 字段,确保允许建立连接。t 值表示允许,f 值表示无法建立连接。
  7. 如果您使用 Datadog 安装将 Cloud SQL 实例升级到 PostgreSQL 10 或更高版本,请在执行升级之前丢弃 pg_stat_activity() 函数。

已知限制

以下限制会影响 Cloud SQL for PostgreSQL 的主要版本就地升级:

  • 您不能对外部副本执行主要版本就地升级。
  • 将具有超过 1,000 个数据库的实例从一个版本升级到另一个版本可能需要很长时间并超时。
  • 使用 select * from pg_largeobject_metadata; 语句查询 Cloud SQL 实例的每个 PostgreSQL 数据库中的大型对象的数量。如果所有数据库的结果超过 1000 万个大型对象,则升级会失败。Cloud SQL 会回滚到数据库的旧版本。
  • 在执行到 PostgreSQL 16 及更高版本的主要版本就地升级之前,请将所有数据库的 PostGIS 扩展程序升级到 3.4.0 版。
  • 如果您使用的是 PostgreSQL 9.6、10、11 或 12 版,则不支持 PostGIS 扩展程序 3.4.0 版。因此,如需执行到 PostgreSQL 16 及更高版本的主要版本就地升级,您必须先升级到 PostgreSQL 的中间版本(版本 13、14 或 15)。
  • 如果您为实例安装了 pgRoutingpg_squeeze 扩展程序,则无法执行主要版本升级。如需解决此问题,请卸载这些扩展程序,然后执行升级。如需详细了解这些扩展程序,请参阅配置 PostgreSQL 扩展程序

  • 如果您启用了 vacuum_defer_cleanup_ageforce_parallel_mode 标志,则无法执行主要版本升级。如需解决此问题,请删除这些标志,然后执行升级。如需详细了解这些标志(包括如何删除它们),请参阅配置数据库标志

就地升级数据库主要版本

启动升级操作时,Cloud SQL 首先会检查实例的配置,以确保实例与升级兼容。验证配置后,Cloud SQL 会将实例设为不可用,进行升级前备份,执行升级,使实例可用,然后在升级后进行备份。

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 点击修改
  4. 实例信息部分中,点击升级按钮并确认您想要进入升级页面。
  5. 选择数据库版本页面上,点击要升级到的数据库版本列表,然后选择一个可用的数据库主要版本。
  6. 点击继续
  7. 实例 ID 框中,输入实例的名称,然后点击开始升级按钮。
此操作需要几分钟才能完成。

验证升级后的数据库主要版本是否显示在实例概览页面上的实例名称下方。

gcloud

  1. 开始升级。

    使用带有 --database-version 标志的 gcloud sql instances patch 命令。

    在运行该命令之前,请替换以下项:

    • INSTANCE_NAME:实例的名称。
    • DATABASE_VERSION:数据库主要版本的枚举(必须高于当前版本)。为主要版本指定一个可用作实例升级目标的数据库版本。您可以将此枚举作为规划升级的第一步来获取。如果您需要完整的数据库版本枚举列表,请参阅 SqlDatabaseEnums
    gcloud sql instances patch INSTANCE_NAME \
    --database-version=DATABASE_VERSION

    主要版本升级需要几分钟才能完成。您可能会看到一条消息,指示操作所花的时间超出了预期。您可以忽略此消息,也可以运行 gcloud sql operations wait 命令来关闭该消息。

  2. 获取升级操作名称。

    使用带有 --instance 标志的 gcloud sql operations list 命令。

    在运行命令之前,请将 INSTANCE_NAME 变量替换为实例名称。

    gcloud sql operations list --instance=INSTANCE_NAME
  3. 监控升级的状态。

    使用 gcloud sql operations describe 命令。

    在运行该命令之前,请将 OPERATION 变量替换为上一步中检索到的升级操作名称。

    gcloud sql operations describe OPERATION

REST v1

  1. 开始就地升级。

    将 PATCH 请求与 instances:patch 方法搭配使用。

    在使用任何请求数据之前,请先替换以下变量:

    • PROJECT_ID:项目的 ID。
    • INSTANCE_NAME:实例的名称。

    HTTP 方法和网址:

    PATCH https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_NAME

    请求 JSON 正文:

    {
      "databaseVersion": DATABASE_VERSION
    }

    DATABASE_VERSION 替换为数据库主要版本的枚举(必须高于当前版本)。为主要版本指定一个可用作实例升级目标的数据库版本。您可以将此枚举作为规划升级的第一步来获取。如果您需要完整的数据库版本枚举列表,请参阅 SqlDatabaseVersion

  2. 获取升级操作名称。

    PROJECT_ID 替换为项目的 ID 后,使用 GET 请求和 operations.list 方法。

    HTTP 方法和网址:

    GET https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations
  3. 监控升级的状态。

    替换以下变量后,使用带有 operations.get 方法的 GET 请求:

    • PROJECT_ID:项目的 ID。
    • OPERATION_NAME:上一步中检索的升级操作名称。

    HTTP 方法和网址:

    GET https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operation/OPERATION_NAME

Terraform

如需更新数据库版本,请使用 Terraform 资源和适用于 Google Cloud 的 Terraform 提供程序 4.34.0 版或更高版本

resource "google_sql_database_instance" "instance" {
  name             = "postgres-instance"
  region           = "us-central1"
  database_version = "POSTGRES_14"
  settings {
    tier = "db-custom-2-7680"
  }
  # set `deletion_protection` to true, will ensure that one cannot accidentally delete this instance by
  # use of Terraform whereas `deletion_protection_enabled` flag protects this instance at the GCP level.
  deletion_protection = false
}

应用更改

如需在 Google Cloud 项目中应用 Terraform 配置,请完成以下部分中的步骤。

准备 Cloud Shell

  1. 启动 Cloud Shell
  2. 设置要在其中应用 Terraform 配置的默认 Google Cloud 项目。

    您只需为每个项目运行一次以下命令,即可在任何目录中运行它。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 配置文件中设置显式值,则环境变量会被替换。

准备目录

每个 Terraform 配置文件都必须有自己的目录(也称为“根模块”)。

  1. Cloud Shell 中,创建一个目录,并在该目录中创建一个新文件。文件名必须具有 .tf 扩展名,例如 main.tf。在本教程中,该文件称为 main.tf
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. 如果您按照教程进行操作,可以在每个部分或步骤中复制示例代码。

    将示例代码复制到新创建的 main.tf 中。

    (可选)从 GitHub 中复制代码。如果端到端解决方案包含 Terraform 代码段,则建议这样做。

  3. 查看和修改要应用到您的环境的示例参数。
  4. 保存更改。
  5. 初始化 Terraform。您只需为每个目录执行一次此操作。
    terraform init

    (可选)如需使用最新的 Google 提供程序版本,请添加 -upgrade 选项:

    terraform init -upgrade

应用更改

  1. 查看配置并验证 Terraform 将创建或更新的资源是否符合您的预期:
    terraform plan

    根据需要更正配置。

  2. 通过运行以下命令并在提示符处输入 yes 来应用 Terraform 配置:
    terraform apply

    等待 Terraform 显示“应用完成!”消息。

  3. 打开您的 Google Cloud 项目以查看结果。在 Google Cloud 控制台的界面中找到资源,以确保 Terraform 已创建或更新它们。

删除更改

如需删除更改,请执行以下操作:

  1. 如需停用删除防护,请在 Terraform 配置文件中将 deletion_protection 参数设置为 false
    deletion_protection =  "false"
  2. 运行以下命令并在提示符处输入 yes,以应用更新后的 Terraform 配置:
    terraform apply
  1. 通过运行以下命令并在提示符处输入 yes,移除之前使用 Terraform 配置应用的资源:

    terraform destroy

在您发出就地升级请求时,Cloud SQL 首先会执行升级前检查。如果 Cloud SQL 确定实例未准备好进行升级,则升级请求会失败,并显示一条消息来建议您如何解决问题。另请参阅排查主要版本升级问题

自动升级备份

执行主要版本升级时,Cloud SQL 会自动进行两个按需备份,称为升级备份:

  • 第一个升级备份是升级前备份,它在开始升级之前立即进行。您可以使用此备份将数据库实例恢复为先前版本的状态。
  • 第二个升级备份是升级后备份,该备份在允许对升级后的数据库实例执行新写入后立即创建。

查看备份列表时,系统会列出类型为 On-demand 的升级备份。升级备份会带有标签,以便您快速识别。例如,如果您要从 PostgreSQL 14 升级到 PostgreSQL 15,则升级前备份标记为 Pre-upgrade backup, POSTGRES_14 to POSTGRES_15.,升级后备份标记为 Post-upgrade backup, POSTGRES_14 to POSTGRES_15.

与其他按需备份一样,升级备份会一直保留,直到您删除它们或删除实例。如果您启用了 PITR,则无法在保留期限内删除升级备份。如果您需要删除升级备份,则必须停用 PITR,或等到升级备份不再位于保留期限内。

完成主要版本升级

完成主实例升级后,请执行以下步骤完成升级:

  1. 如果您的实例在升级之前使用了 pglogical 复制,请启用这种复制功能。此操作将自动创建必要的复制槽。
    1. 使用以下命令删除目标副本上的 pglogical 订阅:
      select pglogical.drop_subscription(subscription_name name);

      name 替换为现有订阅的名称。

      例如:

      postgres=> select pglogical.drop_subscription(subscription_name := 'test_sub');
      -[ RECORD 1 ]-----+--
      drop_subscription | 1
    2. 在目标(副本)上重新创建 pglogical 订阅,方法是向 Cloud SQL 主实例提供连接详细信息,如下所示:
      SELECT pglogical.create_subscription(
          subscription_name := 'test_sub',
          provider_dsn := 'host=primary-ip port=5432 dbname=postgres user=replication_user password=replicapassword'
      ); 

      例如:

      postgres=> SELECT pglogical.create_subscription(
      postgres(>     subscription_name := 'test_sub',
      postgres(>     provider_dsn := 'host=10.58.64.90 port=5432 dbname=postgres user=postgres password=postgres'
      postgres(> );
      -[ RECORD 1 ]-------+-----------
      create_subscription | 2769129391
    3. 使用以下命令检查订阅的状态:
      SELECT * FROM pglogical.show_subscription_status('test_sub');
    4. 通过执行写入事务并验证更改在目标位置是否可见来测试复制。
  2. 升级读取副本。

    如果您停止了读取副本的复制,请逐个升级副本。您可以使用用于升级主实例的任何方法。 当您升级副本时,Cloud SQL 会重新创建它以保留 IP 地址,使用主实例中的最新数据刷新副本,然后重启副本。

    如果您在升级主实例之前删除了读取副本,则可以创建新的读取副本,该副本会自动在升级后的数据库版本上预配。

  3. 刷新数据库统计信息。

    对主实例运行 ANALYZE 以在升级后更新系统统计信息。准确的统计信息可确保 PostgreSQL 查询规划器以最优方式处理查询。缺少统计信息可能会导致查询计划错误,进而可能会降低性能并占用过多内存。

  4. 执行验收测试。

    您应该运行测试以确保升级的系统按预期运行。

排查主要版本升级问题

如果您尝试执行无效的升级命令(例如,如果实例包含新版本的无效数据库标志),则 Cloud SQL 会返回错误消息。

如果升级请求失败,请检查升级请求的语法。如果请求的结构有效,请尝试查看以下建议。

查看升级前检查失败

升级前检查失败是 Cloud SQL 在升级前验证或验证过程中检测到的问题或错误。这些故障在实际升级过程开始之前发生,旨在找出可能会影响升级成功的潜在问题或不兼容问题。

系统针对以下类别显示升级前检查失败:

  • 不兼容的扩展程序:检测与实例的目标版本不兼容的 PostgreSQL 扩展程序。
  • 不受支持的依赖项:确定不再受支持或需要更新的依赖项。
  • 数据格式不兼容:验证由各种因素引起的数据不一致,包括特定于版本的数据结构的差异、编码和排序规则的更改、数据类型的修改以及对系统目录的调整。

下表列出了升级前检查失败及其错误消息:

升级前检查失败 错误消息
Cloud SQL 检测到未知数据类型。 Please remove the following usages of 'Unknown' data types before attempting an upgrade: (database: db_name, relation: rel_name, attribute: attr_name)
升级到 PostgreSQL 12 或更高版本时,Cloud SQL 会检测 'sql_identifier' 数据类型。 Please remove the following usages of 'sql_identifier' data types before attempting an upgrade: (database: db_name, relation: rel_name, attribute: attr_name)
Cloud SQL 会检测 reg* 数据类型。 Please remove the following usages of 'reg*' data types before attempting an upgrade: (database: db_name, relation: rel_name, attribute: attr_name)
Cloud SQL 检测到 postgres 数据库的
LC_COLLATE 值是 en_US.UTF8 以外的字符集。
Please change the 'LC_COLLATE' value of the postgres database to 'en_US.UTF8' before attempting an upgrade
Cloud SQL 会检测具有对象标识符 (OID) 的表。 Please remove the following usages of tables with OIDs before attempting an upgrade: (database: db_name, relation: rel_name)
Cloud SQL 可检测复合数据类型。 Please remove the following usages of 'composite' data types before attempting an upgrade: (database: db_name, relation: rel_name, attribute: attr_name)
Cloud SQL 可检测用户定义的后缀运算符。 Please remove the following usages of 'postfix operators' before attempting an upgrade: (database: db_name, operation id: op_id, operation namespace: op_namespace, operation name: op_name, type namespace: type_namespace, type name: type_name)
Cloud SQL 检测到不兼容的多态函数。 Please remove the following usages of 'incompatible polymorphic' functions before attempting an upgrade: (database: db_name, object kind: obj_kind, object name: obj_name)
Cloud SQL 可检测用户定义的编码转换。 Please remove the following usages of user-defined encoding conversions before attempting an upgrade: (database: db_name, namespace name: namespace_name, encoding conversions name: encod_name)
Cloud SQL 检测到函数 ll_to_earth 的搜索路径为空 Please update the search path of the 'll_to_earth' function
Cloud SQL 会检测是否存在未解压缩的 PostGIS 栅格文件。 PostGIS version upgrade has not been completed, unpackaged raster files present. Follow the steps at https://postgis.net/documentation/tips/tip-removing-raster-from-2-3/ to fix before major version upgrade.

修复了搜索路径为空的问题

之所以会出现这种情况,是因为 earthdistance 扩展程序使用了地球和立方体类型,但未指定函数的搜索路径。您必须指定此路径,因为升级过程中需要此路径。

如需解决此问题,请运行以下查询来修正 ll_to_earth 函数的搜索路径:ALTER FUNCTION ll_to_earth SET search_path = public;

查看升级日志

如果有效升级请求出现任何问题,Cloud SQL 会将错误日志发布到 projects/PROJECT_ID/logs/cloudsql.googleapis.com%2Fpostgres-upgrade.log。 每个日志条目都包含标签,用于标识实例标识符,以帮助您识别升级错误的实例。 请查找此类升级错误并加以解决。

如需查看错误日志,请按照以下步骤操作:

  1. 在 Google Cloud 控制台中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 如需打开实例的概览页面,请点击实例名称。
  3. 在实例概览页面的操作和日志窗格中,点击查看 PostgreSQL 错误日志 (View PostgreSQL error logs) 链接。

    日志浏览器页面随即会打开。

  4. 按以下方式查看日志:

    • 如需列出项目中的所有错误日志,请在日志名称日志过滤条件中选择日志名称。

    如需详细了解查询过滤条件,请参阅高级查询

    • 如需过滤单个实例的升级错误日志,请在搜索所有字段框中输入以下查询,将 DATABASE_ID

    替换为项目 ID,后跟实例名称,格式为 project_id:instance_name

    resource.type="cloudsql_database"
    resource.labels.database_id="DATABASE_ID"
    logName : "projects/PROJECT_ID/logs/cloudsql.googleapis.com%2Fpostgres-upgrade.log"

    例如,如需按项目 buylots 中运行的名为 shopping-db 的实例过滤升级错误日志,请使用以下查询过滤条件:

     resource.type="cloudsql_database"
     resource.labels.database_id="buylots:shopping-db"
     logName : "projects/buylots/logs/cloudsql.googleapis.com%2Fpostgres-upgrade.log"

带有 pg_upgrade_dump 前缀的日志条目表示发生了升级错误。例如:

pg_upgrade_dump: error: query failed: ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.

此外,标有 .txt 辅助文件名的日志条目可能会列出您在尝试再次升级之前可能需要解决的其他错误。

所有文件名都可以在 postgres-upgrade.log 文件中找到。如需查找文件名,请查看 labels.FILE_NAME 字段。

可能包含要解决的错误的文件名包括:

  • tables_with_oids.txt: 此文件包含使用对象标识符 (OID) 列出的表。请删除或修改表,使其不使用 OID。
  • tables_using_composite.txt: 此文件包含使用系统定义的复合类型列出的表。请删除或修改表,使其不使用这些复合类型。
  • tables_using_unknown.txt: 此文件包含使用 UNKNOWN 数据类型列出的表。请删除或修改表,使其不使用此数据类型。
  • tables_using_sql_identifier.txt: 此文件包含使用 SQL_IDENTIFIER 数据类型列出的表。请删除或修改表,使其不使用此数据类型。
  • tables_using_reg.txt: 此文件包含使用 REG* 数据类型(例如 REGCOLLATIONREGNAMESPACE)列出的表。请删除或修改表,使其不使用此数据类型。
  • postfix_ops.txt: 此文件包含使用后缀(一元)运算符列出的表。请删除或修改表,使其不使用这些运算符。

检查内存

如果实例的共享内存不足,您可能会看到以下错误消息:ERROR: out of shared memory. 如果有 10,000 个表,则更有可能发生此错误。

在尝试升级之前,请将 max_locks_per_transaction 标志的值设置为实例中表数的大约两倍。更改此标志的值时,实例将重启。

检查连接容量

如果您的实例没有足够的连接容量,您可能会看到以下错误消息:ERROR: Insufficient connections.

Cloud SQL 建议您根据实例中的数据库数量增加 max_connections 标志值。更改此标志的值时,实例将重启。

检查是否存在模糊的列引用

如果您的视图中存在模糊的列引用,您可能会看到以下错误消息:ERROR: column reference "<column_name>" is ambiguous。当新版 PostgreSQL 对系统目录视图(例如 pg_stat_activitypg_stat_replication)的结构做出更改时,就会出现此问题。这可能会破坏依赖于列顺序的自定义视图。

如需检查此错误消息,请将以下查询添加到查询编辑器中:textPayload =~ "ERROR: column reference .+ is ambiguous at character \d+"

您可以通过以下方式解决此问题:

  1. 自定义视图的适配。

    更新自定义视图中的列引用,使其与目标 PostgreSQL 版本中的新系统目录视图(例如 pg_stat_activitypg_stat_replication)定义保持一致。

  2. 重新创建视图。

    请先移除自定义视图,然后再执行主要版本升级。升级完成后,重新创建视图,确保它们与新结构兼容。

如需查看该问题的更详细示例和进一步的分析,请参阅此堆栈溢出讨论

检查 CASE 语句中的 SRF

如果您要从版本 9.6 升级实例,并在 CASE 语句中使用返回集合的函数,则可能会看到以下错误消息 ERROR: set-returning functions are not allowed in CASE。之所以会出现此问题,是因为从版本 10 开始,不允许在 CASE 语句中使用返回集合的函数。

若要解决此问题并成功升级实例,请确保在重试升级之前修改所有使用集返回函数的 CASE 语句,以免使用这些函数。一些常用的 SRF 包括:

  • unnest()
  • generate_series()
  • array_agg()
  • regexp_split_to_table()
  • jsonb_array_elements()
  • json_array_elements()
  • sonb_each()
  • json_each()

检查基于自定义投放创建的视图

如果您基于自定义投放创建了视图,则系统会显示类似于以下内容的错误消息:ERROR: cannot cast type <type_1> to <type_2>。出现此问题是因为自定义投放的广告存在权限问题。

如需解决此问题,请将实例更新为 [PostgreSQL version].R20240910.01_02

如需了解详情,请参阅自助维护

检查事件触发器所有权

如果事件触发器的所有者缺少 cloudsqlsuperuser 角色,您可能会收到 ERROR: permission denied to change owner of event trigger "<trigger_name>" 等错误消息。此问题是由于在升级过程中尝试重新创建这些触发器时出现权限问题所致。您可以在查询编辑器中添加以下查询,以检查是否出现此错误消息 textPayload =~ "ERROR: permission denied to change owner of event trigger .+ "

要解决此问题,请验证实例中所有事件触发器的所有权。 确保每个触发器的所有者都是 cloudsqlsuperuser。如果任何触发器由其他用户拥有,请先将其所有权更新为 cloudsqlsuperuser,然后再尝试再次升级。您可以使用以下查询更改所有权 ALTER EVENT TRIGGER <trigger_name> OWNER TO <cloudsqlsuperuser>;

您可以使用以下查询获取事件触发器列表和所有者详细信息 SELECT evtname AS trigger_name, evtowner::regrole AS owner FROM pg_event_trigger;

检查未记录表中的生成列

如果您有一个未记录的表生成了列,则可能会看到错误消息 ERROR: unexpected request for new relfilenumber in binary upgrade mode。出现此问题的原因是表及其生成列的序列之间存在持久性特性差异。

如需解决此问题,请执行以下操作:

  1. 删除未记录的表:如果可能,请删除与生成的列关联的所有未记录的表。请确保可以安全地减少数据丢失,然后再继续操作。
  2. 转换为永久表:暂时,请按照以下步骤将未记录表转换为永久表:
    1. 将表转换为已记录的表 ALTER TABLE SET LOGGED;
    2. 执行主要版本升级
    3. 将表转换回未记录日志的表 ALTER TABLE SET UNLOGGED

您可以使用以下查询识别所有此类表:

SELECT
  relnamespace::regnamespace,
  c.relname AS table_name,
  a.attname AS column_name,
  a.attidentity AS identity_type
FROM
  pg_catalog.pg_class c
  JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
WHERE
  a.attidentity IN ('a', 'd') AND c.relkind = 'r' AND c.relpersistence = 'u'
ORDER BY c.relname, a.attname;

检查 PostgreSQL 实例的自定义标志

如果要升级到 PostgreSQL 实例 14 版或更高版本,请检查为该实例配置的任何自定义数据库标志的名称。这是因为 PostgreSQL 为允许的自定义参数名称施加了额外限制

自定义数据库标志的第一个字符必须是字母(A-Z 或 a-z)。所有后续字符可以是字母数字字符、下划线 (_) 特殊字符或美元符号 ($) 特殊字符。

移除扩展程序

如果您要升级 Cloud SQL 实例,则可能会看到以下错误消息:pg_restore: error: could not execute query: ERROR: role "16447" does not exist

如需解决此问题,请按以下步骤操作:

  1. 移除 pg_stat_statementspgstattuple 扩展程序。
  2. 执行升级。
  3. 重新安装扩展程序。

恢复到先前的主要版本

如果升级后的数据库系统未按预期运行,您可能需要将实例恢复到先前版本。您可以通过将升级前备份恢复到 Cloud SQL 恢复实例来执行此操作,该实例是运行升级前版本的新实例。

如需恢复到先前的版本,请执行以下步骤:

  1. 确定升级前备份。

    请参阅自动升级备份

  2. 创建恢复实例。

    使用升级前备份时 Cloud SQL 运行的主要版本创建新的 Cloud SQL 实例。设置与原始实例相同的标志实例设置

  3. 恢复升级前备份。

    将升级前备份恢复到恢复实例。此命令可能需要几分钟才能完成。

  4. 添加读取副本。

    如果您使用的是读取副本,请单独添加。

  5. 连接您的应用。

    恢复数据库系统后,使用有关恢复实例及其读取副本的详细信息来更新应用。您可以继续在数据库的升级前版本上处理流量。

常见问题解答

升级数据库主要版本时,可能会出现以下问题。

实例在升级期间不可用吗?
可以。在 Cloud SQL 执行升级期间,您的实例在一段时间内不可用。
升级需要多长时间?

升级单个实例通常不到 10 分钟。如果您的实例配置使用少量 vCPU 或内存,则升级可能需要更多时间。

如果您的实例托管过多数据库或表,或者您的数据库非常大,则升级可能需要几个小时,甚至超时,因为升级时间与数据库中的对象数量相对应。如果您有多个实例需要升级,那么总升级时间会按比例增加。

我可以监控升级过程的每个步骤吗?
Cloud SQL 支持您监控升级操作是否仍在进行中,但您无法跟踪每次升级中的各个步骤。
升级后是否可以取消?
不可以,升级一旦开始就无法取消。如果升级失败,Cloud SQL 会自动恢复您在先前版本上的实例。
升级期间,我的设置会发生什么情况?

执行主要版本就地升级时,Cloud SQL 会保留您的数据库设置,包括实例名称、IP 地址、明确配置的标志值和用户数据。但是,系统变量的默认值可能会发生变化。例如,PostgreSQL 13 及更低版本中 password_encryption 标志的默认值为 md5。升级到 PostgreSQL 14 后,此标志的默认值会更改为 scram-sha-256

如需了解详情,请参阅配置数据库标志。如果目标版本中不再支持特定标志或值,则 Cloud SQL 会在升级期间自动移除该标志。

后续步骤