MySQL的高可用方案有很多种,双主、MHA、MMM等等,这里只是写下最简单的双主这种高可用方案。
一、配置MySQL互为主从
1、环境准备
系统IP主机名服务
Centos 7.5192.168.100.2mysql1MySQL+keepalivedCentos 7.5192.168.100.3mysql2MySQL+keepalived
2、开启二进制日志及中继日志
#主机mysql1配置文件如下:
[root@mysql1
~]# cat
/etc
/my
.cnf
[mysqld
]
basedir
=/usr
/local
/mysql
datadir
=/usr
/local
/mysql
/data
port
=3306
server_id
=1 #server_id必须唯一
socket
=/usr
/local
/mysql
/mysql
.sock
log
-error
=/usr
/local
/mysql
/data
/mysqld
.err
log
-bin
=/usr
/local
/mysql
/data
/log_bin #指定二进制日志文件
relay
-log
=/usr
/local
/mysql
/data
/relay
-bin #指定中继日志
relay
-log
-index
=relay
-bin
.index
auto_increment_increment
=2
auto_increment_offset
=1
#主机mysql2配置文件如下:
[root@mysql2
~]# cat
/etc
/my
.cnf
[mysqld
]
basedir
=/usr
/local
/mysql
datadir
=/usr
/local
/mysql
/data
port
=3306
server_id
=2
socket
=/usr
/local
/mysql
/mysql
.sock
log
-error
=/usr
/local
/mysql
/data
/mysqld
.err
log
-bin
=/usr
/local
/mysql
/data
/log_bin
relay
-log
=/usr
/local
/mysql
/data
/relay
-bin
relay
-log
-index
=relay
-bin
.index
auto_increment_increment
=2
auto_increment_offset
=2
注:mysql1和mysql2只有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
=数据库名”配置项(可以添加多个)来指定要同步的数据库
3、将mysql2设置为mysql1的从服务器
1)mysql1上创建授权用户
[root@mysql1
~]# mysql
-uroot
-p123
.com
mysql
> grant replication slave on
*.* to rep@
'192.168.20.%' identified by
'123.com';
2)查看mysql1的当前binlog状态信息
mysql
> show master status\
G
*************************** 1. row
***************************
File
: log_bin
.000001 #这个值会用到
Position
: 609 #这个值会用到
Binlog_Do_DB
:
Binlog_Ignore_DB
:
Executed_Gtid_Set
:
1 row
in set (0.00 sec
)
3)在mysql2上指定mysql1为master,并开启slave功能
#指定master地址
mysql
> change master to master_host
='192.168.100.2',
-> master_user
='rep',
-> master_password
='123.com',
-> master_log_file
='log_bin.000001', #必须和master上查看到的名字一样
-> master_log_pos
=609; #同上,这个值也是在master上查看到的
#启动slave功能
mysql
> start slave
;
#确定配置成功
mysql
> show slave status\
G #查看slave状态
*************************** 1. row
***************************
Slave_IO_State
: Waiting
for master to send event
Master_Host
: 192.168.100.2
Master_User
: rep
Master_Port
: 3306
Connect_Retry
: 60
Master_Log_File
: log_bin
.000001
Read_Master_Log_Pos
: 609
Relay_Log_File
: relay
-bin
.000002
Relay_Log_Pos
: 318
Relay_Master_Log_File
: log_bin
.000001
Slave_IO_Running
: Yes # 这个值必须为Yes
Slave_SQL_Running
: Yes # 这个值也必须为Yes
#只要上面两个值为yes,则表示主从没有问题,
#其中,
IO线程是去master上面读取二进制日志到本地的中继日志中;
SQL线程是将本地的中继日志中的内容转换为sql语句并执行。
4、将mysql1设置为mysql2的从服务器
#主机mysql2上操作如下:
mysql
> grant replication slave on
*.* to rep@
'192.168.100.%' identified by
'123.com';
mysql
> flush privileges
;
mysql
> show master status\
G #获取所需的file和Position
*************************** 1. row
***************************
File
: log_bin
.000002
Position
: 609
Binlog_Do_DB
:
Binlog_Ignore_DB
:
Executed_Gtid_Set
:
1 row
in set (0.00 sec
)
#主机mysql1上操作如下:
#指定mysql2为master
mysql
> change master to master_host
='192.168.100.3',
-> master_user
='rep',
-> master_password
='123.com',
-> master_log_file
='log_bin.000002',
-> master_log_pos
=609;
mysql
> start slave
; #启动slave
mysql
> show slave status\
G #查看slave状态
*************************** 1. row
***************************
Slave_IO_State
: Waiting
for master to send event
Master_Host
: 192.168.100.3
Master_User
: rep
Master_Port
: 3306
Connect_Retry
: 60
Master_Log_File
: log_bin
.000002
Read_Master_Log_Pos
: 609
Relay_Log_File
: relay
-bin
.000002
Relay_Log_Pos
: 318
Relay_Master_Log_File
: log_bin
.000002
#确保下面两个值为yes
Slave_IO_Running
: Yes
Slave_SQL_Running
: Yes
5、测试主主同步
1)主机mysql1创建测试数据
mysql
> create database test
;
mysql
> use test
mysql
> create table
test1(id int
,name
varchar(4));
mysql
> insert into t1
values(1,'a'),(2,'b');
#确认mysql1的数据
mysql
> select
* from t1
;
+------+------+
| id
| name
|
+------+------+
| 1 | a
|
| 2 | b
|
+------+------+
2 rows
in set (0.00 sec
)
2)确认mysql2已经同步并插入新的数据
#以下操作在主机mysql2上进行
mysql
> select
* from test1
; #确定数据已同步
+------+------+
| id
| name
|
+------+------+
| 1 | a
|
| 2 | b
|
+------+------+
#插入数据测试
mysql
> insert into test1
values(3,'c'),(4,'d');
mysql
> select
* from test1
; #确定最新数据
+------+------+
| id
| name
|
+------+------+
| 1 | a
|
| 2 | b
|
| 3 | c
|
| 4 | d
|
+------+------+
3)确定mysql1可以同步mysql2的数据
#在mysql1上查询,是否同步mysql2主机上的数据
mysql
> select
* from test1
;
+------+------+
| id
| name
|
+------+------+
| 1 | a
|
| 2 | b
|
| 3 | c
|
| 4 | d
|
+------+------+
4 rows
in set (0.00 sec
)
至此,现在任何一台MySQL上更新数据都会同步到另一台MySQL,MySQL同步完成。
注:若主MySQL服务器已经存在,只是后期业务拓展才搭建从服务器,在配置数据库同步前应先将MySQL服务器的要同步的数据库拷贝到从服务器上(如先在主MySQL上备份数据库,再用备份再从MySQL服务器上恢复)。
二、配置keepalived高可用
1、安装keepalived
两个节点都需要执行以下命令,以便安装keepalived。
[root@mysql1
~]# yum
-y install keepalived
2、修改主机mysql1的keepalived配置文件
[root@mysql1
~]# cat
/etc
/keepalived
/keepalived
.conf
! Configuration File
for keepalived
global_defs
{
router_id mysql
-1 #此处的值必须唯一
}
vrrp_instance
VI_1 {
state
BACKUP #指定角色为backup,两台MySQL服务器的角色均为backup,设置backup将根据优先级决定主从
interface ens33 #指定承载虚拟
IP的网卡
virtual_router_id
51 #指定组,同一个集群内的值必须一致。并且不可和局域网中的其他组冲突
priority
100 #优先级范围为:
0~100
advert_int
1 #发vrrp包的时间间隔,即多久进行一次master选举(可认为是健康检查时间间隔)
nopreempt #不抢占,即允许一个priority比较低的节点作为master,
authentication
{ #认证区域
auth_type
PASS
auth_pass
1111
}
virtual_ipaddress
{ #
VIP区域,指定vip地址
192.168.100.20
}
}
virtual_server
192.168.100.100 3306 { #设置虚拟服务器,需要指定虚拟
IP地址和服务端口,
IP与端口之间用空格隔开
delay_loop
2 #设置运行情况检查时间,单位是秒
lb_algo rr #设置后端调度算法
lb_kind
DR #设置lvs实现负载均衡的机制,有
NAT、
TUN、
DR三个模式,
DR模式效率最高
persistence_timeout
60 #会话保持时间,单位是秒
protocol
TCP #指定转发协议类型,有
TCP和
UDP两种
real_server
192.168.100.2 3306 { #配置服务节点,这里指定的也就是本机的真实
IP
weight
1 #设置权重
notify_down
/etc
/keepalived
/bin
/mysql
.sh #检测到real_server的MySQL服务宕机后执行的脚本。
TCP_CHECK {
connect_port
3306 #健康检查端口
connect_timeout
3 #连接超时时间
retry
3 #重试次数
delay_before_retry
3 #重连间隔时间
}
}
}
#准备指定的脚本
[root@mysql01 keepalived
]# pwd
/etc
/keepalived
[root@mysql01 keepalived
]# mkdir bin
[root@mysql01 keepalived
]# vim bin
/mysql
.sh
#
!/bin
/bash
pkill keepalived #停止keepalived服务
[root@mysql01 keepalived
]# chmod
+x bin
/mysql
.sh #赋予脚本执行权限
[root@mysql01
~]# systemctl start keepalived #启动keepalived服务
3、确定ens33网卡有虚拟Ip
[root@mysql01 ~]# ip a show ens33 #必须使用ip a命令才可以查看到,ifconfig命令查看不到 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:c0:39:80 brd ff:ff:ff:ff:ff:ff inet 192.168.20.2/24 brd 192.168.20.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet 192.168.20.20/32 scope global ens33 #可以看到指定的VIP已经绑定到ens33上 valid_lft forever preferred_lft forever inet6 fe80::659e:9312:318a:e52b/64 scope link noprefixroute valid_lft forever preferred_lft forever #将keepalived的配置文件发送到mysql2主机上 [root@mysql01 ~]# scp /etc/keepalived/keepalived.conf root@192.168.100.3:/etc/keepalived/
4、修改主机mysql2的keepalived配置文件
#修改msyql1发送来的配置文件
[root@mysql02 keepalived
]# cat
/etc
/keepalived
/keepalived
.conf
! Configuration File
for keepalived
global_defs
{
router_id mysql
-2 #更改router_id,此处在热备组中必须要唯一
}
vrrp_instance
VI_1 {
state
BACKUP
interface ens33
virtual_router_id
51
priority
90 #更改优先级
advert_int
1
nopreempt
authentication
{
auth_type
PASS
auth_pass
1111
}
virtual_ipaddress
{
192.168.100.20
}
}
virtual_server
192.168.100.20 3306 {
delay_loop
2
lb_algo rr
lb_kind
DR
persistence_timeout
60
protocol
TCP
real_server
192.168.100.3 3306 { #更改为本机的
IP地址及监听端口
weight
1
notify_down
/etc
/keepalived
/bin
/mysql
.sh
TCP_CHECK {
connect_port
3306
connect_timeout
3
retry
3
delay_before_retry
3
}
}
}
#准备所需脚本
[root@mysql1 keepalived
]# pwd
/etc
/keepalived
[root@mysql2 keepalived
]# mkdir bin
[root@mysql2 keepalived
]# vim bin
/mysql
.sh
#
!/bin
/bash
pkill keepalived
[root@mysql2 keepalived
]# chmod
+x bin
/mysql
.sh
#启动keepalived
[root@mysql2
~]# systemctl start keepalived
三 最终总结
至此,即可实现MySQL的双主效果(只要
VIP所在的节点,MySQL服务端口无法连接,
那么
VIP将切换至另一台节点,即使宕机的mysql服务器恢复,也不会对
VIP进行抢占)。
虽然有两台MySQL数据库,但是其使用keepalived提供的虚拟
IP地址来对外提供服务,
不管这个虚拟Ip地址落在哪台服务器上,
都可以保证数据的一致性,因为它们互为主从,
并且keepalived的状态都为backup,
也设置了不抢占(减少
VIP的切换次数),
这样可以大大的避免keepalived的脑裂问题。