MYSQL双机热备

来源:互联网 发布:有道云协作 知乎 编辑:程序博客网 时间:2024/06/10 21:50

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:111.168.1.10/11/12),

  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::111.168.1.12/32/eth0

 

  2) mysql_start1.sh脚本  3) 同保证和记录当主机由slave到master转变时记录当前master的文件和位置,需要建一个数据库和表来记录
  #!/bin/sh
  # author:wdlinux
  # url:http://www.wdlinux.cn
  # description: mysql start
  local_ip=111.168.1.10
  mip=111.168.1.11
  vip=111.168.1.12
  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的配置
  log-bin=mysql-bin
  binlog_format=mixed
  server-id = 1
  master-host = 111.168.1.11
  master-user = msdata
  master-password = pass
  slave-skip-errors=all
  replicate-do-db=test
  replicate-ignore-db=mysql
  replicate-ignore-db=ms_state

 

  其它配置略

  经测试,10,11重起关机都能自动切换,接管12的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=111.168.1.11
  rip=111.168.1.10
  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的实现和功能。

 

原创粉丝点击