Liquibase là gì? Giải pháp tự động hóa triển khai cơ sở dữ liệu
Trong thời đại công nghệ số, việc tự động hóa quy trình triển khai cơ sở dữ liệu là yếu tố then chốt giúp doanh nghiệp tối ưu hóa hiệu suất và giảm thiểu rủi ro. Bài viết dưới đây Bizfly Cloud sẽ giới thiệu về Liquibase - một công cụ mã nguồn mở mạnh mẽ giúp tự động hóa việc triển khai cơ sở dữ liệu một cách hiệu quả.
Tự động hóa cơ sở dữ liệu với Liquibase
Nhiều tổ chức đã triển khai DevOps trong các ứng dụng của họ. Nhưng đồng thời, quy trình thay đổi cơ sở dữ liệu của họ vẫn chưa nhận ra bất kỳ lợi ích nào từ DevOps và vẫn bị bỏ lại trong thời kỳ đen tối. Nhưng điều gì sẽ xảy ra nếu bạn cũng có thể tự động hóa điều đó? Vâng, bạn đoán đúng rồi - nó có thể được thực hiện bằng cách sử dụng Liquibase. Và đây là hướng dẫn về Liquibase để chỉ cho bạn cách thực hiện điều đó.
Hướng dẫn Liquibase dành cho bạn?
Bạn có đang tự tay thực thi các tập lệnh cho cơ sở dữ liệu của mình? Hay có thể bạn đang lãng phí thời gian để xác thực các tập lệnh cơ sở dữ liệu nhận được từ nhóm của mình?
Sau đó, bạn có hợp nhất các tập lệnh thành một tệp và thực thi chúng trong mọi môi trường? Thế còn lỗi triển khai? Bạn đã bao giờ dành hàng giờ để xem ai, tại sao và điều gì đã được thay đổi trong cơ sở dữ liệu?
Nhưng điều gì sẽ xảy ra nếu bạn không thể có toàn bộ quy trình CI/CD ngay bây giờ hoặc chính sách của công ty không cho phép bạn chạy tập lệnh trên các môi trường cụ thể? Đó không phải là vấn đề đối với Liquibase.
Bằng cách sử dụng Liquibase, bạn có thể:
- Tự động hóa các tập lệnh triển khai cơ sở dữ liệu của bạn,
- Triển khai nhất quán theo cùng một cách trong mọi môi trường,
- Luôn chuẩn bị sẵn sàng khôi phục cho mọi thay đổi cơ sở dữ liệu,
- Có tất cả thông tin chi tiết về việc triển khai ở một nơi.
Hơn nữa, nhờ điều này mà bạn sẽ có:
- Ít lỗi triển khai hơn,
- Các nhà phát triển vui vẻ và hiệu quả cùng nhau viết mã trên cùng một cơ sở dữ liệu,
- Mọi thay đổi đều được kiểm tra, ví dụ: ai, khi nào (và tại sao) đã thay đổi cột shoes.Shoe_size từ kiểu dữ liệu số thành varchar2,
- Có nhiều thời gian uống cà phê hơn.
Trong một loạt bài viết, tôi sẽ chỉ cho bạn cách chúng tôi tự động hóa quy trình thay đổi cơ sở dữ liệu tại Pretius bằng cách sử dụng Liquibase và Git - bao gồm các ví dụ từ môi trường truy cập hạn chế. Hãy bắt đầu với hướng dẫn cơ bản về Liquibase này.
Liquibase là gì?
Liquibase (LB) là một công cụ mã nguồn mở được viết bằng Java. Nó giúp việc xác định các thay đổi cơ sở dữ liệu trở nên dễ dàng, ở định dạng quen thuộc và thoải mái cho mỗi người dùng. Sau đó, nó tự động tạo SQL dành riêng cho cơ sở dữ liệu cho bạn.
Các thay đổi cơ sở dữ liệu (mọi thay đổi được gọi là bộ thay đổi) được quản lý trong các tệp được gọi là nhật ký thay đổi.
Liquibase cần hai bảng tại lược đồ cơ sở dữ liệu của bạn (được tạo tự động):
- DATABASECHANGELOG - một bảng lưu trữ thông tin về tất cả các thay đổi được thực hiện đối với cơ sở dữ liệu của bạn,
- DATABASECHANGELOGLOCK - được sử dụng để ngăn người dùng thực hiện các thay đổi đối với cơ sở dữ liệu cùng một lúc.
Ví dụ của tôi sẽ dựa trên các tập hợp thay đổi được viết bằng SQL - đó là cách dễ nhất để bắt đầu tự động hóa quy trình thay đổi cơ sở dữ liệu Oracle của bạn.
Bắt đầu với việc cài đặt Liquibase
Truy cập và tải xuống phiên bản Liquibase mới nhất - chọn "Chỉ các tệp". Trong bài viết này, tôi sẽ sử dụng phiên bản 4.3.0. build 09.02.2021.
Giải nén thư mục zip đã tải xuống (ví dụ: vào ổ đĩa C:). Sau đó, bạn phải đặt một Biến Hệ thống Đường dẫn Mới vào thư mục liquibase-version # bin trên máy tính của bạn. Để Liquibase hoạt động chính xác, bạn cũng phải cài đặt Java.
Truy cập công cụ CLI yêu thích của bạn (tôi sử dụng Visual Studio Code) và nhập:
Nếu mọi thứ đều ổn, bạn sẽ thấy:
Nếu bạn sử dụng mã hóa UTF8 trong tệp của mình, hãy nhớ chỉnh sửa tệp liquibase.bat bằng cách thêm dòng:
IF NOT DEFINED JAVA_OPTS set JAVA_OPTS=-Dfile.encoding=UTF–8
Định cấu hình dự án và Liquibase của bạn
Được rồi, hãy xem cách chúng ta có thể sắp xếp các tệp của mình (thư mục HR là kho lưu trữ GIT của tôi). Trong các thư mục này, chúng tôi sẽ đặt các tệp được tạo trong quá trình phát triển dự án. Nếu bạn có các loại đối tượng khác (thuộc loại "tạo hoặc thay thế"), chỉ cần tạo một thư mục với chúng, ví dụ: "từ đồng nghĩa."
#đường dẫn đến tệp nhật ký thay đổi chính của chúng tôi changeLogFile: liquibase/update.xml #dbhost và thông tin đăng nhập url: jdbc:oracle:thin:@127.0.0.1:1521/XEPDB1 username: HR password: XXXXXX #Vị trí trình điều khiển OJDBC classpath: liquibase/ojdbc8.jar #lược đồ, nơi Liquibase sẽ lưu trữ bảng DATABASECHANGELOG và DATABASECHANGELOGLOCK của nó (nếu khác với HR, hãy nhớ thêm quyền cho HR!) liquibaseSchemaName: HR #tên tệp SQL mặc định được tạo bởi Liquibase outputFile=output_local.sql #chế độ gỡ lỗi loglevel=SEVERE #tùy chọn bổ sung từ Liquibase, chúng tôi chưa cần đến nó lúc này. liquibase.hub.mode=off
Bây giờ, hãy tạo tệp update.xml (đặt nó vào thư mục hr/liquibase mới với tệp OJDBC):
<?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>
Sử dụng Oracle Wallet (Tùy chọn)
Nếu cơ sở dữ liệu Oracle của bạn được lưu trữ trên Cơ sở dữ liệu tự trị của Oracle, bạn cần sử dụng ví để kết nối với nó thông qua Liquibase. Do đó, hãy tải xuống ví của bạn và ghi nhớ mật khẩu cho nó.
Giải nén WALLET_NAME.ZIP của bạn vào thư mục HR/liquibase đã tạo trước đó. Ngoài ra, hãy chỉnh sửa tệp HR/liquibase/wallet_name/ojdbc.properties của bạn:
Tệp của bạn sẽ trông giống như trên màn hình ở trên. Trong các dòng javax.net.ssl.trustStorePassword và javax.net.ssl.keyStorePassword, hãy đặt mật khẩu ví ATP của bạn.
Chỉnh sửa URL tại tệp liquibase_local.properties của bạn và đặt tên kết nối của bạn (từ Wallet/tnsnames.ora và đường dẫn đến ví):
url: jdbc:oracle:thin:@rgatp28_high?TNS_ADMIN=liquibase/Wallet_RGATP28
Kiểm tra tệp sqlnet.ora của bạn, đảm bảo rằng có "SSL_SERVER_DN_MATCH=yes". Đừng thay đổi bất cứ điều gì khác.
Kết nối Liquibase với cơ sở dữ liệu
Nếu mọi thứ đã được đặt đúng cách, chúng ta có thể thực hiện kết nối đầu tiên đến cơ sở dữ liệu DEV của mình. Khởi động CLI yêu thích của bạn từ thư mục HR (vị trí của tệp thuộc tính Liquibase) - đối với bài viết này, tôi sử dụng terminal trực tiếp từ VS Code và kết nối với cơ sở dữ liệu phát triển cục bộ của tôi.
liquibase —defaultsFile=liquibase_dev.properties updateSQL
**liquibase**> gọi LB (đường dẫn môi trường).
**defaultsFile**> tên và vị trí của tệp thuộc tính của chúng tôi.
(Nếu bạn đặt tên tệp thuộc tính thành "liquibase.properties" thì bạn có thể bỏ qua lệnh này vì đó là mặc định của Liquibase. Tôi muốn có các tên khác nhau cho mọi kết nối.)
**updateSQL**> Lệnh Liquibase, chỉ tạo tập lệnh SQL (nó sẽ không làm gì trên cơ sở dữ liệu của bạn).
Trong vài giây, LB sẽ tạo output_file.sql:
Như bạn có thể thấy, nếu bạn chạy tập lệnh này cho cơ sở dữ liệu của mình, nó sẽ tạo hai bảng: DATABASECHANGELOG và DATABASECHANGELOGLOCK.
Ok, bây giờ hãy tạo những bảng đó:
liquibase —defaultsFile=liquibase_dev.properties update
Lệnh update sẽ thực thi SQL cho cơ sở dữ liệu.
Các bảng được tạo:
Chúng ta cần tạo một tệp nhật ký thay đổi sẽ trỏ đến các thư mục của chúng ta với các đối tượng (những đối tượng mà chúng ta có thể tạo/thay thế).
Tôi đã tạo tệp 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>
Nó trỏ đến các thư mục đối tượng của tôi và tất cả nội dung của nó.
Trong nhật ký thay đổi chính HR/liquibaseupdate.xml, hãy đặt đường dẫn đến tệp master.xml của bạn, chỉ cần thêm dòng:
<include file="./master.xml"/>
bao gồm file="./master.xml" Bên trong update.xml
Liquibase luôn chạy từ tệp liquibase_dev.properties và tệp update.xml của chúng tôi, vì vậy Nó phải xem tất cả các tệp của bạn từ đó.
Theo dõi các thay đổi cơ sở dữ liệu DML và DDL của bạn
Được rồi, hãy đợi... nhưng còn những thay đổi như DDL hoặc DML thì sao? Không vấn đề gì.
Chúng tôi tạo một tệp nhật ký thay đổi riêng biệt cho loại thay đổi đó và viết các bộ thay đổi của chúng tôi bên trong đó.
Chỉ cần tạo tệp changelog.sql và đánh dấu nó là tệp SQL Liquibase bằng cách nhập:
Trỏ đến nhật ký thay đổi mới của chúng tôi trong tệp master.xml bằng cách thêm:
<include file="changelog.sql" relativeToChangelogFile="true" />
Thứ tự bạn trỏ đến nhật ký thay đổi hoặc thư mục của mình rất quan trọng. Nó cho Liquibase biết thứ tự chạy SQL của bạn. Tốt hơn là nên chạy nhật ký thay đổi trước (bên trong là "tạo bảng (…)") và sau đó biên dịch gói sử dụng bảng này.
Hãy tạo bảng dự án đầu tiên trong bộ thay đổi của chúng tôi. Chỉ cần viết:
—changeset AUTHOR:CHANGESET_NAME
—comment OPTIONAL COMMENT
YOUR DDL
Hãy yêu cầu LB tạo tệp SQL của chúng tôi (chỉ để xem trước những thay đổi sẽ được thực hiện đối với cơ sở dữ liệu của chúng tôi).
liquibase —defaultsFile=liquibase_dev.properties updateSQL
Như bạn có thể nhận thấy, LB sẽ khóa bảng DATABASECHANGELOGLOCK của chúng tôi bằng cách đặt LOCKED = 1 (trong khi bạn đang chạy tập lệnh của mình cho DB, cột LOCKED được đặt thành 1. Khi người dùng khác chạy LB cùng lúc, Liquibase sẽ đợi cho đến khi khóa được giải phóng), sau đó nó sẽ tạo bảng SHOES, chèn thay đổi nhật ký vào DATABASECHANGELOG và giải phóng khóa khỏi bảng DATABASECHANGELOGLOCK.
Nếu mọi thứ đều ổn, hãy thực thi tập lệnh sau cho cơ sở dữ liệu của chúng tôi:
liquibase —defaultsFile=liquibase_dev.properties update
Bảng SHOES đã được tạo.
Chúng ta có thể kiểm tra ai, tại sao và khi nào tạo bảng này.
Cuối cùng, không có gì là ẩn danh!
Theo dõi các thay đổi cơ sở dữ liệu khác (Gói, Lượt xem, v.v.)
Bây giờ, chúng ta có thể làm tương tự với một số tập lệnh. Tôi đã tạo một gói có tên SHOES_PKG trong 2 tệp riêng biệt. Mọi tệp là một bộ thay đổi duy nhất và phải được đánh dấu là tệp SQL được định dạng Liquibase.
Tệp SQL là một bộ thay đổi duy nhất với các tham số bổ sung:
**runOnChange**:true - điều đó có nghĩa là, mỗi khi chúng tôi thay đổi gói của mình, Liquibase sẽ chạy bộ thay đổi này dựa trên cơ sở dữ liệu của chúng tôi (biên dịch gói này).
**stripComments**:false - không được cắt bỏ bình luận mã của chúng tôi.
Bây giờ, nếu chúng tôi kiểm tra SQL mà LB sẽ chạy dựa trên cơ sở dữ liệu (updateSQL) - nó sẽ biên dịch cả đặc tả gói và phần thân gói.
Hãy biên dịch gói này trong DB của chúng ta (lệnh update).
Mọi thứ đều được ghi lại và các gói được biên dịch.
Hãy xem giá trị cột MD5SUM - đó là tổng kiểm tra cuối cùng của bộ thay đổi của bạn.
Hiện tại, tất cả các thay đổi đang chờ xử lý đều được thực hiện; LB sẽ không tạo bất kỳ thứ gì trong SQL (ngoài bảng khóa LB) - hãy kiểm tra bằng cách chạy updateSQL.
Bây giờ, chúng ta hãy thay đổi phần thân SHOES_PKG của chúng tôi và lưu tệp.
Tổng kiểm tra của tệp đã thay đổi và LB sẽ biên dịch lại gói này - hãy chạy bản cập nhật.
Liquibase đã biên dịch lại phần thân gói và cập nhật hàng với các bộ thay đổi này trong bảng DATABASECHANGELOG - với DATEEXECUTED thực tế và giá trị MD5SUM mới.
Cách cài đặt Liquibase trong một dự án phần mềm hiện có?
Trong phần này của hướng dẫn Liquibase, bạn sẽ tìm hiểu cách triển khai tự động hóa cơ sở dữ liệu trong một dự án phần mềm hiện có.
Có thể thực hiện được mà không cần hàng giờ làm việc bổ sung? Vâng!
Có một số cách để tự động hóa cơ sở dữ liệu hiện có của bạn bằng Liquibase. Tôi sẽ chỉ cho bạn hai cách mà tôi thấy hữu ích nhất - và bạn có thể chọn cách phù hợp nhất với nhu cầu của mình.
Trong các ví dụ bên dưới, tôi sẽ sử dụng dự án được tạo trong các bước trước của hướng dẫn Liquibase này.
Cách cài đặt Liquibase khi có rất nhiều đối tượng trong dự án hiện có của bạn
Định cấu hình Liquibase trong kho lưu trữ dự án của bạn và để nguyên tất cả các tệp - chỉ cần nhớ thêm đường dẫn đến chúng trong tệp master.xml của bạn.
Vì vậy, tôi đã tạo 2 thủ tục và 2 trình kích hoạt trước khi triển khai Liquibase:
P_ADD_JOB_HISTORY
P_SECURE_DML
TRG_SECURE_EMPLOYEES
TRG_UPDATE_JOB_HISTORY
Bạn KHÔNG cần thêm "changeset" hoặc "–liquibase formatted sql" vào tệp của mình ngay bây giờ.
Bây giờ, hãy chạy Liquibase updateSQL để xem SQL Liquibase muốn thực thi là gì:
liquibase —defaultsFile=liquibase_dev.properties updateSQL
OK, anh bạn. Nhưng đây không phải là những gì chúng tôi muốn! Chúng tôi đã có các thủ tục và trình kích hoạt này trong cơ sở dữ liệu của mình. Chúng tôi không muốn tạo lại những đối tượng này.
Đó là lúc các lệnh ChangelogSync và ChangelogSyncSQL phát huy tác dụng!
Hãy chạy ChangelogSyncSQL để xem điều gì sẽ xảy ra:
liquibase —defaultsFile=liquibase_dev.properties ChangelogSyncSQL
Tệp SQL đầu ra là:
Đây chính xác là những gì chúng tôi muốn - chỉ là một tệp SQL có chèn trong bảng **DATABASECHANGELOG**. Nó sẽ "cho" Liquibase biết rằng những đối tượng đó đã được tạo trong quá khứ và không cần chạy lại chúng nữa.
Bây giờ, hãy chèn nó vào cơ sở dữ liệu Oracle của chúng tôi:
liquibase —defaultsFile=liquibase_dev.properties ChangelogSync
Và chúng tôi có 4 bộ thay đổi mới trong bảng **DATABASECHANGELOG**:
Nhưng những ID "thô" kỳ lạ này là gì? Và tại sao tác giả lại được gọi là "includeAll"? Bởi vì đây là cách dễ nhất và nhanh nhất để chuyển dự án hiện có của bạn sang Liquibase! Và những bộ thay đổi này đã được tạo tự động.
Nếu bạn muốn thực hiện một số thay đổi, ví dụ: trong P_ADD_JOB_HISTORY, chỉ cần thêm một changeset - như bạn thường làm khi tạo một đối tượng cơ sở dữ liệu mới:
Sau đó, chạy lệnh Liquibase Update:
Bộ thay đổi trông đẹp hơn rồi, phải không? Với tác giả, ID, v.v. thích hợp.
Trong các ví dụ trên, tôi đã chỉ cho bạn cách dễ dàng để thêm các đối tượng hiện có (có thể được tạo hoặc thay thế) mà không cần tạo bộ thay đổi theo cách thủ công. Theo tôi, đó là cách tốt nhất để cài đặt Liquibase nếu bạn có hàng trăm đối tượng trong cơ sở dữ liệu hiện có của mình.
Khi nói đến các đối tượng không thể thay thế, chẳng hạn như bảng, chúng ta cần sử dụng cách được mô tả trong kịch bản thứ hai.
Cách cài đặt Liquibase nếu bạn không có nhiều đối tượng trong dự án hiện có của mình
Tùy chọn này yêu cầu bạn tạo bộ thay đổi cho các đối tượng và thay đổi đã được thực hiện đối với cơ sở dữ liệu của bạn.
Các đối tượng mà bạn tạo hoặc thay thế
Thêm đối tượng và nhớ có đường dẫn đến các thư mục trong tệp master.xml của bạn - giống như được mô tả trong kịch bản đầu tiên.
Chạy ChangelogSync và để Liquibase tự động tạo bộ thay đổi thô / includeAll / tên tệp.
Hoặc, một cách tốt hơn, hãy tạo một bộ thay đổi cho mọi tệp như thế này:
Chắc chắn là sẽ mất nhiều công sức hơn, nhưng bạn sẽ nhận được thông tin tốt hơn trong nhật ký của mình:
Các đối tượng không thể được tạo hoặc thay thế
Bạn có thể làm gì với các đối tượng khác như bảng, chỉ mục, v.v.?
Một lần nữa, có hai cách:
- Không làm gì với các đối tượng này nhưng hãy nhớ luôn tạo bộ thay đổi cho mọi thay đổi trong chúng và thêm nó vào tệp changelog.sql của bạn (thay đổi bảng, bỏ cột, v.v.)
- Tạo bộ thay đổi và đánh dấu chúng là đã được thực thi trong quá khứ.
Hãy xem xét kỹ hơn cách thứ hai.
Tôi có một vài bảng đã được tạo trước khi triển khai Liquibase:
Tôi tạo hai tệp nhật ký thay đổi trong một thư mục mới, HR/scripts_before_liquibase.
changelog_ddl.sql
changelog_constraints.sql
Ngoài ra, tôi tạo một tệp scripts_before_liquibase.xml bổ sung sẽ trỏ đến nhật ký thay đổi của chúng tôi.
Mức độ ưu tiên của "include file" rất quan trọng, vì nó cho Liquibase biết thứ tự chạy tập lệnh - trước tiên tạo bảng, sau đó tạo ràng buộc và chỉ mục.
Thực hành tốt là có 2 tệp: một tệp để tạo bảng, tệp thứ hai dành cho ràng buộc. Nó sẽ giúp bạn tránh xung đột khi cố gắng tạo ref_constraint trong một bảng sẽ được tạo sau đó vài giây.
Hãy nhớ thêm đường dẫn trong tệp master.xml vào tệp XML mới được tạo của bạn (HR/script_before_liquibase/scripts_before_liquibase.xml).
Bây giờ, hãy tạo bộ thay đổi cho bảng, ràng buộc, v.v.
OK, sau khi thêm tất cả các bộ thay đổi của chúng tôi, chúng tôi sẽ đánh dấu chúng là đã được thực thi trong quá khứ.
Hãy chạy **ChangelogSyncSQL** để xem trước, sau đó chạy **ChangelogSync** để chạy SQL dựa trên cơ sở dữ liệu.
Và voila! Hoàn thành!
Bây giờ, hãy chọn cách bạn muốn và triển khai tự động hóa cơ sở dữ liệu bằng Liquibase ngay bây giờ.
Tóm tắt hướng dẫn Liquibase
Như bạn có thể thấy, bằng cách sử dụng Liquibase, bạn có thể theo dõi mọi thứ trong quy trình phát hành thay đổi cơ sở dữ liệu của mình.
Tuy nhiên, tất cả các nhà phát triển nên tuân thủ quy trình làm việc này:
Luôn thêm bộ thay đổi của bạn vào nhật ký thay đổi (không thay đổi bất kỳ thứ gì mà không có Liquibase!) - bộ thay đổi phải là duy nhất, kết hợp AUTHOR: ID (nhiệm vụ) và tên tệp (tệp có nhật ký thay đổi của bạn).
Xác minh SQL bạn sẽ thực thi (luôn chạy lệnh **updateSQL** trước lệnh update).
Chạy lệnh **update** cơ sở dữ liệu.
Xác minh rằng bộ thay đổi hoặc các bộ thay đổi đã được thực thi (kiểm tra các đối tượng DB của bạn và bảng DATABASECHANGELOG).
Chúng ta kết thúc hướng dẫn cơ bản về Liquibase tại đây. Tuy nhiên, hãy theo dõi các bài viết tiếp theo!