在备份期间,我需要“空闲”Apache,以便我可以停止 MySQL,然后备份 MySQL 和 SQLite 数据库。只能通过 Apache 访问数据库。
目前,我正在考虑使用一个脚本来修改 Apache 配置以将所有访问重定向到“站点关闭”页面,然后:
apache2ctl graceful
systemctl stop mysqld
但是,这似乎不是一个特别好的主意。graceful
不会停止所有子工作者,并且可能会apache2ctl
立即返回。这是一个非常低容量的服务器,备份在半夜运行,在一个时区,我很确定没有一个请求会持续超过一分钟。
sleep 60
有没有一种“好”的方法来处理这个问题,而不是仅仅在后面加上一个graceful
?我认为做一个可能更好的主意,graceful-stop
不要担心网站关闭页面,设置GracefulShutdownTimeout
为 60 秒,并且也休眠 60 秒。
答案1
当长时间关闭是可以接受的时,停机程序相对简单。或多或少你正在做的事情。
在停机之前,当系统仍在运行时,请考虑在网站上提醒用户系统正在维护。各个组织对此的期望各不相同,有些系统会显示今晚系统将停机的横幅,有些系统会显示单独的维护日历。
由于 Web 服务器正在关闭,因此没有太多机会显示维护页面。目前可能不需要。也许将来,这将位于负载平衡器后面,并且可以在连接耗尽时显示静态关闭页面。
如果可用,请使用相同的服务管理器来启动和停止所有应用程序。使用一个工具可以一致地报告状态、依赖项、处理失败停止的清理和其他功能。令人困惑的是,并不是每个发行版都喜欢使用 apachectl 程序,但这没关系,因为httpd 通过信号停止是有据可查的。
停止 Web 服务器,然后停止数据库服务器。依靠服务管理器(在本例中为 systemd 单元)来提供相对优雅的关闭,类似于apachectl graceful-stop
。阅读单元以了解其实现方式的详细信息。
# Stop web first to stop application from accessing data
systemctl stop apache2
# A long wait here is likely not necessary
# the service manager is shutting down processes, and the database is going away soon as well
# Stop one at a time to ensure done in this order
systemctl stop mysqld
# Wait a bit for database files to be closed, just in case
# FIXME this delay is arbitrary
sleep 10
如果通过复制实时数据库文件进行备份,请注意不要让任何进程仍在访问这些文件。复制仍在写入的文件存在副本损坏和备份不良的风险。在正常情况下,正常停止将快速阻止新请求。在轻负载下,清理和关闭工作可以快速完成。棘手的部分是确保即使在特殊情况下也是如此。
仔细的备份可以检查文件是否打开,例如 fuser
在脚本中。还可能向任何剩余进程发送信号,例如 SIGTERM。
需要停机时间,再加上对确保文件关闭的一点担忧,使得这种文件复制备份方法并不像看起来那么容易。考虑其他在线备份方法,例如使用数据库的内置方法热复制其数据或将导出转储到文件。
为了完整性,另一个选项是一致的、在线的、存储级别快照并复制这些文件。也可以避免停机,但由于数据库从未关闭,因此可能更加棘手。安全地执行此操作意味着暂停写入,并了解数据库如何进行启动恢复。
偶尔进行测试恢复。实际上,将数据恢复到测试环境中的某个临时数据库,启动它,并抽查数据是否正确。