Deepen PracticeOrdered learning track

Liquibase Diff, Snapshot, and Drift Detection

Learn Java Database Migrations, Flyway, Liquibase - Part 020

Liquibase diff, snapshot, generate-changelog, diff-changelog, dan drift detection sebagai kontrol engineering untuk menjaga database tetap sinkron dengan changelog.

13 min read2417 words
PrevNext
Lesson 2034 lesson track1928 Deepen Practice
#java#database#migration#liquibase+7 more

Part 020 — Liquibase Diff, Snapshot, Generate Changelog, dan Drift Detection

Liquibase tidak hanya menjalankan migration. Ia juga bisa membantu kita menginspeksi database, membandingkan database, membuat snapshot, menghasilkan changelog dari state database, dan mendeteksi drift.

Namun fitur-fitur ini sering disalahgunakan.

Kesalahan paling berbahaya:

“Production adalah kebenaran. Generate changelog dari production, commit, selesai.”

Itu bisa mengubah migration discipline menjadi reverse-engineering kacau. Production memang realitas, tetapi belum tentu intended design. Manual hotfix, eksperimen DBA, emergency patch, atau perubahan legacy bisa ada di production tanpa pernah menjadi contract yang disetujui.

Mental model bagian ini:

Diff dan snapshot adalah sensor. Changelog tetap source of intent.


1. Kaufman Deconstruction

Skill “diff/snapshot/drift” kita pecah menjadi komponen kecil.

Sub-skillPertanyaan intiOutput
Snapshot thinkingState apa yang sedang difoto?Snapshot artifact
Diff directionMana reference, mana target?Correct comparison semantics
Drift classificationPerbedaan ini missing, unexpected, changed, atau metadata-only?Drift report triage
Changelog generationKapan generate changelog sah digunakan?Bootstrap/adoption changelog
ReconciliationApakah drift harus dihapus, diadopsi, atau dibuat migration baru?Remediation plan
CI integrationKapan diff dijalankan otomatis?Pipeline guardrail
Audit evidenceBagaimana membuktikan schema sesuai intent?Drift evidence bundle

Tujuan latihan bukan membuat banyak generated SQL, tetapi membangun schema truth management.


2. Core Mental Model: Intent vs Reality

Dalam migration system ada tiga objek konseptual:

  • Changelog adalah intent historis.
  • Expected state adalah hasil jika changelog diterapkan bersih.
  • Live database adalah realitas saat ini.
  • Snapshot adalah representasi state yang diamati.
  • Diff adalah perbedaan antara dua state.
  • Drift adalah perbedaan yang tidak dijelaskan oleh intent resmi.

Diff tidak memberi tahu mana yang benar. Diff hanya memberi tahu bahwa state berbeda.


3. Liquibase Inspection Command Families

Beberapa command penting:

CommandFungsi utamaKapan dipakai
snapshotMenghasilkan representasi state databaseAudit, offline compare, baseline evidence
diffMembandingkan dua database/snapshotDrift detection, environment comparison
diff-changelogMembuat changelog untuk menyinkronkan perbedaanAdoption, controlled reconciliation
generate-changelogMembuat changelog dari state database saat iniExisting database onboarding
statusMelihat changeset pendingPipeline readiness
historyMelihat executed changesetAudit/execution review
update-sqlPreview SQL updateDeployment review
future-rollback-sqlPreview SQL rollback untuk pending changesRollback readiness

Pada sistem besar, inspection command sebaiknya menghasilkan artifact yang disimpan, bukan output ephemeral di terminal.


4. Snapshot

Snapshot adalah foto metadata database pada waktu tertentu.

Contoh conceptual command:

liquibase \
  --url="$JDBC_URL" \
  --snapshot-format=json \
  snapshot \
  --output-file=build/liquibase/snapshots/staging-2026-06-28.json

Snapshot berguna untuk:

  • membandingkan database tanpa koneksi langsung ke reference DB,
  • menyimpan evidence state sebelum/after migration,
  • drift detection periodik,
  • onboarding existing database,
  • investigasi incident,
  • audit trail schema.

Namun snapshot bukan source of truth jangka panjang. Snapshot adalah observation.

Snapshot Artifact Policy

ArtifactSimpan?Alasan
Pre-production snapshotYa untuk high-risk releaseEvidence sebelum perubahan
Post-production snapshotYa untuk regulated systemEvidence hasil perubahan
Dev local snapshotTidak wajibNoise tinggi
Golden schema snapshotYaReference untuk diff
Emergency incident snapshotYaForensic analysis

5. Diff Direction: Reference vs Target

Diff direction adalah sumber bug yang sering terjadi.

Dalam Liquibase, comparison umumnya memakai:

  • reference-url: sumber/reference/basis perbandingan,
  • url: target database yang dibandingkan terhadap reference.

Mental model:

reference-url = expected or source of truth
url           = observed or target to evaluate

Contoh:

liquibase diff \
  --reference-url="offline:postgresql?snapshot=golden-schema.json" \
  --url="$PROD_JDBC_URL"

Makna: “Bandingkan production terhadap golden schema.”

Jika dibalik, interpretasi missing/unexpected bisa terbalik.

Direction Example

ObjectGoldenProductionJika golden referenceJika production reference
case_audit tableAdaTidak adaMissing in prodUnexpected in golden
manual_patch_colTidak adaAdaUnexpected in prodMissing in golden

Kesalahan direction bisa membuat remediation salah total.


6. generate-changelog

generate-changelog menciptakan changelog yang menggambarkan current state database.

Penggunaan sehat:

  • onboarding existing database yang belum pernah dikelola Liquibase,
  • membuat baseline changelog awal,
  • reverse-engineering legacy schema untuk mulai migration discipline,
  • menghasilkan dokumentasi awal yang kemudian direview/manual cleanup.

Penggunaan tidak sehat:

  • menggantikan proses authoring migration,
  • menjadikan production state sebagai design tanpa review,
  • meng-commit generated changelog besar tanpa memahami dependency,
  • menjalankan generated changelog ke environment lain tanpa verifikasi,
  • menggunakan generated changelog berulang setiap release.

Existing Database Adoption Flow

Generated changelog harus diperlakukan sebagai draft, bukan kebenaran final.


7. diff-changelog

diff-changelog membandingkan dua database atau snapshot lalu menghasilkan deployable changesets untuk menyinkronkan sebagian besar perbedaan.

Ini berguna untuk:

  • membuat candidate remediation changelog,
  • memahami drift secara structured,
  • menyinkronkan environment controlled,
  • onboarding multi-environment legacy system.

Tetapi output diff-changelog harus direview.

Contoh warning mental:

Generated changelog tells you how to make A look like B.
It does not tell you whether B is the correct design.

Example Use

liquibase diff-changelog \
  --changelog-file=build/liquibase/generated/drift-candidate.yaml \
  --reference-url="offline:postgresql?snapshot=golden-schema.json" \
  --url="$STAGING_JDBC_URL"

Kemudian engineer harus menjawab:

  • Apakah perubahan ini expected?
  • Apakah object missing karena migration belum jalan?
  • Apakah object unexpected karena manual hotfix?
  • Apakah perubahan harus dihapus dari target atau diadopsi ke changelog?
  • Apakah generated order aman?
  • Apakah dependency object lengkap?

8. Drift

Drift adalah perbedaan antara expected database state dan actual database state yang tidak dijelaskan oleh migration intent resmi.

Drift biasanya muncul dari:

  • manual SQL di production,
  • hotfix yang tidak dikembalikan ke changelog,
  • DBA emergency operation,
  • failed/partial migration,
  • environment-specific script,
  • privilege/grant manual,
  • ORM auto-DDL aktif di satu environment,
  • test data atau seed data bercampur dengan reference data,
  • generated objects yang tidak dimodelkan dengan baik,
  • platform upgrade yang mengubah metadata.

Drift Classification

Drift typeContohSeverity
Missing objecttable expected tidak adaHigh
Unexpected objectmanual table ada di prodMedium/High
Changed objectcolumn type/default berbedaHigh
Constraint driftFK/index/unique berbedaHigh
Permission driftgrant berbedaMedium/High
Stored logic driftfunction/procedure berbedaHigh
Sequence driftincrement/cache berbedaMedium
Metadata driftcomment berbedaLow/Medium
Environment drifttablespace/storage berbedaDepends

Jangan semua drift diperlakukan sama. Severity harus dikaitkan dengan runtime behavior, data correctness, security, dan audit impact.


9. Drift Detection Architecture

Di organisasi mature, drift detection adalah kontrol rutin.

Ada dua mode utama:

9.1 Pre-release Drift Check

Sebelum deploy migration baru, cek apakah target environment berada di expected baseline.

Jika target sudah drift, migration baru bisa gagal atau menghasilkan state yang tidak diprediksi.

9.2 Periodic Drift Audit

Jalankan harian/mingguan untuk regulated atau high-criticality database.

Tujuan bukan hanya teknis, tetapi governance:

  • mendeteksi manual change,
  • menjaga release evidence,
  • mengurangi unknown unknowns,
  • mempercepat incident diagnosis.

10. Golden Schema Strategy

Golden schema adalah expected schema yang dihasilkan dari changelog resmi.

Cara membuatnya:

  1. Start empty database dengan engine/version yang sama.
  2. Jalankan seluruh changelog resmi.
  3. Ambil snapshot.
  4. Gunakan snapshot sebagai reference untuk diff terhadap environment lain.
# 1. Create ephemeral DB
# 2. Apply changelog
liquibase \
  --url="$EPHEMERAL_JDBC_URL" \
  --changelog-file=db/changelog/db.changelog-master.yaml \
  update

# 3. Snapshot expected state
liquibase \
  --url="$EPHEMERAL_JDBC_URL" \
  snapshot \
  --snapshot-format=json \
  --output-file=build/liquibase/golden-schema.json

# 4. Compare prod
liquibase diff \
  --reference-url="offline:postgresql?snapshot=build/liquibase/golden-schema.json" \
  --url="$PROD_JDBC_URL"

Golden schema perlu dibuat ulang dari source setiap pipeline. Jangan treat golden snapshot lama sebagai source of truth yang menggantikan changelog.


11. Baseline vs Drift

Baseline dan drift sering tercampur.

SituationMaknaStrategy
Existing DB belum pakai LiquibaseBukan drift; belum ada trackingGenerate baseline, review, adopt
DB punya manual hotfix setelah Liquibase aktifDriftReconcile via changelog atau revert
Staging belum menerima release terbaruVersion skewApply pending migration, bukan drift incident
Production punya index tambahan manualDrift atau approved exceptionAdopt as migration atau document waiver
Dev DB berbeda karena eksperimen lokalLocal noiseReset/recreate dev DB

Drift baru bermakna jika ada expected state yang jelas.


12. Reconciliation Patterns

Saat diff menemukan perbedaan, ada beberapa pilihan.

12.1 Revert Drift

Jika perubahan manual tidak sah dan tidak dipakai, hapus dari target.

- changeSet:
    id: 020-001-remove-manual-debug-table
    author: platform-db
    preConditions:
      onFail: HALT
      - tableExists:
          tableName: debug_case_export
    changes:
      - dropTable:
          tableName: debug_case_export
    rollback:
      - sql:
          sql: |
            -- Not recoverable. Table was manual/debug-only and approved for removal.

12.2 Adopt Drift

Jika perubahan manual ternyata benar dan dibutuhkan, jangan biarkan tetap manual. Jadikan migration resmi.

- changeSet:
    id: 020-002-adopt-prod-index-case-status
    author: platform-db
    preConditions:
      onFail: MARK_RAN
      - not:
          - indexExists:
              indexName: idx_case_status_created_at
              tableName: enforcement_case
    changes:
      - createIndex:
          tableName: enforcement_case
          indexName: idx_case_status_created_at
          columns:
            - column:
                name: status
            - column:
                name: created_at
    rollback:
      - dropIndex:
          tableName: enforcement_case
          indexName: idx_case_status_created_at

MARK_RAN di sini harus dipakai hati-hati. Tujuannya: jika index sudah ada karena manual hotfix yang disetujui, Liquibase menandai changeset sebagai applied agar environment lain bisa converge. Jangan gunakan MARK_RAN untuk menyembunyikan state yang tidak dipahami.

12.3 Waive Drift

Beberapa drift boleh ada karena environment-specific physical concern:

  • tablespace,
  • storage parameter,
  • index fillfactor,
  • partition placement,
  • replication-specific object,
  • monitoring extension.

Waiver harus eksplisit:

allowedDrift:
  - object: index.enforcement_case.idx_case_status_created_at
    field: tablespace
    environment: production
    reason: DBA-managed storage placement
    approvedBy: database-platform-owner
    expires: 2026-12-31

Allowed drift tanpa expiry berubah menjadi hidden debt.


13. What Diff May Miss or Misrepresent

Diff tooling kuat, tetapi tidak sempurna.

Hal yang perlu diwaspadai:

  • type alias antar database,
  • default expression formatting,
  • computed/generated column syntax,
  • function body formatting,
  • object dependency order,
  • extension-owned objects,
  • privileges/grants support berbeda,
  • collation/charset nuance,
  • index method/vendor-specific option,
  • partitioning detail,
  • trigger/function coupling,
  • data type length/detail tertentu tergantung database support,
  • semantic equivalence yang tidak tampak dari metadata.

Karena itu output diff harus direview oleh engineer yang paham domain dan database engine.


14. Diff in CI/CD

Minimal pipeline untuk Liquibase drift-aware delivery:

CI Checks

CheckPurpose
Apply from scratchChangelog complete
Apply from previous release snapshotUpgrade path valid
statusPending changes known
update-sqlSQL review artifact
future-rollback-sqlRollback review artifact
Snapshot expected schemaGolden reference
Diff target before deployDetect target drift
Diff target after deployVerify convergence

15. Environment Comparison Patterns

15.1 Dev vs Changelog

Purpose: catch local accidental changes.

Action: usually reset dev DB.

15.2 Staging vs Golden

Purpose: ensure staging is production rehearsal.

Action: block release if staging drift unexplained.

15.3 Production vs Golden

Purpose: governance and safety.

Action: raise drift ticket/incident depending severity.

15.4 Production vs Production Replica

Purpose: ensure replicated/region-specific database is aligned.

Action: investigate replication/deployment inconsistency.

15.5 Tenant A vs Tenant B

Purpose: multi-tenant schema convergence.

Action: tenant-level repair/migration fan-out.


16. Multi-Tenant Drift

Dalam tenant-per-schema atau tenant-per-database model, drift bisa terjadi sebagian.

Contoh:

TenantVersionDriftAction
tenant_a2026.06.28.1noneOK
tenant_b2026.06.28.1missing indexRepair targeted
tenant_c2026.06.27.2version skewApply pending migration
tenant_dunknownmanual objectInvestigate

Untuk multi-tenant, jangan hanya punya satu status global. Simpan tenant migration state:

CREATE TABLE tenant_schema_state (
    tenant_id        varchar(100) primary key,
    schema_name      varchar(100) not null,
    target_version   varchar(100) not null,
    current_version  varchar(100),
    drift_status     varchar(30) not null,
    last_checked_at  timestamp not null,
    last_error       text
);

Diff semua tenant setiap deploy mungkin mahal. Gunakan sampling + targeted check + periodic full audit.


17. Drift Severity Model

Severity harus praktis.

SeverityMeaningExampleResponse
0No driftNoneContinue
1Cosmetic metadataComment differsRecord/ignore
2Non-runtime physical diffTablespace differsWaiver/review
3Performance-impactingMissing indexFix before high traffic
4Correctness/security riskMissing FK/grant driftBlock release
5Active production dangerWrong column type, missing tableIncident response

Severity bukan hanya “berapa banyak object berbeda”. Satu missing constraint bisa lebih berbahaya daripada 100 comment differences.


18. Audit Evidence Bundle

Untuk regulated systems, simpan evidence berikut:

drift-evidence/
  changelog-commit-sha.txt
  liquibase-version.txt
  jdbc-driver-version.txt
  expected-schema-snapshot.json
  target-schema-snapshot.json
  diff-output.txt
  diff-changelog-candidate.yaml
  classification.md
  allowed-drift-waivers.yaml
  remediation-plan.md
  approval.md
  post-remediation-diff.txt

Evidence ini menjawab:

  • schema expected berasal dari commit mana,
  • target database state pada waktu apa,
  • perbedaan apa yang ditemukan,
  • siapa mengklasifikasi drift,
  • apakah perbedaan dihapus, diadopsi, atau di-waive,
  • apakah remediation berhasil.

19. Anti-Patterns

19.1 Production-as-Source-of-Truth

Generate changelog dari production lalu menganggapnya benar.

Perbaikan: production adalah observation, changelog adalah intent.

19.2 Blind Diff-Changelog Deploy

Menjalankan output diff-changelog langsung ke production.

Perbaikan: treat output sebagai draft candidate, review dependency dan semantics.

19.3 Wrong Diff Direction

Reference dan target tertukar sehingga missing/unexpected dibaca terbalik.

Perbaikan: tulis eksplisit di pipeline: expected -> actual.

19.4 Ignoring Manual Hotfix

Manual hotfix dilakukan di production tetapi tidak diadopsi ke changelog.

Perbaikan: every manual DB change must end as official migration or documented rollback.

19.5 Drift Report tanpa Owner

Pipeline menghasilkan report tetapi tidak ada yang bertanggung jawab.

Perbaikan: assign drift severity owner and SLA.

19.6 Treating All Drift as Equal

Comment drift dan missing FK diperlakukan sama.

Perbaikan: severity classification.

19.7 Generated Baseline Tanpa Cleanup

Generated changelog dari legacy schema langsung dipakai.

Perbaikan: normalize, split, review, test from scratch, diff back to original.


20. Practice Drills

Drill 1 — Existing Database Onboarding

Ambil database legacy kecil, jalankan generate-changelog, lalu review output. Tandai minimal 10 hal yang perlu cleanup sebelum changelog dianggap production-grade.

Drill 2 — Diff Direction

Buat dua database:

  • DB A punya table case_note,
  • DB B tidak punya table tersebut.

Jalankan diff dua arah. Jelaskan bagaimana interpretasi missing/unexpected berubah.

Drill 3 — Manual Hotfix Adoption

Tambahkan index manual di staging. Jalankan diff terhadap golden schema. Buat remediation changeset yang mengadopsi index secara resmi tanpa gagal di staging yang sudah punya index.

Drill 4 — Drift Severity

Buat daftar 20 drift dari sistem imajiner regulatory case management. Klasifikasikan severity 0-5 dan tulis response playbook.

Drill 5 — Golden Schema Pipeline

Bangun pipeline lokal:

  1. start PostgreSQL Testcontainers,
  2. apply Liquibase changelog,
  3. snapshot expected schema,
  4. mutate database manual,
  5. run diff,
  6. fail build jika drift severity tinggi.

21. Summary

Liquibase diff, snapshot, generate-changelog, dan drift detection adalah alat untuk menjaga alignment antara migration intent dan live database reality.

Prinsip utamanya:

  • changelog adalah source of intent,
  • live DB adalah observed reality,
  • snapshot adalah evidence,
  • diff adalah sensor,
  • drift adalah unexplained divergence,
  • generated changelog adalah draft,
  • production state tidak otomatis benar,
  • reconciliation harus dipilih: revert, adopt, waive, atau investigate,
  • drift detection tanpa owner hanya noise,
  • CI/CD harus membandingkan expected vs actual sebelum dan sesudah deploy.

Engineer yang matang tidak hanya menjalankan migration. Ia menjaga agar database tetap dapat dijelaskan.


References

Lesson Recap

You just completed lesson 20 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.