PostgreSQL 备份恢复 多参数 Dokcer版本 多库for循环

本文介绍了PostgreSQL数据库的备份和恢复方法,包括使用pg_dump和pg_restore命令的不同选项,以及如何通过shell脚本自动化备份过程。文中详细阐述了如何进行全库备份、角色和表空间备份,并提供了示例脚本,同时提到了使用crontab设置定时任务进行定期备份。此外,还讨论了在Docker环境下备份PostgreSQL数据库的方法。
摘要由CSDN通过智能技术生成
#!/bin/bash

#操作类型,backup、restore
type=$1
#造作数据库schema名
dbname=$2
#备份文件名,格式为:注册名_yyyyMMddHHmmss.sql
backupFileName=$3
#数据库所在服务器ip
dbhost=$4

#固定存储目录/home/backup/
if [ ! -d "/home/backup/" ];then
    mkdir "/home/backup/"
fi

backupFile="/home/backup/"${backupFileName}
echo ${backupFile}

cd /usr/pgsql-14/bin

if [ $type == "backup" ];then
    PGPASSWORD="postgres" ./pg_dump -h ${dbhost} -U postgres ${dbname}  > ${backupFile}
elif [ $type == "restore" ];then
    #先清理掉schema,不然相对于恢复点有新增数据,恢复时不会清理
    PGPASSWORD="postgres" ./psql -h ${dbhost} -U postgres -d ${dbname} -c "drop schema public cascade;create schema public;"
    PGPASSWORD='postgres' ./psql -h ${dbhost} -U postgres -d ${dbname}  -f ${backupFile}
else
    echo "没有合适的操作类型"
    exit 1
fi

exit 0

sh -x backup.sh backup a a.2023 localhost
sh -x backup.sh restore a a.2023 localhost

1.1 SQL转储
1.1.1 pg_dump命令
pg_dump是一个普通的PostgreSQL客户端应用,可以访问该数据库的远端主机上进行备份工作。
pg_dump每次只转储一个数据库,而且它不会转储关于角色或表空间(因为它们是集簇范围的)的信息。
a.转储

需要先登陆数据库: su - postgres

# 本机
pg_dump dbname > outfile
 
# 远程
pg_dump -h 1.1.1.1 -p 1234 dbname > dbname.bak
 
# 实时自动备份数据库
   a. 登录数据库
        su - postgres
   b.创建备份目录
        mkdir -p ~/dbbackups
   c.创建定时任务
        crontab -e
    编辑文件:
        0 0 * * 0 pg_dump -U postgres laozuo> ~/dbbackups/laozuo.org.bak
b.恢复 

# infile为pg_dump命令的输出文件,命令不会创建数据库dbname,
# 在执行psql前需要先从template0创建dbname(
# 例如,用命令createdb -T template0 dbname)。
psql dbname < infile
 
 
# ON_ERROR_STOP的作用: 遇到一个SQL错误后让psql退出
psql --set ON_ERROR_STOP=on dbname < infile
c.转储恢复一体化 

# pg_dump和psql使用管道结合,直接从一个服务器转储一个数据库到另一个服务器
pg_dump -h host1 dbname | psql -h host2 dbname
1.1.2 pg_dump命令处理大型数据库
对于非常大型的数据库,可以将将split配合其他两种方法(gizip,并行度)之一进行使用。

# 处理大型数据库时,可以压缩存储
    pg_dump dbname | gzip > filename.gz
    
    # 此时的恢复:
        gunzip -c filename.gz | psql dbname
        # 或者
        cat filename.gz | gunzip | psql dbname
 
# 大型数据库,分割存储
    # 让每一块的大小为1兆字节
        pg_dump dbname | split -b 1m - filename
   
    # 恢复
        cat filename* | psql dbname
 
# 自定义转储格式
    # 如果PostgreSQL所在的系统上安装了zlib压缩库,
    # 自定义转储格式将在写出数据到输出文件时对其压缩。这
    # 将产生和使用gzip时差不多大小的转储文件,
    # 但是这种方式的一个优势是其中的表可以被有选择地恢复。
    pg_dump -Fc dbname > filename
 
    # 恢复
    # 自定义格式的转储不是psql的脚本,只能通过pg_restore恢复
    pg_restore -d dbname filename
 
# 使用并行模式转储
    # 使用-j参数控制并行度,并行转储只支持“目录”归档格式
    pg_dump -j num -F d -f out.dir dbname
 
#目录格式备份:
pg_dump -h localhost -p 5432 -U someuser -F d -f /somepath/a_directory mydb
 
# 从9.3版本开始支持并行备份选项--jobs (-j),
# 此选项只有在按目录格式进行备份时才会生效,每个写线程只负责写一个单独的文件,
# 因此一定是输出结果为多个独立的文件时才可以并行。
pg_dump -h localhost -p 5432 -U someuser -j 3 -Fd -f /somepath/a_directory mydb
 1.1.3 pg_dumpall命令
pg_dumpall备份一个给定集簇中的每一个数据库,并且也保留了集簇范围的数据,如角色和表空间定义。
pg_dump只备份数据库集群中的某个数据库的数据,它不会导出角色和表空间相关的信息,因为这些信息是整个数据库集群共用的,不属于某个单独的数据库。pg_dumpall,对集簇中的每个数据库调用pg_dump来完成该工作,还会还转储对所有数据库公用的全局对象(pg_dump不保存这些对象)。
pg_dumpall工作时会发出命令重新创建角色、表空间和空数据库,接着为每一个数据库pg_dump。这意味着每个数据库自身是一致的,但是不同数据库的快照并不同步。

集簇范围的数据可以使用pg_dumpall的–globals-only选项来单独转储。

建议 :

建议每天对角色和表空间定义等全局对象进行备份,但不建议每天使用pg_dumpall来备份全库数据,因为pg_dumpall仅支持导出为SQL文本格式,而使用这种庞大的SQL文本备份来进行全库级别的数据库恢复时及其耗时的,所以一般只建议使用pg_dumpall来备份全局对象而非全库数据。

pg_dumpall可实现仅备份角色和表空间定义:
pg_dumpall -h localhost -U postgres --port=5432 -f myglobals.sql --globals-only

cat myglobals.sql

--
-- PostgreSQL database cluster dump
--

SET default_transaction_read_only = off;

SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;

--
-- Roles
--

CREATE ROLE postgres;
ALTER ROLE postgres WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS;
CREATE ROLE test;
ALTER ROLE test WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB LOGIN NOREPLICATION NOBYPASSRLS;
CREATE ROLE user01;
ALTER ROLE user01 WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB LOGIN NOREPLICATION NOBYPASSRLS;


--
-- PostgreSQL database cluster dump complete


如果仅需备份角色定义而无需备份表空间,添加--roles-only选项:
pg_dumpall -h localhost -U postgres --port=5432 -f myroles.sql --roles-only  14版本没有

-bash-4.2$ pg_dumpall -h localhost -U postgres --port=5432 -f myroles.sql --roles-only 
pg_dumpall: unrecognized option '--roles-only '
Try "pg_dumpall --help" for more information.

---------------------------------------------------------------

#!/bin/bash
#stgreSQL备份用户
postgreSQL_user="root"
#stgreSQL备份用户密码及pg环境变量
export PGPASSWORD=123
export PGDATA=/mnt/pgsql/data/postgresql/data
export PGHOME=/mnt/pgsql/data/postgresql
export PATH=$PGHOME/bin:$PATH
#数据库地址
postgreSQL_host="127.0.0.1"
#端口号
postgreSQL_port="5432"
#postgreSQL编码
postgreSQL_charset="utf8"
#要备份的数据库名称,多个用空格分开隔开 如("db1" "db2" "db3")
backup_db_arr=("db_test")
#备份数据存放位置,末尾请不要带"/",此项可以保持默认,程序会自动创建文件夹
backup_location=/home/db_bak
#是否开启过期备份删除 ON为开启 OFF为关闭
expire_backup_delete="ON"
#过期时间天数 默认为三十天,此项只有在expire_backup_delete开启时有效
expire_days=30
#定义备份详细时间
backup_time=`date +%Y%m%d%H%M`
#定义备份目录中的年月日时间
backup_Ymd=`date +%Y-%m-%d`
#30天之前的日期
backup_30ago=`date -d '30 days ago' +%Y-%m-%d`
#备份文件夹全路径
backup_dir=$backup_location/$backup_Ymd
#欢迎语
welcome_msg="Welcome to use PostgreSQL backup tools!"
postgreSQL_ps=`ps -ef |grep PostgreSQL|wc -l`
postgreSQL_listen=`netstat -an |grep LISTEN |grep $postgreSQL_port|wc -l`
if [ [$postgreSQL_ps == 0] -o [$postgreSQL_listen == 0] ]; then
        echo "ERROR:postgreSQL is not running! backup stop!"
        exit
else
        echo $welcome_msg
fi
psql -h $postgreSQL_host -p $postgreSQL_port -U $postgreSQL_user -d ${backup_db_arr[0]} <<end
end
flag=`echo $?`
if [ $flag != "0" ]; then
        echo "ERROR:Can't connect postgreSQL server! backup stop!"
        exit
else
        echo "postgreSQL connect ok! Please wait......"
        # 判断有没有定义备份的数据库,如果定义则开始备份,否则退出备份
        if [ "$backup_db_arr" != "" ];then
                #dbnames=$(cut -d ',' -f1-5 $backup_database)
                #echo "arr is (${backup_db_arr[@]})"
                for dbname in ${backup_db_arr[@]}
                do
                        echo "database $dbname backup start..."
                        `mkdir -p $backup_dir`
                        `pg_dump -h $postgreSQL_host -p $postgreSQL_port -U $postgreSQL_user -d dbname -c  | gzip > $backup_dir/$dbname-$backup_time.sql.gz`
                        flag=`echo $?`
                        if [ $flag == "0" ];then
                                echo "database $dbname success backup to $backup_dir/$dbname-$backup_time.sql.gz"
                        else
                                echo "database $dbname backup fail!"
                        fi
                done
        else
                echo "ERROR:No database to backup! backup stop"
                exit
        fi
        # 如果开启了删除过期备份,则进行删除操作
        if [ "$expire_backup_delete" == "ON" -a  "$backup_location" != "" ];then
                 #`find $backup_location/ -type d -o -type f -ctime +$expire_days -exec rm -rf {} \;`
                 `find $backup_location/ -type d -mtime +$expire_days | xargs rm -rf`
                 echo "Expired backup data delete complete!"
        fi
        echo "All database backup success! Thank you!"
        exit
fi
 

1.上为pg备份脚本,目录 /home/db_bak/sqlBackup.sh

2.计划任务

        a.执行命令: crontab -e

        b.编写定时任务:(注意不要用中文,包括空格)

                0 23 * * * /home/db_bak/sqlBackup.sh 

                每天23点指定脚本
 

在使用此脚本的时候有可能遇到错误,不要慌张,用了此命令一定让你健步如飞

 sed -i 's/\r//' 文件名.sh 
 

2. 以下脚本生成bak文件 对postgresql 数据库进行备份 生成bak文件
**

#!/bin/bash
echo "开始执行 PostgreSql 数据库  的备份!"
nowtime=$(date +%Y-%m-%d-%H:%M:%S)   # 时间
export PGPASSWORD=数据库密码
echo "时间:" $nowtime
set timeout 500
/usr/pgsql-9.6/bin/pg_dump --file "/opt/data/文件名-$nowtime.bak" --host "127.0.0.1" --port "5432" --username "postgres" --dbname "数据库名" --verbose --role "postgres" --blobs --encoding "UTF8"
echo "数据库   备份完成!"
exit;

 

 postgresql数据备份与恢复在实际工作中可能会用到,这里记录一下自己整理的备份与恢复的过程,备份一般使用pg_dump来做,但是它备份的结果有两种格式,默认不加-Fc参数,产生的备份文件就是原始的sql,可以直接执行,所以这种恢复,直接运行psql就行。另一种增加了-Fc参数,这里-F表示格式化,它有四个选项c|d|t|p,本别表示定制、目录、tar、明文。而默认就是p,也即是明文,所以最终结果是原始的sql,增加了-Fc参数的备份文件,在进行恢复的时候,需要使用pg_restore命令。

    为了演示上面的两种备份与恢复方式,先准备一个test数据库,里面有一个表xx_user,三条记录:

 
     第一种备份与恢复方式:

D:\tools\pgsql>bin\pg_dump.exe test > test.dump
    在进行恢复的时候,直接运行psql test  < test.dump 

 

  第二种备份与恢复方式

D:\tools\pgsql>bin\pg_dump -Fc -f test2.dump test
 这种方式生成的备份文件,虽然也有sql,但是内容里面包含了一些二进制的东西:

    这种方式的恢复,需要使用pg_restore命令,同样的先删除数据库,然后新建一个数据库实例。

D:\tools\pgsql>bin\pg_restore -d test test2.dump
 
 
     
 


PostgreSQL Dokcer版本备份脚本

cat >> /etc/crontab << EOF
# 定时导出,0 1 * * * 表示每天1点执行一次
0 1 * * * root /opt/pgsql_backup_linux/backup_shell/pgsql-docker-bak-backend.sh
EOF

(2)运行以上命令后,重启crond 使定时任务生效。
service crond restart 
pgsql-docker-bak-backend.sh

#!/bin/bash
# 此脚本适用于备份单用户下多个数据库的备份,使用的是pg_dump自带的压缩备份
# ---------------------------------------------------------------------

### 数据库配置 ###
# pg_dump路径,-i 后面跟的是容器的名称或容器的ID
dump_path="docker exec -i postgres pg_dump -F c"

db_link="host=127.0.0.1 port=5432 user=test password=test"

# 指定要备份的数据库名称,多个用空格分开
dbnames=(test postgres)

### 文件配置 ###
# 备份文件存放路径
bakpath=/opt/pgsql_backup_linux/db_data/
# 目录不存在就创建
mkdir $bakpath -p

# 当前时间
cur_time=$(date '+%Y%m%d%H%M%S')
# 保留多少天的文件
days=30
# 删除指定天数之前的文件
find $bakpath -mtime +$days -name "*.*" -exec rm -rf {} \;

for dbname in ${dbnames[@]};
do
	# 数据库链接,user用户名,password密码
	dblink=$db_link" dbname=$dbname"
	# 文件完整路径
	filepath=$bakpath/$dbname-$cur_time
	echo "开始备份 PostgreSQL ..."
	# 导出文件
	$dump_path "$dblink" > "$filepath.bak"
done  


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值