管理读取副本

本页面介绍如何管理读取副本。相关操作包括停用和启用复制功能、提升副本、配置并行复制以及检查复制状态。

如需详细了解复制的工作原理,请参阅 Cloud SQL 中的复制

停用复制功能

默认情况下,复制功能会随副本的启动而启用。 但您可以停用复制功能,例如,要对实例状态进行调试或分析时。准备就绪后,您可以明确重新启用复制功能。停用或重新启用复制功能不会重启副本实例。

停用复制功能并不会使副本实例停止,而是使该实例变成一个不再从其主实例复制内容的只读实例。系统会继续向您收取该实例的费用。在已停用的副本上,您可以重新启用复制、删除副本或将副本提升为独立实例。

如需停用复制功能,请按如下所述操作:

控制台

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

    转到“Cloud SQL 实例”

  2. 点击某副本实例的名称以选择该实例。
  3. 点击按钮栏中的停用复制功能按钮。
  4. 点击确定

gcloud

gcloud sql instances patch REPLICA_NAME \
--no-enable-database-replication

REST v1

如需在命令行提示符处执行此 cURL 命令,请使用 gcloud auth print-access-token 命令获取访问令牌,也可以使用 Instances:patch 页面上的 APIs Explorer 发送 REST API 请求。

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

  • project-id:项目 ID
  • replica-name:副本实例的名称

HTTP 方法和网址:

PATCH https://sqladmin.googleapis.com/v1/projects/project-id/instances/replica-name

请求 JSON 正文:

{
  "settings":
  {
    "databaseReplicationEnabled": "False"
  }
}

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

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

REST v1beta4

如需在命令行提示符处执行此 cURL 命令,请使用 gcloud auth print-access-token 命令获取访问令牌,也可以使用 Instances:patch 页面上的 APIs Explorer 发送 REST API 请求。

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

  • project-id:项目 ID
  • replica-name:副本实例的名称

HTTP 方法和网址:

PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/replica-name

请求 JSON 正文:

{
  "settings":
  {
    "databaseReplicationEnabled": "False"
  }
}

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

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

启用复制功能

如果某副本已有很长时间未复制内容,它将需要较长时间才能与主实例同步。在这种情况下,请删除该副本并创建一个新副本。

如需启用复制功能,请按如下所述操作:

控制台

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

    转到“Cloud SQL 实例”

  2. 点击某副本实例的名称以选择该实例。
  3. 点击启用复制功能
  4. 点击确定

gcloud

gcloud sql instances patch REPLICA_NAME \
--enable-database-replication

REST v1

如需在命令行提示符处执行此 cURL 命令,请使用 gcloud auth print-access-token 命令获取访问令牌,也可以使用 Instances:patch 页面上的 APIs Explorer 发送 REST API 请求。

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

  • project-id:项目 ID
  • replica-name:副本实例的名称

HTTP 方法和网址:

PATCH https://sqladmin.googleapis.com/v1/projects/project-id/instances/replica-name

请求 JSON 正文:

{
  "settings":
  {
    "databaseReplicationEnabled": "True"
  }
}

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

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

REST v1beta4

如需在命令行提示符处执行此 cURL 命令,请使用 gcloud auth print-access-token 命令获取访问令牌,也可以使用 Instances:patch 页面上的 APIs Explorer 发送 REST API 请求。

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

  • project-id:项目 ID
  • replica-name:副本实例的名称

HTTP 方法和网址:

PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/replica-name

请求 JSON 正文:

{
  "settings":
  {
    "databaseReplicationEnabled": "True"
  }
}

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

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

提升副本

提升读取副本会停止复制,并会将实例转换为具有读写功能的独立 Cloud SQL 主实例。

提升时,读取副本会自动配置备份,但不会自动配置为高可用性 (HA) 实例。您可以在升级副本后启用高可用性,就像处理任何非副本实例一样。为高可用性配置读取副本的方式与为主实例配置的方式相同。详细了解如何配置实例以实现高可用性

在提升只读副本之前,如果主实例仍然可用并为客户端提供服务,则您应执行以下操作:

  1. 停止对主实例的所有写入操作。
  2. 检查副本的复制状态(请按照 psql 客户端标签页中的说明操作)。
  3. 验证副本是否正在复制,然后等到 replay_lag 指标报告的复制延迟时间为 0。

否则,新提升的实例可能缺少提交到主实例的部分事务。

如需将副本提升为独立实例,请按如下所述操作:

控制台

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

    转到“Cloud SQL 实例”

  2. 点击某副本实例的名称以选择该实例。
  3. 点击提升副本
  4. 点击确定

gcloud

gcloud sql instances promote-replica REPLICA_NAME
  

REST v1

如需在命令行提示符处执行此 cURL 命令,请使用 gcloud auth print-access-token 命令获取访问令牌,也可以使用 Instances:promoteReplica 页面上的 APIs Explorer 发送 REST API 请求。

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

  • project-id:项目 ID
  • replica-name:副本实例的名称

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/replica-name/promoteReplica

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

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

REST v1beta4

如需在命令行提示符处执行此 cURL 命令,请使用 gcloud auth print-access-token 命令获取访问令牌,也可以使用 Instances:promoteReplica 页面上的 APIs Explorer 发送 REST API 请求。

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

  • project-id:项目 ID
  • replica-name:副本实例的名称

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/replica-name/promoteReplica

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

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

确认已正确配置提升的实例。 具体而言,如果需要,请考虑配置实例以使其具备高可用性

检查复制状态

使用 Google Cloud 控制台查看副本实例或使用管理客户端登录实例时,您可以获取有关复制的详细信息(包括状态和指标)。使用 gcloud CLI 时,您会看到有关复制配置的简短摘要。

在检查 Cloud SQL 副本实例的复制状态之前,请使用
gcloud sql instances describe 命令显示实例的状态。这样,您便可以查看是否已为副本实例启用了复制功能。

以下指标适用于副本实例。(详细了解适用于所有实例的其他指标,包括非副本实例。)

指标说明
复制状态
(cloudsql.googleapis.com/database/replication/state)

指示复制是否主动将日志从主实例流式传输到副本。可能的值包括:

  • Running
  • Stopped
  • Error

在以下情况下,此指标会报告 Running

  1. pg_catalog.pg_stat_wal_receiver 会报告“正在流式传输”status
  2. pg_catalog.pg_is_wal_replay_paused() 会报告“f”(false)。

如需了解详情,请参阅 PostgreSQL 参考手册中的 Statistics Collector系统管理函数

复制延迟时间
(cloudsql.googleapis.com/database/replication/replica_lag)

副本状态滞后于主实例状态的时间长度。这是指 (1) 当前时间与 (2) 在主实例提交当前对副本应用的事务的原始时间戳之间的差值。具体而言,如果副本尚未被写入数据库,则即使写入副本已被写入,也可能会计为延迟。

对于级联副本,每个主实例-副本对都单独进行监控,并且没有一个指标会导致端到端(主实例到副本)延迟。

如需了解详情,请参阅复制延迟

延迟字节数
(cloudsql.googleapis.com/database/postgresql/replication/replica_byte_lag)

报告只读副本落后于主实例的字节数。系统会为每个副本生成四个时间序列,表明主实例的预写式日志中的字节数尚未…

  • sent_location:…已发送到副本
  • write_location:...由副本写入磁盘
  • flush_location:...由副本刷新到磁盘
  • replay_location:...由副本重放

这些指标的用途不同;例如,replay_location 指示复制延迟(已向主实例提交且尚未应用到副本的事务数),而 flush_location 指示尚未在副本实例上永久记录的事务数。

这些指标通过将 pg_catalog.pg_current_wal_lsn()pg_stat_replication 中的以下字段之一进行比较计算得出:sent_lsnwrite_lsnflush_lsnreplay_lsn。如需了解详情,请参阅 PostgreSQL 参考手册中的统计信息收集器

最大延迟字节数
(cloudsql.googleapis.com/database/postgresql/external_sync/max_replica_byte_lag)

对于外部主实例的副本,报告针对所有要复制到实例的数据库的最大复制延迟(以字节为单位)。对于每个数据库,定义为主实例的预写式日志中尚未确认副本接收的字节数。

该指标通过将查询发送到主实例以将 pg_catalog.pg_current_wal_lsn() 与要复制到副本实例的每个数据库的 confirmed_flush_lsn 值进行比较计算得出。如需了解详情,请参阅 PostgreSQL 参考手册中的统计信息收集器

如需检查复制状态,请执行以下操作:

控制台

Cloud SQL 在默认 Cloud SQL 监控信息中心上报告 Replication State 指标。

如需查看区域内和跨区域副本以及外部服务器副本的其他指标,请创建自定义信息中心并向其添加要监控的指标:

  1. 在 Google Cloud 控制台中,转到 Monitoring 页面。

    转至 Resources

  2. 选择信息中心标签页。
  3. 点击创建信息中心
  4. 为信息中心命名,然后点击“确定”。
  5. 点击添加图表
  6. 对于资源类型,请选择 Cloud SQL 数据库
  7. 执行以下任意操作:
    1. 监控复制状态指标:在选择指标字段中,输入 Replication state。然后,添加 state = "Running" 过滤条件。如果复制正在运行,图表会显示 1,否则显示 0。
    2. 如需监控只读副本的复制延迟(以字节为单位):在选择指标字段中,输入 Lag Bytes。然后,添加 replica_lag_type = "replay_location" 的过滤条件。该图表显示了与已在主实例中提交但尚未在副本上重放的事务相关联的字节数。
    3. 监控外部主实例副本的复制延迟(以字节为单位):在选择指标字段中输入 Max Lag Bytes。该图表显示了与在主实例中已提交但尚未确认副本接收的事务相关联的字节数。

gcloud

对于副本实例,请使用以下命令检查复制状态:

gcloud sql instances describe REPLICA_NAME

在输出中,查找属性 databaseReplicationEnabledmasterInstanceName

对于主实例,请使用以下命令检查是否存在副本:

gcloud sql instances describe PRIMARY_INSTANCE_NAME

在输出中,查找属性 replicaNames

psql 客户端

有些复制状态指标由主实例生成,而有些复制状态指标由副本实例生成。为执行以下步骤,请使用 PostgreSQL 客户端连接到副本实例或主实例(如下所示)。

如需了解详情,请参阅外部应用连接方案

  1. 如需根据主实例检查副本的状态,请运行以下命令:
    select * from pg_stat_replication;
    在该命令的输出中查找以下指标:
    • client_addr:副本实例的 IP 地址。
    • state:指示用于执行中继日志事件的 SQL 线程是否正在运行。复制开始时,此值为 streaming
    • replay_lag:副本 SQL 线程落后于主实例的字节数。此值为 O 或较少字节数。
  2. 如需根据副本实例检查副本的状态,请运行以下命令:
    select * from pg_stat_wal_receiver;

    在此命令的输出中查找以下指标:

    • sender_host:主实例的 IP 地址。
    • status:指示用于执行中继日志事件的 SQL 线程是否正在运行。复制开始时,此值为 streaming
    • last_msg_send_timelast_msg_receipt_time:这两个时间戳之间的差值就是延迟时间。

    如需检查复制是否已暂停,请运行以下命令:

    select pg_is_wal_replay_paused();

    如果复制操作已暂停,则值为 t;否则值为 f

    如需检查是否存在已从主实例接收但尚未应用的事务,请运行以下命令:

    # for PostgreSQL 9.6
    select pg_catalog.pg_last_xlog_receive_location(), pg_catalog.pg_last_xlog_replay_location();
    # for PostgreSQL 10 and above
    select pg_catalog.pg_last_wal_receive_lsn(), pg_catalog.pg_last_wal_replay_lsn();

    如果这两个值相等,则表示副本已处理它从主实例接收的所有事务。

  • 如需详细了解这些命令的输出,请参阅关于统计信息收集器的 PostgreSQL 文档。
  • 问题排查

    问题 问题排查
    创建时读取副本未开始复制。 日志文件中可能有更具体的错误信息。在 Cloud Logging 中查看日志以找到实际错误。
    无法创建只读副本 - invalidFlagValue 错误 请求中的某个标志无效。它可能是您明确提供的标志,也可能是设置为默认值的标志。

    首先,检查 max_connections 标志的值是否大于或等于主实例上的值。

    如果 max_connections 标志设置正确,请在 Cloud Logging 中检查日志以找出实际错误。

    无法创建只读副本 - 未知错误。 日志文件中可能有更具体的错误信息。在 Cloud Logging 中查看日志以找到实际错误。

    如果错误为 set Service Networking service account as servicenetworking.serviceAgent role on consumer project,则停用 Service Networking API,然后重新启用。此操作会创建继续执行该过程所需的服务账号。

    磁盘已满。 主实例磁盘大小可能在副本创建期间变满。 修改主实例以将其升级为更大的磁盘。
    磁盘空间显著增加。 未主动用于跟踪数据的槽会使 PostgreSQL 无限期地保留在 WAL 分段中,从而导致磁盘空间无限增大。如果您使用 Cloud SQL 中的逻辑复制和解码功能,则系统会自动创建和丢弃复制槽。可通过查询 pg_replication_slots 系统视图并过滤 active 列检测到未使用的复制槽。您可以使用 pg_drop_replication_slot 命令丢弃未使用的槽以移除 WAL 分段。
    副本实例占用的内存过多。 副本使用临时内存来缓存经常请求的读取操作,这可能会导致其占用的内存多于主实例。

    重启副本实例以收回临时内存空间。

    已停止复制。 已达到存储空间上限,且未启用存储空间自动扩容功能。

    修改实例以启用 automatic storage increase

    复制延迟一直很高。 写入负载过高,副本无法处理。当副本上的 SQL 线程无法与 IO 线程保持同步时,会发生复制延迟。某些类型的查询和工作负载会导致指定架构出现暂时性或永久性的高复制延迟。下面列出了复制延迟的部分常见原因:
    • 对副本的查询速度较慢。找到这些查询并进行修复。
    • 所有表都必须具有唯一键/主键。每次更新此类没有唯一键/主键的表都会导致对副本进行全表扫描。
    • 由于大量更新堆积在副本上,因此 DELETE ... WHERE field < 50000000 等查询会导致基于行的复制出现复制延迟。

    以下是一些可行的解决方案:

    • 修改实例以增加副本的大小。
    • 减少数据库的负载。
    • 将读取流量发送到读取副本。
    • 将表编入索引。
    • 识别并修复速度缓慢的写入查询。
    • 重新创建副本。
    在 PostgreSQL 9.6 中重建索引时出错。 您会收到来自 PostgreSQL 的错误,告知您需要重新构建特定索引。此操作只能在主实例上完成。如果您创建新的副本实例,则很快就会再次遇到同样的错误。在低于 10 的 PostgreSQL 版本中,哈希索引不会传播到副本

    如果必须使用哈希索引,请升级到 PostgreSQL 10+。否则,如果您还想使用副本,请不要在 PostgreSQL 9.6 中使用哈希索引。

    主实例上的查询始终运行。 创建副本后,查询 SELECT * from pg_stat_activity where state = 'active' and pid = XXXX and username = 'cloudsqlreplica' 应在主实例上连续运行。
    副本创建失败并超时。 主实例上长时间运行的未提交事务可能会导致只读副本创建失败。

    停止所有正在运行的查询后重新创建副本。

    如果主实例和副本具有不同的 vCPU 大小,则可能存在查询性能问题,因为查询优化器会考虑 vCPU 大小。

    如需解决此问题,请完成以下步骤:

    1. 启用 log_duration 标志并将 log_statement 参数设置为 ddl。这样一来,您就可以同时获得针对数据库的查询和运行时间。不过,根据您的工作负载,这可能会导致性能问题。
    2. 在主实例和只读副本上,针对查询运行 explain analyze
    3. 比较查询计划并检查差异。

    如果是特定查询,请修改此查询。例如,您可以更改联接的顺序,以查看是否可以获得更好的性能。

    后续步骤