Rekonsiliasi Data: Membuktikan Migrasi Anda Berjalan dengan Benar

Anda baru saja menyelesaikan migrasi data. Skrip berjalan tanpa error. Log terlihat bersih. Tim siap melanjutkan. Tapi di dalam hati, ada perasaan was-was: apakah semuanya benar-benar berfungsi? Apakah setiap baris berhasil dipindahkan? Apakah ada nilai yang diam-diam rusak?

Inilah momen di mana sebagian besar tim menyadari bahwa migrasi yang sukses belum tentu migrasi yang benar. Sebuah skrip bisa selesai dengan kode keluar nol dan tetap menghasilkan data yang salah. Sebuah filter mungkin mengecualikan baris yang seharusnya disertakan. Konversi tipe data mungkin memotong nilai tanpa memunculkan error. Database tidak akan memberi tahu Anda tentang masalah ini kecuali Anda secara eksplisit bertanya.

Itulah mengapa rekonsiliasi ada. Ini adalah proses membandingkan data sebelum dan sesudah migrasi untuk membuktikan bahwa tidak ada data yang hilang, berubah, atau rusak. Ini adalah pemeriksaan terakhir sebelum Anda menyatakan migrasi selesai.

Mengapa Skrip Bebas Error Tidak Cukup

Kebenaran yang tidak mengenakkan tentang migrasi data adalah bahwa kebenaran dan eksekusi bebas error adalah dua hal yang berbeda. Sebuah skrip migrasi dapat berjalan sempurna dari segi teknis namun tetap menghasilkan hasil yang salah.

Pertimbangkan skenario umum: Anda memigrasi tabel dengan klausa WHERE yang memfilter pengguna tidak aktif. Skrip berjalan, baris berhasil dimasukkan, dan tabel lama dinonaktifkan. Berminggu-minggu kemudian, seseorang menyadari bahwa sekelompok pengguna aktif hilang. Filter terlalu agresif, atau kondisinya salah. Skrip tidak pernah gagal, tetapi datanya salah.

Error di log tidak menangkap masalah semacam ini. Mesin database tidak tahu bahwa baris yang hilang adalah sebuah kesalahan. Mesin hanya tahu bahwa pernyataan INSERT berhasil dieksekusi. Satu-satunya cara untuk menangkap kegagalan diam-diam ini adalah dengan membandingkan data sumber dengan data target secara langsung.

Pendekatan Praktis untuk Rekonsiliasi

Rekonsiliasi tidak perlu rumit. Metode paling sederhana dan efektif adalah perbandingan checksum. Alih-alih melakukan checksum pada file, Anda melakukan checksum pada kumpulan data (batch).

Berikut cara kerjanya untuk migrasi tabel:

  1. Baca satu batch baris dari tabel sumber.
  2. Hitung hash dari seluruh batch (misalnya, menggunakan MD5 atau SHA256 atas gabungan semua nilai kolom).
  3. Baca batch yang sama dari tabel target menggunakan urutan yang sama dan hitung hash yang sama.
  4. Bandingkan kedua hash tersebut.

Jika hash cocok, batch tersebut identik. Jika tidak, Anda tahu persis batch mana yang bermasalah, dan Anda dapat menyelidiki rentang baris tertentu.

Untuk tabel besar, pemrosesan dalam batch sangat penting. Anda tidak ingin memuat jutaan baris ke dalam memori sekaligus. Ukuran batch 1.000 hingga 10.000 baris biasanya bekerja dengan baik untuk sebagian besar database. Anda dapat menjalankan perbandingan ini secara paralel di beberapa batch untuk mempercepat proses.

Diagram alur berikut mengilustrasikan proses rekonsiliasi batch demi batch:

flowchart TD A[Mulai] --> B[Ekstrak batch dari tabel sumber] B --> C[Hitung hash batch] C --> D[Ekstrak batch yang sama dari tabel target] D --> E[Hitung hash batch] E --> F{Bandingkan hash} F -- Cocok --> G[Tandai batch sebagai terverifikasi] F -- Tidak cocok --> H[Tandai batch untuk investigasi] G --> I{Ada batch lain?} H --> I I -- Ya --> B I -- Tidak --> J[Bandingkan jumlah baris] J --> K{Jumlah baris cocok?} K -- Ya --> L[Hasilkan laporan: migrasi terverifikasi] K -- Tidak --> M[Tandai perbedaan dan investigasi] L --> N[Selesai] M --> N

Berikut adalah kueri SQL konkret yang mengimplementasikan pendekatan ini untuk dua tabel:

-- Bandingkan jumlah baris dan checksum antara tabel sumber dan target
WITH source_checksums AS (
    SELECT
        COUNT(*) AS row_count,
        MD5(STRING_AGG(CAST(column1 AS TEXT) || '|' || CAST(column2 AS TEXT) || '|' || CAST(column3 AS TEXT), ',' ORDER BY id)) AS batch_hash
    FROM source_table
),
target_checksums AS (
    SELECT
        COUNT(*) AS row_count,
        MD5(STRING_AGG(CAST(column1 AS TEXT) || '|' || CAST(column2 AS TEXT) || '|' || CAST(column3 AS TEXT), ',' ORDER BY id)) AS batch_hash
    FROM target_table
)
SELECT
    'Jumlah baris tidak cocok' AS masalah
FROM source_checksums, target_checksums
WHERE source_checksums.row_count <> target_checksums.row_count
UNION ALL
SELECT
    'Checksum tidak cocok' AS masalah
FROM source_checksums, target_checksums
WHERE source_checksums.batch_hash <> target_checksums.batch_hash;

Kueri ini menghitung satu checksum untuk semua baris di setiap tabel (menggunakan urutan yang stabil) dan membandingkan jumlah baris serta hash-nya. Jika salah satu berbeda, kueri akan mengembalikan indikasi yang jelas tentang apa yang salah.

Apa Lagi yang Perlu Diperiksa Selain Checksum

Checksum menangkap sebagian besar masalah, tetapi bukan satu-satunya hal yang harus Anda verifikasi. Beberapa pemeriksaan tambahan menambah keyakinan tanpa banyak usaha ekstra.

Jumlah baris. Ini adalah pemeriksaan paling sederhana. Jumlah baris di tabel target harus sesuai dengan jumlah baris di tabel sumber. Jika jumlahnya berbeda, ada yang salah dengan logika migrasi.

Nilai null. Migrasi terkadang mengubah kolom null menjadi nilai default atau sebaliknya. Bandingkan jumlah null per kolom antara sumber dan target. Ketidakcocokan di sini sering kali mengindikasikan masalah konversi tipe atau batasan nilai default yang diterapkan secara tidak benar.

Distribusi nilai. Pilih beberapa kolom penting dan bandingkan distribusi nilainya. Misalnya, jika tabel sumber memiliki 1.000 pengguna dengan status "aktif" dan 500 dengan status "tidak aktif," tabel target harus memiliki angka yang sama. Perbedaan signifikan menunjukkan bahwa filter migrasi atau logika transformasi memiliki bug.

Kasus tepi. Uji baris tertentu yang dikenal rumit: baris dengan karakter khusus, string yang sangat panjang, tanggal mendekati batas, atau angka negatif. Jika migrasi Anda menangani ini dengan benar, itu pertanda baik bahwa logika umumnya sudah tepat.

Menjadikan Rekonsiliasi Bagian dari Pipeline Anda

Rekonsiliasi tidak boleh menjadi tugas manual satu kali yang diingat seseorang untuk dijalankan setelah migrasi larut malam. Ini harus diotomatisasi dan diintegrasikan ke dalam pipeline deployment Anda.

Tulis skrip rekonsiliasi yang berjalan setelah langkah migrasi dan backfill selesai. Skrip harus:

  • Terhubung ke database sumber dan target.
  • Menjalankan perbandingan checksum per batch.
  • Memeriksa jumlah baris, jumlah null, dan distribusi nilai.
  • Menghasilkan laporan detail tentang ketidakcocokan.
  • Mengirim notifikasi (email, Slack, atau apa pun yang digunakan tim Anda) dengan hasilnya.

Jika rekonsiliasi berhasil, pipeline dapat melanjutkan ke langkah berikutnya. Jika gagal, pipeline harus berhenti dan memberi tahu tim. Ini mencegah data yang salah mencapai produksi tanpa ada yang menyadarinya.

Mengotomatiskan rekonsiliasi juga membuatnya dapat diulang. Setiap migrasi melalui proses verifikasi yang sama. Anda tidak perlu mengandalkan seseorang yang ingat menjalankan skrip atau memeriksa hal yang benar. Pipeline yang menegakkannya.

Apa yang Bukan Rekonsiliasi

Rekonsiliasi bukanlah pengganti untuk dry run atau strategi backfill. Setiap langkah memiliki tujuan yang berbeda.

  • Dry run memverifikasi bahwa logika migrasi berfungsi tanpa memengaruhi data produksi.
  • Backfill menangani transfer data aktual dalam potongan yang mudah dikelola untuk meminimalkan dampak.
  • Rekonsiliasi membuktikan bahwa backfill menghasilkan hasil yang benar.

Anggap rekonsiliasi sebagai gerbang kualitas akhir. Ini mengonfirmasi bahwa semua langkah sebelumnya berfungsi sebagaimana mestinya. Jika rekonsiliasi berhasil, Anda dapat yakin bahwa data sudah siap. Jika gagal, Anda kembali, perbaiki masalah, dan jalankan ulang migrasi dari awal.

Daftar Periksa Rekonsiliasi Praktis

Saat Anda menyiapkan rekonsiliasi untuk migrasi berikutnya, berikut adalah daftar periksa singkat untuk memandu Anda:

  • Perbandingan checksum per batch (1.000-10.000 baris per batch)
  • Kecocokan jumlah baris antara sumber dan target
  • Kecocokan jumlah null per kolom
  • Kecocokan distribusi nilai untuk kolom kunci
  • Verifikasi kasus tepi (karakter khusus, nilai batas)
  • Skrip otomatis terintegrasi ke dalam pipeline
  • Notifikasi saat gagal dengan laporan ketidakcocokan detail

Intisari

Migrasi belum selesai sampai Anda membuktikan bahwa data benar. Eksekusi bebas error tidaklah cukup. Rekonsiliasi memberi Anda bukti itu dengan membandingkan data sumber dan target secara langsung. Otomatiskan, jalankan setiap saat, dan perlakukan rekonsiliasi yang gagal sama seperti Anda memperlakukan tes yang gagal: berhenti, selidiki, dan perbaiki sebelum melanjutkan.