##### 数据恢复 调查之后了解到`docker-compose down`没有特别加上`-v` 的option时,是不会删除数据所在的volume的,所以新建postgres容器时`mount`上对应的的volumn就可以了。 ```bash # 查看对应volume ls /var/lib/docker/volumes # 新建postgres容器 docker run -d --name -e POSTGRES_PASSWORD= -p 5432:5432 --mount source=,target=/var/lib/postgresql/data postgres ``` ※docker容器创建时,除了容器本身外还有volume,network一并创建。利用`docker inspect ` 可以查看具体信息。 #### 反思 同事在不了解部署环境与技术的情况下直接操作是一个问题。 自己也因为是内部搭的自用服务而疏忽了数据备份,平时过多依赖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文本数据所以数据量较小) #### 备份脚本 ```bash #!/usr/bin/env bash ##################################### # Author: xxxx # Version: v1.0.0 # Date: 2021-03-10 # Description: Backup Database # Usage: sh ##################################### 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 ```bash # 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 ```