mysql主從配置
MySql主從配置
根據業務備份需要,進行MySql主從配置,主伺服器提供服務,從伺服器作為備份使用,或者做讀寫分離。如果主伺服器出現問題可以進行切換,資料是一樣的。
一、Mysql主從的原理:
Mysql的Replication是一個非同步的複製過程,從一個Mater複製到另一個Slave。在Master與Slave之間的實現 整個複製過程主要由三個執行緒來完成,其中兩個執行緒(Sql執行緒和IO執行緒)在Slave端,另外一個執行緒(IO執行緒)在Master端。
要實現MySQL的Replication,首先必須開啟Master端的BinaryLog(mysql-bin.xxxxxx)功 能,否則無法實現。因為整個複製過程實際上就是Slave從Master端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。打 開MySQL的BinaryLog可以通過在啟動MySQLServer的過程中使用“—log-bin”引數選項,或者 在my.cnf配置檔案中的mysqld引數組([mysqld]標識後的引數部分)增加“log-bin”引數項。
MySQL複製的基本過程如下:
1.Slave上面的IO執行緒連線上Master,並請求從指定日誌檔案的指定位置(或者從最開始的日誌)之後的日誌內容;
2.Master接收到來自Slave的IO執行緒的請求後,通過負責複製的IO執行緒根據請求資訊讀取指定日誌指定位置之後的日誌資訊,返 回給Slave端的IO執行緒。返回資訊中除了日誌所包含的資訊之外,還包括本次返回的資訊在Master端的BinaryLog檔案的 名稱以及在BinaryLog中的位置;
3.Slave的IO執行緒接收到資訊後,將接收到的日誌內容依次寫入到Slave端的RelayLog檔案(mysql-relay- bin.xxxxxx)的最末端,並將讀取到的Master端的bin-log的檔名和位置記錄到master-info檔案中,以便在下一次讀取的 時候能夠清楚的高速Master從某個bin-log的哪個位置開始往後的日誌內容”
4.Slave的SQL執行緒檢測到RelayLog中新增加了內容後,會馬上解析該Log檔案中的內容成為在Master端真實執 行時候的那些可執行的Query語句,並在自身執行這些Query。這樣,實際上就是在Master端和Slave端執行了同樣 的Query,所以兩端的資料是完全一樣的。
實際上,在老版本中,MySQL的複製實現在Slave端並不是由SQL執行緒和IO執行緒這兩個執行緒共同協作而完成的,而是由單獨的一個執行緒來完成所有的工作。但是MySQL的工程師們很快發現,這樣做存在很大的風險和效能問題,主要如下:
首先,如果通過一個單一的執行緒來獨立實現這個工作的話,就使複製Master端的,BinaryLog日誌,以及解析這些日誌,然後再在自身執行的 這個過程成為一個序列的過程,效能自然會受到較大的限制,這種架構下的Replication的延遲自然就比較長了。
其次,Slave端的這個複製執行緒從Master端獲取BinaryLog過來之後,需要接著解析這些內容,還原成Master端所執行 的原始Query,然後在自身執行。在這個過程中,Master端很可能又已經產生了大量的變化並生成了大量的BinaryLog資訊。如果在這 個階段Master端的儲存系統出現了無法修復的故障,那麼在這個階段所產生的所有變更都將永遠的丟失,無法再找回來。這種潛在風險在Slave端 壓力比較大的時候尤其突出,因為如果Slave壓力比較大,解析日誌以及應用這些日誌所花費的時間自然就會更長一些,可能丟失的資料也就會更多。
所以,在後期的改造中,新版本的MySQL為了儘量減小這個風險,並提高複製的效能,將Slave端的複製改為兩個執行緒來完成,也就是前面所提到 的SQL執行緒和IO執行緒。最早提出這個改進方案的是Yahoo!的一位工程師“JeremyZawodny”。通過這樣的改造,這樣既在很大程 度上解決了效能問題,縮短了非同步的延時時間,同時也減少了潛在的資料丟失量。
當然,即使是換成了現在這樣兩個執行緒來協作處理之後,同樣也還是存在Slave資料延時以及資料丟失的可能性的,畢竟這個複製是非同步的。只要資料的更改不是在一個事務中,這些問題都是存在的。
如 果要完全避免這些問題,就只能用MySQL的Cluster來解決了。不過MySQL的Cluster知道筆者寫這部分內容的時候,仍然還 是一個記憶體資料庫的解決方案,也就是需要將所有資料包括索引全部都Load到記憶體中,這樣就對記憶體的要求就非常大的大,對於一般的大眾化應用來說可 實施性並不是太大。當然,在之前與MySQL的CTODavid交流的時候得知,MySQL現在正在不斷改進其Cluster的實現,其 中非常大的一個改動就是允許資料不用全部Load到記憶體中,而僅僅只是索引全部Load到記憶體中,我想信在完成該項改造之後 的MySQLCluster將會更加受人歡迎,可實施性也會更大。
簡單來說整個過程是:
要想實現AB複製,那麼前提是master上必須要開啟二進位制日誌
1)首先master將資料更新記錄到二進位制日誌檔案
2)從slavestart開始,slave通過I/O執行緒向master索要二進位制日誌檔案,slave是知道要從哪個位置點開始要
3)master接收到slave的io請求之後,就會從相應的位置點開始,給slave傳日誌
4)slave接收到日誌後,vi會寫入本地的中繼日誌中
5)slave通過sql執行緒讀取中繼日誌的內容,在資料庫中執行相應的操作,到此為止,master和slave上的資料一致,之後slave伺服器進入等待狀態,等待master的後續更新
原理圖:
二、主從伺服器上的執行緒:
1)從伺服器上的執行緒
I/O執行緒:負責從主伺服器索要二進位制日誌,並將其存入從伺服器的中繼日誌中
SQL執行緒:負責讀取從伺服器上的中繼日誌,並對資料庫執行相應的操作
2)主伺服器上的執行緒
binlogdump執行緒:負責傳送二進位制日誌
三、搭建過程:
Master端:
①開啟二進位制日誌:
vi/etc/my.cnf
[mysqld]
log-bin=mysql-bin
skip-name-resolve
server-id=1//保證主從不一樣
②重啟mysql服務:
/etc/init.d/mysqldrestart
③授權備份使用者
mysql>grantreplicationslave,reload,superon*.*to[email protected]identifiedby'backup';
//此處的IP為從伺服器的IP,使用者名稱salve密碼backup
④做全庫備份:
mysql>flushtableswithreadlock;
//給所有的表加上讀鎖,為了保證資料的一致性
#mysqldump-uroot-p--all-databases>/tmp/all.sql
mysql>showmasterstatus;
+------------------+----------+--------------+------------------+
|File|Position|Binlog_Do_DB|Binlog_Ignore_DB|
+------------------+----------+--------------+------------------+
|mysql-bin.000002|1306|||
+------------------+----------+--------------+------------------+
1rowinset(0.00sec)
//這裡定義到二進位制日誌名和偏移量(當前日誌的位置)
mysql>unlocktables;
Slave端:
①開啟中繼日誌:
vi/etc/my.cnf
relay_log=mysql-relay//開啟中繼日誌
relay_log_index=mysql-relay.index//中繼日誌的索引檔案
server-id=2//保證跟主服務不一致,原有的將1修改為2
②重啟服務:
/etc/init.d/mysqldrestart
③匯入資料:
scp192.168.1.1:/tmp/all.sql/tmp
source/root/.bash_profile
mysql-uroot-p</tmp/all.sql
####################################################################
#或者直接打包資料,這樣能夠節約時間,線上可能用到#
#cp-R/data/app/mysql/data/tmp#
#這時就可以執行下面的讀取日誌點的操作,然後解鎖,然後在往下執行#
#tarcxvf/tmp/all.tar.gz/tmp/data#
##
####################################################################
④開啟主從同步
mysql>changemastertomaster_host="192.168.1.1",master_port=3306,master_user="slave",master_password="backup",master_log_file="mysql-bin.000002",master_log_pos=1306;
mysql>slavestart;//開啟從伺服器
mysql>showslavestatus\G確保這兩行是Yes
Slave_IO_Running:Yes
Slave_SQL_Running:Yes
刪除備份sql
#rm-rf/tmp/all.sql
驗證:
①master上檢視slave的狀態:
mysql>showslavehosts;
+-----------+------+------+-----------+
|Server_id|Host|Port|Master_id|
+-----------+------+------+-----------+
|3||3306|1|
|2||3306|1|
+-----------+------+------+-----------+
2rowsinset(0.00sec)
②master上新增資料檢視從庫是否及時更新
③檢視從庫的錯誤日誌情況
tail-0f/data/app/mysql/data/mysql_error.log
如果該日誌中出現大量的:
15122414:09:40[Note]Slave:receivedendpacketfromserver,apparentmastershutdown:
15122414:09:40[Note]SlaveI/Othread:Failedreadinglogevent,reconnectingtoretry,log'mysql-bin.000034'atposition3621049
15122414:09:40[Note]Slave:receivedendpacketfromserver,apparentmastershutdown:
15122414:09:40[Note]SlaveI/Othread:Failedreadinglogevent,reconnectingtoretry,log'mysql-bin.000034'atposition3621049
15122414:09:40[Note]Slave:receivedendpacketfromserver,apparentmastershutdown:
15122414:09:40[Note]SlaveI/Othread:Failedreadinglogevent,reconnectingtoretry,log'mysql-bin.000034'atposition3621049
15122414:09:40[Note]Slave:receivedendpacketfromserver,apparentmastershutdown:
15122414:09:40[Note]SlaveI/Othread:Failedreadinglogevent,reconnectingtoretry,log'mysql-bin.000034'atposition3621049
原因是server-id出現重複,應該考慮到master的ID和其他的salve的ID
-------------------------------------------------
問題:
1、如果change語句有問題
mysql>slavestop;
再重新執行change那一句。
2、ab複製配置失效
刪除master.info檔案
刪除relay-log.info
服務重啟
重新操作
-------------------------------------------------
出現的問題:
1、change語句裡面多空格或錯誤
2、同步資料的賬號無法連線主伺服器
1)賬號密碼錯誤
2)少了skip-name-resolve這一行,不能遠端登入
-----------------------------------------------------
轉載於:https://blog.51cto.com/dengaosky/1854002