Sepanjang course ini kita selalu bekerja dengan satu server MySQL yang menyimpan seluruh data aplikasi. Arsitektur sesederhana itu memiliki tiga kelemahan serius: server tersebut menjadi single point of failure — satu kerusakan disk atau satu kegagalan proses membuat seluruh layanan mati, seluruh laporan berat berbagi sumber daya dengan transaksi pelanggan, dan satu-satunya peluang pemulihan hanyalah file backup terakhir. MySQL menjawab masalah tersebut dengan fitur replication: server kedua (dan ketiga, keempat, …) menjaga salinan data yang terus diperbarui setiap kali data di server utama berubah. Chapter ini membangun fondasi konsep replication — arsitektur dasarnya, istilah resminya, manfaatnya, dan batas cakupannya — sebelum chapter berikutnya membawa kita ke perintah-perintah konfigurasinya.

Tiga Masalah yang Dijawab Replication #

Sebelum membicarakan solusi, mari kita perinci tiga masalah server tunggal dengan sudut pandang operasional. Pertama, ketersediaan (high availability): ketika server tunggal mati, tidak ada server lain yang siap menggantikan peran, sehingga aplikasi berhenti total sampai server dinyalakan atau dipulihkan dari backup. Kedua, skala baca: aplikasi nyata hampir selalu melakukan jauh lebih banyak SELECT daripada INSERT/UPDATE — katalog produk, daftar pesanan, laporan harian — dan seluruh beban baca itu menumpuk pada satu mesin yang sama yang juga harus menerima tulisan. Ketiga, pemulihan bencana (disaster recovery): backup yang disimpan di mesin yang sama dengan server produksi ikut lenyap bersama server tersebut ketika disk rusak.

Replication mengatasi ketiganya dengan satu mekanisme: setiap perubahan data di server utama dicatat dan dikirim ke server lain, sehingga selalu tersedia lebih dari satu mesin yang memuat data yang (hampir) sama. Tabel berikut merangkum keterkaitan masalah dan manfaatnya:

Masalah server tunggalManfaat replication
Single point of failureAda server cadangan yang datanya mutakhir — dasar failover
Beban baca menumpukQuery SELECT bisa disebarkan ke beberapa replica
Backup berat membebani serverBackup diambil dari replica, source tetap ringan
Laporan/analitik berat mengganggu transaksiAnalitik dijalankan di replica terpisah
Bencana satu lokasi/regionReplica di lokasi geografis berbeda

Ide Dasar: Salin Perubahan, Bukan Salin Seluruh Data Berulang Kali #

Cara paling naif untuk menjaga dua server tetap sama adalah menyalin seluruh database berulang kali — seperti mysqldump penuh setiap menit. Pendekatan itu boros: 99% data tidak berubah antar-dua salinan, tetapi tetap dipindahkan. Replication bekerja jauh lebih cerdas karena MySQL sudah mencatat setiap perubahan ke sebuah file bernama binary log (kita akan mengenalnya lebih dalam di section Backup dan Recovery). Server utama — disebut source — menuliskan event perubahan (INSERT, UPDATE, DELETE, hingga ALTER TABLE) ke binary log-nya; server pengikut — disebut replica — menarik event tersebut, menyimpannya sementara di relay log, lalu menjalankan ulang event demi event sehingga datanya berubah mengikuti source.

Arus tersebut berjalan terus-menerus dan otomatis, bukan sekali jalan seperti dump:

Perhatikan arah panah nomor 2: replica-lah yang aktif mengambil event dari source (istilah teknisnya pull), bukan source yang mendorongnya. Konsekuensi desain ini akan kita bedah tuntas di chapter Asynchronous Replication, karena source tidak menunggu replica selesai — komitmen transaksi di source sudah selesai sebelum event sampai ke replica.

Istilah Baru: Source dan Replica #

Selama lebih dari dua dekade dokumentasi MySQL memakai istilah master dan slave; sejak MySQL 8.0.24 istilah resmi diganti menjadi source dan replica, dan seluruh perintah ikut berganti nama: CHANGE MASTER TO menjadi CHANGE REPLICATION SOURCE TO, START SLAVE menjadi START REPLICA, SHOW SLAVE STATUS menjadi SHOW REPLICA STATUS. Istilah lama sempat berstatus deprecated beberapa versi, lalu di MySQL 8.4 alias lama tersebut dihapus sama sekali. Server uji kita memakai MySQL 8.4, jadi kita bisa membuktikan penghapusan itu secara nyata:

sql
-- @error
SHOW SLAVE STATUS;

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SLAVE STATUS' at line 1
Bye

Server menolak perintah lama dengan ERROR 1064 — error sintaks — karena bagi MySQL 8.4 frasa SLAVE STATUS sudah bukan perintah yang dikenal. Versi barunya, SHOW REPLICA STATUS, adalah satu-satunya bentuk yang valid di 8.4; kita akan sering memakainya di chapter-chapter selanjutnya.

Apa yang Direplikasi dan Apa yang Tidak #

Yang direplikasi adalah setiap perubahan yang tertulis ke binary log source: DML (INSERT, UPDATE, DELETE), DDL (CREATE, ALTER, DROP), dan perubahan objek seperti user dan privilege yang dibuat lewat perintah CREATE USER/GRANT. Sebaliknya, SELECT tidak pernah masuk binary log — query baca tidak menghasilkan perubahan, jadi tidak ada yang perlu disalin; inilah sebabnya replikasi tidak menambah beban jaringan hanya karena replica banyak membaca. Server juga menyediakan filter (binlog_ignore_db di sisi source, replicate_ignore_db/replicate_ignore_table di sisi replica) untuk mengecualikan database atau tabel tertentu dari penyalinan — berguna untuk mengisolasi database staging yang sering di-TRUNCATE.

Dua hal penting juga perlu dicatat. Pertama, binlog merekam perubahan, bukan keadaan: replica menerima urutan event dan menjalankannya, sehingga replica ideal memulai dari salinan awal yang sama lalu mengikuti alur event. Kedua, tidak semua objek internal terrepikasi secara penuh — misalnya tabel temporary dan metadata internal tidak dibawa, dan isi database sistem seperti performance_schema tidak pernah disalin.

Lingkungan Belajar Kita: Satu Server, Binary Log Mati #

Replication membutuhkan minimal dua server yang berjalan bersamaan. Server uji course ini hanya satu instance MySQL 8.4 dan — demi ringan — dijalankan dengan opsi --skip-log-bin, sehingga binary lognya tidak aktif. Kita periksa dulu dua variabel yang menjadi prasyarat replication:

sql
SELECT @@log_bin AS log_bin, @@server_id AS server_id;

Output yang Dihasilkan:

text
+---------+-----------+
| log_bin | server_id |
+---------+-----------+
|       0 |         1 |
+---------+-----------+
1 row in set (0.00 sec)

Nilai log_bin bernilai 0 (binary log nonaktif) dan server_id masih nilai bawaan 1. Di server produksi yang akan menjadi source, kedua nilai ini harus diubah lewat file konfigurasi my.cnf — pekerjaan yang kita lakukan penuh di chapter berikutnya. Meski begitu, satu server ternyata cukup untuk memvisualkan ide replication dengan meniru secara manual apa yang replica lakukan: menyalin data lalu mengejar perubahan. Kita siapkan tabel kecil di database latihan belajar_repl:

sql
DROP DATABASE IF EXISTS belajar_repl;
CREATE DATABASE belajar_repl;
USE belajar_repl;

Output yang Dihasilkan:

text
Query OK, 0 rows affected, 1 warning (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
sql
CREATE TABLE pesanan (
  id INT AUTO_INCREMENT PRIMARY KEY,
  pelanggan VARCHAR(30) NOT NULL,
  kota VARCHAR(20) NOT NULL,
  total DECIMAL(10,2) NOT NULL
);

INSERT INTO pesanan (pelanggan, kota, total) VALUES
  ('Budi', 'Jakarta', 55000.00),
  ('Siti', 'Bandung', 25000.00),
  ('Andi', 'Surabaya', 62000.00);

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

Tabel pesanan berperan sebagai “data di source”. Kita buat salinannya — peran replica — dengan struktur yang sama persis lalu mengisi seluruh isinya, meniru langkah salinan awal (di dunia nyata: restore mysqldump di server replica):

sql
CREATE TABLE pesanan_salinan LIKE pesanan;
INSERT INTO pesanan_salinan SELECT * FROM pesanan;
SELECT
  (SELECT COUNT(*) FROM pesanan) AS baris_source,
  (SELECT COUNT(*) FROM pesanan_salinan) AS baris_replica;

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

+--------------+---------------+
| baris_source | baris_replica |
+--------------+---------------+
|            3 |             3 |
+--------------+---------------+
1 row in set (0.00 sec)

Kedua tabel berisi tiga baris — kondisi “replica mutakhir”. Sekarang kita simulasikan transaksi baru yang hanya terjadi di source:

sql
INSERT INTO pesanan (pelanggan, kota, total) VALUES ('Dewi', 'Yogyakarta', 15000.00);
SELECT
  (SELECT COUNT(*) FROM pesanan) AS baris_source,
  (SELECT COUNT(*) FROM pesanan_salinan) AS baris_replica;

Output yang Dihasilkan:

text
Query OK, 1 row affected (0.00 sec)

+--------------+---------------+
| baris_source | baris_replica |
+--------------+---------------+
|            4 |             3 |
+--------------+---------------+
1 row in set (0.00 sec)

Salinan manual langsung tertinggal: source berisi empat baris, salinan masih tiga. Pada replication sungguhan, pekerjaan “mengantar baris keempat ke replica” dilakukan otomatis oleh event binary log yang ditarik dan dijalankan ulang oleh replica — tanpa ada manusia yang menyalin apa pun.

Membersihkan Database Latihan #

Rangkaian contoh selesai; database latihan kita jatuhkan kembali:

sql
DROP DATABASE belajar_repl;

Output yang Dihasilkan:

text
Query OK, 2 rows affected (0.00 sec)

Referensi #

Kita kini memegang peta besarnya: replication menyalin perubahan dari source ke replica melalui binary log, mengurai tiga masalah klasik server tunggal sekaligus. Peta saja belum cukup — langkah berikutnya adalah menyusun dua sisi topologi itu secara nyata: menyiapkan akun khusus replikasi di source, mengatur konfigurasi kedua server, dan menghidupkan aliran replikasinya dengan CHANGE REPLICATION SOURCE TO serta START REPLICA.