一、MySQL主從複製的原理
1、mysql的複製過程:每執行一個寫操作,它都會往自己的數據庫中存一份,與此同時這個寫操作也會存儲在二進制日誌文件中一份,並且把它們保存爲事件,所以在這個數據庫上,前端數據每執行一個寫操作或者有可能引起修改的操作,都會保存一個事件,我們就把這個事件通過mysql服務器3306端口發送給另外一臺服務器,另外一臺服務器把這個事件接收下來,接受下來以後先保存在本地的日誌文件中,而後從這個日誌文件中一次讀一個事件並且在本地執行一下,然後保存在數據庫裏面,這個過程就叫mysql的複製。如下圖所示:
2、在這樣一個模型當中,我們把允許來自外部操作記錄下來記錄到數據庫中,並保存至二進制文件中的這臺服務器叫做複製架構中主服務器(master)。主服務器中的日誌文件叫二進制日誌。
3、slave:從服務器中的日誌文件是從主服務器中複製過來的,叫做中繼日誌,主要目的是複製下來,再在本地用一遍,相當於產生一個接力的過程。
4、主服務器允許並行執行,主服務器上若有多個CPU,它允許多個服務器並行執行。但是我們寫到二進制文件中,只能一條一條的寫,從服務器只能一條一條的執行。從服務器默認情況下也只能是一個進程,讀一條執行一個,所以從服務器慢於主服務器。
二、MySQL主從複製實現的過程
1、主服務器的配置過程
1)添加系統用戶並修改權限
2)下載mysql軟件包解壓後並創建鏈接
[root@node1 ~]# lftp 172.16.0.1/pub/Sources/mysql-5.5/ 下載mysql-5.5包
cd ok, cwd=/pub/Sources/mysql-5.5
lftp 172.16.0.1:/pub/Sources/mysql-5.5> ls
...
lftp 172.16.0.1:/pub/Sources/mysql-5.5> get mysql-5.5.28-linux2.6-i686.tar.gz
179907710 bytes transferred in 25 seconds (6.89M/s)
lftp 172.16.0.1:/pub/Sources/mysql-5.5> bye
3)初始化數據庫並複製文件
4)修改配置文件並複製到從服務器
[root@node1 mysql]# vim /etc/my.cnf 修改配置文件內容如下:
[root@node1 ~]# scp /etc/my.cnf node2:/etc/ 把配置文件複製到從服務器
my.cnf 100% 4746
5)啓動mysql,測試能否連接到mysql
[root@node1 mysql]# vim /etc/profile.d/mysql.sh 爲了以下命令用起來方便,編輯配置文件
[root@node1 mysql]# . /etc/profile.d/mysql.sh 執行一下腳本
6)複製mysql軟件包到從服務器,然後連接到mysql創建用戶
2、配置從服務器
1)創建用戶修改權限並解壓軟件包連接到數據庫
[root@node2 ~]# mkdir -pv /mydata/data
mkdir: created directory `/mydata'
mkdir: created directory `/mydata/data'
[root@node2 ~]# useradd -r mysql
[root@node2 ~]# chown -R mysql.mysql /mydata/data/
[root@node2 ~]# tar xf mysql-5.5.28-linux2.6-i686.tar.gz -C /usr/local/
[root@node2 ~]# cd /usr/local/
[root@node2 local]# ls
bin etc games include lib libexec mysql-5.5.28-linux2.6-i686 sbin share src
[root@node2 local]# ln -sv mysql-5.5.28-linux2.6-i686 mysql
create symbolic link `mysql' to `mysql-5.5.28-linux2.6-i686'
[root@node2 local]# cd mysql
[root@node2 mysql]# chown -R root.mysql 改變屬主屬組
[root@node2 mysql]# ll
[root@node2 mysql]# scripts/mysql_install_db --user=mysql --datadir=/mydata/data/ 初始化數據庫
2)複製腳本內容並修改所需配置文件
[root@node2 mysql]# vim /etc/my.cnf 修改配置文件內容如下:
3)啓動mysql
[root@node2 mysql]# service mysqld start
Starting MySQL.... [ OK ]
[root@node2 mysql]# vim /etc/profile.d/mysql.sh 編輯配置文件的內容如下:
[root@node2 mysql]# . !$ 讀一下上面的腳本
. /etc/profile.d/mysql.sh
4)在主節點上即HA1上查看從哪個節點開始複製
[root@node1 ~]# mysql
5)修改主服務器的一些屬性
6)查看從服務器啓動前後的狀態
mysql> start slave; 啓動從服務器
Query OK, 0 rows affected (0.00 sec)
到這裏主從複製架構依然完成。
3、主服務器上創建數據,從服務器上是否會出現
1)在主服務器連接到數據庫並創建數據庫
2)查看從服務器的狀態,並查看數據庫
4)讓從服務器變成只讀的
[root@node2 mysql]# vim /etc/my.cnf 修改配置文件,讓read_only = ON永久有效
5)重啓服務器,查看read_only是否啓動
(read-only = YES 對具有SUPER權限的用戶不生效)
mysql> show slave status\G 查看複製線程能否自動運行
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.66.6
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 430
Relay_Log_File: relay-log.000004
Relay_Log_Pos: 254
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Yes 當使用change master to之後
Slave_SQL_Running: Yes 就算重啓服務器複製線程也會自動啓動
Replicate_Do_DB:
Replicate_Ignore_DB:
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: 430
Relay_Log_Space: 404
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
6)查看/mydata/data/下的文件
[root@node2 mysql]# cd /mydata/data/ 切換到/mydata/data目錄下
[root@node2 data]# ls 查看文件
ibdata1 master-bin.000001 master-bin.index node2.magedu.com.pid relay-log.index
ib_logfile0 master-bin.000002 master.info performance_schema relay-log.info
ib_logfile1 master-bin.000003 mysql relay-log.000003 test
magedudb master-bin.000004 node2.magedu.com.err relay-log.000004
[root@node2 data]# file master.info 查看master.info
master.info: ASCII text 純ASCII碼的文件
[root@node2 data]# file relay-log.info
relay-log.info: ASCII text 純ASCII碼的文件
[root@node2 data]# cat relay-log.info 查看一下relay-log.info裏面的內容
./relay-log.000004 當前使用的relay-log文件事件位置
254
master-bin.000001 正在讀取的主服務器上的二進制文件事件位置
430
【read-only = YES 只讀,在從服務器上,但對具有SUPER權限的用戶不生效;所以管理員照樣能寫;
sync-binlog = ON 在主服務器上設定,用於事務安全; 】
7、有沒有這樣一個問題呢?在主服務器上某個事物已經提交了,而有些事務仍然在緩衝區內,萬一這個時候主服務器崩潰了,從服務器上能否得到復件?如何降低主從不一致的可能性呢?應該配置主服務器同步二進制日誌。
配置主服務器同步二進制日誌
mysql> show global variables like '%log%'; 查看跟日誌相關的內容
8、我們的從服務器啓動起來後會自動連接主服務器,如果主服務器崩潰了,從服務器啓動後還會自動連接到主服務器複製二進制日誌,一般來講不應該讓從服務器從複製線程自動啓動,怎麼讓從服務器不會自動啓動?
1)首先連接到mysql查看從服務器相關的內容
mysql>show global variables like '%slave%';
2)如果想徹底的重新定義mysql從服務器的話,執行mysql服務器線程了可以手動停掉;具體過程如下:
mysql> stop slave IO_THREAD; 停掉線程服務
mysql> show slave status/G 查看狀態
補充:也可以一個一個的停掉線程服務
mysql> start slave IO_THREAD;
mysql> show slave status/G
mysql> start slave SQL_THREAD;
mysql> show slave status/G
mysql> \q
所有跟從服務器相關的內容都會保存在數據庫服務的錯誤日誌當中
[root@node2 mysql]# tail /mydata/data/node2.magedu.com.err
三、如何實現mysql的半同步複製
1、在主服務器和從服務器上各自安裝一個插件,這個插件是google提供的。
[root@node2 data]# cd /usr/local/mysql 切換到mysql路徑下
[root@node2 mysql]# ls
[root@node2 mysql]# cd lib/plugin
(semisync_master.so是半同步的主服務器上安裝的插件,semisync_slave.so是半同步的從服務器上安裝的插件)
1)主服務器上的配置:
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; 裝載模塊
rpl_semi_sync_master是模塊(插件)名稱、semisync_master.so是模塊文件名
mysql> show global variables like '%rpl%';
2)從服務器上的配置:
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; 裝載模塊
mysql> show variables like 'rpl%'; 查看rpl開頭的
2、啓用rpl_semi_sync_master_enabled模塊
1)主服務器上:
mysql> set global rpl_semi_sync_master_enabled=1; 啓用rpl_semi_sync_master_enabled
mysql> show global varitables like '%rpl%'; rpl_semi_sync_master_enabled 顯示爲ON了
2)從服務器上:
mysql> set global rpl_semi_sync_master_enabled=1; 啓用rpl_semi_sync_master_enabled
mysql> show global varitables like '%rpl%'; rpl_semi_sync_master_enabled 顯示爲ON了
mysql> show global status like 'rpl%'; 查看全局狀態變量
mysql> stop slave IO_THREAD; 停掉IO線程
mysql> start slave IO_THREAD; 啓用IO線程
mysql> show global status like 'rpl%';
到此,半同步複製就結束了。