一、背景介紹
網(wǎng)站建設(shè)公司,為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計(jì)及定制網(wǎng)站建設(shè)服務(wù),專注于企業(yè)網(wǎng)站制作,高端網(wǎng)頁制作,對(duì)垃圾桶等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。專業(yè)網(wǎng)站設(shè)計(jì),網(wǎng)站優(yōu)化推廣哪家好,專業(yè)seo優(yōu)化優(yōu)化,H5建站,響應(yīng)式網(wǎng)站。
在傳統(tǒng)的MySQL一主一從或一主多從結(jié)構(gòu)中,主節(jié)點(diǎn)存在單點(diǎn)故障隱患,為了解決該故障,進(jìn)而引入了MHA高可用的方式。MHA由manager和node兩部分組成,manager可以安裝在一個(gè)獨(dú)立的服務(wù)器上或非master角色的MySQL服務(wù)器上,1個(gè)manager可以管多個(gè)node集合,每一個(gè)master/node集群稱為一個(gè)application,所有集群可以使用一個(gè)配置文件或者為每個(gè)集群創(chuàng)建單獨(dú)的配置文件,目前MHA最少由3個(gè)主機(jī)組成
二、實(shí)現(xiàn)原理
MHA是在MySQL主從復(fù)制基礎(chǔ)上實(shí)現(xiàn)的高可用,其實(shí)現(xiàn)原理是:
在正常情況下,MHA的manager節(jié)點(diǎn)對(duì)所有node節(jié)點(diǎn)周期性進(jìn)行健康狀態(tài)檢測(cè),當(dāng)MySQL的master節(jié)點(diǎn)出現(xiàn)故障時(shí),MHA的manager試圖從宕機(jī)的MySQL的master上將二進(jìn)制日志保存到本地,并與所有node節(jié)點(diǎn)的中繼日志進(jìn)行對(duì)比,將擁有最新同步狀態(tài)的slave主機(jī)提升為master主機(jī),所有slave主機(jī)指向新的master主機(jī)。
三、實(shí)驗(yàn)環(huán)境
本次實(shí)驗(yàn)采用CentOS7.4系統(tǒng),數(shù)據(jù)庫版本5.5.56-MariaDB,MHA版本mha4mysql-manager-0.58。因?yàn)樗蟹?wù)器之間要傳輸中繼日志,并且還需要指定master,所有所有主機(jī)間要建立密鑰認(rèn)證,master和candidate節(jié)點(diǎn)需要?jiǎng)?chuàng)建用于從服務(wù)器復(fù)制的二進(jìn)制日志的賬號(hào),MySQL每個(gè)服務(wù)器都需要?jiǎng)?chuàng)建可以指定master的賬號(hào),并且master和candidate節(jié)點(diǎn)不能開啟relay_log_purge選項(xiàng),為了最大程度的保證數(shù)據(jù)的不丟失,建議將candidate配置成半同步形式。
MHA角色 | MySQL角色 | IP地址 | 開啟MySQL功能 |
manager | — | 172.16.10.30/24 | — |
node | master | 172.16.10.40/24 | 1.二進(jìn)制日志,中繼日志 2.復(fù)制賬號(hào),管理賬號(hào) 3.中繼日志不能裁剪 4.半同步master插件 |
node/candidate | slave | 172.16.10.50/24 | 1.二進(jìn)制日志,中繼日志 2.復(fù)制賬號(hào),管理賬號(hào) 3.中繼日志不能裁剪 4.半同步slave插件 5.只讀模式 |
node | slave | 172.16.10.60/24 | 1.中繼日志 2.只讀模式 |
四、準(zhǔn)備操作
既然是集群時(shí)間同步和名稱解析就需要提前完成,此處不過多介紹
1.所有主機(jī)互信
可以在一個(gè)主機(jī)生成一對(duì)密鑰,將這對(duì)密鑰和know_hosts文件拷貝給其余主機(jī)的方式,不需要所有主機(jī)都生成密鑰對(duì)相互拷貝
[root@host3 ~]# ssh-keygen
[root@host3 ~]# ssh-copy-id 172.16.10.30
[root@host3 ~]# ssh-copy-id 172.16.10.40
[root@host3 ~]# ssh-copy-id 172.16.10.50
[root@host3 ~]# ssh-copy-id 172.16.10.60
[root@host3 .ssh]# scp -r id_rsa known_hosts root@172.16.10.40:/root/.ssh/
[root@host3 .ssh]# scp -r id_rsa known_hosts root@172.16.10.50:/root/.ssh/
[root@host3 .ssh]# scp -r id_rsa known_hosts root@172.16.10.60:/root/.ssh/
2.安裝Mariadb數(shù)據(jù)庫
[root@host4 ~]# yum install mariadb-server.x86_64 -y
[root@host5 ~]# yum install mariadb-server.x86_64 -y
[root@host6 ~]# yum install mariadb-server.x86_64 -y
3.Master主機(jī)操作
(1)修改配置文件
[root@host4 ~]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip_name_resolve=ON
relay_log=mysql-relaylog
relay_log_index=mysql-relaylog
relay_log_purge=OFF
slow_query_log=ON
server-id=10
innodb_file_per_table=ON
binlog_format=ROW
log_bin=mysql-binlog
log_slave_updates=ON
(2)啟動(dòng)并進(jìn)入MySQL
[root@host4 ~]# systemctl start mariadb.service
[root@host4 ~]# mysql
(3)創(chuàng)建用于主從復(fù)制和管理數(shù)據(jù)庫的賬號(hào)
MariaDB [(none)]> grant replication slave on *.* to 'bak'@'172.16.10.%' identified by 'bakpass';
MariaDB [(none)]> grant all on *.* to 'man'@'172.16.10.%' identified by 'manpass';
MariaDB [(none)]> flush privileges;
(4)開啟并激活半同步插件
MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so';
MariaDB [(none)]> set global rpl_semi_sync_master_enabled=ON;
(5)確定當(dāng)前binlog日志及position
MariaDB [(none)]> show master status;
+---------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------------+----------+--------------+------------------+
| mysql-binlog.000003 | 610 | | |
+---------------------+----------+--------------+------------------+
4.Candidate主機(jī)操作
(1)修改配置文件
[root@host5 ~]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip_name_resolve=ON
relay_log=mysql-relaylog
relay_log_index=mysql-relaylog
relay_log_purge=OFF
read_only=ON
slow_query_log=ON
server-id=20
innodb_file_per_table=ON
binlog_format=ROW
log_bin=mysql-binlog
log_slave_updates=ON
(2)啟動(dòng)并進(jìn)入MySQL
[root@host5 ~]# systemctl start mariadb.service
[root@host5 ~]# mysql
(3)創(chuàng)建用于主從復(fù)制和管理數(shù)據(jù)庫的賬號(hào)
MariaDB [(none)]> set global read_only=0;
MariaDB [(none)]> grant replication slave on *.* to 'bak'@'172.16.10.%' identified by 'bakpass';
MariaDB [(none)]> grant all on *.* to 'man'@'172.16.10.%' identified by 'manpass';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> set global read_only=1;
(4)開啟并激活半同步插件
MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
MariaDB [(none)]> set global rpl_semi_sync_slave_enabled=ON;
(5)指定主服務(wù)器及主服務(wù)器當(dāng)前的binlog日志和position
MariaDB [hellodb]> change master to
-> master_host='172.16.10.40',
-> master_user='bak',
-> master_password='bakpass',
-> master_port=3306,
-> master_log_file='mysql-binlog.000003',
-> master_log_pos=610,
-> master_connect_retry=10;
(6)啟動(dòng)從節(jié)點(diǎn)
MariaDB [hellodb]> start slave [IO_THREAD | SQL_THREAD];
(7)查看從節(jié)點(diǎn)狀態(tài)(Slave_IO_Running和Slave_SQL_Running顯示Yes成功)
MariaDB [(none)]> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.10.40
Master_User: bak
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-binlog.000003
Read_Master_Log_Pos: 610
Relay_Log_File: mysql-relaylog.000002
Relay_Log_Pos: 532
Relay_Master_Log_File: mysql-binlog.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
5.Slave主機(jī)操作
(1)修改配置文件
[root@host6 ~]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip_name_resolve=ON
relay_log=mysql-relaylog
relay_log_index=mysql-relaylog
relay_log_purge=ON
read_only=ON
slow_query_log=ON
server-id=30
innodb_file_per_table=ON
(2)啟動(dòng)并進(jìn)入MySQL
[root@host6 ~]# systemctl start mariadb.service
[root@host6 ~]# mysql
(3)創(chuàng)建用于管理數(shù)據(jù)庫的賬號(hào)
MariaDB [(none)]> set global read_only=0;
MariaDB [(none)]> grant replication slave on *.* to 'bak'@'172.16.10.%' identified by 'bakpass';
MariaDB [(none)]> grant all on *.* to 'man'@'172.16.10.%' identified by 'manpass';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> set global read_only=1;
(4)指定主服務(wù)器及主服務(wù)器當(dāng)前的binlog日志和position
MariaDB [hellodb]> change master to
-> master_host='172.16.10.40',
-> master_user='bak',
-> master_password='bakpass',
-> master_port=3306,
-> master_log_file='mysql-binlog.000003',
-> master_log_pos=610,
-> master_connect_retry=10;
(5)啟動(dòng)從節(jié)點(diǎn)
MariaDB [hellodb]> start slave [IO_THREAD | SQL_THREAD];
(6)查看從節(jié)點(diǎn)狀態(tài)(Slave_IO_Running和Slave_SQL_Running顯示Yes成功)
MariaDB [(none)]> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.10.40
Master_User: bak
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-binlog.000003
Read_Master_Log_Pos: 610
Relay_Log_File: mysql-relaylog.000002
Relay_Log_Pos: 532
Relay_Master_Log_File: mysql-binlog.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
五、MHA高可用實(shí)現(xiàn)
1.安裝MHA軟件
(1)主節(jié)點(diǎn)
[root@host3 mha]# yum install mha4mysql-manager-0.58-0.el7.centos.noarch.rpm mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
-masterha_check_ssh:MHA依賴的SSH環(huán)境檢測(cè)工具;
-masterha_check_repl:MySQL復(fù)制環(huán)境檢測(cè)工具;
-masterha_manager:MHA服務(wù)主程序;
-masterha_check_status:MHA運(yùn)行狀態(tài)探測(cè)工具;
-masterha_master_monitor:MySQL master節(jié)點(diǎn)可用性檢測(cè)工具;
-masterha_master_switch:master節(jié)點(diǎn)切換工具;
-masterha_conf_host:添加或刪除配置的節(jié)點(diǎn);
-masterha_stop:關(guān)閉MHA服務(wù)的工具;
(2)從節(jié)點(diǎn)
[root@host4 mha]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
-save_binary_logs:保存和復(fù)制master的二進(jìn)制日志;
-apply_diff_relay_logs:識(shí)別差異的中繼日志事件并用于其他slave;
-fiter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已不再使用這個(gè)工具);
-purge_relay_logs:清除中繼日志(不會(huì)阻塞SQL線程);
2.在MHA的Manager節(jié)點(diǎn)創(chuàng)建配置文件并檢測(cè)
[root@host3 ~]# mkdir /etc/mha
[root@host3 ~]# vim /etc/mha/app1.conf
[server default]
user=man
password=manpass
manager_workdir=/data/masterha/app1
manager_log=/data/masterha/app1/manager.log
remote_workdir=/data/masterha/app1
ssh_user=root
ping_interval=1
repl_user=bak
repl_password=bakpass
[server1]
hostname=172.16.10.40
candidate_master=1
[server2]
hostname=172.16.10.50
candidate_master=1
[server3]
hostname=172.16.10.60
no_master=1
[root@host3 mha]# masterha_check_ssh --conf=/etc/mha/app1.conf
[root@host3 mha]# masterha_check_repl --conf=/etc/mha/app1.conf
此時(shí)的警告忽略,MHA可以使用--global_conf選項(xiàng)為多個(gè)application指定相同的配置
3.啟動(dòng)并查看MHA
[root@host3 ~]# masterha_manager --conf=/etc/mha/app1.conf 2>&1 &
[root@host3 ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 (pid:2633) is running(0:PING_OK), master:172.16.10.40
4.模擬master節(jié)點(diǎn)故障
(1)關(guān)閉master節(jié)點(diǎn)的MySQL服務(wù)
[root@host4 ~]# mysqladmin -uroot shutdown
(2)在Manager節(jié)點(diǎn)查看此時(shí)狀態(tài)
[root@host3 ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 is stopped(2:NOT_RUNNING).
當(dāng)由node節(jié)點(diǎn)出現(xiàn)故障時(shí)MHA會(huì)自動(dòng)關(guān)閉,故障節(jié)點(diǎn)恢復(fù)后,不會(huì)自動(dòng)啟動(dòng)
(3)查看Candidate節(jié)點(diǎn)狀態(tài)
MariaDB [(none)]> show slave hosts;
+-----------+------+------+-----------+
| Server_id | Host | Port | Master_id |
+-----------+------+------+-----------+
| 30 | | 3306 | 20 |
+-----------+------+------+-----------+
MariaDB [(none)]> show global variables like '%read_only%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only | OFF |
+---------------+-------+
能夠發(fā)現(xiàn)Candidate節(jié)點(diǎn)已經(jīng)升級(jí)為Master節(jié)點(diǎn),并且read_only選項(xiàng)也自動(dòng)關(guān)閉(盡管配置文件中該選項(xiàng)還存在)
(4)slave節(jié)點(diǎn)查看狀態(tài)
MariaDB [(none)]> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.10.50
Master_User: bak
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-binlog.000004
Read_Master_Log_Pos: 605
Relay_Log_File: mysql-relaylog.000002
Relay_Log_Pos: 532
Relay_Master_Log_File: mysql-binlog.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
5.恢復(fù)故障主機(jī)
(1)將故障修復(fù)后的主機(jī)上線
(2)修改my.cnf文件,加入read_only=ON選項(xiàng)
(3)使用mysqldump等備份工具對(duì)當(dāng)前master主機(jī)上的數(shù)據(jù)庫進(jìn)行備份
(4)使用備份在故障主機(jī)上恢復(fù),啟動(dòng)MySQL服務(wù),再指定新的Master主機(jī)和binlog,如果宕機(jī)的是半同步的master主機(jī),還需要調(diào)換半同步的master和slave角色,并且重啟IO_thread
(5)在MHA的manager節(jié)點(diǎn)上重啟MHA
補(bǔ)充說明
MHA檢查復(fù)制狀態(tài)時(shí)出現(xiàn)如下報(bào)錯(cuò):
[root@host3 ~]# masterha_check_repl --conf=/etc/mha/app1.conf
Checking if super_read_only is defined and turned on..DBD::mysql::st execute failed: Unknown system variable'super_read_only' at /usr/share/perl5/vendor_perl/MHA/SlaveUtil.pm line 245.
Fri May 4 11:09:28 2018 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln208] Slaves settings check failed!
Fri May 4 11:09:28 2018 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln416] Slave configuration failed.
Fri May 4 11:09:28 2018 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln427] Error happened on checking configurations. at /usr/bin/masterha_check_repl line 48.
Fri May 4 11:09:28 2018 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Fri May 4 11:09:28 2018 - [info] Got exit code 1 (Not master dead).
原因是在5.5.56-MariaDB版本中雖然從節(jié)點(diǎn)設(shè)置了read_only選項(xiàng),但是對(duì)于管理員權(quán)限的用戶這點(diǎn)不生效,所以在MySQL5.6(Mariadb10.1)后新增了super_read_only選項(xiàng),但當(dāng)前版本中沒有這個(gè)選項(xiàng),所以報(bào)錯(cuò)。解決辦法是最后將MHA的版本換成mha4mysql-0.56