2.pg_start_backup备份及使用

1.pg_start_backup 介绍

pg_start_backup() 和 pg_stop_backup()是postgreSQL提供的一种备份方式。

1.1 pg_start_backup:

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的功能。

1.2 pg_stop_backup:

 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

2.优缺点

2.1 优点:

 相比pg_basebackup 无需创建相关用户或配置 pg_hba.conf 文件 
 pg_start_backup() 和 pg_stop_backup()的使用是不需要开启归档的(强烈建议开启)
 备份脚本相对更通用

2.2缺点:

 无法并行备份
 备份相对麻烦,需要到数据里执行命令
 只能本地备份。

3.备份示例

1. 配置归档模式
配置归档需要编辑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.归档备份
最后拷贝强制检查点之间的所有归档日志文件, 确保备份有效性。

4.恢复示例

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'                                          # 这个说明这个流复制同步到最新的数据

5.脚本示例

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要低




posted @ 2022-02-22 12:19  www.cqdba.cn  阅读(433)  评论(0编辑  收藏  举报