MySQL雙主(master-master)+半同步(Semisync Replication)

概覽

  • nodeA和nodeB互為主備藤韵,即雙主架構(gòu)Master-Master狮腿。
  • 使用semisync半同步機(jī)制,保證雙主數(shù)據(jù)一致雁刷。
  • 只有一個(gè)Master承擔(dān)寫操作覆劈,另一個(gè)備用,可承擔(dān)讀操作沛励,配合應(yīng)用實(shí)現(xiàn)讀寫分離责语。
  • 雙主加上Keepavlied可搭建高可用MySQL集群,實(shí)現(xiàn)單點(diǎn)故障切換目派。(本文不涉及)

準(zhǔn)備工作

  1. 安裝mysql5.7

(MySQL5.7改善了半同步復(fù)制坤候,降低了主從數(shù)據(jù)不一致的風(fēng)險(xiǎn)。)

  1. 修改mysql配置文件

啟動(dòng)MySQL之前先修改/etc/my.cnf企蹭,增加下面的配置白筹。
nodeA的配置文件

server-id = 1
log-bin=mysql-bin    # 打開二進(jìn)制日志功能徘键,作為主庫(kù)時(shí)必須設(shè)置
log-slave-updates    # 做為從庫(kù)時(shí),數(shù)據(jù)庫(kù)的修改也會(huì)寫到bin-log里
binlog-ignore-db = mysql #二進(jìn)制日志忽略的數(shù)據(jù)庫(kù)
binlog-ignore-db = information_schema 
binlog-ignore-db = performance_schema
replicate-wild-ignore-table = mysql.% #忽略備份的表
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
expire_logs_days=5   # 表示自動(dòng)刪除5天以前的binlog遍蟋,可選

nodeB的配置文件

server-id = 2  #確保節(jié)點(diǎn)id不同
log-bin=mysql-bin    # 打開二進(jìn)制日志功能,作為主庫(kù)時(shí)必須設(shè)置
log-slave-updates    # 做為從庫(kù)時(shí)螟凭,數(shù)據(jù)庫(kù)的修改也會(huì)寫到bin-log里
binlog-ignore-db = mysql #二進(jìn)制日志忽略的數(shù)據(jù)庫(kù)
binlog-ignore-db = information_schema 
binlog-ignore-db = performance_schema
replicate-wild-ignore-table = mysql.% #忽略備份的表
replicate-wild-ignore-table = information_schema.%
replicate-wild-ignore-table = performance_schema.%
expire_logs_days=5   # 表示自動(dòng)刪除5天以前的binlog虚青,可選
  1. 在nodeA和nodeB上創(chuàng)建專門用于Replication的賬戶
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%' IDENTIFIED BY '123456';
mysql> FLUSH PRIVILEGES;

Master-Master配置

  1. 配置nodeA為主庫(kù)
    在nodeA上配置:記住 File 和Position字段(File對(duì)應(yīng)MASTER_LOG_FILE,Position對(duì)應(yīng)MASTER_LOG_POS)
mysql> reset master; #清空master的binlog螺男,平時(shí)慎用棒厘,可選
mysql> flush tables with read lock; #只讀
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

mysql> show master status;
+------------------+----------+--------------+---------------------------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            | Executed_Gtid_Set |
+------------------+----------+--------------+---------------------------------------------+-------------------+
| mysql-bin.000002 |      154 |              | mysql,information_schema,performance_schema |                   |
+------------------+----------+--------------+---------------------------------------------+-------------------+
1 row in set (0.00 sec)
  1. 配置nodeB為nodeA的從庫(kù)
    在bodeB上配置:
mysql>stop slave;
mysql> CHANGE MASTER TO MASTER_HOST='{nodeA-server-ip}', MASTER_USER='repl_user', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=154;
mysql> start slave;
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 此處為nodeA_ip地址
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000012
          Read_Master_Log_Pos: 154
               Relay_Log_File: izj6c1rl2qyewsyu87vth0z-relay-bin.000012
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000012
             Slave_IO_Running: Yes (為Yes表示成功,為No查看Last_IO_Error信息)
            Slave_SQL_Running: Yes (為Yes表示成功下隧,為No查看Last_SQL_Error信息)
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table: mysql.%,information_schema.%,performance_schema.%
....
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  1. 將nodeB設(shè)為主庫(kù)
    在nodeB上設(shè)置:同樣記住File和Position
mysql> reset master;(清空master的binlog奢人,平時(shí)慎用,可選)
mysql> flush tables with read lock;
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

mysql> show master status;
+------------------+----------+--------------+---------------------------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            | Executed_Gtid_Set |
+------------------+----------+--------------+---------------------------------------------+-------------------+
| mysql-bin.000002 |      154 |              | mysql,information_schema,performance_schema |                   |
+------------------+----------+--------------+---------------------------------------------+-------------------+
1 row in set (0.00 sec)
  1. 配置nodeA為nodeB的從庫(kù)
    在bodeA上配置:
mysql>stop slave;
mysql> CHANGE MASTER TO MASTER_HOST='{nodeB-server-ip}', MASTER_USER='repl_user', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=154;
mysql> start slave;
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 此處為nodeB_ip地址
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000012
          Read_Master_Log_Pos: 154
               Relay_Log_File: izj6c1rl2qyewsyu87vth0z-relay-bin.000012
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000012
             Slave_IO_Running: Yes (為Yes表示成功淆院,為No查看Last_IO_Error信息)
            Slave_SQL_Running: Yes (為Yes表示成功何乎,為No查看Last_SQL_Error信息)
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table: mysql.%,information_schema.%,performance_schema.%
....
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:

最后在nodeB上執(zhí)行

mysql> unlock tables; #只讀鎖解除

雙Master配置完成

Semisync半同步配置

  1. 加載semisync_master和semisync_slave插件
    nodeA和nodeB上執(zhí)行:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> show variables like '%semi%';

rpl_semi_sync_master_timeout=10000
表示主庫(kù)在某次事務(wù)中,如果等待時(shí)間超過10秒土辩,則降級(jí)為普通模式支救,不再等待備庫(kù)。如果主庫(kù)再次探測(cè)到備庫(kù)恢復(fù)了拷淘,則會(huì)自動(dòng)再次回到semisync模式各墨。
rpl_semi_sync_master_wait_point=AFTER_SYNC

AFTER_SYNC工作流程:
  • 客戶端提交一個(gè)事務(wù),master將事務(wù)寫入binlog并刷新到磁盤启涯,發(fā)送到slave贬堵,master等待slave反饋。
  • slave接收master的binlog结洼,寫到本地的relaylog里黎做。發(fā)送確認(rèn)信息給master。
  • 當(dāng)接收到slave反饋补君,master提交事務(wù)并返回結(jié)果給客戶端引几。這樣就保證了主從數(shù)據(jù)一致。
  1. 開啟semisync master和slave
    nodeA和nodeB上執(zhí)行:
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
mysql> stop slave;start slave;
mysql> show status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    | (master同步)
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
| Rpl_semi_sync_slave_status                 | ON    |(從同步)
+--------------------------------------------+-------+
15 rows in set (0.00 sec)

并修改my.cnf挽铁,添加下面兩行:

rpl_semi_sync_master_enabled = 1
rpl_semi_sync_slave_enabled = 1

至此mysql Master-Master+半同步配置完成

可能出現(xiàn)的錯(cuò)誤

  1. Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs;
    mysql 5.7的復(fù)制引入了uuid的概念伟桅,各個(gè)復(fù)制結(jié)構(gòu)中的server_uuid得保證不一樣,找到/etc/my.cnf文件中的datadir目錄叽掘,找到auto.cnf 中的server_uuid更改后重啟mysql服務(wù)
  2. Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file

在master那邊楣铁,執(zhí)行:

flush logs;
show master status;

記下File, Position。
在slave端更扁,執(zhí)行:

CHANGE MASTER TO MASTER_LOG_FILE='{File}',MASTER_LOG_POS={Position};
slave start;
show slave status \G

參考

https://dev.mysql.com/doc/refman/5.7/en/replication.html
https://blog.csdn.net/qq_16177481/article/details/70332004
https://blog.csdn.net/qq_16177481/article/details/70333978
http://blog.51cto.com/sqlercn/1975157

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盖腕,一起剝皮案震驚了整個(gè)濱河市赫冬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溃列,老刑警劉巖劲厌,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異听隐,居然都是意外死亡补鼻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門雅任,熙熙樓的掌柜王于貴愁眉苦臉地迎上來风范,“玉大人,你說我怎么就攤上這事沪么∨鹦觯” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵禽车,是天一觀的道長(zhǎng)寇漫。 經(jīng)常有香客問我,道長(zhǎng)殉摔,這世上最難降的妖魔是什么猪腕? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮钦勘,結(jié)果婚禮上陋葡,老公的妹妹穿的比我還像新娘。我一直安慰自己彻采,他們只是感情好腐缤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肛响,像睡著了一般岭粤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上特笋,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天剃浇,我揣著相機(jī)與錄音,去河邊找鬼猎物。 笑死虎囚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蔫磨。 我是一名探鬼主播淘讥,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蒲列!你這毒婦竟也來了窒朋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤蝗岖,失蹤者是張志新(化名)和其女友劉穎拭宁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體彩匕,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年袜漩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绪爸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宙攻,死狀恐怖奠货,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情座掘,我是刑警寧澤递惋,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站溢陪,受9級(jí)特大地震影響萍虽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜形真,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一杉编、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咆霜,春花似錦邓馒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至偿衰,卻和暖如春挂疆,著一層夾襖步出監(jiān)牢的瞬間改览,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工缤言, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宝当,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓胆萧,卻偏偏與公主長(zhǎng)得像庆揩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子跌穗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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