
# WAL日志堆积问题定位及处理方法
#### 指标异常说明
PostgreSQL使用WAL（Write-Ahead Logging）日志机制来保证数据的持久性和一致性。WAL 日志记录了对数据库的所有更改操作，在主备复制、崩溃恢复、逻辑复制等场景中都扮演关键角色。
数据库提供了以下与WAL日志相关的监控指标，建议重点关注以下指标：
- 事务日志使用量（WAL日志）：rds040_transaction_logs_usage
- 非活跃逻辑复制槽数量：inactive_logical_replication_slot
- 最滞后副本滞后量（因复制槽积压的WAL日志）：rds045_oldest_replication_slot_lag
- 事务日志生成速率：rds044_transaction_logs_generations
 
#### 排查及解决方法
- **查看WAL日志大小是否异常并进行处理**
  首先通过查看监控rds040_transaction_logs_usage，观察WAL日志占用容量大小。观察WAL日志大小近期是否有明显上涨，或WAL日志占比磁盘容量较大。
  也可以通过下述SQL，查看WAL日志大小。如果发现WAL非常多，可以通过后续步骤依次排查。
  ```
  select pg_size_pretty(sum(size)) from pg_ls_waldir();
  ```
  
- **查看复制槽状态及延迟未清理的日志大小**
  复制槽会阻塞WAL的回收，查看监控指标inactive_logical_replication_slot如果不为0，且rds045_oldest_replication_slot_lag的堆积的WAL日志数据较大，甚至与rds040_transaction_logs_usage基本一致，表示复制槽阻塞WAL日志回收。
  或者通过下述SQL查询slot状态及WAL日志滞后量：
  ```
  select slot_name, active,
  pg_size_pretty(pg_wal_lsn_diff(b, a.restart_lsn)) as slot_latency
  from pg_replication_slots as a, pg_current_wal_lsn() as b;
  ```
  如果查询结果中，active字段存在'f' 状态的slot，并且slot_latency字段的大小很大，表示非活跃复制槽阻塞了WAL日志回收，导致WAL日志堆积无法清理。
  需要分析该复制槽是否还需要，如果不需要，建议执行删除slot命令的SQL：
  ```
  select pg_drop_replication_slot('slot_name');
  ```
  
- **查看WAL日志保留相关参数**
  查看数据库参数"wal_keep_segments"、"wal_keep_size"、"max_wal_size"的值是否设置过大。
  ```
  select name, setting from pg_settings where name in ('wal_keep_segments', 'wal_keep_size', 'max_wal_size');
  ```
  - 参数含义如下：
    - wal_keep_segments：指定pg_wal目录中保留的最小历史日志文件段数，单位16MB。
    
    - wal_keep_size：指定pg_wal目录中保留的历史WAL文件的最小大小，单位MB。
    
    - max_wal_size：设置触发一次检查点的WAL尺寸，仅当WAL日志超过该参数才会清理，单位MB。
     
  
  - 对于RDS for PostgreSQL 12及以下版本，查看"wal_keep_segments"参数的值；对于12以上版本，查看"wal_keep_size"参数的值。
  
  - WAL日志保留参数的值不宜太大，一般设置要小于磁盘总空间的10%；也不宜太小，一般要大于4GB，否则容易导致主库将备库需要的wal日志清理，进而导致备库异常。
   
- **查看写业务繁忙程度**
  可以通过rds044_transaction_logs_generations指标查看写业务繁忙程度，该指标表示平均每秒生成的事务日志（WAL日志）大小。
  如果该指标较大（平均超过50MB/s)，说明写业务较多，数据库内核会自动预留更多的WAL日志以便回收使用，WAL日志占用的磁盘空间会增加，建议通过磁盘扩容保证一定的磁盘冗余。
  
 
#### 备份期间的WAL日志
如果WAL上升时，数据库处于备份状态，在备份完成后，WAL日志大小恢复正常，则表示备份期间WAL日志生成较快，导致备份速度赶不上生成速度。
可以调整备份时间，避免备份期间存在大量数据写入，或者扩大磁盘留足缓存容量。
