【MySQL】2.MySQL主从同步

生来就可爱ヽ(ⅴ<●) 提交于 2020-03-25 21:24:19

一、MySQL主从原理

1、概念

MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。

2、MySQL主从复制涉及的三个线程

    主节点 binary log dump 线程:当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。
    从节点I/O线程:当从节点上执行`start slave`命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。
    从节点SQL线程:SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。

 二、MySQL主从配置

步骤:
(1)多台节点,server_id不同
(2)主库开启binlog
(3)主库提供复制用户:
grant replication slave on *.* to repl@'192.168.0.%' identified by '12345';
(4)从库需要主库的全备,恢复到从库,并记录posication位置
(5)通知从库:复制使用的用户,密码,IP,port,复制的binlog文件和起点
change master to
(6)开启主从复制
 
master:
# cat my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
user=mysql
character_set_server=utf8
log-bin=mysqld-bin.log
server-id=1
binlog-ignore-db=mysql
.......

mysql> grant replication slave on *.* to repl@'192.168.42.%' identified by '123456';
mysql> show master status\G;
slave:
# cat my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
user=mysql
character_set_server=utf8
relay-log=relay-bin.log
server-id=2
......
mysql> change master to MASTER_HOST='192.168.42.133',master_user='repl',master_password='123456',master_port=3306,master_log_file='mysqld-bin.000002',master_log_pos=448,master_connect_retry=10;
mysql> start slave;
mysql> show slave status\G;   
 

三、MySQL主从同步延迟

1、主从同步延迟产生的原因

深入解析Mysql 主从同步延迟原理及解决方案: https://www.cnblogs.com/fengff/p/11011702.html
主服务器开放N个链接给客户端来连接的,这样有会有大并发的更新操作, 但是从服务器的里面读取binlog的线程仅有一个(mysql-5.6.3后已经支持了多线程的主从复制),当某个SQL在从服务器上执行的时间稍长或者由于某个SQL要进行锁表就会导致,主服务器的SQL大量积压,未被同步到从服务器里。这就导致了主从不一致, 也就是主从延迟。
mysql的主从复制都是单线程的操作,主库对所有DDL和 DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,效率很比较高,下一步, 问题来了,slave的Slave_SQL_Running线程将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随机的,不是顺序的,成本高很多,还可能在slave上的其他查询产生lock争用,由于Slave_SQL_Running也是单线程的,所以一个DDL卡住了,需要执行10分钟,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时。

2、判断主从延迟的方法:

mysql>  show slave status\G;    #查看从服务器的状态
可以查看Seconds_Behind_Master参数的值来判断是否有发生主从延时。
其值有这么几种:
NULL - 表示io_thread或是sql_thread有任何一个发生故障,也就是该线程的Running状态是No,而非Yes.
0 - 该值为零,是我们极为渴望看到的情况,表示主从复制状态正常。
> 0 - 表示主从已经出现延时,数字越大表示从库落后主库越多。

3、主从同步延迟的解决方案

(1)架构方面
1.业务的持久化层的实现采用分库架构,mysql服务可平行扩展,分散压力。
2.单个库读写分离,一主多从,主写从读,分散压力。这样从库压力比主库高,保护主库。
3.服务的基础架构在业务和mysql之间加入memcache或者redis的cache层。降低mysql的读压力。
4.不同业务的mysql物理上放在不同机器,分散压力。
5.使用比主库更好的硬件设备作为slave总结,mysql压力小,延迟自然会变小。
(2)硬件方面
1.采用好服务器,比如4u比2u性能明显好,2u比1u性能明显好。
2.存储用ssd或者盘阵或者san,提升随机写的性能。
3.主从间保证处在同一个交换机下面,并且是万兆环境。
总结,硬件强劲,延迟自然会变小。一句话,缩小延迟的解决方案就是花钱和花时间。
(3)mysql主从同步加速
1、sync_binlog在slave端设置为0
2、-logs-slave-updates 从服务器从主服务器接收到的更新不记入它的二进制日志。
3、直接禁用slave端的binlog
4、slave端,如果使用的存储引擎是innodb,innodb_flush_log_at_trx_commit =2
(4)从文件系统本身属性角度优化
master端修改linux、Unix文件系统中文件的atime属性, 由于每当读文件时OS都会将读取操作发生的时间回写到磁盘上,对于读操作频繁的数据库文件来说这是没必要的,只会增加磁盘系统的负担影响I/O性能。可以通过设置文件系统的mount属性,阻止操作系统写atime信息,在linux上的操作为:打开/etc/fstab,加上noatime参数/dev/sdb1 /data reiserfs noatime 1 2然后重新mount文件系统#mount -oremount /data
(5)同步参数调整
主库是写,对数据安全性较高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置是需要的,而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也可以设置为0来提高sql的执行效率
 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!