簡單來講就是保證主服務器(Master)和從服務器(Slave)的數據是一致性的,向Master插入數據後,Slave會自動從Master把修改的數據同步過來(有必定的延遲),經過這種方式來保證數據的一致性,就是Mysql複製css
1、高可用和故障切換
複製可以幫避免MySql單點失敗,由於數據都是相同的,因此當Master掛掉後,能夠指定一臺Slave充當Master繼續保證服務運行,由於數據是一致性的(若是當插入Master就掛掉,可能不一致,由於同步也須要時間),固然這種配置不是簡單的把一臺Slave充當Master,畢竟還要考慮後續的Salve同步Mastermysql
2、負載均衡
由於讀寫分離也算是負載均衡的一種,因此就不單獨寫了,由於通常都是有多臺Slave的,因此能夠將讀操做指定到Slave服務器上(須要代碼控制),而後再用負載均衡來選擇那臺Slave來提供服務,同時也能夠吧一些大量計算的查詢指定到某臺Slave,這樣就不會影響Master的寫入以及其餘查詢sql
3、數據備份
通常咱們都會作數據備份,多是寫定時任務,一些特殊行業可能還須要手動備份,有些行業要求備份和原數據不能在同一個地方,因此主從就能很好的解決這個問題,不只備份及時,並且還能夠多地備份,保證數據的安全shell
4、業務模塊化
能夠一個業務模塊讀取一個Slave,再針對不一樣的業務場景進行數據庫的索引建立和根據業務選擇MySQL存儲引擎, 不一樣的slave能夠根據不一樣需求設置不一樣索引和存儲引擎數據庫
主從配置須要注意的點
(1)主從服務器操做系統版本和位數一致;
(2) Master和Slave數據庫的版本要一致;
(3) Master和Slave數據庫中的數據要一致;
(4) Master開啓二進制日誌,Master和Slave的server_id在局域網內必須惟一;緩存
複製有三個步驟:
一、Master將數據改變記錄到二進制日誌(binary log)中,也就是配置文件log-bin指定的文件,這些記錄叫作二進制日誌事件(binary log events)
二、Slave經過I/O線程讀取Master中的binary log events並寫入到它的中繼日誌(relay log)
三、Slave重作中繼日誌中的事件,把中繼日誌中的事件信息一條一條的在本地執行一次,完成數據在本地的存儲,從而實現將改變反映到它本身的數據(數據重放)安全
第一步Master記錄二進制日誌, 每次提交事務完成數據更新前,Master將數據更新的時間記錄到二進制日誌中,MySql會按事務提交的順序而非每條語句的執行順序來記錄二進制日誌。再記錄二進制日誌後,主庫會告訴存儲引擎能夠提交事務了。ruby
第二步,Slave將Master的二進制日誌複製到本地的中繼日誌中,首先,Slave會啓動一個工做線程,成爲I/O線程, I/O線程跟Master創建一個普通的客戶端連接,而後再Master上啓動一個特殊的二進制轉儲(binlog dump)線程(該線程沒有對應的SQL命令),這個二進制轉儲線程會讀取主庫上的二進制日誌中的事件。從庫I/O線程將接受到時間記錄到中繼日誌中。bash
第三步從庫的SQL線程執行最後異步,該線程的從中繼日誌中讀取事件並在從庫執行,從而實現從庫數據更新。服務器
這種複製架構實現了獲取事件和重放事件的解偶,容許這兩個過程異步進行。也就是說I/O線程可以獨立於SQL線程以外工做。但這種架構頁限制了複製的過程,其中最重要的一點是主庫上併發運行的查詢再從庫只能串行化執行,由於只有一個SQL線程重放中繼日誌中的事件。這是不少工做負載的性能瓶頸所在。由於始終受限於單線程。
一、基於語句的複製
在Master上執行的SQL語句,在Slave上執行一樣的語句。MySQL默認採用基於語句的複製,效率比較高。一旦發現無法精確複製時,會自動選着基於行的複製
二、基於行的複製
把改變的內容複製到Slave,而不是把命令在Slave上執行一遍。從MySQL5.0開始支持
三、混合類型的複製
默認採用基於語句的複製,一旦發現基於語句的沒法精確的複製時,就會採用基於行的複製
相應地,binlog的格式也有三種:STATEMENT,ROW,MIXED。
要配置主從複製,咱們在本機開多個Mysql實例來操做就能夠了,讓他們監聽不一樣端口
多開實例能夠看我另外一篇教程:同一臺Ubuntu 啓動多個mysql
如今咱們兩個實例Mysql
server1 : 127.0.0.1 3306 master
server2 : 127.0.0.1 3301 slave
配置master
在主庫建立一個複製賬號,這個賬號是給從庫的IO線程創建鏈接到主庫時用的,從庫會用這個賬號鏈接主庫並讀取主庫的二進制日誌:
grant replication slave, replication client on *.* to 'repl'@'localhost' identified by '123456';
主庫添加配置:
# 設置server_id,通常設置爲IP, 要獨一無二的 server-id = 10 # 開啓二進制日誌功能,最好是絕對路徑 log_bin = /var/log/mysql/mysql-bin.log # 主從複製的格式(mixed,statement,row,默認格式是statement) binlog_format=mixed # 二進制日誌自動刪除/過時的天數。默認值爲0,表示不自動刪除。 expire_logs_days=7 # 爲每一個session 分配的內存,在事務過程當中用來存儲二進制日誌的緩存 binlog_cache_size=1M # 複製過濾:不須要備份的數據庫,不輸出(mysql庫通常不一樣步) binlog-ignore-db=mysql
啓用二進制日誌後,重啓後, show master status; 能夠看到二進制相關信息
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000008 | 107 | | | +------------------+----------+--------------+------------------+
添加從庫配置
# 設置server_id,通常設置爲IP, 要獨一無二的 server-id = 10 log_bin = /var/log/mysql/mysql-bin.log # 中繼日誌路徑 relay_log = /home/mysql/3301/mysql-relay-bin # 容許從庫將其重放的事件也記錄到自身的二進制日誌中 log_slave_updates = 1 read_only = 1
從庫開啓複製
mysql> CHANGE MASTER TO
MASTER_HOST='$host', MASTER_USER='repl', MASTER_PASSWORD='123456', MASTER_LOG_FILE='msyql-bin.00001', MASTER_LOG_POS=0;
MASTER_LOG_POS設爲0,是從日誌開頭開始複製,MASTER_LOG_FILE是master的二進制文件
# 啓動複製
mysql> start slave; # 查看複製狀態 mysql> show slave status; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 127.0.0.1 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000008 Read_Master_Log_Pos: 107 Relay_Log_File: mysql-relay-bin.000020 Relay_Log_Pos: 253 Relay_Master_Log_File: mysql-bin.000008 Slave_IO_Running: Yes Slave_SQL_Running: Yes Seconds_Behind_Master: 0 Master_Server_Id: 10 # Slave_IO_Running: Yes,Slave_SQL_Running: Yes 說明同步正常進行 # Seconds_Behind_Master: 0 就是徹底同步了
這時就完成了主從複製的配置,當主服務器有更新,從庫也會更新。
咱們還能夠從線程列表看出複製線程,主庫上能夠看到由從庫I/O線程向主庫發起的鏈接。
mysql> show processlist \G
*************************** 1. row *************************** Id: 44 User: repl Host: localhost:32866 db: NULL Command: Binlog Dump Time: 73032 State: Master has sent all binlog to slave; waiting for binlog to be updated Info: NULL
一樣,咱們看看從庫的線程,有兩個,一個I/O線程,一個SQL線程:
mysql> show processlist \G
*************************** 1. row *************************** Id: 4 User: system user Host: db: NULL Command: Connect Time: 73422 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 5 User: system user Host: db: NULL Command: Connect Time: 72417 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL
這兩個線程都是再system user 賬號下運行,I/O線程是寫日誌到中繼日誌的線程, SQL線程是重放SQL的線程。
那麼,至此咱們已經完成了Mysql的主從配置。
可是上面是配置兩臺恰好安裝號的服務器,數據相同,而且知道當前主庫二進制日誌。
更典型的案例是,一個運行已經一段時間的主庫,要用一臺新安裝的從庫與之同步,此時這臺從庫尚未數據。
因此咱們得想辦法,線初始化從庫: 從主庫複製數據、使用最近依次備份來啓動從庫。
這須要三個條件來讓主庫和從庫保持同步:
複製數據到從庫
mysqldump --single-transaction --all-databases --master-data=1 -uroot -p123456|mysql -S /home/mysql/3301/mysqld.sock -uroot -p123456
連接:https://www.jianshu.com/p/63c1a1babfd1