一文详解Liquibase如何智能化数据库脚本部署

您能否还在手动对数据库口头各种脚本?您能否还在糜费期间去验证数据库脚本的正确性?您能否还须要将脚本兼并到某个文件中,以便在每个环境中口头?在面对部署错误时,您能否须要破费数小时去检查数据库的更改,以定位要素?

如今,大少数组织都曾经在其运行程序中实施了DevOps的CI/CD流程。不过,其数据库的智能化变革仿佛尚未跟上时代。为此,我将向您引见一种能够成功智能化脚本部署的数据库产品--Liquibase。

Liquibase的基本特点

上方,我将向您展现如何经常使用Liquibase和Git在Pretius上,智能化数据库的更改环节。

什么是Liquibase?

Liquibase(简称LB)是一个用Java编写的开源工具。它以用户相熟的格局定义了数据库接口,并能够智能生成特定于数据库的SQL。例如,它将数据库的更改(每一次性更改可称为一个更改集)放入被称为changelog的文件中启动治理。通常,Liquibase在数据库架构中会智能创立两张表:

我将在上方示例中,基于SQL编写变卦集,以成功对Oracle数据库的智能化更改环节。

从装置Liquibase开局

请经过链接,决定“仅文件(Just thefiles)”的方式,下载Liquibase的最新版本。在本文中,我将经常使用版本:4.3.0 build 09.02.2021。

在将其zip文件夹解紧缩后,您必定将新的门路变量(New Path SystemVariable)设置为计算机上的liquibase-version#bin文件夹。同时,为了使Liquibase反常上班,您还必定装置Java。

经过在CLI工具(在此,我经常使用的是Visual Studio Code)输入:Liquibase—version,您将能看到:

假设您在文件中经常使用的是UTF8编码,那么请务必在liquibase.bat文件中参与一行:IF NOT DEFINED JAVA_OPTS setJAVA_OPTS=-Dfile.encoding=UTF–8。

性能名目和Liquibase

上方,让咱们来组织各个文件(在本例中,我的GIT存储库放在文件夹HR中)。在各个文件夹中,咱们可以在名目开发的环节中创立不同的文件。假设您有其余类型的对象(如“创立或交流”类型),那么只有要用它们创立“同义(synonyms)”文件夹即可。

Liquibase中的文件组织

#liquibase.hub.mode=

降级了的Liquibase文件夹结构

如今,咱们创立一个update.xml文件,并将它放入带有OJDBC文件的、新的 hr/Liquibase文件夹中:

经常使用 Oracle Wallet(可选)

假设您的Oracle数据库托管在Oracle自治数据库上,那么就须要经常使用Wallet,经过Liquibase去衔接它。为此,请下载Wallet并记住其明码。

请将您的WALLET_NAME.ZIP解压到之前创立的HR/Liquibase文件夹中,并编辑HR/liquibase/wallet_name/ojdbc.properties文件:

更改ojdsb.properties

修正后的文件如上图所示。在javax.net.ssl.trustStorePassword和javax.net.ssl.keyStorePassword行,你可以设置ATPWallet的明码。

在liquibase_local.properties文件中,请编辑URL一行,并设置衔接的称号(即,来自Wallet/tnsnames.ora,以及去往Wallet的门路):

当然,请审核您的sqlnet.ora文件,确保其“SSL_SERVER_DN_MATCH=yes”,且无需扭转其余中央。

将Liquibase与数据库衔接

假设一切设置正确,咱们便可以顺利衔接上DEV数据库。让咱们从HR文件夹(Liquibase的属性文件位置)处启动CLI,并输入:

VSCode终端中的updateSQL命令

其中:

几秒钟后,LB将会生成output_file.sql:

生成的output_file.sql

如前所述,假设您在数据库中运转该脚本,它将创立两个表:DATABASECHANGELOG和DATABASECHANGELOGLOCK。上方,让咱们经过Liquibase—defaultsFile=liquibase_dev.propertiesupdate,来创立这些表。其中的update命令是对数据库口头SQL语句。成功后,您将看到如下结构:

咱们须要创立一个changelog文件,并指向蕴含对象的文件夹。在此,我创立了如下HR/master.xml文件:

它指向对象文件夹、及其一切内容。为了将主changelog文件HR/liquibaseupdate.xml设置为指向master.xml文件的门路,您只有添一行:

在update.xml中的include file="./master.xml"

由于Liquibase一直会从Liquibase_dev.properties文件和update.xml文件处运转,因此咱们须要让它能够“看到”一切的文件。

跟踪DML和DDL数据库的更改

咱们须要为DML和DDL类型的更改创立一个独自的changelog文件,并将更改集写入其中。为此,咱们只有创立一个changelog.sql文件,并输入如下内容,以将其标志为LiquibaseSQL文件:

将changelog.sql标志为LiquibaseSQL文件

咱们经过在master.xml文件中参与如下内容,以指向新的changelog:

指向新的changelog

指向changelog或文件夹的顺序是十分关键的。它须要告知Liquibase在运转SQL时的顺序。咱们最好先运转changelog(其中蕴含了“createtable(...)”),而后再运转经常使用该表的编译包。

上方,让咱们在变卦集中创立第一个名目表:

创立第一个名目表

为了预览到数据库有哪些更改,咱们让LB生成对应的SQL文件。

由Liquibase生成SQL文件

您或许留意到了,LB经过设置LOCKED =1,来锁定DATABASECHANGELOGLOCK表。也就是说,当您将脚本运转到DB时,列LOCKED被设置为1。而当另一个用户同时运转LB时,Liquibase将为此期待,直到锁定被开放,再创立一个SHOES表,将日志的更改拔出到DATABASECHANGELOG中,并从DATABASECHANGELOGLOCK表中监禁掉已有的锁。

假设一切反常,如下脚本会被口头到数据库中:

接着,表SHOES会被创立进去。

咱们也可以查问到谁、为何、以及何时创立了这张表。

跟踪包、视图等其余更改

咱们也可以如法创立其余脚本。在此,我经过2个独自的文件,创立了一个SHOES_PKG包。每个文件都是带有附加参数的惟一变卦集,并被标志为Liquibase格局的SQL文件。

SHOES_BODY和SHOES_SPEC SQL文件

其中:

因此,LB在对数据库启动updateSQL操作时,就会去编译包的规范(package spec)、以及包的主体(packagebody)。一旦咱们在数据库中经过update命令编译这些包,它们都会被记载上去。

经过检查MD5SUM的列值可知,它是变卦集的最后一次性校验和。也就是说,运转了updateSQL后,一切前期被“挂起”的更改都被口头,而且除了锁定LB表外,LB不会在SQL中生成任何内容。

运用updateSQL审核output_local.sql

如今,让咱们扭转SHOES_PKG自身,并保管该文件。

降级SHOES_PKG自身

那么该文件的校验和会出现变动,LB将再次编译这个包,并运转降级。

Liquidbase中的降级

数据库中的降级

Liquibase将再次编译这个包,并经常使用DATABASECHANGELOG表中的实践DATEEXECUTED和新的MD5SUM等变卦集,去降级相应的行。

如何在现有软件名目中装置Liquibase?

只管咱们好几种方法可以让Liquibase为现有的数据库成功智能化,然而我在此只向您展现最适用的两种。您可以从中决定最适宜实践需求的一种。

当现有的名目中有很多对象时

咱们经过在名目的存储库中性能Liquibase,并保管一切文件的基础上,在master.xml文件中参与指向它们的门路。详细而言,在实施Liquibase之前,我创立了2个环节和2个触发器:

现有的P_ADD_JOB_HISTORY.sql文件

您并不须要将“changeset”或“–Liquibaseformatted sql”参与到文件中。

降级后master.xml中的文件门路

我在自己的master.xml中参与了一个指向PROCEDURES文件夹的门路。

上方,让咱们运转LiquibaseupdateSQL,并检查Liquibase会口头什么样的SQL:

初次尝试降级SQL

既然咱们的数据库中曾经有了这些环节和触发器,咱们就须要经过ChangelogSync和ChangelogSyncSQL命令,防止重复创立。让咱们运转ChangelogSyncSQL,并检查其结果。

输入的SQL文件为:

可见,SQL文件只拔出了一个DATABASECHANGELOG表。它会告知Liquibase这些对象曾经创立好了,不须要再次运转。如今,咱们便可以将其拔出到Oracle数据库中了:

此时,在DATABASECHANGELOG表中会有4个新的变卦集:

您兴许会问,这些奇异的“raw”ID是什么?为什么作者又被称为“includeAll”呢?这是由于咱们采取了最繁难、最快捷的方式,将现有的名目迁徙到了Liquibase处,而这些变卦集是被智能创立的。

当然,您也可以启动一些更改。例如,在P_ADD_JOB_HISTORY中,只有参与一个changeset,就像您在创立新数据库对象时常做的那样。

更改P_ADD_JOB_HISTORY

而后运转Liquibase的降级命令:

如今,Changeset就带有了适宜的作者、ID等消息。

在上方的示例中,我向您展现了参与现有对象(可创立或交流)的简双方法,且无需手动创立变卦集。我以为这是将Liquibase装置到领有数百个对象的、现有数据库中的最佳方式。不过,当触及到库里有不能被交流的对象(如表格)时,咱们须要经常使用另一种方式。

当现有名目中没有很多对象时

创立或交流的对象

正如前面所形容过的,请参与对象,并在master.xml文件中记下文件夹的门路。接着请运转ChangelogSync,并让Liquibase智能创立raw/includeAll/filename的变卦集。

由Liquibase生成的变卦集

当然,您也可以驳回更好的方法,为每个文件创立一个变卦集,如下图所示:

只管这会须要更多的上班,然而您可以在日志中取得更片面的消息:

针对无法创立或交流的对象,您雷同有两种方法:

在此,咱们着重探讨第二种方式。由于在实施Liquibase之前我已创立好了EMPLOYEES和JOBS两张表,因此我会在新的文件夹HR/scripts_before_Liquibase中,创立changelog_ddl.sql和changelog_constraints.sql两个changelog文件。此外,我也创立了另一个scripts_before_liquibase.xml文件,并将其指向这两个changelog。其中的“includefile”经过优先级的方式,告知Liquibase运转脚本的顺序,即:首先创立表,而后创立束缚和索引。

新的scripts_before_liquibase.xml文件

这两个文件能够繁难您在表中创立ref_constraint时,防止发生抵触。如下图所示,请记住在master.xml文件中,将门路参与到新创立的XML文件(即HR/script_before_liquibase/scripts_before_liquibase.xml)中。

上方是为各种表和束缚创立的变卦集。

在参与了一切的变卦集之后,咱们将它们标志为已口头的形态。

让咱们运转ChangelogSyncSQL来启动预览,并让ChangelogSync对数据库口头SQL。

运转ChangeSyncSQL和ChangelogSync

下图展现了ChangelogSync命令口头后,降级了的数据库。至此,咱们已功败垂成,您也可以决定自己青睐的方式,经过Liquibase来成功数据库的智能化。

小结

您可能还会对下面的文章感兴趣: