mysql主從復制架構,是mysql數據庫主要特色之一,絕大多數公司都有用到。
而GTID模式是基于事務的復制模式的意思,發展到現在也是越來越多人用。
以前很多文章,介紹搭建mysql主從復制架構,是需要停止應用服務來做的,對于生產環境,怎么可能讓你隨便停服務?所以必須做到在線做,不影響業務,那才是最實際的。
先說明,案例分兩種方案,實現的意義是一樣的,一種是mysqldump方式,一種是xtrabackup方式,視乎實際情況,因為有些業務不一定能用xtrabackup,例如阿里云RDS,騰訊CDB.
?
一、GTID的概述:
1、全局事物標識:global transaction identifieds。
2、GTID事物是全局唯一性的,且一個事務對應一個GTID。
3、一個GTID在一個服務器上只執行一次,避免重復執行導致數據混亂或者主從不一致。
4、GTID用來代替classic的復制方法,不在使用binlog+pos開啟復制。而是使用master_auto_postion=1的方式自動匹配GTID斷點進行復制。
5、MySQL-5.6.5開始支持的,MySQL-5.6.10后開始完善。
6、在傳統的slave端,binlog是不用開啟的,但是在GTID中,slave端的binlog是必須開啟的,目的是記錄執行過的GTID(強制)。
?
?
二、GTID的組成部分:
前面是server_uuid:后面是一個序列號
例如:server_uuid:sequence number
7800a22c-95ae-11e4-983d-080027de205a:10
UUID:每個mysql實例的唯一ID,由于會傳遞到slave,所以也可以理解為源ID。
Sequence number:在每臺MySQL服務器上都是從1開始自增長的序列,一個數值對應一個事務。
?
三、GTID比傳統復制的優勢:
1、更簡單的實現failover,不用以前那樣在需要找log_file和log_Pos。
2、更簡單的搭建主從復制。
3、比傳統復制更加安全。
4、GTID是連續沒有空洞的,因此主從庫出現數據沖突時,可以用添加空事物的方式進行跳過。
?
四、GTID的工作原理:
?
?
要點:
1、slave在接受master的binlog時,會校驗master的GTID是否已經執行過(一個服務器只能執行一次)。
2、為了保證主從數據的一致性,多線程只能同時執行一個GTID。
配置和授權(通用前置步驟)
如果沒有開GTID模式,主從庫不用做些什么特別配置,主從之間注意server-id不要一樣就可以了,這個坑很容易掉進去.
當然了,binlog是必須開的,主從就靠這個來復制的,不開就是白搭.
還有binlog_format推薦用row,原則上mixed也沒啥大問題,但是很多情況下實際上都會自動轉成row模式的,而且row模式是三種模式中,最少可能丟數據的模式,即使丟數據也是極個別的極端情況,例如斷網.
事務隔離界別transaction_isolation推薦REPEATABLE-READ或READ-COMMITTED都可以,視乎你對數據一致性要求高不高,但不代表那種會數據不準確.
========================================
開啟GTID模式,那就要設置下面兩個參數,而且一做就要全做,各主從服務器都要做,并需要重啟mysql服務才能生效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #這個不能在線開啟,要寫到配置文件my.cnf里面,還要重啟才生效。 #不然就是下面的報錯 mysql>? set ?gtid_mode?=?1; ERROR?1238?(HY000):?Variable? 'gtid_mode' ?is?a? read ?only?variable #所以我們要編輯my.cnf來開啟 vim?my.cnf #GTID模式,5.6的新功能,新的復制驗證方式,需要就打開,binlog建議改成row gtid_mode?=?on binlog_format?=?row #強制GTID的一致性,一般和上面參數一起使用,但是開啟后只允許能夠保障事務安全,并且能夠被日志記錄的SQL語句被執行, #像create?table?...?select?和?create?temporarytable語句,以及同時更新事務表和非事務表的SQL語句或事務都不允許執行。 enforce_gtid_consistency?=?1 #然后重啟mysql進程 service?mysqld?restart |
擴展一下,在gtid模式下,出現不支持的語句需要自己去修改,不然會報錯或不記錄,例如下面這樣.
1 2 3 4 | CREATE?TABLE?...?SELECT 可以改為下面這樣分成兩句: CREATE?TABLE INSERT?...?SELECT |
因為GTID模式要重啟才能生效,對于一些大庫要慎重更改使用gtid(重啟失敗那就悲劇了),一定要用的話,主庫要找個月黑風高,夜深人靜的時候設置完再重啟,從庫就沒所謂啦.
==========================================
然后我們還要關注一些參數,在從庫可以選擇性開啟,主庫加不加都不影響使用,
1 2 3 4 5 6 7 8 9 | #用來配置從服務器的更新是否寫入二進制日志,如果有層級從庫就必須開,沒有的話建議關閉,能有效提高性能 log_slave_updates #設置從庫SQL線程并行重放events(事務)的worker線程數量,默認值為0,最大值為1024.在5.6.x版本中設置這個參數大于0時, #則SQL線程充當worker線程的協調者,在多個worker線程之間分發基于庫級別的events,也就是庫級別并行復制, #5.7.x版本的并行復制可以設置基于組提交事務的并行復制,更加好用. slave_parallel_workers?=?8 #5.7新參數,指定并行復制方式,為了兼容5.6的模式,默認的并行復制方式是基于庫級別的,即默認值是:DATABASE, #我們要設置成5.7支持的基于組提交事務的并行復制方式,則需要設置成:LOGICAL_CLOCK,速度更快。 #slave_parallel_type?=?LOGICAL_CLOCK |
題外話,這個看需求來開啟,有個別從庫會再搭從庫來掛載,如果不開這個參數,那就做不了,如果沒有這種需求,不開也沒什么,反而增加性能.
配置修改完了,我還還需要在主庫授權一下主從復制用戶的權限,這里說的授權是指主庫對從庫授權讀寫binlog權限.
1 | mysql>grant?replication?slave?on?*.*?to? 'rep' @ '%' ?identified?by? 'password' ; |
因為我貪方便,直接用的root用戶,后面請見諒了.
?
mysqldump方式
因為mysql自帶,不需要再做些什么,比較方便易用,不過需要強調一下,數據量太大的話,mysqldump就略顯不足了,因為是邏輯備份和導入,導出導入時間耗費巨大,各位自己衡量.
第一步,數據的導出與導入和初始化從庫(以下操作,先在主庫操作,后在從庫操作)
導出和導入,如果庫太大,就會多花點時間,也正如我們開頭說的,先用的是mysqldump來,具體參數我就不多說了,有興趣就去查一下,直接看命令就好了.
首先,我們先從主庫備份個整庫備份:
1 | mysqldump?-uroot?-p123123?--opt?--default-character- set =utf8?--triggers?-R?--hex-blob?--single-transaction?--no-autocommit?--master-data=2?-A?>test2.sql |
就這樣,我們就得到全庫備份文件test2.sql,
對于有沒有必要做全庫備份的問題,要看實際情況,如果你是做MHA,PXC之類的集群,你必然要保持主從數據完全一致,不只是業務庫,系統庫也需要.如果你從庫一開始就不打算拿來用,那確實只操作業務庫就好了,還有其他什么忽略不需要復制到從庫的參數,這個按你需求實際情況來做,這里就不再細說了.
需要強調一下的是,為什么能做到在線建立和重做主從,就是因為這個參數,
--master-data=2
后面會詳細說說這個參數會有些什么特別的地方.
轉回正題,備份做完了,那就是要拷到從庫恢復了,怎么傳輸過去,這里就不細說了,什么scp,rsync,http,ftp什么的,你喜歡就好了,而我這里,用的是scp
1 | scp ?-o?StrictHostKeyChecking=no?root@10.0.2.6: /data/ttt/test2 .sql? /data/ttt |
命令僅供參考,你們自己喜歡怎么改都行
再然后,要初始化一下從庫的mysql。
雖然說現在是測試,不過一般來說,建立和重做主從,必然是因為他本來就是空白機,或者是主從失效了,需要重做,原因我不說了,反正類似pt-osc工具也沒用的,就是必須重做的架勢,至于怎么安裝mysql我就不多說了.
簡單說說怎么初始化,具體可以看我另一篇文章
1 2 3 4 5 6 7 | #這個只是5.6的初始化方式 service?mysqld?stop rm ?-rf? /data/mysql/data/ * /usr/local/mysql/scripts/mysql_install_db ?--defaults- file = /usr/local/mysql/my .cnf?--basedir= /usr/local/mysql/ ?--datadir= /data/mysql/data ?--user=mysql?>? /dev/null ?2>&1 service?mysqld?start /usr/local/mysql/bin/mysqladmin ?-u?root?password? '123123' #5.7的和這個不一樣,請看我另一篇文章 |
簡單幾個命令就完成了初始化,然后準備導入,為什么要說準備呢,當然是因為還有些準備工作,例如是如果要開GTID的話
1 2 3 4 5 6 7 8 9 10 11 12 13 | #使用GTID模式的實例的導入,需要目標實例的GTID記錄是空的,不然會報錯,就類似這樣: [root@pingtest1?ttt] #?mysql?-uroot?-p123123?<?test2.sql? Warning:?Using?a?password?on?the? command ?line?interface?can?be?insecure. ERROR?1840?(HY000)?at?line?24:?@@GLOBAL.GTID_PURGED?can?only?be? set ?when?@@GLOBAL.GTID_EXECUTED?is?empty. #提示GTID_EXECUTED為非空,不能導入. #所以導入前要先重置下binlog mysql>reset?master; #重置了binlog那就沒問題了,重新執行 mysql?-uroot?-p123123?-e? 'reset?master' mysql?-uroot?-p123123?<?test2.sql #好了,導入完成后,我們檢查一下,gtid模式要看看這個 mysql>show?variables?like? "%gtid%" ; gtid_purged????|????16fdabc7-30f9-11e6-9234-0800273e5680:1-3216 |
看到上面這個就行了.
?
第二步,配置主從同步(以下操作,都是在從庫操作)
在說怎么配置之前,我先說一下為什么能在線不停應用服務來做主從的原因,還記得我上面說的那個參數嗎?,沒錯,就是--master-data=2,意思是記錄備份當前的binlog信息.
有不少人以前做主從,都是從主庫show master status查看binlog位置,然后change master to.....所以必須把應用服務停了,不然binlog位置變了后,在做主從期間中間那些語句就執行不了,最終導致數據不同步.
而加了--master-data=2之后,test2.sql這個文件會記錄當前binlog的位置,這樣我們就不用理會做主從期間中間的那些數據,只需要把binlog位置直接指向sql文件里面的binlog位置就可以了,然后數據就會自己同步到最新位置.
來看看我的test2.sql的binlog位置,就文件的前30行,要是你覺得文件太大很難打開,more或者head -30都可以,就不要vim了,只看關鍵字
1 2 3 4 5 | SET?@@GLOBAL.GTID_PURGED= '16fdabc7-30f9-11e6-9234-0800273e5680:1-3216' ; -- --?Position?to?start?replication?or?point- in - time ?recovery?from -- --?CHANGE?MASTER?TO?MASTER_LOG_FILE= 'mysql-bin.000019' ,?MASTER_LOG_POS=1856541; |
看到了,當前binlog位置是mysql-bin.000019,Position位置是1856541,gtid位置是16fdabc7-30f9-11e6-9234-0800273e5680:1-3216.
知道了這些信息,那么我們就可以開干了
一般模式直接change master to就可以了,主要就是mysql-bin.000019和Position位置是1856541,用來告訴主庫,我這些語句執行過了,不需要理會GTID的東西(其實主庫沒開GTID就不會存在這個數據)
1 2 3 4 5 6 7 8 9 10 | #做之前,別忘記先清空一下主從結構的記錄 mysql>reset?slave?all; #然后再執行操作 mysql>change?master?to master_host= '10.0.2.6' , master_user= 'repl' , master_password= '*****' , master_port=3306, master_log_file= 'mysql-bin.000019' , master_log_pos=1856541; |
====================================
GTID模式下,則還需要多做一步,就是執行那個語句,設置gtid編號,用來告訴主庫,我這些語句執行過了,
1 | mysql>SET?@@GLOBAL.GTID_PURGED= '16fdabc7-30f9-11e6-9234-0800273e5680:1-3216' ; |
就是跳過之前已經復制過的事務,因為GTID記錄的事務是從1開始的,只會增加或變更UUID,不會重置計數器,所以就要手動設置跳過之前執行過(已經在備份里的結果)的事務.然后change master to一下,
1 2 3 4 5 6 7 8 9 | #做之前,別忘記先清空一下主從結構的記錄 mysql>reset?slave?all; #然后再執行操作 mysql>change?master?to master_host= '10.0.2.6' , master_user= 'root' , master_password= '123123' , master_port=3306, MASTER_AUTO_POSITION?=?1; |
在這一步GTID簡單很多,這也是為什么越來越多人用的原因,已經不用理會pos跑到哪里,他會自己去找.
要注意的是,主庫開了GTID復制模式,從庫就用不了舊的模式來做復制了,會提示報錯,所以從庫必須也使用GTID模式來做從庫才可以.
======================================
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 然后啟動從庫復制 mysql>start?slave; 最后檢查一下 mysql>show?slave?status\G ?????????? Master_Log_File:?mysql-bin.000019 ?????????? Read_Master_Log_Pos:?4980238 ??????????????? Relay_Log_File:?pingtest1-relay-bin.000002 ???????????????? Relay_Log_Pos:?3124105 ???????? Relay_Master_Log_File:?mysql-bin.000019 ????????????? Slave_IO_Running:?Yes ???????????? Slave_SQL_Running:?Yes ???????????????????? . ???????????????????? . ???????????????????? . ?????????? Exec_Master_Log_Pos:?4980238 ???????????????????? . ???????????????????? . ???????????????????? . ???????? Retrieved_Gtid_Set:?16fdabc7-30f9-11e6-9234-0800273e5680:3217-4885 ???????????? Executed_Gtid_Set:?16fdabc7-30f9-11e6-9234-0800273e5680:1-4885 |
如何證明主從復制正常了呢?主要看下面這些值:
Slave_IO_Running和Slave_SQL_Running的雙yes:????證明io線程和sql線程都正常,如果不是雙yes,這個主從復制架構就是失敗的,不能使用。
Master_Log_File=Relay_Master_Log_File:???? 證明從庫執行的binlog文件和主庫的是一致的,不一致就是不同步了,有一定延時,但還可以用,關鍵看你能不能接受這個延時(跨binlog文件一般算比較大的延時了)。
Read_Master_Log_Pos=Exec_Master_Log_Pos:????證明從庫執行binlog的pos位置是和主庫一致的,如果是操作太頻繁的庫,有一些不一致是正常的,如果太大,就代表數據有延時,但不影響從庫使用。
Seconds_Behind_Master:????表示slave上SQL thread與IO thread之間的延遲,也就是看到還有多少數據還沒寫進去。在MySQL的復制環境中,slave先從master上將binlog拉取到本地(通過IO thread),然后通過SQL thread將binlog重放,而Seconds_Behind_Master表示本地relaylog中未被執行完的那部分的差值。
因為我數據比較少,很容易就追上了,看不到差異,但是可以很肯定和你們說,我主庫沒停過應用服務,然后從庫就做好了。
再看看主庫上面的線程如何 1 2 | mysql>show?processlist; 9172?|?root??|?10.0.2.5:57506??|?NULL?|?Binlog?Dump?GTID?|???75?|?Master?has?sent?all?binlog?to?slave;?waiting? for ?binlog?to?be?updated |
線程也在,可以確定整套復制都正常了.
?
xtrabackup方式
也正如我開頭說的,某些庫很大,幾十G幾百G什么的也不用很意外,如果還用mysqldump就不科學了,導出導入耗費時間巨大,這個時候就必須靠xtrabackup這種物理拷貝的備份還原工具,加快速度進行,另一方面來說,從備份原理得出的結果來看,mysqldump備份得到的結果是備份開始時間的數據結果,而xtrabackup備份得到的結果是備份結束時間的數據結果,是屬于比較新的數據,對于操作頻繁的庫用xtrabackup來做也是優勢明顯.
第一步目的和上面一致,只是用了軟件,而用xtrabackup恢復不需要初始化mysql(以下操作,先在主庫操作,后在從庫操作)
至于怎么安裝xtrabackup就不多說了,各位可以看我另一篇文章,介紹怎么安裝xtrabackup和介紹怎么使用xtrabackup,命令我就簡單貼出來,然后說一下用途就算了.
先在主庫備份全庫(想只備份特定庫的還請自己想辦法,這里就不延伸了)
1 | innobackupex?--defaults- file = "/usr/local/mysql/my.cnf" ??--user=root?--password= '123123' ?--stream= tar ??"/data/ttt" ?2>? /data/ttt/backup .log?|? gzip ?>? /data/ttt/test2 .tgz |
意思就是把/usr/local/mysql/my.cnf配置文件里標明的全庫拷貝出來,并通過gzip壓縮成一個文件.
拷貝到從庫機器
1 | scp ??-o?StrictHostKeyChecking=no?root@10.0.2.6: /data/ttt/test2 .tgz?./ |
然后在從庫服務器操作,拷貝到一個文件夾解壓
1 2 3 4 | mkdir ?test2back mv ?test2.tgz?test2back/ cd ?test2back/ tar ?xf?test2.tgz |
在從庫開始恢復備份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #關閉mysql服務 /etc/init .d /mysqld ?stop #先刪了舊的數據文件 rm ?-rf? /data/mysql/data/ * #然后先apply-log innobackupex?--defaults- file = '/usr/local/mysql/my.cnf' ?--apply-log? /data/ttt/test2back/ #然后開始恢復 innobackupex?--defaults- file = '/usr/local/mysql/my.cnf' ?--copy-back? /data/ttt/test2back/ #恢復完成后看一下,做完收尾工作 ll? /data/mysql/data chown ?-R?mysql.mysql?data/ #啟動mysql服務 /etc/init .d /mysqld ?start #嘗試登陸一下,ok就完成了 mysql?-uroot?-p123123 |
相對來說,速度快了一些,操作也還是簡單一些,就是多安裝了一個軟件.
?
第二步,配置主從同步(以下操作,都是在從庫操作)
實際上和上面用mysqldump的思維是一樣,因為xtrabackup備份完成時會生成一個文件xtrabackup_binlog_info,里面就記錄了binlog位置和GTID值,故而也能做到不停應用服務來做主從,而且用xtrabackup數據還比較新.
我們來打開這個文件看一下
1 2 | vim?xtrabackup_binlog_info mysql-bin.000020????????8454162?16fdabc7-30f9-11e6-9234-0800273e5680:1-22037 |
非常直觀,就這三個值,如果你還有興趣留意,其實xtrabackup_info也有記錄,不過兩者還是有一些差異.
大多數時候用xtrabackup_binlog_info就可以了,但是特殊情況下用xtrabackup_binlog_pos_innodb會好一些,因為xtrabackup_binlog_info中記錄的位置包含非innodb引擎的數據變化位置,但是對于innodb引擎,redo log里邊本身是包含了binlog pos的,如果你apply log,那么事務的前滾,回滾可能造成這個位置有變動,如果你是做主備復制,復制搭建之后,同步的數據包含非innodb表,那這個xtrabackup_binlog_pos_innodb中的位置就不可靠,反之如果你的同步不涉及到非innodb表,那么可以使用它。
也正如我上面第二步說的,備份恢復完之后,這個從庫就可以用了,設置的方法也和上面mysqldump沒差別,如果是非GTID的話,直接change master to 就可以用了,
1 2 3 4 5 6 7 8 9 10 | #做之前,別忘記先清空一下主從結構的記錄 mysql>reset?slave?all; #然后再執行操作 mysql>change?master?to master_host= '10.0.2.6' , master_user= 'repl' , master_password= '*****' , master_port=3306, master_log_file= 'mysql-bin.000020' , master_log_pos=8454162; |
==========================================
如果是GTID模式的話,那就先set一下,跳過之前已經執行過的事務
1 | mysql>SET?@@GLOBAL.GTID_PURGED= '16fdabc7-30f9-11e6-9234-0800273e5680:1-22037' ; |
然后看一下狀態
1 2 | mysql>?show?variables?like? '%gtid%' ; gtid_purged?????????????????????|?16fdabc7-30f9-11e6-9234-0800273e5680:1-22037?| |
再執行change master to 來完成
1 2 3 4 5 6 7 8 9 | #做之前,別忘記先清空一下主從結構的記錄 mysql>reset?slave?all; #然后再執行操作 mysql>change?master?to master_host= '10.0.2.6' , master_user= 'root' , master_password= '123123' , master_port=3306, MASTER_AUTO_POSITION?=?1; |
==========================================
然后啟動從庫復制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | mysql>start?slave; 最后檢查一下 mysql>show?slave?status\G ?????????? Master_Log_File:?mysql-bin.000020 ?????????? Read_Master_Log_Pos:?4980238 ??????????????? Relay_Log_File:?pingtest1-relay-bin.000002 ???????????????? Relay_Log_Pos:?17522575 ???????? Relay_Master_Log_File:?mysql-bin.000020 ????????????? Slave_IO_Running:?Yes ???????????? Slave_SQL_Running:?Yes ???????????????????? . ???????????????????? . ???????????????????? . ?????????? Exec_Master_Log_Pos:?17522575 ???????????????????? . ???????????????????? . ???????????????????? . ???????? Retrieved_Gtid_Set:?16fdabc7-30f9-11e6-9234-0800273e5680:22038-26950 ???????????? Executed_Gtid_Set:?16fdabc7-30f9-11e6-9234-0800273e5680:1-26950 |
如何證明主從復制正常了呢?主要看下面這些值:
Slave_IO_Running和Slave_SQL_Running的雙yes:????證明io線程和sql線程都正常,如果不是雙yes,這個主從復制架構就是失敗的,不能使用。
Master_Log_File=Relay_Master_Log_File:???? 證明從庫執行的binlog文件和主庫的是一致的,不一致就是不同步了,有一定延時,但還可以用,關鍵看你能不能接受這個延時(跨binlog文件一般算比較大的延時了)。
Read_Master_Log_Pos=Exec_Master_Log_Pos:????證明從庫執行binlog的pos位置是和主庫一致的,如果是操作太頻繁的庫,有一些不一致是正常的,如果太大,就代表數據有延時,但不影響從庫使用。
Seconds_Behind_Master:????表示slave上SQL thread與IO thread之間的延遲,也就是看到還有多少數據還沒寫進去。在MySQL的復制環境中,slave先從master上將binlog拉取到本地(通過IO thread),然后通過SQL thread將binlog重放,而Seconds_Behind_Master表示本地relaylog中未被執行完的那部分的差值。
還是太快,看不到差異,不過可以肯定復制是完成了,主從架構完成,主庫依然沒有停過.
再看看主庫上面的線程如何
1 2 | mysql>show?processlist; 32718?|?root??|?10.0.2.5:54224??|?NULL?|?Binlog?Dump?GTID?|???162?|?Master?has?sent?all?binlog?to?slave;?waiting? for ?binlog?to?be?updated |
線程也在,可以確定整套復制都正常了.
?
擴展閱讀:
說起了主從復制延時,就不得不強調,一般的主從復制,是屬于異步復制的,即主庫不需要理會從庫是否執行,或者知否追得上復制的速度,只管自己跑,如果有漏了什么也是不管的,這也是我們常說的主從不一致的根本原因。
為了解決這個問題,就有了半同步復制,和完全同步復制的概念。
半同步的意思是一個事務在主庫執行完還不行,必須在至少一個從庫成功寫入數據,事務才算真正提交成功,而其他還沒寫入的從庫則執行異步操作,后續再寫入。這時主庫不能再把從庫狀態棄之不顧,必須知道至少一個從庫寫入成功才能完成,減少復制失敗的事情,但風險還有一些,因為還有一些異步復制的從庫。
完全同步就更加嚴格,要所有從庫返回寫入成功,這個事務才能算提交成功,嚴格來說,只有一臺從庫的半同步架構,也和完全同步的概念相等。
實現半同步的方式很簡單,mysql有自帶半同步插件,只是一般沒有使用,我的另一篇文章有說明,配置起來也不難。
實現完全同步方式則大多數是靠集群軟件實現,例如很出名的PXC集群軟件,必須所有主從都要寫入成功,事務才算提交完成。
但是論性能,半同步和完全同步,必然會比異步降低得很明顯,數據一致性要求和系統性能,永遠都是背道而馳。
問題匯總:
????有些朋友做的從庫,可能有一種情況,就是除同步賬戶外,本身并不知道主庫的其他用戶密碼,這就造成一種尷尬的情況,如果需要管理從庫的時候,就顯得很不方便,所以逼著要去破解從庫的密碼.
????還有另一種情況,就是主庫和從庫版本不一致,數據表結構可能會有一些版本造成的差異,如果主庫這些表有更改,就會在從庫報錯,算是一個隱性坑,所以我們最好忽略這些表或庫的同步語句.
?1. ? 先來看怎么破解密碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #先關閉mysql service?mysqld?stop #進入安全模式 /usr/local/mysql/bin/mysqld_safe ?--skip-grant-tables?--skip-networking& #此時就免密碼登陸了 /usr/local/mysql/bin/mysql ?-uroot #更改密碼,密碼和用戶可選, #這是5.6及之前的方式 update?mysql.user? set ?password=PASSWORD( '新密碼' )?where?user= 'root' ?and?host= 'root' ?or?host= 'localhost' or?host= 'localhost.localdomain' or?host= '127.0.0.1' ; #5.7之后要用新的字段 update?mysql.user? set ?authentication_string=password( '新密碼' )?where?user= 'root' #刷新策略 flush?privileges; #重啟mysql /etc/init .d /mysqld ?restart #正常登陸 /usr/local/mysql/bin/mysql ?-uroot??-p '新密碼' #如果有需要就升級下版本,例如5.6主庫,5.7主庫這種情況 mysql_upgrade?--defaults- file = /usr/local/mysql/my .cnf?-uroot?-p '新密碼' ?-h127.0.0.1 #測試功能是否正常 mysql>?show?databases; |
2. ?? 然后是第二種情況,忽略某些表和庫的同步,忽略同步的方式可以在主庫做,也可以在從庫做,不過從一些解析起來很麻煩的坑來說(這里就不說太多了),在從庫做是最好的.
1 2 3 4 5 6 7 8 9 10 11 12 | #在5.6版本之前需要在配置文件my.cnf操作,當然是要重啟才生效 vim? /usr/local/mysql/my .cnf #只執行某個庫或某個表的同步語句 replicate_wild_do_table= test .%,mysql.user #忽略掉某個庫或某個表的同步語句 replicate_wild_ignore_table=mysql.%, test .fucking #在5.7之后的版本,新加入了一個動態修改的命令,不用重啟了 #這次不用理會配置文件了,當然后面加一下我覺得還是有必要,避免重啟后還原的報錯 #只執行某個庫或某個表的同步語句 mysql?>?change?replication?filter?replicate_wild_do_table=( '' test .% ',' 'mysql.user' ); #忽略掉某個庫或某個表的同步語句 mysql?>?change?replication?filter?replicate_wild_ignore_table=( '' test .% ',' 'mysql.user' ); |
??? 提醒下,忽略同步的庫和表要走心,考慮多一些情況.
3. 在停止多元復制環境時要注意并行復制的進度,例如出現下面這種情況,就先等一等再停止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #請關注Executed_Gtid_Set:項 show?slave?status\G ???? . ???? . ???? . ????????????? Master_Server_Id:?2721321239 ?????????????????? Master_UUID:?4cdc2a74-6299-11e6-95ce-008cfaf595bc ????????????? Master_Info_File:?mysql.slave_master_info ???????????????????? SQL_Delay:?0 ?????????? SQL_Remaining_Delay:?NULL ?????? Slave_SQL_Running_State:?Reading?event?from?the?relay?log ??????????? Master_Retry_Count:?86400 ?????????????????? Master_Bind:? ?????? Last_IO_Error_Timestamp:? ????? Last_SQL_Error_Timestamp:? ??????????????? Master_SSL_Crl:? ??????????? Master_SSL_Crlpath:? ??????????? Retrieved_Gtid_Set:?4cdc2a74-6299-11e6-95ce-008cfaf595bc:50007036-50049107 ???????????? Executed_Gtid_Set:?09cb91bf-2669-11e7-8b70-00163e0835ff:1-47551250, 3edae34c-6299-11e6-95cd-8038bc0c67be:1-6758, 4cdc2a74-6299-11e6-95ce-008cfaf595bc:1-50010063:50010080-50010093:50010099-50010101:50010108:50010130-50010139:50010145-50010148:50010158:50010179-50010184:50010190-50010200:50010207:50010215-50010221:50010227-50010236:50010243:50010276-50010285:50010291-50010293:50010300:50010308-50010312:50010326-50010328:50010371-50010373:50010391-50010393:50010403-50010405:50010427-50010429:50010464-50010466:50010480-50010482:50010490-50010496:50010518-50010520:50010538-50010540:50010551-50010553:50010574 ???????????????? Auto_Position:?1 ????????? Replicate_Rewrite_DB:? ????????????????? Channel_Name:?al_rds ??????????? Master_TLS_Version:? ***************************?2.?row?*************************** ??????????????? Slave_IO_State:?Waiting? for ?master?to?send?event ???? . ???? . ???? . |
那是因為你這么一停止,并行復制就中途停止了,就有可能出現有些數據回滾不了,或者有些數據復制錯誤,然后后續你還想把他起來就很大可能會報錯了,所以寧愿先等一等,再停止。
當然了,如果是線上環境,究竟要等到什么時候?所以最好就是數據庫不繁忙的時候再做。要么,你就是準備好重做的心態了,那就來吧。