mysql高可用集群部署方案(mha+atlas+keepalived)

一、mysql高可用前提

       在许多比较重要的系统中,基本上都是24h*365d不间断运行的。

  对于应用程序来讲,可以做haproxy+app 或 nginx+app的集群。好,问题来了,当应用程序的性能调优后,那么瓶颈就卡在数据库上。这个时候,就要对数据库进行优化。

  在进行去IOE后,基本上许多的数据库都采用的是开源的mysql数据库。

  当并发较高或数据量比较大的时候,数据库的瓶颈就会成为制约应用的关键。此时,我们会通过做mysql主从机读写分离(主节点master负责写,从节点slave负责读),再对主机进行双机热备(当主节点宕机后,自动切换到另一备用节点上),对从节点做集群(读取数据分离到不同的节点上,以减小读数据库的压力)。

  这里在做主从读写分离是用qihoo的atlas。在mysql做故障转移是用mha。对数据库主备节点做故障切换则是用keepalived。

  高可用性

       很多公司的服务都是24小时*365天不间断的。这就要求高可用性。再比如购物网站,必须随时都可以交易。那么当购物网的server挂了一个的时候,不能对业务产生任何影响。这就是高可用性。

  当服务器down掉,或者出现错误的时候,可以自动的切换到其他待命的服务器,不影响服务器上App的运行。


    读写分离

       随着一个网站的业务不断扩展,数据不断增加,数据库的压力也会越来越大,对数据库或者SQL的基本优化可能达不到最终的效果,我们可以采用读写分离的策 略来改变现状。

  读写分离简单的说是把对数据库读和写的操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力。主数据库提供写操作,从数据库提 供读操作,其实在很多系统中,主要是读的操作。当主数据库进行写操作时,数据要同步到从的数据库,这样才能有效保证数据库完整性。

二、mysql高可用软件概述


    MySQL高可用性大杀器之MHA

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于 Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在 0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

  该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其 他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

  在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器 硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最 新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

  目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。


    读写分离利器atlas

       现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库。

  Master库负责数据更新,Slave库当然负责非实时数据查询。

  因为在实际的应用中,数据库都是读多写少(读取数据的频率高,更新数据的频率相对较少),而读取数据通常耗时比较长,占用数据库服务器的CPU较多,从而影响用户体验。

  我们通常的做法就是把查询从主库中抽取出来,采用多个从库,使用负载均衡,减轻每个从库的查询压力。

  采用读写分离技术的目标:有效减轻Master库的压力,又可以把用户查询数据的请求分发到不同的Slave库,从而保证系统的健壮性。

  我们看下采用读写分离的背景。随着网站的业务不断扩展,数据不断增加,用户越来越多,数据库的压力也就越来越大,采用传统的方式。

  比如:数据库或者SQL的优化基本已达不到要求,这个时候可以采用读写分离的策 略来改变现状。

  常见实现读写分离的方法:

  1. 开发在代码中写死 #指定修改操作,连接的是主库。查询操作,连接的是从库

  2. 第三方工具实现 AtlascobarTDDLmysql-proxy阿米巴

  3. 我们这套架构中的读写分离是使用Atlas实现的,Atlas是由 Qihoo 360 Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。

  它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。

  目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。

  主要功能:

    a.读写分离

  b.从库负载均衡

  c.IP过滤

  d.SQL语句黑白名单

  e.自动分表

高可用Keepalived

   keepalived是一款c语言写的实现在linux系统上实现负载均衡和高可用的软件。它遵从于GNU是一款优秀的开源软件。keepalived观其名可知,保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,用来防止单点故障的发生。


    负载均衡

  keepalived内置了对ipvs函数的调用支持。可以直接在keepalived中按照语法配置ipvs然后keepalived就可以实现对ipvs的配置。


    高可用

  keepalived是以VRRPVirtual Router Redundancy Protocol协议为实现基础的即虚拟路由冗余协议。虚拟路由冗余协议可以认为是实现路由器高可用的协议即将N台提供相同功能的路由器组成一个路由器组这个组里面有一个master和多个backupmaster上面有一个对外提供服务的vip该路由器所在局域网内其他机器的默认路由为该vipmaster会发组播当backup收不到vrrp包时就认为master宕掉了这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。


    本套架构中keepalive的作用

  由于mysql+replication方案中master和slave的关系是一对多的关系,整个系统中只有一个master节点(写入节点),多个slave节点,那么master节点一旦down机后,整个系统的数据写入操作将瘫痪,对系统造成严重后果。为此引入了keepalive工具,让这个系统的master和slave关系是多对多的关系,对master节点进行双机热备,以达到整个系统的高可用性。其中keepalive工具负责对两个master节点进行不间断监听,一旦工作中的master节点停止工作后,那么备份master节点就会接管 ,让这个系统正常工作。向外提供一个虚拟ip以供proxy访问master,虚拟ip对应了两个实ip的maser节点。

三、mysql高可用架构


    本次架构实现功能

  1. 一主库,两个从库(其中1个为备主),实现ABB复制
  2. 使用Atlas实现读写分离,主库和备主库接收写操作,从库接收读操作
  3. 使用Mha实现现有架构的高可用
  4. 使用keepalived实现vip的漂移
  5. 手工编写shell,修复Mha的不足
  6. 修复当AB故障切换一次后,mha-manager会自动退出
  7. 修复原主库,出问题后,修复后不能自动加入现有AB集群
  8. 关于relay log的清除


    本次实现架构图

       ip划分

主机ip os 安装软件 vip
192.168.10.189 centos 6.7 mysql master 、keepalived 192.168.10.240
192.168.10.190 centos 6.7 mysql slave(master) 、keepalived 192.168.10.240
192.168.10.166 centos 6.7 mysql slave
192.168.10.192 centos 6.7

mha、atlas

   架构图 

mysql高可用集群部署方案(mha+atlas+keepalived)_第1张图片

 四、mysql数据库安装

1、先检查系统是否装有mysql

rpm -qa | grep mysql

 这里返回空值,说明没有安装

这里执行安装命令是无效的,因为centos-7默认是Mariadb,所以执行以下命令只是更新Mariadb数据库;

yum install mysql

删除可用

yum remove mysql

2、下载mysql的repo源

# wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm

安装mysql-community-release-el7-5.noarch.rpm包

# sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm

 安装这个包后,会获得两个mysql的yum repo源:/etc/yum.repos.d/mysql-community.repo,/etc/yum.repos.d/mysql-community-source.repo

 3、安装mysql

# sudo yum install mysql-server

根据步骤安装就可以了,不过安装完成后,没有密码,需要重置密码。

安装后再次查看mysql

 如果报错,内容含有

Error: Package: mysql-community-libs-5.6.35-2.el7.x86_64 (mysql56-community)
           Requires: libc.so.6(GLIBC_2.17)(64bit)
Error: Package: mysql-community-server-5.6.35-2.el7.x86_64 (mysql56-community)
           Requires: libc.so.6(GLIBC_2.17)(64bit)
Error: Package: mysql-community-server-5.6.35-2.el7.x86_64 (mysql56-community)
           Requires: systemd
Error: Package: mysql-community-server-5.6.35-2.el7.x86_64 (mysql56-community)
           Requires: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
Error: Package: mysql-community-client-5.6.35-2.el7.x86_64 (mysql56-community)
           Requires: libc.so.6(GLIBC_2.17)(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

解决:

#yum install glibc.i686
# yum list libstdc++*

4、重置密码

重置密码前,首先要登录

# mysql -u root

登录时有可能报这样的错:ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2),原因是/var/lib/mysql的访问权限问题。下面的命令把/var/lib/mysql的拥有者改为当前用户:

# sudo chown -R openscanner:openscanner /var/lib/mysql

如果报chown: 无效的用户: "openscanner:openscanner"错误,更换命令,并用 ll 查看目录权限列表

chown root /var/lib/mysql/

附:
① 更改文件拥有者 (chown )
[root@linux ~]# chown 账号名称 文件或目录
② 改变文件的用户组用命令 chgrp
[root@linux ~]# chgrp 组名 文件或目录
③ 对于目录权限修改之后,默认只是修改当前级别的权限。如果子目录也要递归需要加R参数
Chown -R : 进行递归,连同子目录下的所有文件、目录

chmod -777 -R 文件路径

然后,重启服务:

service mysqld restart

为root添加远程连接的能力。链接密码为 “root”(不包括双引号)

mysql> GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "root";  

6、查询数据库编码格式,确保是 UTF-8

show variables like "%char%";

需要修改编码格式为UTF-8,导入数据库sql的时候,请确保sql文件为utf8编码
进入mysql命令行后 输入

set names utf8;

7、开放3306端口号
firewalld 防火墙(centos-7)运行命令,并重启:

firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload

iptables 防火墙(centos6.5及其以前)运行命令

vim /etc/sysconfig/iptables

在文件内添加下面命令行,然后重启

-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT

8、添加系统路径
# vim /etc/profile
添加:
export PATH=/usr/local/mysql/bin:$PATH
如下:

mysql高可用集群部署方案(mha+atlas+keepalived)_第2张图片

# source /etc/profile

9、配置mysql自动启动
# chmod 755 /etc/init.d/mysql
# chkconfig --add mysql
# chkconfig --level 345 mysql on

补充:

--退出mysql命令窗口

#exit

 --查看mysql状态

#service mysql status

--停止mysql

#service mysql stop

--启动mysql

#service mysql start

五、mysql主从复制


MySql AB复制

  AB复制又称主从复制,实现的是数据同步。如果要做MySQL AB复制,数据库版本尽量保持一致。如果版本不一致,从服务器版本高于主服务器,但是版本不一致不能做双向复制。

MySQL AB复制有什么好处呢?

  • 解决宕机带来的数据不一致,因为MySQL AB复制可以实时备份数据。

  • 减轻数据库服务器压力,这点很容易想到,多台服务器的性能一般比单台要好。

AB复制主要通过2个线程实现:

  • I/O线程:从主库上把bin-log下载到从库后,放到从库的Relay-log中。(从库中的)

  • SQL线程:把Relay-log中的动作,在从库上做一次。(从库中的)AB复制的3个主要步骤

  • 主服务器把数据更改记录到二进制日志中,这个操作叫做二进制日志事件。

  • 从服务器把主服务器的二进制日志事件拷贝到自己的中继日志(relay log)中。

  • 从服务器执行中继日志中的事件,把更改应用到自己的数据上。

修改主库和从库的参数文件(/etc/my.cnf)

主库:192.168.10.189

#[mysqld]标签下追加
 
#表示是本机的序号为1,一般来讲就是master的意思
server_id =1
#服务器在关闭它之前在一个连接上等待行动的秒数。
wait_timeout=360000 
#开启Binlog日志
log-bin=binlog 
#开启Binlog日志的索引文件
log-bin-index=binlog.index 
#表示slave将复制事件写进自己的二进制日志
log_slave_updates=1 
#当每进行1次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘
sync-binlog = 1 
#表示自增长字段从那个数开始,他的取值范围是1 .. 65535
auto_increment_offset = 2 
#表示自增长字段每次递增的量,其默认值是1,取值范围是1 .. 65535
auto_increment_increment = 2

从库1:192.168.10.190(备主)

#[mysqld]标签下追加
#是否自动清空不再需要中继日志时,0不启动
relay_log_purge=0 
server_id =2
#服务器在关闭它之前在一个连接上等待行动的秒数。
wait_timeout=360000 
#开启Binlog日志
log-bin=binlog 
#开启Binlog日志的索引文件
log-bin-index=binlog.index
#表示slave将复制事件写进自己的二进制日志
log_slave_updates=1 
#当每进行1次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘
sync-binlog = 1 
#表示自增长字段从那个数开始,他的取值范围是1 .. 65535
auto_increment_offset = 1 
#表示自增长字段每次递增的量,其默认值是1,取值范围是1 .. 65535
auto_increment_increment = 2 

从库2:192.168.10.166(所有从库的操作都一样)

此时配置文件中:relay_log、relay_log_index后面配置的文件夹可能会报错找不到,

解决方案:1、配置mysql访问此文件夹的权限;

                2、

  • 修改:relay-log=relay-log
  • 修改:relay-log-index=relay-log.index
#[mysqld]标签下追加
 #只读操作控制
read_only=1
 #是否自动清空不再需要中继日志时,0不启动
relay_log_purge=0
server_id = 3
#定义relay_log的位置和名称
relay_log = /usr/local/mysql/mysql-relay-bin 
#定义relay_log的索引文件位置和名称
relay_log_index=/usr/local/mysql/mysql-relay-bin.index 
#服务器在关闭它之前在一个连接上等待行动的秒数。
wait_timeout=360000

主库

#创建用AB复制所需的用户
mysql> GRANT replication slave ON *.* TO 'xtgss'@'%' identified by 'Xtgss@123';
mysql> flush privileges;

所有从库 #如果从库以前有数据,要干掉原有数据,保持从库是干净的

service mysql stop #停止Mysql服务
cd /var/lib/mysql/data #进入数据目录
rm -fr 数据库目录 #删除数据库目录
service mysql restart #启动Mysql服务

主库 #主库的数据导出,并导入所有从库,保持数据一致

#主库导出数据
mysqldump -u root -pmysql m >/tmp/full.sql 
#主库导出的数据通过scp传送到所有从库
scp /tmp/full.sql root@从库IP:/tmp/

所有从库 #导入主库传过来的数据

#导入主库传递过来的数据
1mysql -u root -pmysql m < /tmp/full.sql

主库 #为主库加上只读锁,查看当前Binlog日志情况

mysql> flush tables with read lock; #给主库加上读锁
mysql> show master status; #查看Bin-log状态
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000001 | 402 | | | |
+---------------+----------+--------------+------------------+-------------------+
mysql>unlock tables; #给主库解锁

所有从库 #向主库做同步操作,开启AB复制

#向主库做同步操作
mysql> change master to master_host='主库IP', master_port=主库端口, master_user='同步用户', master_password='同步用户的密码', master_log_file='主库Binlog',master_log_pos=主库Binlog位置; 
#启动AB复制
mysql> start slave; 

所有从库 #查看AB复制的状态

mysql> show slave status \G
Slave_IO_Running: Yes #I/O线程状态OK
Slave_SQL_Running: Yes #SQL线程状态OK
Seconds_Behind_Master: 0 #同步效率非常好,没有延迟

主库 #模拟产生数据

mysql> create database slave; #创建数据库
mysql> use slave; #选择数据库
mysql> create table a(a int); #创建表
mysql> insert into a values(1); #插入数据
mysql> insert into a values(2); #插入数据

所有从库 #查看数据同步状态

mysql> show databases; #查看当前有哪些数据库(主库新建的slave库同步过来了)
mysql> use slave; #选择数据库
mysql> select * from a; #查看a表数据

如果从库的同步进程停止了,主库的操作还会往从库中同步吗?会丢数据吗?

所有从库 #模拟服务出现问题

service mysql stop #停止mysql服务,模拟从库出现问题

主库 #从库出现问题,此期间主库正常操作

use slave; #选择数据库
insert into a values(3); #插入数据
insert into a values(4); #插入数据

所有从库 #问题解决,查看有没有丢数据

service mysql start #启动Mysql服务
mysql >use slave; #选择数据库
mysql >select * from a; #数据自动同步过来了,主库的数据没有丢失

上面的结果说明了,从库中肯定保存着主库相关的配置:

/var/lib/mysql/data/master.info

安装可能出现问题汇总

1、mysql主从复制异常Slave_IO_Running: NO

 原因一:mysql5.6以上版本使用唯一uuid表示符,数据迁移是使用的物理备份,uuid会重复,修改uuid不一致即可

vim /var/lib/mysql/auto.cnf 
[auto]
server-uuid=85dba00a-e0ef-11e9-b341-000c29812345
# 任意修改几位,重启mysql

原因二 确认server-id 是否唯一, mysql 有可能并没有加载my.cnf 文件中的server-id

# 修改/etc/my.cnf
server-id=3  #主从要不一致

mysql>  show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 3     |
+---------------+-------+

mysql> set global server-id=3; # 如果与my.cnf中设置的不一样,请修改一致
# 重启mysql

原因三 :这种原因有可能是主库重启造成的二进制文件位置从库于主库不一致

解决: 需要手动将这些文件二进制日志mysql-bin.00000x,mysql-bin.index删除,rm -rf 掉 在重启数据库

六、atlas读写分离


下载atlas

把所有的软件包放在 /home/soft/ 目录下

地址:Releases · Qihoo360/Atlas · GitHubA high-performance and stable proxy for MySQL, it is developed by Qihoo's DBA and infrastructure team - Releases · Qihoo360/Atlashttps://github.com/Qihoo360/Atlas/releases

安装 

rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
#查看Atlas安装的详细路径
rpm -ql Atlas
 
grep -v '^#' /usr/local/mysql-proxy/conf/test.cnf |grep -v '^$' > /usr/local/mysql-proxy/conf/xtgss #过滤配置文件中的乱码,重写向到lipengfei文件
mv test.cnf test.cnf.old #备份test.cnf文件
cat /usr/local/mysql-proxy/conf/xtgss > /usr/local/mysql-proxy/conf/test.cnf 
#将lipengfei文件输入,重定向到test.cnf
/usr/local/mysql-proxy/bin/encrypt mysql 
#mysql是我root用户的密码,把密码加密,加密后:TWbz0dlu35U=

修改Atlas配置文件

[mysql-proxy]
 
plugins=admin,proxy
#带#号的为非必需的配置项目
 
#管理接口的用户名
admin-username = admin
 
#管理接口的密码
admin-password = admin
 
#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔,vip
proxy-backend-addresses = 192.168.10.240:3306
 
#Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
proxy-read-only-backend-addresses = 192.168.10.166:3306,192.168.10.190:3306
 
#用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码!
pwds = xtgss:JV0U7WaQ4KGTZ6zxvGQr9A==
 
#设置Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
daemon = true
 
#设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
keepalive = true
 
#工作线程数,对Atlas的性能有很大影响,可根据情况适当设置
event-threads = 8
 
#日志级别,分为message、warning、critical、error、debug五个级别
log-level = message
 
#日志存放的路径
log-path = /usr/local/mysql-proxy/log
 
#SQL日志的开关,可设置为OFF、ON、REALTIME,OFF代表不记录SQL日志,ON代表记录SQL日志,REALTIME代表记录SQL日志且实时写入磁盘,默认为OFF
#sql-log = OFF
 
#慢日志输出设置。当设置了该参数时,则日志只输出执行时间超过sql-log-slow(单位:ms)的日志记录。不设置该参数则输出全部日志。
#sql-log-slow = 10
 
#实例名称,用于同一台机器上多个Atlas实例间的区分
instance = test
 
#Atlas监听的工作接口IP和端口
proxy-address = 0.0.0.0:1234
 
#Atlas监听的管理接口IP和端口
admin-address = 0.0.0.0:2345
 
#分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项
#tables = person.mt.id.3
 
#默认字符集,设置该项后客户端不再需要执行SET NAMES语句
charset = utf8
 
#允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
#client-ips = 127.0.0.1, 192.168.1
 
#Atlas前面挂接的LVS的物理网卡的IP(注意不是虚IP),若有LVS且设置了client-ips则此项必须设置,否则可以不设置
#lvs-ips = 192.168.1.1
 

查看监听端口

netstat -tanlp | grep mysql

开启、关闭Atlas

/usr/local/mysql-proxy/bin/mysql-proxyd test start
/usr/local/mysql-proxy/bin/mysql-proxyd test stop

登录并管理Atlas

mysql -h192.168.10.189 -P 2345 -u admin -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.99-agent-admin
 
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select * from help; 
+----------------------------+---------------------------------------------------------+
| command                    | description                                             |
+----------------------------+---------------------------------------------------------+
| SELECT * FROM help         | shows this help                                         |
| SELECT * FROM backends     | lists the backends and their state                      |
| SET OFFLINE $backend_id    | offline backend server, $backend_id is backend_ndx's id |
| SET ONLINE $backend_id     | online backend server, ...                              |
| ADD MASTER $backend        | example: "add master 127.0.0.1:3306", ...               |
| ADD SLAVE $backend         | example: "add slave 127.0.0.1:3306", ...                |
| REMOVE BACKEND $backend_id | example: "remove backend 1", ...                        |
| SELECT * FROM clients      | lists the clients                                       |
| ADD CLIENT $client         | example: "add client 192.168.1.2", ...                  |
| REMOVE CLIENT $client      | example: "remove client 192.168.1.2", ...               |
| SELECT * FROM pwds         | lists the pwds                                          |
| ADD PWD $pwd               | example: "add pwd user:raw_password", ...               |
| ADD ENPWD $pwd             | example: "add enpwd user:encrypted_password", ...       |
| REMOVE PWD $pwd            | example: "remove pwd user", ...                         |
| SAVE CONFIG                | save the backends to config file                        |
| SELECT VERSION             | display the version of Atlas                            |
+----------------------------+---------------------------------------------------------+
16 rows in set (0.00 sec)

正常通过代理操作

[root@localhost bin]# mysql -h192.168.10.189 -P 1234 -u xtgss -p Xtgss@123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.0.81-log MySQL Community Server (GPL)
 
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql> SHOW VARIABLES LIKE 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
 

发现上面的SHOW VARIABLES LIKE 'server_id';操作,每次的结果都不一样,分离是2台从库的server_id,说明我们的读写分离功能配置成功了

七、keepalived


安装

本次安装采用yum的方式进行安装,在192.168.10.189192.168.10.190均进行安装

yum -y install keepalived

keepalived的启动与停止

service keepalived start
service keepalived stop
service keepalived restart

 192.168.10.189配置文件:

! Configuration File for keepalived
 
global_defs {
   notification_email {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id MySQL1 
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
 
vrrp_instance VI_1 {
    state BACKUP 
    interface eth0
    virtual_router_id 60 
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
       192.168.10.240
    }
}
 
virtual_server 192.168.10.240 3306 {
    delay_loop 6
	lb_algo wrr
	lb_kind DR
	nat_mask 255.255.255.0
    persistence_timeout 50
    protocol TCP
 
    real_server 192.168.10.189 3306 {
        weight 1
		notify_down /etc/keepalived/mysql_down.sh
        TCP_CHECK {
			connect_timeout 10
			nb_get_retry 3
			connect_port 3306
		}
    }
}
 

mysql_down.sh:

#!/bin/bash
pkill keepalived

192.168.10.190配置文件:

! Configuration File for keepalived
 
global_defs {
   notification_email {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id MySQL1 
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
 
vrrp_instance VI_1 {
    state BACKUP 
    interface eth0
    virtual_router_id 60 
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
       192.168.10.240
    }
}
 
virtual_server 192.168.10.240 3306 {
    delay_loop 6
	lb_algo wrr
	lb_kind DR
	nat_mask 255.255.255.0
    persistence_timeout 50
    protocol TCP
 
    real_server 192.168.10.190 3306 {
        weight 1
		notify_down /etc/keepalived/mysql_down.sh
        TCP_CHECK {
			connect_timeout 10
			nb_get_retry 3
			connect_port 3306
		}
    }
}
 

mysql_down.sh:

#!/bin/bash
pkill keepalived

未实现

  •  判断mysql服务是否正常的脚本
  •  当前服务器为主时的脚本
  •  当前服务器为备时的脚本
  •  当前服务器不正常时的脚本

通过vip登录Mysql服务器

mysql -h 192.168.10.240 -uxtgss -pXtgss@123
SHOW VARIABLES LIKE 'server_id'; #查看当前是哪个mysql主机,当前mysql主库

把mysql主库停止

mysql -h 192.168.10.240 -uxtgss -pXtgss@123
SHOW VARIABLES LIKE 'server_id'; #查看当前是哪个mysql主机,当前是mysql备主

可以看出主库停了,vip会自动漂移到备主上。

八、mha2 安装


MHA工作原理

  1. 从宕机崩溃的master保存二进制日志事件(binlog events)。

  2. 识别含有最新更新的slave。

  3. 应用差异的中继日志(relay log)到其它slave。

  4. 应用从master保存的二进制日志事件(binlog events)。

  5. 提升一个slave为新master。

  6. 使其它的slave连接新的master进行复制。


MHA工具包


mha-manager工具

  • masterha_check_ssh : 检查MHA的SSH配置。
  • masterha_check_repl : 检查MySQL复制。
  • masterha_manager : 启动MHA。
  • masterha_check_status : 检测当前MHA运行状态。
  • masterha_master_monitor : 监测master是否宕机。
  • masterha_master_switch : 控制故障转移(自动或手动)。
  • masterha_conf_host : 添加或删除配置的server信息。


mha-node工具

  • save_binary_logs : 保存和复制master的二进制日志。
  • apply_diff_relay_logs : 识别差异的中继日志事件并应用于其它slave。
  • filter_mysqlbinlog : 去除不必要的ROLLBACK事件(MHA已不再使用这个工具)。
  • purge_relay_logs : 清除中继日志(不会阻塞SQL线程)。


perl安装

安装rpm包时经常会遇到

warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID***** 

这是由于yum安装了旧版本的GPG keys造成的,解决办法就是

rpm --import /etc/pki/rpm-gpg/RPM* 

1、卸载perl

yum remove perl

2、安装perl

rpm -ivh perl-5.10.1-141.el6_7.1.x86_64.rpm perl-libs-5.10.1-141.el6_7.1.x86_64.rpm perl-Module-Pluggable-3.90-141.el6_7.1.x86_64.rpm perl-Pod-Simple-3.13-141.el6_7.1.x86_64.rpm perl-version-0.77-141.el6_7.1.x86_64.rpm perl-Pod-Escapes-1.04-141.el6_7.1.x86_64.rpm 
 

3、安装perl-ExUtils

rpm -ivh perl-ExtUtils-*.rpm perl-Test-Harness-3.17-141.el6_7.1.x86_64.rpm perl-devel-5.10.1-141.el6_7.1.x86_64.rpm  db4-devel-4.7.25-20.el6_7.x86_64.rpm db4-4.7.25-20.el6_7.x86_64.rpm db4-cxx-4.7.25-20.el6_7.x86_64.rpm db4-utils-4.7.25-20.el6_7.x86_64.rpm --force  --nodeps
 

4、安装 CPAN

rpm -ivh perl-CPAN-1.9402-141.el6_7.1.x86_64.rpm --force --nodeps

安装mha-node #所有数据库节点都要安装

rpm -ivh perl-DBI-1.609-4.el6.x86_64.rpm
rpm -ivh perl-DBD-MySQL-4.013-3.el6.x86_64.rpm 

安装mha-manager

rpm -ivh perl-Config-Tiny-2.12-7.1.el6.noarch.rpm    
rpm -ivh perl-Parallel-ForkManager-0.7.9-1.el6.noarch.rpm
rpm -ivh perl-Mail-Sender-0.8.16-1.el6.rf.noarch.rpm
rpm -ivh perl-Mail-Sendmail-0.79_16-4.2.noarch.rpm
rpm -ivh perl-Params-Validate-0.92-3.el6.x86_64.rpm
rpm -ivh perl-Email-Date-Format-1.002-5.el6.noarch.rpm 
rpm -ivh perl-MIME-Lite-3.028-1.el6.rfx.noarch.rpm
rpm -ivh perl-TimeDate-1.16-13.el6.noarch.rpm
rpm -ivh perl-MailTools-2.04-4.el6.noarch.rpm
rpm -ivh perl-Log-Dispatch-2.27-1.el6.noarch.rpm
rpm -ivh perl-Time-HiRes-1.9721-141.el6_7.1.x86_64.rpm

编辑mha-manager配置文件

[root@localhost Desktop]# vim /etc/masterha/app.cnf 
[server default]
user=xtgss
password=Xtgss@123
ssh_user=root
repl_user=xtgss
repl_password=Xtgss@123
manager_workdir=/usr/local/masterha/app
manager_log=/usr/local/masterha/app/app.log
remote_workdir=/usr/local/masterha/app
ping_interval=1
[server1]
hostname=192.168.10.189
candidate_master=1
check_repl_delay=0
master_binlog_dir=/var/lib/mysql
[server2]
hostname=192.168.10.190
candidate_master=1
check_repl_delay=0
master_binlog_dir=/var/lib/mysql
[server3]
hostname=192.168.10.166
no_master=1
 

启动mha-manager

nohup masterha_manager--conf=/etc/masterha/app1.cnf --ignore_last_failover < /dev/null > /app/masterha/app1/app1.log2>&1 & #以nohup模式,放在后台启动

故障测试

- 手工停止 189上的mysql服务,service mysql stop
- 大约30秒,190自动成为新的主库 #在166从库上show slave status就可以看出来
- 52再次启动mysql服务,要手工加入到AB架构中 #51是主库,使用如下演示命令加入AB架构
- change master to master_host='192.168.10.190', master_port=3306,master_user='xtgss', master_password='Xtgss@123',master_log_file='binlog.000001',master_log_pos=120;
- 手工停止190上的Mysql服务
- 约30秒,189自动成为新的主库 #在166从库上show slave status就可以看出来

注意如下2个问题

  • 当主DB故障,切换到另外的服务器上后,即使恢复了原来的主DB,也不能立即加入整套MHA系统中,得重新手工加入AB架构。
  • 当发生一次切换后,管理节点的监控进程就会自动退出,需要用脚本来自动启动。另外还得删除app1.failover.complete这个文件,否则新的主DB出现问题MHA就不会切换了。


mha-manager常用命令

nohup masterha_manager--conf=/etc/masterha/app1.cnf --ignore_last_failover < /dev/null > /app/masterha/app1/app1.log2>&1 & 
#开启MHA Manager监控
masterha_check_status--conf=/etc/masterha/app1.cnf 
#查看MHA Manager监控是否正常
masterha_stop--conf=/etc/masterha/app1.cnf 
#关闭MHA Manage监控
masterha_check_ssh--conf=/etc/masterha/app1.cnf 
#检查SSH配置
masterha_check_repl--conf=/etc/masterha/app1.cnf 
#检查整个复制环境状况

九、mha shell 补充2 relay log的清除

MHA在发生切换的过程中,从库的恢复过程中依赖于relay log的相关信息,所以这里要将relay log的自动清除设置为OFF,采用手动清除relay log的方式。在默认情况下,从服务器上的中继日志会在SQL线程执行完毕后被自动删除。但是在MHA环境中,这些中继日志在恢复其他从服务器时可能会被 用到,因此需要禁用中继日志的自动删除功能。定期清除中继日志需要考虑到复制延时的问题。在ext3的文件系统下,删除大的文件需要一定的时间,会导致严 重的复制延时。为了避免复制延时,需要暂时为中继日志创建硬链接,因为在linux系统中通过硬链接删除大文件速度会很快。(在mysql数据库中,删除大表时,通常也采用建立硬链接的方式)

  MHA节点中包含了pure_relay_logs命令工具,它可以为中继日志创建硬链接

#执行
SET GLOBAL relay_log_purge=1 #等待几秒钟以便SQL线程切换到新的中继日志,再执行
SET GLOBAL relay_log_purge=0。
    #pure_relay_logs脚本参数如下所示:
     --user mysql                 #用户名
     
     --password mysql             #密码
     
     --port                       #端口号
     
     --workdir                    #指定创建relay log的硬链接的位置,默认是/var/tmp,
                                  #由于系统不同分区创建硬链接文件会失败,
                                  #故需要执行硬链接具体位置,成功执行脚本后,
                                  #硬链接的中继日志文件被删除
                                  
     --disable_relay_log_purge    #默认情况下,如果relay_log_purge=1,
                                  #脚本会什么都不清理,自动退出,通过设定这个参数,
                                  #当relay_log_purge=1的情况下会将relay_log_purge设置0。 
                                  #清理relay log之后,最后将参数设置为OFF。

1、设置relay log的清除方式(在每个slave节点上)

mysql -u xtgss -pXtgss@123 -e 'set global relay_log_purge=0'

2、设置定期清理relay脚本(在每个slave节点上)

vi purge_relay_log.sh 
#!/bin/bash
user=xtgss #声明登录mysql的用户
passwd=Xtgss@123 #声明登录mysql的用户的密码
port=3306 #声明mysql的端口
log_dir='/usr/local/masterha/app/log' #log目录
work_dir='/etc/masterha/app' #work目录
purge='/usr/local/bin/purge_relay_logs' #声明命令绝对路径
if [ ! -d $log_dir ] #如果日志目录不存在
then
mkdir $log_dir -p #创建目录
fi
$purge --user=$user --password=$passwd --disable_relay_log_purge --port=$port --workdir=$work_dir >> $log_dir/purge_relay_logs.log 2>&1

3、添加到crontab定期执行

crontab -l0 4 * * * /bin/bash /usr/local/bin/purge_relay_log.sh

purge_relay_logs脚本删除中继日志不会阻塞SQL线程。也可以手工执行:

purge_relay_logs --user=xtgss --password=Xtgss@123 --port=3306 -disable_relay_log_purge --workdir=/app/masterha/app

十、访问

mha集群设置了虚拟vip,多台机器公用一个ip,外部访问直接访问固定的虚拟ip即可。

你可能感兴趣的:(mysql,数据库)