【问题标题】:MySQL for testing environment. Is there a way to freeze the database?MySQL 用于测试环境。有没有办法冻结数据库?
【发布时间】:2017-11-08 23:31:31
【问题描述】:

我有一个网站,在将我的开发代码投入生产之前,我需要进行一些单元测试。

我正在考虑编写一些单元测试,但不是将虚假数据库数据发送回单元测试,而是使用实际的 MySQL 数据库。

但是,我希望测试 MySQL 数据库保持相对静态。也就是说,在页面加载完成后,我希望 MySQL 数据库撤消任何修改数据的查询,例如 INSERTUPDATE 等。这样,数据库将重置为其旧数据并准备好下一个测试。

  • 有没有简单的方法来实现这个想法?还是我应该采取其他方法?
  • 在测试严重依赖 MySQL 查询的网站时,有哪些常见的行业做法?

【问题讨论】:

    标签: mysql database unit-testing testing


    【解决方案1】:

    正如@Barmar 所提到的,您可以在每次测试运行后重新加载数据。这可行,但根据数据的大小,运行 mysqldump 和恢复转储文件可能需要很长时间。

    您可以努力为您的测试创建尽可能小的数据集,以减少时间。

    您还可以努力组织单元测试,以尽量减少需要还原数据的次数。我的意思是对你的测试进行分组,这样即使在对数据进行了更改之后,他们也可以继续测试数据库,直到他们真的需要恢复数据,然后进行恢复,然后继续下一组测试。通过仔细订购测试,您不必在每次测试后都恢复。

    还有其他一些策略:

    • 使用物理备份而不是 mysqldump 备份。使用Percona XtraBackup 创建备份,然后恢复,关闭mysqld,rsync datadir 上的备份文件,chown -R mysql:mysql 文件,然后启动 mysqld。不幸的是,这需要关闭并重新启动 mysqld。

    • 使用InnoDB transportable tablespaces。如果您使用特殊选项对数据库进行物理备份以使表空间可传输,那么您可以使用几个 ALTER TABLE 命令并逐个表替换每个文件表。请参阅文档。不幸的是,我不知道有任何社区工具可以对架构中的所有表执行此操作,您必须自己编写脚本来执行此操作。

    • 使用Percona feature for "fake changes." 我从来没有在单元测试环境中尝试过这个,但我想这是可能的。它实际上是为了帮助启动副本上的缓冲池。这个想法是任何像 INSERT、UPDATE、DELETE 这样的 DML 都将成为空操作。这需要使用 Percona Server。而且它可能无法满足您的测试需求,因为当然,您的测试应该编写的任何更改都不会产生任何更改。

    • LVM snapshots. 这可能是您的最佳选择。在开始测试之前加载您的测试数据,并在那时拍摄文件系统快照。然后在每次测试运行后,将文件系统恢复为快照。这需要您在每次还原时关闭 mysqld。但无论数据库大小如何,执行快照和恢复都非常简单快捷。我见过这种方法用于快速恢复数 TB 的数据库。

    【讨论】:

    • 感谢您的回答!
    【解决方案2】:

    通过将数据库转储到文件来制作快照。

    mysqldump yourDB > yourDB.sql
    

    然后运行您的测试并恢复到快照:

    mysql < yourDB.sql
    

    【讨论】:

    • 我希望在每次测试之间重置数据库。我也希望以非处理器密集型方式进行,即不转储和恢复。
    • 我想如果必须的话,我可以创建一个类来跟踪 UPDATEINSERT 查询,并在测试结束时撤消它们。但我希望有一个更直接的解决方案。
    • 以通用方式很难做到这一点。
    • 例如,如果UPDATE 处于复杂连接中,则很难确定更新了哪些行。如果您有DELETE 查询,则需要保存旧内容以便恢复它们。您的测试框架最终可能比应用程序更复杂,您需要对测试进行单元测试。
    • 也许我可以为每个UPDATEINSERTDELETE 进行交易?然后计算事务数并在测试结束时回滚该事务数?
    猜你喜欢
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    相关资源
    最近更新 更多