MySQL主從複製與讀寫分離
搭建mysql的master-slave環境
一.mysql主從備份(複製)的基本原理
mysql支援單向、非同步複製,複製過程中一個伺服器充當主伺服器,而一個或多個其它伺服器充當從伺服器。mysql複製基於主伺服器在二進位制日誌中跟蹤所有對資料庫的更改(更新、刪除等等)。因此,要進行復制,必須在主伺服器上啟用二進位制日誌。每個從伺服器從主伺服器接收主伺服器已經記錄到其二進位制日誌的儲存的更新。當一個從伺服器連線主伺服器時,它通知主伺服器從伺服器在日誌中讀取的最後一次成功更新的位置。從伺服器接收從那時起發生的任何更新,並在本機上執行相同的更新。然後封鎖並等待主伺服器通知新的更新。從伺服器執行備份不會干擾主伺服器,在備份過程中主伺服器可以繼續處理更新。
二. 主從備份的實現細節
mysql使用3個執行緒來執行復制功能(其中1個在主伺服器上,另兩個在從伺服器上)。當發出start slave時,從伺服器建立一個I/O執行緒,以連線主伺服器並讓它傳送記錄在其二進位制日誌中的語句。主伺服器建立一個執行緒將二進位制日誌中的內容傳送到從伺服器。該執行緒可以即為主伺服器上show processlist輸出中的Binlog Dump執行緒。從伺服器I/O執行緒讀取主伺服器Binlog Dump執行緒傳送的內容並將該資料拷貝到從伺服器資料目錄中的本地檔案中,即中繼日誌。第3個執行緒是sql執行緒,由從伺服器建立,用於讀取中繼日誌並執行日誌中包含的更新。
三.配置
在進行mysql主從備份時,最好確保主從伺服器的版本相容。從伺服器至少與主伺服器版本相同或更高。
主資料庫伺服器ip:10.80.3.87
從資料庫伺服器ip:10.80.3.86
主機(master)配置:
1.修改mysql配置檔案my.cnf
在[mysqld]標籤下新增以下幾行
log-bin=mysql-bin #開啟二進位制日誌
server-id=1 #主伺服器id號,自定義
#binlog-do-db=db_nameA #指定對db_nameA記錄二進位制日誌
#binlog-ignore-db=db_namB #指定不對db_namB記錄二進位制日誌
#expire_logs_days=2 # 自動清理 2 天前的log檔案,可根據需要修改
注意:
log-bin,server-id是配置檔案中必須新增的內容。此時主伺服器預設對所有資料庫進行備份。如果需要特殊指明只對某個資料庫進行備份或不備份,則可以加入binlog-do-db和binlog-ignore-db選項
2.為從伺服器新增複製賬戶並配置許可權
在Master MySQL上建立一個使用者‘repl’,並允許其他Slave伺服器可以通過遠端訪問Master,通過該使用者讀取二進位制日誌,實現資料同步。
mysql>create user repl;
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.80.5.%' IDENTIFIED BY 'mysql';
從機(slave)配置:
修改mysql配置檔案my.cnf
在[mysqld]標籤下新增:
server-id=2
#log-bin=mysql-bin
#master-connect-retry=60 # 連結重連間隔(單位s)
replicate-ignore-db=mysql # 不從主機同步的資料庫(多個寫多行)
#replicate-do-db=db1 # 要從主機同步的庫(多個寫多行)
#replicate-do-db=db2 # 要從主機同步的庫(多個寫多行)
#log-slave-update # 啟用從機伺服器上的slave日誌功能,使這臺計算機可以用來構成一個映象鏈(A->B->C)
slave-skip-errors # 跳過錯誤,從機一般應該配置該項
主從配置檔案修改完成,重啟MySQL
登入主伺服器MySQL,檢視master狀態:
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 535 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
登入從伺服器MySQL,檢視slave狀態:
mysql> change master to
master_host = '10.80.3.87',
master_user = 'repl',
master_password = 'mysql',
master_log_file = 'mysql-bin.000003',
master_log_pos = 0 ; # 0代表日誌開始位置
mysql> start slave #啟動slave
mysql> show slave status\G
注:Slave_IO及Slave_SQL程序必須正常執行,即YES狀態,否則都是錯誤的狀態(如:其中一個NO均屬錯誤)
至此,主從伺服器配置完成。
四.測試
主伺服器Mysql中,建立資料庫,並在這個庫中建表插入一條資料,隨後在從伺服器MySQL中可以查到同樣的資料。
######################################################################
搭建database proxy
amoeba代理伺服器ip:10.80.3.80
基於 Amoeba 實現mysql資料庫讀寫分離的配置
簡要原理圖
Amoeba是java編寫的,執行需要JDK環境,下載jdk1.6 http://www.oracle.com/technetwork/java/javase/downloads/java-se-6u24-download-338091.html
chmod +x jdk-6u24-linux-x64.bin
./jdk-6u24-linux-x64.bin
cd jdk1.6.0_24/
mkdir /usr/local/jdk
cp -rf * /usr/local/jdk/
vim /etc/profile.d/java.sh 新增一下內容
JAVA_HOME="/usr/local/jdk"
CLASS_PATH="$JAVA_HOME/lib:$JAVA_HOME/jre/lib"
PATH=".:$PATH:$JAVA_HOME/bin"
export JAVA_HOME
儲存退出
source /etc/profile.d/java.sh
java -version 檢視版本
amoeba下載地址: https://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/3.x/ 最新版本為amoeba-mysql-3.0.5-RC
unzip amoeba-mysql-3.0.5-RC-distribution.zip -d /usr/local/
cd /usr/local
mv amoeba-mysql-3.0.5-RC-distribution amoeba
cd amoeba/conf
實現讀寫分離只需配置amoeba.xml,dbServers.xml
啟動amoeba
launcher
mysql -uroot -p -h127.0.0.1 -P8066
出現紅框資訊說明通過中間代理登入到MySQL
測試讀寫分離(node1:master node2:slave)
在node3上操作
use mydb
create table stu(name varchar(10),age int);
select * from stu;
insert into stu values('bill',35);
同時檢視node1,node2上MySQL的操作日誌,如未開啟日誌功能需開啟
show global variables like 'general_log';
set global general_log=1;
show global variables like 'general_log';
tail -f /var/run/mysqld/mysqld.log
node1:
node2:
可以看到寫操作insert發生在master上,slave同步執行了這條語句
讀操作select僅在slave上發生
通過以上驗證得知簡單的master-slave讀寫分離得以生效
常用命令:
show binlog events;檢視二進位制日誌事件
reset master;刪除所有二進位制日誌檔案並清空所有二進位制日誌索引檔案
reset slave;刪除slave複製所用的所有檔案