一、综述
数据库位于现代企业应用的核心,它储存了组织机构中最有价值的资产,包括客户信息、产品信息、订单信息和历史数据。另外,组织机构依赖于数据库来运行他们 关键业务应用。几小时甚至是几分钟的宕机,往往会造成收入的大量流失和客户的不满。因此,保证数据库高可用是所有组织机构优先考虑的事情。对于希望在当今 瞬息万变的经济环境立于不败之地并取得成功的企业来说,构建一个具有高可用性的IT 基础架构至关重要。
二、完成目标 通过技术手段实现mysql数据库的高可用性,从而减少停工时间保证服务的正常稳定运行。
三、方案建设概要
1、现有高可用方案分析
Mysql作为一款开源软件经过多年的发展,已经形成很多套实现高可用方案,并且均都投入生产使用,主要为这几种:mysql + replication 、mysql + heartbeat + 存储、mysql + drbd + heartbeat 、mysql cluster。以下将依次对各个方案进行分析。
Mysql的复制(Replication)是一个异步的复制,从一个Mysql instace(称之为Master)复制到另一个Mysql instance(称之Slave)。实现整个复制操作主要由三个进程完成的,其中两个进程在Slave(Sql进程和IO进程),另外一个进程在Master(IO进程)上。
2.2 Mysqlreplication方案拓扑图
Mysql+replication主从复制拓扑图
方案具体解释:
要实施复制,首先必须打开Master端的binary log(bin-log)功能,否则无法实现。因为整个复制过程实际上就是Slave从Master端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。
2.3 Mysql+replication优缺点优点:易实施、成本低、经济实惠、后期维护方便,且由于整套系统架构简单,不涉及到存储及双机软件,因此系统出现故障率很低。方便做到读写分离。
缺点:在主机出现问题后不能自动切换到备份机,需要人工干涉更改IP地址。
3.1 概述
HA双机热备软件将操作环境推广到一种群集操作系统。群集是一种松散耦合的计算节点集合,提供网络服务或应用程序(包括数据库、web 服务和文件服务)的单一客户视图。
HA双机热备软件的目标是:
1:减少或消灭由软件或硬件故障引起的系统停机时间
2:提供增强的系统可用性,能够不必关掉整个群集就可执行维护
3.2 Mysql+heartbeat方案拓扑图
方案具体解释:
本方案采用高可靠性的HA双机热备软件来保证邮件服务的高稳定性及连续性。默认情况下两台mysql机器只有一台机器在工作,当工作机mysql主机出现问题后,系统将自动切换到mysql备机上继续提供服务,而整个过程只需要30秒的时间,当mysql主机故障维修完毕后,服务将自动切换回mysql主机上继续提供服务。
3.3 Mysql+heartbeat优缺点优点:安全性、稳定性高,出现故障系统将自动切换,从而保证服务的连续性。
缺点:相对mysql replication成本提高,需要有存储设备,同时由于多了存储设备及双机软件。
4、Mysql+drbd+heartbeat
4.1 概述
此方案除了刚刚介绍完的heartbeat外,主要用了DRBD这个工具,DRBD是一种块设备,可以被用于高可用(HA)之中.它类似于一个网络RAID-1功能.当你将数据写入本地文件系统时,数据还将会被发送到网络中另一台主机上.以相同的形式记录在一个文件系统中.
本地(主节点)与远程主机(备节点)的数据可以保证实时同步.当本地系统出现故障时,远程主机上还会保留有一份相同的数据,可以继续使用.
4.3 Mysql+drbd+heartbeat优缺点优点:安全性、稳定性高,出现故障系统将自动切换,从而保证服务的连续性,相对mysql+heartbeat+存储来说对大优点是节约了存储这个硬件设备。
缺点:mysql主机宕机,切换到备机,备机接管服务,待主机修复完配置failback机制的话会发生脑裂情况,需要手工执行命令进行主机接管。
5、Mysqlcluster
5.1 概述
MySQL集群是一种分布式设计,目标是要达到没有任何单点故障点。因此,任何组成部分都应该拥有自己的内存和磁盘。任何共享存储方案如网络共享,网络文件系统和SAN设备是不推荐或不支持的。通过这种冗余设计,MySQL声称数据的可用度可以达到99。999%。
5.3 Mysqlcluster优缺点优点:安全性、稳定性高,可以在线增加节点,官方声称可用度可达到99.999%。
缺点:至少三个节点,对主机的数量又要求,无形增加方案成本、对于数据节点要求内存一直、对于引擎只能使用ndb、不支持外键功能、管理复杂
四、Mysql+heartbeat+存储方案具体实施步骤环境:
nfs:192.168.184.103 as4u7
主机-cm5.3:192.168.184.124 10.0.0.1
备机-as5u3:192.168.184.102 10.0.0.2
注意:关闭防火墙,selinux
第一块:nfs的搭建(在192.168.184.103上面)
[root@oracle ~]# vi /etc/exports
/data 192.168.184.*(rw,sync,no_root_squash)
[root@oracle ~]# service nfs start
[root@oracle ~]# exportfs -rv
#####################################################################
第二块:mysql的安装(主备机一样)
# tar -zxvf mysql-5.0.67.tar.gz
# cd mysql-5.0.67
# groupadd mysql
# useradd -g mysql -s /sbin/nologin -M mysql
# ./configure –prefix=/usr/local/mysql (至于编译参数很多,这里不枚举)
# make && make install
# cp support-files/my-large.cnf /etc/my.cnf
# cp support-files/mysql.server /etc/rc.d/init.d/mysqld
# chmod 755 /etc/rc.d/init.d/mysqld
加入服务队列:
# chkconfig –add mysqld
# chown -R mysql.mysql /usr/local/mysql/
# /usr/local/mysql/bin/mysql_install_db –user=mysql
# chown -R mysql.mysql /usr/local/mysql/var
# /usr/local/mysql/bin/mysqld_safe –user=mysql &
*************************************************************************
配置库文件搜索路径
# echo “/usr/local/mysql/lib/mysql” >> /etc/ld.so.conf
# ldconfig
添加/usr/local/mysql/bin到环境变量PATH中
#echo “export PATH=$PATH:/usr/local/mysql/bin” >> /etc/profile
#source /etc/profile
**************************************************************************
在执行第三步之前,为了确保mysql+nfs的能否成功执行,可以先测试一下,我这里是这么做的,①停掉原
先的mysql。②先在主机上面把nfs挂上来挂到/data目录,③然后mv /usr/local/mysql/var /data/里面去
,④然后起mysql服务,看能不能起来,然后往里面建库建表,再用备机挂nfs看主机建的库和表是否存在,
这么来回测试。测试完就可以确定mysql+nfs是ok的了。底下出错专心找heartbeat的问题。
#######################################################################
第三块:heartbeat的安装(主备机一样,唯独ha.cf里面的ucast那条信息)
tar -zxvf libnet.tar.gz
cd libnet
./configure
make && make install
tar -zxvf heartbeat-2.1.3.tar.gz
cd heartbeat-2.1.3
groupadd haclient
useradd -g haclient hacluster
./ConfigureMe configure
make && make install
配置双机文件,一共需要三个文件(手工配置就行)–ha.cf、haresources、authkeys
# cd /etc/ha.d
[root@cm5 ha.d]# vi ha.cf
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility local0
keepalive 2
deadtime 30
warntime 10
initdead 120
auto_failback on
node as5u3
node cm5.3
udpport 694
ucast eth0 10.0.0.2
ping_group group1 192.168.184.102 192.168.184.124
respawn hacluster /usr/lib/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster
hopfudge
[root@cm5 ha.d]# vi haresources
cm5.3 IPaddr::192.168.184.200/24/eth0Filesystem::192.168.184.103:/data::/data::nfs mysqld
[root@cm5 ha.d]# vi authkeys
auth 1
1 crc
[root@cm5 ha.d]# chmod 600 authkeys
##########################################################
第四步:测试
1、先停掉主备机的上面的mysql,卸掉nfs的挂载。
2、/etc/init.d/heartbeat start (主备机双执行)
3、可以看到主机的虚ip已经起来了、nfs也挂上来了、mysql服务也已经起来了(其实他们的起来的顺序也
是这样的,释放资源是反顺序,可以看/var/log/ha-log日志)
4、主机上写表,断掉主机的网卡,主机释放资源,备机起来,所有的都在
5、主机网卡起来,资源从备机释放。
********************************************************************************************************************************************************************
第五步:意外情况
上面能成功那是因为我的表格式是myisam的。但是用innodb却是不成功的,主机把网卡断了,备机mysql起不来。刚开始以为是inndb的原因,后来才知道是nfs的锁!!!! (下面的是报错日志)
/var/log/mysql.log
InnoDB: Unable to lock ./ibdata1, error: 11
InnoDB: Check that you do not already have anothermysqld process
InnoDB: using the same InnoDB data or log files.
/var/log/ha-log
ResourceManager[25602]: 2010/07/16_18:13:10 info:Running /etc/init.d/mysqld start
ResourceManager[25602]: 2010/07/16_18:13:41 ERROR:Return code 1 from /etc/init.d/mysqld
ResourceManager[25602]: 2010/07/16_18:13:41 CRIT:Giving up resources due to failure of mysqld
解决思路:
1.修改了mysql.sock文件存放的路径不能全部放在共享的分区里面。(修改my.cnf)
2.既然修改mysql.sock路径就得修改启动脚本的里面的配置,详情见最后。
3.修改/etc/ha.d/haresource-------test1 IPaddr::192.168.122.13/24/eth0 nfsmysqld
4.在/etc/ha.d/resource.d/里面添加了一文件nfs ,主要作用就是设置nfs的mount
[root@test2 resource.d]# more nfs
#!/bin/sh
unset LC_ALL; export LC_ALL
unset LANGUAGE; export LANGUAGE
case “$1″ in
‘start’)
/bin/mount -onolock 192.168.122.12:/data /var/lib/mysql
;;
‘pre-start’)
;;
‘post-start’)
;;
‘stop’)
/bin/umount /var/lib/mysql
;;
‘pre-stop’)
;;
‘post-stop’)
;;
*)
echo “Usage: $0 { start | pre-start | post-start| stop | pre-stop | post-stop }”
;;
esac
exit 0
5.测试
我写了一个测试脚本,脚本意思通过建立log表,不断往里面的插数据,数据的顺序依次是0、1、2……10000。
[root@test1 ~]# more test.sh
#!/bin/bash
i=0
while [ $i -lt 10000 ]
do
mysql --socket=/tmp/mysql.sock -e “insert intocm.log values (“$i”)”;
let i=i+1
echo “add $i to table log”
done
此时在主机上面执行这个脚本,如下所示开始往数据库的log表里面插入数据了
[root@test1 ~]# ./test.sh
add 1 to table log
add 2 to table log
add 3 to table log
add 4 to table log
add 5 to table log
add 6 to table log
……
add 2026 to table log
到了插入到第2026的时候,断开主机的网卡。
查看备机mysql的log日志,看到备机的mysql的会有一个inndb检查修复的操作。很快备机的mysql服务就起来了。
[root@test2 ~]#tail –f /var/log/mysql.log
100716 22:12:23 mysqld started
100716 22:12:23 InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibdfiles...
InnoDB: Restoring possible half-written data pagesfrom the doublewrite
InnoDB: buffer...
100716 22:12:24 InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 17445609.
InnoDB: Doing recovery: scanned up to log sequencenumber 0 17451961
100716 22:12:25 InnoDB: Starting an apply batch of log records to the database...
InnoDB: Progress in percents: 29 30 31 32 33 34 35 3637 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 6263 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 8889 90 91 92 93 94 95 96 97 98 99
InnoDB: Apply batch completed
100716 22:12:25 InnoDB: Started; log sequence number 017451961
100716 22:12:25 [Note] /usr/libexec/mysqld:ready for connections.
Version: ’5.0.45′ socket: ‘/tmp/mysql.sock’ port: 3306 Source distribution
在进入到备机的mysql,查看log表里面的数据一共有2027条,正截止到我们在断开主机执行到的数字2026。
[root@test2 resource.d]# mysql --socket=/tmp/mysql.sock -e “select count(*) from cm.log”;
+----------+
| count(*) |
+----------+
| 2027 |
+----------+