mysql主從複製

第1章 MySQL主從複製

1.1 數據庫損壞了?

主要理解爲:業務不能使用數據庫mysql

外在緣由:sql

 一、網絡問題數據庫

 二、業務應用有問題,客戶端損壞服務器

數據庫自己的緣由:網絡

 一、物理損壞:機器壞了、硬盤壞了、存儲壞了架構

 二、邏輯損壞:誤drop、delete、truncate、、update。併發

解決方案:app

一、備份負載均衡

二、主從複製異步

1.2 MySQL主從複製

1.2.1 MySQL複製概念

指將主數據庫的DDL和DML操做經過二進制日誌傳到複製服務器上,而後在複製服務器上將這些日誌文件從新執行,從而使複製服務器和主服務器的數據保持同步。複製過程當中一個服務器充當主服務器(master),而一個或多個其它服務器充當從服務器(slaves)。主服務器將更新從新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌能夠記錄發送到從服務器的更新。當一個從服務器鏈接主服務器時,它通知主服務器、從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接受從那時起發生的任何更新,而後封鎖並等待主服務器通知新的更新。

 

複製的用途:

經過主從複製(master-slave)的方式來同步數據,再經過讀寫分離(mysql-proxy)來提高數據庫的併發負載能力,或者用來做爲主備機的設計,保證在主機中止響應以後在很短的時間內就能夠將應用切換到備機上繼續運行。

 

優點:

(1)數據庫集羣系統具備多個數據庫節點,在單個節點出現故障的狀況下,其餘正常節點能夠繼續提供服務。

(2)若是主服務器上出現了問題能夠切換到從服務器上

(3)經過複製能夠在從服務器上執行查詢操做,下降了主服務器的訪問壓力,實現數據分佈和負載均衡

(4)能夠在從服務器上進行備份,以免備份期間影響主服務器的服務。

1.2.2 主從複製簡介

1、能作什麼?

²  高可用

²  輔助備份

²  分擔負載

 

2.主從是怎麼實現的?

²  經過二進制日誌

²  至少兩臺(主, 從)

²  主服務器的二進制日誌」拿「到從服務器上再運行一遍。

²  經過網絡鏈接兩臺機器,通常都會出現延遲的狀態。也能夠說是異步。

 

3.MySQL主從複製的企業應用場景

²  應用場景1:從服務器做爲主服務器的實時數據備份

²  應用場景2:主從服務器實現讀寫分離,從服務器實現負載均衡

²  應用場景3:把多個從服務器根據業務重要性進行拆分訪問

1.2.3 主從複製原理

1. 前提

 

²  主服務器必定要打開二進制日誌

²  必須兩臺服務器(或者是多個實例)

²  從服務器須要一次數據初始化

²  若是主從服務器都是新搭建的話,能夠不作初始化

²  若是主服務器已經運行很長時間了,能夠經過備份將主庫數據恢復到從庫

²  主庫必需要有對從庫複製請求的用戶。

²  從庫須要有relay-log設置,存放從主庫傳過來的二進制日誌

²  在第一次的時候,從庫須要change master to 去鏈接主庫

²  change mater 信息須要存放到master.info中

²  從庫經過relay-log.info記錄了已經應用過的relaylog信息發現了主庫發生了新的變化

²  在複製過程當中涉及到的線程

n  從庫會開啓一個IO thread 負責鏈接主庫,請求binlog,接收binlog並寫入relay-log中。

n  從庫會開啓一個SQ thread 負責執行relay-log中的事件

n  主庫會開啓一個dump thread 複製響應從IO thread中請求

 

複製過程

複製原理

 

 

原理:第一次開啓主從

1.從庫經過change master to 語句鏈接主庫,而且讓從庫知道,二進制日誌的起點位置(file名 position號)

    2.從庫的IO和主庫的dump線程創建鏈接

    3.從庫根據changemaster to 語句提供的file名和position號,IO線程向主庫發起binlog請求

    4.主庫dump線程根據從庫的請求,將本地binlog以events方式發給從庫IO線程

    5.從庫IO線程接收binlog events,並存放到本地relay-log中,傳送過來的信息,會記錄到master.info中。

    6.從庫應用relay-log,而且把應用過來的記錄到relay-log.info,默認狀況下,已經應用過來餓的relay會自動被清理purge。

到此,一次主從複製就完成,一旦主從運行起來,就不須要手工執行changemaster to,由於信息都會被存放到master.info 中,其餘的過程也是同樣的。

注意:若是不是新搭建的主從,須要將原來的數據全備,進行同步到從庫中,而後在開啓change master to。

過程:

1.初始化數據,使用備份將主庫數據恢復到從庫。

2.主庫開啓binlog server id,從庫開啓server id 默認開啓relay log,建議本身設置relay-log,防止從庫忽然修改主機名,relaylog會生成新的名字,原來的就找不到了

3.主庫中建立複製用戶

4.從庫開啓change change master to 

5.開啓slave

6.驗證主從

1.1.1 配置主從

1.在主庫中添加用戶權限
grant replication slave on *.* to repl@'10.0.0.%' identified by '123456';

flush privileges;

初始化數據
2.mysqldump -uroot -p123456 -A -B -F --master-data=2  >/tmp/full.sql

scp /tmp/server.sql 10.0.0.53:/tmp

在從庫中進行source恢復
3.進入二進制文件找position號

在主庫中查看binlog起點

mysql> mysql> show master;

+----------------+----------+--------------+------------------+-------------------+

| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+----------------+----------+--------------+------------------+-------------------+

| log-bin.000013 |      120 |              |                  |                  |

+----------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)
[root@db02 ~]# vi  /tmp/full.sql

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=120;
4.進入從庫開啓主從複製
set sql_log_bin=0;

 CHANGE MASTER TO

       MASTER_HOST='10.0.0.52 ',

       MASTER_USER='repl',

       MASTER_PASSWORD='123456',

       MASTER_PORT=3306,

       MASTER_LOG_FILE='mysql-bin.000004',

       MASTER_LOG_POS=120;

注意:也能夠設置relay-bin的名稱。

檢查狀態

start slave;

show slave status\G

成功的標誌是:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes
查看狀態
[root@db02 ~]# mysql  -S /data/3307/mysql.sock -e "show slave status\G"|egrep "_Running|Behind_Master"|head -3

            Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

        Seconds_Behind_Master: 0

[root@db02 ~]#mysql> show slave status\G #查看狀態

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 10.0.0.52

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000005

          Read_Master_Log_Pos: 544

               Relay_Log_File: DB03-relay-bin.000002

                Relay_Log_Pos: 754

        Relay_Master_Log_File: mysql-bin.000005

             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: 544

              Relay_Log_Space: 957

              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: 52

                  Master_UUID: 9cd29dbb-d003-11e7-a49d-000c29310c49

             Master_Info_File: /application/mysql-5.6.36/data/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: 9cd29dbb-d003-11e7-a49d-000c29310c49:1-2

            Executed_Gtid_Set: 9cd29dbb-d003-11e7-a49d-000c29310c49:1-2,

e19e3a5b-d33f-11e7-b9b6-000c29af0efd:1-123

                Auto_Position: 1

1 row in set (0.00 sec)

 

mysql>

出現故障:

一、緣由:

 

²  主機沒啓動,或者宕機

²  網絡通訊問題

²  防火牆

²  複製用戶密碼(用戶密碼錯誤)

二、故障

Slave_IO_Running: Connecting

Slave_SQL_Running: Yes

或者
Slave_IO_Running: NO

Slave_SQL_Running: NO

緣由:在change master to 的時候,填錯了用戶密碼,端口

 

1.1.2 配置主從注意事項

Slave_*_Running

Slave_IO_RunningI/O 線程正在運行、未運行仍是正在運行但還沒有鏈接到主服務器。可能值分別爲Yes、No 或Connecting。

Slave_SQL_RunningSQL 線程當前正在運行、未運行,可能值分別爲Yes、No

主服務器日誌座標:

Master_Log_File和Read_Master_Log_Pos標識主服務器二進制日誌中I/O 線程已經傳輸的最近事件的座標。

若是Master_Log_File和Read_Master_Log_Pos的值遠遠落後於主服務器上的那些值,這表示主服務器與從屬服務器之間事件的網絡傳輸可能存在延遲。

中繼日誌座標:

Relay_Log_File和Relay_Log_Pos列標識從屬服務器中繼日誌中SQL 線程已經執行的最近事件的座標。這些座標對應於Relay_Master_Log_File和Exec_Master_Log_Pos列標識的主服務器二進制日誌中的座標。

若是Relay_Master_Log_File和Exec_Master_Log_Pos列的輸出遠遠落後於Master_Log_File和Read_Master_Log_Pos列(表示I/O 線程的座標),這表示SQL 線程(而不是I/O 線程)中存在延遲。即,它表示複製日誌事件快於執行這些事件。

Last_IO_Error、Last_SQL_Error

+分別致使I/O 線程或SQL 線程中止的最新錯誤的錯誤消息。在正常複製過程當中,這些字段是空的。若是發生錯誤並致使消息顯示在以上任一字段中,則錯誤值也顯示在錯誤日誌中。

Last_IO_Errno、Last_SQL_Errno

與分別致使I/O 線程或SQL 線程中止的最新錯誤關聯的錯誤編號。在正常複製過程當中,這些字段包含編號0。

Last_IO_Error_Timestamp、Last_SQL_Error_Timestamp

分別致使I/O 線程或SQL 線程中止的最新錯誤的時間戳,格式爲YYMMDD HH:MM:SS。在正常複製過程當中,這些字段是空的。

1.1.3 複製過濾

主庫方面:

    白名單:只記錄白名單中列出的庫的二進制日誌

     binlog-do-db

    黑名單:不記錄黑名單列出的庫的二進制日誌

     binlog-ignore-db

從庫

白名單:只執行白名單中列出的庫或者表的中繼日誌

   

--replicate-do-db=test

--replicate-do-table=test.t1

--replicate-wild-do-table=test.x*

  

黑名單:不執行黑名單中列出的庫或者表的中繼日誌

--replicate-ignore-db

--replicate-ignore-table

--replicate-wild-ignore-table

1.2 錯誤實例

從庫binlog落後於主庫

Master_Log_File: log-bin.000014

Read_Master_Log_Pos: 120

從庫的logbin比主庫的logbin慢的緣由:

網絡問題

主庫dump線程繁忙

從庫IO線程繁忙

【擴展】

延時節點概念:是SQL線程延時,不是IO線程延時。

SQL線程報錯

緣由:

²  主庫操做對象在從庫中不存在

²  主庫操做對象的屬性和從庫不一致

²  主從操做順序顛倒

解決方法:

跳過錯誤

stop slave;

set global sql_slave_skip_counter = 1;

start slave;

也能夠在配置文件中跳過錯誤號碼:

[mysqld]

slave-skip-errors = 1032,1062,1007

 

1.3 企業實例

背景:標準主從複製結構,在業務邏輯中有oldboy數據庫,oldboy數據庫下有t1表爲生產表。

故障緣由:開發人員在從庫建立了一個oldgirl庫,以爲不對,後又在主庫中作了相同的操做。致使了從庫複製失效。

解決方案:

主從複製故障及解決

stop slave; #<==臨時中止同步開關。

set global sql_slave_skip_counter= 1 ; #<==將同步指針向下移動一個,若是屢次不一樣步,能夠重複操做。

start slave;

/etc/my.cnf

slave-skip-errors = 1032,1062,1007

如何避免問題?

從庫設置爲只讀庫

在my.cnf中添加read_only=1

單獨在從庫建立一個只讀用戶

在主庫建立寫用戶

優勢:

配置時不須要重啓

故障切換時也不須要重啓

 

1.4 主從架構演變

1.4.1 演變

備份

  1. 至關於實時備份
  2. 使用從庫備份

問題: 
若是從庫只是做爲備份服務器使用,那麼主庫的壓力會增長,由於全部的業務都在主庫進行讀寫(dump線程讀取併發送給binlog)

解決方法:

  1. 一主一從 
    分出部分讀業務到從庫(讀寫分離)
  2. 一主多從,分擔壓力(針對讀業務多的需求) 
    可是這種一主多從的模式會使dump線程壓力更大了
  3. 多級主從 
    使用中間庫分擔主庫dump線程讀取分發binlog的壓力,因爲中間庫只做爲分發者,不須要其餘操做,爲了提升中間庫的性能,可使用blackhole存儲引擎。
  4. 雙主模型
  5. 環狀複製

1.4.2 高級應用架構

性能

²  讀寫分離——MySQLproxy、amoeba、xx-dbproxy等。

²  分庫分表——cobar、自主研發等。

²  比較依賴於業務

²  實施思路:

²  判斷語句類型

²  根據語句類型進行分發

²  負載均衡,分發到從庫

²  會話持續性(減小用戶認證之類的操做)

²  判斷語句是否執行過(提升性能,減小重複操做)

高可用

²  MMM架構——mysql-mmm(google)(不在使用)

²  MHA架構——mysql-master-ha(日本DeNa)

²  MGR ——5.7 新特性MySQLGroup replication

²  PXC、MySQLCluster架構

1.4.3 多級主從部署(級聯主從)

 

相似於一主一從的部署

不一樣之處在於主從之間多了一箇中間服務器

[mysqld]

basedir = /application/mysql/

datadir = /application/mysql/data/

socket = /application/mysql/tmp/mysql.sock

character_set_server=utf8

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

server-id = 2

log-bin=/tmp/log-bin

binlog-format=row

autocommit=1

log-slave-updates

 

[client]

socket = /application/mysql/tmp/mysql.sock

在中間服務器的my.cnf文件中須要開啓binlog並添加log-slave-updates參數,表示強制刷新binlog,不然binlog日誌不會刷新。

至關於作了兩套主從。

reset slave;重置slave(關閉狀態)

相關文章
相關標籤/搜索