Liquibase ChangeLog 和 LogLock table 在后期创建而不会使已经执行的脚本失败
Liquibase ChangeLog and LogLock table creation on Later stage without failing already executed scripts
我有一个 微服务 运行 很久以前我们意识到 自定义 changelog
和 changeloglock
表定义不正确。见下文...
spring:
liquibase:
abc:
change-log: classpath:/liquibase/changelog.yml
database-change-log-table: CUSTOM_CHANGE_LOG
database-change-log-lock-table: CUSTOM_CHANGE_LOG_LOCK
abc
被添加到正确的路径之间,我们已经执行了几乎 18 个脚本 并且已经登录到 master表格 DATABASECHANGELOG
和 DATABASECHANGELOGLOCK
.
因此,如果我根据以下内容更正 yml 中的路径
spring:
liquibase:
change-log: classpath:/liquibase/changelog.yml
database-change-log-table: CUSTOM_CHANGE_LOG
database-change-log-lock-table: CUSTOM_CHANGE_LOG_LOCK
然后它会继续执行所有旧的18个脚本,这将导致失败。 如何解决?
此外,我不确定它是否会自动创建自定义表格,还是我需要手动创建这些表格?
如能为 both the points
提供任何帮助,我们将不胜感激。如果您需要更多详细信息,请发表评论
如果我正确理解你的问题,有两种选择:
将 preConditions
写入您现有的变更集并指定 onFail="MARK_RAN" 属性。这样,您的所有变更集都将在 preConditions
上失败,并在 CUSTOM_CHANGE_LOG
table 中标记为 运行。您的应用程序将成功启动。
指定CUSTOM_CHANGE_LOG
table并从databasechangelog
复制所有数据。
用于将数据从 table 复制到 table 的 ChangeSet 可能如下所示:
<changeSet id="foo" author="bar">
<preConditions onFail="MARK_RAN">
<tableExists tableName="databasechangelog"/>
<tableExists tableName="CUSTOM_CHANGE_LOG"/>
<sqlCheck expecterResult="0">
SELECT COUNT(*) FROM databasechangelog;
</sqlCheck>
</preConditions>
<sql>
INSERT INTO CUSTOM_CHANGE_LOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, EXECTYPE, MD5SUM, DESCRIPTION, COMMENTS, TAG, LIQUIBASE, CONTEXTS, LABELS, DEPLOYMENT_ID)
SELECT ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, EXECTYPE, MD5SUM, DESCRIPTION, COMMENTS, TAG, LIQUIBASE, CONTEXTS, LABELS, DEPLOYMENT_ID
FROM databasechangelog
</sql>
</changeSet>
这个changeSet应该是应用程序启动时最先执行的。所以你应该把这个 changeSet 放在你的 changeLog 中的所有其他 changeSets 之前。复制所有数据后,liquibase 应将所有现有的变更集视为已执行。
我会使用选项 #1,因为无论如何你的 changeSets 应该有先决条件。
此问题已解决。有两种方法可以 w/o 运行 使用任何手动脚本。但我更喜欢下面一个
我们将 不在 application.yml
中输入任何自定义 table 但会在更新日志中添加新查询.
changeset
看起来像这样
- changeSet:
id: your-id-here
author: kunal-vohra
#dbms: oracle #if you want it to run db specific then uncomment
changes:
- sqlFile:
encoding: utf8
path: ./liquibase/changes/sql-file-name.sql
而 sql-file-name.sql
看起来像
declare
begin
execute immediate 'CREATE TABLE CUSTOM_CHANGE_LOG AS SELECT * FROM DATABASECHANGELOG WHERE AUTHOR = ''kunal-vohra''';
exception when others then
if SQLCODE = -955 then null; else raise; end if;
UPDATE CUSTOM_CHANGE_LOG SET MD5SUM = null;
end;
/
上面查询中发生的事情是,如果 table 已经创建,那么它不会创建新的 table,否则它会创建。
然后它正在丢弃所有 **HASH**
。
然后在 application.yml
中提出第二个 PR 并进行更改
spring:
liquibase:
change-log: classpath:/liquibase/changelog.yml
database-change-log-table: CUSTOM_CHANGE_LOG
database-change-log-lock-table: CUSTOM_CHANGE_LOG_LOCK
我们在这里的主要好处是我们不必 运行 在 PROD 上手动进行任何操作。
如果您想在一个 PR 中执行上述操作 另一种方法是 只需将 changeset
移动到文件顶部而不是下面。
我有一个 微服务 运行 很久以前我们意识到 自定义 changelog
和 changeloglock
表定义不正确。见下文...
spring:
liquibase:
abc:
change-log: classpath:/liquibase/changelog.yml
database-change-log-table: CUSTOM_CHANGE_LOG
database-change-log-lock-table: CUSTOM_CHANGE_LOG_LOCK
abc
被添加到正确的路径之间,我们已经执行了几乎 18 个脚本 并且已经登录到 master表格 DATABASECHANGELOG
和 DATABASECHANGELOGLOCK
.
因此,如果我根据以下内容更正 yml 中的路径
spring:
liquibase:
change-log: classpath:/liquibase/changelog.yml
database-change-log-table: CUSTOM_CHANGE_LOG
database-change-log-lock-table: CUSTOM_CHANGE_LOG_LOCK
然后它会继续执行所有旧的18个脚本,这将导致失败。 如何解决?
此外,我不确定它是否会自动创建自定义表格,还是我需要手动创建这些表格?
如能为 both the points
提供任何帮助,我们将不胜感激。如果您需要更多详细信息,请发表评论
如果我正确理解你的问题,有两种选择:
将
preConditions
写入您现有的变更集并指定 onFail="MARK_RAN" 属性。这样,您的所有变更集都将在preConditions
上失败,并在CUSTOM_CHANGE_LOG
table 中标记为 运行。您的应用程序将成功启动。指定
CUSTOM_CHANGE_LOG
table并从databasechangelog
复制所有数据。
用于将数据从 table 复制到 table 的 ChangeSet 可能如下所示:
<changeSet id="foo" author="bar">
<preConditions onFail="MARK_RAN">
<tableExists tableName="databasechangelog"/>
<tableExists tableName="CUSTOM_CHANGE_LOG"/>
<sqlCheck expecterResult="0">
SELECT COUNT(*) FROM databasechangelog;
</sqlCheck>
</preConditions>
<sql>
INSERT INTO CUSTOM_CHANGE_LOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, EXECTYPE, MD5SUM, DESCRIPTION, COMMENTS, TAG, LIQUIBASE, CONTEXTS, LABELS, DEPLOYMENT_ID)
SELECT ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, EXECTYPE, MD5SUM, DESCRIPTION, COMMENTS, TAG, LIQUIBASE, CONTEXTS, LABELS, DEPLOYMENT_ID
FROM databasechangelog
</sql>
</changeSet>
这个changeSet应该是应用程序启动时最先执行的。所以你应该把这个 changeSet 放在你的 changeLog 中的所有其他 changeSets 之前。复制所有数据后,liquibase 应将所有现有的变更集视为已执行。
我会使用选项 #1,因为无论如何你的 changeSets 应该有先决条件。
此问题已解决。有两种方法可以 w/o 运行 使用任何手动脚本。但我更喜欢下面一个
我们将 不在 application.yml
中输入任何自定义 table 但会在更新日志中添加新查询.
changeset
看起来像这样
- changeSet:
id: your-id-here
author: kunal-vohra
#dbms: oracle #if you want it to run db specific then uncomment
changes:
- sqlFile:
encoding: utf8
path: ./liquibase/changes/sql-file-name.sql
而 sql-file-name.sql
看起来像
declare
begin
execute immediate 'CREATE TABLE CUSTOM_CHANGE_LOG AS SELECT * FROM DATABASECHANGELOG WHERE AUTHOR = ''kunal-vohra''';
exception when others then
if SQLCODE = -955 then null; else raise; end if;
UPDATE CUSTOM_CHANGE_LOG SET MD5SUM = null;
end;
/
上面查询中发生的事情是,如果 table 已经创建,那么它不会创建新的 table,否则它会创建。
然后它正在丢弃所有 **HASH**
。
然后在 application.yml
spring:
liquibase:
change-log: classpath:/liquibase/changelog.yml
database-change-log-table: CUSTOM_CHANGE_LOG
database-change-log-lock-table: CUSTOM_CHANGE_LOG_LOCK
我们在这里的主要好处是我们不必 运行 在 PROD 上手动进行任何操作。
如果您想在一个 PR 中执行上述操作 另一种方法是 只需将 changeset
移动到文件顶部而不是下面。