背景
MySQL的数据备份一直以来都是一个重要议题,近来我遇到了一些奇怪的事件,同时网络攻击也层出不穷,这让我更加认识到了MySQL数据备份的重要性。
目前,我在使用阿里云的RDS服务,无法进行物理备份,只能依靠mysqldump进行逻辑备份。然而,考虑到备份文件存放在本地磁盘的风险,一旦磁盘发生故障,备份工作就相当于无用功。
因此,我最终决定将数据库备份的SQL文件同时存储到阿里云的OSS对象存储和腾讯云的COS对象存储中。我在不同城市分别创建了不同的存储桶(Bucket),以最大程度地避免同一城市发生大规模故障的问题。这样做的目的是为了确保备份文件的安全性和可靠性。
具体使用了如下资源:
备份脚本准备
备份脚本是执行mysqldump 循环将对应数据库的数据以单个文件存储,shell如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | DB_HOST=""DB_PORT=""
 DB_USER=""
 DB_PASSWORD=""
 
 # 备份目录
 BACKUP_DIR="mysqlbackup"
 
 BACKUP_FOLDER=$(date +"%Y-%m-%d-%H_%M_%S")
 
 BACKUP_FOLDER_PATH="$BACKUP_DIR/$BACKUP_FOLDER"
 
 mkdir -p $BACKUP_FOLDER_PATH
 
 # 获取数据库列表
 DATABASES=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD -e "SHOW DATABASES;" | awk '{if (NR>1) print $1}')
 
 # 备份每个数据库
 for DATABASE in $DATABASES; do
 BACKUP_FILE="$BACKUP_FOLDER_PATH/$DATABASE.sql"
 mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD $DATABASE > $BACKUP_FILE
 if [ $? -eq 0 ]; then
 echo "数据库备份成功:$BACKUP_FILE"
 else
 echo "数据库备份失败:$DATABASE"
 fi
 
 | 
然后就是对应执行mysqldump的环境了,因为的物理机服务器没有装mysql,直接使用阿里云的flow使用docker容器跑对应脚本就可以了。
运行环境准备
阿里云的flow支持直接在docker镜像内运行对应的脚本,所以要准备一个合适的docker镜像,需要满足三个条件:
直接根据对应的需求写一个简单的dockerfile:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | # centOS镜像FROM centos:7
 
 # 备份原始的yum源配置文件
 RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
 
 # 添加阿里云的yum源配置文件
 ADD https://mirrors.aliyun.com/repo/Centos-7.repo /etc/yum.repos.d/CentOS-Base.repo
 
 # 清除yum缓存
 RUN yum clean all
 
 RUN yum -y update && yum -y install mysql mysql-server
 
 COPY coscli /usr/bin/
 COPY ossutil /usr/bin/
 
 | 
需要提前将对应的文件下载到本地,然后赋予执行权限:
| 12
 
 | chmod +x cosclichmod +x ossutil
 
 | 
接下来就是build镜像,然后推送到镜像仓库(阿里云个人镜像):
| 12
 
 | docker build -t aliyun-mysql:latest .docker push aliyun-mysql:latest
 
 | 
创建GIT仓库
创建一个空的git仓库,将cosconfig、ossconfig需要的ak等信息存储在仓库中,然后push到git仓库
cosconfig.yaml示例:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | cos:base:
 secretid:  sid加密
 secretkey: sek加密
 sessiontoken: token
 protocol: https
 mode: ""
 cvmrolename: ""
 buckets:
 - name: bucket-name
 alias: bucket-name
 region: "ap-shanghai"
 endpoint: cos.ap-shanghai.myqcloud.com
 ofs: false
 
 | 
ossconfig.yaml示例:
| 12
 3
 4
 5
 6
 
 | [Credentials]language=EN
 endpoint  = oss-cn-beijing.aliyuncs.com
 accessKeyID = akid
 accessKeySecret = aks
 mode = AK
 
 | 
创建阿里云flow任务
 创建任务主要是要选择自定义环境构建,使用上文中的docker镜像,执行对应的命令,图片中完整命令如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | DB_HOST=""DB_PORT=""
 DB_USER=""
 DB_PASSWORD=""
 COS_BUCKET_NAME=""
 OSS_BUCKET_NAME=""
 
 # 备份目录
 BACKUP_DIR="mysqlbackup"
 
 BACKUP_FOLDER=$(date +"%Y-%m-%d-%H_%M_%S")
 
 BACKUP_FOLDER_PATH="$BACKUP_DIR/$BACKUP_FOLDER"
 
 mkdir -p $BACKUP_FOLDER_PATH
 
 # 获取数据库列表
 DATABASES=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD -e "SHOW DATABASES;" | awk '{if (NR>1) print $1}')
 
 # 备份每个数据库
 for DATABASE in $DATABASES; do
 BACKUP_FILE="$BACKUP_FOLDER_PATH/$DATABASE.sql"
 mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD $DATABASE > $BACKUP_FILE
 if [ $? -eq 0 ]; then
 echo "数据库备份成功:$BACKUP_FILE"
 else
 echo "数据库备份失败:$DATABASE"
 fi
 
 # 文件上传到oss
 ossutil cp -r mysqlbackup oss://$OSS_BUCKET_NAME/ --update -c mysql/ossutilconfig
 #文件上传到cos
 coscli cp mysqlbackup/ cos://$COS_BUCKET_NAME/ -r -c mysql/cos.yaml
 
 done
 
 
 | 
最终任务详情如下图:

定时触发

总结
编写Shell脚本基本上没有花费太多时间,我直接使用了助理工具完成。在此过程中,也遇到了一些问题:
- 官方的mysql:latest镜像无法正常执行coscli命令,所以我决定直接在centos:7中安装所需的工具。
- 在创建带有时间标记的文件夹时,由于无法使用yyyy-MM-dd HH:mm:ss样式。
- 关于COS/OSS的Access Key最小授权问题,这个需要探索。
备份并不是我们的终极目标,而是为了确保服务的长期稳定运行,以应对突发情况。在我们日常使用MySQL时,更需要关注MySQL本身的安全措施,包括限制端口的可访问性、避免对外暴露、使用复杂密码进行数据库访问并定期更改密码等等。