Chapter sebelumnya meninggalkan kita dengan satu fakta penting: source membalas aplikasi lebih dulu, replica mengejar belakangan. Selisih waktu antara “data berubah di source” dan “perubahan itu diterapkan di replica” bernama replication lag, dan satu angka — Seconds_Behind_Source — menjadi denyut nadi yang dipantau operator setiap hari. Lag yang sehat tak terasa oleh pengguna; lag yang memburuk diam-diam membuat aplikasi membaca data basi, mengecewakan pelanggan yang barusan mengubah profilnya, dan menunda kesiapan failover. Chapter ini membedah cara lag terukur, lima penyebab utamanya, dan strategi mitigasinya.
Bagaimana Lag Diukur #
Seconds_Behind_Source dihitung dengan cara yang sederhana namun cerdik: setiap event di binary log membawa timestamp saat event itu dieksekusi di source. Replica membandingkan timestamp event yang sedang diproses dengan jam replica sendiri — selisihnya itulah Seconds_Behind_Source. Baca 0 berarti replica sedang memproses event yang umurnya di bawah satu detik; baca NULL berarti IO thread mati — replica bahkan tidak tahu kondisi source, sehingga lag “tak terhingga”. Angka ini selalu dilihat berpasangan dengan Replica_IO_Running/Replica_SQL_Running, karena angka 5 detik pada thread yang hidup jauh lebih menenangkan daripada 5 detik yang beku selama sejam.
Kita tidak bisa mengukur lag sungguhan di server uji (tidak ada pasangan source-replica), tetapi kita bisa membangun tabel pemantauan mini semacam yang dikumpulkan tool monitoring dari SHOW REPLICA STATUS:
DROP DATABASE IF EXISTS belajar_repl;
CREATE DATABASE belajar_repl;
USE belajar_repl;
CREATE TABLE monitor_lag (
host VARCHAR(30) NOT NULL,
seconds_behind_source INT NOT NULL,
diperiksa_pada DATETIME NOT NULL
);
INSERT INTO monitor_lag (host, seconds_behind_source, diperiksa_pada) VALUES
('replica-1', 0, '2026-03-01 10:00:00'),
('replica-2', 4, '2026-03-01 10:00:00'),
('replica-3', 27, '2026-03-01 10:00:00');Output yang Dihasilkan:
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Database changed
Query OK, 0 rows affected (0.00 sec)
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0Tiga replica, tiga kondisi kesehatan. Query berikut meniru keputusan router aplikasi: replica mana yang layak menerima bacaan:
SELECT host, seconds_behind_source,
IF(seconds_behind_source <= 1, 'sehat', 'perlu perhatian') AS status
FROM monitor_lag
ORDER BY seconds_behind_source;Output yang Dihasilkan:
+-----------+-----------------------+-----------------+
| host | seconds_behind_source | status |
+-----------+-----------------------+-----------------+
| replica-1 | 0 | sehat |
| replica-2 | 4 | perlu perhatian |
| replica-3 | 27 | perlu perhatian |
+-----------+-----------------------+-----------------+
3 rows in set (0.00 sec)replica-1 dengan lag 0 layak menerima bacaan apa pun; replica-3 dengan lag 27 detik sebaiknya disingkirkan dari rotasi sampai pulih. Tabel kecil ini sekaligus menjadi kerangka alarm: pantau nilai terbesar, bukan rata-rata — rata-rata bisa tampak cantik sementara satu replica sekarat.
Lima Penyebab Utama Lag #
Lag lahir dari ketidakseimbangan antara kecepatan source menghasilkan event dan kecepatan replica menerapkannya. Penyebabnya bisa dikelompokkan menjadi lima:
| Penyebab | Mekanisme |
|---|---|
| Applier satu-thread (klasik) | SQL thread menjalankan event satu per satu — tulisan paralel di source mengantri |
| Batch raksasa | Satu UPDATE/DELETE jutaan baris = satu event raksasa yang butuh menit untuk diterapkan |
| Query berat di replica | Laporan analitik panjang mengunci baris/metadata yang sedang dibutuhkan applier |
| Jaringan & disk replica | Event datang lambat, atau relay log ditulis/dibaca di disk yang sesak |
| Lonjakan tulis di source | Import massal, INSERT ... SELECT besar, atau batch ETL mendadak |
Penyebab pertama patut dibedah khusus karena paling sering disalahpahami. Selama bertahun-tahun SQL thread memang satu-satunya pekerja di sisi replica — sekuat apapun server, event tetap diproses berurutan. MySQL modern menjawabnya dengan multithreaded applier: sejumlah worker menerapkan event secara paralel dalam batas aman (transaksi yang menyentuh baris sama tetap dijaga urutannya). Jumlah worker-nya dikendalikan variabel replica_parallel_workers:
SHOW VARIABLES LIKE 'replica_parallel_workers';Output yang Dihasilkan:
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| replica_parallel_workers | 4 |
+--------------------------+-------+
1 row in set (0.00 sec)Nilai 4 di server uji kita (bawaan MySQL 8.4) berarti applier siap memakai empat worker paralel saat replikasi aktif — sebagian beban penyebab nomor satu di atas sudah terurai secara bawaan. Yang tidak bisa diurai paralel adalah satu event raksasa itu sendiri: satu UPDATE 20 juta baris tetap satu pekerjaan tunggal, dan lag melejit sepanjang event itu berjalan di replica.
Dampak: Baca Basi dan Masalah Read-Your-Writes #
Lag paling terasa bukan di dashboard operator, melainkan di layar pengguna. Pola kejadiannya khas dan berulang di banyak aplikasi: pengguna menyimpan perubahan profil (tulis ke source), halaman langsung dimuat ulang (baca dari replica), dan yang tampil adalah data lama karena event perubahan belum sampai. Pengguna menyimpan ulang, mengira fiturnya rusak, lalu menghubungi support — padahal satu-dua detik kemudian datanya sudah benar di replica. Fenomena ini disebut pelanggaran read-your-writes: pihak yang menulis berhak membaca kembali tulisannya sendiri, tetapi konsistensi eventual replikasi mengingkarinya untuk sementara.
Kita buktikan polanya dengan simulasi satu server yang kini memakai pasangan tabel pelanggan_source/pelanggan_replica:
CREATE TABLE pelanggan_source (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(30) NOT NULL,
email VARCHAR(50) NOT NULL
);
INSERT INTO pelanggan_source (nama, email) VALUES
('Budi', '[email protected]'),
('Siti', '[email protected]'),
('Andi', '[email protected]');
CREATE TABLE pelanggan_replica LIKE pelanggan_source;
INSERT INTO pelanggan_replica SELECT * FROM pelanggan_source;Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.00 sec)
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0Budi sekarang mengganti alamat emailnya — transaksi ini sampai ke source saja, dan aplikasi seketika membaca ulang profil Budi dari replica:
UPDATE pelanggan_source SET email = '[email protected]' WHERE id = 1;
SELECT 'source' AS dibaca_dari, id, nama, email FROM pelanggan_source WHERE id = 1
UNION ALL
SELECT 'replica', id, nama, email FROM pelanggan_replica WHERE id = 1
ORDER BY dibaca_dari;Output yang Dihasilkan:
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
+-------------+----+------+--------------------------+
| dibaca_dari | id | nama | email |
+-------------+----+------+--------------------------+
| replica | 1 | Budi | [email protected] |
| source | 1 | Budi | [email protected] |
+-------------+----+------+--------------------------+
2 rows in set (0.00 sec)Dua baris, dua isi: source sudah menyimpan [email protected], replica masih menampilkan [email protected] — inilah baca basi yang dilihat pengguna. Setelah SQL thread replica menyelesaikan event (di sini kita terapkan sendiri perannya), bacaan menjadi konsisten:
UPDATE pelanggan_replica SET email = '[email protected]' WHERE id = 1;
SELECT 'source' AS dibaca_dari, id, nama, email FROM pelanggan_source WHERE id = 1
UNION ALL
SELECT 'replica', id, nama, email FROM pelanggan_replica WHERE id = 1
ORDER BY dibaca_dari;Output yang Dihasilkan:
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
+-------------+----+------+--------------------------+
| dibaca_dari | id | nama | email |
+-------------+----+------+--------------------------+
| replica | 1 | Budi | [email protected] |
| source | 1 | Budi | [email protected] |
+-------------+----+------+--------------------------+
2 rows in set (0.00 sec)Kapan Angka Lag Menipu #
Seconds_Behind_Source mengukur umur event yang sedang diproses, dan definisi itu punya dua lubang. Pertama, transaksi panjang: sebuah transaksi yang berjalan 300 detik di source menghasilkan event dengan timestamp awal — saat replica baru mulai memprosesnya, Seconds_Behind_Source langsung meloncat ke ratusan detik meskipun replica sesungguhnya hanya tertinggal sedikit. Kedua, kemungkinan clock skew: replica yang jamnya lebih cepat dari source bisa melaporkan lag negatif-imajiner, sebaliknya jam yang telat menggelembungkan angkanya. Karena itu tool eksternal seperti pt-heartbeat (dari Percona Toolkit) menjadi standar pemantauan serius: tool ini menulis timestamp ke sebuah tabel melalui source sungguhan dan membacanya di replica, sehingga mengukur lag ujung-ke-ujung tanpa bergantung pada jam yang diselaraskan sempurna.
Strategi Mitigasi #
Mitigasi lag selalu berdimensi dua: kurangi lajunya, dan lindungi pengguna dari sisanya. Daftar berikut urut dari yang paling berdampak:
- Session routing kritis ke source. Bacaan yang mengikuti tulisan pengguna yang sama (read-your-writes) diarahkan ke source atau ke replica yang lag-nya nol — keputusan routing berbasis session, bukan acak.
- Naikkan
replica_parallel_workerspada replica yang applier-nya jadi leher botol, dan pastikan beban tulis di source memang bisa diparalelkan. - Pecah batch raksasa menjadi potongan-potongan ribuan baris dengan jeda — lag tetap naik tetapi tidak sampai menit-puluhan menit.
- Isolasi analitik di replica lain (topologi bercabang — chapter Read Replicas) agar query laporan tidak berebut kunci dengan applier.
- Tuning disk & jaringan replica — relay log di disk tercepat, koneksi source-replica di jalur low-latency.
Sebagai angka acuan sehat yang lazim dipakai: lag di bawah 1 detik tergolong prima, beberapa detik masih wajar untuk beban normal, puluhan detik sudah area investigasi, dan menit penuh berarti replica tengah kritis — biasanya karena satu event raksasa atau satu thread yang mati.
Membersihkan Database Latihan #
DROP DATABASE belajar_repl;Output yang Dihasilkan:
Query OK, 3 rows affected (0.00 sec)Referensi #
- Replication Implementation — MySQL 8.4 Reference Manual
- Replication Solutions — MySQL 8.4 Reference Manual
- Replication Administration — MySQL 8.4 Reference Manual
Lag kini bukan lagi angka magis: kita tahu dari mana angka itu lahir, kapan ia berbohong, dan bagaimana melindungi pengguna dari bisikannya. Pemahaman ini membuka pintu babak besar berikutnya — memakai replica secara sengaja sebagai mesin baca yang terpisah dari source. Chapter Read Replicas menyusun pola routing baca, topologi bercabang dan berantai, serta batas kapan pola ini berhenti membantu.