399 Star 1.3K Fork 1.5K

GVPopenGauss / openGauss-server

 / 详情

执行gs_basebackup期间最大可用模式无效

已完成
缺陷
创建于  
2021-10-22 16:00

【标题描述】:
【测试类型:工具功能】【测试版本: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);

【操作步骤】(请填写详细的操作步骤):

  1. 在备库(192.168.56.114)执行
gs_basebackup -D data5432 --h192.168.56.103 -p5432
  1. 在备库(192.168.56.114)执行gs_basebackup期间,在主库(192.168.56.103)执行
insert into t1 values (1);

【预期输出】:
上述操作步骤2中insert语句能写入

【实际输出】:
上述操作步骤2中insert语句处于阻塞状态,直到备库(192.168.56.114)的gs_basebackup执行完成,insert语句才结束
【原因分析】:

  1. 这个问题的根因
    walsender有四种角色,参考内核源码枚举类型SndRole,产生此缺陷的根因是用于gs_basebackup命令的walsender角色不是SNDROLE_PRIMARY_BUILDSTANDBY,导致SyncRepCheckSyncStandbyAlive函数内判断是否切换为standalone模式错误。

  2. 问题推断过程
    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函数内误判存在同步备库,导致主库写入阻塞

  3. 还有哪些原因可能造成类似现象

  4. 该问题是否有临时规避措施

  5. 问题解决方案
    在ProcessStartupPacket,如果客户端是gs_basebackup,把变量t_thrd.postmaster_cxt.senderToBuildStandby设置为true

  6. 预计修复问题时间

【日志信息】(请附上日志文件、截图、coredump信息):
输入图片说明
输入图片说明
【测试代码】:
见操作步骤

评论 (1)

wenger 创建了缺陷

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.

wenger 修改了描述
wenger 修改了描述
wenger 修改了描述
zhangxubo 添加了
 
sig/storageengine
标签
wenger 负责人设置为wenger
wanglei 优先级设置为主要
赵文浩 负责人wenger 修改为chenxiaobin
chenxiaobin 任务状态待办的 修改为已确认
chenxiaobin 任务状态已确认 修改为修复中
chenxiaobin 任务状态修复中 修改为已完成

登录 后才可以发表评论

状态
负责人
项目
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
预计工期 (小时)
参与者(2)
5622128 opengauss bot 1581905080
C++
1
https://gitee.com/opengauss/openGauss-server.git
git@gitee.com:opengauss/openGauss-server.git
opengauss
openGauss-server
openGauss-server

搜索帮助