您当前的位置:首页 > 电脑百科 > 数据库 > 百科

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

时间:2021-12-22 09:55:29  来源:51CTO  作者:
一文详解Liquibase如何自动化数据库脚本部署

 

作者丨Rafal Grzegorczyk

译者丨陈骏

策划丨孙淑娟

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

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

Liquibase的基本特点

  • 自动化数据库的部署脚本。
  • 以相同的方式部署到不同的环境中。
  • 能够为每次数据库的更改准备好回滚。
  • 能够将部署的所有详细信息集中到一处。
  • 最少化的部署错误。
  • 方便开发人员针对相同的数据库,进行高效的协同编程。
  • 审核逐个更改(请参考下图)。
一文详解Liquibase如何自动化数据库脚本部署

 

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

什么是Liquibase?

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

  • DATABASECHANGELOG — 存储有关数据库所有更改信息的表。
  • DATABASECHANGELOGLOCK — 用于防止用户同时对数据库进行更改。

我将在下面示例中,基于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命令

其中:

  • Liquibase会调用LB的环境路径。
  • defaultsFile指定属性文件的名称和位置。如果您将属性文件命名为“liquibase.properties”,那么可以省略此命令。
  • updateSQL负责生成SQL脚本(它并不会对数据库执行任何操作)。

几秒钟后,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文件

其中:

  • runOnChange:true ——意味着每次更改包时,Liquibase都会针对数据库运行该变更集,也就是编译这个包。
  • stripComments:false ——意味着不要去除代码注释。

因此,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如何自动化数据库脚本部署

 

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

  • 对这些对象不做任何操作,但请记住始终为其中的每个更改(包括:更改表、删除列等)创建变更集,并将其添加到changelog.sql文件中。
  • 创建变更集并将它们标记为过去已被执行过。

在此,我们着重讨论第二种方式。由于在实施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,我们可以在数据库更改的发布过程中,跟踪所有的相关内容。其中,需要开发人员遵守如下流程:

  • 基于变更集的唯一性,并结合AUTHOR:ID(task)与文件名(带changelog的文件),将变更集添加到changelog中。而且,请不要在没有Liquibase的情况下,更改任何内容。
  • 验证待执行的SQL。
  • 运行数据库的update命令(记住,应当先运行updateSQL,再执行update命令)。
  • 通过检查数据库对象和DATABASECHANGELOG表,验证变更集是否已被执行。

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



Tags:Liquibase   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
作者丨Rafal Grzegorczyk译者丨陈骏策划丨孙淑娟【51CTO.com原创稿件】您是否还在手动对数据库执行各种脚本?您是否还在浪费时间去验证数据库脚本的正确性?您是否还需要将...【详细内容】
2021-12-22  Tags: Liquibase  点击:(3)  评论:(0)  加入收藏
▌简易百科推荐
1增1.1【插入单行】insert [into] <表名> (列名) values (列值)例:insert into Strdents (姓名,性别,出生日期) values (&#39;开心朋朋&#39;,&#39;男&#39;,&#39;1980/6/15&#3...【详细内容】
2021-12-27  快乐火车9d3    Tags:SQL   点击:(1)  评论:(0)  加入收藏
最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫, 不知道各种写法孰优孰劣,该选用哪种写法,以及各种写法的优缺点,本文以一个简单的查询...【详细内容】
2021-12-23  linux上的码农    Tags:sql   点击:(9)  评论:(0)  加入收藏
《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的HasorDB 是一个全功能数据库访问工具,提供对象映射、丰...【详细内容】
2021-12-22  GitHub精选    Tags:HasorDB   点击:(5)  评论:(0)  加入收藏
作者丨Rafal Grzegorczyk译者丨陈骏策划丨孙淑娟【51CTO.com原创稿件】您是否还在手动对数据库执行各种脚本?您是否还在浪费时间去验证数据库脚本的正确性?您是否还需要将...【详细内容】
2021-12-22    51CTO  Tags:Liquibase   点击:(3)  评论:(0)  加入收藏
场景描述:由于生产环境的表比较复杂,字段很多。这里我们做下简化,只为说明今天要聊的问题。有两张表 tab1,tab2: tab1 数据如下: tab2 数据如下: 然后给你看下,我用来统计 name=&#3...【详细内容】
2021-12-20  Bald    Tags:SQL   点击:(5)  评论:(0)  加入收藏
前言知识无底,学海无涯,知识点虽然简单,但是比较多,所以将MySQL的基础写出来,方便自己以后查找,还有就是分享给大家。一、SQL简述1.SQL的概述Structure Query Language(结构化查...【详细内容】
2021-12-16  谣言止于独立思考    Tags:SQL基础   点击:(13)  评论:(0)  加入收藏
前言作为一名测试工程师,工作中在对测试结果进行数据比对的时候,或多或少要和数据库打交道的,要和数据库打交道,那么一些常用的 SQL 查询语法必须要掌握。最近有部分做测试小伙...【详细内容】
2021-12-14  柠檬班软件测试    Tags:SQL   点击:(15)  评论:(0)  加入收藏
话说C是面向内存的编程语言。数据要能存得进去,取得出来,且要考虑效率。不管是顺序存储还是链式存储,其寻址方式总是很重要。顺序存储是连续存储。同质结构的数组通过其索引表...【详细内容】
2021-12-08  小智雅汇    Tags:数据存储   点击:(17)  评论:(0)  加入收藏
概述DBConvert Studio 是一款强大的跨数据库迁移和同步软件,可在不同数据库格式之间转换数据库结构和数据。它将成熟、稳定、久经考验的 DBConvert 和 DBSync 核心与改进的现...【详细内容】
2021-11-17  雪竹聊运维    Tags:数据库   点击:(26)  评论:(0)  加入收藏
一、前言 大家好,我是小诚,《从0到1-全面深刻理解MySQL系列》已经来到第四章,这一章节的主要从一条SQL执行的开始,由浅入深的解析SQL语句由客户端到服务器的完整执行流程,最...【详细内容】
2021-11-09  woaker    Tags:SQL   点击:(35)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条