Hướng dẫn này mô tả thiết lập MySQL được sao chép (sao chép Mater/Master) với 2 nút, trong đó dữ liệu có thể được đọc và ghi vào cả hai nút cùng một lúc. MySQL sẽ đảm bảo sao chép dữ liệu vào nút còn lại và đảm bảo rằng các khóa tự động tăng chính không xung đột.
Kể từ phiên bản 5, MySQL đi kèm với hỗ trợ tích hợp cho sao chép master-master, giải quyết vấn đề có thể xảy ra với các khóa tự tạo. Trong các phiên bản MySQL trước đây, vấn đề với sao chép master-master là xung đột phát sinh ngay lập tức nếu cả nút A và nút B đều chèn một khóa tự động tăng vào cùng một bảng. Ưu điểm của sao chép master-master so với sao chép master-slave truyền thống là bạn không phải sửa đổi ứng dụng của mình để chỉ tạo quyền truy cập ghi vào master và dễ cung cấp tính khả dụng cao hơn vì nếu master bị lỗi, bạn vẫn có master khác.
server1/server2:
Để đảm bảo rằng bản sao có thể hoạt động, chúng ta phải để MySQL lắng nghe trên tất cả interfaces, do đó chúng tôi chú thích dòng bind-address = 127.0.0.1 trong /etc/mysql/my.cnf:
server1/server2:
Khởi động lại MySQL sau đó:
server1/server2:
Sau đó kiểm tra bằng
server1/server2:
MySQL thực sự đang lắng nghe trên tất cả các giao diện:
Bây giờ chúng ta thiết lập một người dùng sao chép slave2_user có thể được server2 sử dụng để truy cập cơ sở dữ liệu MySQL trên server1.
server1:
Đăng nhập vào shell MySQL:
Trên shell MySQL, hãy chạy các lệnh sau:
server1:
Thay thế từ "secretpassword" bằng mật khẩu an toàn mà bạn chọn. Bây giờ chúng ta thực hiện lại hai bước cuối cùng trên server2:
server2:
Thay thế từ "secretpassword" bằng mật khẩu an toàn tại đây. Ghi lại mật khẩu vì chúng ta cần chúng sau này.
Nếu máy chủ của bạn không như vậy, thì bạn phải khóa và dump cơ sở dữ liệu trên máy chủ đầu tiên và import chúng trên máy chủ thứ hai trước khi tiếp tục. Không mở khóa cơ sở dữ liệu trước khi thiết lập bản sao. Dưới đây là một số lệnh cho thấy cách sao chép tất cả cơ sở dữ liệu sang máy chủ mới trong trường hợp bạn không bắt đầu bằng thiết lập MySQL "sạch".
Ví dụ về cách khóa tất cả các bảng cơ sở dữ liệu trong cơ sở dữ liệu MySQL.
Ví dụ về cách dump tất cả cơ sở dữ liệu vào tệp all_databases.sql.
Ví dụ về cách nhập tất cả các bảng trên máy chủ thứ hai từ tệp all_databses.sql.
Bây giờ hãy cấu hình hai nút MySQL của chúng ta:
server1:
Tìm kiếm phần bắt đầu bằng [mysqld] và đưa các tùy chọn sau vào đó (bình luận về tất cả các tùy chọn xung đột[/b] hiện có):
Sau đó khởi động lại MySQL:
server1:
Bây giờ hãy thực hiện tương tự trên server2:
server2:
server2:
Tiếp theo, chúng ta khóa cơ sở dữ liệu exampledb trên server1, tìm hiểu về trạng thái chính của server1, tạo một bản dump SQL của exampledb (mà chúng ta sẽ nhập vào exampledb trên server2 để cả hai cơ sở dữ liệu đều chứa cùng một dữ liệu) và mở khóa cơ sở dữ liệu để có thể sử dụng lại:
server2:
Bây giờ chúng ta bắt đầu sao chép trên Máy chủ 2. Mở shell MySQL:
Và thực thi lệnh SQL sau để kích hoạt sao chép từ máy chủ 1 sang máy chủ 2:
Thay thế secretpasswordbằng mật khẩu cho repl người dùng MySQL mà bạn đã thiết lập ở chương 2.
Bây giờ hãy kiểm tra trạng thái của máy phụ bằng cách thực thi lệnh "show slave status\G" trong shell MySQL.
Đầu ra sẽ tương tự như sau:
[TR]mysql> hiển thị trạng thái slave\G
****************************** 1. hàng ***************************
Slave_IO_State:
Master_Host: 192.168.1.101
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 107
Relay_Log_File: mysqld-relay-bin.000003
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Không
Slave_SQL_Running: Không
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Relay_Log_Space: 410
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Không
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: Không
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 hàng trong tập hợp (0,00 giây)
Các dòng bạn nên kiểm tra là:
Bây giờ hãy bắt đầu sao chép bằng lệnh này trên shell MySQL:
và sau đó kiểm tra trạng thái của slave một lần nữa:
Hai dòng sau đây sẽ hiển thị "yes" ngay bây giờ:
Nếu "Seconds_Behind_Master" không phải là 0, hãy đợi vài giây và kiểm tra lại trạng thái. Trường này hiển thị xem master và slave có đồng bộ không.
Đối với bước tiếp theo, chúng ta cần biết giá trị của "Master_Log_File" và "Read_Master_Log_Pos" trong lệnh "show slave status\G". Trong trường hợp của tôi, đây là:
Ghi lại các giá trị bạn nhận được trên máy chủ của mình, chúng tôi cần chúng cho bước tiếp theo trên máy chủ 1.
Sau đó, bạn có thể thoát khỏi shell MySQL:
server1:
Chúng tôi tiếp tục trên máy chủ đầu tiên, mở shell MySQL trên server1:
Và thực hiện lệnh MySQL sau:
Bạn phải thay thế một vài thứ trong lệnh trên:
trên shell MySQL nếu không có lỗi.
Và khởi động slave.
Kiểm tra lại trạng thái slave:
Hai dòng sau đây sẽ hiển thị "yes" ngay bây giờ:
Sau đó, bạn có thể thoát khỏi shell MySQL:
Nếu không có gì sai sót, MySQL master-master replication hiện sẽ hoạt động. Nếu không, vui lòng kiểm tra /var/log/syslog để biết lỗi MySQL trên server1 và server2.
server1:
Đăng nhập vào bảng điều khiển MySQL trên server1 và tạo cơ sở dữ liệu:
server2
Bây giờ hãy đăng nhập vào bảng điều khiển MySQL trên server2 và kiểm tra xem exampledb1 có tồn tại ở đó không:
Như chúng ta có thể thấy, cơ sở dữ liệu mới cũng hiển thị trên server2.
Tiếp theo, tôi sẽ kiểm tra xem bản sao có hoạt động theo hướng khác không. Chúng tôi vẫn đăng nhập trên server2 và tạo cơ sở dữ liệu exampledb2 ở đó:
Bây giờ hãy quay lại server1 và chạy "show databases" trong bảng điều khiển MySQL:
server1
Kết quả hiển thị cơ sở dữ liệu mới của chúng tôi exampledb2, do đó bản sao đang hoạt động theo cả hai hướng.
Kể từ phiên bản 5, MySQL đi kèm với hỗ trợ tích hợp cho sao chép master-master, giải quyết vấn đề có thể xảy ra với các khóa tự tạo. Trong các phiên bản MySQL trước đây, vấn đề với sao chép master-master là xung đột phát sinh ngay lập tức nếu cả nút A và nút B đều chèn một khóa tự động tăng vào cùng một bảng. Ưu điểm của sao chép master-master so với sao chép master-slave truyền thống là bạn không phải sửa đổi ứng dụng của mình để chỉ tạo quyền truy cập ghi vào master và dễ cung cấp tính khả dụng cao hơn vì nếu master bị lỗi, bạn vẫn có master khác.
1 Lưu ý sơ bộ
Trong hướng dẫn này, tôi sẽ chỉ cách sao chép cơ sở dữ liệu exampledb từ máy chủ server1.example.com có địa chỉ IP 192.168.1.101 đến máy chủ server2.example.com có địa chỉ IP 192.168.1.102 và ngược lại. Mỗi hệ thống vừa là slave của master kia vừa là master của slave kia cùng một lúc. Cả hai hệ thống đều chạy Debian 8; tuy nhiên, cấu hình này sẽ áp dụng cho hầu hết các bản phân phối với ít hoặc không có sửa đổi nào.2 Cài đặt MySQL 5.5
Nếu MySQL chưa được cài đặt trên server1 và server2, hãy cài đặt ngay:server1/server2:
Mã:
apt-get -y install mysql-server-5.5 mysql-client-5.5
server1/server2:
Mã:
nano /etc/mysql/my.cnf
Mã:
[...]# Thay vì bỏ qua mạng, mặc định hiện chỉ lắng nghe trên# localhost tương thích hơn và không kém an toàn.#bind-address = 127.0.0.1[...]
server1/server2:
Mã:
servicemysql restart
server1/server2:
Mã:
netstat -tap | grep mysql
Mã:
netstat -tap | grep mysql[B]tcp 0 0 *:mysql *:* LISTEN 15437/mysqld
server1:~#
server1:
Đăng nhập vào shell MySQL:
Mã:
mysql --defaults-file=/etc/mysql/debian.cnf
server1:
Mã:
GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY 'secretpassword';
XẢ QUYỀN;
thoát;
server2:
Mã:
mysql --defaults-file=/etc/mysql/debian.cnf
Mã:
CẤP QUYỀN SAO CHÉP SLAVE TRÊN *.* CHO repl@'%' ĐƯỢC XÁC ĐỊNH BỞI 'secretpassword';
XẢ QUYỀN;
thoát;
3 Một số lưu ý
Trong phần sau, tôi sẽ giả sử rằng cả hai máy chủ MySQL đều trống (chưa chứa bất kỳ cơ sở dữ liệu nào ngoại trừ cơ sở dữ liệu 'mysql').Nếu máy chủ của bạn không như vậy, thì bạn phải khóa và dump cơ sở dữ liệu trên máy chủ đầu tiên và import chúng trên máy chủ thứ hai trước khi tiếp tục. Không mở khóa cơ sở dữ liệu trước khi thiết lập bản sao. Dưới đây là một số lệnh cho thấy cách sao chép tất cả cơ sở dữ liệu sang máy chủ mới trong trường hợp bạn không bắt đầu bằng thiết lập MySQL "sạch".
Ví dụ về cách khóa tất cả các bảng cơ sở dữ liệu trong cơ sở dữ liệu MySQL.
Mã:
FLUSH TABLES WITH READ LOCK;
SET GLOBAL read_only = ON;
Mã:
mysqldump --defaults-file=/etc/mysql/debian.cnf -cCeQ --hex-blob --quote-names --routines --events --triggers --all-databases -r all_databases.sql
Mã:
mysql --defaults-file=/etc/mysql/debian.cnf < all_databases.sql
4 Thiết lập sao chép
Bây giờ chúng ta thiết lập sao chép master-master trong /etc/mysql/my.cnf. Các tùy chọn cấu hình quan trọng cho bản sao master-master là auto_increment_increment và auto_increment_offset:- auto_increment_increment kiểm soát mức tăng giữa các giá trị AUTO_INCREMENT liên tiếp.
- auto_increment_offset xác định điểm bắt đầu cho các giá trị cột AUTO_INCREMENT.
Bây giờ hãy cấu hình hai nút MySQL của chúng ta:
server1:
Mã:
nano /etc/mysql/my.cnf
Mã:
[...][mysqld]
# ID máy chủ duy nhất
server-id = 1
# Không sao chép các cơ sở dữ liệu sau
binlog-ignore-db = mysql
replicate-ignore-db = mysql
# Tự động tăng offset
auto-increment-increment = 2
# Không sao chép các truy vấn sql cho ID máy chủ cục bộ
replicate-same-server-id = 0
# Tự động tăng giá trị mặc định là 1
auto-increment-offset = 1
# Xóa dữ liệu binlog sau 10 ngày
expire_logs_days = 10
# Kích thước binlog tối đa
max_binlog_size = 500M
# Đường dẫn tệp binlog
log_bin = /var/log/mysql/mysql-bin.log
[...]
server1:
Mã:
servicemysql restart
server2:
Mã:
nano /etc/mysql/my.cnf
Mã:
[...]
# ID máy chủ duy nhất
server-id = 2
# Không sao chép các cơ sở dữ liệu sau
binlog-ignore-db = mysql
replicate-ignore-db = mysql
# Tự động tăng độ lệch
auto-increment-increment = 2
# Không sao chép các truy vấn sql cho ID máy chủ cục bộ
replicate-same-server-id = 0
# Tự động hóa việc sao chép dữ liệu với 1
auto-increment-offset = 2
# Xóa dữ liệu binlog sau 10 ngày
expire_logs_days = 10
# Kích thước binlog tối đa
max_binlog_size = 500M
# Đường dẫn tệp binlog
log_bin = /var/log/mysql/mysql-bin.log
[...]
Mã:
servicemysql restart
server2:
Bây giờ chúng ta bắt đầu sao chép trên Máy chủ 2. Mở shell MySQL:
Mã:
mysql --defaults-file=/etc/mysql/debian.cnf
Mã:
ĐỔI MASTER THÀNH MASTER_HOST='192.168.1.101', MASTER_USER='repl', MASTER_PASSWORD='secretpassword';
Bây giờ hãy kiểm tra trạng thái của máy phụ bằng cách thực thi lệnh "show slave status\G" trong shell MySQL.
Mã:
show slave status\G
[TR]mysql> hiển thị trạng thái slave\G
****************************** 1. hàng ***************************
Slave_IO_State:
Master_Host: 192.168.1.101
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 107
Relay_Log_File: mysqld-relay-bin.000003
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Không
Slave_SQL_Running: Không
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Relay_Log_Space: 410
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Không
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: Không
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 hàng trong tập hợp (0,00 giây)
Các dòng bạn nên kiểm tra là:
Mã:
Master_Host: 192.168.1.101
Master_User: repl
Master_Port: 3306
Master_Log_File: mysql-bin.000001
Relay_Log_File: mysqld-relay-bin.000003
Slave_IO_Running: Không
Slave_SQL_Running: Không
Mã:
khởi động slave;
Mã:
show slave status\G
Mã:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
Đối với bước tiếp theo, chúng ta cần biết giá trị của "Master_Log_File" và "Read_Master_Log_Pos" trong lệnh "show slave status\G". Trong trường hợp của tôi, đây là:
Mã:
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 107
Sau đó, bạn có thể thoát khỏi shell MySQL:
Mã:
quit
server1:
Chúng tôi tiếp tục trên máy chủ đầu tiên, mở shell MySQL trên server1:
Mã:
mysql --defaults-file=/etc/mysql/debian.cnf
Mã:
THAY ĐỔI MASTER THÀNH MASTER_HOST='192.168.1.102', MASTER_USER='repl', MASTER_PASSWORD='secretpassword', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=107;
- Địa chỉ IP phải là IP của máy chủ MySQL thứ hai của bạn.
- Mật khẩu "secretpassword" phải là mật khẩu mà bạn đã chọn trong chương 2 cho người dùng repl.
- MASTER_LOG_FILE và MASTER_LOG_POS phải là các giá trị mà chúng ta đã ghi lại ở bước cuối cùng.
Mã:
show slave status\G
Mã:
mysql> hiển thị trạng thái slave\G
****************************** 1. hàng ***************************
Slave_IO_State:
Master_Host: 192.168.1.102
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 107
Relay_Log_File: mysqld-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Không
Slave_SQL_Running: Không
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Relay_Log_Space: 107
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Không
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: Không
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
1 hàng trong tập hợp (0,00 giây)
Mã:
khởi động slave;
Mã:
show slave status\G
Mã:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Mã:
quit
5 Kiểm tra bản sao
Bây giờ là lúc kiểm tra thiết lập bản sao của chúng ta. Tôi sẽ tạo một cơ sở dữ liệuexampledb1 trên server1 rồi kiểm tra trên server2 xem cơ sở dữ liệu đã được sao chép sang máy chủ thứ hai chưa:server1:
Đăng nhập vào bảng điều khiển MySQL trên server1 và tạo cơ sở dữ liệu:
Mã:
mysql --defaults-file=/etc/mysql/debian.cnf
Mã:
CREATE DATABASE exampledb1;
Bây giờ hãy đăng nhập vào bảng điều khiển MySQL trên server2 và kiểm tra xem exampledb1 có tồn tại ở đó không:
Mã:
mysql --defaults-file=/etc/mysql/debian.cnf
Mã:
show databases;
Mã:
mysql> show databases;
+--------------------+
| Cơ sở dữ liệu |
+------------------+
| information_schema |
| exampledb1 |
| mysql |
| performance_schema |
+------------------+
4 hàng trong tập hợp (0,00 giây)
Mã:
CREATE DATABASE exampledb2;
server1
Mã:
show databases;
Mã:
mysql> show databases;
+------------------+
| Cơ sở dữ liệu |
+------------------+
| information_schema |
| exampledb1 |
| exampledb2 |
| mysql |
| performance_schema |
+------------------+
5 hàng trong tập hợp (0,01 giây)
6 liên kết
- MySQL: http://www.mysql.com
- Debian: http://www.debian.org