MySQL Replication
主从架构
主从架构的原理就是从节点通过获取主节点的二进制日志,重放执行sql语句来达到和主节点数据同步。如下图:
主从架构有基本的一主一从,有一主多从,有循环复制(就是每个是下一个的主,是上一个的从,围城一个环),级连复制(分配一个从节点,让他从主节点上获取二进制日志并发送给其他从节点,用来分担主节点的压力,而他自己本身不去重放二进制日志)
然后从另一个角度又可以分为异步主从和半同步主从,主从默认就是异步的,主节点写数据可以是多线程同时及逆行,而从节点通过主节点的二进制日志去重读操作的过程是单进程的,所以默认为异步。所谓半同步就是指定一个或者多个从节点,请求的写操作不仅在主节点写完,还要在在从节点也同步完成后主节点才返回给客户端处理完成的信息,而没有指定的从节点仍然是异步的,所以叫做半同步。
下面我们来实现最简单的一主一从
我们先来理一下思路,做主从首先将时间同步,然后主节点开启二进制日志,从节点开启中继日志,主节点要创建一个能用来同步的账号,然后从服务器使用这个账号去找主节点去同步。
1.环境
- 主节点ip:172.16.200.102
- 从节点ip:172.16.200.101
- 两个服务器时间同步,都使用centos6.9系统,mysql版本为5.1.73
- 防火墙和selinux确保是关闭的
2.主节点上修改配置文件/etc/my.cnf,在[mydqld]段中添加如下内容
server-id=1
log-bin=binlog
skip_name_resolve
3.从节点上修改配置文件/etc/my.cnf,在[mysqld]段中添加如下内容
server-id=2
relay_log=relaylog #开启中继日志
skip_name_resolve
read_only=ON
启动从节点mysqld
4.主节点上授权用户
启动mysqld,然后授权一个能做主从的账号,根据最小权限准则,我们使用如下权限:
mysql> grant replication client,replication slave on *.* to 'repluser'@'172.16.200.%' identified by '123';
然后查询binlog日志位置并记录,方便从节点同步时不会处乱子
mysql> show master status;
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| binlog.000003 | 356 | | |
+---------------+----------+--------------+------------------+
这里看到当前的binlog日志使用的是binlog.000003,位置是在356处
5.配置从节点
登陆到从节点上,执行如下操作
mysql> change master to master_host='172.16.200.102',master_user='repluser',master_pas
sword='123',master_log_file=' binlog.000003',master_log_pos=356;
#master_log_file就是主节点的二进制日志,master_log_pos为二进制日志位置
mysql> start slave; #开启io线程和sql线程,单独开一个就在后边跟上想要开启的线程名就行
mysql> show slave status\G #查看如下两个线程是不是已经显示YES
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
6.此时,一个简单的主从复制就已经成功了,我们可以在主节点上创建一个表,在从节点看一下有没有,有的话实验成功。
半同步实现
之前我们讲了半同步的原理,实现需要通过加载插件来完成,步骤如下:
1.环境
半同步基于semisync_master.so和semisync_slave.so这两个插件来完成,注意较老版本的mysql可能没有这两个插件
- 主节点:172.16.200.107,mariadb5.5.52
- 从节点:172.16.200.108,mariadb5.5.52
- 时间同步,selinux和防火墙关闭
2.主节点上加载这两个插件并启用
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%'; #查看插件装载上了,但是处于OFF状态
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled=ON; #设置插件为启用状态
3.从节点上安装配套的从节点插件
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
MariaDB [(none)]> stop slave IO_THREAD;
MariaDB [(none)]> start slave IO_THREAD;
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)
主从复制的读写分离
主从复制只是将从节点和主节点的数据做了备份,要分散各个节点的压力,就要让读请求去找从节点,而写请求去找主节点,这样就可以分散各个节点的压力。而要实现这种功能,一般的反向代理像nginx,haproxy是实现不了的,需要一个能识别mysql协议的代理,这里我们使用proxysql来实现。
我们到http://www.proxysql.com/去下载一个最新版本的proxysql,进去之后点download后就会跳转到下载节点,找到当前系统版本对应的包,下载就行,这里我们使用proxysql-1.3.6
实现步骤:
1.环境
这里我们还是使用上面的主从主机,然后添加一台读写分离器主机,ip为172.16.200.109,将下载好的proxysql包放到/root下,关闭selinux和firewalld。
2.安装proxysql和mysql客户端
[root@localhost ~]# yum -y install ./proxysql-1.4.2-1-centos7.x86_64.rpm #在/root目录下用yum安装本地包
[root@localhost ~]# yum -y install mariadb
3.修改配置文件
[root@localhost ~]# rpm -qc proxysql-1.4.2-1
/etc/proxysql.cnf
[root@localhost ~]# vim /etc/proxysql.cnf
#在mysql_variables段中,修改监听的端口
interfaces="0.0.0.0:3306;/tmp/proxysql.sock"
#在mysql_servers段中将第一个{}的内容注释去掉,并在拷贝一份放到下面以此来做模板,然后修改
{
address = "172.16.200.107" #主节点ip
port = 3306
hostgroup = 0 #分组,主一个组,从一个组,编号不能一样
status = "ONLINE"
weight = 1
compression = 0
max_replication_lag = 10
},
{
address = "172.16.200.108" #从节点ip
port = 3306
hostgroup = 1
status = "ONLINE"
weight = 1
compression = 0
max_replication_lag = 10
}
#mysql_users段中添加下面这段
{
username = "feng"
password = " 123"
default_hostgroup = 0
active = 1
}
#mysql_replication_hostgroups=段中添加
{
writer_hostgroup=0
reader_hostgroup=1
comment="test repl 1"
}
完成后在主节点上创建用户feng,密码为123,然后就可以用这个账号在代理端登陆验证了
[root@localhost ~]# mysql -S /tmp/proxysql.sock -ufeng -p123
mysql高可用
完成主从复制和读写分离之后,我们还需要做高可用,解决主节点是单点的问题,保证主节点挂掉后有从节点可以接管主节点的工作,这里我们使用MHA这款高可用程序。注意这里的高可用不是针对的proxysql这个读写分离器来做的,而读写分离器如果是单点可以使用别的方案,如keepalived等,这里就不说这些了。
MHA服务分为Manager节点和Node节点,服务端安装Manager服务,而Node上安装节点的工具
实现步骤:
1.环境
- 上边实验的环境,加上一台ip为172.16.200.120的centos主机作为MHA.
- MHA需要从节点上一定要增加read_only=ON选项,如果从节点上没有,就给加上。
- 确保每个节点的id必须唯一。
- 确保有一个账户可以在各个节点上都能有管理权限,这里我们上面创建了feng用户拥有这个权限,所以就不在创建了。
- 下载 mha4mysql-node-0.56-0.el6.noarch.rpm mha4mysql-manager-0.55-0.el6.noarch.rpm这两个包分别到从节点和主节点/root目录下
2.由于从节点可能成为主节点,而主节点如果断了在上线时就是从节点了,所以要在主节点和从节点的配置文件中都设置二进制日志和中继日志;由于MHA在指定一个 新的主节点时,要让这个准备升级的从节点和别的从节点做比较,如果有别的从节点上有而本从节点没有的东西就都要传过来,让自己也拥有,这样能避免不同步的问题,而要实现这个功能就需要通过中继日志来做比较,而中继日志默认是会自动清理的,所以需要在配置文件中加入选项,关闭自动清理中继日志的功能。
主节点/etc/my.cnf配置文件中增加中继日志选项
relay-log=relay-bin
从节点/etc/my.cnf增加二进制日志选项,关闭自动清理中继日志
log-bin=bin_log
relay_log_purge=0
重启这些服务
3.MHA集群中各个节点彼此之间需要基于ssh互相通信,以实现远程控制及数据管理。所以我们需要在一个节点上配置密钥对,然后将私钥和authorized_keys文件拷贝到别的节点上,这样就能实现集群中各主机之间无密码直接通信了。
我们在MHA主机上创建密钥对:
[root@localhost ~]# ssh-keygen -t rsa -P ''
[root@localhost ~]# for i in {7..9};do scp -p -r .ssh/ root@172.16.200.10$i:/root/.ssh
/;done #将生成的钥匙文件目录整个复制到各个节点上
测试用ssh连接,发现不用输入密码了,就成功了
4.安装MHA的程序
在MHA主机上安装Manager
[root@localhost ~]# cd
[root@localhost ~]# yum -y install ./mha4mysql-manager-0.55-0.el6.noarch.rpm
各个节点上安装node
[root@localhost ~]# cd
[root@localhost ~]# yum -y install ./mha4mysql-node-0.56-0.el6.noarch.rpm
5.在MHA中,每一个被监控的集群叫做一个application,而每个监控的app需要单独创建一个配置文件。所以下边我们自己定义配置文件,并加入配置:
[root@localhost ~]# mkdir /etc/mha
[root@localhost ~]# cd /etc/mha
[root@localhost mha]# vim app1.cnf
[server default]
user=feng
password=123
manager_workdir=/data/masterha/app1
manager_log=/data/masterha/app1/manager.log
remote_workdir=/dta/masterha/app1
ssh_user=root
repl_user=repluser
repl_password=123
ping_interval=1
[server1]
hostname=172.16.200.107
candidate_master=1 #设置能成为主节点
[server2]
hostname=172.16.200.108
candidate_master=1
然后测试ssh是否连通
[root@localhost mha]# masterha_check_ssh --conf=/etc/mha/app1.cnf
测试集群是否正确
[root@localhost mha]# masterha_check_repl --conf=/etc/mha/app1.cnf
如果出现ERROR提示User repluser does not exist,原因是之前主从实验时,在主节点创建的repluser用户没有同步到从节点,我们只需要在主节点再次执行授权repluser用户的语句就可以同步到从节点了,如下
MariaDB [(none)]> grant replication client,replication slave on *.* to 'repluser'@'172
.16.200.%' identified by '123';
在后台运行程序,并且将日志记录
[root@localhost mha]# nohup masterha_manager --conf=/etc/mha/app1.cnf > /data/masterha/app1/manager.log 2>&1 &
测试集群运行状态
[root@localhost mha]# masterha_check_status --conf=/etc/mha/app1.cnf
6.模拟故障
我们手动关闭主节点,然后去恢复集群
主节点关闭后,检测程序就会自动停止,所以配置完主节点后要再次启用检测层序。
在主节点上关闭mariadb
[root@localhost ~]# service mariadb stop
然后在172.16.200.108这个从上查看
MariaDB [feng]> show global variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only | OFF |
+---------------+-------+
我们看到之前在配置文件中设置的只读选项成为了OFF,证明MHA已经将这个从节点设置成为主节点。
7.恢复
我们接下来要做的就是将之前宕掉的主节点现在设置为从节点,让他上线正常运行,然后将MHA程序再运行起来。