我们已经多次遇到过这种情况,即在尝试恢复 mysqldump 文件时导致 MySQL 数据库损坏。几年来,我们一直使用相同的程序(通过批处理脚本)没有出现问题,直到最近几个月才开始遇到这个问题。
我们正在运行 MySQL 服务器版本:5.7.18-0ubuntu0.16.04.1(Ubuntu 16.04.2 LTS)并且正在恢复两个包含约 350K 条记录(合并)的 MyISAM 表。
我们使用以下 cmd 脚本从内部备份表并恢复到远程数据库服务器:
"%mysql_path%\mysqldump.exe" --user=root --password="%PWD%" --host=%source% ourdbname --tables table1 table2 | "%mysql_path%\mysql.exe" -uroot --password="%PWD%" --host=%dbtarget% -C ourdbname
其中%%
变量作为较大批处理脚本的一部分提供。基本上,我们将转储的输出传输到 mysql.exe 以在远程服务器上恢复。该脚本在 Windows 10 计算机上运行,但源数据库和目标数据库都在 Linux 上。
恢复部分是数据库损坏的地方,这会导致数据库服务器 CPU 使用率飙升至每核 100%。我们发现解决此问题的唯一方法是终止 mysql 进程,删除文件,.frm, .MYD, .MYI
然后启动 mysql 并在本地恢复表(将 mysqldump 文件 scp 到服务器并恢复)。
我们发现,只有当网站上有活跃流量时,数据库才会损坏。因此,我们可以关闭网站(运行 Java 的单独服务器通过 JDBC 连接),运行脚本,然后让网站重新上线,这样网站就可以 100% 正常运行。显然,这不是理想的选择,但这是我们现在唯一能做到的方法。
你知道是什么原因造成的吗?有没有关于如何在不关闭前端服务器的情况下解决这个问题的建议?
答案1
看来您正在使用 MyISAM 作为网站的数据库引擎。我建议使用 InnoDB,它在很多方面都更好。
但是,这里的主要问题是您的 Web 应用程序很可能在将备份写入数据库的同时写入数据库。根据实际的表模式,这可能会导致各种不良影响。使用 MyISAM 只会使其起作用,因为如果我没记错的话,MyISAM 中没有行级锁定。
因此,使用 InnoDB 可能会有所帮助,但话又说回来,也可能无济于事。唯一安全的选择可能是简单地停止前端服务器。另一个选择是为远程应用程序创建一个 API,以便安全地将传入数据写入数据库。