【问题标题】:Managing mysql schema changes with SQL scripts and transactions使用 SQL 脚本和事务管理 mysql 架构更改
【发布时间】:2010-08-05 10:07:48
【问题描述】:

我在 PHP/MySQL 应用程序中处理多个数据库。我有开发、测试、登台和生产数据库来保持同步。

目前我们仍在构建这个东西,所以很容易让它们保持同步。我使用我的开发数据库作为主数据库,当我想更新其他数据库时,我只需核对它们并从我的重新创建它们。但是,将来一旦有真实数据,我就无法做到这一点。

我想将 SQL 脚本编写为文本文件,我可以使用 svn 中伴随它们的 PHP 更改对其进行版本控制,然后在我更新它们时将脚本应用到每个数据库实例。

我想使用事务,这样如果脚本期间出现任何错误,它将回滚所做的任何部分更改。所有的表都是 InnoDB

当我尝试添加一个已经存在的列,并像这样添加一个新列时:

SET FOREIGN_KEY_CHECKS = 0;
START TRANSACTION;
ALTER TABLE `projects` ADD COLUMN `foo1` varchar(255) NOT NULL after `address2`;
ALTER TABLE `projects` ADD COLUMN `foo2` varchar(255) NOT NULL after `address2`;
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

...它仍然提交新列,即使它未能添加第一个列,当然,因为我发出的是 COMMIT 而不是 ROLLBACK。

我需要它在出错时有条件地发出回滚命令。如何在即席 SQL 脚本中执行此操作?

我知道存储过程的“声明退出处理程序”功能,但我不想存储它;我只想将它作为临时脚本运行。

为了获得条件回滚,我是否需要将其放入存储过程中,或者是否有另一种方法可以在单个即席 SQL 脚本中使整个事务原子化?

欢迎任何指向示例的链接 - 我已经用 Google 搜索过,但目前只找到存储的 proc 示例

非常感谢

伊恩

编辑 - 这永远行不通; ALTER TABLE 遇到时会导致隐式提交:http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html 感谢 Brian 的提醒

【问题讨论】:

    标签: mysql transactions rollback


    【解决方案1】:

    前几天我了解到,数据定义语言语句总是在 MySQL 中起作用,并在应用它们时导致事务被提交。如果您想确保成功,我认为您可能必须以交互方式执行此操作。

    我在讨论这个问题的网站上找不到问题(只是几天前)。

    如果您需要保持多个数据库同步,您可以考虑复制。尽管复制不是小事,但它可能正是您所需要的。见http://dev.mysql.com/doc/refman/5.0/en/replication-features.html

    【讨论】:

    • 嗨,Brian,感谢您提供有关 DDL 的提示 - 这确实隐约响起了某种铃声……如果我发现任何问题,我会检查并更新问题。复制绝对不是这里的答案! ...作为开发工作流程的一部分,这些副本意味着每个副本在不同的时间点都有不同的数据和架构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 2017-12-16
    • 2011-08-04
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    相关资源
    最近更新 更多