Nguyên lý hoạt động của MySQL Replication
Mô hình Master-Slave trong MySQL hoạt động dựa trên việc truyền tải dữ liệu từ nhật ký nhị phân (Binary Log). Khi dữ liệu trên Master thay đổi, các sự kiện này được ghi vào binlog. Phía Slave sẽ chạy một luồng I/O thread để kết nối với Master, đọc các sự kiện binlog và chép vào relay log cục bộ. Sau đó, một luồng khác là SQL thread sẽ đọc relay log và thực thi lại các câu lệnh đó trên cơ sở dữ liệu của Slave để đảm bảo tính đồng bộ.
1. Chuẩn bị môi trường
Trong hướng dẫn này, chúng ta sử dụng 3 máy chủ Ubuntu 22.04 cài đặt MySQL 8.0.33:
- Master: 192.168.1.10 (Hostname: db-master)
- Slave 1: 192.168.1.11 (Hostname: db-slave-1)
- Slave 2: 192.168.1.12 (Hostname: db-slave-2)
Cấu hình ánh xạ hostname trong file /etc/hosts trên cả 3 máy:
192.168.1.10 db-master
192.168.1.11 db-slave-1
192.168.1.12 db-slave-2
Làm mới cấu hình mạng:
sudo systemctl restart systemd-networkd
2. Cài đặt và cấu hình cơ bản
Cài đặt MySQL Server trên tất cả các node:
sudo apt update
sudo apt install mysql-server -y
Sau khi cài đặt, thực hiện thiết lập quyền truy cập cho người dùng root và cho phép MySQL lắng nghe trên tất cả các giao diện mạng:
-- Đăng nhập vào MySQL
mysql -u root -p
-- Cho phép root truy cập từ xa (Chỉ dùng cho môi trường lab)
USE mysql;
UPDATE user SET host='%' WHERE user='root';
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'YourStrongPassword';
FLUSH PRIVILEGES;
Chỉnh sửa file cấu hình /etc/mysql/mysql.conf.d/mysqld.cnf, sửa dòng bind-address:
bind-address = 0.0.0.0
Khởi động lại dịch vụ: sudo systemctl restart mysql.
3. Cấu hình trên node Master (192.168.1.10)
Mở file cấu hình /etc/mysql/my.cnf hoặc /etc/mysql/mysql.conf.d/mysqld.cnf và thêm các tham số sau:
[mysqld]
# ID duy nhất cho mỗi server trong cụm
server-id = 101
# Kích hoạt binary log
log-bin = mysql-bin
# Đảm bảo dữ liệu được ghi xuống đĩa ngay khi commit
sync_binlog = 1
# Thời hạn lưu trữ log (tính bằng giây, ví dụ 7 ngày)
binlog_expire_logs_seconds = 604800
# Các database không cần replicate
binlog_ignore_db = mysql,information_schema
Tạo tài khoản dành riêng cho việc đồng bộ dữ liệu:
CREATE USER 'sync_user'@'192.168.1.%' IDENTIFIED BY 'ReplicaPass@123';
GRANT REPLICATION SLAVE ON *.* TO 'sync_user'@'192.168.1.%';
FLUSH PRIVILEGES;
Kiểm tra trạng thái hiện tại của Master để lấy thông tin file log:
SHOW MASTER STATUS;
Ghi lại giá trị của cột File (ví dụ: mysql-bin.000001) và Position (ví dụ: 157).
4. Cấu hình trên các node Slave (192.168.1.11 | 192.168.1.12)
Chỉnh sửa file cấu hình trên Slave:
[mysqld]
# ID phải khác Master và khác các Slave khác
server-id = 201
# Chế độ chỉ đọc để tránh sai lệch dữ liệu
read_only = 1
# Kích hoạt relay log
relay-log = slave-relay-bin
Thiết lập kết nối tới Master trong terminal MySQL:
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_PORT=3306,
MASTER_USER='sync_user',
MASTER_PASSWORD='ReplicaPass@123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=157,
GET_MASTER_PUBLIC_KEY=1;
Lưu ý: Đối với MySQL 8.0, tham số GET_MASTER_PUBLIC_KEY=1 là cần thiết nếu bạn sử dụng cơ chế xác thực mặc định.
Kích hoạt tiến trình đồng bộ:
START SLAVE;
5. Kiểm tra trạng thái đồng bộ
Sử dụng câu lệnh sau trên Slave để kiểm tra:
SHOW SLAVE STATUS\G;
Các thông số quan trọng cần lưu ý:
- Slave_IO_Running: Phải là
Yes. - Slave_SQL_Running: Phải là
Yes. - Seconds_Behind_Master: Độ trễ của Slave so với Master (lý tưởng là 0).
Các lưu ý quan trọng
Quyền Read-only: Thuộc tính read_only=1 không ngăn cản người dùng có quyền SUPER hoặc CONNECTION_ADMIN thực hiện ghi dữ liệu. Do đó, cần phân quyền cẩn thận cho người dùng ứng dụng.
Bỏ qua Binary Log cho các tác vụ đặc biệt: Nếu bạn muốn thực hiện một thay đổi trên Master mà không muốn nó đồng bộ xuống Slave (ví dụ: tạo user cục bộ), bạn có thể tạm tắt ghi log cho session đó:
SET sql_log_bin = 0;
-- Thực hiện lệnh SQL tại đây
SET sql_log_bin = 1;
Thay đổi thư mục dữ liệu: Trên hệ thống Ubuntu, nếu bạn thay đổi datadir trong cấu hình MySQL, bạn cần phải cập nhật cấu hình bảo mật AppArmor tại /etc/apparmor.d/usr.sbin.mysqld để cho phép MySQL truy cập vào đường dẫn mới, nếu không dịch vụ sẽ không khởi động được.