postgresql运维策略

备份

方案一,pgagent执行定时任务

基础条件

postgresql数据库和配套的pgagent安装。注意,现在的pgagent不再是服务而是一个可执行软件,所以,并没有关联路径和配置*.so库的事了。

最好是要安装pgadmin4来配合。图形界面操控更好。

重点

由于pgagent不是服务了,所以,要保证进程运行着。同时如果运行成功,事实上数据库这边的扩展已经建立好了。

下面是检查,可以推导出pgagent的运行命令。

ps aux | grep pgagent | grep -v grep
aroot    23664  0.0  0.1 107680  9624 pts/1    S    15:19   0:00 pgagent -t -f -l 8 host=localhost port=5432 dbname=postgres user=postgres password=w98dy007

同时,从数据库这边要想根据计划任务来调用脚本,则要先检查一个sql(如下图中行一)。如果能列出主机名,则后面就是脚本运行的问题。否则,还不通,即连接和握手协议的底层未成功。

SELECT jagstation FROM pgagent.pga_jobagent;
附赠一个从数据库中查看计划任务结果的查询,方便调试你的任务执行:
select j.jobname, s.jstname, l.jslstart, l.jslduration, l.jsloutput from pgagent.pga_jobsteplog as l 
inner join pgagent.pga_jobstep as s on s.jstid = l.jsljstid 
inner join pgagent.pga_job as j on j.jobid = s.jstjobid
where jslstart > CURRENT_DATE

所以,感觉postgresql的强大就是在于,使用最低调的环境。即不用系统服务,也不用crontab。数据库管理也是B/S架构。

方案二,crond服务

基础条件

已经有了postgresql数据库安装,并且系统是有crond服务。
对于没有crond的嵌入式的系统,可以用方案一,同时配合使用pg_dump,pg_restore这些命令行就不必说了吧。当然安装完库就直接有命令行了。

重点

权限正确而且把要备份的库先查出来,后硬编码在脚本中,再占crond服务来定期调用。举例来说,如果是运维dify项目的话,dify开源中目前是两个重要的库,dify和dify_plugin。

代码是硬通货

#!/bin/bash
# 配置参数
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
DB_USER="postgres"
DB_HOST="localhost"
# 要备份的数据库列表
DATABASES=("dify" "dify_plugin")
# 确保备份目录存在
if [ ! -d "$BACKUP_DIR" ]; then
    echo "备份目录 $BACKUP_DIR 不存在,正在创建..."
    mkdir -p "$BACKUP_DIR"
    # 设置目录权限,确保postgres用户可以写入
    chown -R $DB_USER:$DB_USER "$BACKUP_DIR"
    if [ $? -ne 0 ]; then
        echo "创建备份目录失败,请检查权限!"
        exit 1
    fi
fi
# 备份函数
backup_database() {
    local db_name=$1
    local backup_file="$BACKUP_DIR/${DATE}${db_name}.backup"
    
    echo "开始备份数据库: $db_name"
    su - $DB_USER -c "pg_dump -h $DB_HOST -U $DB_USER -F c -d $db_name -f $backup_file"
    
    # 检查备份是否成功
    if [ $? -eq 0 ]; then
        echo "数据库 $db_name 备份成功,文件: $backup_file"
        echo "文件大小: $(du -h $backup_file | awk '{print $1}')"
    else
        echo "错误:数据库 $db_name 备份失败!" >&2
        # 如果备份失败且文件存在则删除
        if [ -f "$backup_file" ]; then
            rm "$backup_file"
        fi
    fi
}

# 批量备份所有数据库
for db in "${DATABASES[@]}"; do
    backup_database "$db"
    # 每个备份之间间隔1秒,避免资源竞争
    sleep 1
done

echo "所有数据库备份操作已完成"

还原

根据情况是否要手工创建数据库。这取决于你备份时的命令pg_dump选项,如果是-C,-c。可能就不用下用的建库步骤了.
建库的图形化界面操作参考

命令


sudo -u postgres pg_restore --dbname=dify --job=4 --verbose ./20250806dify.backup
sudo -u postgres pg_restore --dbname=dify_plugin --job=4 --verbose ./20250806dify_plugin.backup

结果如下: