1. 程式人生 > >初識MariaDB之7——MHA高可用

初識MariaDB之7——MHA高可用

mysql mariadb mha

一、背景介紹

在傳統的MySQL一主一從或一主多從結構中,主節點存在單點故障隱患,為了解決該故障,進而引入了MHA高可用的方式。MHA由manager和node兩部分組成,manager可以安裝在一個獨立的服務器上或非master角色的MySQL服務器上,1個manager可以管多個node集合,每一個master/node集群稱為一個application,所有集群可以使用一個配置文件或者為每個集群創建單獨的配置文件,目前MHA最少由3個主機組成

技術分享圖片技術分享圖片

二、實現原理

MHA是在MySQL主從復制基礎上實現的高可用,其實現原理是:

在正常情況下,MHA的manager節點對所有node節點周期性進行健康狀態檢測,當MySQL的master節點出現故障時,MHA的manager試圖從宕機的MySQL的master上將二進制日誌保存到本地,並與所有node節點的中繼日誌進行對比,將擁有最新同步狀態的slave主機提升為master主機,所有slave主機指向新的master主機。

技術分享圖片技術分享圖片

三、實驗環境

本次實驗采用CentOS7.4系統,數據庫版本5.5.56-MariaDB,MHA版本mha4mysql-manager-0.58。因為所有服務器之間要傳輸中繼日誌,並且還需要指定master,所有所有主機間要建立密鑰認證,master和candidate節點需要創建用於從服務器復制的二進制日誌的賬號,MySQL每個服務器都需要創建可以指定master的賬號,並且master和candidate節點不能開啟relay_log_purge選項,為了最大程度的保證數據的不丟失,建議將candidate配置成半同步形式。

MHA角色

MySQL角色

IP地址

開啟MySQL功能

manager

172.16.10.30/24

node

master

172.16.10.40/24

1.二進制日誌,中繼日誌

2.復制賬號,管理賬號

3.中繼日誌不能裁剪

4.半同步master插件

node/candidate

slave

172.16.10.50/24

1.二進制日誌,中繼日誌

2.復制賬號,管理賬號

3.中繼日誌不能裁剪

4.半同步slave插件

5.只讀模式

node

slave

172.16.10.60/24

1.中繼日誌

2.只讀模式

技術分享圖片技術分享圖片

四、準備操作

既然是集群時間同步和名稱解析就需要提前完成,此處不過多介紹

1.所有主機互信

可以在一個主機生成一對密鑰,將這對密鑰和know_hosts文件拷貝給其余主機的方式,不需要所有主機都生成密鑰對相互拷貝

[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 [email protected]:/root/.ssh/

[root@host3 .ssh]# scp -r id_rsa known_hosts [email protected]:/root/.ssh/

[root@host3 .ssh]# scp -r id_rsa known_hosts [email protected]:/root/.ssh/

2.安裝Mariadb數據庫

[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主機操作

(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)啟動並進入MySQL

[root@host4 ~]# systemctl start mariadb.service

[root@host4 ~]# mysql

(3)創建用於主從復制和管理數據庫的賬號

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)確定當前binlog日誌及position

MariaDB [(none)]> show master status;

+---------------------+----------+--------------+------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+---------------------+----------+--------------+------------------+

| mysql-binlog.000003 | 610 | | |

+---------------------+----------+--------------+------------------+

4.Candidate主機操作

(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)啟動並進入MySQL

[root@host5 ~]# systemctl start mariadb.service

[root@host5 ~]# mysql

(3)創建用於主從復制和管理數據庫的賬號

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)指定主服務器及主服務器當前的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)啟動從節點

MariaDB [hellodb]> start slave [IO_THREAD | SQL_THREAD];

(7)查看從節點狀態(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主機操作

(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)啟動並進入MySQL

[root@host6 ~]# systemctl start mariadb.service

[root@host6 ~]# mysql

(3)創建用於管理數據庫的賬號

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)指定主服務器及主服務器當前的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)啟動從節點

MariaDB [hellodb]> start slave [IO_THREAD | SQL_THREAD];

(6)查看從節點狀態(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高可用實現

1.安裝MHA軟件

(1)主節點

[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環境檢測工具;

-masterha_check_repl:MySQL復制環境檢測工具;

-masterha_manager:MHA服務主程序;

-masterha_check_status:MHA運行狀態探測工具;

-masterha_master_monitor:MySQL master節點可用性檢測工具;

-masterha_master_switch:master節點切換工具;

-masterha_conf_host:添加或刪除配置的節點;

-masterha_stop:關閉MHA服務的工具;

(2)從節點

[root@host4 mha]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y

-save_binary_logs:保存和復制master的二進制日誌;

-apply_diff_relay_logs:識別差異的中繼日誌事件並用於其他slave;

-fiter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已不再使用這個工具);

-purge_relay_logs:清除中繼日誌(不會阻塞SQL線程);

2.在MHA的Manager節點創建配置文件並檢測

[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

此時的警告忽略,MHA可以使用--global_conf選項為多個application指定相同的配置

技術分享圖片技術分享圖片

3.啟動並查看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節點故障

(1)關閉master節點的MySQL服務

[root@host4 ~]# mysqladmin -uroot shutdown

(2)在Manager節點查看此時狀態

[root@host3 ~]# masterha_check_status --conf=/etc/mha/app1.conf

app1 is stopped(2:NOT_RUNNING).

當由node節點出現故障時MHA會自動關閉,故障節點恢復後,不會自動啟動

(3)查看Candidate節點狀態

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 |

+---------------+-------+

能夠發現Candidate節點已經升級為Master節點,並且read_only選項也自動關閉(盡管配置文件中該選項還存在)

(4)slave節點查看狀態

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.恢復故障主機

(1)將故障修復後的主機上線

(2)修改my.cnf文件,加入read_only=ON選項

(3)使用mysqldump等備份工具對當前master主機上的數據庫進行備份

(4)使用備份在故障主機上恢復,啟動MySQL服務,再指定新的Master主機和binlog,如果宕機的是半同步的master主機,還需要調換半同步的master和slave角色,並且重啟IO_thread

(5)在MHA的manager節點上重啟MHA

補充說明

MHA檢查復制狀態時出現如下報錯:

[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版本中雖然從節點設置了read_only選項,但是對於管理員權限的用戶這點不生效,所以在MySQL5.6(Mariadb10.1)後新增了super_read_only選項,但當前版本中沒有這個選項,所以報錯。解決辦法是最後將MHA的版本換成mha4mysql-0.56


初識MariaDB之7——MHA高可用