一.mysql主從同步原理
- Slave上面的IO線程連接上Master,並請求從指定Binary log文件的指定位置(或者從最開始的日志)之后的日志內容;
- Master接收到來自Slave的IO線程的請求后,通過負責復制的IO線程根據請求信息讀取指定日志指定位置之后的日志信息,返回給Slave端的IO線程。返回信息中除了日志所包含的信息之外,還包括本次返回的信息在Master端Binary log文件的名稱以及在Binary log中的位置;
- Slave的IO線程收到信息后,將接收到的日志內容依次寫入到Slave端的RelayLog文件(mysql-relay-lin.xxxxx)的最末端,並將讀取到的Master端的bin-log的文件名和位置記錄到master-info文件中,以便在下一次讀取的時候能夠清楚的告訴master“我需要從某個bin-log的哪個位置開始往后的日志內容,請發給我”
- Slave的SQL線程檢測到Relay Log中新增加了內容后,會馬上解析該Log文件中的內容成為在Master端真實執行時候的那些可執行的查詢或操作語句,並在自身執行那些查詢或操作語句,這樣,實際上就是在master端和Slave端執行了同樣的查詢或操作語句,所以兩端的數據是完全一樣的。
binlog輸出線程。每當有從庫連接到主庫的時候,主庫都會創建一個線程然后發送binlog內容到從庫。
對於每一個即將發送給從庫的sql事件,binlog輸出線程會將其鎖住。一旦該事件被線程讀取完之后,該鎖會被釋放,即使在該事件完全發送到從庫的時候,該鎖也會被釋放。
在從庫里,當復制開始的時候,從庫就會創建兩個線程進行處理:
從庫I/O線程。當START SLAVE語句在從庫開始執行之后,從庫創建一個I/O線程,該線程連接到主庫並請求主庫發送binlog里面的更新記錄到從庫上。
從庫I/O線程讀取主庫的binlog輸出線程發送的更新並拷貝這些更新到本地文件,其中包括relay log文件。
從庫的SQL線程。從庫創建一個SQL線程,這個線程讀取從庫I/O線程寫到relay log的更新事件並執行。
可以知道,對於每一個主從復制的連接,都有三個線程。擁有多個從庫的主庫為每一個連接到主庫的從庫創建一個binlog輸出線程,每一個從庫都有它自己的I/O線程和SQL線程。
從庫通過創建兩個獨立的線程,使得在進行復制時,從庫的讀和寫進行了分離。因此,即使負責執行的線程運行較慢,負責讀取更新語句的線程並不會因此變得緩慢。比如說,如果從庫有一段時間沒運行了,當它在此啟動的時候,盡管它的SQL線程執行比較慢,它的I/O線程可以快速地從主庫里讀取所有的binlog內容。這樣一來,即使從庫在SQL線程執行完所有讀取到的語句前停止運行了,I/O線程也至少完全讀取了所有的內容,並將其安全地備份在從庫本地的relay log,隨時准備在從庫下一次啟動的時候執行語句
二.mysql8.0.13主從配置
環境介紹及說明
1、主庫所在的操作系統:windows 10 (64位);
主庫目錄:C:\mysql-8.0.13\master\3307
主庫的版本:mysql-8.0.13-winx64.zip;
主庫的ip地址:127.0.0.1;
主庫的端口:3307;
2、從庫所在的操作系統:windows10 (64位);
從庫目錄:C:\mysql-8.0.13\slave\3308
從庫的版本:mysql-8.0.13-winx64.zip;
從庫的ip地址:127.0.0.1;
從庫的端口:3308;
注:主庫和從庫版本可以一致也可以不一致,需要說明一點,如果兩者版本不一致,一般主庫的版本需要比從庫的版本低,這樣就可以避免由於版本問題,有些sql不能執行的問題。
數據庫配置及注冊服務
1、主庫(master)的配置(因為在虛擬機上,C盤為例)
- 將下載的數據庫解壓到:C:\mysql-8.0.13\master\3307;
- 在3307目錄下建立my.ini;配置內容如下:
[mysqld] #主庫配置 server-id=1 #開啟二進制日志 log_bin=master-bin log_bin-index=master-bin.index # 設置3307端口 port=3307 # 設置mysql的安裝目錄 basedir=C:/mysql-8.0.13/master/3307 # 設置mysql數據庫的數據的存放目 datadir=C:/mysql-8.0.13/master/3307/data # 允許最大連接數 max_connections=200 # 允許連接失敗的次數。 max_connect_errors=10 # 服務端使用的字符集默認為UTF8 character-set-server=utf8 # 創建新表時將使用的默認存儲引擎 default-storage-engine=INNODB # 默認使用“mysql_native_password”插件認證 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] # 設置mysql客戶端默認字符集 default-character-set=utf8 [client] # 設置mysql客戶端連接服務端時默認使用的端口 port=3307 default-character-set=utf8
- 管理員身份(必須,必須,必須)運行cmd,並cd到C:\mysql-8.0.13\master\3307\bin下,輸入命令:
mysqld --initialize --user=mysql --console(bin目錄下生成data文件,系統默認創建數據庫,此時還會生成一個臨時的密碼!找不到密碼點擊這里)
- 注冊服務,輸入命令:
mysqld --install mysql-master --defaults-file="C:\mysql-8.0.13\master\3307\my.ini"
- 啟動MySQL服務,輸入命令:(默認是啟動的,可以先登陸數據庫,如果服務沒有啟動,再執行此命令)
net start mysql-master
- 登陸mysql,輸入命令:
mysql -u root -P3307 -p
- 修改密碼,輸入命令:
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密碼';
- 退出mysql,輸入命令:
exit;
重新登陸OK。恭喜,主庫完成!!!
2、從庫(slave)的配置(因為在虛擬機上,C盤為例)
- 將下載的數據庫解壓到:C:\mysql-8.0.13\slave\3308;
- 在3308目錄下建立my.ini;配置內容如下:
[mysqld] #從庫配置 server_id=2 relay-log-index=slave-relay-bin.index relay-log=slave-relay-bin # 設置3308端口 port=3308 # 設置mysql的安裝目錄 basedir=C:/mysql-8.0.13/slave/3308 # 設置mysql數據庫的數據的存放目錄 datadir=C:/mysql-8.0.13/slave/3308/data # 允許最大連接數 max_connections=200 # 允許連接失敗的次數。 max_connect_errors=10 # 服務端使用的字符集默認為UTF8 character-set-server=utf8 # 創建新表時將使用的默認存儲引擎 default-storage-engine=INNODB # 默認使用“mysql_native_password”插件認證 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] # 設置mysql客戶端默認字符集 default-character-set=utf8 [client] # 設置mysql客戶端連接服務端時默認使用的端口 port=3308 default-character-set=utf8
- 管理員身份(必須,必須,必須)運行cmd,並cd到C:\mysql-8.0.13\slave\3308\bin下,輸入命令:
mysqld --initialize --user=mysql --console
- 注冊服務,輸入命令:
mysqld --install mysql-slave3308 --defaults-file="C:\mysql-8.0.13\slave\3308\my.ini"
- 啟動MySQL服務,輸入命令:(默認是啟動的,可以先登陸數據庫,如果服務沒有啟動,再執行此命令)
net start mysql-slave3308
- 登陸mysql,輸入命令:
mysql -u root -P3308 -p
- 修改密碼,輸入命令:
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密碼';
- 退出mysql,輸入命令:
exit;
重新登陸OK。恭喜,從庫完成!!!
3、主庫(master)關聯從庫(slave)配置
- 登陸master主庫,創建一個用於讓從數據庫連接的用戶,輸入命令(自定義用戶warm,密碼為warm123456)
CREATE USER 'warm'@'%' IDENTIFIED WITH mysql_native_password BY 'warm123456';
- 給用戶授權,輸入命令
GRANT REPLICATION SLAVE ON *.* TO 'warm'@'%';
- 刷新權限,輸入命令
flush privileges;
- 查看master的狀態,輸入命令
show master status;
- 登陸slave從庫,在slave從庫節點上設置master主庫主節點參數,輸入命令
CHANGE MASTER TO
MASTER_HOST='172.0.0.1', MASTER_PORT=3307,
MASTER_USER='warm',
MASTER_PASSWORD='warm123456',
MASTER_LOG_FILE='binlog.000012',
MASTER_LOG_POS=631746;
注意,MASTER_LOG_FILE和master狀態里的File保持一致,MASTER_LOG_POS和master狀態里的Positon保持一致
- 開啟主從同步,輸入命令
start slave;
- 查看主從同步狀態,輸入命令
show slave status\G;
Slave_IO_Running和Slave_SQL_Running的狀態都為YES才表示同步成功!!!!
若有錯誤,可在下方查看報錯信息
根據錯誤信息,自行百度!
自行創建庫與表進行驗證即可。
備注:注意不要往從庫中寫數據,如果從庫寫入數據,master_log_pos是不會變化的,主庫的信息沒有發生變化,當主庫又變化和從庫一樣的操作時就有可能會產生沖突,因此,只能在主庫中寫數據,從庫只能讀數據,當然主庫也可以讀數據。
在從庫中建立只讀用戶,避免往從庫中寫數據。
轉載於:https://my.oschina.net/warm6Y/blog/3003452