主從複製--非同步篇

程式設計師的貓發表於2020-03-26

最常見的叢集方案

MySQL Replication

主從複製(也稱 AB 複製)允許將來自一個MySQL資料庫伺服器(主伺服器)的資料複製到一個或多個MySQL資料庫伺服器(從伺服器)。

複製是非同步的 從站不需要永久連線以接收來自主站的更新。

根據配置,您可以複製資料庫中的所有資料庫,所選資料庫甚至選定的表。

MySQL中複製的優點包括:

  • 橫向擴充套件解決方案 - 在多個從站之間分配負載以提高效能。在此環境中,所有寫入和更新都必須在主伺服器上進行。但是,讀取可以在一個或多個從裝置上進行。該模型可以提高寫入效能(因為主裝置專用於更新),同時顯著提高了越來越多的從裝置的讀取速度。
  • 資料安全性 - 因為資料被複制到從站,並且從站可以暫停複製過程,所以可以在從站上執行備份服務而不會破壞相應的主資料。
  • 分析 - 可以在主伺服器上建立實時資料,而資訊分析可以在從伺服器上進行,而不會影響主伺服器的效能。
  • 遠端資料分發 - 您可以使用複製為遠端站點建立資料的本地副本,而無需永久訪問主伺服器。

Replication 的原理

前提是作為主伺服器角色的資料庫伺服器必須開啟二進位制日誌

  1. 主伺服器上面的任何修改都會通過自己的 I/O tread(I/O 執行緒)儲存在二進位制日誌 Binary log 裡面。

  2. 從伺服器上面也啟動一個 I/O thread,通過配置好的使用者名稱和密碼, 連線到主伺服器上面請求讀取二進位制日誌,然後把讀取到的二進位制日誌寫到本地的一個Realy log(中繼日誌)裡面。

  3. 從伺服器上面同時開啟一個 SQL thread 定時檢查 Realy log(這個檔案也是二進位制的),如果發現有更新立即把更新的內容在本機的資料庫上面執行一遍。

每個從伺服器都會收到主伺服器二進位制日誌的全部內容的副本。

從伺服器裝置負責決定應該執行二進位制日誌中的哪些語句。

除非另行指定,否則主從二進位制日誌中的所有事件都在從站上執行。

如果需要,您可以將從伺服器配置為僅處理一些特定資料庫或表的事件。

重要: 您無法將主伺服器配置為僅記錄特定事件。

每個從站(從伺服器)都會記錄二進位制日誌座標:

  • 檔名
  • 檔案中它已經從主站讀取和處理的位置。

由於每個從伺服器都分別記錄了自己當前處理二進位制日誌中的位置,因此可以斷開從伺服器的連線,重新連線然後恢復繼續處理。

一主多從

如果一主多從的話,這時主庫既要負責寫又要負責為幾個從庫提供二進位制日誌。此時可以稍做調整,將二進位制日誌只給某一從,這一從再開啟二進位制日誌並將自己的二進位制日誌再發給其它從。或者是乾脆這個從不記錄只負責將二進位制日誌轉發給其它從,這樣架構起來效能可能要好得多,而且資料之間的延時應該也稍微要好一些。

關於二進位制日誌

mysqld將數字副檔名附加到二進位制日誌基本名稱以生成二進位制日誌檔名。每次伺服器建立新日誌檔案時,該數字都會增加,從而建立一系列有序的檔案。每次啟動或重新整理日誌時,伺服器都會在系列中建立一個新檔案。伺服器還會在當前日誌大小達到max_binlog_size引數設定的大小後自動建立新的二進位制日誌檔案 。二進位制日誌檔案可能會比max_binlog_size使用大型事務時更大, 因為事務是以一個部分寫入檔案,而不是在檔案之間分割。

為了跟蹤已使用的二進位制日誌檔案, mysqld還建立了一個二進位制日誌索引檔案,其中包含所有使用的二進位制日誌檔案的名稱。預設情況下,它具有與二進位制日誌檔案相同的基本名稱,並帶有副檔名'.index'。在mysqld執行時,您不應手動編輯此檔案。

術語二進位制日誌檔案通常表示包含資料庫事件的單個編號檔案。

術語 二進位制日誌 表示含編號的二進位制日誌檔案集加上索引檔案。

SUPER 許可權的使用者可以使用SET sql_log_bin=0語句禁用其當前環境下自己的語句的二進位制日誌記錄

配置 Replication

配置步驟:
  1. 在主伺服器上,您必須啟用二進位制日誌記錄並配置唯一的伺服器ID。需要重啟伺服器。

編輯主伺服器的配置檔案 my.cnf,新增如下內容

[mysqld]
log-bin=/var/log/mysql/mysql-bin
server-id=1

建立日誌目錄並賦予許可權

shell> mkdir /var/log/mysql
shell> chown mysql.mysql /var/log/mysql

重啟服務

shell> systemctl restart mysqld

注意:

如果省略server-id(或將其顯式設定為預設值0),則主伺服器拒絕來自從伺服器的任何連線。

為了在使用帶事務的InnoDB進行復制設定時儘可能提高永續性和一致性,
您應該在master my.cnf檔案中使用以下配置項:

innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

確保在主伺服器上 skip_networking 選項處於 OFF 關閉狀態, 這是預設值。
如果是啟用的,則從站無法與主站通訊,並且複製失敗。

mysql> show variables like '%skip_networking%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| skip_networking | OFF   |
+-----------------+-------+
1 row in set (0.00 sec)
  1. 應該建立一個專門用於複製資料的使用者

每個從伺服器需要使用MySQL 主伺服器上的使用者名稱和密碼連線到主站。

例如,計劃使用使用者 repl 可以從任何主機上連線到 master 上進行復制操作, 並且使用者 repl 僅可以使用複製的許可權。

主伺服器 上執行如下操作

mysql> CREATE USER 'repl'@'%' 
mysql> GRANT REPLICATION SLAVE ON *.*  TO  'repl'@'%'  identified by 
 'QFedu123!';
mysql> 
  1. 從伺服器上使用剛才的使用者進行測試連線
shell> mysql -urepl -p'QFedu123!' -hmysql-master1

下面的操作根據如下情況繼續

主伺服器中有資料
  • 如果在啟動複製之前有現有資料需要與從屬裝置同步,請保持客戶端正常執行,以便鎖定保持不變。這可以防止進行任何進一步的更改,以便複製到從站的資料與主站同步。
  1. 在主伺服器中匯出現有的資料

如果主資料庫包含現有資料,則必須將此資料複製到每個從站。有多種方法可以實現:

  • 使用mysqldump工具建立要複製的所有資料庫的轉儲。這是推薦的方法,尤其是在使用時 InnoDB
shell> mysqldump  -u使用者名稱  -p密碼    --all-databases  --master-data=1 > dbdump.db

這裡的使用者是主伺服器的使用者

如果不使用 --master-data 引數,則需要手動鎖定單獨會話中的所有表。

  1. 從主伺服器中使用 scprsync 等工具,把備份出來的資料傳輸到從伺服器中。

在主服務中執行如下命令

scp  dbdump.db root@mysql-slave1:/root/

這裡的 mysql-slave1 需要能被主伺服器解析出 IP 地址,或者說可以在主伺服器中 ping 通。

  1. 配置從伺服器,並重啟
    從伺服器 上編輯其配置檔案 my.cnf 並新增如下內容:
// my.cnf 檔案
[mysqld]
server-id=2
  1. 匯入資料到從伺服器,並配置連線到主伺服器的相關資訊

登入到從伺服器上,執行如下操作

/*匯入資料*/
mysql> source   /root/fulldb.dump

在從伺服器配置連線到主伺服器的相關資訊

mysql> CHANGE MASTER TO
MASTER_HOST='mysql-master1',  -- 主伺服器的主機名(也可以是 IP) 
MASTER_USER='repl',                  -- 連線到主伺服器的使用者
MASTER_PASSWORD='123';        == 到主伺服器的密碼
  1. 啟動從伺服器的複製執行緒
mysql> start slave;
Query OK, 0 rows affected (0.09 sec)

檢查是否成功

在從服務上執行如下操作,加長從伺服器端 IO執行緒和 SQL 執行緒是否是 OK

mysql> show slave status\G

輸出結果中應該看到 I/O 執行緒和 SQL 執行緒都是 YES, 就表示成功。

執行此過程後,在主服務上操作的修改資料的操作都會在從伺服器中執行一遍,這樣就保證了資料的一致性。

將新的伺服器加入,變為從伺服器

和上面的步驟一樣,但是新加入的伺服器的server-id 的值不能和現有都伺服器 server-id 的值一樣。

假如在新加入從伺服器之前,主伺服器執行了刪除庫的操作。
並且,刪除的庫剛好是在第一次 mysqldump 備份時的資料中。
就會出現問題,在從伺服器上提示報錯沒有這個資料庫;

主伺服器中無資料

主伺服器中設定

  1. my.cnf配置檔案
[mysqld]
log-bin=/var/log/mysql/mysql-bin
server-id=1

設定 log-bin 時必須同時設定 server-id

建立日誌目錄並賦予許可權

shell> mkdir /var/log/mysql
shell> chown mysql.mysql /var/log/mysql

重啟服務

從伺服器設定

  1. my.cnf配置檔案
[mysqld]
server-id=3

重啟服務

  1. 檢視主伺服器的二進位制日誌的名稱

通過使用命令列客戶端連線到主伺服器來啟動主伺服器上的會話,並通過執行以下FLUSH TABLES WITH READ LOCK語句來重新整理所有表和阻止寫語句:

mysql> FLUSH TABLES WITH READ LOCK;
mysql> show master status \G
****************** 1. row ****************
             File: mysql-bin.000001
         Position: 0
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
  1. 在從伺服器的 mysql 中執行如下語句
mysql> CHANGE MASTER TO
MASTER_HOST='mysql-master1',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;

mysql> start slave;
檢視

在master上執行show binlog events命令,可以看到第一個binlog檔案的內容。

mysql> show binlog events\G
*************************** 1. row ***************************
   Log_name: mysql-bin.000001
        Pos: 4
 Event_type: Format_desc
  Server_id: 1
End_log_pos: 107
       Info: Server ver: 5.5.28-0ubuntu0.12.10.2-log, Binlog ver: 4
*************************** 2. row ***************************
   Log_name: mysql-bin.000001
        Pos: 107
 Event_type: Query
  Server_id: 1
End_log_pos: 181
       Info: create user rep
*************************** 3. row ***************************
   Log_name: mysql-bin.000001
        Pos: 181
 Event_type: Query
  Server_id: 1
End_log_pos: 316
       Info: grant replication slave on *.* to rep identified by '123456'
3 rows in set (0.00 sec)
  • Log_name 是二進位制日誌檔案的名稱,一個事件不能橫跨兩個檔案
  • Pos 這是該事件在檔案中的開始位置
  • Event_type 事件的型別,事件型別是給slave傳遞資訊的基本方法,每個新的binlog都以Format_desc型別開始,以Rotate型別結束
  • Server_id 建立該事件的伺服器id
  • End_log_pos 該事件的結束位置,也是下一個事件的開始位置,因此事件範圍為Pos~End_log_pos - 1
  • Info 事件資訊的可讀文字,不同的事件有不同的資訊

在從站上暫停複製

您可以使用STOP SLAVESTART SLAVE語句停止並啟動從站上的複製 。

要停止從主伺服器處理二進位制日誌,請使用 STOP SLAVE

mysql> STOP SLAVE;

當複製停止時,從I / O執行緒停止從主二進位制日誌讀取事件並將它們寫入中繼日誌,並且SQL執行緒停止從中繼日誌讀取事件並執行它們。您可以通過指定執行緒型別單獨暫停I / O或SQL執行緒:

mysql> STOP SLAVE IO_THREAD;
mysql> STOP SLAVE SQL_THREAD;

要再次開始執行,請使用以下START SLAVE語句:

mysql> START SLAVE;

要啟動特定執行緒,請指定執行緒型別:

mysql> START SLAVE IO_THREAD;
mysql> START SLAVE SQL_THREAD;

複製原理實現細節

MySQL複製功能使用三個執行緒實現,一個在主伺服器上,兩個在從伺服器上:

  • Binlog轉儲執行緒 主裝置建立一個執行緒,以便在從裝置連線時將二進位制日誌內容傳送到從裝置。可以SHOW PROCESSLIST在主伺服器的輸出中將此執行緒標識為Binlog Dump執行緒。

    二進位制日誌轉儲執行緒獲取主機二進位制日誌上的鎖,用於讀取要傳送到從機的每個事件。一旦讀取了事件,即使在事件傳送到從站之前,鎖也會被釋放。

  • 從屬 I/O執行緒 在從屬伺服器上發出 START SLAVE 語句時,從屬伺服器會建立一個 I/O 執行緒,該執行緒連線到主伺服器並要求主伺服器傳送其在二進位制日誌中的更新記錄。

    從屬 I/O執行緒讀取主Binlog Dump執行緒傳送的更新 (請參閱上一項)並將它們複製到包含從屬中繼日誌的本地檔案。

    此執行緒的狀態顯示為 Slave_IO_running輸出 SHOW SLAVE STATUSSlave_running輸出中的狀態SHOW STATUS

  • 從屬SQL執行緒 從屬裝置建立一個SQL執行緒來讀取由從屬 I/O 執行緒寫入的中繼日誌,並執行其中包含的事件。

  • 當從屬伺服器從放的事件,追幹上主伺服器的事件後,從屬伺服器的 I/O 執行緒將會處於休眠狀態,直到主伺服器的事件有更新時,被主伺服器傳送的訊號喚醒。

在前面的描述中,每個主/從連線有三個執行緒。具有多個從站的主站為每個當前連線的從站建立一個二進位制日誌轉儲執行緒,每個從站都有自己的I / O和SQL執行緒。

從站使用兩個執行緒將讀取更新與主站分開並將它們執行到獨立任務中。因此,如果語句執行緩慢,則不會減慢讀取語句的任務。例如,如果從伺服器尚未執行一段時間,則當從伺服器啟動時,其I / O執行緒可以快速從主伺服器獲取所有二進位制日誌內容,即使SQL執行緒遠遠落後。如果從伺服器在SQL執行緒執行了所有獲取的語句之前停止,則I / O執行緒至少已獲取所有內容,以便語句的安全副本本地儲存在從屬的中繼日誌中,準備在下次執行時執行奴隸開始。

SHOW PROCESSLIST語句提供的資訊可以告訴您主伺服器和從伺服器上有關複製的資訊。有關主狀態的資訊,請參見第8.14.4節“複製主執行緒狀態”。有關從站狀態,請參見第8.14.5節“複製從站I / O執行緒狀態”第8.14.6節“複製從站SQL執行緒狀態”

以下示例說明了三個執行緒如何顯示在輸出中SHOW PROCESSLIST

在主伺服器上,輸出SHOW PROCESSLIST如下所示:

mysql> SHOW PROCESSLIST\G
*************************** 1\. row ***************************
     Id: 2
   User: root
   Host: localhost:32931
     db: NULL
Command: Binlog Dump
   Time: 94
  State: Has sent all binlog to slave; waiting for binlog to
         be updated
   Info: NULL

這裡,執行緒2是Binlog Dump為連線的從屬服務的複製執行緒。該 State資訊表明所有未完成的更新已傳送到從站,並且主站正在等待更多更新發生。如果Binlog Dump在主伺服器上看不到任何 執行緒,則表示複製未執行; 也就是說,目前沒有連線任何從站。

在從屬伺服器上,輸出SHOW PROCESSLIST如下所示:

mysql> SHOW PROCESSLIST\G
*************************** 1\. row ***************************
     Id: 10
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Waiting for master to send event
   Info: NULL
*************************** 2\. row ***************************
     Id: 11
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Has read all relay log; waiting for the slave I/O
         thread to update it
   Info: NULL

State資訊指示執行緒10是與主伺服器通訊的I / O執行緒,並且執行緒11是處理儲存在中繼日誌中的更新的SQL執行緒。在 SHOW PROCESSLIST執行時,兩個執行緒都處於空閒狀態,等待進一步更新。

Time列中 的值可以顯示從站與主站進行比較的時間。請參見 第A.13節“MySQL 5.7 FAQ:複製”。如果主站側有足夠的時間在Binlog Dump執行緒上沒有活動,則主站確定從站不再連線。對於任何其他客戶端連線,這樣做的超時取決於的值 net_write_timeoutnet_retry_count; 有關這些的更多資訊,請參見第5.1.7節“伺服器系統變數”

SHOW SLAVE STATUS語句提供有關從屬伺服器上的複製處理的其他資訊。請參見 第16.1.7.1節“檢查複製狀態”

關於複製的格式

閱讀這篇官方文件

基於事務的 Replication

就是利用 GTID 來實現的複製

GTID(全域性事務標示符)最初由google實現,在MySQL 5.6中引入.GTID在事務提交時生成,由UUID和事務ID組成.uuid會在第一次啟動MySQL時生成,儲存在資料目錄下的auto .CNF檔案裡,事務ID則從1開始自增使用GTID的好處主要有兩點:

  1. 不再需要指定傳統複製中的master_log_files和master_log_pos,使主從複製更簡單可靠
  2. 可以實現基於庫的多執行緒複製,減小主從複製的延遲

實驗環境要求: 5.7.6 以上版本

主庫配置
[mysqld]
log-bin=/var/log/mysql/mysql-bin
server-id=1
gtid_mode=ON
enforce_gtid_consistency=1   # 強制執行GTID一致性。

重啟服務

其他和之前的一樣

  • 建立專屬使用者並授權
  • 假如有資料匯出資料
mysql> CREATE USER 'repl'@'%' IDENTIFIED BY '123';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
mysql> 
從庫配置

測試使用者有效性

shell> mysql -urepl -p'123' -hmysql-master1
[mysqld]
server-id=2
gtid_mode=ON
enforce_gtid_consistency=1

# 可選項, 把連線到 master 的資訊存到資料庫中的表中
master-info-repository=TABLE
relay-log-info-repository=TABLE

重啟服務

假如有資料,先匯入資料

mysql> source dump.db

Mysql 終端執行連線資訊

mysql> CHANGE MASTER TO
MASTER_HOST='172.16.153.10',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_AUTO_POSITION=1;

> start slave;

檢查 slave 狀態

mysql> show slave status\G

設定 從伺服器只讀狀態

檢視當前只讀的狀態
SHOW VARIABLES LIKE ‘%read_only%’;

設定普通使用者只讀
SET GLOBAL read_only=1;

設定超級使用者只讀
SET GLOBAL super_read_only=1;

mysql> SHOW VARIABLES LIKE '%read_only%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | OFF   |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
| tx_read_only          | OFF   |
+-----------------------+-------+
5 rows in set (0.01 sec)

mysql> SET GLOBAL read_only=1;
Query OK, 0 rows affected (0.00 sec)

mysql> ;
ERROR:
No query specified

mysql> SHOW VARIABLES LIKE '%read_only%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | ON    |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
| tx_read_only          | OFF   |
+-----------------------+-------+
5 rows in set (0.00 sec)

mysql> SET GLOBAL super_read_only=1;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE '%read_only%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | ON    |
| super_read_only       | ON    |
| transaction_read_only | OFF   |
| tx_read_only          | OFF   |
+-----------------------+-------+
5 rows in set (0.00 sec)

mysql> create database db1;
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

開啟 GTID 後的匯出匯入資料的注意點

Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don’t want to restore GTIDs, pass –set-gtid-purged=OFF. To make a complete dump, pass –all-databases –triggers –routines –events

意思是: 當前資料庫例項中開啟了 GTID 功能, 在開啟有 GTID 功能的資料庫例項中, 匯出其中任何一個庫, 如果沒有顯示地指定–set-gtid-purged引數, 都會提示這一行資訊. 意思是預設情況下, 匯出的庫中含有 GTID 資訊, 如果不想匯出包含有 GTID 資訊的資料庫, 需要顯示地新增–set-gtid-purged=OFF引數.

mysqldump -uroot  -p  --set-gtid-purged=OFF   --all-databases > alldb.db

匯入資料是就可以相往常一樣匯入了。

配置多執行緒複製

多執行緒複製在 5.6 中被引入,並且在 5.7 中得到了進一步的完善。

5.7 中是基於邏輯時鐘的方式進行的多執行緒複製。

配置過程:

  1. 先在從庫上檢視預設的多執行緒複製型別
mysql> show variables like "slave_parallel_type";
+---------------------+----------+
| Variable_name       | Value    |
+---------------------+----------+
| slave_parallel_type | DATABASE |
+---------------------+----------+
1 row in set (0.01 sec)

mysql>
  1. 接著在從庫上停止目前正在執行復制鏈路

停止之前可以檢視目前的執行緒數

show processlist;
mysql> stop slave
  1. 配置併發執行緒的方式
mysql> set global slave_parallel_type = "logical_clock";
Query OK, 0 rows affected (0.00 sec)
  1. 配置併發數量
mysql> set global slave_parallel_workers = 4;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like "slave_parallel_workers";
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| slave_parallel_workers | 4     |
+------------------------+-------+
1 row in set (0.00 sec)
  1. 啟動從伺服器的複製鏈路
mysql> start slave

關於複製的架構(擴充套件)

  1. 主主複製

上圖中,Master-Master複製的兩臺伺服器,既是master,又是另一臺伺服器的slave。這樣,任何一方所做的變更,都會通過複製應用到另外一方的資料庫中。在這種複製架構中,各自上執行的不是同一db,比如左邊的是db1,右邊的是db2,db1的從在右邊反之db2的從在左邊,兩者互為主從,再輔助一些監控的服務還可以實現一定程度上的高可以用。

  1. 主動—被動模式的Master-Master(Master-Master in Active-Passive Mode)

上圖中,這是由master-master結構變化而來的,它避免了M-M的缺點,實際上,這是一種具有容錯和高可用性的系統。它的不同點在於其中只有一個節點在提供讀寫服務,另外一個節點時刻準備著,當主節點一旦故障馬上接替服務。比如通過corosync+pacemaker+drbd+MySQL就可以提供這樣一組高可用服務,主備模式下再跟著slave伺服器,也可以實現讀寫分離。

  1. 帶從伺服器的Master-Master結構(Master-Master with Slaves)

這種結構的優點就是提供了冗餘。在地理上分佈的複製結構,它不存在單一節點故障問題,而且還可以將讀密集型的請求放到slave上。

半同步機制(擴充套件)

MySQL-5.5 及以上支援半同步複製
早前的MySQL複製只能是基於非同步來實現,從MySQL-5.5開始,支援半自動複製。在以前的非同步(asynchronous)複製中,主庫在執行完一些事務後,是不會管備庫的進度的。如果備庫處於落後,而更不幸的是主庫此時又出現Crash(例如當機),這時備庫中的資料就是不完整的。簡而言之,在主庫發生故障的時候,我們無法使用備庫來繼續提供資料一致的服務了。Semisynchronous Replication(半同步複製)則一定程度上保證提交的事務已經傳給了至少一個備庫。Semi synchronous中,僅僅保證事務的已經傳遞到備庫上,但是並不確保已經在備庫上執行完成了。

此外,還有一種情況會導致主備資料不一致。在某個session中,主庫上提交一個事務後,會等待事務傳遞給至少一個備庫,如果在這個等待過程中主庫Crash,那麼也可能備庫和主庫不一致,這是很致命的。如果主備網路故障或者備庫掛了,主庫在事務提交後等待10秒(rpl_semi_sync_master_timeout的預設值)後,就會繼續。這時,主庫就會變回原來的非同步狀態。

MySQL在載入並開啟Semi-sync外掛後,每一個事務需等待備庫接收日誌後才返回給客戶端。如果做的是小事務,兩臺主機的延遲又較小,則Semi-sync可以實現在效能很小損失的情況下的零資料丟失。

千鋒雲端計算

開啟
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.08 sec)

mysql> show global variables like '%semi%';                            
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

mysql>

關於主從複製的更多引數

官網: https://dev.mysql.com/doc/refman/5.7/en/change-master-to.html

加密複製

官網:https://dev.mysql.com/doc/refman/5.7/en/replication-solutions-encrypted-connections.html

主伺服器

建立 CA 證照和私鑰 公鑰

shell> mysql_ssl_rsa_setup

My.cnf 檔案配置項

以下的情況是用 yum 安裝 mysql 的情況

[mysqld]
ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/server-cert.pem
ssl-key=/var/lib/mysql/server-key.pem

選項如下:

  • --ssl-ca:證照頒發機構(CA)證照檔案的路徑名。(--ssl-capath類似但指定CA證照檔案目錄的路徑名。)

    • --ssl-cert:伺服器公鑰證照檔案的路徑名。可以將其傳送到客戶端,並根據其擁有的CA證照進行身份驗證。

    • --ssl-key:伺服器私鑰檔案的路徑名。

從伺服器配置

首先要保證從伺服器的 sql 執行緒和 io 執行緒處於關閉狀態

mysql> stop slave;
mysql> stop slave sql_thread;
mysql> CHANGE MASTER TO
    -> MASTER_HOST='master_hostname',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='password',
    -> MASTER_SSL=1,
    -> MASTER_SSL_CA = 'ca_file_name',
    -> MASTER_SSL_CAPATH = 'ca_directory_name',
    -> MASTER_SSL_CERT = 'cert_file_name',
    -> MASTER_SSL_KEY = 'key_file_name';
mysql> START SLAVE;

關於複製使用者

全新建立

mysql> CREATE USER 'repl'@'%.example.com' IDENTIFIED BY 'password'
    -> REQUIRE SSL;
mysql> GRANT REPLICATION SLAVE ON *.*
    -> TO 'repl'@'%.example.com';

給原來的使用者新增 REQUIRE SSL

mysql> ALTER USER 'repl'@'%.example.com' REQUIRE SSL;

二進位制的日誌的自動刪除

Mysql 終端中設定

不用重啟服務

下面的命令是隻保留 10 天內的日誌,就是10天前的全部刪除

mysql> set global expire_logs_days = 10;

當二進位制日誌的大小達到max_binlog_size系統變數的值時,將重新整理二進位制日誌 。

max_binlog_size

屬性
命令列格式 --max-binlog-size=#
系統變數 max_binlog_size
範圍 全域性
動態
型別 整數
預設值 1073741824
最低價值 4096
最大價值 1073741824

如果對二進位制日誌的寫入導致當前日誌檔案大小超過此變數的值,則伺服器將輪轉二進位制日誌(關閉當前檔案並開啟下一個檔案)。最小值為4096位元組。最大值和預設值為1GB。

事務在一個塊中寫入二進位制日誌,因此它永遠不會在幾個二進位制日誌之間拆分。因此,如果您有大事務,您可能會看到大於的二進位制日誌檔案max_binlog_size

如果max_relay_log_size為0,則該值也 max_binlog_size適用於中繼日誌。

配置檔案中設定

此方法需要重啟服務

[mysqld]
expire_logs_days=10

在 MySQL 終端中手動刪除

--清除MySQL-bin.010日誌
mysql> PURGE MASTER LOGS TO 'MySQL-bin.010';

--清除2008-06-22 13:00:00前binlog日誌
mysql> PURGE MASTER LOGS BEFORE '2008-06-22 13:00:00';   

--清除3天前binlog日誌BEFORE,變數的date自變數可以為'YYYY-MM-DD hh:mm:ss'格式。
mysql> PURGE MASTER LOGS BEFORE DATE_SUB( NOW(), INTERVAL 3 DAY);  
本作品採用《CC 協議》,轉載必須註明作者和本文連結

你還差得遠吶!

相關文章