本文共 1446 字,大约阅读时间需要 4 分钟。
报错: 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操作. 转载地址:http://kvbzx.baihongyu.com/