一、什么是主从复制
将主数据库中的执行语句m通过二进制日志传输到从数据库上,然后从数据库会执行这些语句,
从而使从数据库的数据与主数据库保持一致。
基本原理:
MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。
mysql复制是基于主服务器的每次操作都由一个二进制日志记录下来,然后传入到子服务器上。
所以主节点要开启二进制日志,子节点要设置接收主节点的二进制日志。
当一个子节点连接到主节点,,会通知通知主节点发送日志的最后一次更新位置,
然后子节点就会从这个位置开始接收以后的所有操作日志,接收到了之后在子节点执行一次。
二、主从复制的作用
1、主数据库出现问题,可以切换到从数据库。
2、可以进行数据库层面的读写分离。
3、可以在从数据库上进行日常备份。
三、复制过程
Binary log:主数据库的二进制日志。
Relay log:从服务器的中继日志。
1、主节点执行完操作之后,将日志串行地操作写入Binary log
2、子节点开启一个I/O Thread,该线程在master打开一个普通连接,
主要工作是将主节点是Binary log数据
读取到子节点的中继日志Relay log中。
3、然后子节点中会开启一个sql Thread,从中继日志中读取日志,按顺序执行这些操作。
四、主从复制的具体操作
1、在主数据库授权给子节点,也就是创建一个用于子节点复制主节点log数据的账号并给予相应的权限。
2、分别修改主从数据库的配置文件/etc/my.cnf
master:
server-id用来指定唯一id
binlog-do-db指定需要复制的数据库;
log-bin用来指定文件位置和文件名
slave:
1、添加二进制日志配置,开启二进制(设置从库中继日志的目录和文件名)
2、将slave指向master
mysql>CHANGE MASTER TO
>MASTER_HOST='master所在服务器的IP',
>MASTER_USER='master授权的账号',
>MASTER_PASSWORD='master授权的密码',
>MASTER_LOG_FILE='master的日志文件名',
>MASTER_LOG_POS=master的日志所在位置;
在从库用命令设置要同步的主库的ip,主库建立的有权限同步数据的账号和密码,
主库的log日志文件名和目录。
3、开始主从复制
在slave上执行
mysql>start slave;
查看slave的运行状态:
show slave status\G;
注意点,开启了主从复制,slave库如果写入数据的话,可能导致数据回滚从而主从复制线程中断,
可以通过以下方式解决:
mysql> stop slave;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> start slave;
由于主从复制是基于I/O的日志,所以会存在一定延时,如果对数据一致性要求非常高的话,简单的主从复制在实际环境中会存在问题。
五、MySQL主从同步延迟原因及解决办法
master可以并发去写入日志,但是slave是单线程的,只能串行。这样就导致了其中一个操作耗时,
后面的操作只有等着。
当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,
那么延时就产生了
还有就是可能与slave的大型query语句产生了锁等待。(子节点在同步的时候,其它线程正在查相同的资源。)
MySQL数据库主从同步延迟解决方案:
1、最简单的减少slave同步延时的方案就是在架构上做优化,尽量让主库的DDL快速执行。
2、主库是写,对数据安全性较高,所以设置sync_binlog=1
(二进制日志(binary log)同步到磁盘的频率,设置为1在就会每个语句或事务后同步一次 binary log),
innodb_flush_log_at_trx_commit=0(指定了 InnoDB 在事务提交后的日志写入频率)
–slave-net-timeout=seconds 参数:
当slave从主数据库读取log数据失败后,等待多久重新建立连接并获取数据 ,单位为秒 默认设置为 3600秒。
slave_net_timeout 3600 –master-connect-retry=seconds 参数:
当重新建立主从连接时,如果连接建立失败,间隔多久后重试。 master-connect-retry单位为秒 默认设置为 60秒。
而从库只读,所以关于数据安全性可以降低。
3、增加从服务器,这个目的还是分散读的压力,从而降低服务器负载。
总结:
解决主从复制延时问题,主要是以下几点:
1、提高slave库的sql执行效率,比如说降低执行语句刷新到日志,日志刷新到磁盘的频率
提高slave库读取失败后重连主库的频率等。
2、多加slave,加强负载均衡能力
3、主库写,从库只读。
六、双主双从架构
1、双主双从,当m1挂了之后,还有m2顶上成为新的主机。
2、m1的数据变动,会自动同步到s1(m1的从机)
3、m1的数据变动,会同步到m2上,而m2也有自己的从机s2,所以也会同步到s2上。
步骤:
1、m1和m2这两台主机,各种建立一个有权限复制数据的账号。
2、修改配置文件:
m1:
server-id = 10
log-bin = mysql-bin 指定binary.log文件位置和文件名
log_slave_updates 所有的操作(不限于本机执行操作,包括同步数据的操作)
写入到binary log,因为s1需要从这个日志文件读。
relay-log = relay-mysql 打开中继日志,要复制m2的数据
auto-increment-offset = 1 # 起始值
auto-increment-increment = 2 # 步长(每次id增长长度)
m2:
server-id = 20
log-bin = mysql-bin
relay-log = relay-mysql 打开中继日志,要复制m1的数据
auto-increment-increment = 2 起始值
auto-increment-offset = 2 # 步长(每次id增长长度)
3、m1和m2服务器,各自指定对另一台服务器为自己的主服务器:
mysql>CHANGE MASTER TO
>MASTER_HOST='master所在服务器的IP',
>MASTER_USER='master授权的账号',
>MASTER_PASSWORD='master授权的密码',
>MASTER_LOG_FILE='master的日志文件名',
>MASTER_LOG_POS=master的日志所在位置;
4、以上就将双主双从搭建好了,如果m1宕机,m2里面会有m1的数据,但是需要手动切换为主机,
做不到双击热备的效果,所以需要使用keepalived+加双主的方式实现双机热备。
5、配置keepalived实现热备
有两台机器(MASTER1)所在的192.168.187.129与(Master2)192.168.187.132,用(VIP)192.168.187.61做虚拟IP。
在两台服各器中的/etc/keepalived文件夹中的keepalived.conf下进行配置:
Master1的设置
global_defs {
router_id Mysql_HA #当前节点名
}
vrrp_instance VI_1{
state BACKUP #两台配置节点均为BACKUP
interface eth0 #绑定虚拟IP的网络接口
virtual_router_id 51 #VRRP组名,两个节点的设置必须一样,以指明各 个节点属于同一VRRP组
priority 100 #节点的优先级,另一台优先级改低一点
acvert_int 1 #组播信息发送间隔,两个节点设置必须一样
nopreempt #不抢占,只在优先级高的机器上设置即可,优先级低的机器不设置
authentication{ #设置验证信息,两个节点必须一致
auth_type PASS
auth_pass 1111
}
Virtual_ipaddress{ #指定虚拟IP,两个节点设置必须一样
192.168.187.61
}
}
virtual_server 192.168.187.61 3306 { #linux虚拟服务器(LVS)配置
delay_loop 2 #每个2秒检查一次real_server状态
lb_algo wrr #LVS调度算法,rr|wrr|lc|wlc|lblc|sh|dh
lb_kind DR #LVS集群模式 ,NAT|DR|TUN
persistence_timeout 60 #会话保持时间
protocol TCP #使用的协议是TCP还是UDP
real_server 192.168.187.129 3306 {
weight 3 #权重
notify_down /usr/local/bin/mysql.sh #检测到服务down后执行的脚本
TCP_CHECK {
connect_timeout 10 #连接超时时间
nb_get_retry 3 #重连次数
delay_before_retry 3 #重连间隔时间
connect_port 3306 #健康检查端口
}
}
总结:
实际上就是在两个master服务器中,用keepalived创建一个LVS(linux虚拟服务器),
本机ip配置到这个LVS中,各个master节点设置不同的优先级,设置相同的VRRP组名等。
外面的应用就访问lvs的ip地址,默认会转发到优先级高的master节点,
如果这个master节点挂了,就会自动转发到另外一个master节点上,这样就实现了双机热备。