openGauss备机追数Catchup过程中主库写入阻塞问题
最近在测试openGauss主从复制时发现一个问题:当备机落后主机很多时(比如停了一段时间后再启动),启动后会自动的追数,追数的过程状态是catchup,而在catchup的过程中,主库上的写入会全部阻塞,当然经过进一步验证,如果存在其他正常的备库(状态是normal),那么其中一个备库catchup不会阻塞主库。
下面我们来复现一下这个问题,由于openGauss主从搭建会自动创建物理复制槽,所以备库需要的xlog主库不会自动清理,那么我们就可以先把两个备库都停掉(我这里的环境是一主两备),然后在主库插入大量数据,产生大量xlog的堆积,然后过一段时间再挨个开启备库,查看追数过程中tps的影响。
停止两个备库
[omm@db02 ~]$ gs_ctl stop
[2020-09-16 14:03:56.724][89873][][gs_ctl]: gs_ctl stopped ,datadir is (null)
waiting for server to shut down.... done
server stopped
[omm@db03 ~]$ gs_ctl stop
[2020-09-16 14:04:03.525][60271][][gs_ctl]: gs_ctl stopped ,datadir is (null)
waiting for server to shut down.... done
server stopped
使用压测工具对主库进行并发插入,并观察xlog个数
可以看到xlog在逐步堆积
199
199
199
203
210
217
224
231
238
245
253
260
267
274
tps比较稳定
14:04:58 22254
14:04:59 23582
14:05:00 23937
14:05:01 23316
14:05:02 22994
14:05:03 23452
14:05:04 23920
14:05:05 24097
14:05:06 23886
14:05:07 21578
14:05:08 22731
14:05:09 23315
14:05:10 24749
此时启动第一个备库,观察状态
[omm@db02 ~]$ gs_ctl start -M standby
[omm@db02 ~]$ gs_ctl query
[2020-09-16 14:07:48.392][108727][][gs_ctl]: gs_ctl query ,datadir is (null)
HA state:
local_role : Standby
static_connections : 2
db_state : Catchup
detail_information : Normal
Senders info:
No information
Receiver info:
receiver_pid : 108470
local_role : Standby
peer_role : Primary
peer_state : Normal
state : Catchup
sender_sent_location : 2B/B6800000
sender_write_location : 2D/A2F5B7D8
sender_flush_location : 2D/A2F5B7D8
sender_replay_location : 2D/A2F5B7D8
receiver_received_location : 2B/B6800000
receiver_write_location : 2B/B6000000
receiver_flush_location : 2B/B6000000
receiver_replay_location : 2B/B4C1E548
sync_percent : 95%
channel : 192.168.1.2:38782<--192.168.1.1:5533
tps如下:
14:06:14 19037
14:06:15 18776
14:06:16 19302
14:06:17 11734
14:06:18 0
14:06:19 0
14:06:20 0
14:06:21 0
14:06:22 0
14:06:23 0
14:06:24 0
14:06:25 0
14:06:26 0
14:06:27 0
14:06:28 0
14:06:29 0
14:06:30 0
14:06:31 0
14:06:32 0
14:06:33 0
14:06:34 0
14:06:35 0
14:06:36 0
14:06:37 0
14:06:38 0
14:06:39 0
14:06:40 0
14:06:41 0
14:06:42 0
14:06:43 0
14:06:44 0
14:06:45 0
14:06:46 0
14:06:47 0
14:06:48 0
14:06:49 0
14:06:50 7753
14:06:51 12308
14:06:52 10988
14:06:53 12337
直到catchup状态变为normal时tps才恢复正常
启动第二个备库:
[omm@db03 ~]$ gs_ctl start -M standby
观察状态,虽然sync_percent没有完全同步完,状态是catchup,(有时候也有可能是normal,可能和主备启动时间间隔有关),因为此时已经有一个正常同步的备库,这时第二个备库在追数过程中不会影响主库。
[omm@db03 ~]$ gs_ctl query
[2020-09-16 14:09:19.995][74488][][gs_ctl]: gs_ctl query ,datadir is (null)
HA state:
local_role : Standby
static_connections : 2
db_state : Normal
detail_information : Normal
Senders info:
No information
Receiver info:
receiver_pid : 73921
local_role : Standby
peer_role : Primary
peer_state : Normal
state : Catchup
sender_sent_location : 2C/3F800000
sender_write_location : 2D/D5F901D8
sender_flush_location : 2D/D5F901D8
sender_replay_location : 2D/D5F901D8
receiver_received_location : 2C/3F800000
receiver_write_location : 2C/3D000000
receiver_flush_location : 2C/3D000000
receiver_replay_location : 2C/2B070088
sync_percent : 96%
channel : 192.168.1.3:30200<--192.168.1.1:5533
tps一直比较稳定
14:07:14 12551
14:07:15 11853
14:07:16 12530
14:07:17 12432
14:07:18 12680
14:07:19 12036
14:07:20 11758
14:07:21 11242
14:07:22 11206
14:07:23 11607
14:07:24 11926
14:07:25 11494
14:07:26 11804
14:07:27 12842
14:07:28 12613
14:07:29 12188
14:07:30 13310
14:07:31 15119
14:07:32 15165
14:07:33 14045
为了找到catchup过程中阻塞主机的根本原因,看了相关代码。
在openGauss-server/src/bin/pg_ctl/pg_ctl.cpp中有如下代码:
if (beforeStat.st_mtim.tv_sec != afterStat.st_mtim.tv_sec ||
beforeStat.st_mtim.tv_nsec != afterStat.st_mtim.tv_nsec) {
nRet = memset_s(&state, sizeof(state), 0, sizeof(state));
securec_check_c(nRet, " ", " ");
ReadDBStateFile(&state);
switch (state.state) {
case NORMAL_STATE:
case NEEDREPAIR_STATE:
case WAITING_STATE:
case DEMOTING_STATE:
case PROMOTING_STATE:
case BUILDING_STATE:
case CATCHUP_STATE:
return PQPING_OK;
case COREDUMP_STATE:
pg_log(PG_WARNING, _(" gaussDB state is %sn"), get_string_by_state(state.state));
return PQPING_NO_RESPONSE;
case STARTING_STATE:
case UNKNOWN_STATE:
default:
/* nothing to do */
break;
}
可以看到,如果数据库状态是catchup,那么代表PGPING_OK,也就是代表备机正常,那么主库收到该备机正常的信号后会去向备机同步,但是备机同步该条变更的前提是之前的xlog已经接收完成,但是当前还是catchup状态,依旧在发送日志,所以此时主库的变更都会陷入等待。PINGOK只能代表主备的连通性正常,不代表备机可以立刻提供服务,所以catchup这段时间不能认为该备机是一个正常的备机,除非当时有其他normal状态的备机。
那么如果第一个备机已经完成catchup,第二个备机再启动然后catchup追日志为什么不阻塞呢?因为synchronous_standby_names设置的是*,已经有一个备机能够同步了,不需要等待另一个备机同步了。
该问题需要提交华为解决。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- AWVS13破解版安装
- Sqlmap注入使用技巧总结
- Lyft 宣布开源基础设施工具管理平台 Clutch!
- 从库mysqldump会导致复制中断
- DBA的福音,SQL审核利器-goinception
- 前端组件设计原则
- 分析网页 JavaScript Bundles 的几种方法
- 使用 DevTools 新增的 Issues 选项卡发现网页问题
- OpenCV绘制标记函数drawMarker()
- 【crossbeam系列】3 crossbeam-deque:work-stealing算法
- 【Rust日报】2020-08-21 RustConf研讨会在线举办
- 了解不同架构思维,赏析架构之美
- 【Rust日报】2020-08-22 google/autocxx - 高度自动化的rust调用c++,而且安全,时尚
- 【Rust日报】2020-08-24 理解 Rust 的切片
- 猿实战05——手把手教你拥有自己的代码生成器