作者:瀚高PG实验室(Highgo PG Lab)- 徐云鹤

数据库备机前期稳定执行备份操作,成功无报错。近期发现pg_rman无法完成备份,提示段错误并产生core文件。

通过执行pg_rman debug模式定位到checkpoint后发生错误。

postgres@备机:~> pg_rman backup -b incremental -Z -F --keep-data-days=2 --standby-host=x.x.x.x4 --standby-port=5432 -h x.x.x.x3 -p 5432 -d postgres -U repuser -w --debug -c

DEBUG: the initially configured target database : SYSTEM_IDENTIFIER = 12345678902345678 
DEBUG: the system identifier of current target database : 12345678902345678 

DEBUG: the backup target database is the same as initial configured one.

DEBUG: destination directories of backup are initialized

DEBUG: checking PostgreSQL server version

DEBUG: server version is 10.0.3

DEBUG: checking block size setting

DEBUG: (query) SELECT current_setting($1)

DEBUG:  (param:0) = block_size

DEBUG: block size is 8192

DEBUG: checking block size setting

DEBUG: (query) SELECT current_setting($1)

DEBUG:  (param:0) = wal_block_size

DEBUG: wal block size is 8192

DEBUG: data checksum disabled on the initially configured database

INFO: copying database files

DEBUG: executing pg_start_backup()

DEBUG: (query) SELECT * from pg_walfile_name_offset(pg_start_backup($1, $2, $3))

DEBUG:  (param:0) = 2021-08-05 11:42:31 with pg_rman

DEBUG:  (param:1) = true

DEBUG:  (param:2) = false

DEBUG: backup start point is (WAL file: 00000001000004700000008C, xrecoff: 99072)

DEBUG: (query) SELECT * FROM pg_last_wal_replay_lsn()

DEBUG: (query) CHECKPOINT

段错误(core dumped) 

通过查询源码定位到是backup.c中执行do_backup_database函数抛出的异常。

为定位到具体报错行,工程师决定对pg_rman进行重新编译。并添加-g参数,便于使用gdb进行分析定位。

首先修改pg_rman源码中Makefile文件中相关编译参数,找到如下行,在后边添加-g关键字,保存。

PG_CPPFLAGS = -I$(libpq_srcdir) -lm -g

使用make &&make install 重新编译安装。

然后重新运行pg_rman备份命令,生成新的core文件。

通过gdb进行调试,调试命令及结果如下。
记一次pg_rman备份postgresql数据库报段错误的处理过程_数据库报段错误
通过上边结果定位到是dir.c的第95行pgFileNew函数执行报错,传入这个函数的参数包括/sxxxxxxxxxxxx1,怀疑是该目录引起的报错,对该目录进行排查。

排查发现存在data目录下存在一个软连接,软连接指向为当前目录,当前目录还存在一个软连接指向自己,导致pg_rman读取该目录的时候造成死循环现象。

与相关人员进行确认,是由于该文件创建错误。经同意后进行删除。

验证后问题不再出现。

至此问题解决。