PostgreSQL的物理备份

PostgreSQL的物理备份

1. 简单了解

1.1 pg_basebackup备份

1.1.1 简介

pg_basebackup是从postgresql 9.1版本开始提供的一个方便基础备份的工具。
pg_basebackup用于对正在运行的PostgreSQL数据库集群进行基本备份。备份是在不影响数据库的其他客户端的情况下进行的,并且可以用于时间点恢复和作为日志传送或流复制备用服务器的起点 。
pg_basebackup 不仅可以从主服务器也可以从备用服务器进行基本备份。要从备用数据库进行备份,请设置备用数据库以便它可以接受复制连接(即 setmax_wal_sendershot_standby,并对其进行pg_hba.conf适当配置)。您还需要在主节点上启用full_page_writes

1.1.2 优点

a. 可以远程备份, 通过日志可以恢复到最新
b. 可以通过备库备份
c. 备份操作相关简单

1.1.3 不足

a. 它只把整个数据库实例的数据都拷贝出来,而不只是把实例中的部分(如某个数据库或表)单独备份
b. 归档日志需要单独备份
c. 使用复制协议 REPLICATION权限或者是超级用户的用户 ID 建立连接,并且pg_hba.conf必须允许复制连接。
d.服务器还必须配置max_wal_senders设置得足够高,以提供至少一个用于备份的 walsender 和一个用于 WAL 流式传输(如果使用)。
e.如果在备份期间将备用数据库提升为主数据库,则备份将失败。

1.1.4 工作原理

1)创建检查点,打开FPW (full_page_writes) ,创建备份标签(存储检查点位置,时间等信息)
2)通过流复制协议与数据库建立连接,主库的WAL Sender进程向pg_basebackup发送数据库物理文件
3)pg_basebackup接收到文件后写入目标位置(压缩或不压缩)

1.1.5 参数说明
[fbase@localhost ~]$ pg_basebackup --help 
用法:
  pg_basebackup [选项] ...

控制输出的选项:
  -D, --pgdata=DIRECTORY  接收基本备份到目录
  -F, --format=p|t                     输出格式(plain(默认),tar)
  -r, --max-rate=RATE             传输数据目录的最大传输速率(以 kB/s 为单位,或使用后缀“k”或“M”)
  -R, --write-recovery-conf       用于复制的写入配置
  -T, --tablespace-mapping=OLDDIR=NEWDIR 将 OLDDIR 中的表空间重定位到 NEWDIR
      --waldir=WALDIR             预写日志目录的位置
  -X, --wal-method=none|fetch|stream 包含指定方法所需的 WAL 文件
  -z, --gzip                               压缩 tar 输出
  -Z, --compress=0-9               使用给定的压缩级别压缩 tar 输出

常规选项:
  -c, --checkpoint=fast|spread 设置快速或扩展检查点
  -C, --create-slot 创建复制槽
  -l, --label=LABEL 设置备份标签
  -n, --no-clean 出错后不清理
  -N, --no-sync 不等待更改安全写入磁盘
  -P, --progress 显示进度信息
  -S, --slot=SLOTNAME 要使用的复制槽
  -v, --verbose 输出详细信息
  -V, --version 输出版本信息,然后退出
      --no-slot 防止创建临时复制槽
      --no-verify-checksums 不验证校验和
  -?, --help 显示此帮助,然后退出

连接选项:
  -d, --dbname=CONNSTR 连接字符串
  -h, --host=HOSTNAME 数据库服务器主机或套接字目录
  -p, --port=PORT 数据库服务器端口号
  -s, --status-interval=状态包发送到服务器的间隔时间(以秒为单位)
  -U, --username=NAME 以指定的数据库用户连接
  -w, --no-password 从不提示输入密码
  -W, --password 强制密码提示(应该自动
1.1.6 备份示例

(1)开启归档

创建归档目录
mkdir -p /home/fbase/wal_Archive
chown -R fbase:fbase /home/fbase/wal_Archive

配置归档命令
vi $PGDATA/postgresql.conf
archive_mode = on
archive_command = 'mkdir -p /home/fbase/wal_Archive && cp %p /home/fbase/wal_Archive/%f'
archive_command = 'DATE=`date +%Y%m%d`; DIR="/home/fbase/wal_Archive/$DATE"; (test -d $DIR || mkdir -p $DIR) && cp %p $DIR/%f'
wal_level = replica  #备注说明
        注释:
        %p 表示xlog文件名$PGDATA的相对路径, 如pg_xlog/00000001000000190000007D
        %f 表示xlog文件名, 如00000001000000190000007D

        备注:
        wal_level:指定生成wal日志的级别,值为minmal,archive,hot_standby。
        minmal一般的配置,archive会生成wal归档需要的日志记录,hot_standby添加备库时需要设置。 

(2)重启并验证归档

checkpoint;                #   解释checkpoint做了什么
select pg_switch_wal();    # 10g 以前用 select pg_switch_xlog();     

[root@hgdb01 20180117]# pwd
/ssd/pg957/arch/20180117
[root@hgdb01 20180117]# ls
000000020000000000000003  000000020000000000000004

(3)创建replication权限的角色

创建replication权限的角色, 或者超级用户的角色。
create role repuser nosuperuser replication login connection limit 32 encrypted password '123456';

(4)配置pg_hba.conf

 配置pg_hba.conf,添加以下内容
host replication repuser 0.0.0.0/0 md5

(5)执行备份

pg_basebackup -Ft -Pv -Xf -z -Z5 -p 8432 -D /home/postgres/backup/


#因为使用流复制协议, 所以支持异地备份
pg_ctl reload  #执行加载配置的命令
mkdir `date +%F` ; 
pg_basebackup -Ft -x -D /home/fbase/bak/`date +%F` -h 192.168.198.157 -p 8432 -U repuser

V12:
pg_basebackup -Ft -X s -D /home/fbase/bak/`date +%F` -h 192.168.198.157 -p 8432 -U repuser

V16.3
# 压缩
pg_basebackup -Ft -Pv -Xf -z -Z5 -p 8432 -D /home/fbase/backup/
#或者(若不压缩)下面是不压缩的命令
pg_basebackup -Fp -Xs -v -P -p 8432 -D /home/fbase/backup/

[fbase@localhost wal_Archive]$ pg_basebackup -Ft -Pv -Xf -z -Z5 -p 8432 -D /home/fbase/backup/
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/1C000028 on timeline 1
71261/71261 kB (100%), 1/1 tablespace                                         
pg_basebackup: write-ahead log end point: 0/1C000138
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed


查看备份结果

V12:

[fbase@localhost 2024-07-29]$ ll ~/bak/2024-07-29/
total 71584
-rw-------. 1 fbase fbase   319563 Jul 29 22:48 backup_manifest
-rw-------. 1 fbase fbase 56194048 Jul 29 22:48 base.tar
-rw-------. 1 fbase fbase 16779264 Jul 29 22:48 pg_wal.tar

V16.3:

[fbase@localhost ~]$ ll ~/backup/
total 7708
-rw-------. 1 fbase fbase  319741 Jul 29 22:46 backup_manifest
-rw-------. 1 fbase fbase 7568144 Jul 29 22:46 base.tar.gz

[fbase@localhost ~]$ tar -tvf base.tar |less	#查看备份包内容
1.1.7 恢复过程

(1)切换日志

在需要备份的库中创建标记表,并检查点和归档指令
    create table t_flag(id int) ;
    insert into t_flag values(1);
    checkpoint;        				#刷新内存脏页到磁盘
    select pg_switch_wal();    		#手动日志归档

(2)删除原数据

V12:

停止数据库并删除数据目录,将pg_basebackup生成的备份包分别解压到相应目录
 pg_ctl stop   -D /data/fbase/fbdata
清空 data_bak 里的文件 
rm -rf  /data/fbase/fbdata/*

#解决备份文件到指定目录 
tar -xvf base.tar -C  /data/fbase/fbdata/

# 如果归档文件存在可以直接用归档文件 
tar -xvf pg_wal.tar -C  /data/fbase/fbdata

V16.3:

#上传base.tar.gz文件到postgres根目录下后,解压到指定目录中
tar -zxvf base.tar.gz -C /data/fbase/fbdata/
#拷贝recovery.conf.sample文件到当前目录下
touch /data/fbase/fbdata/recovery.signal
#修改文件权限
cd pgdata/
chmod 0600 recovery.signal

#编辑postgresql.auto.conf,添加如下一行
vim postgresql.auto.conf

restore_command = 'cp /home/fbase/wal_Archive/%f %p'
recovery_target = 'immediate'

(3)恢复参数

pg12以前
在PG12以前需要修改 recovery.conf文件配置还原参数

cp $PGHOME/share/recovery.conf.sample $PGHOME/recovery.conf 

vi $PGDATA/recovery.conf #备注
#备注
restore_command = 'mkdir -p /home/fbase/wal_Archive && cp %p /home/fbase/wal_Archive/%f'
recovery_target_timeline = 'latest'

备注1:配置recovery_target_timeline参数, 便于判断是否已经到达还原点. (可选, 仅做PITR时需要.一般都是恢复到最新)

备注2:对路径 /ssd/pg957/arch/20180118/的解释

备注3:备份完成后recovery.conf文件名会自动修改为 recovery.done

pg12以后
从v12开始,针对此问题进行了改进,把recovery.conf中的参数合到了postgresql.conf配置文件中,但在非恢复模式这些参数将被忽略。

从PG12开始,recovery.conf文件不存在,由下面两个新文件进行替换:
recovery.signal:告诉PostgreSQL进入正常的归档恢复
standby.signal:告诉PostgreSQL进入standby模式
如果两个文件都存在,则standby.signal优先。

export PGDATA=/data/fbase/fbdata

# 告诉PostgreSQL进入正常的归档恢复
touch $PGDATA/recovery.signal    

echo "
restore_command = 'mkdir -p /home/fbase/wal_Archive && cp %p /home/fbase/wal_Archive/%f'
recovery_target = 'immediate'
"  >> $PGDATA/postgresql.auto.conf

(4)启动验证

启动数据库并做数据查看验证是否恢复完成

 pg_ctl start -D /data/fbase/fbdata
1.1.8 基于时点恢复

(1)恢复目标

默认情况下,恢复将恢复到 WAL 日志的末尾即,备份那一刻的日志。即recovery_target默认为immediate。
以下参数可用于指定较早的停止点。最多可以使用recovery_target
, recovery_target_lsn
, recovery_target_name
, recovery_target_time
, or之一;recovery_target_xid
如果在配置文件中指定了其中一个以上,则会引发错误。这些参数只能在服务器启动时设置

recovery_target = ’immediate’指定恢复应该在达到一个一致状态后尽快结束,即尽早结束。 在从一个在线备份中恢复时,这意味着备份结束的那个点。
recovery_target_name (string)指定恢复将继续进行的已命名的恢复点 (pg_create_restore_point()创建)。
recovery_target_time (timestamp)这个参数指定恢复将继续执行的时间戳。精确的停止点也受到recovery_target_inclusive的影响。
recovery_target_xid (string)指定恢复将继续执行的事务ID。
recovery_target_inclusive (boolean)指定我们是否在指定的恢复目标之后停止(true), 或者在恢复目标之前停止(false)。
recovery_target_timeline (string)指定恢复到一个特定的时间线中。默认值是沿着基础备份建立时的当前时间线恢复。
将这个参数设置为latest会恢复到该归档中能找到的最新的时间线, 这在一个后备服务器中有用。
recovery_target_action (enum) (boolean)指定当到达恢复目标时服务器应该采取什么动作。默认值是pause, 这意味着将暂停恢复。
promote意味着将结束恢复进程并且服务器开始接受连接。 shutdown将在到达恢复目标后停止服务器。

(2)示例

基于时间点注意事项:

  1. 归档日志完整

  2. 指定从归档目录万利 restore_command = ‘cp /u01/postgresql/arch/%f %p’

  3. 设置recovery_target_time 或 recovery_target_lsn 或 recovery_target_xid

  4. 创建touch $PGDATA/recovery.signal

    #示例: 
    #设置基于时间的恢复 
    recovery_target_time = '2022-02-07 13:45:00+08'   
    
    #设置基于lsn,或 xid 的恢复
    recovery_target_lsn  或 recovery_target_xid  可以通过pg_waldump 解析日志,来确定恢复目标
    如本例需要恢复到COMMIT  可以设置 xid 为 '50'  或 lsn 为 '0/07000028'
    recovery_target_xid='50' 或  recovery_target_lsn='0/07000028'
    
    [fbase@localhost wal_Archive]$ pg_waldump 000000010000000000000007
    rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/07000028, prev 0/06000100, desc: RUNNING_XACTS nextXid 744 latestCompletedXid 743 oldestRunningXid 744
    rmgr: XLOG        len (rec/tot):     24/    24, tx:          0, lsn: 0/07000060, prev 0/07000028, desc: SWITCH
    

(3)恢复控制

pg_is_wal_replay_paused() →boolean         如果请求恢复暂停,则返回 true。

pg_get_wal_replay_pause_state() →text      返回恢复暂停状态。返回值是not paused是否未请求pause requested暂停,是否请求暂停但恢复尚未暂停,以及paused恢复是否实际暂停。

pg_promote ( wait boolean DEFAULT true, wait_seconds integer DEFAULT 60 ) → boolean   
将备用服务器提升为主状态。wait如果设置为(默认值),该true函数会等待升级完成或wait_seconds秒数过去,true如果升级成功则返回,false否则返回。如果wait设置为false,则函数在向 postmastertrue发送SIGUSR1信号以触发提升后立即返回。默认情况下,此功能仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该功能。

pg_wal_replay_pause() →void       请求暂停恢复。请求并不意味着恢复立即停止。如果要保证恢复实际上已暂停,则需要检查由pg_get_wal_replay_pause_state().请注意,pg_is_wal_replay_paused()返回是否发出请求。恢复暂停时,不会应用进一步的数据库更改。如果热备用处于活动状态,所有新查询将看到相同的数据库快照,并且在恢复恢复之前不会产生进一步的查询冲突。默认情况下,此功能仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该功能。

pg_wal_replay_resume() →void 如果已暂停,则重新启动恢复。 默认情况下,此功能仅限超级用户使用,但可以授予其他用户 EXECUTE 权限来运行该功能。
注意:
    pg_wal_replay_pause 和 pg_wal_replay_resume不能在提升主库时进行执行。如果在恢复暂停时触发了提升,则暂停状态结束并继续提升。

(4)备份进度

在pg 14中备份进行可以通过下面这个视图查询
pg_stat_progress_basebackup

postgres=# select * from pg_stat_progress_basebackup;
 pid | phase | backup_total | backup_streamed | tablespaces_total | tablespaces_streamed 
-----+-------+--------------+-----------------+-------------------+----------------------
(0 rows)
1.1.9 脚本化备份部署

脚本为basebackup.sh,可根据实际环境进行修改对应的路径等内容。

脚本内容:

#!/bin/bash

export PGHOME=/usr/local/fbase/16.3
export PGDATA=/data/fbase/fbdata
export PATH=$PGHOME/bin:$PATH:.
export LD_LIBRARY_PATH=$PGHOME/lib:$LD_LIBRARY_PATH
export PGHOST=/home/fbase
export MANPATH=$PGHOME/share/man:$MANPATH

export DATE_7=$(date --date '7 days ago' +"%Y%m%d")
#export DATE_7=$(date +"%Y%m%d")
#export DATE=$(date +"%Y%m%d%H%M")
export DATE=$(date +"%Y%m%d")

#主库IP
export IP=192.168.198.149
export PGPORT=8432

#流复制用户
export PGUSER=repuser
export PGPASSWORD=123456
export PGPASSFILE=/home/fbase/.pgpass

#备份目录
export BACKUP_DIR=/home/fbase/backup/basebackup
#备份日志
export DUMP_LOG=/home/fbase/backup/pglog_backup/basebackup-$DATE.log



echo >> $DUMP_LOG
echo >> $DUMP_LOG
echo >> $DUMP_LOG
date "+%Y-%m-%d %H:%M:%S CRON_LOG:1.start $0 ..." >> $DUMP_LOG
echo "##################################################################"  >> $DUMP_LOG
echo "backup time:                                                      "  >> $DUMP_LOG
echo "     `date +"%Y-%m-%d %H:%M:%S"`                                  "  >> $DUMP_LOG
echo "##################################################################"  >> $DUMP_LOG




del_basebackup(){
    echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"  >> $DUMP_LOG
    echo "`date +"%Y-%m-%d"` remove the backup of database zabbix 7 days ago" >> $DUMP_LOG
    echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"  >> $DUMP_LOG

    test -f $BACKUP_DIR/DB-$DATE_7.tar.gz
    if [ X"$?" = X"0" ]; then
        rm -f ${BACKUP_DIR:?var is empty}/DB-${DATE_7:?var is empty}.tar.gz
    fi

    test -f $BACKUP_DIR/DB-$DATE_7.tar.gz
    if [ X"$?" = X"0" ]; then
         echo " Warning: the file 'DB-$DATE_7.tar.gz' has not been moved." >> $DUMP_LOG
    else
    	 echo "the file 'DB-$DATE_7.tar.gz' has been moved." >> $DUMP_LOG
    fi
}

do_basebackup(){
    echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"  >> $DUMP_LOG
    echo "`date +"%Y-%m-%d %H:%M:%S"` backup the database today starting..." >> $DUMP_LOG
    echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"  >> $DUMP_LOG
    
    if [ -d $BACKUP_DIR ]; then
        echo "BACKUP Directory $BACKUP_DIR exist,continue..." >> $DUMP_LOG
    else
        mkdir -p $BACKUP_DIR
    fi		
    	
    test -f  $BACKUP_DIR/DB-$DATE.tar.gz
    if [ X"$?" = X"0" ]; then
        echo "ERROR: Today's(`date +"%Y-%m-%d"`) BACKUP job $BACKUP_DIR/DB-$DATE.tar.gz has done,quit!" >> $DUMP_LOG
        exit;
    else
        pg_basebackup -h $IP -p $PGPORT -U $PGUSER -F p -P -X s -s 5 -R -D $BACKUP_DIR/DB-$DATE -l postgresbackup$DATE >> $DUMP_LOG
    fi
    
    test  -d  $BACKUP_DIR/DB-$DATE
    if [ X"$?" != X"0" ]; then
	    echo “ERROR: the databases backup failed!>> $DUMP_LOG
        exit;
    else
	cd $BACKUP_DIR
        PWD=$(pwd)
    fi
    
    # 判断当前目录是否为备份目录,如果不是则退出脚本
    if [ $PWD != $BACKUP_DIR ] ; then
        echo "进入备份目录失败,退出脚本" >> $DUMP_LOG
        exit
    else
        tar zcvf DB-$DATE.tar.gz DB-$DATE --remove-files >> $DUMP_LOG
        fsize
    fi
	
}
fsize(){
    export DATE=$(date +"%Y%m%d")
    fsize=$(du -sh  ${BACKUP_DIR:?var is empty}/DB-${DATE:?var is empty}.tar.gz | awk -F" " '{print $1}')
    if [ X"$fsize" !=  X"0" ] ; then
        echo "`date +"%Y-%m-%d %H:%M:%S"`: the basebackup file $BACKUP_DIR/DB-$DATE.tar.gz  has been  backuped successfully " >> $DUMP_LOG
        echo "DB-$DATE.tar.gz's file size is about $fsize" >> $DUMP_LOG
    else
        echo "`ERROR: date +"%Y-%m-%d %H:%M:%S"`: the basebackup file has been backuped failed,file size is 0 KB" >> $DUMP_LOG
    fi
}

del_basebackup
do_basebackup

date "+%Y-%m-%d %H:%M:%S CRON_LOG:1.stop $0 ..." >> $DUMP_LOG

定时执行任务:

[postgres@zabbix ~]$ crontal -l     # database backup  
55 23 * * 0   /home/fbase/service/batch.weekly/basebackup.sh  

2. 官方介绍

pg_basebackup — 获取 PostgreSQL 集群的基本备份

2.1 概要

pg_basebackup [option…]

2.2 描述

pg_basebackup 用于获取正在运行的 PostgreSQL 数据库集群的基本备份。获取备份时不会影响数据库的其他客户端,并且可以用于时间点恢复(请参阅 第 26.3 节)以及作为日志传输或流复制备用服务器的起点(请参阅 第 27.2 节)。

pg_basebackup 会制作数据库集群文件的精确副本,同时确保服务器自动进入和退出备份模式。备份始终针对整个数据库集群进行;无法备份单个数据库或数据库对象。对于选择性备份,必须使用另一个工具,例如 pg_dump

备份通过使用复制协议的常规 PostgreSQL 连接进行。必须使用具有 REPLICATION 权限(请参见 第 22.2 节)或为超级用户的用户 ID 建立连接,并且 pg_hba.conf 必须允许复制连接。还必须将服务器配置为将 max_wal_senders 设置得足够高,以提供至少一个用于备份的 walsender 和一个用于 WAL 流传输(如果使用)的 walsender。

可以同时运行多个 pg_basebackup,但从性能角度来看,通常最好只进行一次备份,然后复制结果。

pg_basebackup 不仅可以从主服务器进行基本备份,还可以从备用服务器进行基本备份。要从备用服务器进行备份,请设置备用服务器,以便它可以接受复制连接(即,设置 max_wal_sendershot_standby,并适当地配置其 pg_hba.conf)。您还需要在主服务器上启用 full_page_writes

请注意,从备用服务器进行备份时有一些限制

  • 备份历史文件不会在备份的数据库集群中创建。
  • pg_basebackup 无法在备份结束时强制备用服务器切换到新的 WAL 文件。当您使用 -X none 时,如果主服务器上的写入活动较少,pg_basebackup 可能需要等待很长时间,才能切换并归档备份所需的最后一个 WAL 文件。在这种情况下,在主服务器上运行 pg_switch_wal 以触发立即 WAL 文件切换可能很有用。
  • 如果在备份期间将备用服务器提升为主服务器,备份将失败。
  • 备份所需的所有 WAL 记录都必须包含足够的全页写入,这需要您在主服务器上启用 full_page_writes

每当 pg_basebackup 正在进行基础备份时,服务器的 pg_stat_progress_basebackup 视图将报告备份进度。有关详细信息,请参见 第 28.4.6 节

2.3 选项

以下命令行选项控制输出的位置和格式:

-D directory
--pgdata=directory					设置目标目录以写入输出。pg_basebackup 将创建此目录(以及任何缺失的父目录),如果它不存在。如果它已存在,则它必须为空。
当备份为 tar 格式时,目标目录可以指定为 -(破折号),导致 tar 文件被写入 stdout。此选项是必需的。


-F format
--format=format						选择输出的格式。format 可以是以下之一

    p
    plain							以纯文本文件形式写入输出,其布局与源服务器的数据目录和表空间相同。当集群没有其他表空间时,整个数据库将被放置在目标目录中。如果集群包含其他表空间,则主数据目录将被放置在目标目录中,但所有其他表空间将被放置在与源服务器上相同的绝对路径中。(请参见 --tablespace-mapping 以更改它。)

    这是默认格式。

    t
    tar								以 tar 文件形式将输出写入目标目录。主数据目录的内容将被写入名为 base.tar 的文件,而每个其他表空间将被写入以该表空间的 OID 命名的单独 tar 文件中。
									如果目标目录指定为 -(破折号),tar 内容将写入标准输出,适合管道传输到(例如)gzip。仅当群集没有其他表空间且未使用 WAL 流时才允许这样做。


-R
--write-recovery-conf				创建 standby.signal 文件,并将连接设置追加到目标目录中的 postgresql.auto.conf 文件(或使用 tar 格式时追加到基础归档文件)。这简化了使用备份结果设置备用服务器。postgresql.auto.conf 文件将记录连接设置,如果指定,还将记录 pg_basebackup 使用的复制槽,以便流复制稍后使用相同的设置。


-t target
--target=target						指示服务器放置基础备份的位置。默认目标是 client,它指定应将备份发送到运行 pg_basebackup 的计算机。如果目标改为设置为 server:/some/path,备份将存储在运行服务器的计算机的 /some/path 目录中。在服务器上存储备份需要超级用户权限或具有 pg_write_server_files 角色的权限。如果目标设置为 blackhole,内容将被丢弃,不会存储在任何地方。这仅应出于测试目的而使用,因为你最终不会获得实际备份。由于 WAL 流是通过 pg_basebackup 而不是通过服务器实现的,因此此选项不能与 -Xstream 一起使用。由于这是默认值,因此在指定此选项时,还必须指定 -Xfetch 或 -Xnone。


-T olddir=newdir
--tablespace-mapping=olddir=newdir	在备份期间将目录 olddir 中的表空间重新定位到 newdir。为了生效,olddir 必须与源服务器上定义的表空间的路径规范完全匹配。(但如果源服务器上的 olddir 中没有表空间,则不会出错。)同时,newdir 是接收主机文件系统中的一个目录。与主目标目录一样,newdir 不必已经存在,但如果存在,则必须为空。 olddir 和 newdir 都必须是绝对路径。如果任一路径需要包含等号 (=),请在其前面加上反斜杠。此选项可以为多个表空间指定多次。如果表空间以这种方式重新定位,则主数据目录中的符号链接将更新为指向新位置。因此,新数据目录可以用于具有更新位置中所有表空间的新服务器实例。
目前,此选项仅适用于普通输出格式;如果选择了 tar 格式,则会忽略此选项。


--waldir=waldir						设置要将 WAL(预写式日志)文件写入的目录。默认情况下,WAL 文件将放置在目标目录的 pg_wal 子目录中,但可以使用此选项将它们放置在其他位置。 waldir 必须是绝对路径。与主目标目录一样, waldir 不必已经存在,但如果确实存在,则必须为空。仅当备份为普通格式时,才能指定此选项。


-X method
--wal-method=method					将所需的 WAL(预写式日志)文件包含在备份中。这将包括备份期间生成的所有预写式日志。除非指定方法 none,否则可以在目标目录中启动一个后端,而无需查阅 WAL 存档,从而使输出成为一个完全独立的备份。支持用于收集预写式日志的以下 method

    n
    none							不在备份中包含预写式日志。

    f
    fetch							预写式日志文件在备份结束时收集。因此,源服务器的 wal_keep_size 参数必须设置得足够高,以便在备份结束之前不会删除所需的日志数据。如果在传输所需日志数据之前已对其进行回收,则备份将失败且无法使用。当使用 tar 格式时,预写式日志文件将包含在 base.tar 文件中。

    s
    stream							在进行备份时流式传输预写式日志数据。此方法将打开与服务器的第二个连接,并在运行备份时并行开始流式传输预写式日志。因此,它将需要两个复制连接,而不仅仅是一个连接。只要客户端能够跟上预写式日志数据,使用此方法就不需要在源服务器上保存额外的预写式日志。当使用 tar 格式时,预写式日志文件将被写入名为 pg_wal.tar 的单独文件(如果服务器版本早于 10,则该文件将被命名为 pg_xlog.tar)。
此值为默认值。

    -z
    --gzip							启用 tar 文件输出的 gzip 压缩,采用默认压缩级别。仅当使用 tar 格式时才可以使用压缩,并且后缀 .gz 将自动添加到所有 tar 文件名。


-Z level
-Z [{client|server}-]method[:detail]
--compress=level
--compress=[{client|server}-]method[:detail]
请求压缩备份。如果包含 client 或 server,则指定压缩执行的位置。在服务器上压缩将减少传输带宽,但会增加服务器 CPU 消耗。默认值为 client,但使用 --target 时除外。在这种情况下,备份不会发送到客户端,因此只有服务器压缩才有意义。当使用默认值 -Xstream 时,服务器端压缩不会应用于 WAL。要压缩 WAL,请使用客户端压缩,或指定 -Xfetch。
压缩方法可以设置为 gzip、lz4、zstd、none(表示不压缩)或整数(如果为 0 则不压缩,如果大于 0 则为 gzip)。还可以选择指定压缩详细信息字符串。如果详细信息字符串为整数,则指定压缩级别。否则,它应为逗号分隔的项列表,每个项的格式为 keyword 或 keyword=value。目前,支持的关键字为 level、long 和 workers。当压缩方法指定为普通整数时,无法使用详细信息字符串。
如果未指定压缩级别,则将使用默认压缩级别。如果仅指定一个级别而未提及算法,则当级别大于 0 时将使用 gzip 压缩,当级别为 0 时将不使用压缩。
当 tar 格式与 gzip、lz4 或 zstd 一起使用时,后缀 .gz、.lz4 或 .zst 将分别自动添加到所有 tar 文件名。当使用普通格式时,可能无法指定客户端压缩,但仍然可以请求服务器端压缩。如果这样做,服务器将压缩备份以进行传输,客户端将对其进行解压缩并提取。
当此选项与 -Xstream 结合使用时,如果选择了客户端 gzip 压缩,pg_wal.tar 将使用 gzip 压缩,但如果选择了任何其他压缩算法或选择了服务器端压缩,则不会压缩。


下列命令行选项控制备份的生成和程序的调用:

-c {fast|spread}
--checkpoint={fast|spread}			将检查点模式设置为快速(立即)或分散(默认)(请参阅 第 26.3.3 节)。


-C
--create-slot						指定应在启动备份之前创建 --slot 选项命名的复制槽。如果槽已存在,则会引发错误。


-l label
--label=label						设置备份的标签。如果未指定,将使用默认值 “pg_basebackup base backup”。


-n
--no-clean							默认情况下,当 pg_basebackup 因错误而中止时,它会删除在发现无法完成作业之前可能已创建的任何目录(例如,目标目录和预写日志目录)。此选项禁止清理,因此对于调试很有用。请注意,无论哪种方式,表空间目录都不会被清理。


-N
--no-sync							默认情况下,pg_basebackup 将等待所有文件安全写入磁盘。此选项导致 pg_basebackup 在不等待的情况下返回,这更快,但意味着随后的操作系统崩溃可能会损坏基本备份。通常,此选项对于测试很有用,但不应在创建生产安装时使用。


-P
--progress							启用进度报告。打开此选项将在备份期间提供近似进度报告。由于数据库在备份期间可能会发生变化,因此这只是一个近似值,可能不会完全以 100% 结束。特别是,当 WAL 日志包含在备份中时,无法预先估计数据总量,在这种情况下,一旦超过不含 WAL 的总估计值,估计的目标大小就会增加。


-r rate
--max-rate=rate						设置从源服务器收集数据的最大传输速率。这有助于限制 pg_basebackup 对服务器的影响。值以每秒千字节为单位。使用后缀 M 表示每秒兆字节。后缀 k 也可以接受,并且没有效果。有效值介于每秒 32 千字节和每秒 1024 兆字节之间。此选项始终影响数据目录的传输。仅当收集方法为 fetch 时,WAL 文件的传输才会受到影响。


-S slotname
--slot=slotname						此选项只能与 -X stream 结合使用。它使 WAL 流使用指定的复制槽。如果基本备份打算使用复制槽作为流复制备用,则备用应使用与 primary_slot_name 相同的复制槽名称。这可确保主服务器在基本备份结束和在新备用上开始流复制之间的时间内不会删除任何必要的 WAL 数据。
除非同时使用了选项 -C,否则指定的复制槽必须存在。如果未指定此选项,并且服务器支持临时复制槽(版本 10 及更高版本),则会自动使用临时复制槽进行 WAL 流。


-v
--verbose							启用详细模式。将在启动和关闭期间输出一些额外的步骤,以及在启用进度报告时显示当前正在处理的确切文件名。


--manifest-checksums=algorithm		指定应应用于备份清单中每个文件的校验和算法。目前,可用的算法有 NONE、CRC32C、SHA224、SHA256、SHA384 和 SHA512。默认值为 CRC32C。如果选择 NONE,备份清单将不包含任何校验和。否则,它将使用指定的算法包含备份中每个文件的校验和。此外,清单将始终包含其自身内容的 SHA256 校验和。与 CRC32C 相比,SHA 算法的 CPU 密集程度要高得多,因此选择其中一个算法可能会增加完成备份所需的时间。对于希望验证备份未被篡改的用户来说,使用 SHA 哈希函数可以提供每个文件的加密安全摘要,而 CRC32C 算法提供的校验和计算速度要快得多;它擅长捕获因意外更改而导致的错误,但无法抵抗恶意修改。请注意,为了对抗有权访问备份的攻击者,备份清单需要安全地存储在其他地方,或以其他方式验证自备份以来未被修改。
pg_verifybackup 可用于根据备份清单检查备份的完整性。


--manifest-force-encode				强制备份清单中的所有文件名进行十六进制编码。如果未指定此选项,则仅对非 UTF8 文件名进行十六进制编码。此选项主要用于测试读取备份清单文件的工具是否正确处理此情况。


--no-estimate-size					阻止服务器估算将要流式传输的备份数据的总量,导致 backup_total 列在 pg_stat_progress_basebackup 视图中始终为 NULL。如果没有此选项,备份将首先枚举整个数据库的大小,然后返回并发送实际内容。这可能会使备份花费更长的时间,尤其是发送第一条数据之前需要更长的时间。如果估算时间太长,此选项可用于避免此类估算时间。
使用 --progress 时不允许使用此选项。


--no-manifest						禁用备份清单的生成。如果未指定此选项,服务器将生成并发送一个备份清单,该清单可以使用 pg_verifybackup 进行验证。清单是备份中存在的所有文件的列表,但其中不包括可能包含的任何 WAL 文件。它还存储每个文件的大小、上次修改时间和可选的校验和。


--no-slot							阻止为备份创建临时复制槽。默认情况下,如果选择了日志流式传输,但未使用 -S 选项给出槽名称,则会创建一个临时复制槽(如果源服务器支持)。
此选项的主要目的是允许在服务器没有空闲复制槽时进行基本备份。几乎总是首选使用复制槽,因为它可以防止服务器在备份期间删除所需的 WAL。


--no-verify-checksums				如果在进行基础备份的服务器上启用了校验和,则禁用校验和验证。
默认情况下,将验证校验和,并且校验和失败将导致非零退出状态。但是,在这种情况下,不会删除基础备份,就像使用了 --no-clean 选项一样。校验和验证失败也会在 pg_stat_database 视图中报告。


以下命令行选项控制与源服务器的连接:

-d connstr
--dbname=connstr					指定用于连接到服务器的参数,作为 连接字符串;这些参数将覆盖任何冲突的命令行选项。为了与其他客户端应用程序保持一致,该选项称为 --dbname,但由于 pg_basebackup 不会连接到群集中的任何特定数据库,因此连接字符串中的任何数据库名称都将被忽略。


-h host
--host=host							指定服务器正在运行的机器的主机名。如果值以斜杠开头,则将其用作 Unix 域套接字的目录。如果已设置,则默认值取自 PGHOST 环境变量,否则尝试 Unix 域套接字连接。


-p port
--port=port							指定服务器正在侦听连接的 TCP 端口或本地 Unix 域套接字文件扩展名。如果已设置,则默认为 PGPORT 环境变量,或编译时默认值。


-s interval
--status-interval=interval			指定发送回源服务器的状态数据包之间的秒数。值越小,服务器对备份进度的监控越准确。零值会完全禁用定期状态更新,但当服务器请求时仍会发送更新,以避免基于超时的断开连接。默认值为 10 秒。


-U 用户名
--username=用户名					  指定要连接的用户名。


-w
--no-password						禁止发出密码提示。如果服务器需要密码身份验证,并且无法通过 .pgpass 文件等其他方式获得密码,则连接尝试将失败。此选项在没有用户输入密码的批处理作业和脚本中非常有用。


-W
--password							强制 pg_basebackup 在连接到源服务器之前提示输入密码。此选项永远不是必需的,因为如果服务器要求密码身份验证,pg_basebackup 会自动提示输入密码。但是,pg_basebackup 会浪费一次连接尝试来找出服务器是否需要密码。在某些情况下,值得键入 -W 以避免额外的连接尝试。

还有其他选项:

-V
--version							打印 pg_basebackup 版本并退出。


-?
--help								显示有关 pg_basebackup 命令行参数的帮助,然后退出。

2.4 环境

此实用程序与大多数其他 PostgreSQL 实用程序一样,使用 libpq 支持的环境变量(请参阅 第 34.15 节)。

环境变量 PG_COLOR 指定是否在诊断消息中使用颜色。可能的值有 alwaysautonever

2.5 备注

在备份开始时,需要在源服务器上执行检查点。这可能需要一些时间(特别是如果未使用 --checkpoint=fast 选项),在此期间 pg_basebackup 似乎处于空闲状态。

备份将包括数据目录和表空间中的所有文件,包括配置文件和第三方放置在该目录中的任何附加文件,但 PostgreSQL 管理的某些临时文件除外。但是,只复制常规文件和目录,但用于表空间的符号链接除外。指向 PostgreSQL 已知某些目录的符号链接将复制为空目录。其他符号链接和特殊设备文件将被跳过。有关确切详细信息,请参见第 55.4 节

在普通格式中,表空间将备份到源服务器上的相同路径,除非使用选项 --tablespace-mapping。如果没有此选项,在与服务器相同的主机上运行普通格式基本备份将不起作用(如果表空间正在使用),因为备份必须写入与原始表空间相同的目录位置。

当使用 tar 格式时,用户有责任在启动使用数据的 PostgreSQL 服务器之前解压缩每个 tar 文件。如果有其他表空间,则需要将它们的 tar 文件解压缩到正确的位置。在这种情况下,服务器将根据 base.tar 文件中包含的 tablespace_map 文件的内容创建这些表空间的符号链接。

pg_basebackup 与相同或较旧主要版本的服务器配合使用,最低版本为 9.1。但是,WAL 流模式 (-X stream) 仅适用于服务器版本 9.3 及更高版本,而 tar 格式 (--format=tar) 仅适用于服务器版本 9.5 及更高版本。

如果在源集群上启用了组权限,pg_basebackup 将保留数据文件的组权限。

2.6 示例

要在 mydbserver 上创建服务器的基本备份并将其存储在本地目录 /usr/local/pgsql/data

$ pg_basebackup -h mydbserver -D /usr/local/pgsql/data

要使用每个表空间的一个压缩 tar 文件创建本地服务器的备份,并将其存储在目录 backup 中,同时在运行时显示进度报告

$ pg_basebackup -D backup -Ft -z -P

要创建单表空间本地数据库的备份并使用 bzip2 对其进行压缩

$ pg_basebackup -D - -Ft -X fetch | bzip2 > backup.tar.bz2

(如果数据库中有多个表空间,此命令将失败。)

要创建本地数据库的备份,其中 /opt/ts 中的表空间重新定位到 ./backup/ts

$ pg_basebackup -D backup/data -T /opt/ts=$(pwd)/backup/ts

要创建本地服务器的备份,其中每个表空间使用 gzip 在级别 9 上压缩一个 tar 文件,存储在目录 backup

$ pg_basebackup -D backup -Ft --compress=gzip:9

附录

附录1 logicalreplica

在 PostgreSQL 中,replica(流复制)和 logical(逻辑复制)是两种不同的复制机制。它们各自有不同的用途和实现方式。理解它们的区别可以帮助你更好地选择适合的复制方案。以下是它们的主要区别以及为什么使用逻辑复制后可能没有复制文件的问题:

1. 流复制(Streaming Replication)

定义
流复制是 PostgreSQL 的一种物理复制方式。它将主数据库的事务日志(WAL 文件)流式地传输到一个或多个备用数据库(副本)。副本数据库通过应用这些日志来保持与主数据库的同步。

特点

  • 物理复制:复制的是数据库的数据页的二进制快照(即 WAL 文件)。
  • 实时同步:提供几乎实时的数据同步。
  • 全量同步:副本数据库是主数据库的一个完全拷贝,包含所有的数据和索引。
  • 用途:主要用于高可用性(HA)和灾难恢复(DR)。

配置

  • 在主数据库上启用流复制。
  • postgresql.conf 中设置 wal_level = replica
  • 配置 pg_hba.conf 文件允许复制连接。
  • 使用 archive_command 将 WAL 文件存档到指定位置。
2. 逻辑复制(Logical Replication)

定义
逻辑复制是一种基于逻辑数据流的复制方式。它允许选择性地复制表的变化到其他数据库。逻辑复制只复制数据变更,不复制整个数据页。

特点

  • 逻辑复制:复制的是数据变更(如 INSERT、UPDATE、DELETE),而不是数据库的二进制文件。
  • 选择性同步:可以选择复制特定的表或数据集,而不是整个数据库。
  • 灵活性:支持不同版本的 PostgreSQL 和不同的数据格式。
  • 用途:适用于跨版本的数据库迁移、数据集成和数据仓库。

配置

  • 在主数据库上启用逻辑复制。
  • postgresql.conf 中设置 wal_level = logical
  • 配置 pg_hba.conf 文件允许逻辑复制连接。
  • 创建发布(publication)和订阅(subscription)来定义需要复制的数据。

为什么使用逻辑复制后没有复制文件?

逻辑复制的工作原理

  • 数据复制:逻辑复制不涉及复制物理 WAL 文件。它只是复制数据变更日志到订阅端。
  • 数据变更捕获:逻辑复制依赖于 WAL 记录数据变更,并通过逻辑复制流将变更应用到订阅端。
3. 可能的问题
  1. 没有物理文件复制:逻辑复制不使用 archive_command 来存档 WAL 文件,而是通过逻辑流复制数据。因此,你不会看到复制的 WAL 文件。
  2. 日志设置:确认在 postgresql.conf 中是否正确配置了 wal_levellogical,并设置了适当的 max_replication_slotsmax_wal_senders
  3. 发布和订阅:检查发布(publication)和订阅(subscription)是否正确配置并且处于活动状态。
  4. 权限问题:确保逻辑复制用户有足够的权限进行数据复制。
4. 总结
  • 流复制:物理复制整个数据库的数据页,适用于高可用性和灾难恢复,复制的是 WAL 文件。
  • 逻辑复制:逻辑复制数据变更,适用于数据迁移和集成,复制的是数据变更而非文件。

使用逻辑复制时,你不会看到物理的 WAL 文件被复制,因为它不涉及到物理的 WAL 文件传输。请确保你的逻辑复制配置正确,特别是发布和订阅的设置。

附录2 recovery_targetrecovery_target_timeline

在 PostgreSQL 中,recovery_targetrecovery_target_timeline 是用来配置数据库恢复行为的两个关键参数。它们的功能和作用有所不同:

1. recovery_target
  • 定义recovery_target 是一个配置参数,用于指定恢复的目标点或恢复的模式。

    • 'immediate':表示 PostgreSQL 应该在恢复过程中尽快完成恢复操作,而不是等待 WAL 日志的进一步传输。这通常用于尽快恢复到一个可用状态。
    • 其他可能的值(取决于 PostgreSQL 版本和配置)包括 'standby'(用于启动数据库作为备用服务器)和 'point-in-time'(用于恢复到某个特定时间点)。

    示例:

    recovery_target = 'immediate'
    
2. recovery_target_timeline
  • 定义recovery_target_timeline 参数指定了恢复时要应用的时间线。时间线是在 PostgreSQL 的 WAL(Write-Ahead Logging)系统中用于管理恢复和分支的。

    • 'latest':表示恢复应该应用最新的时间线。通常用于在恢复过程中获取最新的数据库状态。
    • 'recovery':表示恢复到当前恢复操作开始时的时间线,这可以帮助确保在恢复过程中数据一致性。

    示例:

    recovery_target_timeline = 'latest'
    
3. 具体区别和结合使用
  1. recovery_target 的作用
    • 这个参数决定了恢复的整体策略。例如,使用 'immediate' 可以使 PostgreSQL 在恢复过程中尽快达到一个可用状态,这对于快速恢复非常重要。
  2. recovery_target_timeline 的作用
    • 这个参数决定了在恢复过程中要应用哪个时间线。时间线对于确保数据一致性和正确的恢复过程非常重要。使用 'latest' 可以确保恢复到最新的时间线状态。
4. 结合使用的效果
  • recovery_target = 'immediate'recovery_target_timeline = 'latest'
    • 当使用这两个配置项时,PostgreSQL 会尽快完成恢复操作,并且在恢复过程中会应用最新的时间线。这通常用于在发生故障或需要快速恢复的场景下,确保恢复过程既快速又能够反映最新的数据库状态。
5. 示例配置

在 PostgreSQL 12及更高版本中,你可以在 postgresql.conf 文件或恢复信号文件中设置这些参数:

# PostgreSQL 复原目标配置
recovery_target = 'immediate'
recovery_target_timeline = 'latest'
6. 总结
  • recovery_target 决定恢复的策略或模式。
  • recovery_target_timeline 决定要应用的时间线,以确保恢复到最新或指定的时间线。

通过正确配置这两个参数,可以有效管理 PostgreSQL 的恢复过程,确保数据的完整性和一致性

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值