docker部署postgresSQL 并做持久化
修改外部可以连接,复制配置到外部。把 第一行的改成第二行。把修改的配置复制到容器。
先安装docker,安装docker 方法自行寻找方法
然后安装pgsql
拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/postgres:16.4
运行容器
docker run -it --name postgres --privileged --restart always -e POSTGRES_PASSWORD='Yo5WYypu0mCCheOU' -e ALLOW_IP_RANGE=0.0.0.0/0 -e TZ=Asia/Shanghai -p 5432:5432 -v /data/postgres/data:/var/lib/postgresql/data -d registry.cn-hangzhou.aliyuncs.com/qiluo-images/postgres:16.4
运行postgresql 18.3 (注意:数据目录改到 /var/lib/postgresql/18/啦)
docker run -d \
--name postgres \
--restart always \
-e POSTGRES_PASSWORD='Yo5WYypu0mCCheOU' \
-e POSTGRES_DB=postgres \
-p 5432:5432 \
-v /data/postgres:/var/lib/postgresql \
-v /data/postgres/config:/etc/postgresql \
registry.cn-hangzhou.aliyuncs.com/qiluo-images/postgres:latest
带连接数
docker run -it --name postgres --privileged --restart always -e POSTGRES_PASSWORD='Yo5WYypu0mCCheOU' -e ALLOW_IP_RANGE=0.0.0.0/0 -e TZ=Asia/Shanghai -p 5432:5432 -v /data/postgres/data:/var/lib/postgresql/data -d registry.cn-hangzhou.aliyuncs.com/qiluo-images/postgres:16.4 -c 'max_connections=20000'
修改外部可以连接,复制配置到外部
docker cp postgres:/var/lib/postgresql/data/pg_hba.conf /data/postgres/pg_hba.conf
把 第一行的改成第二行
把修改的配置复制到容器
docker cp /data/postgres/pg_hba.conf postgres:/var/lib/postgresql/data/pg_hba.conf
然后重启容器
docker restart postgres
开启5432端口
firewall-cmd --permanent --add-port=5432/tcp
firewall-cmd --reload
查看安装的服务版本
docker exec -it postgres psql -U postgres -c "SELECT version();"
docker exec -it postgres psql -U postgres -c "SHOW server_version;"
本文镜像版本是16.4
默认是设置了时区,如果没有设置的,在容器内手动设置,你也可以在运行的 PostgreSQL 容器内手动更改时区设置。
进入容器:
docker exec -it postgres bash
编辑 postgresql.conf 文件,将 timezone 设置为你需要的时区:
echo "timezone = 'Asia/Shanghai'" >> /var/lib/postgresql/data/postgresql.conf
退出,重启容器
docker restart postgres
如果是单独修改,复制出来
docker cp postgres:/var/lib/postgresql/data/postgresql.conf /data/postgres/
如果要开启记录慢sql(不开启忽略)
在配置文件中找到并修改 shared_preload_libraries 行:
# 取消注释或添加这行
shared_preload_libraries = 'pg_stat_statements'
# 在文件末尾添加这些配置
pg_stat_statements.track = all
pg_stat_statements.max = 10000
pg_stat_statements.track_utility = on
pg_stat_statements.save = on
完整验证
-- 验证扩展状态
SELECT extname, extversion FROM pg_extension WHERE extname = 'pg_stat_statements';
-- 执行测试查询来生成统计信息
SELECT version();
SELECT current_timestamp;
SELECT count(*) FROM pg_class;
-- 等待统计信息更新
SELECT pg_sleep(2);
-- 现在应该能正常查询了
SELECT count(*) FROM pg_stat_statements;
-- 查看统计信息
SELECT
query,
calls,
total_exec_time,
mean_exec_time
FROM pg_stat_statements
LIMIT 5;
-- 查看最耗时的 SQL
SELECT
queryid,
query,
calls,
total_exec_time,
mean_exec_time,
min_exec_time,
max_exec_time,
stddev_exec_time,
rows,
100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent,
wal_records,
wal_fpi
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())
ORDER BY mean_exec_time DESC
LIMIT 10;
然后再宿主机编辑,修改连接数
max_connections=100 改成max_connections=20000
然后把配置文件复制回去
docker cp /data/postgres/postgresql.conf postgres:/var/lib/postgresql/data/postgresql.conf
重启容器
docker restart postgres
执行如下SQL进行验证,查看max_connections:
docker exec -it postgres psql -U postgres -c "show max_connections;"
查看当前连接数:
select count(*) from pg_stat_activity;
数据库定期备份
vi backup_postgres.sh
#!/bin/bash
# 设置变量
BACKUP_DIR="/data/postgres/data_backup"
CONTAINER_NAME="postgres"
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/postgres_backup_${TIMESTAMP}.tar.gz"
# 创建备份目录(如果不存在)
mkdir -p "$BACKUP_DIR"
# 清理旧的备份(根据您的需求)
find "$BACKUP_DIR" -type f -name "*.tar.gz" -mtime +30 -exec rm {} \;
# 复制容器内的数据到临时目录
docker cp "${CONTAINER_NAME}:/var/lib/postgresql/data" "/tmp/postgres_data"
# 压缩数据
tar -czf "$BACKUP_FILE" -C "/tmp" "postgres_data"
# 清理临时目录
rm -rf "/tmp/postgres_data"
# 输出备份文件路径
echo "备份已完成,文件:$BACKUP_FILE"
赋予该脚本执行权限:
chmod +x backup_postgres.sh
定期运行备份:
您可以通过 cron 定期运行该脚本。每日备份,可以编辑 cron 任务:
crontab -e
然后添加以下行以设置每天凌晨 2 点备份:
0 2 * * * /data/postgres/backup_postgres.sh
0 2,8,12,20 * * * /data/postgres/backup_postgres.sh
0:表示在每小时的第0分钟执行。
2,8,12,20:表示凌晨2点、早上8点、中午12点和晚上8点执行。
-
- *:表示每天都执行。
这样,备份任务会在你指定的四个时间点执行。
- *:表示每天都执行。
整个表达式的意思是:每天凌晨 2 点、早上 8 点、中午 12 点和晚上 8 点,在每个小时的第0分钟执行 /data/postgres/backup_postgres.sh 这个备份脚本。
请将 /data/backup_postgres.sh 替换为您的脚本实际路径
注意事项:
此脚本会创建一个备份目录 /data/postgres/data_backup,若该目录不存在,则会自动创建。
只保留最近 30 天的备份(通过 -mtime +30 进行控制),可以根据需要调整这个值。
确保您的 PostgreSQL 容器名(CONTAINER_NAME)与实际的容器名称一致。
若您需要更频繁的备份,可以调整 cron 的设置来满足需求。
脚本运行时可能需要适当的权限来访问 Docker 和目标目录。
数据恢复
把备份数据复制到/opt然后解压,然后把数据复制到容器
docker cp /opt/data postgres_back:/var/lib/postgresql/
sudo docker exec -it postgres_back chown postgres:postgres /var/lib/postgresql/data/
sudo docker exec -it -u 0 postgres_back chmod 644 /var/lib/postgresql/data/
进入容器后,创建备份目录:
docker exec -it <容器名称或ID> bash
mkdir -p /data/backup
- 重新运行 pg_dump 命令
在容器中运行以下命令:
pg_dump -U <用户名> -d dynamic_xx_v3 -t public.sys_log > /data/backup/sys_log.sql
- 从容器拷贝到主机
如果文件存在,可以从容器中拷贝到主机:
docker cp <容器名称或ID>:/data/backup/sys_log.sql /opt/sys_log.sql
怎么恢复sys_log.sql
docker cp /opt/sys_log.sql <容器名称或ID>:/data/backup/sys_log.sql
- 进入容器
进入 PostgreSQL 容器:
docker exec -it <容器名称或ID> bash
- 使用 psql 恢复表数据
运行以下命令,恢复 sys_log 表的数据:
psql -U postgres -d dynamic_xx_v3 < /data/backup/sys_log.sql
就完成数据恢复单张表了
额外备份最新的一份到/mnt
#!/bin/bash
# 设置变量
SOURCE_DIR="/data/postgres/data_backup" # 源备份目录
TARGET_DIR="/mnt" # 目标目录
# 检查源目录是否存在
if [ ! -d "$SOURCE_DIR" ]; then
echo "错误:源目录 $SOURCE_DIR 不存在"
exit 1
fi
# 创建目标目录(如果不存在)
mkdir -p "$TARGET_DIR"
# 查找源目录中最新的备份文件
LATEST_BACKUP=$(find "$SOURCE_DIR" -maxdepth 1 -type f -name "postgres_backup_*.tar.gz" -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
# 检查是否找到备份文件
if [ -z "$LATEST_BACKUP" ]; then
echo "错误:在 $SOURCE_DIR 中未找到备份文件"
exit 1
fi
echo "找到最新备份文件:$LATEST_BACKUP"
# 清理目标目录中的所有旧备份文件
echo "清理目标目录中的旧备份文件..."
find "$TARGET_DIR" -maxdepth 1 -type f -name "postgres_backup_*.tar.gz" -exec rm -f {} \;
# 复制最新备份文件到目标目录
echo "正在复制最新备份文件到 $TARGET_DIR ..."
cp "$LATEST_BACKUP" "$TARGET_DIR/"
# 验证复制结果
if [ $? -eq 0 ]; then
echo "备份文件复制成功!"
echo "当前 $TARGET_DIR 中的备份文件:"
ls -lt "$TARGET_DIR"/postgres_backup_*.tar.gz 2>/dev/null
else
echo "错误:备份文件复制失败"
exit 1
fi
chmod +x backup_script.sh
./backup_script.sh
这种是防止数据盘挂载丢失数据。
crontab -e
0 2,8,12,20 * * * /mnt/backup_script.sh
包含备份宿主机的最新文件
#!/bin/bash
# 设置变量
BACKUP_DIR="/data/postgres/data_backup" # 备份文件存放目录
SOURCE_DIR="/data/postgres/data" # PostgreSQL数据目录
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/postgres_backup_${TIMESTAMP}.tar.gz"
# 创建备份目录(如果不存在)
mkdir -p "$BACKUP_DIR"
# 清理旧的备份(保留30天)
find "$BACKUP_DIR" -type f -name "*.tar.gz" -mtime +30 -exec rm {} \;
# 检查源目录是否存在
if [ ! -d "$SOURCE_DIR" ]; then
echo "错误:源目录 $SOURCE_DIR 不存在"
exit 1
fi
# 检查PostgreSQL是否在运行
if systemctl is-active --quiet postgresql; then
echo "警告:PostgreSQL服务正在运行"
echo "选项:"
echo "1) 停止服务后备份(推荐,保证数据一致性)"
echo "2) 在线备份(可能造成数据不一致)"
read -p "请选择 [1/2]: " choice
case $choice in
1)
echo "停止PostgreSQL服务..."
systemctl stop postgresql
NEED_RESTART=true
;;
2)
echo "执行在线备份(风险自负)..."
NEED_RESTART=false
;;
*)
echo "无效选择,退出"
exit 1
;;
esac
else
NEED_RESTART=false
fi
# 压缩数据
echo "正在压缩 $SOURCE_DIR 到 $BACKUP_FILE ..."
# 方式1:如果数据目录较小,可以先创建临时目录再打包
# TMP_DIR="/tmp/postgres_backup_${TIMESTAMP}"
# cp -r "$SOURCE_DIR" "$TMP_DIR"
# tar -czf "$BACKUP_FILE" -C "/tmp" "$(basename "$TMP_DIR")"
# rm -rf "$TMP_DIR"
# 方式2:直接打包(推荐,效率更高)
cd "$(dirname "$SOURCE_DIR")" || exit 1
tar -czf "$BACKUP_FILE" "$(basename "$SOURCE_DIR")"
# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "备份已完成,文件:$BACKUP_FILE"
echo "备份文件大小:$(du -h "$BACKUP_FILE" | cut -f1)"
# 显示备份文件信息
echo "备份文件列表:"
tar -tzf "$BACKUP_FILE" | head -10
echo "..."
else
echo "错误:备份失败"
# 如果需要重启服务
if [ "$NEED_RESTART" = true ]; then
echo "启动PostgreSQL服务..."
systemctl start postgresql
fi
exit 1
fi
# 如果需要重启服务
if [ "$NEED_RESTART" = true ]; then
echo "启动PostgreSQL服务..."
systemctl start postgresql
if [ $? -eq 0 ]; then
echo "PostgreSQL服务已启动"
else
echo "错误:PostgreSQL服务启动失败"
exit 1
fi
fi
# 创建最新备份的符号链接
ln -sf "$BACKUP_FILE" "${BACKUP_DIR}/latest_backup.tar.gz"
echo "备份完成时间:$(date)"
创建命令 18.3 版本
CREATE DATABASE "cq_xx_platform" WITH OWNER = "cq_xx_platform";
CREATE ROLE"cq_xx_platform" CREATEDB CREATEROLE LOGIN PASSWORD '50Gaula6FIM64k1R';
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)