【标题描述】:
【测试类型:工具功能】【测试版本:2.1.0】
一主一备场景下,只启动主库并且最大可用模式most_available_sync设置为on,备库执行gs_basebackup创建副本期间,主库写入数据阻塞,最大可用模式无效
【操作系统和硬件信息】(查询命令: cat /etc/system-release, uname -a):
CentOS Linux release 7.6.1810 (Core)
【测试环境】(单机/1主x备x级联备):
一主一备
【被测功能】:
一主一备场景下,只启动主库并且最大可用模式most_available_sync设置为on,备库执行gs_basebackup创建副本期间,主库写入数据阻塞,最大可用模式无效
【测试类型】:
可用性
【数据库版本】(查询命令: gaussdb –V):
gaussdb (openGauss 2.1.0 build 590b0f8e) compiled at 2021-09-30 14:29:04 commit 0 last mr
【预置条件】:
1、配置主库(192.168.56.103)实例的postgresql.conf参数
listen_addresses = '*'
port = 5432
pgxc_node_name = gauss_ha
shared_buffers = '1024MB'
work_mem = '48MB'
enable_data_replicate = off
replication_type = 1
max_connections = 500
remote_read_mode = 'non_authentication'
most_available_sync = on
log_destination = 'stderr'
logging_collector = on
password_encryption_type = 0
synchronous_commit = on
synchronous_standby_names = '*'
unix_socket_directory = '/tmp'
hot_standby = on
max_wal_senders = 10
wal_keep_segments = 8
wal_level = 'hot_standby'
application_name = 'gauss_node_1'
replconninfo1 = 'localhost=192.168.56.103 localport=5434 localheartbeatport=5435 localservice=5436 remotehost=192.168.56.114 remoteport=5434 remoteheartbeatport=5435 remoteservice=5436'
2、启动主库(192.168.56.103)
gs_ctl -D data5432 -l data5432/db.log -M primary start
3、往主库(192.168.56.103)写入数据
create table test(id1 int,id2 int);
insert into test SELECT generate_series(1,5000000) as key, (random()*(10^3))::integer; --执行多次,使得实例目录达到10G左右容易复现,此时最大可用模式生效,因此可以写入
4、创建测试表
create table t1 (id int);
【操作步骤】(请填写详细的操作步骤):
gs_basebackup -D data5432 --h192.168.56.103 -p5432
insert into t1 values (1);
【预期输出】:
上述操作步骤2中insert语句能写入
【实际输出】:
上述操作步骤2中insert语句处于阻塞状态,直到备库(192.168.56.114)的gs_basebackup执行完成,insert语句才结束
【原因分析】:
这个问题的根因
walsender有四种角色,参考内核源码枚举类型SndRole,产生此缺陷的根因是用于gs_basebackup命令的walsender角色不是SNDROLE_PRIMARY_BUILDSTANDBY,导致SyncRepCheckSyncStandbyAlive函数内判断是否切换为standalone模式错误。
问题推断过程
a) 分析函数SyncRepCheckSyncStandbyAlive函数,发现walsender角色为SNDROLE_PRIMARY_DUMMYSTANDB和SNDROLE_PRIMARY_STANDBY才有可能从standalone模式变为非standalone模式,也就是说gs_basebackup客户端对应的walsender的角色,是上述两种角色的其中一种,但我们预期该walsender的角色是SNDROLE_PRIMARY_BUILDSTANDBY。
b) 分析InitWalSnd函数,发现只有变量t_thrd.postmaster_cxt.senderToBuildStandby为true时,walsender的角色才是SNDROLE_PRIMARY_BUILDSTANDBY
c) 分析ProcessStartupPacket函数发现,只有客户端名称是gs_ctl,t_thrd.postmaster_cxt.senderToBuildStandby变量才会为真,但该缺陷实际执行build的客户端是gs_basebackup,因此t_thrd.postmaster_cxt.senderToBuildStandby变量为false,也就是说该walsender的角色是SNDROLE_PRIMARY_STANDBY,这导致SyncRepCheckSyncStandbyAlive函数内误判存在同步备库,导致主库写入阻塞
还有哪些原因可能造成类似现象
该问题是否有临时规避措施
问题解决方案
在ProcessStartupPacket,如果客户端是gs_basebackup,把变量t_thrd.postmaster_cxt.senderToBuildStandby设置为true
预计修复问题时间
【日志信息】(请附上日志文件、截图、coredump信息):
【测试代码】:
见操作步骤
Hey @wenger, Welcome to openGauss Community.
All of the projects in openGauss Community are maintained by @opengauss-bot.
That means the developers can comment below every pull request or issue to trigger Bot Commands.
Please follow instructions at https://gitee.com/opengauss/community/blob/master/contributors/command.en.md to find the details.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
登录 后才可以发表评论