MySQL主从/主主复制
引言
MySQL作为世界上最广泛的数据库之一,免费是原因之一,其本身功能的强大也是获得众多用的青睐的重要原因。在实际的生产环境中,单机版MySQL数据库就不能满足实际的需求了,此时数据库集群就很好的解决了这个问题了。采用MySQL分布式集群,能够搭建一个高并发、负载均衡的集群服务器。在此之前必须要保证每台MySQL服务器里的数据同步。数据同步可以通过MySQL内部配置就可以轻松完成,主要有主从复制和主主复制。
在本案例下使用同一台机器安装两个数据库,只是端口不一致,一个为3306,一个为3308。
复制原理
- Master将数据改变记录到二进制日志(binary log)中,也就是配置文件log-bin指定的文件,这些记录叫做二进制日志事件(binary log events) 。
- Slave通过I/O线程读取Master中的binary log events并写入到它的中继日志(relay log) 。
- Slave重做中继日志中的事件,把中继日志中的事件信息一条一条的在本地执行一次,完成数据在本地的存储,从而实现将改变反映到它自己的数据(数据重放)。
复制类型
1、基于语句的复制(statement)
根据上图可得到执行计划的列信息,下面分析一下每列所表示的信息。在Master上执行的SQL语句,在Slave上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
把改变的内容复制到Slave,而不是把命令在Slave上执行一遍。从MySQL5.0开始支持。
3、混合类型的复制(mixed)
默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
要求
- 文件${mysql}/data/auto.cnf里server-uuid不能重复。
- 主从服务器操作系统版本和位数一致。
- Master和Slave数据库的版本要一致。
- Master和Slave数据库中的数据要一致。
- Master开启二进制日志,Master和Slave的server_id在局域网内必须唯一。
主从复制
主从复制能保证主SQL(Master)和从SQL(Slave)的数据是一致性的,向Master插入数据后,Slave会自动从Master把修改的数据同步过来(有一定的延迟),通过这种方式来保证数据的一致性,主从复制**基于日志(binlog)**。
主从复制可解决:
- 高可用
因为数据都是相同的,所以当Master挂掉后,可以指定一台Slave充当Master继续保证服务运行,因为数据是一致性的(如果当插入Master就挂掉,可能不一致,因为同步也需要时间)。
- 负载均衡
因为读写分离也算是负载均衡的一种,一般都是有多台Slave的,所以可以将读操作指定到Slave服务器上(需要代码控制),然后再用负载均衡来选择那台Slave来提供服务,同时也可以吧一些大量计算的查询指定到某台Slave,这样就不会影响Master的写入以及其他查询。
- 数据备份
一般我们都会做数据备份,可能是写定时任务,一些特殊行业可能还需要手动备份,有些行业要求备份和原数据不能在同一个地方,所以主从就能很好的解决这个问题,不仅备份及时,而且还可以多地备份,保证数据的安全。
- 业务模块化
可以一个业务模块读取一个Slave,再针对不同的业务场景进行数据库的索引创建和根据业务选择MySQL存储引擎。
配置Master
配置my.cnf
Linux下MySQL配置文件为my.cnf,windows下为my.ini。在Master添加以下配置:
1 | [mysqld] |
配置完成后重启MySQL。
创建数据同步用户
1 | -- -- 用户名:slave,密码:slave |
配置Slave
Linux下MySQL配置文件为my.cnf,windows下为my.ini。在Slave添加以下配置:
1 | [mysqld] |
如果Slave为其它Slave的Master时,必须设置bin_log。配置完成后重启MySQL。
连接Master和Slave
查询Master状态
在master中执行
1 | SHOW MASTER STATUS; |
记录下返回结果的File列和Position列的值。
在Slave中设置Master信息
在slave中执行
1 | CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='slave', MASTER_PASSWORD='slave', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000014', MASTER_LOG_POS=1122, MASTER_CONNECT_RETRY=30; |
查看主从同步状态
1 | SHOW SLAVE STATUS; |
可看到Slave_IO_State为空, Slave_IO_Running和Slave_SQL_Running是No,表明Slave还没有开始复制过程。相反Slave_IO_Running和Slave_SQL_Running是Yes表明已经开始工作了。
开启/关闭主从
在slave中执行
1 | -- 停止主从 |
查询查看主从同步状态,会发现Slave_IO_Running和Slave_SQL_Running是Yes了,表明开启成功。
主主复制
主主复制即在两台MySQL主机内都可以变更数据,而且另外一台主机也会做出相应的变更。其实现就是将两个主从复制有机合并起来就好了。只不过在配置的时候我们需要注意一些问题,例如,主键重复,server-id不能重复等等。
配置Master
接上一案例,在上一案例中的Slave中执行
1 | -- 用户名:slave1,密码:slave1 |
同样记录下返回结果的File列和Position列的值。
配置Slave
在上一案例中的Master中执行
1 | CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='slave1', MASTER_PASSWORD='slave1', MASTER_PORT=3308, MASTER_LOG_FILE='mysql-bin.000017', MASTER_LOG_POS=1860, MASTER_CONNECT_RETRY=30; |
分别开启 START SLAVE;
当且仅当两个数据库Slave_IO_Running和Slave_SQL_Running都为 YES才表明状态正常。
注意
- 主主复制只能保证主键不重复,却不能保证主键有序。
- 当配置完成Slave_IO_Running、Slave_SQL_Running不全为YES时,show slave status\G信息中有错误提示,可根据错误提示进行更正。
- Slave_IO_Running、Slave_SQL_Running不全为YES时,大多数问题都是数据不统一导致。