MySQL復(fù)制入門

Ⅰ屉佳、復(fù)制類型

1.1 邏輯復(fù)制

  • 記錄每次邏輯操作
  • 主從數(shù)據(jù)庫可以不一致

1.2 物理邏輯復(fù)制

  • 記錄每次對于數(shù)據(jù)頁的操作
  • 主從數(shù)據(jù)物理嚴(yán)格一致
  • 基于重做日志

說明:

如果一個塊(頁)修改了绪钥,就把這個修改發(fā)到遠(yuǎn)端

主從兩端不僅僅是數(shù)據(jù)一致淹魄,而是物理上的一致纪他,頁都是一樣的

1.3 復(fù)制選型與對比

簡單的主從環(huán)境趣苏,兩邊同樣的表扰楼,space_id不用一樣,只要保證數(shù)據(jù)在邏輯內(nèi)容上一致划鸽,物理上不用一樣输莺。也就是說戚哎,一張表的數(shù)據(jù)一致就行,不要求這些數(shù)據(jù)對應(yīng)的表空間里面內(nèi)容也一致

Oracle的優(yōu)勢
Oracle中commit時間是平均的嫂用,MySQL卻不是

MySQL中事務(wù)越大commit越慢型凳,binlog是事務(wù)執(zhí)行完commit之后才寫,從而產(chǎn)生延時的問題嘱函,Oracle中是物理邏輯復(fù)制甘畅,塊的變化實時同步到從上

MySQL的優(yōu)勢
做大數(shù)據(jù),把MySQL里面的數(shù)據(jù)變化傳到數(shù)據(jù)倉庫平臺往弓,MySQL做起來就很方便疏唾,Oralce做起來麻煩,物理日志要去解析是解析不出來行的變化的函似,但是有ogg工具可以同步到hive槐脏,不過偏商業(yè)

Ⅱ、典型關(guān)系型數(shù)據(jù)庫復(fù)制對比

- MySQL Oracle Data Gurad SQL Server Mirroring
類型 邏輯復(fù)制 物理邏輯復(fù)制 物理邏輯復(fù)制
優(yōu)點 靈活 復(fù)制速度快 復(fù)制速度快
缺點 配置不當(dāng)易出錯 要求物理數(shù)據(jù)嚴(yán)格一致 要求物理數(shù)據(jù)嚴(yán)格一致

問:MySQL的innodb也有redo撇寞,那為什么不支持redo級別的復(fù)制呢顿天?

答:因為MySQL有很多種引擎,需要有一個統(tǒng)一的復(fù)制層蔑担,而不是在引擎層做復(fù)制牌废,所以在server層實現(xiàn)復(fù)制,每個引擎做一個復(fù)制就做不到一致性了

一般業(yè)務(wù)架構(gòu)钟沛,一主兩從足夠畔规,金融行業(yè)可能會做一主四從

Ⅲ、復(fù)制搭建

小常識
MySQL的事務(wù)一次commit分成三個階段

第一階段的prepare和第三階段的commit都在innodb層

第二階段的write binlog在server層

三個步驟都是group commit的恨统,所以性能不會差

3.1 基本原理

 +-----+                      +-----+  
 |  M  |                      |  S  | 
 +--+--+                      +--^--+
    | change                     | apply
    |              +-----+   +---+--+
    |        +---->|io td|   |sql td| 
    |        |     +--+--+   +---^--+ 
    |        |        |          |
    |        |        |in_put    | out_put
 +--v-----+  |   +----v----+     |
 | binlog +--^   |relay log+-----^
 +--------+      +---------+

當(dāng)commit寫到二進(jìn)制文件之后,如果搭建了復(fù)制三妈,就會有一個dump thread將binlog傳送到遠(yuǎn)程服務(wù)器

遠(yuǎn)端服務(wù)器上有一個IO thread來接收這些event放到relay log中畜埋,還有一個SQL thread來回放relay log中的event

5.6版本開始,可以多個線程并行回放畴蒲,所以速度相對來說可能快一些

tips:
①關(guān)于binlog悠鞍,詳見binlog——邏輯復(fù)制的基礎(chǔ)

②master發(fā)送給slave的是什么東西?具體怎么發(fā)送的模燥? 答:以event為最小單位發(fā)送咖祭,千萬不要說sql語句或者記錄

③關(guān)于relay log

  • Relay_Log_File和Relay_Log_Pos 是中繼日志(relay log)信息
  • 由于IO線程拉取數(shù)據(jù)的速度快于SQL線程回放數(shù)據(jù)的速度,所以relay log可在兩者之間起到一個緩沖的作用
  • relay log的格式和binlog的格式是一樣的蔫骂,但是兩者的內(nèi)容是不一樣的(不是和binlog一一對應(yīng)的)
  • relay log在SQL線程回放完成后就會被刪除(默認(rèn))么翰,而 binlog 不會(由expire_logs_days控制)
  • relay log 可以通過設(shè)置 relay_log_purge=0,使得relay Log不被刪除(MHA中不希望被purge)辽旋,需要通過外部的腳本進(jìn)行刪除

3.2 動手搭一個

炒雞簡單浩嫌,雖然沒mongodb簡單檐迟,但比oracle簡單太多了(redis的cluster比mongodb都簡單),搞起來B肽汀I取廓块!

步驟 操作
step1 主機(jī)備份數(shù)據(jù)
step2 從機(jī)恢復(fù)數(shù)據(jù)
step3 主機(jī)授權(quán)一個復(fù)制用戶權(quán)限
step4 從機(jī)change master to(filename,pos)
  • pos之前是導(dǎo)過來的數(shù)據(jù)浓利,pos之后通過binlog同步,這是一個最終一致性的模型苹威,master不斷將binlog發(fā)到slave
  • binlog的恢復(fù)是手工的,MySQL的復(fù)制是準(zhǔn)實時的

實操

本人是窮人,這里用單機(jī)多實例模擬:
主用3306端口    server-id:3306
從用3307端口    server-id:3307

重點:
主從之間的server-id千萬不能一樣,否則可能導(dǎo)致宕機(jī)

說明:我這里3306跑的是mysql5.5,3307跑的mysql5.6,所以bashrc和my.cnf中配置的東西55就是3306,56就是3307的意思

step1:
主上做備份
[root@VM_0_5_centos ~]# mysqldump --single-transaction --master-data=1 -A -S /tmp/mysql.sock55 > /tmp/fullbackup.sql

step2:
從上導(dǎo)入備份
[root@VM_0_5_centos ~]# mysql56 < /tmp/fullbackup.sql

step3:
主上授權(quán)復(fù)制用戶權(quán)限
(root@172.16.0.10) [test]> create user 'rpl'@'%' identified by '123';
Query OK, 0 rows affected (0.01 sec)
(root@172.16.0.10) [test]> grant replication slave on *.* to 'rpl'@'%'; --需要replication和slave的權(quán)限筑煮,線上建議 限制成內(nèi)網(wǎng)的網(wǎng)段
Query OK, 0 rows affected (0.01 sec)

打開備份文件初澎,找到二進(jìn)制文件位置點
[root@VM_0_5_centos ~]# head -n 30 /tmp/fullbackup.sql
CHANGE MASTER TO MASTER_LOG_FILE='bin.000004', MASTER_LOG_POS=107;
找到上面這句

step4:
登陸到從實例執(zhí)行如下語句:
(root@172.16.0.10) [test]> CHANGE MASTER TO MASTER_LOG_FILE='bin.000004', MASTER_LOG_POS=107, MASTER_HOST='127.0.0.1' ,MASTER_PORT=3306 ,MASTER_USER='rpl' ,MASTER_PASSWORD='123';
Query OK, 0 rows affected, 2 warnings (0.12 sec) -- 有warning是因為密碼寫在了里面

檢查:
從上執(zhí)行show slave status\G --此處只貼部分關(guān)鍵內(nèi)容
(root@172.16.0.10) [test]> show slave status\G
*************************** 1. row ***************************
 Slave_IO_State: 
 Master_Host: 127.0.0.1
 Master_User: rpl
 Master_Port: 3306
 Connect_Retry: 60
 Master_Log_File: bin.000004        -- change master中的filename
 Read_Master_Log_Pos: 107           -- change master中的pos
 Relay_Log_File: relay.000001
 Relay_Log_Pos: 4
 Relay_Master_Log_File: bin.000004
 Slave_IO_Running: No 
 Slave_SQL_Running: No
 
到這一步延柠,我們的主從復(fù)制就搭建好了贿条!但是我們看到io線程和sql線程都是no峻仇,我們需要在從機(jī)上啟動復(fù)制
(root@172.16.0.10) [test]>start slave;
Query OK, 0 rows affected (0.00 se
再看兩個線程就都是Yes了
Slave_IO_Running和Slave_SQL_Running這兩個指標(biāo)都為YES,表示目前的復(fù)制的狀態(tài)是正常的

3.3 細(xì)說show slave status\G

(root@172.16.0.10) [test]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event     IO線程狀態(tài)
                  Master_Host: 127.0.0.1                            主機(jī)IP
                  Master_User: rpl                                  復(fù)制用戶名
                  Master_Port: 3306                                 主機(jī)端口號
                Connect_Retry: 60                                   連不上凡蚜,重連次數(shù),默認(rèn)60次
              Master_Log_File: bin.000004                           當(dāng)前同步到主機(jī)的logfile
          Read_Master_Log_Pos: 15451622                             當(dāng)前同步到的位置點
               Relay_Log_File: cloud-relay-bin.000002               slave上的中繼日志
                Relay_Log_Pos: 15451775                             中繼日志的位置點
        Relay_Master_Log_File: bin.000004                           當(dāng)前Relay文件對應(yīng)的Master文件
             Slave_IO_Running: Yes                                  IO線程狀態(tài)
            Slave_SQL_Running: Yes                                  SQL線程狀態(tài)
              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                                    跳過錯誤次數(shù)
          Exec_Master_Log_Pos: 15451622                             現(xiàn)在回放到的位置
              Relay_Log_Space: 15451944                             當(dāng)前中繼日志的大小
              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                                    sql線程落后io線程的時間
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: 3306
                  Master_UUID:
             Master_Info_File: /data/mysql_test_data56/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

最終來看,io線程和sql線程執(zhí)行的位置應(yīng)該一樣轿秧,但是通常sql線程會比io線程慢一點

tips:
①Seconds_Behind_Master: The number of seconds that the slave SQL thread is behind processing the master binary log

relay log中event記錄的時間戳是主庫上的時間戳咨堤,而SQL thread的時間戳是從庫上的菇篡,只有主從時間完全一致,該指標(biāo)才有意義

②重連機(jī)制

slave-net-timeout       從獲取不到數(shù)據(jù)后等待時間
master-connect-retry    重連等待時間
master-retry-count      重連次數(shù)

當(dāng)從庫發(fā)現(xiàn)從主庫上無法獲得更多的數(shù)據(jù)了一喘,就會等待slave-net-timeout時間驱还,然后將IO thread置為no狀態(tài),接著開始嘗試重建建立連接凸克,每次建立失敗之后等待master-connect-retry時間议蟆,一直重試master-retry-count次

Ⅳ、主從架構(gòu)中常用的操作

4.1 主

查看從服務(wù)器列表
(root@172.16.0.10) [test]> show slave hosts;
+-----------+------+-------+-----------+
| Server_id | Host | Port  | Master_id |
+-----------+------+-------+-----------+
|    3307   |      | 3307  |    3306   |
+-----------+------+-------+-----------+
1 row in set (0.00 sec)

看binlog到了什么位置
(root@172.16.0.10) [test]> show master status;
+----------------+----------+--------------+------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| mysql-bin.003  |     73   |              |                  |
+-------------------------------------------------------------+
1 row in set (0.00 sec)

4.2 從

show slave status;

change master to

start/stop slave

4.3 報錯處理

模擬報錯:
從:
(root@172.16.0.10) [test]> create database sb;
Query OK, 1 row affected (0.00 sec)

主:
(root@172.16.0.10) [test]> create database sb;
Query OK, 1 row affected (0.00 sec)

從:
(root@172.16.0.10) [test]> show slave status\G
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'sb'; database exists' on query. Default database: 'sb'. Query: 'create database sb'

報錯沖突了萎战!

怎么辦咐容?
從:
執(zhí)行如下sql,跳過當(dāng)前報錯,不執(zhí)行這個event
(root@172.16.0.10) [test]> set global sql_slave_skip_counter=1;
Query OK, 0 row affected (0.00 sec)
重新把主從復(fù)制拉起來
start slave;
Query OK, 0 row affected (0.00 sec)

關(guān)于這個跳過當(dāng)前報錯后面會專門具體展開分析蚂维,暫時了解這么多即可

Ⅴ戳粒、read_only與super_read_only

如果在slave機(jī)器上對數(shù)據(jù)庫進(jìn)行修改或者刪除,會導(dǎo)致主從的不一致鸟雏,需要對Slave機(jī)器設(shè)置為read_only = 1 享郊,讓slave提供只讀操作。

tips:

  • read_only僅僅對沒有SUPER權(quán)限的用戶有效(即 mysql.user表的Super_priv字段為Y)孝鹊,一般給APP的權(quán)限是不需要SUPER權(quán)限的

  • MySQL 5.7中參數(shù)super_read_only可以將有SUPER權(quán)限的用戶也設(shè)置為只讀炊琉,且該參數(shù)設(shè)置為ON后,read_only也跟著自動設(shè)置為ON

  • 當(dāng)前MySQL中又活,在/etc/my.cnf中將super_read_only=1配置好后重啟苔咪,還是可以插入或修改數(shù)據(jù)。需要在命令行中執(zhí)行set global super_read_only=1; 才能真正修改為只讀柳骄,具體何時修復(fù)還沒注意

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末团赏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子耐薯,更是在濱河造成了極大的恐慌舔清,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曲初,死亡現(xiàn)場離奇詭異体谒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)臼婆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門抒痒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颁褂,你說我怎么就攤上這事故响】悖” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵彩届,是天一觀的道長伪冰。 經(jīng)常有香客問我,道長惨缆,這世上最難降的妖魔是什么糜值? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮坯墨,結(jié)果婚禮上寂汇,老公的妹妹穿的比我還像新娘。我一直安慰自己捣染,他們只是感情好骄瓣,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耍攘,像睡著了一般榕栏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蕾各,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天扒磁,我揣著相機(jī)與錄音,去河邊找鬼式曲。 笑死妨托,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吝羞。 我是一名探鬼主播兰伤,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼钧排!你這毒婦竟也來了敦腔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤恨溜,失蹤者是張志新(化名)和其女友劉穎符衔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糟袁,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡柏腻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了系吭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡颗品,死狀恐怖肯尺,靈堂內(nèi)的尸體忽然破棺而出沃缘,到底是詐尸還是另有隱情,我是刑警寧澤则吟,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布槐臀,位于F島的核電站,受9級特大地震影響氓仲,放射性物質(zhì)發(fā)生泄漏水慨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一敬扛、第九天 我趴在偏房一處隱蔽的房頂上張望晰洒。 院中可真熱鬧,春花似錦啥箭、人聲如沸谍珊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砌滞。三九已至,卻和暖如春坏怪,著一層夾襖步出監(jiān)牢的瞬間贝润,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工铝宵, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留打掘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓捉超,卻偏偏與公主長得像胧卤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拼岳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

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