生產環境中一臺mysql主機存在單點故障,因此咱們要確保mysql的高可用性,即兩臺MySQL服務器若是其中有 一臺MySQL服務器掛掉後,另一臺能立馬接替其進行工做。 MySQL的高可用方案通常有以下幾種: keepalived+雙主,MHA,PXC,MMM,Heartbeat+DRBD等,比較經常使用的是keepalived+雙主,MHA和PXC。 本節主要介紹了利用 keepalived 實現 MySQL 數據庫的高可用。 Keepalived+mysql雙主來實現MySQL-HA,我 們必須保證兩臺MySQL數據庫的數據徹底同樣,基本思路是兩臺MySQL互爲主從關係,經過Keepalived配置虛 擬IP,實現當其中的一臺MySQL數據庫宕機後,應用可以自動切換到另一臺MySQL數據庫,保證系統的高可 用。
1、配置兩臺MySQL主主同步
該過程的第一部分就是master記錄二進制日誌。在每一個事務更新數據完成以前,master在二日誌記錄這些改 變。MySQL將事務寫入二進制日誌。在事件寫入二進制日誌完成後,master通知存儲引擎提交事務。 下一步就 是slave將master的binary log拷貝到它本身的中繼日誌。首先,slave開始一個工做線程——I/O線程。I/O線程 在master上打開一個普通的鏈接,而後開始binlog dump process。Binlog dump process從master的二進制日 志中讀取事件,若是已經同步了master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日 志。 SQL slave thread(SQL從線程)處理該過程的後一步。SQL線程從中繼日誌讀取事件,並重放其中的事 件而更新slave的數據,使其與master中的數據一致。只要該線程與I/O線程保持一致,中繼日誌一般會位於OS 的緩存中,因此中繼日誌的開銷很小。 主主同步就是兩臺機器互爲主的關係,在任何一臺機器上寫入都會同 步。 若mysql主機開啓了防火牆,須要關閉防火牆或建立規則。
master1有關複製的配置以下:mysql
#開啓二進制日誌,修改server-id號 [root@mysql ~]# vim /etc/my.cnf log-bin=mysql-bin binlog_format=mixed server-id=1 relay-log=relay-bin relay-log-index=slave-relay-bin.index auto-increment-increment=2 auto-increment-offset=1 [root@mysql ~]# systemctl restart mysqld
master2有關複製的配置以下:sql
[root@mysql ~]# vim /etc/my.cnf log-bin=mysql-bin binlog_format=mixed server-id=2 relay-log=relay-bin relay-log-index=slave-relay-bin.index auto-increment-increment=2 auto-increment-offset=2 [root@mysql ~]# systemctl restart mysqld
注:master1和master2只有server-id不一樣和 auto-increment-offset不一樣。
注:master1和master2只有server-id不一樣和 auto-increment-offset不一樣。
注:master1和master2只有server-id不一樣和 auto-increment-offset不一樣。
mysql中有自增加字段,在作數據庫的主主同步時須要設置自增加的兩個相關配置:auto_increment_offset和 auto_increment_increment。 auto-increment-increment表示自增加字段每次遞增的量,其默認值是1。它的值 應設爲整個結構中服務器的總數,本案例用到兩臺服務器,因此值設爲2。 auto-increment-offset是用來設定數 據庫中自動增加的起點(即初始值),由於這兩能服務器都設定了一次自動增加值2,因此它們的起點必須得不一樣,這樣才能避免兩臺服務器數據同步時出現主鍵衝突。
注:能夠在my.cnf文件中添加「binlog_do_db=數據庫名」配置項(能夠添加多個)來指定要同步的數據庫 。
將master1設爲master2的主服務器 在master1主機上建立受權帳戶,容許在master2(192.168.171.145)主機上 鏈接數據庫
mysql> grant replication slave on *.* to rep@'192.168.171.%' identified by '123'; mysql> flush privileges; #查看master1的當前binlog狀態信息 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 610 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
在master2上將master1設爲自已的主服務器並開啓slave功能vim
mysql>change master to master_host='192.168.171.135',master_user='rep',master_password='123',master_log_file='mysql-bin.000001',master_log_pos=610; mysql>start slave; mysql>show slave status\G # 查看slave狀態,一下兩個進程必須爲yes Slave_IO_Running:Yes Slave_SQL_Running:Yes
標註:切記MySQL的UUID不要相同,這裏我是克隆的另外一個mysql因此作的過程當中報錯UUID相同致使兩個進程只有一個yes了,報錯信息以下緩存
Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
將master2設爲master1的主服務器 在master2主機上建立受權帳戶,容許在master1(192.168.171.135)主機上 鏈接bash
mysql>grant replication slave on *.* to rep@'192.168.171.%' identified by '123'; mysql>flush privileges; #查看master2的當前binlog狀態信息 mysql>show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000002 | 610 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
在master1上將master2設爲自已的主服務器並開啓slave功能服務器
mysql> change master to master_host='192.168.171.145',master_user='rep',master_password='123',master_log_file='mysql-bin.000002',master_log_pos=610; mysql> start slave; #查看salve狀態 mysql> show slave status\G Slave_IO_Running: Yes Slave_SQL_Running: Yes
測試主主同步 在master1上建立要同步的數據庫如test1,並在test1中建立一張測試表如tab1ide
mysql> create database test1; mysql> use test1; mysql> create table tab1(id int,name varchar(32)); #查看master2主機是否同步了master1上的數據變化 mysql>show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test1 | +--------------------+ 5 rows in set (0.00 sec) mysql>use test1; mysql>show tables; +-----------------+ | Tables_in_test1 | +-----------------+ | tab1 | +-----------------+ 1 row in set (0.00 sec) #能夠看出master2同步了master的數據變化 在master2主機上向tab1表中插入數據 mysql>insert into tab1 values(1,'tom1'); mysql>commit; #查看master1主機是否同步了master2上的數據變化 mysql> select * from tab1; +------+------+ | id | name | +------+------+ | 1 | tom1 | +------+------+ 1 row in set (0.00 sec)
如今任何一臺MySQL上更新數據都會同步到另外一臺MySQL,MySQL同步完成。 工具
注:若主MYSQL服務器已經存在,只是後期才搭建從MYSQL服務器,在置配數據同步前應先將主 MYSQL服務器的要同步的數據庫拷貝到從MYSQL服務器上(如先在主MYSQL上備份數據庫,再用備份 在從MYSQL服務器上恢復) oop
下面咱們就完成keepalived的高可用性。 keepalived是集羣管理中保證集羣高可用的一個軟件解決方案,其功 能相似於heartbeat,用來防止單點故障 keepalived是以VRRP協議爲實現基礎的,VRRP全稱Virtual Router Redundancy Protocol,即虛擬路由冗餘協議。 虛擬路由冗餘協議,能夠認爲是實現路由器高可用的協議,即 將N臺提供相同功能的路由器組成一個路由器組,這個組裏面有一個master和多個backup,master上面有一個 對外提供服務的vip,master會發組播(組播地址爲224.0.0.18),當backup收不到vrrp包時就認爲master宕掉 了,這時就須要根據VRRP的優先級來選舉一個backup當master。這樣的話就能夠保證路由器的高可用了。 keepalived主要有三個模塊,分別是core 、check和vrrp。core模塊爲keepalived的核心,負責主進程的啓動、 維護以及全局配置文件的加載和解析。check負責健康檢查,包括常見的各類檢查方式。vrrp模塊是來實現 VRRP協議的。
2、keepalived的安裝配置
在master1和master2上安裝軟件包keepalived 安裝keepalived軟件包與服務控制 在編譯安裝Keepalived以前,必須先安裝內核開發包kernel-devel以及openssl-devel、popt-devel等支持庫。
在兩臺master上進行以下操做
[root@mysql ~]# wget https://www.keepalived.org/software/keepalived-2.0.20.tar.gz [root@mysql ~]# yum -y install kernel-devel openssl-devel popt-devel [root@mysql ~]# tar zxf keepalived-2.0.20.tar.gz [root@mysql ~]# cd keepalived-2.0.20/ [root@mysql keepalived-2.0.20]# ./configure --prefix=/ && make && make install
注意:如不知道keepalived須要哪些依賴包,可到下載後的源碼解壓目錄下查看INSTALL 文件內容, 執行make install操做以後,會自動生成/etc/init.d/keepalived腳本文件,但還須要手動添加爲系統服務,這樣就可使用 service、chkconfig工具來對keepalived服務程序進行管理了。
修改Keepalived的配置文件 :
配置區域含義說明:
global_defs:主要是配置故障發生時的通知對象以及 機器標識。
vrrp_instance:用來定義對外提供服務的VIP區域及其相關屬性。
virtual_server:虛擬服務器定義
#master1上修改 [root@mysql ~]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { router_id mysql-1 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.171.200 } } virtual_server 192.168.171.200 3306 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.171.135 3306 { weight 1 notify_down /etc/keepalived/bin/mysql.sh TCP_CHECK { connect_port 3306 connect_timeout 3 retry 3 delay_before_retry 3 } } } [root@mysql /]# systemctl start keepalived
#將master1配置好的文件複製給master,稍加修改便可 [root@mysql /]# scp /etc/keepalived/keepalived.conf root@192.168.171.145:/etc/keepalived/ ! Configuration File for keepalived global_defs { router_id mysql-2 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 50 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.171.200 } } virtual_server 192.168.171.200 3306 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 60 protocol TCP real_server 192.168.171.145 3306 { weight 1 notify_down /etc/keepalived/bin/mysql.sh TCP_CHECK { connect_port 3306 connect_timeout 3 retry 3 delay_before_retry 3 } } } [root@mysql ~]# systemctl start keepalived
在兩臺master上進行以下操做:
[root@mysql ~]# mkdir /etc/keepalived/bin [root@mysql ~]# vim /etc/keepalived/bin/mysql.sh #!/bin/bash pkill keepalived #賦予執行權限 [root@mysql ~]# chmod +x /etc/keepalived/bin/mysql.sh
測試 在master1和master2分別執行ip addr show dev eth0命令查看master1和 master2對VIP(羣集虛擬IP)的控制權。
master1上:
master2上:
對比兩個圖能夠發現,VIP地址在master1上
中止MySQL服務,看keepalived健康檢查程序是 否會觸發咱們編寫的腳本 中止master1主機的mysql服務
master1:
master2: