1

您应该如何“安全地”恢复(和备份)MySQL 数据库?我所说的“安全”是指:恢复应该创建/覆盖所需的数据库,但不要冒险更改该数据库之外的任何内容

我已经阅读了https://dev.mysql.com/doc/refman/5.7/en/backup-types.html

我有外部用户。他们和我可能想要交换备份以进行恢复。我们没有商业 MySQL Enterprise Backup,也没有寻找第三方商业产品。

在 Microsoft SQL Server 中有BACKUPRESTORE命令。 BACKUP创建一个只包含您想要的数据库的文件;它的行和它的所有模式/结构都包括在内。 RESTORE接受这样的文件,并创建或覆盖其结构。用户可以恢复到同名数据库,或指定不同的数据库名称。这种行为正是我想要的。

在 MySQL 中,我遇到了 3 种可能性:

  1. 大多数人似乎使用mysqldump创建一个“转储文件”,并将mysql其读回。转储文件包含任意 MySQL 语句的列表,这些语句由mysql. 这是非常不可接受的:该文件可能包含任何SQL 语句。(限制恢复用户的访问权限以确保它不能做任何“顽皮”的事情是不可接受的。)还有一个问题是用户可能已经使用“包含 CREATE Schema”选项(MySQL Workbench)创建了转储文件,它硬编码原始数据库名称以供娱乐。这种“转储”方法完全不适合我,而且我发现有人会在生产环境中使用它感到惊讶。

  2. 我遇到过 MySQL 的SELECT ... INTO OUTFILELOAD DATA INFILE语句。至少它们不包含要执行的 SQL 代码。但是,它们看起来工作量很大,一次处理一个表而不是整个数据库,并且不处理表的结构,您必须自己了解才能进行恢复。有一个mysqlimport辅助命令行实用程序,但我没有看到导出端的任何内容,也没有看到它用于恢复完整的数据库。

  3. 最后一种是使用 MySQL 所说的“物理(原始)”而不是“逻辑”备份。这适用于数据库目录和文件本身。它相当于 SQL Server 的detach/attach备份/恢复方法。但是,根据https://dev.mysql.com/doc/refman/5.7/en/backup-types.html,它有各种各样的警告,例如“备份只能移植到具有相同或相似硬件的其他机器上特征。” (我不知道,例如某些用户是 Windows 与 Windows,我不知道他们的架构)和“可以在 MySQL 服务器未运行时执行备份。如果服务器正在运行,则有必要执行适当的锁定,因此服务器在备份期间不会更改数据库内容。”

那么,如上所述,任何东西都可以满足(我认为)我对 MySQL 备份/恢复的适度要求吗?我真的是唯一一个认为上述 3 是唯一但不可接受的可能解决方案的人吗?

4

3 回答 3

1

如果您不打算使用第三方工具(例如 innobackupex),那么您只能使用... mysqldump,它位于 mysql 包中。
我不明白为什么你不能接受它,为什么你不喜欢那些转储中的 sql 命令。最佳实践是将单个数据库还原到已包含其他数据库的服务器中时,有一个单独的用户,该用户仅有权写入还原的数据库。然后,即使用户执行恢复,会更改 sql 命令并尝试写入另一个数据库,他们将无法做到。
进行原始备份(数据库文件的物理副本)时,您需要关闭所有实例,mysql 服务器未运行。类似的硬件意味着您需要与源服务器具有相同的目录(除非您在启动服务器之前更改 my.cnf 并将所有文件放在正确的目录中)。
进入 mysql 时,尽量不要将其与 sql server 进行比较——这是完全不同的方法和理念。
但是,如果你想说服自己使用第三方工具——我推荐 Percona 的 innobackex,顺便说一句,它是免费的。

于 2017-12-13T16:23:20.777 回答
1

1 - mysqldump- 我经常使用这个,通常在我自己处理所有细节的环境中。我确实有一种配置,我用它来发送开发数据库的副本 - 将其全部转储/恢复 - 给其他开发人员。它可能是最快的解决方案,具有一些合理的配置选项(例如,包含/排除特定表)并生成非常实用的 SQL 代码(例如,每个 INSERT 批处理足够小以避免锁定/速度问题)。对于“替换整个数据库”或“替换特定数据库中的关键表”的解决方案,它工作得很好。我不太关心“任意 SQL 命令”问题 - 如果这是一个问题,那么您可能会遇到其他问题,即用户试图“做自己的事情”。

2 -SELECT ... INTO OUTFILE并且LOAD DATA INFILE- 这些问题是,如果你有任何非常大的表,那么该LOAD DATA INFILE语句可能会导致问题,因为它试图一次加载所有内容。您还必须添加代码来创建(如果需要)或清空之前的表LOAD DATA

3 - 物理(原始)文件传输。这可以工作,但在有限的情况下。我有一个多千兆字节数据库的情况,并决定压缩原始文件,将它们移动到新机器,解压缩并告诉 MySQL“一切都已经存在”。它大多运作良好。但是由于许多可能的问题,我不建议将它用于任何无人值守/最终用户进程。

我有什么建议?

1 - mysqldump- 忍受它的限制和风险,设置一个脚本来调用mysqldump并压缩文件(我很确定mysqldump中有自动压缩的选项),在文件名中包含日期以便更少当文件被发送时混淆,并为用户制作一个简单的脚本来加载文件。

2 - 编写自己的程序。我已经这样做了几次。这最初的工作量更大,但允许您控制流程的各个方面并传输仅包含数据而没有任何实际 SQL 代码的文件。您可以控制特定的数据库、表等。一个问题是,如果您对表结构、索引等进行任何更改,您将需要确保信息以某种方式传输到接收问题,以便它可以更改根据需要构建结构——这不是问题,mysqldump因为它通常会替换表、创建新结构、索引等。这可以用任何可以连接到 MySQL 的语言编写——它不必与您的语言相同应用。

于 2017-12-13T16:23:44.537 回答
1

补充的导出工具mysqlimportmysqldump --tab. 这会输出 CSV 文件,例如SELECT...INTO OUTFILE. 它还在更小的 .sql 文件中输出表结构。所以每个表有两个文件。

从 .sql 文件重新创建表后,您可以使用它mysqlimport来导入所有数据文件。您甚至可以使用该mysqlimport --use-threads选项使其并行加载多个数据文件。

通过这种方式,您可以更好地控制将数据加载到哪个模式,并且它的运行速度应该比加载大型 SQL 转储快得多。

于 2017-12-13T16:30:25.337 回答