【发布时间】:2015-07-14 17:36:05
【问题描述】:
我想创建 MySQL 数据库的自动备份。我想要的行为如下
-
Cron作业每天运行一次 - 转储文件被压缩并存档到
Amazon S3
当我需要从备份中恢复时,会发生以下情况..
- 连接到 Amazon S3
- 从相应的存储桶下载压缩转储文件
- 解压缩文件并从该文件恢复数据库。
发生了什么:一切似乎都运行良好。我使用 Python 将所有行为自动化。我已经成功备份,并按预期成功恢复了数据库。
现在我注意到有时 dump-zip-archive 过程会导致无法恢复的转储文件。当我尝试恢复数据库时,我收到错误gzip: myDumpFile.sql.gz: unexpected end of file。我注意到,通常一个不成功的备份文件会比正常工作的文件小(好的:2 Mb。坏的:~600 Kb)。运行 python 脚本以创建损坏的备份时,我没有收到任何错误。
我是怎么做的
我正在使用boto Python 库与Amazon S3 进行通信。实际的转储文件如下创建
import subprocess
...
dump_cmd = ['mysqldump ' +
'--user={mysql_user} '.format(mysql_user=cfg.DB_USER) +
'--password={db_pw} '.format(db_pw=cfg.DB_PW) +
'--host={db_host} '.format(db_host=cfg.DB_HOST) +
'{db_name} '.format(db_name=cfg.DB_NAME) +
'| ' +
'gzip ' +
'> ' +
'{filepath}'.format(filepath=self.filename)]
subprocess.Popen(dump_cmd, shell=True)
...
当我要恢复时,从 S3 下载文件并发出以下命令
unzip_cmd = ['gzip -d {filename}'.format(filename=self.filename)]
restore_cmd = ['mysql ' +
'--user={mysql_user} '.format(mysql_user=cfg.DB_USER) +
'--password={db_pw} '.format(db_pw=cfg.DB_PW) +
'--host={db_host} '.format(db_host=cfg.DB_HOST) +
'{db_name} '.format(db_name=cfg.DB_NAME) +
'< ' +
'{filepath}'.format(filepath=self.filename[:-3])]
subprocess.Popen(unzip_cmd, shell=True)
subprocess.Popen(restore_cmd, shell=True)
为什么这有时会导致.gz 文件损坏? CRON 运行它或我手动执行之间没有相关性,好的和坏的转储都来自任何一个。
注意我被警告不要使用shell=True 作为安全漏洞,尽管在这种情况下它是安全的,因为只有我可以访问服务器并负责配置文件和输入。
【问题讨论】:
-
@BK435 我正在从具有活动连接的实时数据库中删除转储
-
@BK435 我没有看过 CRON 运行,但我手动运行过。手动运行随机失败
-
Popen()立即返回。你试过check_call()吗? -
@BK435 这是一个危险的建议...您无法安全地复制正在运行的 MySQL 服务器的数据目录作为备份方法。这是不支持的。您对连接计数或超时的推测也不正确。这两种情况都会导致 无错误 gzip 容器,其中包含截断或空的 SQL 语句文件。该错误清楚地表明 gzip 结构已损坏,并且没有传达有关有效负载的信息。
标签: python mysql amazon-s3 subprocess gzip