alex.collins Asked: 2013-01-04 02:38:04 +0800 CST2013-01-04 02:38:04 +0800 CST 2013-01-04 02:38:04 +0800 CST 在更新和应用程序的 RPM 时,是否有推荐的方法来更新数据库架构? 772 我有一个非常标准的服务器布局: 2 在 Redhat 上运行 Tomcat 的应用程序服务器。 2 在 Redhat 上运行 Postgres 的数据库服务器。一个数据库是主数据库并复制到从属数据库。 我想在更新网络应用程序时自动升级方案。Web 应用程序是使用 RPM 部署的。我不知道是否有推荐的方法。 postgresql redhat 2 个回答 Voted Best Answer Craig Ringer 2013-01-04T02:56:20+08:002013-01-04T02:56:20+08:00 除非您使用的工具具有对数据库模式迁移的内置支持(如 ActiveRecord/Rails 所做的,尽管相当不安全) - 您需要在您的应用程序中自己完成。 通常的技术是在您的数据库中创建一个表,其中包含有关模式和应用程序的元数据。您可以将其构建为键/值形式,或者作为具有多个列的单行;没关系。无论哪种方式,此表都应存储模式版本。 当您在应用程序启动时连接时,在对数据库执行任何其他操作之前,您应该查询元数据表以获取架构版本。如果它低于应用程序中的当前版本,您的应用程序应该将架构更改脚本从旧版本应用到新版本。为此,我使用@Singleton @Startup了 EJB3,并使用类加载器从嵌入在应用程序 jar 中的属性文件中读取模式更改脚本;您可能正在使用 Spring 或具有类似功能的类似框架。 因为您有两个应用程序服务器,所以您可能必须LOCK TABLE your_database_metadata_table在开始应用更改之前确保两个服务器不会尝试应用相同的数据库迁移脚本。 PostgreSQL 中的 DDL 更改比其他一些数据库更容易,因为它支持事务性 DDL。您可以BEGIN进行事务,一次性应用所有数据库更改 - DDL、元数据表更新等 - 和COMMIT. 您不会因为应用了一半的架构更改而着陆。这仅在架构更改不会花费太长时间或者您可以承受延迟时才可行。如果您正在ALTER处理 1 亿行表的数据类型,那么您不希望在单个大事务中执行此操作,除非其他一切都可以等待。 如果您使用内置的流式复制,则会自动处理复制;它没有区分 DDL 和 DML,就复制系统而言,它们都只是数据库更改。 如果您使用的是另一个复制引擎,如 Slony-I 或 Bucardo,那么这取决于复制引擎如何处理模式更改。这是特定于引擎的,因此您需要查看复制引擎的文档。(在 9.3 事件触发器、逻辑复制和命令解析支持被添加到 PostgreSQL 核心之后,当前与 3rd 方复制和 DDL 更改的混乱应该会显着改善。其中一些看起来会滑到 9.4。) 现在,如果您想在不中断应用程序的情况下无中断地更改 DDL,那将是另一个层面的乐趣。 Basil Bourque 2019-10-06T16:23:40+08:002019-10-06T16:23:40+08:00 克雷格·林格的答案比这个更重要。但我想解释一下工具如何帮助你解决这个问题。 数据库迁移工具 我们现在有数据库迁移工具来帮助您更新: 数据库结构 添加/删除/修改模式、表、列、索引等。 又名DDL 数据内容 添加/删除/修改行 添加查找表或数据库重构需要 又名DML …根据您的应用程序发展的需要。 您可以选择多种工具,包括LiquiBase和Flyway。 飞路 我在自己的工作中成功地使用了 Flyway。所以下面是一个简短的描述,尽管我敦促你做一些研究,看看哪些工具适合你的需求和风格。 Flyway 是用 Java 构建的,但也可以在非 Java 商店中使用。所有 Flyway 命令都包含在命令行可执行文件中,因此您可以在控制台或脚本中使用它们。如果您是 Java 公司,您可以选择使用对象从 Java 中调用命令。对于特殊需求,您可以选择编写 Java 类来完成一些在直接 SQL 或 SQL 超集( PL/pgSQL等)数据库编程中可能无法实现的繁重工作。 Flyway 会自动将表安装到您的数据库中,以存储自己的元数据。Flyway 在指定文件夹中查找您编写的 SQL 脚本。Flyway 规定的特定命名约定控制执行顺序。每次运行 Flyway 时,该工具都会检查您的所有脚本,在元数据中查找每个脚本以查看它是否已在此特定数据库中运行。如果尚未运行,Flyway 将运行它并记录结果。如果脚本之前运行过,Flyway 会使用校验和来确保脚本未被编辑,否则会标记潜在问题。 使用 Flyway 等数据库迁移工具最好从项目一开始就完成。但是您可以将 Flyway 添加到现有数据库中,请参阅文档。或者考虑使用为 Flyway 组织的一组 SQL 脚本重新创建数据库,如果这对您的情况可行的话。我喜欢完全通过 Flyway 从头开始重新创建新数据库的能力——方便开发和测试。 说到测试,您可以轻松地添加或删除 SQL 脚本(以及可选的 Java 类)来完成测试工作。此类目的可能包括加载一组已知数据。或者您可能想要设置某些条件来重新创建错误场景。 Flyway 非常易于使用,因为它具有智能的默认设置和简单的设计。但是您也可以根据特殊需要自定义其行为,覆盖默认值。 Flyway 与 Postgres 配合得很好,因为它通过JDBC运行,无论是它自己捆绑的JDBC 驱动程序副本,还是通过您的驱动程序。对于非 Java 商店,JDBC 驱动程序的使用对您来说是透明的。实际上很少使用 JDBC 的功能,因为 Flyway 只是将您的 SQL 脚本传递给数据库。除了创建和更新自己的元数据表之外,Flyway 并没有真正触及您的数据库——您是在自己操作数据库,通过您编写的那些脚本。打个比方,将 Flyway 视为邮政承运人,而您是信件的作者。 Flyway 是免费增值的,具有开源且免费的社区版。此版本具有可能 Flyway 如此受欢迎的所有经典功能。这些功能可能就是您所需要的。额外的特殊功能和技术支持在后续版本中提供,但需付费。请参阅此功能网格。Flyway 项目和公司最近被Redgate Software收购,Flyway 的创造者Axel Fontaine也加入了。
除非您使用的工具具有对数据库模式迁移的内置支持(如 ActiveRecord/Rails 所做的,尽管相当不安全) - 您需要在您的应用程序中自己完成。
通常的技术是在您的数据库中创建一个表,其中包含有关模式和应用程序的元数据。您可以将其构建为键/值形式,或者作为具有多个列的单行;没关系。无论哪种方式,此表都应存储模式版本。
当您在应用程序启动时连接时,在对数据库执行任何其他操作之前,您应该查询元数据表以获取架构版本。如果它低于应用程序中的当前版本,您的应用程序应该将架构更改脚本从旧版本应用到新版本。为此,我使用
@Singleton @Startup
了 EJB3,并使用类加载器从嵌入在应用程序 jar 中的属性文件中读取模式更改脚本;您可能正在使用 Spring 或具有类似功能的类似框架。因为您有两个应用程序服务器,所以您可能必须
LOCK TABLE your_database_metadata_table
在开始应用更改之前确保两个服务器不会尝试应用相同的数据库迁移脚本。PostgreSQL 中的 DDL 更改比其他一些数据库更容易,因为它支持事务性 DDL。您可以
BEGIN
进行事务,一次性应用所有数据库更改 - DDL、元数据表更新等 - 和COMMIT
. 您不会因为应用了一半的架构更改而着陆。这仅在架构更改不会花费太长时间或者您可以承受延迟时才可行。如果您正在ALTER
处理 1 亿行表的数据类型,那么您不希望在单个大事务中执行此操作,除非其他一切都可以等待。如果您使用内置的流式复制,则会自动处理复制;它没有区分 DDL 和 DML,就复制系统而言,它们都只是数据库更改。
如果您使用的是另一个复制引擎,如 Slony-I 或 Bucardo,那么这取决于复制引擎如何处理模式更改。这是特定于引擎的,因此您需要查看复制引擎的文档。(在 9.3 事件触发器、逻辑复制和命令解析支持被添加到 PostgreSQL 核心之后,当前与 3rd 方复制和 DDL 更改的混乱应该会显着改善。其中一些看起来会滑到 9.4。)
现在,如果您想在不中断应用程序的情况下无中断地更改 DDL,那将是另一个层面的乐趣。
克雷格·林格的答案比这个更重要。但我想解释一下工具如何帮助你解决这个问题。
数据库迁移工具
我们现在有数据库迁移工具来帮助您更新:
…根据您的应用程序发展的需要。
您可以选择多种工具,包括LiquiBase和Flyway。
飞路
我在自己的工作中成功地使用了 Flyway。所以下面是一个简短的描述,尽管我敦促你做一些研究,看看哪些工具适合你的需求和风格。
Flyway 是用 Java 构建的,但也可以在非 Java 商店中使用。所有 Flyway 命令都包含在命令行可执行文件中,因此您可以在控制台或脚本中使用它们。如果您是 Java 公司,您可以选择使用对象从 Java 中调用命令。对于特殊需求,您可以选择编写 Java 类来完成一些在直接 SQL 或 SQL 超集( PL/pgSQL等)数据库编程中可能无法实现的繁重工作。
Flyway 会自动将表安装到您的数据库中,以存储自己的元数据。Flyway 在指定文件夹中查找您编写的 SQL 脚本。Flyway 规定的特定命名约定控制执行顺序。每次运行 Flyway 时,该工具都会检查您的所有脚本,在元数据中查找每个脚本以查看它是否已在此特定数据库中运行。如果尚未运行,Flyway 将运行它并记录结果。如果脚本之前运行过,Flyway 会使用校验和来确保脚本未被编辑,否则会标记潜在问题。
使用 Flyway 等数据库迁移工具最好从项目一开始就完成。但是您可以将 Flyway 添加到现有数据库中,请参阅文档。或者考虑使用为 Flyway 组织的一组 SQL 脚本重新创建数据库,如果这对您的情况可行的话。我喜欢完全通过 Flyway 从头开始重新创建新数据库的能力——方便开发和测试。
说到测试,您可以轻松地添加或删除 SQL 脚本(以及可选的 Java 类)来完成测试工作。此类目的可能包括加载一组已知数据。或者您可能想要设置某些条件来重新创建错误场景。
Flyway 非常易于使用,因为它具有智能的默认设置和简单的设计。但是您也可以根据特殊需要自定义其行为,覆盖默认值。
Flyway 与 Postgres 配合得很好,因为它通过JDBC运行,无论是它自己捆绑的JDBC 驱动程序副本,还是通过您的驱动程序。对于非 Java 商店,JDBC 驱动程序的使用对您来说是透明的。实际上很少使用 JDBC 的功能,因为 Flyway 只是将您的 SQL 脚本传递给数据库。除了创建和更新自己的元数据表之外,Flyway 并没有真正触及您的数据库——您是在自己操作数据库,通过您编写的那些脚本。打个比方,将 Flyway 视为邮政承运人,而您是信件的作者。
Flyway 是免费增值的,具有开源且免费的社区版。此版本具有可能 Flyway 如此受欢迎的所有经典功能。这些功能可能就是您所需要的。额外的特殊功能和技术支持在后续版本中提供,但需付费。请参阅此功能网格。Flyway 项目和公司最近被Redgate Software收购,Flyway 的创造者Axel Fontaine也加入了。