參考文檔:https://dev.mysql.com/doc/refman/5.7/en/replication.html
本文是對上述文檔的關鍵步驟進行整理,有時間還是看看文檔全面瞭解更好
一、Master 配置
在 my.cnf
或 my.ini
配置文件的 [mysqld]
部分添加如下配置:
[mysqld]
# 服務器 ID,在 1和(2^32)-1 之間的正整數,不能和其他 MySQL 服務器ID重複
server-id=1
# 啓用二進制日誌,值爲日誌文件的前綴
log-bin=mysql-bin
# 爲了在使用InnoDB事務的複製設置中實現最大的持久性和一致性
# 您應該在主 文件中啓用下面兩項配置
innodb_flush_log_at_trx_commit=1
sync_binlog=1
上面最後兩個配置可以提供最高的數據安全,但是會導致更高的磁盤 IO,因此 TPS 最低,實際使用時需要根據自己業務進行測試尋求更合適的配置。
參數詳細說明:sysvar_innodb_flush_log_at_trx_commit
二、創建用於複製的用戶
創建用戶
CREATE USER 'repl'@'%.example.com' IDENTIFIED BY 'password';
賦予權限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%.example.com';
三、獲取二進制日誌座標
爲了主從一致,需要先禁用主機的增刪改操作,給所有表設置讀鎖。
在 master 執行:
FLUSH TABLES WITH READ LOCK;
警告
讓發出FLUSH TABLES
語句的客戶端保持運行狀態,以使讀鎖保持有效。如果退出客戶端,則會釋放鎖。
在 master 上打開一個新的會話,執行:
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 73 | test | manual,mysql |
+------------------+----------+--------------+------------------+
記錄 File 和 Position 信息。
四、同步現有數據
如果 master 已有數據,需要先同步。同步方法如下。
4.1 使用 mysqldump
在命令行執行:
$ mysqldump --all-databases --master-data > dbdump.db
五、Slaves 配置
5.1 在 master 上釋放鎖
UNLOCK TABLES;
5.2 配置 slave 服務器
修改 my.cnf
或 my.ini
配置:
[mysqld]
server-id=2
多個 slave 時需要保證 server-id 不重複
slave 不需要開啓 log-bin
,如果開啓,就能通過二進制日誌進行數據備份或崩潰恢復操作。同時還可以作爲另一個 slave 的 master(主-從(主)-從
)。
5.3 設置 master 信息
執行下面的 SQL:
mysql> CHANGE MASTER TO
MASTER_HOST='master_host_name',
MASTER_USER='replication_user_name',
MASTER_PASSWORD='replication_password',
MASTER_LOG_FILE='recorded_log_file_name',
MASTER_LOG_POS=recorded_log_position;
將上面參數 'xxx'
部分修改爲對應的主機名(IP),複製用的用戶名和密碼,SHOW MASTER STATUS;
時看到的二進制文件名和 Position。
5.4 恢復 master 數據
如果在前面導出了現有數據,這裏需要先將數據導入,執行下面的命令:
$ mysql -h master < dbdump.db
如果在 mysqldump 使用了
--single-transaction
,導入數據時會自動執行上述配置。
5.5 啓動 Slave 線程
執行SQL:START SLAVE;
六、實踐
簡單嘗試時可以通過 docker 快速部署兩個容器用於學習。
參考:https://hub.docker.com/_/mysql
Docker 宿主機 IP:192.168.200.202
準備掛載目錄結構如下:
/docker
└── mysql
├── master
│ ├── conf
│ │ └── my.cnf
│ └── data
└── slave
├── conf
│ └── my.cnf
└── data
6.1 Master
my.cnf
配置文件:
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
collation-server=utf8mb4_unicode_ci
character-set-server=utf8mb4
init-connect='SET NAMES utf8mb4'
max_connections=2000
lower_case_table_names=1
server-id=1
log-bin=mysql-bin
innodb_flush_log_at_trx_commit=1
sync_binlog=1
這裏設置了字符集爲 utf8mb4
通過 docker 啓動服務:
docker run --name mysql-master \
-e MYSQL_ROOT_PASSWORD=root \
-p 3306:3306 \
-v /docker/mysql/master/conf:/etc/mysql \
-v /docker/mysql/master/data:/var/lib/mysql \
-d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
6.2 Slave
my.cnf
配置文件:
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
collation-server=utf8mb4_unicode_ci
character-set-server=utf8mb4
init-connect='SET NAMES utf8mb4'
max_connections=2000
lower_case_table_names=1
server-id=10
log-bin=mysql-bin
這裏設置了字符集爲 utf8mb4
通過 docker 啓動服務:
docker run --name mysql-slave \
-e MYSQL_ROOT_PASSWORD=root \
-p 3307:3306 \
-v /docker/mysql/slave/conf:/etc/mysql \
-v /docker/mysql/slave/data:/var/lib/mysql \
-d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
6.3 測試
6.3.1. 準備數據
先在 master 執行 SQL:數據庫結構.sql,這就是有現有數據的情況。
6.3.2. 備份 master
執行下面的 docker 命令備份數據:
$ docker exec mysql-master sh -c 'exec mysqldump --all-databases --master-data --single-transaction --include-master-host-port -uroot -proot' > /docker/mysql/dbdump.db
6.3.3. 還原 slave
執行下面的 docker 命令還原數據:
$ docker exec -i mysql-slave sh -c 'exec mysql -uroot -proot' < /docker/mysql/dbdump.db
6.3.4 創建複製用戶
創建用戶
CREATE USER 'slave'@'%' IDENTIFIED BY 'slave';
賦予權限
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
提醒
第一次使用@'192.168.200.202'
出現了下面的 slave 狀態Slave_IO_Running: Connecting
Slave_SQL_Running: Yes然後在 master 日誌發現:
[Note] Access denied for user ‘slave’@‘172.17.0.1’ (using password: YES)
上面展示的是容器 IP沒有訪問權限,修改爲
@'%'
後狀態變爲正常。
6.3.5 slave 配置 master
CHANGE MASTER TO
MASTER_HOST='192.168.200.202',
MASTER_USER='slave',
MASTER_PASSWORD='slave',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=15114;
其中 MASTER_LOG_FILE
和 MASTER_LOG_POS
值可以在上面備份 /docker/mysql/dbdump.db
的 SQL 語句中看到,也可以按照前文加鎖保證備份時這兩個參數不變。
6.3.6 修改 master 查看 slave 變化
隨便增刪改數據或增加數據庫、表等查看效果。
七、小結
很早很早以前就做過主從方面的數據庫配置,當初也是看別人文章學,如今發現不同文檔配置有差異,因此看官方文檔從頭操作一遍,MySQL 官方文檔很全面,當前只看了一小部分內容,等看全再補充,同時推薦看到這裏的朋友看看官方文檔瞭解更多細節。