MySQL Replication 主從復制全方位解決方案


1.1 主從復制基礎概念

    在了解主從復制之前必須要了解的就是數據庫的二進制日志(binlog),主從復制架構大多基於二進制日志進行,二進制日志相關信息參考:http://www.cnblogs.com/clsn/p/8087678.html#_label6

1.1.1 二進制日志管理說明

  二進制日志在哪?如何設置位置和命名?

    在my.cnf文件中使用 log-bin = 指定;命名規則為 mysql-bin.000000 (后為6位數字)

  二進制日志位置

mysql> show variables like '%log_bin%' ;
+---------------------------------+-----------------------------------------+
| Variable_name                   | Value                                   |
+---------------------------------+-----------------------------------------+
| log_bin                         | ON                                      |
| log_bin_basename                | /application/mysql/data/mysql-bin       |
| log_bin_index                   | /application/mysql/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF                                     |
| log_bin_use_v1_row_events       | OFF                                     |
| sql_log_bin                     | ON                                      |
+---------------------------------+-----------------------------------------+
6 rows in set (0.06 sec)

       日志命名

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |      2979 |
| mysql-bin.000002 |       120 |
+------------------+-----------+
2 rows in set (0.00 sec)

  二進制日志記錄什么?

    二進制日志中記錄的是一個個完成的事件

  二進制日志格式是怎樣的?

    推薦使用row格式

       查看當前使用的日志 格式。

mysql> show variables like '%format%';
+--------------------------+-------------------+
| Variable_name            | Value             |
+--------------------------+-------------------+
| binlog_format            | ROW               |
| date_format              | %Y-%m-%d          |
| datetime_format          | %Y-%m-%d %H:%i:%s |
| default_week_format      | 0                 |
| innodb_file_format       | Antelope          |
| innodb_file_format_check | ON                |
| innodb_file_format_max   | Antelope          |
| time_format              | %H:%i:%s          |
+--------------------------+-------------------+
8 rows in set (0.00 sec)

  二進制日志如何滾動?

    每次重啟都會刷新日志,也可以通過命令進行刷新  reset master;

  二進制日志用來干嘛?

    備份恢復

    起始點的備份恢復

  二進制日志的操作命令?

         查看都有哪些二進制日志

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |      2979 |
| mysql-bin.000002 |       167 |
| mysql-bin.000003 |       120 |
+------------------+-----------+
3 rows in set (0.00 sec)

         查看當前使用的二進制日志文件

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

    binlog相關詳情參照:http://www.cnblogs.com/clsn/p/8087678.html#_label6

1.1.2 mysql傳統備份方式和缺陷

  1、二進制日志備份

  2、mysqldump

       a)必須有數據庫服務器完成邏輯工作,需要更多地cpu周期

       b)邏輯備份還原速度慢:需要MySQL加載和解釋語句、轉化存儲格式、重建引擎

  3、xtrabackup

       a)文件大

     b)不總是可以跨平台、操作系統和MySQL版本

1.1.3 MySQL主從復制能為我們做什么

     高可用、輔助備份、分擔負載

1.2 MySQL主從復制介紹

1.2.1 復制技術

作用

  1.保證數據安全(異機實時備份)

  2.保證服務持續運行(宕機接管)

主從復制實現基本原理

  1.自帶功能,復制是 MySQL 的一項功能,允許服務器將更改從一個實例復制到另一個實例。

  2.主服務器將所有數據和結構更改記錄到二進制日志中。

  3.從屬服務器從主服務器請求該二進制日志並在本地應用其內容。即通過把主庫的binlog傳送到從庫,從新解析應用到從庫。

1.2.2 復制架構

mysql復制的應用常見場景:

應用場景1:從服務器作為主服務器的實時數據備份

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

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

1.2.2.1  主–從復制

  傳統的 MySQL 復制提供了一種簡單的主–從復制方法。 有一個主,以及一個或多個從。 主節點執行和提交事務,然后將它們(異步地)發送到從節點,以重新執行(在基於語句的復制中)或應用(在基於行的復制中)。 這是一個 shared-nothing 的系統,默認情況下所有 server 成員都有一個完整的數據副本。

 

(圖)MySQL 異步復制

  還有一個半同步復制,它在協議中添加了一個同步步驟。 這意味着主節點在提交時需要等待從節點確認它已經接收到事務。只有這樣,主節點才能繼續提交操作。

 

(圖)MySQL 異步復制

  在上面的兩個圖片中,可以看到傳統異步 MySQL 復制協議(以及半同步)的圖形展示。 藍色箭頭表示在不同 server 之間或者 server 與 client 應用之間的信息交互。

1.2.3 MySQL主從復制原理介紹

復制過程:

1、開啟binlog日志,通過把主庫的binlog傳送到從庫,從新解析應用到從庫。

2、復制需要3個線程(dump、io、sql)完成,5.6從庫多個sql。

3、復制是異步的過程。主從復制是異步的邏輯的SQL語句級的復制。

復制前提:

1、主服務期一定要打開二進制日志

2、必須兩台服務器(或者是多個實例)

3、從服務器需要一次數據初始化

     3.1如果主從服務器都是新搭建的話,可以不做初始化

     3.2如果主服務器已經運行了很長時間了,可以通過備份將主庫數據恢復到從庫。

4、主庫必須要有對從庫復制請求的用戶。

5、從庫需要有relay-log設置,存放從主庫傳送過來的二進制日志 show variables  like '%relay%';

6、在第一次的時候,從庫需要change master to 去連接主庫。

7、change master信息需要存放到master.info中  show variables  like '%master_info%';

8、從庫怎么知道,主庫發生了新的變化?通過relay-log.info記錄的已經應用過的relay-log信息。

9、在復制過程中涉及到的線程

      從庫會開啟一個IO thread(線程),負責連接主庫,請求binlog,接收binlog並寫入relay-log。

      從庫會開啟一個SQL thread(線程),負責執行relay-log中的事件。

      主庫會開啟一個dump thrad(線程),負責響應從IO thread的請求。

主從怎么實現的?

1、通過二進制日志

2、至少兩台(主、從)

3、主服務器的二進制日志“拿”到從服務器上再運行一遍。

4、通過網絡連接兩台機器,一般都會出現延遲的狀態。也可以說是異步的。

 

1.2.4 執行原理--第一次開啟主從過程

1、 從庫通過手工執行change master to 語句連接主庫,提供了連接的用戶一切條件

(user、password、port、ip

    並且讓從庫知道,二進制日志的起點位置(file名  position號)

    start slave

2、從庫的IO和主庫的dump線程建立連接

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

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

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

6、從庫SQL線程應用relay-log,並且把應用過的記錄到relay-log.info,默認情況下,已經應用過的relay會自動被清理purge。

到此位置,一次主從復制就完成

  一旦主從運行起來:

        就不需要手工執行change master to,

        因為信息都會被存放到master.info

      (user、password、port、ip,上次獲取過的binlog信息file和position)中

        其他的過程都是一樣的

1.2.4.1  詳細的mysql replication 過程  

1.3 主從搭建配置

    本次主從搭建使用mysql多實例進行實驗。多實例配置參考文檔進行配置:http://www.cnblogs.com/clsn/p/8038964.html#_label8

1.3.1 多實例數據庫slave配置

系統環境說明:

[root@db02 ~]# cat /etc/redhat-release 
CentOS release 6.9 (Final)
[root@db02 ~]# uname -r
2.6.32-696.el6.x86_64
[root@db02 ~]# /etc/init.d/iptables status 
iptables: Firewall is not running.  # 注意:務必關閉防火牆(iptables  selinux)
[root@db02 ~]# getenforce  
Disabled
[root@db02 ~]# mysql --version
mysql  Ver 14.14 Distrib 5.6.36, for Linux (x86_64) using  EditLine wrapper

1、啟動多實例數據庫

[root@db02 ~]# /data/3306/mysql start
Starting MySQL...
[root@db02 ~]# /data/3307/mysql start
Starting MySQL...

2、配置文件說明:

master 配置文件說明

[root@db02 ~]# cat /data/3306/my.cnf 
[client]
port            = 3306
socket          = /data/3306/mysql.sock

[mysqld]
user    = mysql
port    = 3306
socket  = /data/3306/mysql.sock
basedir = /application/mysql
datadir = /data/3306/data
log-bin = /data/3306/mysql-bin
server-id = 6  # server id 不能相同
skip_name_resolve = 0 # 跳過域名解析參數


[mysqld_safe]
log-error=/data/3306/mysql_3306.err
pid-file=/data/3306/mysqld.pid

slave 配置文件說明:

[root@db02 ~]# cat /data/3307/my.cnf 
[client]
port            = 3307
socket          = /data/3307/mysql.sock

[mysqld]
user    = mysql
port    = 3307
socket  = /data/3307/mysql.sock
basedir = /application/mysql
datadir = /data/3307/data
log-bin = /data/3307/mysql-bin
server-id = 7  # server id 不能相同
skip_name_resolve = 0  # 跳過域名解析參數
read_only = 1  # 從庫只讀 (非root用戶 )

[mysqld_safe]
log-error=/data/3307/mysql_3307.err
pid-file=/data/3307/mysqld.pid

3、在主庫創建復制用戶

         登陸到主數據庫中:

mysql -uroot -p123 -S /data/3306/mysql.sock

         創建授權用戶,注意是slave用戶。

grant replication slave  on *.* to repl@'10.0.0.%' identified by '123';

4、初始化從庫數據

備份主庫當前數據

 mysqldump -uroot -p123 -A -B -F --master-data=2  -S /data/3306/mysql.sock >/tmp/full.sql

 部分參數說明:(詳細參照http://www.cnblogs.com/clsn/p/8138015.html#_label2

    -F 刷新二進制日志

    --master-data [=#]這會導致二進制日志的位置和文件名被追加到輸出中。

    如果等於1,則將其打印為CHANGE MASTER命令; 如果等於2,那么該命令將以注釋符號為前綴。

到從庫進行恢復

 mysql -uroot -p123 -S /data/3307/mysql.sock

# 恢復備份的數據

set sql_log_bin=0;
source /tmp/full.sql

5、開啟從庫復制

         查看備份的當前使用的文件及POS號

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000012 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

         登入數據庫,進行slave配置。

mysql -uroot -p123 -S /data/3307/mysql.sock 
CHANGE MASTER TO
  MASTER_HOST='10.0.0.52',
  MASTER_USER='repl',
  MASTER_PASSWORD='123',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000012',
  MASTER_LOG_POS=120;
start  slave;  # 啟動從庫復制

         該配置想關說明可以通過 help 獲得。

mysql> help CHANGE MASTER TO
CHANGE MASTER TO
  MASTER_HOST='master2.mycompany.com',
  MASTER_USER='replication',
  MASTER_PASSWORD='bigs3cret',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='master2-bin.001',
  MASTER_LOG_POS=4,
  MASTER_CONNECT_RETRY=10;

1.3.2 測試主從同步

查看slave庫的狀態

           主要查看   Slave_IO_Running 與 Slave_SQL_Running 是否都為Yes

 1 mysql> show slave status\G
 2 *************************** 1. row ***************************
 3                Slave_IO_State: Waiting for master to send event
 4                   Master_Host: 10.0.0.52
 5                   Master_User: repl
 6                   Master_Port: 3306
 7                 Connect_Retry: 60
 8               Master_Log_File: mysql-bin.000010
 9           Read_Master_Log_Pos: 842
10                Relay_Log_File: 3307-relay-bin.000018
11                 Relay_Log_Pos: 283
12         Relay_Master_Log_File: mysql-bin.000010
13              Slave_IO_Running: Yes
14             Slave_SQL_Running: Yes
15               Replicate_Do_DB: 
16           Replicate_Ignore_DB: 
17            Replicate_Do_Table: 
18        Replicate_Ignore_Table: 
19       Replicate_Wild_Do_Table: 
20   Replicate_Wild_Ignore_Table: 
21                    Last_Errno: 0
22                    Last_Error: 
23                  Skip_Counter: 0
24           Exec_Master_Log_Pos: 842
25               Relay_Log_Space: 455
26               Until_Condition: None
27                Until_Log_File: 
28                 Until_Log_Pos: 0
29            Master_SSL_Allowed: No
30            Master_SSL_CA_File: 
31            Master_SSL_CA_Path: 
32               Master_SSL_Cert: 
33             Master_SSL_Cipher: 
34                Master_SSL_Key: 
35         Seconds_Behind_Master: 0
36 Master_SSL_Verify_Server_Cert: No
37                 Last_IO_Errno: 0
38                 Last_IO_Error: 
39                Last_SQL_Errno: 0
40                Last_SQL_Error: 
41   Replicate_Ignore_Server_Ids: 
42              Master_Server_Id: 6
43                   Master_UUID: 4f344556-e0ab-11e7-9138-000c29d60ab3
44              Master_Info_File: /data/3307/data/master.info
45                     SQL_Delay: 0
46           SQL_Remaining_Delay: NULL
47       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
48            Master_Retry_Count: 86400
49                   Master_Bind: 
50       Last_IO_Error_Timestamp: 
51      Last_SQL_Error_Timestamp: 
52                Master_SSL_Crl: 
53            Master_SSL_Crlpath: 
54            Retrieved_Gtid_Set: 
55             Executed_Gtid_Set: 
56                 Auto_Position: 0
57 1 row in set (0.00 sec)
View Code 從庫狀態信息

         在主庫進行操作,在從庫驗證

[root@db02 ~]# mysql -uroot -p123  -S /data/3306/mysql.sock
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database clsn;
Query OK, 1 row affected (0.00 sec)

         在從庫上可以看到該數據庫已創建

[root@db02 ~]# mysql -uroot -p123 -S /data/3307/mysql.sock
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| clsn               |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

  至此mysql主從復制就搭建完成

1.3.3 忘記數據庫密碼?

shell> /application/mysql/bin/mysqld_safe  --defaults-file=/data/3306/my.cnf    --skip-grant-tables --skip-networking  &
mysql> update user set password=password('123') where user='root' and host='localhost';
mysql> flush privileges;

1.3.4 主從復制狀態失敗的原因?

Last_IO_Error: error reconnecting to master 'repl@10.0.0.52:3306' - retry-time: 60  retries: 1

原因:

1、主機沒啟動,或者宕機,檢查主庫的狀態。

2、網絡通信問題,使用ping命令進行檢查;或使用mysql命令進行shell端登陸測試

3、防火牆,selinux(務必檢查)。

4、復制用戶和密碼、端口號、地址有問題,使用mysql命令進行shell端登陸測試。

5、mysql自動解析,會將連接的IP解析成主機名(skip-name-resolve = 0)寫入my.cnf文件即可。

6、從庫IO異常關閉,通過show slave status \G 進行查看。

1.4 MySQL主從復制常見問題

1.4.1 從庫binlog落后主庫binlog?

  從庫記錄的已經主庫已經給我傳送的binlog事件的坐標,一般在繁忙的生產環境下會落后於主庫

show master status\G  --- 主
show slave status \G  --- 從
Master_Log_File: mysql-bin.000007
Read_Master_Log_Pos: 729

落后太遠的原因:

硬件條件有關的,機器磁盤IO性能不足。

主要還是網絡問題,網絡傳輸的性能。

主庫存放二進制日志的存儲性能太低,建議binlog日志存咋SSD中。

主庫DUMP線程太繁忙,主要發生在一主多從的環境下。

從庫IO線程太忙

人為控制(delay節點、延時節點 )

1.4.2 主庫update,從庫遲遲的沒有更新。

特殊情況:日志已經傳過來了,數據並沒有同步

一般情況:

1、沒開啟SQL線程

2、傳的東西有問題(你要做的事情,我提前已經做了,不想重復做了,然后他就死了)

3、SQL線程忙。

4、人為控制了【delay(從庫)節點、延時節點,一般生產設置為3-6小時之間,可以保證過去3-6小時之間的誤操作,可以避免】。

1.4.3 主從復制延時配置(從庫配置)

停止從庫復制

mysql>stop slave;
Query OK, 0 rows affected (0.01 sec)

         修改延時參數,MASTER_DELAY,單位位S (秒)。

mysql>CHANGE MASTER TO MASTER_DELAY = 30;
Query OK, 0 rows affected (0.07 sec)

         啟動從庫復制

mysql>start slave;
Query OK, 0 rows affected (0.07 sec)

         查看配置是否生效

mysql> show slave status \G
……
              SQL_Delay: 30

1.4.4 從庫安全配置(其他用戶只讀)

修改my.cnf配置文件,添加只讀參數

read_only = 1    ====> 控制普通用戶
innodb_read_only = 1  ====> 控制root用戶,正常情況不要加

         添加完成后重啟數據庫

mysql> show variables like '%read_only%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_read_only | OFF   |
| read_only        | ON    |
| tx_read_only     | OFF   |
+------------------+-------+
3 rows in set (0.00 sec)

  延時從庫: delay節點、延時節點

1.4.5 主從復制故障及解決(跳過錯誤)

命令行設置

stop slave; #<==臨時停止同步開關。
set global sql_slave_skip_counter = 1 ; #<==將同步指針向下移動一個,如果多次不同步,可以重復操作。
start slave;

         在配置文件修改,設置要跳過的pos

/etc/my.cnf
slave-skip-errors = 1032,1062,1007

  在mysql中可以跳過某些錯誤,但是最好的解決辦法,重新搭建主從復制。

1.4.6 延時節點概念 --> SQL線程延時?

Last_SQL_Errno: 0
Last_SQL_Error:

原因:

1、主庫做操作的對象,在從庫不存在

2、主庫做操作的對象屬性不一致。

3、主庫做操作的對象,從庫已經存在

                  ……

1.4.7 Slave_*_Running:?

1、Slave_IO_Running I/O 線程正在運行、未運行還是正在運行但尚未連接到主服務器。可能值分別為Yes、No 或 Connecting。

2、Slave_SQL_Running SQL 線程當前正在運行、未運行,可能值分別為 Yes、No 主服務器日志坐標:

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

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

1.4.8 中繼日志坐標

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

b)  如果 Relay_Master_Log_File 和 Exec_Master_Log_Pos 列的輸出遠遠落后於 Master_Log_File 和Read_Master_Log_Pos 列(表示 I/O 線程的坐標),這表示 SQL 線程(而不是 I/O 線程)中存在延遲。即,它表示復制日志事件快於執行這些事件。

1.4.9 單一主從需要改變的地方

從庫的作用

1、相當於實時備份

2、使用從庫備份

3、一主多從應對讀多的業務需求

      如果,從庫只做備份服務器用,那么主庫的壓力會不減反增。因為,所有的業務都在主庫實現,讀和寫,dump線程讀取並投遞binlog

解決方案:

(1)可不可以挪走一部分讀業務到從庫,讀寫分離

(2) 一主多從應對讀多的業務需求,一旦發展成這個架構,dump線程投遞binlog的壓力更大

(3) 多級主從,采用中間庫緩解主庫dump的壓力,會出現中間庫瓶頸的問題,選擇blackhole引擎,看性能與安全的權衡

(4)雙主模型:緩解,數據一致性難保證

(5)環裝復制

1.5 【生產案例】主從復制事故

1.5.1 發生背景

1、有一台已經工作很久的單機mysql數據。在2017年12月24日的平安夜,我司購物網站宕機了。機器物損壞,系統硬盤報廢。

2、在接到一條短信告知服務器宕機,數據庫連不上。當時的我一臉懵逼的還在開party,誰能想到在這樣一個闔家歡樂的時刻發生這樣的事情。  

3、隨之我火速趕回公司處理事故。首先更換硬盤,從備份服務器上拉取備份數據,用備份恢復宕機的時刻數據,經歷40分鍾后所有應用恢復正常。

4、經歷這次事故,決心修改數據庫架構,我跟領導承諾,保證改完之后,出現類似故障能在5-10分鍾恢復業務。把原來的停機時間縮短4-8倍。

1.5.2 搭建流程

1.5.2.1  架構設計

 

                  修改架構采用數據庫主從同步,能保證數據的安全,提高事故發生的恢復速度。

1.5.2.2  架構實施

         (1)准備一台新機器,配置、系統、環境等與原數據庫保持一致。

         (2)在主庫檢查binlog開關,沒有開啟將其開啟 ,檢查server_id 與 auto.cnf文件中的uuid 是否唯一。

         (3)主庫創建授權復制的用戶,授權 replication slave。

         (4)備份主庫上現有數據,恢復到從庫中,推薦使用mysqldump,在訪問低谷的時候做。

         (5)在從庫上開啟binlog和relaylog,server_id。

         (6)在從庫配置change master to 信息:在第一次開啟主從的時候,告訴從庫user password host  port,復制binlog的起點file、position。

         (7)start slave 開啟主從復制。

         到此歷經千辛萬苦主從復制搭建完成。

1.5.3 測試主從切換

(1) 主從的可用性測試:在主庫中插入數據,在從庫查看有沒有。  

(2) 主從快速恢復演練

  a)  在一個月黑風高夜選一個業務不繁忙時間點,人工宕掉主庫。

  b)  將從庫定為主庫,查看從庫的日志量(master.info、relay-log.info)

  c)  判斷主從日志的差距(master.info,show master status)

  d)  恢復后發現偏差,就人為登錄到主庫(備份服務器也行)中,把截取差距的binlog日志,並傳送到從庫進行數據補償。

  e)  此時從庫數據現在已經和主庫一致。

  f)  reset master,reset slave

  g)  應用割接到從庫,將應用數據庫IP指向從庫IP,測試應用。

(3)小結:經歷里這次測試,主從見的切換歷時6分32秒,比之前縮短許多,但是感覺還差點什么,以后再補吧。

1.6 mysql半同步復制

  MySQL復制默認是異步復制,存在一定的概率備庫與主庫的數據是不對等的,如果Master宕機,事務在Master上已提交,但很可能這些事務沒有傳到任何的Slave上,此時Slave也可能會丟失事務。在半同步復制的架構下,當master在將自己binlog發給slave上的時候,要確保slave已經接受到了這個二進制日志以后,才會返回數據給客戶端。

  半同步復制介於異步復制和全同步復制之間,主庫在執行完客戶端提交的事務后不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於異步復制,半同步復制提高了數據的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步復制最好在低延時的網絡中使用。

半同步復制的原理圖

  在5.6中加入了group commit特性之后,性能不比傳統的異步復制差。

1.6.1 半同步復制的潛在問題

  客戶端事務在存儲引擎層提交后,在得到從庫確認的過程中,主庫宕機了,此時,可能的情況有兩種

事務還沒發送到從庫上

  此時,客戶端會收到事務提交失敗的信息,客戶端會重新提交該事務到新的主上,當宕機的主庫重新啟動后,以從庫的身份重新加入到該主從結構中,會發現,該事務在從庫中被提交了兩次,一次是之前作為主的時候,一次是被新主同步過來的。

事務已經發送到從庫上

  此時,從庫已經收到並應用了該事務,但是客戶端仍然會收到事務提交失敗的信息,重新提交該事務到新的主上。

1.6.2 半同步架構搭建

加載使用的插件

主庫:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
從從:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

查看是否加載成功

show plugins;

啟動半同步復制

主庫:
SET GLOBAL rpl_semi_sync_master_enabled = 1;
從庫:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

重啟從庫上的IO線程

STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

查看是否在運行

主庫:
show status like 'Rpl_semi_sync_master_status';
從庫:
show status like 'Rpl_semi_sync_slave_status';

測試半同步復制

查看延遲時間:
show variables like '%rpl_semi_sync%';
從庫:
stop slave;
主庫:
create database clsn;

  如果創建庫的時間是設置的時間就成功了。

1.7 主從復制架構的演變

1.7.1 基本結構

(1)一主一從

(2)一主多從

 

(3)多級主從

(4)雙主

(5)多主一從(5.7之后開始支持)

 

(6)循環復制

                  對於循環數據庫鏡像,就是多個數據庫A、B、C、D等,對其中任一個數據庫的修改,都要同時鏡像到其它的數據庫里。  replicate-same-server-id = 0 

 

1.7.2 高級應用架構演變

(1)讀寫分離——MySQL proxy、amoeba、xx-dbproxy等。

 

  一般來說都是通過主從復制(Master-Slave)的方式來同步數據,再通過讀寫分離(MySQL-Proxy)來提升數據庫的並發負載能力這樣的方案來進行部署與實施的。  

(2)分庫分表——cobar、自主研發等。

 

  1) 系統對外提供的數據庫名是dbtest,並且其中有兩張表tb1和tb2。

  2) tb1表的數據被映射到物理數據庫dbtest1的tb1上。

  3) tb2表的一部分數據被映射到物理數據庫dbtest2的tb2上,另外一部分數據被映射到物理數據庫dbtest3的tb2上。

(3)MMM架構——mysql-mmm(google)-使用極少

 

  MMM(Master-Master replication manager for MySQL)是一套支持雙主故障切換和雙主日常管理的腳本程序。MMM使用Perl語言開發,主要用來監控和管理MySQL Master-Master(雙主)復制,可以說是mysql主主復制管理器。

  雖然叫做雙主復制,但是業務上同一時刻只允許對一個主進行寫入,另一台備選主上提供部分讀服務,以加速在主主切換時刻備選主的預熱,可以說MMM這套腳本程序一方面實現了故障切換的功能,另一方面其內部附加的工具腳本也可以實現多個slave的read負載均衡。

  關於mysql主主復制配置的監控、故障轉移和管理的一套可伸縮的腳本套件(在任何時候只有一個節點可以被寫入),這個套件也能對居於標准的主從配置的任意數量的從服務器進行讀負載均衡,所以你可以用它來在一組居於復制的服務器啟動虛擬ip,除此之外,它還有實現數據備份、節點之間重新同步功能的腳本。

  對於那些對數據的一致性要求很高的業務,非常不建議采用MMM這種高可用架構。

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

 

  MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司youshimaton(現就職於Facebook公司)開發,是一套優秀的作為MySQL高可用性環境下故障切換和主從提升的高可用軟件。在MySQL故障切換過程中,MHA能做到在0~30秒之內自動完成數據庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證數據的一致性,以達到真正意義上的高可用。

  該軟件由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。

(5)MGR-- 5.7     新特性    MySQL    Group      replication

 

  基於傳統異步復制和半同步復制的缺陷——數據的一致性問題無法保證,MySQL官方在5.7.17版本正式推出組復制(MySQL Group Replication,簡稱MGR)。

  由若干個節點共同組成一個復制組,一個事務的提交,必須經過組內大多數節點(N / 2 + 1)決議並通過,才能得以提交。如上圖所示,由3個節點組成一個復制組,Consensus層為一致性協議層,在事務提交過程中,發生組間通訊,由2個節點決議(certify)通過這個事務,事務才能夠最終得以提交並響應。

(6)PXC、MySQL Cluster、galera cluster架構

 

在PXC中,一次數據寫入在各個節點間的驗證/回滾流程

PXC架構的優點:

a)  服務高可用;

b)  數據同步復制(並發復制),幾乎無延遲;

c)  多個可同時讀寫節點,可實現寫擴展,不過最好事先進行分庫分表,讓各個節點分別寫不同的表或者庫,避免讓galera解決數據沖突;

d)  新節點可以自動部署,部署操作簡單;

e)  數據嚴格一致性,尤其適合電商類應用;

f)  完全兼容MySQL;

1.7.3 分庫分表簡單實踐

  實踐中使用的為world數據庫,為mysql官方提供,詳情參照:http://www.cnblogs.com/clsn/p/8087417.html#_label0

第一個里程碑:創建新表

CREATE TABLE `country_1` (
  `Code` char(3) NOT NULL DEFAULT '',
  `Name` char(52) NOT NULL DEFAULT '',
  `Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
  PRIMARY KEY (`Code`),
  KEY `name_idx` (`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

第二個里程碑:從舊表導入數據到新表

insert into country_1(code,name,continent) select code,name,continent from country;

第三個里程碑:橫向拆表

         創建與導出表相同格式的新表1

create table country_1_p1 like country_1;

         將數據的前100行插入到新表1中

insert into country_1_p1 select code,name,continent from country_1 order by code limit 100;

         創建與新表1相同格式的新表2

create table country_1_p2 like country_1;

         將100行之后的139行導入表2.

insert into country_1_p2 select code,name,continent from country_1 order by code limit 139 offset 100;

1.8 參考文獻

[1]  http://blog.csdn.net/hguisu/article/details/7325124

[2]  https://www.cnblogs.com/ivictor/p/5735580.html

[3]  https://www.cnblogs.com/Aiapple/p/5792939.html

[4]  http://heylinux.com/archives/1004.html 讀寫分離

[5]  http://hualong.iteye.com/blog/2102798 Cobar邏輯層次圖

[6]  https://www.cnblogs.com/kevingrace/p/5662975.html MMM架構

[7]  https://www.cnblogs.com/gomysql/p/3675429.html  MHA架構

[8]  http://blog.jobbole.com/70844/   MySQL在大型網站的應用架構演變

[9]  https://www.cnblogs.com/dosmile/p/6681923.html  MGR復制

[10] http://imysql.cn/tag/pxc    PXC架構

[11] https://mp.weixin.qq.com/s/Ll0sdKS6Vbw1pXIKbW3-NQ 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM