Metode master slave adalah metode replikasi sederhana yang bisa kita gunakan untuk mendemonstrasikan clustering basis data. Biasanya metode ini tidak direkomendasikan pada lingkungan production, namun sudah cukup menggambarkan bagaimana clustering bekerja.
Dalam latihan ini kita akan membuat sebuah cluster basis data MySQL dengan metode master slave replication dengan menggunakan Docker.
Untuk lingkungan production kita bisa menggunakan image
mysql/cluster
yang sudah production-ready untuk clustering.mysql/cluster
menggunakan engine database yang berbeda yaitu NDB (Network Database) yang teroptimasi untuk basis data terdistribusi.
Mendefinisikan container untuk node master dan slave
Pertama buat sebuah directory baru untuk menempatkan file project latihan. Misalkan dengan nama mysql-cluster. Di dalam directory mysql-cluster, buat sebuah file dengan nama docker-compose.yml
. Isikan file tersebut dengan code berikut:
services: master: image: mysql:8 container_name: bdl-master environment: MYSQL_ROOT_PASSWORD: telurrebus MYSQL_DATABASE: appku MYSQL_USER: bang_kopi MYSQL_PASSWORD: telurrebus command: > --server-id=1 --log-bin=mysql-bin --binlog-do-db=appku --binlog_format=ROW --gtid_mode=ON --enforce-gtid-consistency=ON --mysql-native-password=ON ports: - "3307:3306" networks: - appku-net volumes: - ./custom.cnf:/etc/mysql/conf.d/mysql.cnf slave1: image: mysql:8 container_name: bdl-slave1 environment: MYSQL_ROOT_PASSWORD: telurrebus MYSQL_DATABASE: appku MYSQL_USER: bang_kopi MYSQL_PASSWORD: telurrebus command: > --server-id=2 --relay-log=mysql-relay-bin --log-bin=mysql-bin --read-only=ON --gtid_mode=ON --enforce-gtid-consistency=ON --mysql-native-password=ON ports: - "3308:3306" depends_on: - master networks: - appku-net volumes: - ./custom.cnf:/etc/mysql/conf.d/mysql.cnf slave2: image: mysql:8 container_name: bdl-slave2 environment: MYSQL_ROOT_PASSWORD: telurrebus MYSQL_DATABASE: appku MYSQL_USER: bang_kopi MYSQL_PASSWORD: telurrebus command: > --server-id=3 --relay-log=mysql-relay-bin --log-bin=mysql-bin --read-only=ON --gtid_mode=ON --enforce-gtid-consistency=ON --mysql-native-password=ON ports: - "3309:3306" depends_on: - master networks: - appku-net volumes: - ./custom.cnf:/etc/mysql/conf.d/mysql.cnf networks: appku-net:
Selanjutnya, jalankan cluster dengan perintah:
docker compose up -d
Cek status apakah cluster sudah berjalan dengan baik:
docker ps
Atau kita juga bisa cek dari status dari container dari aplikasi Docker Desktop.
docker compose
adalah tools untuk mendefinisikan dan menjalankan serangkaian container. docker compose membaca setiap definisi dari file bernamadocker-compose.yml
.
docker compose up -d
adalah perintah untuk menjalankan rangkaian container yang telah didefinisikan. Argument-d
membuat proses container berjalan di sisi background (detach dari session bash).-d
adalah shorthand dari detach .
Di dalam docker-compose.yml
di atas kita akan membuat 3 buah node MySQL yang terdiri dari 1 master database dan 2 node slave. Master berfungsi sebagai basis data utama, sumber data yang terkini ada di dalam master. Sedangkan slave, kita gunakan sebagai replikasi dan backup. Masing-masing slave hanya kita gunakan untuk membaca data, jadi perubahan data pada slave tidak diizinkan. Ini secara explisit telah kita konfigurasikan pada parameter —read-only=ON
.
slave1: image: mysql:8 container_name: bdl-slave1 environment: MYSQL_ROOT_PASSWORD: telurrebus MYSQL_DATABASE: appku MYSQL_USER: bang_kopi MYSQL_PASSWORD: telurrebus command: > --server-id=2 --relay-log=mysql-relay-bin --log-bin=mysql-bin --read-only=ON # Update data (insert, update, delete) tidak diizinkan --gtid_mode=ON --enforce-gtid-consistency=ON --mysql-native-password=ON
Dalam docker-compose.yml, kita mendefinisikan service dengan nama master
, slave1
, dan slave2
. Perlu dicatat bahwa penamaan ini mewakili nama host dari masing-masing intance MySQL yang terhubung di dalam network appku-net
. Dengan demikian, masing-masing instance dapat mengenali host yang lainnya dari nama service tersebut.
services: master: # ... konfigurasi lainnya container_name: bdl-master networks: - appku-net # ... konfigurasi lainnya slave1: # ... konfigurasi lainnya container_name: bdl-slave1 networks: - appku-net # ... konfigurasi lainnya slave2: # ... konfigurasi lainnya container_name: bdl-slave2 networks: - appku-net # ... konfigurasi lainnya networks: appku-net:
Jika Anda ingin menguji coba koneksi dari salah satu instance MySQL ke instance lainnya, Anda bisa mencoba dengan mengaksesmysql-server
master dengan menggunakanmysql-client
dari salah satu slave. Contoh:# bash session baru ke dalam bdl-slave1 docker exec -it bdl-slave1 bash # eksekusi query pada master dari mysql-client dari bdl-slave1 mysql -h master -u root -p appku -e 'show tables'
Argument dalam menjalankan mysqld
Pada setiap container, kita menggunakan image
yang akan di-pull dari DockerHub. Konfigurasi mysql:8
command
berfungsi untuk mem-passing argument saat menjalankan mysqld
command: > --server-id=3 --relay-log=mysql-relay-bin --log-bin=mysql-bin --read-only=ON --gtid_mode=ON --enforce-gtid-consistency=ON --mysql-native-password=ON
Berikut penjelasan beberapa argument kunci yang digunakan dalam konfgurasi:
Menentukan nama file relay log yang digunakan oleh server slave dalam replikasi.--relay-log=mysql-relay-bin
Mengaktifkan binary log untuk mencatat semua perubahan data. Diperlukan untuk replikasi master-slave dan pemulihan data.--log-bin=mysql-bin
Membuat server hanya bisa menerima query baca (--read-only=ON
SELECT
)
Mengaktifkan Global Transaction Identifiers (GTID) untuk replikasi yang lebih andal dan mudah dikelola.--gtid_mode=ON
Memastikan semua transaksi dalam database mematuhi aturan GTID agar replikasi tetap konsisten.--enforce-gtid-consistency=ON
Mengaktifkan metode autentikasi lama--mysql-native-password=ON
mysql_native_password
, biasanya untuk kompatibilitas dengan klien atau aplikasi lama.
adalah program daemon untuk menjalankan
mysqld
.
mysql-server
dapat menerima berbagai argument/option eksekusi seperti contoh pada
mysqld
docker-compose.yml
Setup database client dengan DataGrip (atau client lainnya)
Untuk tahap selanjutnya, saya sarankan Anda mnggunakan DataGrip atau aplikasi client berbasis GUI untuk memudahkan interaksi dengan masing-masing instance.
Buat sebuah project baru dengan DataGrip kemudian, tambahkan setiap node sebagai data source. Untuk membuat project baru bisa dengan:
- File → New Project
- Berikan nama project, misalkan
dbl-cluster
- Tambahkan data source baru ke dalam project dengan klik icon Plus (+) → MySQL → MySQL

- Gunakan user root dan masukan credentials lain sesuai dengan docker-compose.yml

- Lakukan langkah 4 untuk data source dari master, slave1, dan slave2.
Melakukan konfigurasi pada master
Kita perlu melakukan konfigurasi pada node master untuk mengijinkan replikasi dari semua slave.
Klik kanan pada data source master → New → Query Console.
Lakukan eksekusi query berikut:
GRANT REPLICATION SLAVE ON *.* TO 'bang_kopi'@'%'; FLUSH PRIVILEGES; SHOW BINARY LOG STATUS;

Catat value dari kolom File dan Position karena akan kita gunakan pada tahap berikutnya.
Melakukan konfigurasi pada slave
Ekskusi query berikut pada node slave:
STOP REPLICA; CHANGE REPLICATION SOURCE TO SOURCE_HOST='master', SOURCE_USER='bang_kopi', SOURCE_PASSWORD='telurrebus', SOURCE_LOG_FILE='mysql-bin.000004', -- gunakan hasil dari SHOW BINARY LOG STATUS dari master SOURCE_LOG_POS=582; -- gunakan hasil dari SHOW BINARY LOG STATUS dari master START REPLICA; -- memulai replikasi SHOW REPLICA STATUS; -- melihat status replikasi (koneksi) dengan master
akan menampilkan apakah slave sudah terhubung dengan master. Jika sukses, hasilnya akan menampilkan log bahwa slave telah siap menerima perubahan dari master.SHOW REPLICA STATUS
Replica_IO_State: Waiting for source to send event Source_Host: master Source_User: bang_kopi Source_Port: 3306 Connect_Retry: 60 Source_Log_File: mysql-bin.000007 Read_Source_Log_Pos: 1465 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 1171 Relay_Source_Log_File: mysql-bin.000007 Replica_IO_Running: Yes Replica_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Source_Log_Pos: 1465 Relay_Log_Space: 1382 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Source_SSL_Allowed: No Source_SSL_CA_File: Source_SSL_CA_Path: Source_SSL_Cert: Source_SSL_Cipher: Source_SSL_Key: Seconds_Behind_Source: 0 Source_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Source_Server_Id: 1 Source_UUID: 7203c779-0a23-11f0-8899-0242ac120002 Source_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates Source_Retry_Count: 10 Source_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Source_SSL_Crl: Source_SSL_Crlpath: Retrieved_Gtid_Set: 7203c779-0a23-11f0-8899-0242ac120002:6-8 Executed_Gtid_Set: 7203c779-0a23-11f0-8899-0242ac120002:6-8 Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Source_TLS_Version: Source_public_key_path: Get_Source_public_key: 0 Network_Namespace:
Lakukan tahap di atas pada semua node slave (slave1 dan slave2).
Error authentication
Jika Anda menemukan error Authentication
plugin 'caching_sha2_password' cannot be loaded
pada
, lakukan pergantian plugin password user pada node master agar menggunakan plugin SHOW REPLICA STATUS
.mysql_native_password
ALTER USER 'bang_kopi'@'%' IDENTIFIED WITH mysql_native_password BY 'telurrebus'; FLUSH PRIVILEGES;
Setelah itu pada node slave, ulangi proses:
STOP REPLICA; CHANGE REPLICATION SOURCE TO SOURCE_HOST='master', SOURCE_USER='bang_kopi', SOURCE_PASSWORD='telurrebus', SOURCE_LOG_FILE='mysql-bin.000004', -- gunakan hasil dari SHOW BINARY LOG STATUS dari master SOURCE_LOG_POS=582; -- gunakan hasil dari SHOW BINARY LOG STATUS dari master START REPLICA; SHOW REPLICA STATUS;
Oleh karena koneksi di dalam Docker network tidak menggunakan SSL/TLS, maka kita perlu menggunakan otentikasi dengan cara lama yaitu
mysql_native_password
. SSL/TLS secara default telah berlaku pada MySQL versi 8+.
Test replikasi
Kita bisa melakukan uji coba replikasi dengan membuat table baru pada database appku
pada node master. Setelah itu, cek node slave, dan pastikan table baru tersebut juga muncul. Eksekusi query berikut untuk membuat sebauh test table dengan nama pendaftaran:
create table pendaftaran ( id int auto_increment primary key, nama varchar(255) null );
Selamat mencoba 🍃
Download project:
Contoh project dapat didownload via Github repository berikut: https://github.com/budasuyasa/mysql-cluster-demo