我想创建一个MySQL数据库的自动备份。我想要的行为如下
Cron
每天工作一次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
作为安全漏洞,虽然在这种情况下它是安全的,因为我只能访问服务器并负责配置文件和输入。
答案 0 :(得分:1)
根据J.F Sebastian对我原来问题的评论,我已经知道subprocess.Popen()
立即返回。
我的程序正在启动数据库转储,然后立即转移到执行所有上传工作的函数。因此,正在向AWS S3
发送不完整的数据库转储。解决方案是添加.wait()
函数。
dc = subprocess.Popen(dump_cmd, shell=True)
dc.wait()
用户BK435
曾建议将正在运行的数据库数据文件的副本作为替代方案,但该注释已被否定/删除。在其中,他提到将mysqldump从正在运行的数据库中删除并不是一个好主意,但我没有找到证据支持这是一个坏主意。它确实锁定了表格,但我很好,应用程序每晚都会停机几分钟。