MySQL 主從複製

標籤:主從前端

概述  

本篇文章主要介紹mysql主從的搭建過程和中間涉及的一些概念知識,但願能最全面的將mysql主從所涉及到的知識都概況進來;環境已經安裝好了mysql,這裏就不介紹mysql的安裝方法。mysql

測試環境:linux

主:mysql(5.6.21),linux:redhat 6.0,ip:192.168.1.6sql

從:mysql(5.6.21),linux:redhat 6.0,ip:192.168.1.7數據庫

原理和概念

主從複製原理

1)主庫在事務提交時會把變動做爲事件記錄(Events)到二進制文件(Binlog)當中緩存

2)主庫將二進制文件中的事件推送到從庫的中繼日誌文件中(Relay-bin),從庫根據中繼日誌中事件作變動操做。服務器

線程

 Binlog Dump線程:該線程運行在主庫上,當主從都配置好後,從庫運行START SLAVE啓動複製後,會在主庫上生成一個Binlog Dump線程,該線程的主要做用就是讀取主庫Binlog事件發送到從庫(從庫的I/O線程)。網絡

 I/O線程:該線程運行在從庫上,I/O線程的做用是向主數據庫要數據而且將主庫發送過來的變動事件寫入到從庫的中繼日誌中。多線程

 SQL線程:該線程運行在從庫上,該線程的主要做用是讀取中繼日誌中的變動事件並更新從庫。併發

 

 該圖來自深刻淺出mysql數據庫開發這本書中。

 

步驟

主庫

在這裏主庫是運行的,主庫的配置文件也是已經配置好了的。

1.配置my.cnf

 

server-id=6
log-bin=/var/lib/mysql/mysql-bin
max_binlog_size = 100M
sync_binlog=0
binlog-format=MIXED
binlog-ignore-db=test
replicate-ignore-db=test

server-id必須是惟一的,默認設置當前IP主機

log-bin是開啓binlog且配置路徑,默認是不開啓的

max_binlog_size設置binlog文件的最大值,這裏設置最大爲100M,當達到這個值會自動生成一個新的binlog文件,固然生成環境會設置的比這個大一點。

sync_binlog:配置是否每次事務提交都須要刷新binlog到磁盤,默認0是不每次刷新,有文件系統本身控制,若是設置爲1默認每次事務提交都會刷新binlog到磁盤,這樣的好處是當系統忽然down掉了系統損傷的會少一點,由於binlog也有緩存,默認事務提交是先寫緩存這樣當系統忽然down掉了就有可能會丟失緩存中的記錄,可是若是每次事務提交都寫磁盤會對性能形成影響,能夠經過半同步複製解決因系統忽然down掉致使binlog緩存數據丟失的問題。

binlog-format:二進制日誌記錄的方法,有三種方式:row(記錄每一行的變動操做,優勢:對複製的兼容性高,缺點:日誌記錄量大,對IO的影響也很大,也不容易用來作分析),STATEMENT(記錄操做的sql語句,這也是默認的格式,優勢:日誌量小,便於用來作分析,IO影響小,缺點:可能會致使複製出錯例若有時候使用的某些函數),MIXED(混合了上面兩種格式,默認採用STATEMENT記錄,當出現不肯定函數時就採起row記錄例如curret_user(),now()等)

binlog-ignore-db:不記錄指定數據庫的binlog,若是指定多個數據庫能夠在配置文件中重複多行。反過來若是配置了binglog-do-db那麼久只記錄指定的這一關數據庫的binlog其它的數據庫都不記錄。

replicate-ignore-db:不復制指定的數據庫的binlog

2.建立複製用戶

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.7' IDENTIFIED BY 'repl';

在主庫上執行,授予192.168.1.7服務器使用用戶repl的REPLICATION SLAVE權限。

3.刷新表並設置數據庫只讀

FLUSH TABLES WITH READ LOCK;

當前主庫只能讀不容許更新操做

4.記錄主庫二進制文件名和偏移量

SHOW MASTER STATUS;

記錄日誌名和便宜量的目的是爲了後面從庫用的

 5.備份主庫

中止主庫服務,須要將主庫的數據庫備份還原到從服務器中去

service mysql stop

備份的方法有不少種:1.若是主庫是在線不能中止服務,能夠經過熱備份方式,使用dump、ibbackup、xtrabackup等熱備份工具有份數據庫而後到從庫還原

2.若是主庫容許中止服務那麼能夠直接cp主庫數據目錄下的全部文件到從庫的路徑下,可使用xftp工具比較方便。

作好了這步就能夠重啓主庫服務了。

從庫

這裏從庫的服務是中止的。

1.配置my.cnf

log-bin=/var/lib/mysql/mysql-bin
server-id=7
max_binlog_size = 100M
sync_binlog=0
binlog-format=MIXED binlog-ignore-db=test replicate-ignore-db=test

注意server-id不能和主相同

2.使用--skip-slave-start方式啓動從庫服務

使用--skip-slave-start啓動的目的是爲了避免當即啓動從服務器上面的複製進程,方便對後面的配置操做。

mysqld_safe --skip-slave-start &

3.登入mysql

mysql -uroot -p123456

登入mysql後執行如下操做

change master to  
master_host = '192.168.1.6',  
master_user = 'repl',  
master_password = 'repl',  
master_log_file = 'mysql-bin.000046',  
master_log_pos = 211991;

 啓動從庫slave線程

start slave

4.檢查

 在從庫上執行

show processlist\G;

 代表已經鏈接上面了master

注意線程3中的Time字段:該時間表示上次執行的語句在主庫二進制文件中記錄的時間和更新到從庫的時候的當前時間的時間差,若是主庫更新很是頻繁而從庫又跟不上主庫更新的速度的時候該時間差值會增大(影響的因素有:從庫的硬件和主庫的差距、網絡傳輸、早期版本的從庫sql線程是單線程寫而主庫應用前端的寫的多線程併發寫)。

 

測試

在主庫上執行

#在主庫上建立repltest數據庫並在數據庫下建立test表插入數據
create database repltest;

use repltest
create table test(id int);
insert into test() values(1),(2);

#測試在已有的test數據庫下建立norepl表並插入數據
use test
create table norepl(id int);
insert into norepl() values(1);

在從庫執行

select * from repltest.test;

select * from test.norepl;

結果除了test數據庫的操做不會被複制之外其餘的數據操做都會被複制到從庫。這也正符合前面的設置。

 

補充

 從服務器啓動參數

–read_only
該選項讓從服務器只容許來自從服務器線程或具備SUPER權限的用戶的更新(ALL PRIVILEGES權限的用戶也不行,必須是超級用戶)。能夠確保從服務器不接受來自客戶的更新。

–replicate_do_db=db_name
告訴從服務器只作默認數據庫(由USE所選擇)爲db_name的語句的複製。要指定多個數據庫,應屢次使用該選項,每一個數據庫使用一次。請注意不復制跨數據庫的語句

–replicate_do_table=db_name.tbl_name
告訴從服務器線程只作對指定表的複製。要指定多個表,應屢次使用該選項,每一個表使用一次。同–replicate-do-db對比,容許跨數據庫更新。

–replicate_ignore_db=db_name
告訴從服務器不要複製默認數據庫(由USE所選擇)爲db_name的語句。要想忽略多個數據庫,應屢次使用該選項,每一個數據庫使用一次。

–replicate-ignore-table=db_name.tbl_name
告訴從服務器線程不要複製更新指定表的任何語句(即便該語句可能更新其它的表)。要想忽略多個表,應屢次使用該選項,每一個表使用一次。

–replicate_wild_do_table=db_name.tbl_name
告訴從服務器線程限制複製更新的表匹配指定的數據庫和表名模式的語句。模式能夠包含‘%'和‘_'通配符,與LIKE模式匹配操做符具備相同的含義。要指定多個表,應屢次使用該選項,每一個表使用一次。該選項能夠跨數據庫進行更新。

–replicate_wild_ignore_table=db_name.tbl_name
告訴從服務器線程不要複製表匹配給出的通配符模式的語句。要想忽略多個表,應屢次使用該選項,每一個表使用一次。該選項能夠跨數據庫進行更新。

–replicate_rewrite_db=from_name->to_name
告訴從服務器若是默認數據庫(由USE所選擇)爲主服務器上的from_name,則翻譯爲to_name。隻影響含有表的語句

–report_host=slave_name
從服務器註冊過程當中報告給主服務器的主機名或IP地址。該值出如今主服務器上SHOW SLAVE HOSTS的輸出中。若是不想讓從服務器本身在主服務器上註冊,則不設置該值。

–report_port=slave_port
鏈接從服務器的TCP/IP端口號,從服務器註冊過程當中報告給主服務器。

–skip_slave_start
告訴從服務器當服務器啓動時不啓動從服務器線程。使用START SLAVE語句在之後啓動線程。

–slave_skip_errors=[err_code1,err_code2,… | all]
一般狀況,當出現錯誤時複製中止,這樣給你一個機會手動解決數據中的不一致性問題。該選項告訴從服務器SQL線程當語句返回任何選項值中所列的錯誤時繼續複製

log_slave_updates
配置從庫的更新操做是否寫二進制日誌,默認從庫讀取主庫過來的二進制日誌只寫入中繼日誌文件中(mysqld-relay-bin.000001)文件中不會寫入從庫的二進制文件中,不管從庫的二進制文件是否開啓,若是你須要主庫傳遞過來的二進制日誌寫入從庫的二進制文件中就必須開啓此參數,該參數不能在線開啓,只能修改配置文件「
log_slave_updates=1」,默認不打開,除非你的從庫還須要做爲其它從庫的主庫,若是開啓次參數須要和bin-log一塊兒開啓。

master_connect_retry
配置從庫和主庫鏈接中斷後重試鏈接的時間間隔,默認是60S

 

複製線程狀態

經過show processlist \G能夠查看複製線程狀態。常見的線程狀態有:
(1)主服務器Binlog Dump線程
Has sent all binlog to slave; waiting for binlog to be updated
線程已經從二進制日誌讀取全部主要的更新並已經發送到了從服務器。線程如今正空閒,等待由主服務器上新的更新致使的出如今二進制日誌中的新事件。

(2)從服務器I/O線程狀態
Waiting for master to send event
線程已經鏈接上主服務器,正等待二進制日誌事件到達。若是主服務器正空閒,會持續較長的時間。若是等待持續slave_read_timeout秒,則發生超時。此時,線程認爲鏈接被中斷並企圖從新鏈接。

(3)從服務器SQL線程狀態
Reading event from the relay log
線程已經從中繼日誌讀取一個事件,能夠對事件進行處理了。
Has read all relay log; waiting for the slave I/O thread to update it
線程已經處理了中繼日誌文件中的全部事件,如今正等待I/O線程將新事件寫入中繼日誌。

 

文件

在從庫的數據庫路徑下會發現生成了三個文件:master.info,relay-log.info,relay-bin

master.info:用來記錄從庫的I/O線程當前讀取到主庫的binglog的位置。

relay-log.info:用來記錄從庫的SQL線程當前讀取到中繼日誌(relay-bin)的位置。

relay-bin:中繼日誌,中繼日誌記錄的格式和主庫的二進制日誌是同樣的,可是中繼日誌在SQL線程執行完當前中繼日誌中的事件以後會刪除中繼日誌中的內容。

 

從庫複製狀態

能夠在從庫上經過show slave status \G查看

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.6
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000047
          Read_Master_Log_Pos: 763952
               Relay_Log_File: localhost-relay-bin.000003
                Relay_Log_Pos: 764115
        Relay_Master_Log_File: mysql-bin.000047
             Slave_IO_Running: Yes
            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: 763952
              Relay_Log_Space: 764455
              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: 6
                  Master_UUID: d58e2793-8534-11e5-b224-000c2908cc04
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0

 

Slave_IO_State: 線程已經鏈接上主服務器,正等待二進制日誌事件到達
Master_Host: 主服務器ip
Master_User: 鏈接主服務器使用的用戶
Master_Port: 主服務器的端口
Connect_Retry: 當從新創建主從鏈接時,若是鏈接創建失敗,間隔多久後重試,默認60s。
Master_Log_File: I/O線程當前正在讀取的主服務器二進制日誌文件的名稱
Read_Master_Log_Pos: 在當前的主服務器二進制日誌中,I/O線程已經讀取的位置。
Relay_Log_File: SQL線程當前正在讀取和執行的中繼日誌文件的名稱
Relay_Log_Pos: SQL線程在當前的中繼日誌中已讀取和執行的位置。
Relay_Master_Log_File: SQL線程執行的主服務器二進制文件
Slave_IO_Running: I/O線程是否運行併成功地鏈接到主服務器上。
Slave_SQL_Running: SQL線程是否運行。
Replicate_Do_DB:用於複製的數據庫,必須在配置文件中配置了
Replicate_Ignore_DB:不用來複制的數據庫
Replicate_Do_Table:複製表
Replicate_Ignore_Table:不復制的表
Replicate_Wild_Do_Table: 限制複製更新的表匹配指定的數據庫和表名模式的語句
Replicate_Wild_Ignore_Table: 不要複製表匹配給出的通配符模式的語句
Last_Errno:錯誤代碼
Last_Error:錯誤信息
Skip_Counter: SQL_SLAVE_SKIP_COUNTER的值
Exec_Master_Log_Pos: 主服務器上一個被執行的位置
Relay_Log_Space: 中繼日誌文件大小
Until_Condition: 在START SLAVE語句的UNTIL子句中指定的值
Until_Log_File: 用於指示日誌文件名
Until_Log_Pos: 位置值
Master_SSL_Allowed: 若是容許對主服務器進行SSL鏈接,則值爲Yes
不然NO
Master_SSL_CA_File:下面的這些都是SSL鏈接的一些信息
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 本字段是從屬服務器落後多少的一個指示(這個狀態是一個很重要的性能指標,正常爲0,若是從服務器的I/O線程沒法鏈接主服務器顯示null)
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 最近的IO線程錯誤代碼,其中2003表明I/o線程沒法鏈接主服務器
Last_IO_Error: 最近的IO線程錯誤信息(例如:error reconnecting to master 'repl@192.168.1.6:3306' - retry-time: 60  retries: 3)
Last_SQL_Errno: 最近的SQL線程錯誤代碼
Last_SQL_Error: 最近的SQL線程錯誤信息
Replicate_Ignore_Server_Ids:
Master_Server_Id: 主服務器的服務器ID
Master_UUID: 主服務器的UUID值
Master_Info_File: 從服務器的master.info文件路徑
SQL_Delay: 正數代表slave有延遲了
SQL_Remaining_Delay: 整數代表延遲時間
Slave_SQL_Running_State: SQL線程運行狀態(SQL線程已經處理了中繼日誌文件中的全部事件,如今正等待I/O線程將新事件寫入中繼日誌。
)
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:最近的I/O線程錯誤時間
Last_SQL_Error_Timestamp:最近的SQL線程報錯時間
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0

其中須要注意比較重要的狀態:Slave_SQL_Running以前的這十幾個狀態再加上Last_IO_Errno,Last_IO_Error,Last_SQL_Errno,Last_SQL_Error,SQL_Delay,SQL_Remaining_Delay,Slave_SQL_Running_State,Last_IO_Error_Timestamp,Last_SQL_Error_Timestamp,Seconds_Behind_Master

 

解決主從延時的方案

從前面總結的延時致使的緣由主要有可能來自如下三個緣由:

網絡傳輸:對應網絡傳輸這塊只能從硬件方面解決,避免千兆網關用百兆網線、百兆網卡等狀況,主從在同一網段。

硬件問題:對應由於主從的硬件相差很是大的狀況,能夠適當提升從庫的硬件。

併發寫的問題:在5.6版本以後從庫的sql線程改爲了併發寫,有助於提升從庫的寫延時的問題;

查詢從庫配置的多個SQL線程
show variables like '%slave_parallel_workers%';

還有一種方案是對於一主多從的方案能夠將主庫的複製數據庫或者表分散到每一個從庫上面,例如每一個從庫複製一個數據庫來減小從庫的壓力,可是這種方案對於主宕機以後因爲每一個從庫只有單個數據庫的數據若是須要組合多個從庫的數據會有點麻煩。

總結

在企業的環境中主從複製是最基礎也是很是廣泛的一種形式,相對來講配置管理也比較簡單。上面講的是一主一從,在這基礎上只要再添加從服務器就能夠作到一主多從的結構,可是這種結構對於主服務器的可靠性要求很高,這就又有了主主複製,後面會花點時間寫一篇關於主主複製的文章,歡迎關注。

 

 

 

備註:

    做者:pursuer.chen

    博客:http://www.cnblogs.com/chenmh

本站點全部隨筆都是原創,歡迎你們轉載;但轉載時必須註明文章來源,且在文章開頭明顯處給明連接,不然保留追究責任的權利。

《歡迎交流討論》

 

---恢復內容結束---

相關文章
相關標籤/搜索