暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

postgresql 查询冲突

原创 Oracle 2023-01-03
1365

查询冲突
什么是查询冲突?
备库在查询时可能会遇到如下错误
ERROR:canceling statement due to confilct with recovery。
为什么会产生冲突呢?我们细想一下,比如说备库正在执行基于某个表的查询(这个查询可能是应用产生的,也可能是手动连接进行的查询),这时主库执行了drop table操作,该操作写入wal日志后传至备库进行应用,为了保证数据一致性,postgresql必然会迅速回放数据,这时drop table和select就会形成冲突。如下图所示:

冲突场景:
上面只介绍了1种查询冲突的情况。总结一下有以下几种情况
1.主库排他锁(包括显示LOCK命令和各种DDL)
2.主库vacuum清理死元组,从库如果正在使用该元组,就会产生冲突
3.主库删除了从库查询正在使用的表空间
4.主库删除了从库正在使用的数据库



试想在仅有主库的情况下:
场景1:一个会话发起了drop table,此时发现有select语句正在执行,那么该会话只能等待select完成其事务。
场景2:一个会话发起vacuum或后台自动vacuum,不会与当前库查询发生冲突,因为vacuum不会清理正在使用的元组。

从库的处理就不同。因为主库不知道从库的事务状态,而从库又需要与主库保持一致,所以才发生了“查询冲突”

查询冲突参数
hot_standby_feedback:
这个参数是查询冲突这个话题中提到最多的参数,下面我们详细探讨一下。我们假设在没有备库的情况下,会话1查询某行数据,会话2删除该数据,然后commit,此时会话2执行一次vacuum,我们知道这次vacuum并不会删除该行数据,因为会话1的事务还需要使用该元组,所以不会清理该元组。那么如果是主从呢?主库在准备进行vacuum时怎么知道从库还在进行查询,这就是设置该参数的意义,设置hot_standby_feedback参数之后备库会定期向主库通知最小活跃事务id(xmin)值,这样使得主库vacuum进程不会清理大于xmin值的事务。
这个参数有利于减少冲突的发生,但并不能完全避免冲突,其实细想一下,这个参数只是减少了由于主库vacuum死亡元组造成的冲突,并不能解决排他锁造成的冲突。或者由于网络中断造成的冲突,假如主备之间的网络中断后,备库就无法向主库正常发送xmin值,如果时间够长,主库在这段时间内还是会清理无用元组,这样网络恢复后就可能发生上面的vacuum造成的冲突。
值得注意的是hot_standby_feedback参数并不会覆盖主库上old_snapshot_threshold参数限定的值,old_snapshot_threshold参数限制了死亡元组的无限膨胀,当事务信息超过old_snapshot_threshold的限制时,依然会进行清理。

max_standby_streaming_delay:
备机因为接收wal流日志产生查询冲突而取消查询之前的等待时间,设置该参数会在发生冲突时,备库查询不会立即取消,而是等待一个时间后如果还没结束再抛出报错。这个值的大小可以参考备库可能产生的长事务运行时间。

max_standby_archive_delay:
备机因为处理归档的wal日志产生查询冲突而取消查询之前的等待时间,和上面的参数类似。

vacuum_defer_cleanup_age:
指定vacuum延迟清理死亡元组的事务数,vacuum会延迟清除无效的记录,延迟的事务个数通过vacuum_defer_cleanup_age进行设置。即vacuum和vacuum full操作不会立即清理刚刚被删除元组

可以根据pg_stat_database和pg_stat_database_conflicts视图查看冲突发生的情况





原文链接:https://blog.csdn.net/qq_40687433/article/details/120000817

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论