什麼是MYSQL主從模式
主從複製過程使數據庫管理員能夠同時複製或拷貝存儲在多個服務器中的數據。這有助於數據庫管理員一直創建數據庫的實時備份。在某些情況下,當主從機出現任何問題時,他們可以立即切換到從機數據庫,並保持應用程序正常運行。複製過程確保你的應用程序根本不會面臨任何形式的停機。
在這種複製中,有各種類型的複製過程。你可以有一個主站和多個從站,或者多個主站和多個從站等。
在這個過程中,它總是一個單一的或單向的數據傳輸。數據首先存儲在主站,然後再複製到從站。因此,寫操作只在主數據庫中進行。讀取操作是在主數據庫和從數據庫中進行的。從機也可用於數據訪問,以減少主數據庫的負荷。
部署主從實例
新建Master實例
新建名爲mysql-master
的實例,端口16000
docker run -d --name mysql-master --restart unless-stopped -p 16000:3306 -e MYSQL_ROOT_PASSWORD=xxxxxxxxxxxxx mysql:5.7.40
新建Slave實例
新建名爲mysql-slave-01
的實例,端口17001
docker run -d --name mysql-slave-01 --restart unless-stopped -p 17001:3306 -e MYSQL_ROOT_PASSWORD=xxxxxxxxxxxxx mysql:5.7.40
新建名爲mysql-slave-02
的實例,端口17002
docker run -d --name mysql-slave-02 --restart unless-stopped -p 17002:3306 -e MYSQL_ROOT_PASSWORD=xxxxxxxxxxxxx mysql:5.7.40
爲Master和Slave創建庫表
我們可以使用一些SQL工具連接到Master和所有的Slave,然後通過下面語句創建好數據庫tesla
和它名下的數據表order
CREATE DATABASE IF NOT EXISTS tesla;
USE tesla;
CREATE TABLE IF NOT EXISTS `order` (
`id` int(11) NOT NULL,
`name` varchar(254) NOT NULL,
`bir` varchar(254) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
等下的主從同步都是基於這些信息來同步的,如果不一致的話,會出現錯誤。
配置Master實例
先將Master實例中配置文件拷貝出來
docker cp mysql-master:/etc/my.cnf F:\mysql-master\my.cnf
通過VSCode編輯它,在[client]
之前位置,插入兩行配置
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql
# 開啓Log_bin
log-bin=mysql.bin
# 指定全局唯一ID
server-id=11
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock
其中log-bin=mysql.bin
指定了BinLog日誌的相對位置,最終會記錄在/var/lib/mysql/mysql.bin
,然後server-id=11
,給這個Master實例指定了唯一ID。
這裏還有一些可選的配置:
# 無需同步的數據庫名稱
binlog-ignore-db=mysql
# 設置使用的二進制日誌格式(mixed,statement,row)
binlog_format=mixed
# 設置二進制日誌過期清理時間,默認值爲0,,表示不自動清理
expire_logs_days=7
# 跳過主從複製中遇到的所有錯誤或者指定類型的錯誤,避免slave端的複製中斷
# 如1062錯誤是指一些主鍵重複,1032錯誤是指主從數據庫的數據不一致。
slave_skip_errors=1062
將修改後的配置文件拷貝回Master實例
docker cp F:\mysql-master\my.cnf mysql-master:/etc/my.cnf
然後重啓一次Master實例
docker restart mysql-master
進入Master實例
docker exec -it mysql-master /bin/bash
登錄mysql
mysql -u root -p
然後輸入密碼
登錄成功後,通過命令查看log-bin是否開啓成功
show variables like '%log_bin%';
創建用於主從複製的賬號
create user 'repl-from-master'@'%' identified by 'xxxxxxxxxx';
並且授予其複製權限
grant replication slave,replication client on *.* to 'repl-from-master'@'%';
查看實例狀態
show master status;
這裏的File
和Position
都是我們Slave需要用到的信息,記錄下來。
另外,quit
之後,還可以切換到log-bin數據目錄也應該可以看到日誌文件
cd /var/lib/mysql/
ls
配置Slave實例
先將Slave實例中配置文件拷貝出來
docker cp mysql-slave-01:/etc/my.cnf F:\mysql-slave-01\my.cnf
通過VSCode編輯它,在[client]
之前位置,插入兩行配置
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql
# 指定全局唯一ID
server-id=21
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock
其中server-id=21
,給這個Slave實例指定了唯一ID。
這裏還有一些可選的配置:
# 無需同步的數據庫名稱
binlog-ignore-db=mysql
# 設置使用的二進制日誌格式(mixed,statement,row)
binlog_format=mixed
# 設置二進制日誌過期清理時間,默認值爲0,,表示不自動清理
expire_logs_days=7
# 跳過主從複製中遇到的所有錯誤或者指定類型的錯誤,避免slave端的複製中斷
# 如1062錯誤是指一些主鍵重複,1032錯誤是指主從數據庫的數據不一致。
slave_skip_errors=1062
# 將複製事件寫入自己的二進制日誌
log_slave_updates=1
# 設置數據庫數據爲只讀(具有super權限的用戶除外)
read_only=1
將修改後的配置文件拷貝回Slave實例
docker cp F:\mysql-slave-01\my.cnf mysql-slave-01:/etc/my.cnf
然後重啓一次Slave實例
docker restart mysql-slave-01
進入Slave實例
docker exec -it mysql-slave-01 /bin/bash
登錄mysql
mysql -u root -p
然後輸入密碼
登錄成功後,爲了防止之前有設置過Slave,我們先做一次停止
stop slave;
通過命令設置它Slave哪個Master,相關連接信息和位置是多少。
change master to master_host='192.168.0.109',master_port=16000, master_user='repl-from-master',master_password='xxxxxxxxxxxx',master_log_file='mysql-bin.000004',master_log_pos=154;
這些參數的含義分別是
master_host
=主數據庫IPmaster_port
=主數據端口master_user
=在主數據庫創建的用於同步的用戶賬號master_password
=在主數據庫創建的用於同步的用戶密碼master_log_file
=指定從主數據庫複製數據的日誌文件,查看主數據狀態的File字段的值master_log_pos
=指定從主數據庫哪個位置開始複製數據,查看主數據狀態的Position字段的值master_connect_retry
=從數據庫連接主數據庫失敗時,重新嘗試連接的間隔時間,單位秒
這裏有個要特別注意的地方,
master_host
不能使用localhost
或者127.0.0.1
這樣的,如果是Docker Desktop for Windows可以使用本機的局域網Ip,通過ipconfig
可以查閱。
重置一次同步
reset slave;
然後開始執行同步
start slave;
查看同步狀態
show slave status \G;
這裏使用了\G
代表以鍵值對的方式輸出結果。
其中Slave_IO_Running
和Slave_SQL_Running
都爲Yes
,纔算是正常。
處理異常情況
如果這時候Slave_IO_Running
爲No
,我們可以考慮先停止Slave
stop slave;
再回到Master裏面,在mysql
模式下,執行
flush logs;
刷新下日誌。
再次查看位置
show master status;
File的名字會+1
回到Slave實例中更新位置
change master to master_log_file='mysql-bin.000002',master_log_pos=154;
然後先重置一次
reset slave;
然後啓動並查看Slave狀態
start slave;
show slave status \G;
驗證主從同步
我們先在Master的tesla
庫的order
表中新增一條數據。
接下來,我們去Slave的tesla
庫的order
表中看看
如果它在那裏,並且和Master保持一致,那麼就同步成功了。
常見錯誤
Error_code: 2003
這個錯誤表示,連接Master用的master_host
、master_port
、master_user
、master_password
四個信息裏面肯定錯了至少一個。
[ERROR] Slave I/O for channel '': error connecting to master 'repl-from-master@localhost:16000' - retry-time: 60 retries: 1, Error_code: 2003
Error_code: 1236
這個錯誤表示,沒有讀取到Master BinLog正確的日誌文件,如果確實文件都在,做一次Master的flush logs;
動作,在來Slave修正下位置試試。
[ERROR] Slave I/O for channel '': Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file', Error_code: 1236
Error_code: 1051
這個錯誤表示,同步過來一個刪表動作,但是Slave中根本沒有這個表,估計也是Slave沒有同步創建好這張表。
[ERROR] Slave SQL for channel '': Error 'Unknown table 'tesla.order'' on query. Default database: 'tesla'. Query: 'DROP TABLE `order` /* generated by server */', Error_code: 1051
Error_code: 1146
這個錯誤表示,在Slave中都沒有找到這個名稱的表,可能是Master裏面新建了,但是在Slave中沒有對應的建,這裏補創建下就好了。
[ERROR] Slave SQL for channel '': Error executing row event: 'Table 'tesla.order' doesn't exist', Error_code: 1146
Error_code: 1032
這個錯誤表示,同步過來一個刪除動作,但是Slave中沒有這條記錄。
[ERROR] Slave SQL for channel '': Could not execute Delete_rows event on table tesla.order; Can't find record in 'order', Error_code: 1032; handler error HA_ERR_END_OF_FILE; the event's master log mysql.000007, end_log_pos 1662, Error_code: 1032
參考
- Docker cp命令
- docker精簡版沒有vi,vim命令,怎麼修改文件
- 【docker+mysql】基於docker 配置 mysql5.7 主從 master-slave
- mysql數據庫開啓log-bin
- 'COULD NOT FIND FIRST LOG FILE NAME IN BINARY LOG INDEX FILE'的解決辦法
- canal異常 Could not find first log file name in binary log index file
- Docker部署MySQL 8.0主從(Master-Slave)
- MySQL 創建數據表
- Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file n
- Error 1236 - "Could not find first log file name in binary log index file"