记一次pg_rman备份postgresql数据库报段错误的处理过程
数据库备机前期稳定执行备份操作,成功无报错。近期发现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进行调试,调试命令及结果如下。
通过上边结果定位到是dir.c的第95行pgFileNew函数执行报错,传入这个函数的参数包括/sxxxxxxxxxxxx1,怀疑是该目录引起的报错,对该目录进行排查。
排查发现存在data目录下存在一个软连接,软连接指向为当前目录,当前目录还存在一个软连接指向自己,导致pg_rman读取该目录的时候造成死循环现象。
与相关人员进行确认,是由于该文件创建错误。经同意后进行删除。
验证后问题不再出现。
至此问题解决。