诊断迁移到 Cloud SQL for PostgreSQL 的单一数据库迁移问题

迁移作业进程在运行时可能会出错。

  • 某些错误(例如源数据库上的密码错误)可以恢复,这意味着它们可以得到修复,并且迁移作业会自动恢复。
  • 有些错误无法恢复,例如数据复制错误,这意味着迁移作业需要从头开始重启。

发生错误时,迁移作业状态会变为 Failed,子状态会反映失败前的最后状态。

如需排查错误,请导航到失败的迁移作业以查看错误,然后按照错误消息中列出的步骤操作。

如需查看有关错误的更多详细信息,请使用迁移作业中的链接导航到 Cloud Monitoring。日志会按特定的迁移作业进行过滤。

在下表中,您可以找到一些问题示例以及解决这些问题的方法:

针对此问题… 可能的原因… 请尝试以下操作…
当您迁移到 现有目标实例 时,会收到以下错误消息: The destination instance contains existing data or user defined entities (for example databases, tables, or functions). You can only migrate to empty instances. Clear your destination instance and retry the migration job. 您的目标 Cloud SQL 实例包含额外数据。您只能 迁移到空的现有实例。请参阅 已知限制 提升目标实例,使其成为读写实例,移除额外数据,然后重试迁移作业。请参阅 清除现有目标实例中的额外数据
未能连接到源数据库实例。 源数据库实例与目标实例之间存在连接问题。 按照调试连接中的步骤操作。
由于源数据库和目标数据库版本不兼容,无法运行迁移作业。 源数据库和目标数据库版本不是受支持的组合。具体而言,提供的源数据库版本与目标数据库版本不兼容。 确保目标数据库版本与源数据库版本相同,或者比源数据库版本还要新一个主要版本。然后,创建新的迁移作业。
数据定义语言 (DDL) 或数据操纵语言 (DML) 在源数据库上被屏蔽。 需要 ACCESS EXCLUSIVE 并在完整转储阶段运行的 DDL 会被屏蔽。

在初始同步过程(完整转储)中,应避免在表上使用需要 ACCESS EXCLUSIVE 的 DDL 或程序,例如 ALTER TABLEDROP TABLE。否则,DDL 或程序将等待初始同步完成。

例如,如果某个表仍在初始同步过程中,并且对同一表执行了 ALTER TABLE 命令,则该命令将不会运行,并且后续的 DDL 和 DML 命令将被屏蔽,直到初始同步完成。

错误消息: No pglogical extension installed on databases (X) 一个或多个源数据库未安装 pglogical 请按照 以下准则 在源实例的数据库上安装 pglogical
迁移到 PostgreSQL 版本 15 时,在多次连续重试连接 后,会出现以下某种症状: 此问题通常归因于 pglogical 扩展程序中的死锁问题。如需了解详情,请参阅 GitHub 中的 pglogical 问题跟踪器 重试迁移作业,或先迁移到中间 PostgreSQL 版本 first. 如需了解详情,请参阅 错误消息:Cannot connect to invalid database
错误消息: Replication user 'x' doesn't have sufficient privileges. 使用 Database Migration Service 的用户没有执行指定操作所需的权限。 请按照以下准则确保此用户拥有所需的权限。
错误消息: Unable to connect to source database server. Database Migration Service 无法与源数据库服务器建立连接。 确保源数据库实例和目标数据库实例可以相互通信,并且您已完成在定义迁移作业设置时显示的所有必需前提条件。
错误消息: The source database 'wal_level' configuration must be equal to 'logical'. 源数据库的 wal_level 设置为 logical 以外的值。 wal_level 设置为 logical
错误消息: The source database 'max_replication_slots' configuration is not sufficient. max_replication_slots 参数配置不正确。 请按照以下准则正确设置此参数。
错误消息: The source database 'max_wal_senders' configuration is not sufficient. max_wal_senders 参数配置不正确。 请按照以下准则正确设置此参数。
错误消息: The source database 'max_worker_processes' configuration is not sufficient. max_worker_processes 参数配置不正确。 请按照以下准则正确设置此参数。

错误消息: Cleanup may have failed on source due to error: generic::unknown: failed to connect to on-premises database.

错误消息: Error promoting EM replica: finished drop replication with errors.

在提升迁移作业期间,无法清理复制所需的设置。

对于每个数据库,以具有 superuser 权限的用户身份运行命令。

如需详细了解要运行哪些命令,请参阅清理复制槽

错误消息: x509 certificate signed by unknown authority.

提供给 Database Migration Service 的源 CA 证书可能仅包含根证书。但是,源证书需要根证书和所有中间证书。

例如,对于 Amazon Relational Database Service,使用 rds-ca-2019-root.pem 证书可能会导致此问题。

创建一个组合的源 CA 证书,其中包含根证书和所有必需的中间证书。

对于 Amazon Relational Database Service 用例,请使用 rds-combined-ca-bundle.pem 证书,而不是 rds-ca-2019-root.pem 证书。

错误消息: ERROR: Out of shared memory HINT: You might need to increase max_locks_per_transaction.

max_locks_per_transaction 参数设置的值不足。 将此参数的值设置为至少 {max_number_of_tables_per_database}/(max_connections + max_prepared_transactions)。

错误消息: ERROR: no data left in message.

pglogical 软件包未在源实例上正确安装。 如需详细了解如何正确安装此软件包,请参阅在源实例上安装 pglogical 软件包

错误消息: Cannot assign TransactionIds during recovery.

配置的源处于恢复模式。 配置一个不处于恢复模式的源。
完整转储速度缓慢。 Cloud SQL 目标实例从源数据库导入大型数据时速度可能较慢。
  • 创建目标实例时,请将数据磁盘大小设置为接近最终大小。完整转储阶段使用 I/O 写入密集型工作负载,磁盘大小越大,I/O 性能越好。如需了解详情,请参阅块存储性能
  • 为 Cloud SQL 目标实例选择更高的层级,以获得最大的可用网络和磁盘带宽。
  • 调整 Cloud SQL 目标实例的 max_wal_size 标志。通常,将此标志设置为 32 GB 或 64 GB 是一个不错的选择。更新此标志不需要您重启服务器。
错误消息:subscriber {subscriber_name} initialization failed during nonrecoverable step (d), please try the setup again

迁移作业在完整转储阶段失败,且作业无法恢复。源数据库实例已重启或处于恢复模式,或者由于为 wal_sender_timeout 参数设置的值不足,复制连接已结束。

如需查找问题的根本原因,请执行以下操作:

  1. 转到Logs Explorer页面,在 Google Cloud 控制台中。
  2. 从资源列表中,选择 Cloud SQL 副本。系统会显示副本的最新日志列表。
  3. 从日志文件名中,选择 postgres.log
  4. 将日志的严重级别设置为高于 Warning 的所有级别。第一个错误日志可能是失败的根本原因。
  • 确保 Database Migration Service 在完整转储阶段始终可以连接到源数据库实例。
  • 检查源数据库实例上的 wal_sender_timeout 参数的值是否设置为较大的数字(例如 0)。
  • 重启迁移作业,然后重试。
错误消息:ERROR: unknown column name {column_name}

在主节点上向复制的表中添加了列,但在副本节点上未添加。

在持续迁移期间,只有数据操纵语言 (DML) 更改会自动更新。管理数据定义语言 (DDL) 更改以确保源数据库和目标数据库保持兼容是用户的责任,并且可以通过两种方式来实现:

  • 停止写入源数据库,并在源数据库和目标数据库中运行 DDL 命令。在目标实例上运行 DDL 命令之前,请向应用 DDL 更改的 Cloud SQL 用户授予 cloudsqlexternalsync 角色。
  • 使用 pglogical.replicate_ddl_command,可允许 DDL 命令在源数据库和目标数据库上同时运行。运行命令的用户在源数据库和目标数据库上必须具有相同的用户名,并且应该是超级用户或要迁移的工件(例如表、序列、视图或数据库)的所有者。
  • 如需查看使用 pglogical.replicate_ddl_command. 的示例,请参阅 持续迁移

错误消息:ERROR: cannot truncate a table referenced in a foreign key constraint

用户尝试截断具有外键约束的表。

先移除外键约束,然后截断表。

错误消息:ERROR: connection to other side has died

由于为 wal_sender_timeout parameter 设置的值不足,复制连接已结束。此错误通常在初始转储成功后的复制阶段发生。

请考虑增加 wal_sender_timeout 参数值,或通过在源数据库实例上将其值设置为 0 来停用超时机制。

警告消息:migration job test configuration has returned the following warnings: Some table(s) have limited support.

源数据库包含支持有限的表,例如没有主键的表。

这是一条警告消息。您可以继续迁移,但请注意 不支持的实体(例如没有主键的表) 不会迁移。如需了解详情,请参阅 配置源数据库

当您迁移所选数据库,并且迁移作业无法将数据复制到一个或多个数据库时,数据库列表中会显示失败 状态。 各种迁移作业错误。

错误 列中,点击查看错误 并修复这些错误。您还可以从迁移作业中移除失败的数据库。

如需详细了解如何从迁移作业中移除失败的数据库,请参阅管理迁移作业

清除现有目标实例中的额外数据

当您迁移到 现有目标实例时,会收到以下错误消息: The destination instance contains existing data or user defined entities (for example databases, tables, or functions). You can only migrate to empty instances. Clear your destination instance and retry the migration job.

如果您的目标实例包含额外数据,则可能会出现此问题。 您只能迁移到空的现有实例。请参阅 已知限制

可以尝试的操作

清除目标实例中的额外数据,然后按照以下步骤再次启动迁移作业:

  1. 停止迁移作业
  2. 此时,您的目标 Cloud SQL 实例处于 `read-only` 模式。 提升目标实例 以获得写入权限。
  3. 连接到 Cloud SQL 目标实例
  4. 从目标实例数据库中移除额外数据。您的 目标实例只能包含系统配置数据。目标数据库 不能包含用户数据(例如表)。您可以在数据库上运行不同的 SQL 语句 来查找非系统数据,例如:

    用于检索非系统数据库的 SQL 语句示例(点击展开)

    SELECT datname FROM pg_catalog.pg_database
    WHERE datname NOT IN ('cloudsqladmin', 'template1', 'template0', 'postgres');

    用于检索 postgres 数据库中的非系统数据的 SQL 语句示例(点击展开)

    postgres 数据库是一个系统数据库,但它可以 包含非系统数据。请确保在 postgres 数据库上运行这些语句。如果您使用 psql 客户端连接到目标实例,则可以使用 \connect {database_name_here} 命令切换到其他数据库,而无需重置连接。

    SELECT table_schema, table_name FROM information_schema.tables
    WHERE table_schema != 'information_schema' AND table_schema not like 'pg\_%';
    
    SELECT routine_schema, routine_name FROM information_schema.routines
    WHERE routine_schema != 'information_schema' AND routine_schema not like 'pg\_%';
    
    SELECT extname FROM pg_extension WHERE extname != 'plpgsql';
        
  5. 启动迁移作业

清理复制槽

您会看到以下某条消息:

  • Cleanup may have failed on source due to error: generic::unknown: failed to connect to on-premises database.
  • Error promoting EM replica: finished drop replication with errors.

可能的原因

提升 Cloud SQL 实例时,如果无法从 Cloud SQL 实例访问源实例(例如,源实例未运行,或者您从源实例的许可名单中移除了 Cloud SQL 实例),则在提升迁移作业期间,无法清理复制所需的设置。您必须手动清理复制槽。

可以尝试的操作

对于每个数据库,以具有 superuser 权限的用户身份运行以下命令:

  1. 从错误消息中获取复制槽名称,然后运行以下命令以逐个删除槽:

    select pg_drop_replication_slot({slot_name});
  2. 如果错误消息中没有复制槽名称,请运行以下命令来查询现有复制槽:

    select pg_drop_replication_slot(slot_name) from pg_replication_slots where slot_name like '%cloudsql%' and active = 'f';
  3. 如果没有 Cloud SQL 副本使用源实例,请运行以下命令来清理 pglogical 设置:

    select pglogical.drop_node(node_name) from pglogical.node where node_name like 'cloudsql';
  4. 如果不再需要 pglogical 扩展程序,请运行以下命令来卸载该扩展程序:

    DROP EXTENSION IF EXISTS pglogical;


错误消息: Cannot connect to invalid database

迁移到 PostgreSQL 版本 15 时,在多次连续重试连接 后,会出现以下某种症状:

可能的原因

此问题通常归因于 pglogical 扩展程序中的死锁问题。如需了解详情,请参阅 GitHub 中的 pglogical问题跟踪器

可以尝试的操作

使用新的目标实例再次执行迁移作业

尝试删除遇到问题的目标数据库,然后重新创建迁移作业。请按照以下步骤操作:

  1. 删除遇到问题的目标实例。 请参阅 Cloud SQL for PostgreSQL 文档中的删除实例
  2. 删除失败的迁移作业。 请参阅 审核迁移作业
  3. 重新创建迁移作业。 请参阅 创建迁移作业

迁移到中间版本

请考虑迁移到较早的 PostgreSQL 版本,例如 PostgreSQL 14。 成功迁移后,您可以尝试升级到所需的 PostgreSQL 15 实例。请参阅 通过迁移数据升级数据库主要版本在 Cloud SQL for PostgreSQL 文档中。

管理用户和角色

迁移现有用户

目前,Database Migration Service 不支持将现有用户从源实例迁移到目标 Cloud SQL 实例。您可以通过在 Cloud SQL 中创建用户来手动管理此迁移。

关于 cloudsqlexternalsync 用户

在迁移期间,Cloud SQL 副本上的所有对象都归 cloudsqlexternalsync 用户所有。迁移数据后,您可以按照以下步骤将对象的所有权修改为其他用户:

  • 运行 GRANT cloudsqlexternalsync to {USER} 命令。
  • 在每个数据库上,运行 reassign owned by cloudsqlexternalsync to {USER}; 命令。
  • 如需移除 cloudsqlexternalsync 用户,请运行 drop role cloudsqlexternalsync 命令。

将数据导入新的 Cloud SQL 实例

如果您先从 Database Migration Service 迁移到 Cloud Storage 中的 Cloud SQL 实例中导出数据,然后将数据从 Cloud Storage 导入到独立的 Cloud SQL 实例中导入数据,则导入可能会失败,因为目标实例中不存在 cloudsqlexternalsync 用户。

如需缓解此问题,请在目标实例上创建 cloudsqlexternalsync 用户,或从迁移的实例中移除该用户