天天看點

Mysql雙機互備熱備,自動切換

作者:wdlinux http://www.wdlinux.cn QQ:12571192

歡迎轉載,轉載時請務必以超連結形式标明文章原始出處和作者資訊及本聲明。

Mysql雙機互備熱備

在實際的應用中,資料庫是非常重要和關鍵的一個環節。在保障資料庫安全的同時,提高應用性和縮短出故障後的恢複時間,也同等重要。特别是在一些持續性和實時性要求高的應用中,故障一小時,可能會讓你損失幾千到幾萬甚至更高。

本方案緻力于資料庫實時備份,并且在故障發生後以最短的時間恢複和修複

在mysql資料庫的備份應用中,主從複制結構是應用的比較廣泛,資料同步和實時性都很高,基本上能滿足大部分的需求。

本方案基于主從複制結構的基礎上,當主庫出現故障時,從庫能自動接管主庫的功能,向外提供服務,且将自身設定為主庫,将這個故障時間和影響縮短至最小,5秒内可切換完成。待原主庫修複後,會自動進入從庫的備份角色,如此循環。

在本方案的實作中,有兩種方法且均基于mysql的主從結構中

1 高可用(High Availability)HA叢集,用heartbeat實作及增加了故障後的恢複功能

2 同樣是高可用,隻是是自己編寫腳本程式來監控,切換,恢複

在方法1中,使用穩定的heartbeat開源軟體實作,但此方法,需要多一個IP對外通路,同時在監控上,是監控機器的狀态而不是mysql,有些情況下,機器是好的但mysql服務挂了,這種情況下就不準确了。不過可以修改監控方式或增加對mysql服務的監控

方法2中,可以不用增加一個對外IP,同時在監控上,可以直接監控mysql的服務,至于穩定性,有待測試。此方法中還有一個問題,就是提供給用戶端的資料庫連接配接IP,因為切換後,IP也就變了。如果說更改程式,那不現實。是以,這裡可以用域名,不過仍然需要修改域名的IP指向或是修改客戶機的hosts檔案。本文使用的是修改DNS的方法,因為DNS是自己配置的,可以靈活操作。

本方分兩部分進行說明

第一部分 用 heartbeat 實作的高可用

1環境條件

兩個虛拟機(IP:192.168.1.91/92/93),

CentOS5.4,mysql-5.1.37,heartbeat-2.1.3-3

2 安裝前的準備

Heartbeat 的工作原理:heartbeat最核心的包括兩個部分,心跳監測部分和資源接管部分,心跳監測可以通過網絡鍊路和序列槽進行,而且支援備援鍊路,它們之間互相發送封包來告訴對方自己目前的狀态,如果在指定的時間内未受到對方發送的封包,那麼就認為對方失效,這時需啟動資源接管子產品來接管運作在對方主機上的資源或者服務。更多請看官網http://linux-ha.org/HomePage

基礎系統的安裝,mysql的安裝(略)

軟體下載下傳

http://linux-ha.org/DownloadSoftware

Http://www.packetfactory.net/libnet

http://dev.mysql.com/downloads/mysql/5.1.html

3 安裝過程(heartbeat)

一般的軟體源碼安裝是./configure –prefix=path;make;make install,本文使用yum安裝

yum install heartbeat

yum install heartbeat-ldirectord

有一點要注意:heartbeat的監測,可以是網絡或序列槽,本文使用網絡也就是網卡

4 配置文檔及腳本

1) Heartbeat的三個配置檔案ha.cf,authkeys,haresources

Cat Ha.cf

debugfile /var/log/ha-debug

logfile /var/log/ha-log

logfacility local0

keepalive 2

deadtime 5

warntime 10

initdead 10

udpport 694

bcast eth0

auto_failback off

node mysqlm

node mysqls

respawn hacluster /usr/lib/heartbeat/ipfail

apiauth ipfail gid=haclient uid=hacluster

Cat authkeys

auth 1

1 crc

Cat haresources

mysqlm mysql_start1.sh IPaddr::192.168.1.93/32/eth0

2) mysql_start1.sh腳本

#!/bin/sh

# author:wdlinux

# url:http://www.wdlinux.cn

# description: mysql start

local_ip=192.168.1.91

mip=192.168.1.92

vip=192.168.1.93

mysql_in=/usr/local/mysqlm

mysql_bin=${mysql_in}/bin/mysql

mysql_user=root

mysql_port=3306

mysql_pass=12345

mysqld_start=/etc/rc.d/init.d/mysqldm

. /etc/rc.d/init.d/functions

function slave_to_master() {

echo "mysql to master from slave..."

$mysql_bin -u"${mysql_user}" -p"${mysql_pass}" -e "slave stop;"

log_file=$(${mysql_bin} -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e"show master status\G" | grep "File:" | a

wk -F ': ' '{printf $2}')

log_id=$(${mysql_bin} -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e"show master status\G" | grep "Position:" |

awk -F ': ' '{printf $2}')

$mysql_bin -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e "use ms_state;update ms_log set mlf='${log_file}',mlp

='${log_id}'"

echo "mysql server is master"

}

function master_to_slave {

echo "mysql to slave from master..."

if (${mysql_bin} -h"${vip}" -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e"show slave status" > /dev/null 2>&1)

then

log_file=$(${mysql_bin} -h"${vip}" -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e"use ms_state;select m

lf from ms_log\G" | grep "mlf:" | awk -F': ' '{printf $2}')

log_id=$(${mysql_bin} -h"${vip}" -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e"use ms_state;select mlp

from ms_log\G" | grep "mlp:" | awk -F': ' '{printf $2}')

$mysql_bin -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e "slave stop;CHANGE MASTER TO MASTER_LOG_FILE

= '${log_file}',MASTER_LOG_POS = ${log_id};slave start";

echo "mysql server is slave"

fi

}

case "$1" in

start)

slave_to_master

;;

stop)

master_to_slave

;;

*)

echo "Usage: mysql_start.sh {start|stop}"

echo "start is slave to master"

echo "stop is master to slave"

exit 1

esac

3) 同保證和記錄當主機由slave到master轉變時記錄目前master的檔案和位置,需要建一個資料庫和表來記錄

create database ms_state;

use ms_state;

create table ms_log(

id tinyint (1) unsigned not null auto_increment,

mlf varchar (20) not null default '',

mlp varchar (20) not null default '',

primary key (id)

);

insert into ms_log values (NULL,"test","123");

4) mysql的配置

在原本的配置裡加上,檔案my.cnf,主從一樣,ID要不同

log-bin=mysql-bin

binlog_format=mixed

server-id = 1

master-host = 192.168.1.92

master-user = msdata

master-password = pass

slave-skip-errors=all

replicate-do-db=test

replicate-ignore-db=mysql

replicate-ignore-db=ms_state

其它配置略

經測試,91,92重起關機都能自動切換,接管93的IP,且故障機恢複後都能自動進入備份狀态,且資料同步及時和一緻

第二部分 自己編寫腳本實作的高可用

一 監控實作原理

自己編寫腳本,實作的功能和heartbeat差不多,都是監控,切換等

對于監控,可以監控系統的狀态如ping,也可以監控mysql服務狀态(本文使用的方法)

二 實作腳本

除了用此腳本替換heartbeat外,其它的實作和配置同上

1 監控腳本 mysql_monitor.sh

#!/bin/bash

# author:wdlinux

# url:http://www.wdlinux.cn

# description:monitor shell of mysql

local_ip=192.168.1.92

rip=192.168.1.91

mysql_in=/usr/local/mysqlm

mysql_bin=${mysql_in}/bin/mysql

mysql_user=root

mysql_pass=12345

mysql_port=3306

st=0

while true;do

if (${mysql_bin} -h"${rip}" -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e "show master status" --connect_timeout=1 > /

dev/null 2>&1)

then

if (($st==0));then

/etc/rc.d/init.d/mysql_start1.sh stop

let st=$st+1

fi

else

for ((i=0;i<=3;i++));do

sleep 3

if (${mysql_bin} -h"${rip}" -u"${mysql_user}" -p"${mysql_pass}" -P"${mysql_port}" -e "show master status" --conne

ct_timeout=1 > /dev/null 2>&1)

then

break

else

if (($i==3));then

echo "slave to master"

/etc/rc.d/init.d/mysql_start1.sh start

###modify dns prg

exit

fi

fi

done

fi

sleep 3

done

将local_ip,rip作相應的修改,local_ip代表本機IP,rip為另一台機的IP

2 将監控腳本加入自啟動,随系統啟動,如

Echo “/etc/rc.d/init.d/mysql_monitor.sh &” >> /etc/rc.d/rc.local

此方法也可以增加一個對外服務IP,如ha實作的一樣,這樣就省去了修改域名IP等問題

但在腳本裡,需要增加監控,添加,删除IP的實作和功能

歡迎轉載,但請保留此資訊

http://www.wdlinux.cn/old/mysql_replicate_ha

繼續閱讀