【问题标题】:Concurrent database creation并发数据库创建
【发布时间】:2017-01-25 20:39:27
【问题描述】:

我的网络应用程序需要在安装期间执行一些初始数据库脚本。这些只是一些需要运行的 CREATE TABLE 脚本。我正在处理它。

我一直在尝试使用 Docker 1.12 的 swarm 模式来创建我的 Web 应用程序的多个容器副本,这些副本使用共享数据库。 (Oracle 12c 或 MySQL 实例)。

问题是当我启动容器的多个副本时,它们都尝试同时运行 SQL 脚本并失败。我尝试使用 Flyway 处理数据库迁移,但无济于事。

这种情况应该怎么处理?

【问题讨论】:

  • 您的应用肯定要先检查这些表是否存在,也就是说您的数据库迁移只会执行尚未完成的操作,否则您的应用将无用...
  • @OlegSklyar 你想把它转换成诸如create table IF NOT EXISTS thing ( col1 int not null, col2 int not null, age int not null ); 这样给出警告/错误1050 link 的答案吗?
  • @Drew 谢谢,完成。

标签: mysql database oracle docker


【解决方案1】:

一般来说,数据库迁移作业应该在每个新脚本都执行完后才执行版本控制。以此为先决条件,可以设计一种工具,如果尚未运行,则依次运行这些作业,或者让作业始终运行,但设计它们以检查它们是否尚未运行之前做过。

否则,所有应用程序数据都有在下次部署时被清除的风险。您应该能够随时部署并重用现有数据(使用或不使用 docker)。

在您的“简单”情况下,以下类型的数据库检查会有所帮助:

create table IF NOT EXISTS thing (col1 int not null, col2 int not null, age int not null );

感谢@Drew 提示我将我的评论放入答案中。

【讨论】:

  • 不应该像 Flyway(我提到的)这样的数据库迁移工具处理这个问题吗? Flyway 确实创建了一个 schema_version 表来处理版本化迁移。但是在运行迁移时创建同一个表时失败。请参阅 [此] (github.com/flyway/flyway/issues/1435)。此外,这些数据库脚本的执行只是一次性的事情。在此休眠启动并处理所有数据库操作之后。
  • AFAIK flyway 通常应该,因为它正是它所应用的原理,但我不是 flyway 专家来告诉你如何配置版本控制。但是,flyway 通常在部署时使用,而不是在启动时使用,或者至少与启动分开使用,因为即使您部署 100 个实例,它也只需要运行一次。并行运行它(除了在单个数据库上几乎没有意义)可能会导致您描述的那种竞争条件。
  • 实际上,您可能想阅读以下内容:stackoverflow.com/questions/39196505/…
  • 显然我是提出这个问题的人。但我认为我不应该关心使用 Flyway,而应该关心数据库设计。
  • 如果这是您关心的问题,请不要在每次启动应用程序时运行 flyway 或任何其他数据库迁移。您的应用程序将很高兴快速启动,这将在发生崩溃时提供极大的帮助,您的数据将被写入一次(每次迁移运行)并保持一致。一定要自动迁移(单个),然后启动(在 docker 上并行),但要提供一个单独的启动脚本,而不是你用来执行(重新)启动的启动脚本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
  • 2013-03-03
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 2018-11-25
相关资源
最近更新 更多