<返回更多

一文详解Liquibase如何自动化数据库脚本部署

2021-12-22  51CTO  
加入收藏
一文详解Liquibase如何自动化数据库脚本部署

 

作者丨Rafal Grzegorczyk

译者丨陈骏

策划丨孙淑娟

【51CTO.com原创稿件】您是否还在手动对数据库执行各种脚本?您是否还在浪费时间去验证数据库脚本的正确性?您是否还需要将脚本合并到某个文件中,以便在每个环境中执行?在面对部署错误时,您是否需要花费数小时去查看数据库的更改,以定位原因?

如今,大多数组织都已经在其应用程序中实施了DevOps的CI/CD流程。不过,其数据库的自动化改造似乎尚未跟上时代。为此,我将向您介绍一种能够实现自动化脚本部署的数据库产品--Liquibase。

Liquibase的基本特点

一文详解Liquibase如何自动化数据库脚本部署

 

下面,我将向您展示如何使用Liquibase和Git在Pretius上,自动化数据库的更改过程。

什么是Liquibase?

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

我将在下面示例中,基于SQL编写变更集,以实现对Oracle数据库的自动化更改过程。

从安装Liquibase开始

请通过链接
https://www.liquibase.org/download,选择“仅文件(Just the files)”的方式,下载Liquibase的最新版本。在本文中,我将使用版本:4.3.0 build 09.02.2021。

在将其zip文件夹解压缩后,您必须将新的路径变量(New Path System Variable)设置为计算机上的liquibase-version#bin文件夹。同时,为了使Liquibase正常工作,您还必须安装Java。

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

一文详解Liquibase如何自动化数据库脚本部署

 

如果您在文件中使用的是UTF8编码,那么请务必在liquibase.bat文件中添加一行:IF NOT DEFINED JAVA_OPTS set JAVA_OPTS=-Dfile.encoding=UTF–8。

一文详解Liquibase如何自动化数据库脚本部署

 

配置项目和Liquibase

下面,让我们来组织各个文件(在本例中,我的GIT存储库放在文件夹HR中)。在各个文件夹中,我们可以在项目开发的过程中创建不同的文件。如果您有其他类型的对象(如“创建或替换”类型),那么只需要用它们创建“同义(synonyms)”文件夹即可。

一文详解Liquibase如何自动化数据库脚本部署

 

Liquibase中的文件组织

#path to our master changelog file changeLogFile:Liquibase/update.xml #dbhost and credentials url:  jdbc:oracle:thin:@127.0.0.1:1521/XEPDB1 username: HR password: XXXXXX #OJDBC driver localization classpath:Liquibase/ojdbc8.jar #schema, whereLiquibasewill store it’s DATABASECHANGELOG and DATABASECHANGELOGLOCK table(if other than HR, remember to add grants to HR!) liquibaseSchemaName: HR #default  SQL file name generated byLiquibase outputFile=output_local.sql #debug mode loglevel=SEVERE #extra option fromLiquibase, we don’t need it for now. liquibase.hub.mode=off 
一文详解Liquibase如何自动化数据库脚本部署

 

更新了的Liquibase文件夹结构

现在,我们创建一个update.xml文件,并将它放入带有OJDBC文件的、新的 hr/Liquibase文件夹中:

<?xml version="1.0″ encoding="UTF-8″?><databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"></databaseChangeLog> 

使用 Oracle Wallet(可选)

如果您的Oracle数据库托管在Oracle自治数据库上,那么就需要使用Wallet,通过Liquibase去连接它。为此,请下载Wallet并记住其密码。

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

一文详解Liquibase如何自动化数据库脚本部署

 

更改ojdsb.properties

修改后的文件如上图所示。在
javax.NET.ssl.trustStorePassword和javax.net.ssl.keyStorePassword行,你可以设置ATP Wallet的密码。


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

url: jdbc:oracle:thin:@rgatp28_high?TNS_ADMIN=liquibase/Wallet_RGATP28 

当然,请检查您的sqlnet.ora文件,确保其“SSL_SERVER_DN_MATCH=yes”,且无需改变其他地方。

将Liquibase与数据库连接

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

Liquibase—defaultsFile=liquibase_dev.properties updateSQL 
一文详解Liquibase如何自动化数据库脚本部署

 

VSCode终端中的updateSQL命令

其中:

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

一文详解Liquibase如何自动化数据库脚本部署

 

生成的output_file.sql

如前所述,如果您在数据库中运行该脚本,它将创建两个表:DATABASECHANGELOG和DATABASECHANGELOGLOCK。下面,让我们通过Liquibase—defaultsFile=liquibase_dev.properties update,来创建这些表。其中的update命令是对数据库执行SQL语句。完成后,您将看到如下结构:

一文详解Liquibase如何自动化数据库脚本部署

 

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

<?xml version="1.0″ encoding="UTF-8″?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> <includeAll path="triggers" relativeToChangelogFile="true"/> <includeAll path="views" relativeToChangelogFile="true"/> <includeAll path="types" relativeToChangelogFile="true"/> <includeAll path="package_spec" relativeToChangelogFile="true"/> <includeAll path="package_bodies" relativeToChangelogFile="true"/> </databaseChangeLog> 

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

<include file="./master.xml"/> 
一文详解Liquibase如何自动化数据库脚本部署

 

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

由于Liquibase始终会从Liquibase_dev.properties文件和update.xml文件处运行,因此我们需要让它能够“看到”所有的文件。

跟踪DML和DDL数据库的更改

我们需要为DML和DDL类型的更改创建一个单独的changelog文件,并将更改集写入其中。为此,我们只需创建一个changelog.sql文件,并输入如下内容,以将其标记为LiquibaseSQL文件:

—Liquibaseformatted sql 
一文详解Liquibase如何自动化数据库脚本部署

 

将changelog.sql标记为LiquibaseSQL文件

我们通过在master.xml文件中添加如下内容,以指向新的changelog:

一文详解Liquibase如何自动化数据库脚本部署

 

指向新的changelog

指向changelog或文件夹的顺序是非常重要的。它需要告知Liquibase在运行SQL时的顺序。我们最好先运行changelog(其中包含了“create table(...)”),然后再运行使用该表的编译包。

下面,让我们在变更集中创建第一个项目表:

—changeset AUTHOR:CHANGESET_NAME —comment OPTIONAL COMMENT YOUR DDL 
一文详解Liquibase如何自动化数据库脚本部署

 

创建第一个项目表

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

Liquibase—defaultsFile=liquibase_dev.properties updateSQL 
一文详解Liquibase如何自动化数据库脚本部署

 

由Liquibase生成SQL文件

您可能注意到了,LB通过设置LOCKED = 1,来锁定DATABASECHANGELOGLOCK表。也就是说,当您将脚本运行到DB时,列LOCKED被设置为1。而当另一个用户同时运行LB时,Liquibase将为此等待,直到锁定被放开,再创建一个SHOES表,将日志的更改插入到DATABASECHANGELOG中,并从DATABASECHANGELOGLOCK表中释放掉已有的锁。

如果一切正常,如下脚本会被执行到数据库中:

Liquibase—defaultsFile=liquibase_dev.properties update 

接着,表SHOES会被创建出来。

一文详解Liquibase如何自动化数据库脚本部署

 

我们也可以查询到谁、为何、以及何时创建了这张表。

一文详解Liquibase如何自动化数据库脚本部署

 

跟踪包、视图等其他更改

我们也可以如法创建其他脚本。在此,我通过2个单独的文件,创建了一个SHOES_PKG包。每个文件都是带有附加参数的唯一变更集,并被标记为Liquibase格式的SQL文件。

一文详解Liquibase如何自动化数据库脚本部署

 

SHOES_BODY和SHOES_SPEC SQL文件

其中:

因此,LB在对数据库进行updateSQL操作时,就会去编译包的规范(package spec)、以及包的主体(package body)。一旦我们在数据库中通过update命令编译这些包,它们都会被记录下来。

一文详解Liquibase如何自动化数据库脚本部署

 

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

一文详解Liquibase如何自动化数据库脚本部署

 

运用updateSQL检查output_local.sql

现在,让我们改变SHOES_PKG本身,并保存该文件。

一文详解Liquibase如何自动化数据库脚本部署

 

更新SHOES_PKG本身

那么该文件的校验和会发生变化,LB将再次编译这个包,并运行更新。

一文详解Liquibase如何自动化数据库脚本部署

 

Liquidbase中的更新

一文详解Liquibase如何自动化数据库脚本部署

 

数据库中的更新

Liquibase将再次编译这个包,并使用DATABASECHANGELOG表中的实际DATEEXECUTED和新的MD5SUM等变更集,去更新相应的行。

如何在现有软件项目中安装Liquibase?

虽然我们好几种方法可以让Liquibase为现有的数据库实现自动化,但是我在此只向您展示最实用的两种。您可以从中选择最适合实际需求的一种。

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

我们通过在项目的存储库中配置Liquibase,并保留所有文件的基础上,在master.xml文件中添加指向它们的路径。具体而言,在实施Liquibase之前,我创建了2个过程和2个触发器:

P_ADD_JOB_HISTORY P_SECURE_DML TRG_SECURE_EMPLOYEES TRG_UPDATE_JOB_HISTORY 
一文详解Liquibase如何自动化数据库脚本部署

 

现有的P_ADD_JOB_HISTORY.sql文件

您并不需要将“changeset”或“–Liquibaseformatted sql”添加到文件中。

一文详解Liquibase如何自动化数据库脚本部署

 

更新后master.xml中的文件路径

我在自己的master.xml中添加了一个指向PROCEDURES文件夹的路径。

下面,让我们运行LiquibaseupdateSQL,并查看Liquibase会执行什么样的SQL:

Liquibase—defaultsFile=liquibase_dev.properties updateSQL 
一文详解Liquibase如何自动化数据库脚本部署

 

首次尝试更新SQL

既然我们的数据库中已经有了这些过程和触发器,我们就需要通过ChangelogSync和ChangelogSyncSQL命令,避免重复创建。让我们运行ChangelogSyncSQL,并查看其结果。

Liquibase—defaultsFile=liquibase_dev.properties ChangelogSyncSQL 

输出的SQL文件为:

一文详解Liquibase如何自动化数据库脚本部署

 

可见,SQL文件只插入了一个DATABASECHANGELOG表。它会告知Liquibase这些对象已经创建好了,不需要再次运行。现在,我们便可以将其插入到Oracle数据库中了:

Liquibase—defaultsFile=liquibase_dev.properties ChangelogSync 

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

一文详解Liquibase如何自动化数据库脚本部署

 

您也许会问,这些奇怪的“raw”ID 是什么?为什么作者又被称为“includeAll”呢?这是因为我们采取了最简单、最快捷的方式,将现有的项目迁移到了Liquibase处,而这些变更集是被自动创建的。

当然,您也可以进行一些更改。例如,在P_ADD_JOB_HISTORY中,只需添加一个changeset,就像您在创建新数据库对象时常做的那样。

一文详解Liquibase如何自动化数据库脚本部署

 

更改P_ADD_JOB_HISTORY

然后运行Liquibase的更新命令:

一文详解Liquibase如何自动化数据库脚本部署

 

现在,Changeset就带有了合适的作者、ID等信息。

在上面的示例中,我向您展示了添加现有对象(可创建或替换)的简单方法,且无需手动创建变更集。我认为这是将Liquibase安装到拥有数百个对象的、现有数据库中的最佳方式。不过,当涉及到库里有不能被替换的对象(如表格)时,我们需要使用另一种方式。

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

创建或替换的对象

正如前面所描述过的,请添加对象,并在master.xml文件中记下文件夹的路径。接着请运行ChangelogSync,并让Liquibase自动创建raw/includeAll/filename的变更集。

一文详解Liquibase如何自动化数据库脚本部署

 

由Liquibase生成的变更集

当然,您也可以采用更好的方法,为每个文件创建一个变更集,如下图所示:

一文详解Liquibase如何自动化数据库脚本部署

 

虽然这会需要更多的工作,但是您可以在日志中获得更全面的信息:

一文详解Liquibase如何自动化数据库脚本部署

 

针对无法创建或替换的对象,您同样有两种方法:

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

一文详解Liquibase如何自动化数据库脚本部署

 

新的scripts_before_liquibase.xml文件

这两个文件能够方便您在表中创建ref_constraint时,避免产生冲突。如下图所示,请记住在master.xml文件中,将路径添加到新创建的XML文件(即
HR/script_before_liquibase/scripts_before_liquibase.xml)中。

一文详解Liquibase如何自动化数据库脚本部署

 

下面是为各种表和约束创建的变更集。

一文详解Liquibase如何自动化数据库脚本部署

 

在添加了所有的变更集之后,我们将它们标记为已执行的状态。

让我们运行ChangelogSyncSQL来进行预览,并让ChangelogSync对数据库执行SQL。

一文详解Liquibase如何自动化数据库脚本部署

 

运行ChangeSyncSQL和ChangelogSync

下图展示了ChangelogSync命令执行后,更新了的数据库。至此,我们已大功告成,您也可以选用自己喜欢的方式,通过Liquibase来实现数据库的自动化。

一文详解Liquibase如何自动化数据库脚本部署

 

小结

如您所见,通过使用Liquibase,我们可以在数据库更改的发布过程中,跟踪所有的相关内容。其中,需要开发人员遵守如下流程:

【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>