您好,登錄后才能下訂單哦!
本篇文章為大家展示了MySQL MHA集群方案是怎樣的,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
MySQL MHA集群方案調研
MHA是由日本Mysql專家用Perl寫的一套Mysql故障切換方案以保障數據庫的高可用性,它的功能是能在0-30s之內實現主Mysql故障轉移(failover),
MHA故障轉移可以很好的幫我們解決從庫數據的一致性問題,同時最大化挽回故障發生后的數據。MHA里有兩個角色一個是node節點 一個是manager節點,要實現這個MHA,必須最少要三臺數據庫服務器,一主多備,即一臺充當master,一臺充當master的備份機,另外一臺是從屬機。
官方資料網站:
https://code.google.com/p/mysql-master-ha/w/list
https://code.google.com/p/mysql-master-ha/wiki/Tutorial
在基于MySQL復制的MHA集群架構中,當Master發生故障時,MHA 通過如下步驟來保證數據的一致性:
(1) 找出同步最成功的一臺從服務器(也就是與主服務器數據最接近的那臺從服務器)。
(2) 如果主機還能夠訪問,從主服務器上找回最新從機與主機間的數據差異。
(3) 在每一臺從服務器上操作,確定他們缺少哪些events,并分別進行補充。
(4) 將最新的一臺從服務器提升為主服務器后。
(5) 將其它從服務器重新指向新的主服務器。
雖然MHA試圖從宕機的主服務器上保存二進制日志,但并不是總是可行的。例如,如果主服務器硬件故障或無法通過ssh訪問,MHA沒法保存二進制日志,只進行故障轉移而丟失最新數據。
結合半同步復制,可以大大降低數據丟失的風險。MHA可以與半同步復制結合起來,如果只有一個slave已經收到了最新的二進制日志,MHA可以將最新的二進制日志應用于其他所有的slave服務器上,因此他們彼此保持一致性。
1.3.2 MHA組內架構圖
復制組內使用Keepalived + LVS :
在當前已存在的主從復制環境中,MHA可以監控master主機故障,并且故障自動轉移。即使有一些slave沒有接受新的relay log events,MHA也會從最新的slave自動識別差異的relay log events,并apply差異的event到其他slaves。因此所有的slave都是一致的。 MHA秒級別故障轉移, 另外,在配置文件里可以配置一個slave優先成為Master。
當遷移新的master之后,并行恢復其他slave。即使有成千上萬的slave,也不會影響恢復master時間,slave也很快完成。整個過程無需DBA干預。
在很多情況下,有必要將master轉移到其他主機上(如替換raid控制器,提升master機器硬件等等)。這并不是master崩潰,但是計劃維護必須去做。計劃維護導致downtime,必須盡可能快的恢復。快速的master切換和優雅的阻塞寫操作是必需的,MHA提供了這種方式。優雅的master切換, 0.5-2秒內阻塞寫操作。在很多情況下0.5-2秒的downtime是可以接受的,并且即使不在計劃維護窗口。這意味著當需要更換更快機器,升級高版本時,dba可以很容易采取動作。
當master 宕后,MHA自動識別slave間relay logevents的不同,然后應用與不同的slave,最終所有slave都同步。結合通過半同步一起使用,幾乎沒有任何數據丟失。
MHA最重要的一個設計理念就是盡可能使用簡單。其只要是在主從環境下,MHA集群無需改變現有部署便可部署,無論是在同步和半同步環境都可以用。啟動/停止/升級/降級/安裝/卸載 MHA都不用改變mysql主從(如啟動/停止)。而它集群方案需要改變mysql部署設置。
當需要升級MHA到新版本時,不需要停止mysql,僅僅更新HMA版本,然后重新啟動MHAmanger即可。
MHA 包含MHA Manager和MHA node。一個MHA Manager可以管理多個MHA node集群組。增加集群組時,對新增的集群組配置復制,并且更新MHA Manager的配置即可。對現有的集群組基本無影響。增加集群組數量也不會對MHA Manager有太大負擔。Manager可以單獨部署一臺機器,也可以運行在slaves中的一臺機器上。
MHA監控Master不發送大的查詢,主從復制性能不受影響。本案例通過自定義腳本,定期嘗試登陸Master 如果登陸失敗,即實施故障切換。這么監控辦法,對性能基本沒什么影響。
Mysql不僅僅適用于事務安全的innodb引擎,在主從中適用的引擎,MHA都可以適用。即使用遺留環境的mysiam引擎,不進行遷移,也可以用MHA。
MHA可通常有兩種方式實現業務層面的透明故障轉移:一種是虛擬IP地址,MHA結合Keepalived 和LVS,當群集內的數據庫進行故障轉移時,對外提供服務的虛擬IP也進行轉移;第二種是全局配置文件,通過配置MHA的master_ip_failover_script 、master_ip_online_change_script參數來實現。
MHA的Master為可讀寫,而備用Master和Slave都可用于查詢,分擔讀壓力。
Master down掉后,如需重新加入集群,需要手工執行命令切換。
備用的Master 默認是可寫的,如果不設置為read only,存在數據不一致性的風險。并且read-only對super用戶不起作用。
由于使用了MySQL的復制,而MySQL的復制是存在延遲的。MySQL的復制延遲主要是因為Master多線程對Slave單線程的遲延。
為了實現更好的效果,本實驗使用四臺機器。使用MySQL的半同步復制,保證數據的完整性。結合Keepalived和LVS 實現IP故障透明轉移和讀寫分離。需要說明的是一旦主服務器宕機,備份機即開始充當master提供服務,如果主服務器上線也不會再成為master了,因為如果這樣數據庫的一致性就被改變了。
IP | 主機 | 用途說明 |
192.168.0.11 | Master | Master,Keepalived HA的Master |
192.168.0.12 | Slave1(備用Master) | 備用Master,Keepalived HA的BACKUP,LVS均衡負載主機 |
192.168.0.13 | Slave2 | Slave,LVS均衡負載主機 |
192.168.0.14 | MHA Manager | MHA集群的管理主機 |
192.168.0.20 | 虛擬IP地址 | MHA集群寫VIP地址 |
192.168.0.21 | 虛擬IP地址 | MHA集群讀VIP地址 |
(1)首先用ssh-keygen實現四臺主機之間相互免密鑰登錄
(2)安裝MHAmha4mysql-node,mha4mysql-manager 軟件包
(3)建立master,slave1,slave2之間主從復制
(4)管理機manager上配置MHA文件
(5)masterha_check_ssh工具驗證ssh信任登錄是否成功
(6)masterha_check_repl工具驗證mysql復制是否成功
(7)啟動MHA manager,并監控日志文件
(8)測試master(156)宕機后,是否會自動切換
在MHA所有主機中生成rsa加密認證,并配置為相互訪問無需密碼
ssh-keygen -t rsa
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.0.11
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.0.12
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.0.13
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.0.14
在3個MySQL主從節點上安裝MySQL軟件。
rpm -qa mysql
rpm -e mysql-devel
rpm -e mysql
cd /media/RHEL_6.4\ x86_64\ Disc\ 1/Packages/
rpm -ivh cmake-2.6.4-5.el6.x86_64.rpm
cd /root
tar zxvf mysql-5.6.19.tar.gz
cd /root/mysql-5.6.19
mkdir -p /usr/local/mysql/data
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/usr/local/mysql/data
make && make install
groupadd mysql
useradd -r -g mysql mysql
(5)初始化MySQL
cd /usr/local/mysql
chown -R mysql .
chgrp -R mysql .
scripts/mysql_install_db --user=mysql
chown -R root .
chown -R mysql data
./bin/mysqld_safe --user=mysql &
cp support-files/mysql.server /etc/init.d/mysql.server
vi ~/.bash_profile
PATH加上:
:/usr/local/mysql/bin
source ~/.bash_profile
cp /usr/local/mysql/my.cnf /etc/
vi /etc/my.cnf
log_bin # mha3 不會是master,因此不用該參數
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
server_id = 1 #主從同步需要
socket = /tmp/mysql.sock
重啟MySQL :service mysql.server restart
GRANT ALL ON *.* TO root@localhost IDENTIFIED BY 'revenco123' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY 'revenco123' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO root@mha1 IDENTIFIED BY 'revenco123' WITH GRANT OPTION;
FLUSH PRIVILEGES;
(1)修改MASTER上的/etc/my.cnf,加入:
server_id=1
log_bin
(2)修改SLAVE1(備用MASTER)上的/etc/my.cnf,加入:
server_id=2
log_bin
(3)修改SLAVE2上的/etc/my.cnf,加入:
server_id=3
(1)在master上授權
mysql> grant replication slave on *.* to repl@'192.168.0.%' identified by 'repl';
(2)在備選master上授權:
mysql> grant replication slave on *.* to repl@'192.168.0.%' identified by 'repl';
(1)在Master查看當前使用的二進制日志名稱和位置
mysql> show master status;
記錄下 “File”和“Position”即當前主庫使用的二進制日志名稱和位置。
(2)切換到從庫模式
在Slave1(備用Master)和Slave2 上切換到從庫模式
mysql> change master to master_host="mha1",master_user="repl",master_password="repl",master_log_file="mha1-bin.000005",master_log_pos=120;
master_log_file 和 master_log_pos 是上面記下的東西。
(3)啟動復制
在Slave1(備用Master)和slave2上啟用復制:
mysql>start slave;
(6)在slave2上設置為只讀
mysql>set global read_only=1
注意:read-only對super權限的用戶不起作用
(1)查看出庫的狀態
mysql>show master status\G;
(2)查看從庫的狀態
mysql>show slave status\G;
# 如果 Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 則說明主從配置成功。
# 還可以到master上執行 Mysql>show global status like “rpl%”;
如果Rpl_semi_sync_master_clients 是2說明半同步復制正常
日志的同步格式有3種:
(1)基于SQL語句的復制(statement-based replication, SBR)
(2)基于行的復制(row-based replication, RBR)
(3)混合模式復制(mixed-based replication, MBR)
相應地,binlog的格式也有三種:STATEMENT,ROW,MIXED。 MBR 模式中,SBR 模式是默認的。為了數據的一致性,建議選擇ROW或MIXED模式。
比如,有函數:
CREATE DEFINER = 'root'@'%' FUNCTION f_test2
(
pid int
)
RETURNS int(11)
BEGIN
insert into t1 values (pid,sysdate());
RETURN 1;
END
在主庫執行 select f_test2(8)后,在主庫和各個從庫上,插入的sysdate()的值是不同的;
配置MySQL半同步復制的前提是已經配置了MySQL的復制。半同步復制工作的機制處于同步和異步之間,Master的事務提交阻塞,只要一個Slave已收到該事務的事件且已記錄。它不會等待所有的Slave都告知已收到,且它只是接收,并不用等其完全執行且提交。
在故障切換的時候,Master和Slave1(備用Master)都有可能成為Master或Slave,因此這兩個服務器上都要安裝'semisync_master.so'和'semisync_slave.so'。
(1)安裝半同步插件
(作為Master時需要安裝的插件)
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
(作為Slave時需要安裝的插件)
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
(2)設置參數
(作為Master時需要設置的參數)
mysql> set global rpl_semi_sync_master_enabled=1;
mysql> set global rpl_semi_sync_master_timeout=1000;
mysql> show global status like 'rpl%';
(作為Slave時需要設置的參數)
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> set global rpl_semi_sync_slave_enabled=1;
(3)修改配置文件
為了讓mysql在重啟時自動加載該功能,在/etc/my.cnf 加入:
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000
rpl_semi_sync_slave_enabled=1
(1)安裝半同步插件
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
(2)設置參數
mysql> set global rpl_semi_sync_slave_enabled=1;
(3)修改配置文件
在/etc/my.cnf中加入:
rpl_semi_sync_slave_enabled=1
可以到master上執行 Mysql>show global status like 'rpl%';
如果Rpl_semi_sync_master_clients 是2.說明半同步復制正常
MHA有個不方便的地方是,無論宕機導致的master切換還是手動切換master, 原來的master都不在MHA架構內了,重新啟動也不會加入,必須手動加入。手動加入的步驟類似,先把當前master數據復制到要加入的機器,然后change master,再start slave, 關鍵在做這一過程中,系統不能寫入,這點要人命。
一個MHA主機可以管理多個MySQL復制組,安裝MHA需要先安裝DBD-MySQL,為了安裝DBD-MySQL方便,先安裝yum工具。
vim /etc/yum.repos.d/rhel-source.repo
[rhel-source]
name=Red Hat Enterprise Linux $releasever - $basearch - Source
#baseurl=ftp://ftp.redhat.com/pub/redhat/linux/enterprise/$releasever/en/os/SRPMS/
baseurl=file:///mnt
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
[rhel-source-beta]
name=Red Hat Enterprise Linux $releasever Beta - $basearch - Source
#baseurl=ftp://ftp.redhat.com/pub/redhat/linux/beta/$releasever/en/os/SRPMS/
baseurl=file:///mnt
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
umount /dev/cdrom
mount /dev/cdrom /mnt
yum clean all
yum list
yum install perl-DBD-MySQL
cd /root
tar zxvf mha4mysql-node-0.54.tar.gz
cd mha4mysql-node-0.54
perl Makefile.PL
make
make install
(1)下載和安裝必要的包
下載地址:http://apt.sw.be/redhat/el6/en/i386/extras/RPMS/perl-Config-Tiny-2.12-1.el6.rfx.noarch.rpm
http://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/perl-Log-Dispatch-2.26-1.el6.rf.noarch.rpm
http://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/perl-Parallel-ForkManager-0.7.5-2.2.el6.rf.noarch.rpm
(2)安裝必要的包
rpm -ivh perl-Params-Validate-0.92-3.el6.x86_64.rpm
rpm –ivh perl-Config-Tiny-2.12-1.el6.rfx.noarch.rpm
rpm –ivh perl-Log-Dispatch-2.26-1.el6.rf.noarch.rpm
rpm –ivh perl-Parallel-ForkManager-0.7.5-2.2.el6.rf.noarch.rpm
(3)安裝MHA manager軟件
cd /mnt/Packages
cd /root
tar zxvf mha4mysql-manager-0.55.tar.gz
cd mha4mysql-manager-0.55
perl Makefile.PL
make
make install
在MHA Manager上創建MHA配置
[root@mha4 ~]# more /etc/masterha/app1.cnf
[server default]
# mysql user and password
user=root
password=revenco123
ssh_user=root
repl_user=repl
repl_password=repl
ping_interval=1
shutdown_script=""
# working directory on the manager
manager_workdir=/var/log/masterha/app1
manager_log=/var/log/masterha/app1/manager.log
# working directory on MySQL servers
remote_workdir=/var/log/masterha/app1
[server1]
hostname=mha1
master_binlog_dir=/usr/local/mysql/data
candidate_master=1
[server2]
hostname=mha2
master_binlog_dir=/usr/local/mysql/data
candidate_master=1
[server3]
hostname=mha3
master_binlog_dir=/usr/local/mysql/data
no_master=1
注釋:具體的參數請查看官方文檔
https://code.google.com/p/mysql-master-ha/wiki/Parameters
在MHA Manager上執行
masterha_check_ssh --conf=/etc/masterha/app1.cnf
masterha_check_repl --conf=/etc/masterha/app1.cnf
如果報錯,請檢查配置。
問題1 :
Can't exec "mysqlbinlog": No such file or directory at /usr/local/share/perl/5.10.1/MHA/BinlogManager.pm line 99.
mysqlbinlog version not found!
解決辦法:
#vi ~/.bashrc或vi /etc/bashrc,然后在文件末尾添加
PATH="$PATH:/usr/local/mysql/bin"
export PATH
source /etc/bashrc
問題2:
Testing mysql connection and privileges..Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'mha2' (using password: YES)
解決辦法: 查看用戶表。
RANT ALL PRIVILEGES ON *.* TO root@mha1 IDENTIFIED BY 'revenco123' WITH GRANT OPTION;
啟動管理節點進程
masterha_manager --conf=/etc/masterha/app1.cnf &
注:停止和啟動MHA服務,不影響MySQL對外提供服務。
當MHA群集內的數據庫進行故障轉移時,對外提供服務的虛擬IP也進行轉移;本實驗案例通過使用Keepalived + LVS的方法,實現讀寫分離,IP故障透明轉移。
寫分離,Master和Slave1(備用Master)共用一個寫虛擬IP,任何時刻,只能有一臺機可寫,正常情況下,寫操作在Master執行,當Master down機后,MHA把Slave1(備用Master)提升為Master,此后,Slave1(備用Master)可寫,當Master修復起來后,它成為Slave,仍然是Slave1(備用Master)可寫。除非人工干預,將修復后的Master提升為Master。
讀分離,Slave1(備用Master)和Slave2 共用一個讀虛擬IP。采用LVS的輪詢算法,輪流訪問Slave1(備用Master)和Slave2,如果其中一臺不可訪問,則訪問另外一臺服務器。
注意:一旦主服務器宕機,備份機即開始充當master提供服務,如果主服務器上線也不會再成為master了,因為如果這樣數據庫的一致性就被改變了。
在Master和Slave1(備份Master)上安裝Keepalived
rpm -ivh openssl-devel-1.0.0-27.el6.x86_64
tar zxvf keepalived-1.2.13.tar.gz
cd keepalived-1.2.13
./configure --prefix=/usr/local/keepalived
編譯后看到三個yes才算成功如果出現兩個yes或者一個應該要檢查下內核軟連接做對了沒有:
Use IPVS Framework : Yes #必須為YES
IPVS sync daemon support : Yes #必須為YES
IPVS use libnl : No
fwmark socket support : Yes
Use VRRP Framework : Yes #必須為YES
Use VRRP VMAC : Yes
make
make install
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
mkdir -pv /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
ln -s /usr/local/keepalived/sbin/keepalived /sbin/
service keepalived restart
整個MHA使用keepalived 的"HA + LVS"模式,在mha1和mha2 上配置 Keepalived HA 模式,即下面代碼的“vrrp_instance VI_1”實例組;在mha2和mha3 上配置 Keepalived LVS 模式,即下面代碼的“vrrp_instance VI_2”實例組。兩個主機配置的都是“state BACKUP”,但優先級priority 不同。配置如下:
[root@mha1 ~]# more /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id mha1
}
vrrp_script check_mysql {
script "/usr/local/keepalived/bin/keepalived_check_mysql.sh"
interval 3
}
vrrp_sync_group VG1 {
group {
VI_1
}
}
vrrp_sync_group VG2 {
group {
VI_2
}
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 150
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass revenco123
}
track_script {
check_mysql
}
virtual_ipaddress {
192.168.0.20
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass revenco1234
}
track_script {
check_mysql
}
virtual_ipaddress {
192.168.0.21
}
}
virtual_server 192.168.0.21 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.0.12 80 {
weight 3
TCP_CHECK {
connect_timeout 3
}
}
real_server 192.168.0.13 80 {
weight 3
TCP_CHECK {
connect_timeout 3
}
}
}
}
[root@mha2 ~]# more /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id mha2
}
vrrp_script check_mysql {
script "/usr/local/keepalived/bin/keepalived_check_mysql.sh"
interval 3
}
vrrp_sync_group VG1 {
group {
VI_1
}
}
vrrp_sync_group VG2 {
group {
VI_2
}
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass revenco123
}
track_script {
check_mysql
}
virtual_ipaddress {
192.168.0.20
}
}
vrrp_instance VI_2 {
state BACKUP
interface eth0
virtual_router_id 52
priority 150
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass revenco1234
}
track_script {
check_mysql
}
virtual_ipaddress {
192.168.0.21
}
}
virtual_server 192.168.0.21 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.0.12 3306 {
weight 3
TCP_CHECK {
connect_timeout 3
}
}
real_server 192.168.0.13 3306 {
weight 3
TCP_CHECK {
connect_timeout 3
}
}
}
在兩臺Keepalived主機上,配置檢測mysql狀態腳本(兩臺mysql一樣的配置),腳本文件要實現的功能大體為:只要檢測到mysql服務停止keepalived服務也停止 ,因為keepalived是通過組播方式告訴本網段自己還活著當mysql服務停止后keepalived還依然運行 這時就需要停止keepalived讓另一個主機獲得虛擬IP,可以在后臺運行這個腳本 也可以在keepalived配置文件加入這個腳本,本實驗把該腳本配置在keepalived配置文件中。
腳本文件名: /usr/local/keepalived/bin/keepalived_check_mysql.sh
#!/bin/bash
MYSQL=/usr/local/mysql/bin/mysql
MYSQL_HOST=localhost
MYSQL_USER=root
MYSQL_PASSWORD=revenco123
CHECK_TIME=3
#mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
MYSQL_OK=1
function check_mysql_helth (){
$MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -e "show status;" >/dev/null 2>&1
if [ $? = 0 ] ;then
MYSQL_OK=1
else
MYSQL_OK=0
fi
return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
let "CHECK_TIME -= 1"
check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
CHECK_TIME=0
exit 0
fi
if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
then
/etc/init.d/keepalived stop
exit 1
fi
sleep 1
done
使用LVS技術要達到的目標是:通過LVS提供的負載均衡技術和Linux操作系統實現一個高性能、高可用的服務器群集,它具有良好可靠性、可擴展性和可操作性。從而以低廉的成本實現最優的服務性能。本實驗通過使用LVS軟件,在Slave1(備用Master)和Slave2上實現讀負載均衡。
Keepalived 附帶了LVS的功能,因此LVS服務器端的配置是直接在Keepalived的配置文件中配置的,Keepalived的配置文件的“virtual_server”部分的配置,便是LVS的配置。具體請查看Keepalived的配置文件的“virtual_server”部分。
在本實驗案例中,LVS的真實機是Slave1(備用Master)和Slave2
在lvs的DR和TUn模式下,用戶的訪問請求到達真實服務器后,是直接返回給用戶的,而不再經過前端的Director Server,因此,就需要在每個Real server節點上增加虛擬的VIP地址,這樣數據才能直接返回給用戶,增加VIP地址的操作可以通過創建腳本的方式來實現,創建文件/etc/init.d/lvsrs,腳本內容如下
[root@mha3 ~]# more /etc/init.d/lvsrs
#!/bin/bash
#description : Start Real Server
VIP=192.168.0.21
. /etc/rc.d/init.d/functions
case "$1" in
start)
echo " Start LVS of Real Server"
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
;;
stop)
/sbin/ifconfig lo:0 down
echo "close LVS Director server"
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
vim /etc/iptables
/etc/init.d/iptables restart
# 允許vrrp協議通過
(1). 啟動mha1,mha2的keepalived,訪問兩個VIP所訪問的主機。
測試結果:對于VIP1,訪問mha1;對于VIP2,輪流訪問mha2和mha3。
(2). 關閉mha1的keepalived
測試結果:對于VIP1,訪問mha2;對于VIP2,輪流訪問mha2和mha3。
(3). 再啟動mha1的keepalived
測試結果:對于VIP1,訪問mha2;對于VIP2,輪流訪問mha2和mha3。
(4). 關閉mha2的keepalived
測試結果:對于VIP1,訪問mha1;對于VIP2,輪流訪問mha2和mha3。
(5). 再啟動mha2的keepalived
測試結果:對于VIP1,訪問mha1;對于VIP2,輪流訪問mha2和mha3。
(6). 重復一次“1--5”步驟。
測試結果:測試結果相同。
(7). 同時關閉mha1,mha2的keepalived
測試結果:兩個VIP都不能訪問。
測試的服務為httpd:
(沒有加腳本,讓httpd服務器停止,keepalived服務也停止。如果是Mysql服務器是有相應的腳本的)
(1). 啟動mha1,mha2的keepalived 和httpd服務,訪問兩個VIP所訪問的主機。
測試結果:對于VIP1,訪問mha1;對于VIP2,輪流訪問mha2和mha3。
(2). 關閉mha1的httpd
測試結果:對于VIP1,訪問mha2;對于VIP2,輪流訪問mha2和mha3。
(3). 再啟動mha1的httpd
測試結果:對于VIP1,訪問mha2;對于VIP2,輪流訪問mha2和mha3。
(4). 關閉mha2的httpd
測試結果:對于VIP1,無法訪問;對于VIP2,訪問mha3。
(應該在keepalive中定期檢測httpd服務,httpd服務停止,那么keepalived服務也停止,讓mha1作為Master,那樣VIP1就可以訪問mha1,而不是現在的“無法訪問”)
(5). 再啟動mha2的httpd
測試結果:對于VIP1,恢復訪問mha2;對于VIP2,輪流訪問mha2和mha3。
(6). 關閉mha3的httpd
測試結果:對于VIP1 無任何影響;對于VIP2,訪問mha2。
(7). 再啟動mha3的httpd
測試結果:對于VIP1 無任何影響;對于VIP2,輪流訪問mha2和mha3。
(8). 同時關閉mha1,mha2的httpd
測試結果:兩個VIP都不能訪問。
(1)先使用mha-w-vip 連接到mha集群,查看所連接的數據庫主機信息。
mysql -uroot -ptest123 -h 172.20.52.252
use mysql
select host,user,password from user;
(2)關閉當前的master 的mysql服務。
(3)查看mha-w-vip(寫VIP) 連接是否可連接到mha集群,當前連接是否斷掉。
(4)測試結果:停止master上的mysql服務后,3秒內進行切換 "寫VIP"。當master上的mysql服務down后,備用master成為master,集群可用。當原master恢復后,需要手工把它切換到復制狀態。
只能做到連接的高可用性,做不到會話級別的高可用性。即,down后,原有的會話將斷開,然后馬上重新連接。
輪流停止備用master和、slave,然后使用讀vip連接后,查看當前所連接的庫的主機信息。
(1)先使用mha-r-vip (讀VIP)連接到mha集群,查看所連接的數據庫主機信息。
mysql -uroot -ptest -h 172.20.52.253
use mysql
select host,user,password from user;
(2)打開多個會話,重復上一步。
(3)查看各個會話是連接到哪個主機上。
(4)測試結果:備用master、slave都在線時,輪流訪問。
(1)先使用mha-r-vip (讀VIP)連接到mha集群,查看所連接的數據庫主機信息。
mysql -uroot -ptest123 -h mha1-r-vip
use mysql
select host,user,password from user;
(2)輪流停止備用master和slave,然后使用讀vip連接后,查看當前所連接的庫的主機信息。
(3)測試結果:備用master、slave任何一臺的mysql服務down掉,集群都可讀。
在主庫上執行創建庫、表、并插入數據,查看備用master和slave的數據同步情況。
(1)在主庫上執行創建庫、表、并插入數據
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> create table t1 (id int ,name varchar(20));
ERROR 1046 (3D000): No database selected
mysql> use test;
Database changed
mysql> create table t1 (id int ,name varchar(20));
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t1 values (1,'a');
Query OK, 1 row affected (0.02 sec)
mysql> insert into t1 values (2,'b');
(2)登錄備庫,查看數據
Use test
Select * from t1;
(3)測試結果:
備用master slave都能馬上自動同步數據。(后臺在毫秒級別上完成同步)
測試把備用master和slave設置為read_only后,效果如何
(1)設置為只讀
set global read_only=1;
(2)登錄并插入數據
Mysql –uroot –prtest123 –D test
Insert into t1 values(1,’a’);
插入成功
(3)創建普通用戶
GRANT ALL ON test.* TO test@'%' IDENTIFIED BY 'test' WITH GRANT OPTION;
GRANT ALL ON test* TO test@localhost IDENTIFIED BY 'test' WITH GRANT OPTION;
(3)登錄并插入數據
Mysql –utest–ptest–D test
Insert into t1 values(1,’a’);
插入失敗
(4)測試結果:read_only對super用戶無影響,對普通用戶能起到限制作用。
主庫
mysql -utest-ptest-D test
insert into t1 values(3,'c');
備用master、slave查詢:
select * from t1;
測試
備用master、slave插入:
mysql -utest -ptest -D test
insert into t1 values(4,'d');
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
結論:在備用master、slave設置只讀,可限制備用master、slave的寫功能,并且不影響主從復制功能。
原master恢復后,如果想讓原master(mha1)一直為slave,需要做以下:
1). 需要更改mha manager文件中mha1的順序。
2). 刪除 rm /var/log/masterha/app1/app1.failover.complete
3). 再次啟動mha manager進程
4). 讓mha2的keepalived為HA 的Master,mha1為"BACKUP"狀態,保證“寫vip”是關聯到Master上的。
5). 修改讀VIP。讀VIP為mha1、mha3(原mha2、mha3)
6). 設置原master(mha1)為read_only
7). 檢查 show slave status \G; show master status;
原master恢復后,如果想讓原master(mha1)重新成為Master,需要做以下:
1). 在mha manager上,手工把mha1切換為Master。
2). 設置備用master(mha2)為read_only.
3). 刪除 rm /var/log/masterha/app1/app1.failover.complete
4). 重新啟動mha manager進程。
5). 讓mha1的keepalived為HA 的Master,mha2為"BACKUP"狀態,保證“寫vip”是關聯到Master上的。
6). 檢查 show slave status \G; show master status;
(1).停止master_manager進程:masterha_stop --conf=/etc/app1.cnf
(2).執行切換命令,可根據需要執行使用不同的參數。
主庫down的情況
masterha_master_switch --master_state=dead --conf=/etc/conf/masterha/app1.cnf --dead_master_host=mha2
非交互式故障轉移
masterha_master_switch --master_state=dead --conf=/etc/conf/masterha/app1.cnf --dead_master_host=mha2 --new_master_host=mha1 --interactive=0
在線切換,切換后原來的主庫不要
masterha_master_switch --master_state=alive --conf=/etc/masterha/app1.cnf --new_master_host=mha1
在線切換,切換后原來的主庫變成從庫
masterha_master_switch --master_state=alive --conf=/etc/masterha/app1.cnf --new_master_host=mha1 --orig_master_is_new_slave
導出:
mysqldump -uroot -p123456 test > test_20140704.sql
導入:
mysql -uroot -ptest123 test< test_20140704.sql
測試結果:在主庫執行導入,從庫自動同步數據。
在Master上創建存儲過程`f_test`,然后在備用master和slave上創建,如果提示存儲過程已存在,則說明創建存儲過程也會同步到備用master和slave。
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `f_test`(
IN p_id int,
IN p_name varchar(20)
)
begin
insert into t1 values(p_id,p_name);
END;
$$
DELIMITER ;
測試結果:創建存儲過程也會同步到備用master和slave。
在master上執行
call f_test(4,'d');(f_test的功能是插入一條記錄到t1)
查詢select * from t1;
在備用master和slave查詢select * from t1;
數據與Master上一致,存儲過程內修改數據會同步。
測試結果:存儲過程內修改數據會同步。
mysql主從復制,經常會遇到錯誤而導致slave端復制中斷,這個時候一般就需要人工干預,跳過錯誤才能繼續。跳過錯誤有兩種方式:
mysql> stop slave;
mysql>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1 #跳過一個事務
mysql>slave start
通過slave_skip_errors參數來跳所有錯誤或指定類型的錯誤
vi /etc/my.cnf
[mysqld]
#slave-skip-errors=1062,1053,1146 #跳過指定error no類型的錯誤
#slave-skip-errors=all #跳過所有錯誤
Mysql 對函數的同步有限制。只有被明確聲明為DETERMINISTIC或NO SQL 或READS SQL DATA的函數,才可以創建,并可自動同步到從庫,否則創建函數會失敗。可以通過設置參數“set global log_bin_trust_function_creators = 1”,使得函數能創建成功,并同步到從庫。此參數只有在開啟log-bin的情況下才有用。log_bin_trust_function_creators=0的情況下,需要有SUPER權限,并且不包含修改數據的SQL,才能創建函數。
(1)測試正常主從復制情況下,函數的創建
mysql> set global log_bin_trust_function_creators = 1;
CREATE DEFINER = 'root'@'%' FUNCTION f_test2
(
pid int
)
RETURNS int(11)
BEGIN
insert into t1 values (pid,sysdate());
RETURN 1;
END
測試結果:在主從環境下,如果函數沒有聲明DETERMINISTIC或NO SQL 或READS SQL DATA,創建函數失敗。
(2)強行聲明為DETERMINISTIC或NO SQL 或READS SQL DATA的函數測試
CREATE DEFINER = 'root'@'%' FUNCTION f_test2
(
pid int
)
RETURNS int(11)
DETERMINISTIC
BEGIN
insert into t1 values (pid,sysdate());
RETURN 1;
END
測試結果:可以創建成功,并且可同步到從庫。但無法執行該函數,執行時報錯。
(3)把global log_bin_trust_function_creators = 1后,不聲明函數的為DETERMINISTIC或NO SQL 或READS SQL DATA屬性。
mysql> set global log_bin_trust_function_creators = 0;
創建函數成功,也可以同步到從庫(開啟bin-log的從庫必須做同樣的參數配置)。
在主庫執行函數
mysql> select f_test2(7);
mysql> select * from t1;
在主庫的t1表有插入記錄,并且有同步到從庫。
binlog_format = STATEMEN 的情況下:
創建存儲過程p_test1,自動同步到從庫,并不需要“set global log_bin_trust_function_creators = 1;”,由此看出,存儲過程的復制時安全的;執行call p_test1(14);數據完全同步到從庫。如果是函數,并不完全同步,sysdate()獲取的值不同。
p_test1代碼:
DELIMITER |
CREATE DEFINER = 'root'@'%' PROCEDURE p_test1
(
pid int
)
BEGIN
declare v_time datetime;
set v_time = sysdate();
insert into t1 values (pid,v_time);
END|
DELIMITER ;
測試結果:結合函數同步的測試情況,可得出:
在binlog_format = STATEMEN的情況下,執行存儲過程時,后臺采用binlog_format =ROW的方式同步日志;而執行函數時,后臺采用binlog_format =STATEMEN的方式同步日志。
(1)查看ssh登陸是否成功
masterha_check_ssh --conf=/etc/masterha/app1.cnf
(2)查看復制是否建立好
masterha_check_repl --conf=/etc/masterha/app1.cnf
(3)啟動mha
nohup masterha_manager --conf=/etc/masterha/app1.cnf > /tmp/mha_manager.log < /dev/null 2>&1 &
當有slave節點宕掉的情況是啟動不了的,加上--ignore_fail_on_start即使有節點宕掉也能啟動mha
nohup masterha_manager --conf=/etc/masterha/app1.cnf --ignore_fail_on_start > /tmp/mha_manager.log < /dev/null 2>&1 &
(4)檢查啟動的狀態
masterha_check_status --conf=/etc/masterha/app1.cnf
(5)停止mha
masterha_stop --conf=/etc/masterha/app1.cnf
(6)failover后下次重啟
每次failover切換后會在管理目錄生成文件app1.failover.complete ,下次在切換的時候會發現有這個文件導致切換不成功,需要手動清理掉。
rm -rf /masterha/app1/app1.failover.complete
也可以加上參數--ignore_last_failover
(7)手動在線切換
1).手動切換時需要將在運行的mha停掉后才能切換。可以通過如下命令停止mha
masterha_stop --conf=/etc/app1.cnf
2).執行切換命令
手工failover場景,master死掉,但是masterha_manager沒有開啟,可以通過手工failover:
masterha_master_switch --master_state=dead --conf=/etc/app1.cnf --dead_master_host=host1 --new_master_host=host5
或者
masterha_master_switch --conf=/etc/app1.cnf --master_state=alive --new_master_host=host1 --orig_master_is_new_slave
或者
masterha_master_switch --conf=/etc/app1.cnf --master_state=alive --new_master_host=host1 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0
參數解釋
--orig_master_is_new_slave切換時加上此參數是將原master變為slave節點,如果不加此參數,原來的master將不啟動,需要設置在配置文件中配置repl_user 、repl_password參數 。
--running_updates_limit=10000 切換時候選master如果有延遲的話,mha切換不能成功,加上此參數表示延遲在此時間范圍內都可切換(單位為s),但是切換的時間長短是由recover時relay日志的大小決定。
--interactive=0,切換時是否互交,默認是互交的。互交的意思就是要你選擇一些選項,如根據提示輸入“yes or no”。
--master_state=alive master在線切換,需要如下條件,第一,在所有slave上IO線程運行;第二,SQL線程在所有的slave上正常運行;第三,在所有的slaves上 Seconds_Behind_Master 要小于等于 running_updates_limit seconds;第四,在master上,在show processlist輸出結果上,沒有更新查詢操作多于running_updates_limit seconds。
在備庫先執行DDL,一般先stop slave,一般不記錄mysql日志,可以通過set SQL_LOG_BIN = 0實現。然后進行一次主備切換操作,再在原來的主庫上執行DDL。這種方法適用于增減索引,如果是增加字段就需要額外注意。
上述內容就是MySQL MHA集群方案是怎樣的,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。