0

Setup một mô hình Mysql Master-Slave đơn giản

MySql replication là một quá trình cho phép dữ liệu từ một server MySQL (master) được sao lưu lại trên một hoặc nhiều server MySQL khác (slaves). Nó thường được sử dụng để cấp quyền đọc cho nhiều server khác cho khả năng nhân rộng, đồng thời nó cũng được sử dụng cho mục đích khác như là để dự phòng lỗi cho server master, hoặc là để phân tích dữ liệu trên server slave giúp giảm tải cho server master.

Vì việc sao chép theo mô hình Master-Slave là sao chép một chiều (từ master sang slave), chỉ có server database master được sử dụng các hoạt động ghi dữ liệu, trong khi các hoạt động đọc được trải rộng trên nhiều server slave. Điều này có nghĩa là mô hình Master-Slave được chọn làm giải pháp mở rộng quy mô, bạn phải có ít nhất hai nguồn dữ liệu xác định, một cho các hoạt động đọc và một cho các hoạt động ghi.

MySQL developer thường sử dụng một máy tính và đã có toàn bộ môi trường phát triển trong đó, họ không phụ thuộc vào kết nối mạng chậm hay nhanh để phải setup một mô hình như trên. Nhưng nếu một mô hình master-slave là cần thiết để kiểm thử việc sử dụng mô hình này trong môi trường phát triển trước khi tiến hành deploy ở bất kỳ nơi nào khác, họ phải cài đặt nó trên cùng một máy tính của mình. Việc setup một CSDL MySQL là vô cùng đơn giản, chúng ta chỉ việc bỏ ra một chút effort nữa để setup một CSDL thứ hai, và cuối cùng là thiết lập master-slave.

Cài đặt MySQL instance đầu tiên

Nếu bạn đã có sẵn một CSDL MySQL được cài trong máy, bạn có thế bỏ qua bước này.

Cách đơn giản nhất để install MySQL đó là chạy lệnh sau

sudo apt-get install mysql-server

Trong quá trình cài đặt, bạn sẽ được hỏi để setting password cho root user.

Setup mysqld_multi

Để quản lý hai instance MySQL hiệu quả trên cùng một host, chúng ta cần sử dụng mysqld_multi.

Bước đầu tiên để cài đặt mysqld_multi là tạo ra hai [mysqld] group riêng biệt trong file cài đặt my.cnf.

Mặc định, file my.cnf được lưu ở /etc/mysql với Ubuntu. Chúng ta sẽ mở file này và thay đổi tên group có sẵn là [mysqld] thành [mysqld1]. Group này sẽ được sẽ là instance MySQL đầu tiên và là master instance.

Với tùy từng phiên bản MySQL mà file này sẽ có cấu trúc khác nhau, phiên bản hiện tại mà tôi đang sử dụng có cấu trúc như sau:

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

Trong file này sẽ include setting từ các file .cnf trong thư mục conf.dmysql.conf.d vì vậy khi đổi tên group, chúng ta phải đổi tên tất cả những chỗ có tên group [mysqld]

➜  mysql grep -r mysqld mysql.conf.d 
mysql.conf.d/mysqld_safe_syslog.cnf:[mysqld_safe]
mysql.conf.d/mysqld.cnf:[mysqld_safe]
mysql.conf.d/mysqld.cnf:socket		= /var/run/mysqld/mysqld.sock
mysql.conf.d/mysqld.cnf:[mysqld]
mysql.conf.d/mysqld.cnf:pid-file	= /var/run/mysqld/mysqld.pid
mysql.conf.d/mysqld.cnf:socket		= /var/run/mysqld/mysqld.sock
➜  mysql grep -r mysqld conf.d      
conf.d/mysqldump.cnf:[mysqldump]

Như vậy chúng ta cần thay đổi ở file /etc/mysq/mysql.conf.d/mysqld.cnf. Vì trong master-slave thì mỗi instance cần có uniqe server-id của đó nên chúng ta cần add setting sau vào phần group [mysqld1]

server-id = 1

Chúng ta cần một group thứ hai cho instance MySQL thứ hai, copy [mysql1] group với tất cả config và paste vào cùng một file dưới group [mysqld2], và thay đổi những thông tin như sau cho slave:

[mysql2]
server-id = 2
user            = mysql
pid-file        = /var/run/mysqld/mysqld_slave.pid
socket          = /var/run/mysqld/mysqld_slave.sock
port            = 3307
datadir         = /var/lib/mysql_slave
tmpdir          = /tmp
lc-messages-dir = /usr/share/mysql
relay-log           = /var/log/mysql_slave/relay-bin
relay-log-index     = /var/log/mysql_slave/relay-bin.index
master-info-file    = /var/log/mysql_slave/master.info
relay-log-info-file = /var/log/mysql_slave/relay-log.info
log_error = /var/log/mysql_slave/error.log
read_only           = 1

Để setup instance MySQL thứ hai, set server-id là 2. Vì cả hai instance cùng chạy trên cùng một host, chúng ta cần setup port là 3307 hoặc bất kì port nào khác 3306. Chúng ta cũng cần setup socket, pid-file, datadir, và log_error khác với master instance.

Cuối cùng chúng ta cần enable relay-log để sử dụng instance như là một slave bằng cách setup các parameter relay-log, relay-log-index, relay-log-info-filemaster-info-file.

Và để slave instance chỉ có quyển đọc, chúng ta set read-only = 1. Chúng ta cũng có một điều cần lưu ý với option này đó là nó không hoàn toàn ngăn cản quyền ghi ở slave, updates vẫn được permit với user có quyền SUPER. MySQL đã thêm một param nữa là super_read_only để chặn quyền update của SUPER (option này được cung cấp từ bản 5.7.8).

Chúng ta cần thêm một group nữa đó là group mysql_multi:

[mysqld_multi]
mysqld     = /usr/bin/mysqld_safe
mysqladmin = /usr/bin/mysqladmin
user       = multi_admin
password   = multipass

Sau khi cài đặt instance thứ hai, chúng ta khởi động lại cả hai, và chúng ta sẽ phân quyền cho multi_admin user quyền để shutdown MySQL instance.

Tạo thư mục cho slave instance

Chúng ta sẽ tạo thư mục đã setting cho slave instance ở bước trước.

mkdir -p /var/lib/mysql_slave
chmod --reference /var/lib/mysql /var/lib/mysql_slave
chown --reference /var/lib/mysql /var/lib/mysql_slave
 
mkdir -p /var/log/mysql_slave
chmod --reference /var/log/mysql /var/log/mysql_slave
chown --reference /var/log/mysql /var/log/mysql_slave

Cài đặt bảo mật cho AppArmor

Trong một số môi trường Linux, thiết lập bảo mật AppArmor là cần thiết để khởi chạy instance MySQL thứ hai (nhất là đối với Ubuntu).

Để setup AppArmor, chúng ta sẽ edit file /etc/apparmor.d/usr.sbin.mysqld bằng cách add thêm những line sau:

/var/lib/mysql_slave/ r,
/var/lib/mysql_slave/** rwk,
/var/log/mysql_slave/ r,
/var/log/mysql_slave/* rw,
/var/run/mysqld/mysqld_slave.pid rw,
/var/run/mysqld/mysqld_slave.sock w,
/run/mysqld/mysqld_slave.pid rw,
/run/mysqld/mysqld_slave.sock w,

Sau khi save file, chúng ta cần khởi động lại máy để những thay đổi trên có hiệu lực.

Cài đặt cho slave instance

Sau khi đã setup và tạo các thư mục cần thiết cho slave instance, chúng ta sử dụng lệnh sau để để init thư mục data cho nó:

sudo mysqld --initialize --user=mysql --datadir=/var/lib/mysql_slave

Khi MySQL thư mục data cho slave đã được tạo, bạn có thể khởi động cả hai instance sử dụng mysqld_multi:

sudo mysqld_multi start

Set lại root password cho slave instance bằng cách sử dụng mysqladmin với host và port tương ứng, nếu host và port không được định nghĩa thì nó sẽ connect đến master slave

mysqladmin --host=127.0.0.1 --port=3307 -u root password rootpwd

Trong ví dụ trên chúng ta set password cho root là "rootpwd"

Config cho mysqld_multi

Ở phần trên chúng ta đã setup user cho mysqld_multimulti_admin, chúng ta cần cấp quyền cho user này trên cả 2 instance, bằng cách connect vào 2 instance và set quyền cho nó:

mysql --host=127.0.0.1 --port=3306 -uroot -p
mysql> GRANT SHUTDOWN ON *.* TO 'multi_admin'@'localhost' IDENTIFIED BY 'multipass';
mysql> FLUSH PRIVILEGES;

Setup master-slave

Bây giờ chúng ta đã có 2 instance MySQL chạy cùng trên một máy, chúng ta sẽ setup master cho instance 1 và slave cho instance thứ 2.

Chúng ta cần setting binary logging ở my.cnf cho instance 1. Thêm dòng sau vào file my.cnf trong phần setting của group [mysqld1]:

log_bin                     = /var/log/mysql/mysql-bin.log
innodb_flush_log_at_trx_commit  = 1
sync_binlog                 = 1
binlog-format               = ROW

Khởi động lại master instance:

mysqld_multi stop 1
mysqld_multi start 1

Để slave có thể connect tới master với đúng quyền sao chép, một user mới cần được tạo trên master.

mysql -uroot -p --host=127.0.0.1 --port=3306
mysql> CREATE USER 'replication'@'%' IDENTIFIED BY 'replication';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';

Sau đó dump data từ server master:

mysqldump -uroot -p --host=127.0.0.1 --port=3306 --all-databases --master-data=2 > replicationdump.sql

option --master-data=2 sinh ra một dòng comment CHANGE MASTER trong file backup. Comment này chỉ ra thời điểm sao chép chính là thời điểm backup, và chúng ta cũng cần thông tin này để update thông master tại slave instance.

Sau đó import nó vào trong slave instance:

mysql -uroot -p --host=127.0.0.1 --port=3307 < replicationdump.sql

Cuối cùng, connect slave tới master bằng cách cập nhật thông tin master cho slave:

mysql -uroot -p --host=127.0.0.1 --port=3307

mysql> CHANGE MASTER TO
  -> MASTER_HOST='127.0.0.1',
  -> MASTER_USER='replication',
  -> MASTER_PASSWORD='replication',
  -> MASTER_LOG_FILE='mysql-bin.000001',
  -> MASTER_LOG_POS=349;

Thực thi câu lệnh sau để start slave:

mysql> START SLAVE;

Sử dụng lệnh sau để kiểm tra xem việc sao chép sang slave đã thành công chưa:

mysql> SHOW SLAVE STATUS \G

Chúc mừng, quá trình đã hoàn tất, và chúng ta có thể môi trường phát triển để test được rồi.

https://www.toptal.com/mysql/mysql-master-slave-replication-tutorial


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí