作者:Asher.hu
原文链接:【物理备份】 之 pg_start_backup 介绍及使用-Asher.hu-PGFans问答社区:全球唯一的PostgreSQL中文技术交流社区
pg_start_backup() 和 pg_stop_backup()是postgreSQL提供的一种备份方式。
1.强制发生一次checkpoint点。 将未写到磁盘上的脏数据全部刷到磁盘上去。这样从这之后产生的日志就是记录整个数据块。可以“确保”恢复的正确性。 2.置写日志标志为:XLogCtl->Insert.forcePageWrites = true,这样wal日志将会记录整个数据块。避免了在进行备份时候(读操作——旧数据)持续向数据库写入数据(写操作——新数据)造成的前后数据不一致。 需要注意的是: 在备份期间,wal日志仍然会进行循环使用,如果日志保存在小,或备份过久有可能导至数据不一致。
postgres=# \x Expanded display is on. postgres=# \df pg_start_backup List of functions -[ RECORD 1 ]-------+----------------------------------------------------------------------- Schema | pg_catalog Name | pg_start_backup Result data type | pg_lsn Argument data types | label text, fast boolean DEFAULT false, exclusive boolean DEFAULT true Type | func
第一个参数:开始记录备份的标签; 第二个参数:设置是否为快速执行,默认为false,将会做一个schedule checkpoint,把脏数据刷到磁盘。这里会等待其他checkpoint结束,有时候会等一下;如果设置为true,会尽快执行checkpoint,可能会产生大量的IO,拖慢正在执行的SQL; 第三个参数:是否是exclusive模式,既是否为独占模式;默认为true, 如果设置为false,则在调用pg_stop_back时,需要指定独占模式为false,且将返回备份标签文件里面的内容。如: select pg_stop_backup('f'); 注意: 1.如果设置为独占模式(默认是),将会把开始备份的LSN和checkpoint信息记录到标签文件。同时,如果有表空间链接,也会记录一个tablespace_map。如果是no-exclusive 模式,则不会记录,这些信息会在执行pg_stop_back时返回。 2. 那么他会不会switch一个新的wal文件呢?会不会把归档日志做完归档呢?有没有必要 ? 答案是没有必要的。 在此时拷贝数据库data文件进行恢复可能会失败,因为备份的数据可能不是在一致性下,数据文件的刷盘不可能同时完成。单纯恢复到checkpoint点应该可以,但是,只有一个备份文件是无法这样回退恢复的。因此,还需要获取到从startbackup到stopbackup之间的wal日志,以拷贝的data目录+这段wal日志进行恢复,即可恢复成功。 这也是pg_basebackup的逻辑。 3.将wal日志设置为forcepagewrites,即使没有把full_page_writes设为on,保证在startbackup期间,对数据库的写是可以完全回放的。 如果不这样做,在从checkpoint点恢复时,从新的环境的对应block进行数据回放,块的初始数据不一样,恢复后的结果就可能是错的。这点可以参考full_page_writes的功能。
pg_stop_backup则是将日志模式恢复正常,删除data目录下的备份日志文件 backup_label,返回结束LSN或者备份标记信息。 它的作用就是结束此次备份状态,以便进行下次备份(非并发性备份),一直不执行pg_stop_backup()也并不会撑爆xlog目录,但是是无法执行下次备份的。
postgres=# \df pg_stop_backup List of functions -[ RECORD 1 ]-------+------------------------------------------------------------------------------------------------------------------ Schema | pg_catalog Name | pg_stop_backup Result data type | pg_lsn Argument data types | Type | func -[ RECORD 2 ]-------+------------------------------------------------------------------------------------------------------------------ Schema | pg_catalog Name | pg_stop_backup Result data type | SETOF record Argument data types | exclusive boolean, wait_for_archive boolean DEFAULT true, OUT lsn pg_lsn, OUT labelfile text, OUT spcmapfile text Type | func
相比pg_basebackup 无需创建相关用户或配置 pg_hba.conf 文件 pg_start_backup() 和 pg_stop_backup()的使用是不需要开启归档的(强烈建议开启) 备份脚本相对更通用
无法并行备份 备份相对麻烦,需要到数据里执行命令 只能本地备份。
1.配置归档模式 2.配置归档需要编辑postgresql.conf文件:
vim /usr/local/pgsql/data/postgesql.conf archive_mode = on ---开启归档模式 archive_command = ‘cp %p /arch /%f’ ---指定归档路径 注:%p要被归档的日志文件的路径,%f是要被归档的日志文件的文件名
2. 超级用户连接数据库,执行命令:
select pg_start_backup(now()::text); 或 select pg_start_backup(‘baseline’);
3. 通过函数pg_is_in_backup();查看到备份状态
select pg_is_in_backup(); pg_is_in_backup ----------------- t (1 row) 也可以通过$PGDATA目录下生成的标签文件查看备份信息 cat $PGDATA/backup_label START WAL LOCATION: 0/DC000060 (file 0000000500000000000000DC) CHECKPOINT LOCATION: 0/DC000098 BACKUP METHOD: pg_start_backup BACKUP FROM: master START TIME: 2022-02-22 10:18:17 HKT LABEL: 2022-02-22 10:18:17.289201+08 START TIMELINE: 5
4.执行备份
# 备份整个data目录: tar –jcv –f /usr/local/pgsql/backup/baseline.tar.bz2 /usr/local/pgsql/data/ 这里是用打包成bz2 建议先安装包 yum -y install bzip2 使用操作系统工具比如 tar 或 cp -ra 等,或直接把数据目录复制到备份位置。过程中既不需要关闭数据库,也不需要停止数据库的任何操作。 如: tar -jcv -f ~/bak/pgdata.tar.bz2 $PGDATA 注意: 手动备份表空间路径,即目录的pg_tblspc软连接指向目录。 tar -jcv -f ~/bak/dbbak/tbls.tar.bz2 /pgtbls/tbls01 注意: tar -jcv的压缩及解压缩 bzip2是一个压缩能力更强的压缩程序,.bz2结尾的文件就是bzip2压缩的结果。 tar中使用-j这个参数来调用bzip2 tar -jxvf -f /dbbak/pgdata.tar.bz2 这条命令是将上面产生的包解开。
5.停止备份 : 再次以数据库超级用户身份连接数据库,然后发出命令:
这将终止备份模式并自动切换到下一个 WAL 段。 select pg_stop_backup();
6.归档备份 最后拷贝强制检查点之间的所有归档日志文件, 确保备份有效性。
1. 停止数据库,删除原库
pg_ctl –D /usr/local/pgsql/data/ stop rm –r /usr/local/pgsql/data/
2. 恢复备份
tar –jxv –f /usr/local/pgsql/backup/baseline.tar.bz2 –C /
3. 清空/data/pg_xlog/目录下所有文件
rm –r /usr/local/pgsql/data/pg_xlog/
4. 创建/pg_xlog/及其下面的archive_status目
mkdir /usr/local/pgsql/data/pg_xlog/ mkdir /usr/local/pgsql/data/pg_xlog/archive_status
5. 在/data/目录下创建 recovery.signal:告诉PostgreSQL进入正常的归档恢复
touch /usr/local/pgsql/data/recovery.signal #指定还原点 echo ' restore_command = 'cp /usr/local/pgsql/backup/archived_log/%f %p' recovery_target = 'immediate' ' >> $PGDATA/postgresql.auto.conf
6. 启动数据库检查数据
一切正常的话数据库就会自动应用WAL日志进行恢复 pg_ctl –D /usr/local/pgsql/data/ start
7.备注(如果有自定义表空间,需要以这种 copy 方式进行恢复同步): 如果作为从库(slave),则只需要把备份文件 拷贝到备库, 同时在备库的/data/目录下创建standby.signal 告诉PostgreSQL进入standby模式 并在添加如下内容:
hot_standby = on # 让从库可读 primary_conninfo = 'host=172.16.10.100 port=5432 user=repl password=replica' # 对应的主库信息 recovery_target_timeline = 'latest' # 这个说明这个流复制同步到最新的数据
vi backup.sh export LANG=en_US.utf8 export PGHOME=/u01/postgresql/pg12 export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH export DATE=`date +'%Y%m%d'` export PATH=$PGHOME/bin:$PATH:. export PGDATA=/u01/postgresql/data BASEDIR='/u01/postgresql/backup' date +%F%T if [ ! -d $BASEDIR/$DATE ]; then mkdir -p $BASEDIR/$DATE if [ $? -eq 0 ]; then psql -h 127.0.0.1 -p 5432 -U postgres postgres -c 'select pg_start_backup(now()::text)' if [ $? -eq 0 ]; then # cp -r -L $PGDATA $BASEDIR/$DATE # 这是直接cp的方式, 也可以用下面tar包的方式 # tar -cjv -f $BASEDIR/$DATE/$DATE.tar.bz2 $PGDATA tar -czv -f $BASEDIR/$DATE/$DATE.tar.gz $PGDATA else echo -e 'select pg_start_backup(now()::text) error' exit 1 fi psql -h 127.0.0.1 -p 5432 -U postgres postgres -c 'select pg_stop_backup()' date +%F%T echo -e 'backup successed' exit 0 else echo -e 'mkdir -p $BASEDIR/$DATE error' exit 1 fi else echo -e '$DATE backuped, don't backup repeated' exit 1 fi # 注意事项 tar -jcvf bz2 速度慢,压缩比高 tar -zcvf gz 速度快 ,压缩比相对要bz2要低
点击加载更多