canceling statement due to conflict with recovery

报错: 
canceling statement due to conflict with recovery 
DETAIL:  User query might have needed to see row versions that must be removed. 

Hot Standby 环境下的 standby 节点执行查询时报错,报错信息如下: 
1、执行长时间查询时报错。 
   根据错误信息,初步估计当在从库上执行查询时,与主库发生了冲突。 
           
2、网上GOOGLE ,信息如下   
   Long running queries on the standby are a bit tricky, because they 
might need to see row versions that are already removed on the master.   
备注:意思是说,长时间SQL如果跑在 standby 节点上是一个笑话,因为 standby 节点有可能需要读取主库上被 removed 的数据。    

3、解决方法,修改参数 
   根据实际情况,调大参数:max_standby_streaming_delay = 30min; 
  
   当在 Standby 提供应用时,如果 Standby 节点上的SQL 与接收主库日志发生冲突时, 
这个参数决定了从库等侍这个查询的时间,默认值为 30s, 有SQL执行时间估计在二分钟左 
右,从而被 Standby库主动 Cancel 了。也可以将这个参数设置成 -1. 表示 standby 节点永远等侍这个查询, 
这无疑是有风险的,如果这个查询不结束,那么从库一直处于与主库的中断状态,不会同步主库数据,而会一 
直等从库这个SQL执行完成。 

4、其他说明 
   PostgreSQL 的 Hot Standby常被用来当只读的数据库提供查询或者统计服务, 但是由于各种原因查询SQL可能被cancel掉。 
例如: 
1)主库执行了DROP某TABLE的操作, 而standby库上某用户正在查询这个表的数据. 当standby接收到了这些XLOG的信息并且 
准备在standby库上apply的时候, 如果这个SQL还在执行, 就发生冲突了, 这个时候standby 要判断是否要cancel掉这个SQL 
使得apply可以正常进行下去, 或者standby选择等待多长时间. 

2)主库执行删除表空间或者删除库等相关的操作也会遇到上面的问题. 

3)更隐晦的是主库上执行了vacuum操作, 这些被vacuum掉的tuple, 可能是standby库上的SQL可见的TUPLE, 也会发生冲突. 

4)还有其他原因 

那么Standby根据什么来判断是CANCEL SQL还是选择等待, 如果等待, 等多长时间?有两个参数控制: 
max_standby_archive_delay 
max_standby_streaming_delay 

    如果值等于-1表示永不因为recovery 和SQL冲突原因cancel standby上的SQL. 
    如果设置了一个值如30秒, 那么在cancel 冲突的SQL前, 会等待,通过GetStandbyLimitTime来判断是否要触发CANCEL SQL, 当GetStandbyLimitTime返回的值为0 时表示永不触发CANCEL, 如果返回的是一个时间值, 这个时间值和当前时间进行比较,如果小于当前时间则进行CANCEL操作.
上一篇:pg 序列


下一篇:postgresql dblink 使用