2021.03.10 原发布地址:数据库容器恢复与简易备份实现
前情
同事想给小组内部自用的 outline 文档服务添加mathjax
功能,由于不熟悉docker的使用,直接在生产环境大胆执行了docker-compose down
,导致postgres和redis容器被直接删除。
数据恢复
调查之后了解到 docker-compose down
没有特别加上 -v
option时,是不会删除数据所在的volume的,所以新建postgres容器时 mount
上对应的的volumn就可以了。
# 查看对应volume
ls /var/lib/docker/volumes
# 新建postgres容器
docker run -d --name <Container Name> -e POSTGRES_PASSWORD=<Your Password> -p 5432:5432 --mount source=<Volume Name>,target=/var/lib/postgresql/data postgres
复制代码
※docker容器创建时,除了容器本身外还有volume,network一并创建。利用docker inspect <container_id>
可以查看具体信息。
反思
同事在不了解部署环境与技术的情况下直接操作是一个问题。
自己也因为是内部搭的自用服务而疏忽了数据备份,平时过多依赖AWS RDS自带的备份服务也没有养成很好的意识。
生产环境中一份保底的备份策略是必须的,不然等问题真正发生就无法挽回了。
以后利用人数增加的话,实现一个primary+standby+pgBackRest架构应该是最优解吧。
简易备份实现
花了20分钟写了一个备份脚本,因为公司是全套AWS云,所以选择了AWS S3作为备份仓库。
直接用了AWS CLI因为熟悉流程实现起来快一点,考虑到云储存服务适配性应该也能用rclone
来实现。
需求
- 每晚进行数据库备份,文件名格式:outline.YYYYMMDD
- 留下简单的脚本执行日志:/var/log/backup/outline.log
- 设计简单的恢复策略(恢复时限:4h以内)
- 备份失败时进行邮件通知
实现
- 环境:AWS EC2 + postgres in Docker
- 备份脚本
- 备份生成:利用docker的容器交互命令直接进行postgres备份
- 备份上传:AWS S3 (事先准备IAM用户并配置好AWS CLI)
- 定时执行:
crontab
- 失败通知:利用
crontab
的MAILTO=
,设置mutt邮件客户端。
- 恢复策略
- aws cli 拉取S3最新备份
- drop db,create db, 导入。(基本都是markdown文本数据所以数据量较小)
备份脚本
#!/usr/bin/env bash
#####################################
# Author: xxxx
# Version: v1.0.0
# Date: 2021-03-10
# Description: Backup Database
# Usage: sh <file_name>
#####################################
set -Eeuo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1
trap cleanup SIGINT SIGTERM ERR EXIT
DB_NAME=your_database_name
DB_USER=your_database_user
DB_CONTAINER=your_docker_container_name
S3_BACKUP_PATH=s3://
DT=$(date +'%Y%m%d')
cleanup(){
rm -f "${DB_NAME}.${DT}"
}
main(){
# dump
docker exec -it ${DB_CONTAINER} pg_dump -U ${DB_USER} ${DB_NAME} > ${DB_NAME}.${DT}
aws s3 cp ${DB_NAME}.${DT} ${S3_BACKUP_PATH}
# log
echo "[${DT}] ${DB_NAME}.${DT} uploaded to ${S3_BACKUP_PATH}" >> /var/log/backup/${DB_NAME}.log
cleanup
}
main "$@"
复制代码
- Snippets: pg_dump, pg_restore
# dump to single SQL file
$ pg_dump -d mydb -n public -f mydb.sql
# dump to a custom format file
$ pg_dump -d mydb -n public --format=custom -f mydb.pgdmp
# restoring from a SQL dump file, the simple version
$ psql -d mydb_new < mydb.sql
# restoring from a SQL dump file, the recommended version
$ PGOPTIONS='--client-min-messages=warning' psql -X -q -1 -v ON_ERROR_STOP=1 --pset pager=off -d mydb_new -f mydb.sql -L restore.log
# restoring from a dump written to a custom format file
$ pg_restore -d mydb_new -v -1 mydb.pgdmp
# restore a single table from the dump
$ pg_restore -d mydb_new --table=mytable -v -1 mydb.pgdmp
# restore a single function from the dump
$ pg_restore -d mydb_new --function=myfunc -v -1 mydb.pgdmp
复制代码
近期评论