KingbaseES V8R6 流复制冲突分类以及对应解决方案
背景
据实施人员反馈发现如下报错:
FATAL: terminating connection due to conflict with recovery
DETAIL: User query might have needed to see row versions that must be removed.
HINT: In a moment you should be able to reconnect to the database and repeat your command.
很明显报错说明发生了查询冲突现象,下面来讲解并分析一下流复制冲突以及如何避免。
提前说明:一切避免冲突的手段都可能导致主节点的垃圾回收做无用功, 费劲IO和CPU却不回收垃圾.
什么是复制冲突?
每当恢复过程无法将 WAL 信息从主服务器应用到备用服务器时,就会发生复制冲突,因为主库的更改会造成备库查询中断。
复制冲突类型
快照复制冲突
这是最常见的复制冲突。基于mvcc特性。
如果主库VACUUM 处理表并删除死元组,则可能发生快照冲突。此删除将在备用服务器上replay。现在备用数据库上的查询可能在主数据库上的 VACUUM 之前开始(它有一个较旧的快照),所以它仍然可以看到应该删除的元组。这构成了快照冲突。
锁复制冲突
备用服务器上的查询在它们正在读取的表上使用ACCESS SHARE锁。因此,必须在备用数据库上重放主数据库上的任何 ACCESS EXCLUSIVE 锁(与 ACCESS SHARE 冲突),例如 DROP TABLE、TRUNCATE 和许多 ALTER TABLE 等语句。如果备用数据库应该在查询使用的表上重放这样的锁,我们就会发生锁冲突。
buffer pin复制冲突
减少对 VACUUM 需求的一种方法是使用 HOT 更新。然后在主节点上的任何查询访问具有仅死堆的页面并且可以获得排他锁将修剪HOT链。(查询修改时页面,缩短热链。加轻量级锁)数据库总是持有这样的页面锁定时间很短,因此与主节点上的处理没有冲突。页面锁定还有其他原因,但这可能是最常见的原因。
When the standby server should replay such an exclusive page lock and a query is using the page (“has the page pinned”), you get a buffer pin replication conflict. Pages can be pinned for a while, for example during a sequential scan of a table on the outer side of a nested loop join. (当从库上有nest loop join, 并且外表是全表扫描, 而且刚好这个外表有prune HOT chains的wal replay时, 这个replay可能长时间等待).
HOT chain pruning can of course also lead to snapshot replication conflicts. (HOT chain pruning也会导致snapshot 冲突)
罕见的复制冲突
- 死锁复制冲突:在使用从主数据库重放 WAL 所需的共享缓冲区时对备用块的查询。数据库会立即取消这样的查询。
- 表空间复制冲突:一个表空间在备用服务器上的 temp_tablespaces 中,并且一个查询在那里有临时文件。当主数据库发生 DROP TABLESPACE 时,我们会遇到冲突。在这种情况下,数据库会取消备用数据库上的所有查询。
- 数据库复制冲突:如果备用数据库在数据库上有活动会话,则 DROP DATABASE 的复制会导致冲突。在这种情况下,数据库会终止与备用数据库的所有连接。
监控复制冲突
统计视图 pg_stat_database_conflicts 包含自上次统计重置以来发生的所有复制冲突的详细说明。必须在备用服务器而不是主服务器上查看该视图,因为那是发生复制冲突的地方。
请注意,此视图不会显示发生的所有复制冲突,它仅显示导致在备用数据库上取消查询的那些。
避免流复制冲突
避免所有冲突
显然,如果备库上没有查询,就不会有复制冲突。因此,可以在备库上设置 hot_standby=off,则不会发生冲突问题。
但是,只有备库专门用于高可用性才可以使用上面的配置,如果用于读写分离场景,这样做就违背初衷了。
避免快照冲突
减少此类冲突的方法是防止主库删除备库上仍然可见的死元组。可以通过以下两个参数实现:
- 将主库上的 hot_standby_feedback 设置为on。它阻止
VACUUM
移除最近死亡的元组,就有可能导致主库上的表膨胀。默认情况下,没有启用该设置。 - 将主库上 vacuum_defer_cleanup_age 参数设置为大于0的值。VACUUM将不会立即清除死元组,除非超过了 vacuum_defer_cleanup_age 指定的事务数据的旧值。还不如 hot_standby_feedback 那么具体明确,还可能导致表膨胀。
hot_standby_feedback = on 将消除大多数快照复制冲突,但不一定消除buffer pin冲突。
避免锁冲突
避免锁冲突的明显措施是不发出对表使用ACCESS EXCLUSIVE锁的语句。例如:DROP TABLE、TRUNCATE、LOCK、DROP INDEX、DROP TRIGGER、ALTER TABLE。
但是有一种ACCESS排他锁是无法通过这种方式避免的:来自VACUUM截断的锁。当VACUUM完成了对表的处理,并且表末尾的页变为空时,它会尝试在表上获得一个短的ACCESS EXCLUSIVE锁。如果成功,它将截断空页并立即释放锁。虽然这类锁不会中断主库上的处理,但它们可能导致备库上的复制冲突
避免VACUUM截断的方法
- 从KingbaseESV8R6开始,可以针对单个表的禁用此功能
ALTER TABLE test SET(vacuum_truncate = off);
- 将主库上的old_snapshot_threshold设置为-1以外的值。这会禁用VACUUM截断,这是未被记录的副作用。
避免buffer pin冲突
没有很好的方法可以避免这些冲突。也许可以减少 HOT 更新的数量,但这会损害主节点的性能。
解决复制延迟的代价
当hot_standby_feedback=on。
如果备库出现了LONG QUERY,或者Repeatable Read的长事务,并且主库对备库还需要或正查询的数据执行了更新并产生了垃圾时,主库会保留这部分垃圾版本(与vacuum_defer_cleanup_age参数效果类似)。
代价1,主库对应对象膨胀,因为垃圾版本要延迟若干个事务后才能被回收。
代价2,重复扫描垃圾版本,重复耗费垃圾回收进程的CPU和IO资源。(n_dead_tup会一直处于超过垃圾回收阈值的状态,从而autovacuum 不断唤醒worker进行回收动作)。
当主库的 autovacuum_naptime=很小,同时autovacuum_vacuum_scale_factor=很小时,尤为明显。
代价3,如果期间发生大量垃圾,垃圾版本可能会在事务到达并解禁后,爆炸性的被回收,产生大量的WAL日志,从而造成WAL的IO峰值。
当设置参数max_standby_archive_delay, max_standby_streaming_delay时,
代价,如果备库的QUERY与APPLY(恢复进程)冲突,那么备库的apply wal会出现延迟,也许从备库读到的是很久以前的数据,导致备库的数据过于陈旧。
请注意,如果备用服务器在应用 WAL 方面落后,则您无需在故障转移期间丢失更多数据——WAL 信息仍会流式传输到备用服务器并写入 sys_wal。但是备用数据库需要更长的时间才能追平,因此有故障转移时间会增加的风险。
结论
对于读写分离的集群模式架构,想解决复制冲突,
则必须调整 hot_standby_feedback、max_standby_streaming_delay 和 Vacuum_truncate 存储参数,以尽可能少地取消查询,同时避免过度的表膨胀和长时间的复制延迟。
解决流复制会造成表膨胀,所谓鱼与熊掌不可兼得。如果可以和业务协调,尽量不要把备库的查询和主库的DDL语句放同一时间段执行。
KingbaseES V8R6 流复制冲突分类以及对应解决方案的更多相关文章
- KingbaseES V8R6集群部署案例之---Windows环境配置主备流复制(异机复制)
案例说明: 目前KingbaseES V8R6的Windows版本不支持数据库sys_rman的物理备份,可以考虑通过建立主备流复制实现数据库的异机物理备份.本案例详细介绍了,在Windows环境下建 ...
- KingbaseES V8R6集群部署案例之---Windows环境配置主备流复制(同一主机)
案例说明: 目前KingbaseES V8R6的Windows版本不支持数据库sys_rman的物理备份,可以考虑通过建立主备流复制实现数据库的异机物理备份.本案例详细介绍了,在Windows环境下建 ...
- KingbaseES R6 手工创建主备流复制案例
数据库版本: TEST=# select version(); version ---------------------------------------------------------- ...
- KingbaseES R6 集群创建流复制只读副本库案例
一.环境概述 [kingbase@node2 bin]$ ./ksql -U system test ksql (V8.0) Type "help" for help. test= ...
- KingbaseES R6 主备流复制集群创建级联复制案例
案例环境: 数据库: test=# select version(); version -------------------------------------------------------- ...
- 命令行部署KingbaseES流复制+切换测试
建立系统数据库安装用户组及用户,在所有的节点执行 root用户登陆服务器,创建用户组及用户并且设置密码 groupadd -g 2000 kingbase useradd -G kingbase -g ...
- KingbaseES V8R6集群维护案例之--单实例数据迁移到集群案例
案例说明: 生产环境是单实例,测试环境是集群,现需要将生产环境的数据迁移到集群中运行,本文档详细介绍了从单实例环境恢复数据到集群环境的操作步骤,可以作为生产环境迁移数据的参考. 适用版本: Kingb ...
- KingbaseES V8R6集群运维案例之---repmgr standby promote应用案例
案例说明: 在容灾环境中,跨区域部署的异地备节点不会自主提升为主节点,在主节点发生故障或者人为需要切换时需要手动执行切换操作.若主节点已经失效,希望将异地备机提升为主节点. $bin/repmgr s ...
- Oracle 流复制实践笔记
最近因为业务需求,需要在两个数据库之间做双向实时同步,遂实践了一把Oracle的流复制,遇到了很多疑难问题,最终也貌似成功,现记录如下. 我是使用OEM来实现流复制的. 10.进行流复制的两个数据库的 ...
- postgresSQL主从流复制安装
命令行运维: https://blog.csdn.net/zhangzeyuaaa/article/details/77941039 安装流程: 先准备类库: yum -y install readl ...
随机推荐
- Java集合框架学习(十五) ListIterator接口详解
ListIterator介绍 一个为list对象设计的迭代器,允许开发人员在2个方向上迭代,修改和获得list迭代位置. ListIterator 没有所谓当前元素. 它的游标位置总是位于previo ...
- 摸鱼快报:golang net/http中的雕虫小技
以后会开一个板块,摸鱼快报,快速记录这几周开发中雕虫小技. 1. 向开发环境localhost:3000种植cookie 前端使用Create React App脚手架,默认以localhost:30 ...
- Kotlin 函数 与 lambda 表达式
一.函数 代码块函数体: fun sum(x: Int, y: Int): Int { return x + y } 表达式函数体: fun sum(x: Int, y: Int) = x + y 使 ...
- 一分钟带你了解mySql执行SQL的内部原理
1.把MySQL当个黑盒子一样执行SQL语句 我们知道执行了insert语句之后,在表里会多出来一条数据:执行了update语句之后,会对表里的数据进行更改:执行了delete语句之后,会把表里的一条 ...
- sql组合索引怎样使用?怎样命中?
一.联合索引的使用 本文中联合索引的定义为(MySQL): ALTER TABLE table_name ADD INDEX (col1,col2,col3); 二.联合索引的本质 当创建(col1, ...
- 【Azure 存储服务】Azure Data Lake Storage (ADLS) Gen2 GRS Failover是否支持自动切换或者手动切换到灾备的终结点呢?
问题描述 在Azure的存储服务中,介绍灾备恢复和Storage Account故障转移的文档中,有一句话"Account failover is not supported for sto ...
- 手把手带你快速上手香橙派AIpro
本文分享自华为云社区<香橙派AIpro快速上手指南>,作者:昇腾CANN. 1 前言 作为业界首款基于昇腾深度研发的AI开发板,Orange Pi AIpro无论在外观上.性能上还是技术服 ...
- XWAF安装遇到的坑
存在的问题:需要的编译环境没有安装配置好的话出现下面的问题: 1.error: Microsoft Visual C++ 14.0 or greater is required. Get it wit ...
- .vscode\settings.json .gitignore 项目文件配置
一.项目本地新增配置文件: .vscode\settings.json { // editor "editor.formatOnSave": true, "e ...
- vscode git冲突 1. git stash 2. 更新代码 3. git stash pop 4.提交代码
vscode git冲突 1. git stash 2. 更新代码 3. git stash pop 4.提交代码