Deployment skema database yang bergantung pada tiket manual dan pengeksekusian skrip SQL ad-hoc oleh Database Administrator (DBA) menimbulkan bottleneck rilis software. Pendekatan ini rentan terhadap human error, hilangnya audit trail, dan memicu schema drift—kondisi di mana struktur skema pada environment Development, Staging, dan Production tidak sinkron.
Oracle SQLcl menyediakan modul native Liquibase tanpa dependensi JDBC pihak ketiga tambahan. Integrasi modul ini ke dalam pipeline CI/CD memindahkan pengelolaan DDL ke sistem version control, memungkinkan inspeksi otomatis, peninjauan SQL dry-run, hingga eksekusi migrasi yang idempoten.
Struktur Direktori dan Changelog Controller
Pola manajemen objek skema membutuhkan changelog controller utama (master changelog) yang mengorganisasi rilis berdasarkan versi atau modul aplikasi. Controller ini bertindak sebagai entry-point tunggal bagi runner CI/CD.
database/
├── controller.xml
├── release-1.0/
│ ├── 001-create-orders-table.sql
│ └── 002-create-indexes.sql
└── release-1.1/
└── 003-alter-orders-table.sqlGunakan file XML sebagai controller root untuk mengimpor file perubahan individual. Ini memudahkan isolasi perubahan antar rilis.
<?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-latest.xsd">
<include file="release-1.0/001-create-orders-table.sql" relativeToChangelogFile="true"/>
<include file="release-1.0/002-create-indexes.sql" relativeToChangelogFile="true"/>
</databaseChangeLog>Format Changeset DDL (Formatted SQL)
Meskipun format XML/YAML didukung, format SQL beranotasi Liquibase (--liquibase formatted sql) lebih praktis untuk tim engineer karena mempertahankan sintaks native Oracle PL/SQL dan DDL khusus.
--liquibase formatted sql
--changeset dimas:001-create-orders-table failOnError:true
--comment: Inisialisasi tabel orders
CREATE TABLE orders (
order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
customer_id NUMBER NOT NULL,
order_date TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
total_amount NUMBER(12,2) NOT NULL,
status VARCHAR2(20) DEFAULT 'PENDING' NOT NULL
);
--rollback DROP TABLE orders CASCADE CONSTRAINTS;
--changeset dimas:002-create-orders-status-idx failOnError:true
--comment: Optimasi pencarian berdasarkan status order
CREATE INDEX idx_orders_status ON orders(status);
--rollback DROP INDEX idx_orders_status;Setiap changeset wajib menyertakan blok --rollback untuk memastikan rollback otomatis dapat dieksekusi jika terjadi kesalahan pada rilis terkait.
Manajemen Autentikasi Aman via Oracle Wallet
Mengekspos cleartext password database dalam variabel pipeline CI/CD melanggar standar kepatuhan keamanan. Gunakan Oracle Wallet (kredensial tersimpan dalam cwallet.sso) yang dibundel dalam format ZIP dan disimpan sebagai Base64-encoded secret pada CI repository.
Encode file wallet lokal sebelum menyimpannya ke GitHub Secrets:
base64 -w 0 wallet.zip > wallet_base64.txtDalam runner CI, ekstrak wallet tersebut lalu konfigurasi TNS_ADMIN agar SQLcl dapat tersambung langsung menggunakan TNS Alias tanpa input password manual.
Pipeline CI/CD pada GitHub Actions
Pipeline migrasi database dijalankan bertahap: inspeksi status skema, pembuatan artifact SQL dry-run, eksekusi deployment, dan penanganan kegagalan otomatis.
name: Oracle Schema Migration
on:
push:
branches: [ main ]
paths:
- 'database/**'
jobs:
migrate:
runs-on: ubuntu-latest
container:
image: container-registry.oracle.com/database/sqlcl:latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Oracle Wallet
env:
WALLET_BASE64: ${{ secrets.ORACLE_WALLET_BASE64 }}
run: |
mkdir -p /opt/oracle/wallet
echo "$WALLET_BASE64" | base64 -d > /opt/oracle/wallet/wallet.zip
unzip -o /opt/oracle/wallet/wallet.zip -d /opt/oracle/wallet/
export TNS_ADMIN=/opt/oracle/wallet
- name: 1. Inspeksi Status Skema (lb status)
env:
TNS_ADMIN: /opt/oracle/wallet
run: |
sql -s /nolog <<EOF
connect /@app_prod_high
lb status -changelog-file database/controller.xml -verbose
exit;
EOF
- name: 2. Dry-Run SQL Preview (lb update-sql)
env:
TNS_ADMIN: /opt/oracle/wallet
run: |
sql -s /nolog <<EOF
connect /@app_prod_high
lb update-sql -changelog-file database/controller.xml -output-file pending_migration.sql
exit;
EOF
- name: Upload Migration Preview Artifact
uses: actions/upload-artifact@v4
with:
name: migration-dryrun-preview
path: pending_migration.sql
- name: 3. Eksekusi Deployment Skema (lb update)
id: deploy
env:
TNS_ADMIN: /opt/oracle/wallet
run: |
sql -s /nolog <<EOF
whenever sqlerror exit failure rollback;
connect /@app_prod_high
lb update -changelog-file database/controller.xml
exit;
EOF
- name: Rollback Otomatis Saat Deployment Gagal
if: failure() && steps.deploy.outcome == 'failure'
env:
TNS_ADMIN: /opt/oracle/wallet
run: |
echo "Deployment gagal. Menjalankan rollback ke tag/status sebelumnya..."
sql -s /nolog <<EOF
connect /@app_prod_high
lb rollback-count -count 1 -changelog-file database/controller.xml
exit;
EOFSiklus Lifecycle Perintah Liquibase di SQLcl
lb status -verbose: Membaca tabel trackingDATABASECHANGELOGdan mencetak daftar changeset yang belum dieksekusi. Perintah ini mengidentifikasi item yang tertunda tanpa mengubah struktur DB.lb update-sql: Meng-generate skrip SQL mentah yang akan dieksekusi berdasarkan changeset yang tertunda. Simpan output ini sebagai artifact pipeline untuk audit kepatuhan dan validasi manual jika diperlukan.lb update: Mengeksekusi DDL pending secara atomik per changeset, memperbarui tabelDATABASECHANGELOGdengan ID, penulis, nama file, dan nilai hash (checksum).
Validasi Checksum dan Penanganan Error
1. Checksum Mismatch (MD5 Error)
Liquibase mencatat MD5 hash dari isi file changeset pada tabel DATABASECHANGELOG saat eksekusi pertama. Jika engineer mengedit file yang sudah berstatus deployed di production, runner CI akan menghentikan eksekusi dengan pesan kegagalan:
ValidationFailedException: Validation Failed:
1 change sets check sum
database/release-1.0/001-create-orders-table.sql::001-create-orders-table::dimas was: 8:e5b61f... but is now: 8:c3f12a...Solusi: Jangan ubah file yang sudah berjalan di production. Buat changeset baru untuk memodifikasi struktur yang ada (contoh: buat 003-alter-orders-table.sql dengan DDL ALTER TABLE). Jika perubahan bersifat non-fungsional (misal: memformat spasi atau komentar), tambahkan tag <validCheckSum> atau gunakan instruksi --validCheckSum: ANY pada header changeset.
2. Strategi Rollback: Fail-Forward vs Automated Rollback
Meskipun lb rollback-count tersedia, rollback DDL otomatis pada RDBMS Oracle memiliki batasan: perintah DDL (seperti CREATE, ALTER, DROP) mengeksekusi implisit commit di Oracle. Rollback transaksi SQL biasa tidak membatalkan DDL.
Rekomendasi: Gunakan strategi fail-forward pada tabel sistem critical yang memuat data produksi. Rollback via DROP COLUMN atau DROP TABLE berisiko menghilangkan data secara permanen. Pastikan script rollback hanya dijalankan jika changeset yang gagal merupakan tabel baru yang belum menampung transaksi data.
3. Mengatasi Schema Drift
Schema drift terjadi ketika user dengan hak akses DBA melakukan modifikasi langsung pada tabel tanpa melalui Git. Ketika pipeline CI/CD dijalankan, modifikasi manual tersebut dapat bentrok dengan changeset Liquibase berikutnya.
- Terapkan least privilege access: Akun personal DBA tidak boleh memiliki akses DDL langsung pada target schema di Production. Akses DDL hanya diberikan kepada service account yang digunakan oleh CI/CD runner.
- Gunakan
lb diffsecara terjadwal pada cron job CI untuk membandingkan skema produksi terhadap master changelog dan mengirimkan alert jika terdeteksi anomali.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!