Mysql 主從復(fù)制 讀寫分離

第1章 Mysql 主從復(fù)制

MySQL replication

主從復(fù)制 (也稱之為AB復(fù)制) 允許將一個(gè)MySQL數(shù)據(jù)庫(kù)服務(wù)器 (主服務(wù)器) 的數(shù)據(jù)復(fù)制到一 或多個(gè)MySQL數(shù)據(jù)庫(kù)服務(wù)器 (從服務(wù)器).

復(fù)制是異步的****從站不需要永久連接來(lái)接收來(lái)自主站的更新數(shù)據(jù)

根據(jù)配置 可用復(fù)制數(shù)據(jù)庫(kù)中所有數(shù)據(jù)庫(kù) 或 選擇數(shù)據(jù)庫(kù)中指定的表

MySQL主從復(fù)制優(yōu)點(diǎn)

(1) 橫向擴(kuò)展解決方案 - 在多個(gè)從站之間分配負(fù)載以提高性能。

在此環(huán)境中,所有寫入和更新都必須在主服務(wù)器上進(jìn)行。 但是,讀取可以在一個(gè)或多個(gè)從設(shè)備上進(jìn)行。該模型可以提高寫入性能(因?yàn)橹髟O(shè)備專用于更新),同時(shí)顯著提高了越來(lái)越多的從設(shè)備的讀取速度

(2) 數(shù)據(jù)安全性 - 因?yàn)閿?shù)據(jù)被復(fù)制到從站,并且從站可以暫停復(fù)制過(guò)程,所以可以在從站上運(yùn)行備份服務(wù)而不會(huì)破壞相應(yīng)的主數(shù)據(jù)。

(3) 分析 - 可以在主服務(wù)器上創(chuàng)建實(shí)時(shí)數(shù)據(jù),而信息分析可以在從服務(wù)器上進(jìn)行,而不會(huì)影響主服務(wù)器的性能。

(4) 遠(yuǎn)程數(shù)據(jù)分發(fā) - 您可以使用復(fù)制為遠(yuǎn)程站點(diǎn)創(chuàng)建數(shù)據(jù)的本地副本,而無(wú)需永久訪問(wèn)主服務(wù)器。

Replication的原理

image.png

(1) 主服務(wù)器上的任何修改都會(huì)通過(guò)自己的I/O tread(I/O 線程)保存在二進(jìn)制日志 Binary log 里面

(2) 從服務(wù)器上面也啟動(dòng)一個(gè)I/O tread 通過(guò)配找到用戶名和密碼,連接到主服務(wù)器上面 請(qǐng)求讀取二進(jìn)制日志 然后把讀取到的二進(jìn)制日志寫到本地的一個(gè)Realy log (中繼日志)內(nèi)

(3) 從服務(wù)器上面同時(shí)開啟一個(gè)SQL thread 定時(shí)檢查Realy log (這個(gè)文件也是二進(jìn)制的) 如果發(fā)現(xiàn)有更新 立即把更新內(nèi)容在本地?cái)?shù)據(jù)庫(kù)上執(zhí)行一遍

每個(gè)從服務(wù)器都會(huì)收到主服務(wù)器的二進(jìn)制日志其內(nèi)容的副本

從服務(wù)器設(shè)備負(fù)責(zé)決定應(yīng)該執(zhí)行二進(jìn)制日志中的那些語(yǔ)句,除非另行指定 否則主從二進(jìn)制日志中的所有事件都會(huì)在從站上執(zhí)行一次

如果需要, 你可以將從服務(wù)器配置為僅處理一些特定數(shù)據(jù)庫(kù)或表的事件

你無(wú)法將主服務(wù)器配置為僅處理一些特定數(shù)據(jù)庫(kù)或表的事件

每個(gè)從站都會(huì)記錄二進(jìn)制日志坐標(biāo): 文件名 文件中它已經(jīng)從主站讀取和處理的位置。

由于每個(gè)從服務(wù)器都分別記錄了自己當(dāng)前處理的二進(jìn)制日志中的位置,因此可以斷開從服務(wù)器的連接, 重新連接然后恢復(fù)繼續(xù)處理任務(wù).

一主多從

如果一主多從的話,這時(shí)主庫(kù)既要負(fù)責(zé)寫又要負(fù)責(zé)為幾個(gè)從庫(kù)提供二進(jìn)制日志。

此時(shí)可以稍做調(diào)整,將二進(jìn)制日志只給某一從,這一從再開啟二進(jìn)制日志并將自己的二進(jìn)制日志再發(fā)給其它從。或者是干脆這個(gè)從不記錄只負(fù)責(zé)將二進(jìn)制日志轉(zhuǎn)發(fā)給其它從,這樣架構(gòu)起來(lái)性能可能要好得多,而且數(shù)據(jù)之間的延時(shí)應(yīng)該也稍微要好一些。

工作原理圖如下:

image.png

關(guān)于二進(jìn)制日志

mysqld將數(shù)字?jǐn)U展名附加到二進(jìn)制日志基本名稱以生成二進(jìn)制日志文件名。每次服務(wù)器創(chuàng)建新日志文件時(shí),該數(shù)字都會(huì)增加,從而創(chuàng)建一系列有序的文件。

每次啟動(dòng)或刷新日志時(shí),服務(wù)器都會(huì)在系列中創(chuàng)建一個(gè)新文件。

服務(wù)器還會(huì)在當(dāng)前日志大小達(dá)到max_binlog_size參數(shù)設(shè)置的大小后自動(dòng)創(chuàng)建新的二進(jìn)制日志文件 。

二進(jìn)制日志文件可能會(huì)比max_binlog_size使用大型事務(wù)時(shí)更大, 因?yàn)槭聞?wù)是以一個(gè)部分寫入文件,而不是在文件之間分割。

為了跟蹤已使用的二進(jìn)制日志文件, mysqld還創(chuàng)建了一個(gè)二進(jìn)制日志索引文件,其中包含所有使用的二進(jìn)制日志文件的名稱。默認(rèn)情況下,它具有與二進(jìn)制日志文件相同的基本名稱,并帶有擴(kuò)展名'.index'。在mysqld運(yùn)行時(shí),您不應(yīng)手動(dòng)編輯此文件。

術(shù)語(yǔ)二進(jìn)制日志文件通常表示包含數(shù)據(jù)庫(kù)事件的單個(gè)編號(hào)文件。

術(shù)語(yǔ) 二進(jìn)制日志 表示含編號(hào)的二進(jìn)制日志文件集加上索引文件。

SUPER 權(quán)限的用戶可以使用SET sql_log_bin=0語(yǔ)句禁用其當(dāng)前環(huán)境下自己的語(yǔ)句的二進(jìn)制日志記錄

第2章 配置 Replication

配置步驟:

主服務(wù)器配置

第一步

在主服務(wù)器上,你必須啟用二進(jìn)制日志記錄并配置唯一的服務(wù)器ID信息 最后重啟服務(wù)器

  1. 編輯主服務(wù)器上的配置文件 /etc/my.cof 添加內(nèi)容
vim /etc/my.cof
最后一行添加
[mysqld]
server-id=1 
log-bin=mysql-bin                     (mysql-bin)默認(rèn)指定文件  不用設(shè)置默認(rèn)存放在/var/lib/mysql/ 
log_bin_index=mysql-bin.index         (master-bin.index)默認(rèn)指認(rèn)文件 不用設(shè)置
binlog_do_db=test
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

備注:
server-id         服務(wù)器唯一標(biāo)識(shí)。
log_bin           啟動(dòng)MySQL二進(jìn)制日志,即數(shù)據(jù)同步語(yǔ)句,從數(shù)據(jù)庫(kù)會(huì)一條一條的執(zhí)行這些語(yǔ)句。
log_bin_index     指定的是二進(jìn)制文件的索引文件 這個(gè)文件管理了所有的binlog文件的目錄
binlog_do_db      指定記錄二進(jìn)制日志的數(shù)據(jù)庫(kù),即需要復(fù)制的數(shù)據(jù)庫(kù)名,如果復(fù)制多個(gè)數(shù)據(jù)庫(kù),重復(fù)設(shè)置這個(gè)選項(xiàng)即可。
binlog_ignore_db  指定不記錄二進(jìn)制日志的數(shù)據(jù)庫(kù),即不需要復(fù)制的數(shù)據(jù)庫(kù)名,如果有多個(gè)數(shù)據(jù)庫(kù),重復(fù)設(shè)置這個(gè)選項(xiàng)即可。
其中需要注意的是,binlog_do_db和binlog_ignore_db為互斥選項(xiàng),一般只需要一個(gè)即可。
  1. 重啟服務(wù)

systemctl restart mysqld
systemctl restart mariadb (小型數(shù)據(jù)庫(kù))

注意:

如果省略 server-id(或?qū)⑵滹@式設(shè)置為默認(rèn)值0),則主服務(wù)器拒絕來(lái)自從服務(wù)器的任何連接。

為了在使用帶事務(wù)的InnoDB進(jìn)行復(fù)制設(shè)置時(shí)盡可能提高持久性和一致性, 您應(yīng)該在master (主服務(wù)器) my.cnf文件中使用以下配置項(xiàng):

innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

確保在主服務(wù)器上 skip_networking 選項(xiàng)處于 OFF 關(guān)閉狀態(tài), 這是默認(rèn)值。 如果是啟用的,則從站無(wú)法與主站通信,并且復(fù)制失敗。

mysql> show variables like '%skip_networking%';

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

|  Variable_name  |  Value  |

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

| skip_networking |  OFF  |

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

查看主數(shù)據(jù)庫(kù)信息,記住下面的“File”與“Position”的信息,它們是用來(lái)配置從數(shù)據(jù)庫(kù)的關(guān)鍵信息。

mysql> show master status;

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

 | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

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

 | mysql-bin.000004 | 381 | test | |

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

 1 row in set (0.00 sec)

第二步

創(chuàng)建一個(gè)專用于負(fù)責(zé)數(shù)據(jù)的用戶

每個(gè)從站需要使用MySQL主站上的用戶名和密碼連接到主站上

例如: 計(jì)劃使用用戶old可以從任何主機(jī)上連接到master (主服務(wù)器)上進(jìn)行輔助操作并且用戶old僅僅可以使用復(fù)制權(quán)限

實(shí)現(xiàn)以上執(zhí)行操作

mysql> GRANT REPLICATION SLAVE ON *.* TO 'old'@'%' identified by '123456';

  1. 192.168.17.%通配符,表示0-255的IP都可訪問(wèn)主服務(wù)器,正式環(huán)境請(qǐng)配置指定從服務(wù)器IP

  2. 若將 192.168.17.% 改為 %,則任何ip均可作為其從數(shù)據(jù)庫(kù)來(lái)訪問(wèn)主服務(wù)器

在從服務(wù)器上使用用戶進(jìn)行測(cè)試連接

shell> mysql -uold -p'123456' -h

如果主服務(wù)器中有數(shù)據(jù)

如果在啟動(dòng)復(fù)制之前有現(xiàn)有數(shù)據(jù)需要與從屬設(shè)備同步,請(qǐng)保持客戶端正常運(yùn)行,以便鎖定保持不變。這可以防止進(jìn)行任何進(jìn)一步的更改,以便復(fù)制到從站的數(shù)據(jù)與主站同步。

在主服務(wù)器中導(dǎo)出現(xiàn)有的數(shù)據(jù)

  1. 如果主數(shù)據(jù)庫(kù)包含現(xiàn)有數(shù)據(jù),則必須將此數(shù)據(jù)復(fù)制到每個(gè)從站。有多種方法可以實(shí)現(xiàn)
    使用mysqldump工具創(chuàng)建要復(fù)制的所有數(shù)據(jù)庫(kù)的轉(zhuǎn)儲(chǔ)。這是推薦的方法
    mysqldump -u用戶名 -p密碼 --all-databases --master-data=1 > /tmp/back.sql
    這里的用戶是主服務(wù)器的用戶
    如果不使用--master-data參數(shù),則需要手動(dòng)鎖定單獨(dú)會(huì)話中的所有表。

  2. 從主服務(wù)器中使用 scp 或 rsync 等工具,把備份出來(lái)的數(shù)據(jù)傳輸?shù)綇姆?wù)器中。
    在主服務(wù)中執(zhí)行如下命令
    rsync -avz /tmp/back.sql 目標(biāo)ip:存放目錄
    這里的 目標(biāo)ip需要能被主服務(wù)器解析出 IP 地址,或者說(shuō)可以在主服務(wù)器中 ping 通的。

  3. 導(dǎo)入數(shù)據(jù)到從服務(wù)器,并配置連接到主服務(wù)器的相關(guān)信息
    登錄到從服務(wù)器上,執(zhí)行如下操作
    導(dǎo)入數(shù)據(jù)mysql> source /tmp/back.sql

從服務(wù)器配置

  1. 配置從服務(wù)器,并重啟 在從服務(wù)器 上編輯其配置文件 /etc/my.cnf 并添加如下內(nèi)容:

vim my.cnf 文件 最后編寫

[mysqld]

server-id=2

relay-log=slave-relay-bin

relay-log-index=slave-relay-bin.index

replicate-do-db=test

server-id 服務(wù)器唯一標(biāo)識(shí),如果有多個(gè)從服務(wù)器,每個(gè)服務(wù)器的server-id不能重復(fù),跟IP一樣是唯一標(biāo)識(shí), 如果你沒設(shè)置server-id或者設(shè)置為0,則從服務(wù)器不會(huì)連接到主服務(wù)器。

relay-log 啟動(dòng)MySQL二進(jìn)制日志,可以用來(lái)做數(shù)據(jù)備份和崩潰恢復(fù),或主服務(wù)器掛掉了將此從服務(wù)器作為其他從服務(wù)器的主服務(wù)器。

replicate-do-db 指定同步的數(shù)據(jù)庫(kù),如果復(fù)制多個(gè)數(shù)據(jù)庫(kù),重復(fù)設(shè)置這個(gè)選項(xiàng)即可。 若在master端不指定binlog-do-db,則在slave端可用replication-do-db來(lái)過(guò)濾。

replicate-ignore-db 不需要同步的數(shù)據(jù)庫(kù),如果有多個(gè)數(shù)據(jù)庫(kù),重復(fù)設(shè)置這個(gè)選項(xiàng)即可。

其中需要注意的是,replicate-do-dbreplicate-ignore-db為互斥選項(xiàng),一般只需要一個(gè)即可。

  1. 在從服務(wù)器配置連接到主服務(wù)器的相關(guān)信息
mysql> CHANGE MASTER TO
MASTER_HOST='遠(yuǎn)程IP地址',              -- 主服務(wù)器的主機(jī)名(也可以是 IP) 
MASTER_USER='old',                     -- 連接到主服務(wù)器的用戶
MASTER_PASSWORD='123456',              -- 到主服務(wù)器的密碼
MASTER_LOG_FILE=' mysql-bin.000004',   -- 日志文件的名稱,需要與主服務(wù)器對(duì)應(yīng)
MASTER_LOG_POS='381';                  -- 日志位置,需要與主服務(wù)器對(duì)應(yīng)
  1. 啟動(dòng)從服務(wù)器的復(fù)制線程
mysql>  start slave;       開啟線程
Query OK, 0 rows affected (0.09 sec) 

stop slave ? 停止線程
重啟服務(wù)
systemctl restart mysql
systemctl restart mariadb.service

出現(xiàn)問(wèn)題解決思路

如果執(zhí)行出現(xiàn)問(wèn)題可使用下面命令 查看server_id狀態(tài) 主站應(yīng)為數(shù)值1 從站應(yīng)為數(shù)值2以上

show variables like 'server_id';

可在數(shù)據(jù)庫(kù)中手動(dòng)進(jìn)行設(shè)置

SET GLOBAL server_id=2;

啟動(dòng)服務(wù)出現(xiàn):

ERROR 1201 (HY000): Could not initialize master info structure; more error messages can be found in the MariaDB error log

解決辦法: 由于新的slave改變了服務(wù)端口和文件路徑,分析應(yīng)該是由于mysql-relay-bin.index中仍然保存著舊relay日志文件的路徑,而這些路徑下又找不到合適的文件,因此報(bào)錯(cuò)。

對(duì)于這類問(wèn)題解決起來(lái)是比較簡(jiǎn)單的,重置slave的參照即可,執(zhí)行命令如下:

mysql>reset slave;            重置slave的參照

Query OK, 0 rows affected (0.01 sec)

重新設(shè)置salve參照

mysql> CHANGE MASTER TO

 MASTER_HOST='172.16.1.51',

 MASTER_USER='old',

 MASTER_PASSWORD='123456';

檢查是否成功

在從服務(wù)上執(zhí)行如下操作,加長(zhǎng)從服務(wù)器端 IO線程和 SQL 線程是否是 OK

mysql>show slave status\G;

輸出結(jié)果中應(yīng)該看到 I/O 線程和 SQL 線程都是 YES, 就表示成功。

image.png

執(zhí)行此過(guò)程后,在主服務(wù)上操作的修改數(shù)據(jù)的操作都會(huì)在從服務(wù)器中執(zhí)行一遍,這樣就保證了數(shù)據(jù)的一致性。

第3章 小結(jié)

讀寫分離,我們可以通過(guò)程序來(lái)實(shí)現(xiàn),這里簡(jiǎn)單講解一下實(shí)現(xiàn)思想。

我們可以在主服務(wù)器創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)用戶(出于安全,根據(jù)需求給予相應(yīng)的權(quán)限)主要用于寫操作,在程序中通過(guò)這一用戶連接主數(shù)據(jù)庫(kù)的只用于寫操作而不用讀操作。

在從服務(wù)器上創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)用戶(出于安全,只給予讀select的權(quán)限)主要用于讀操作,在程序中通過(guò)這一用戶連接從數(shù)據(jù)庫(kù)即可。

當(dāng)然,也可以找一個(gè)組件來(lái)完成MYSQL的代理,實(shí)現(xiàn)SQL語(yǔ)句的路由,這樣就不需要我們?cè)诔绦蛏详P(guān)注哪個(gè)數(shù)據(jù)庫(kù)是寫,哪個(gè)數(shù)據(jù)庫(kù)是讀的了。

參照文檔****: https://blog.csdn.net/qq_15092079/article/details/81672920#2%20master%E4%B8%BB%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E9%85%8D%E7%BD%AE

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容