由於mysql對性能的要求較高,而且作向上擴展價格及其昂貴,因此通常都會採用向下擴展的主從複製方案,來提升mysql的性能;主從複製能夠實現僅主mysql服務器能夠提供讀寫數據,而從服務器僅可提供讀數據,即讓來自客戶端的寫請求僅發送至主服務器,讀請求分散發送到各個從服務器,從而提升mysql的併發能力以及處理請求的能力;可是這就要求從服務器中要有主服務器上的所有數據,只有這樣才能讓從從服務器請求到的數據是正確的,因此就要有一種方法來實現主從服務器之間數據的同步;這種方法爲:從服務器會按期向主服務器請求其二進制日誌中的數據,而後主服務器接受請求之後將其要求的數據返回給從服務器,接着從服務器將其寫到本身的中繼日誌中,再經過讀取中繼日誌,將其中的操做再從新操做一遍,並將其記錄到本身的二進制日誌中,從而實現了數據的同步;從服務器的每次請求都會攜帶本身的已經同步的數據的位置,以便主服務器將最新的、本身沒有的數據發送給本身;
Note:從服務器的二進制日誌功能能夠根據須要決定是否啓用,若是此臺從服務器仍是另外一臺服務器的主服務器(級聯複製),則須要啓用二進制日誌功能,若是其只是從服務器,則能夠不啓用二進制日誌功能;
主從複製詳細過程:
從節點啓動一個線程做爲主節點的客戶端,經過mysql協議向mysql主節點請求讀取其二進制日誌文件中的事件;mysql主節點首先會啓動一個線程,而後會檢查從節點發送過來的請求中的關於日誌中的事件位置的號碼,而後主mysql節點會根據這個位置將數據返回給從節點;從節點接收到主mysql節點的響應之後會將其首先存儲在其中繼日誌中,而後再經過一個文件記錄(master.info)本身已經讀到主節點二進制日誌文件中的位置,等下次再請求數據時就會將這個位置發送給主mysql節點,以便請求接下來的數據;從節點接着會再啓動一個線程負責根據中繼日誌將其中的全部記錄將數據都重作一遍;其中主節點中的線程叫作dump線程,爲每一個從節點的I/O Thread啓動一個dump線程,用於向其發送binary log events;從節點中負責請求數據的線程叫作I/O Thread、負責從中繼日誌中讀取事件並在本地重作的線程叫作SQL Thread;
mysql複製的特色:
異步複製:主節點將二進制日誌中的事件發送給從節點之後不會等待從節點的反饋信息就接着處理其餘任務去了;可是這樣有個風險,就是從節點可能沒有接收執行成功,到時數據不一致;
讀寫分離器(r/w spliter):mysql的七層負載均衡器,未來自客戶端的寫請求分發到主節點,將讀請求分發到從節點;
gtid:全局事務ID,能夠在主節點故障時,將從節點提高爲主節點繼續提供服務,可是從節點的數據不必定是最新的,也不必定是完整的,因此能夠經過這個特性,將同是從節點的其餘節點中的,可是本身沒有的數據同步到本身的數據庫中,而後本身做爲主節點提供服務;可是也有缺點,就是技術比較複雜;也能夠經過高可用主節點來增長數據庫持續提供服務的能力;
會致使數據不一致
主從複製的幾種方案:
一主多從:一個主節點,多個從節點;
若是從節點過多則會在主節點中啓動很是多的dump線程,這樣會增長主節點的負載,原本主節點就要處理大量的寫操做,如今又要運行這麼多的線程,將數據發送到各個從節點,這會使主節點不堪重負,,稱爲性能瓶頸;咱們能夠經過級聯的方式減輕主節點的負載,其拓撲通常爲:一個主節點鏈接一個從節點,而後全部其餘的從節點所有鏈接到也主節點相連的從節點上,這樣就減輕了主節點的負載,可是這樣又增長那個特殊從節點的負載,因此咱們讓這個節點只負責將數據複製到各個從節點,而不負責存數據,也就不對外提供讀請求響應了(使用blackhole存儲引擎,將全部數據都傳入黑洞);
雙主多從高可用:兩個主節點,多個從節點,可是同時只有一個主節點在提供服務,另外一個主節點做爲備份節點;
雙主雙從互爲備份:每一個節點既是主節點也是從節點,當一個節點故障時,另外一個節點能夠繼續提供服務;經過Server ID來分辨各個節點,以防止一個節點的操做被複制到另外一個節點上重作一遍之後又被髮回本身自己進行重作,這樣就造成了一個循環,當其發現Server ID是本身時就不會再從新記錄了;這種方案能夠實現讀請求的負載均衡,可是沒有實現寫請求的負載均衡,由於在一個節點中處理寫請求之後,在另外一個節點還會再進行一次;
多主(環狀結構):一個節點的是另外一個節點的從,另外一個節點又是另外一個節點的從,最後造成一個環;
示例:
1.主從複製:
主節點:
a.啓動二進制日誌;
b.爲當前接單設置一個全局惟一的Server ID;
c.建立有複製權限的用戶帳號;
REPLICATION SLAVE,REPLICATION CLIENT
從節點:
a.啓動中繼日誌;
b. 爲當前接單設置一個全局惟一的Server ID;
c.肯定複製位置,即要從主服務器的哪一個位置開始複製數據;
d.使用有複製權限的用戶帳號鏈接至主節點服務器,並啓用相關的線程;
html
192.168.80.143爲主節點:
cat /etc/my.cnf.d/server.cnf
……
[mariadb-5.5]
log_bin=master-bin
server_id=1
innodb_file_per_table=ON
skip_name_resolve=ON
MariaDB [(none)]> grant replication slave,replication client on *.* to 'repluser'@'192.168.80.136' identified by 'replpassword';
192.168.80.136爲從節點:
cat /etc/my.cnf.d/server.cnf
……
[mariadb-5.5]
relay_log=relay-log
relay_log_index=relay-log.index
server_id=5
innodb_file_per_table=ON
skip_name_resolve=ON
MariaDB [(none)]> show master logs; (此操做是在主節點上執行的)
MariaDB [(none)]> change master to master_host='192.168.80.143',master_user='repluser',master_password='replpassword',master_log_file='master-bin.000001',master_log_pos=425; (此操做是在從節點上執行的)
MariaDB [(none)]> show slave status\G;
mysql
MariaDB [(none)]> start slave;
MariaDB [(none)]> show slave status\G;
sql
接下來就能夠在主節點上建立一個數據庫或者表來測試一下從節點中是否也出現相同的改變啦;
注意事項
a.限制從節點爲只讀;
在從節點中設置read_only爲ON;可是此限制對擁有super權限的用戶無效;還有一種方法就是啓動一個鏈接線程,鏈接至mysql中執行mysql>flush tables with read lock;
b.保證主從複製的事務安全
在主節點啓用參數:
sync_binlog=ON 當事務提交時,將二進制日誌緩衝區中的事件當即寫入到磁盤中,避免系統忽然宕機致使數據丟失;
sync_master_info 是否及時將內存中的master.info文件的信息同步到磁盤中;
若是是innodb存儲引擎建議開啓:
innodb_flush_logs_at_trx_commit=ON 在事務提交時,將事務日誌緩衝區中跟事務相關的數據當即寫到事務日誌中;
innodb_support_xa=ON 使innodb支持分佈式事務,使其支持兩段式提交功能;
在從節點啓動的參數:
skip_slave_start=ON 當從節點上的mysql服務啓動之後是否自動啓動複製線程;這個根據狀況而定;
sync_relay_log 是否及時將內存中的relay_log數據同步到磁盤中;
sync_relay_log_info 是否及時將內存中的relay-log.info文件的信息同步到磁盤中;
思考:若是主節點已經運行了一段時間,且有大量數據時,如何配置並啓動從節點?
答:經過備份恢復數據至從服務器,而後在從節點上開始複製起始位置爲備份時的二進制日誌文件及其POS位置;
2.主主複製(互爲主從):
可能會出現的問題:
數據不一致
自動增加ID會出現衝突(因版本而異,如今的新版本已經不會出現這個問題了),能夠經過配置一個節點使用基數ID(auto_increment_offset=1 auto_increment_increment=2),另外一個節點使用偶數ID來解決這個問題(auto_increment_offset=2 auto_increment_increment=2);
配置步驟:
a.各節點使用一個惟一的Server ID;
b.都啓動binary log和relay log;
c.建立擁有複製權限的用戶帳號;
d.定義自動增加id字段的數值範圍爲奇偶(根據狀況而定);
e.均把對方指定爲主節點,並啓用複製線程;
使用192.168.80.143和192.168.80.136這兩臺主機作主主複製:
cat /etc/my.cnf.d/server.cnf
……
[mariadb-5.5]
log_bin=master-bin
relay_log=relay-log
server_id=1
innodb_file_per_table=ON
skip_name_resolve=ON
MariaDB [(none)]>grant replication slave,replication client on *.* to 'repluser'@'192.168.80.136|143' identified by 'replpasswd';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> change master to master_host='192.168.80.136',master_user='repluser',master_password='replpasswd',master_log_file='master-bin.000003',master_log_pos=506;
MariaDB [(none)]> show slave status\G;
數據庫
MariaDB [(none)]> start slave;
安全
接下來就能夠在主節點上建立一個數據庫或者表來測試一下從節點中是否也出現相同的改變啦;
3.半同步複製(google提供的插件):
在配置文件中指明須要安裝的插件的位置(默認不用指定就能夠直接安裝):
/usr/lib64/mysql/plugin/semisync_master.so 主節點
/usr/lib64/mysql/plugin/semisync_slave.so 從節點
安裝插件:
主節點:
mysql>install plugin rpl_semi_sync_master soname ‘semisync_master.so’
mysql>set global variables rpl_semi_sync_master_enabled=1
mysql>show global variables like ‘%semi%’
mysql>show global status like ‘%semi%’
從節點:
mysql> install plugin rpl_semi_sync_slave soname ‘semisync_slave.so’
mysql>set global variables rpl_semi_sync_slave_enabled=1
Note:其餘過程與上面的相似,就不在贅述了;
複製過濾器:
使用複製過濾器能夠實現僅複製指定的數據庫,能夠在主節點實現也能夠在從節點實現,可是在主節點實現會形成主節點的二進制日誌不完整,因此通常都都會在從節點上設置這個功能,即讓從節點只重作指定數據庫或指定數據庫的指定表;
兩種實現方式;
1.主節點僅向二進制日誌中記錄與指定數據庫或指定數據庫的指定表相關的事件;
經過binlog_do_db(白名單)或者binlog_ignore_db(黑名單)來實現;(這個在mariadb-5.5.60中已經沒有了,至少默認是沒有的)
2.從節點SQL Thread在replay中繼日誌中的事件時,僅讀取與指定數據庫或指定數據庫的指定表相關的事件並應用到本地;
經過replicate_do_db|table(白名單)或者replicate_ignore_db|table(黑名單)來實現;
基於SSL的複製:
能夠添加一個限制,就是必須使用ssl鏈接mysql才能夠實現複製:在grant受權用戶時加上require ssl便可;
這篇文章寫的不錯:https://www.cnblogs.com/xiaocen/p/3709838.html
清理二進制日誌:
Examples:
PURGE BINARY LOGS TO 'mysql-bin.010';
PURGE BINARY LOGS BEFORE '2008-04-02 22:46:26';服務器
Note:根據馬哥視頻作的學習筆記,若有錯誤,歡迎指正;侵刪
併發