
# 最滞后副本滞后量和复制时延高问题定位及处理方法
本章节的所有SQL操作都使用root用户执行。
#### 指标异常说明（影响）
- 最滞后副本滞后量：多个副本中最滞后副本（依据接收到的WAL数据）滞后量。可以使用root用户执行如下SQL查看多个副本使用复制槽的滞后量情况。
  ```
  select slot_name, temporary, active,restart_lsn, confirmed_flush_lsn, master_lsn, pg_size_pretty(pg_wal_lsn_diff(master_lsn, a.restart_lsn)) as latency from pg_replication_slots a, pg_current_wal_lsn() as master_lsn;
  ```
  
- 复制时延：副本滞后时延，即数据写入主数据库和复制到副本之间的时间延迟。
当数据库最滞后副本滞后量或复制时延高时，可能会产生以下影响：
- 数据库主服务器会保留所需要的wal日志，使得该部分wal日志无法被清理，从而导致wal日志积压，占用更多的磁盘空间，严重时会导致磁盘满。
- 复制时延高，说明回放速度落后主机，影响数据实时性。
 
#### 问题排查思路
RDS for PostgreSQL中，业务需要关注的是主机和只读实例间的最滞后副本滞后量和复制时延指标。引起指标异常的原因一般如下：
- 主机业务压力大。
- 只读副本回放延迟高。
- 主机和只读副本之间网络延迟。
 
#### 排查及解决方法
1. 排查主机业务压力大。 排查主机上是否存在大的业务写入或者更新。
   在主机查看管理控制台的监控平台中事务日志生成速率监控项，观察目标时间段事务日志生成速率是否超过40MB/s（一般只读实例回放wal日志的速率大概为40MB/s）。
   - 若长时间超过指标阈值，说明主机业务压力较大，此时建议优化业务量大小。 若存在主机业务压力大时，典型的现象还有pg_stat_replication中的sent_lsn和主机上**select pg_current_wal_lsn();**的查询结果差异较大，可使用root用户执行如下SQL来查看：
     1. 确认只读实例节点信息，在主机上执行以下SQL，并重点关注sent_lsn列的值，记为lsn1。
        ```
        select * from pg_stat_replication;
        ```
        
     
     2. 主机上查询当前位点信息，记为lsn2。
        ```
        select pg_current_wal_lsn();
        ```
        
     
     3. 计算主机当前位点和发送的位点的距离。
        ```
        select  pg_size_pretty(pg_wal_lsn_diff(lsn1,lsn2));
        ```
        
      
   
   - 若未超过指标阈值，可进行后续步骤排查。
    
2. 排查只读副本回放延迟高。 只读实例上复制延迟出现原因是，当只读实例有长事务或者业务繁忙时,只读上的查询与日志回放出现冲突，只读副本没有将其查询信息反馈给主机，导致回放被延迟。此时可以下载只读实例的错误日志，查看错误日志中是否包含此类报错。
   ```
   ERROR: canceling statement due to conflict with recovery
   Detail:  User query might have needed to see row versions that must be removed
   ```
   - 若日志中包含此类报错，建议业务按如下方式排查处理。
     - 避免长事务，排查长事务请参考[长事务问题定位及处理方法](https://support.huaweicloud.com/usermanual-rds-pg/rds_pg_08_00010.html)。
     
     - 只读hot_standby_feedback设置为on，可以减少只读的查询冲突。
      
   
   - 若无此类报错，可进行后续步骤排查。
    
3. 排查主机和只读副本之间网络延迟。 主机和只读副本之间网络延迟高的表现一般为如下情况，若符合以下现象，可[提交工单](https://console.huaweicloud.com/ticket/?locale=zh-cn#/ticketindex/createIndex)进行问题具体原因定位。
   在主机上查询sent_lsn和只读副本上pg_last_wal_receive_lsn接收位点的查询结果差异较大，可使用root用户执行如下SQL来查看。
   1. 在主机上执行以下SQL，并重点关注sent_lsn列的值，记为lsn1。
      ```
      select * from pg_stat_replication;
      ```
      
   
   2. 在只读上查询pg_last_wal_receive_lsn()，接收位点的值，记为lsn2。
      ```
      select pg_last_wal_receive_lsn();
      ```
      
   
   3. 计算主机当前发送位点和只读当前接收位点的距离。
      ```
      select  pg_size_pretty(pg_wal_lsn_diff(lsn1,lsn2));
      ```
      
    
 
