1.主从复制的原理
原理:Mysql里面对应每个增删改操作都会记录到一个日志文件中 成为binlog日志
由于sql线程是单线程的,所以速度会比较慢,是串行化的,因此mysql主从是一定会出现延时的,主从延迟
大概过程:
写日志的时候,加到binlog日志里,同时开启一个io线程将binlog日志转到从库中,然后从库开启io线程(现在改进为多线程),读取binlog日志后,写到一个relay日志里,然后开启sql线程去读取里面的relay日志,写到本地的数据库里(为什么需要这个relay日志?)
所谓的延迟,其实主要是看主库的写并发,如果写并发很低,延迟会很低;主库的写并发达到每秒的1000/s,从库的延迟会有几ms;如果达到2000/s,从库的延迟会有十几ms; 主库的写并发如果还增加,达到 4000 8000 /s的话,那么延迟会到几秒
2. 主从复制的数据丢失问题 以及半同步复制的原理 ,并行复制的原理
还有一个问题就是,如果主库突然宕机,数据还没有同步到从库里,数据就有可能丢失了;
解决办法有两个机制,1.半同步复制,解决主数据库数据丢失问题 2. 并行复制,用来解决主从同步延时问题
半同步复制(semi-sync半同步复制): 主库要求写数据的时候,记录binlog日志而且至少有一台从库把binlog日志同步成功了,并且从库返回一个ack,这里只是拉到从库本地的relay日志里,还没有完全同步,这个时候才会认为写操作成功了,否则写操作过来以后只是写好了binlog日志 还没有同步,就会认为是失败的或者说写操作还没有完成; 如果此时主库挂了,宕机了,就认为写操作是不成功的,不成功的话客户端可以感知到,重试一次,重试的时候从库已经切换成主库了,就可以保证写操作的时候还没有同步到从库,宕机导致数据丢失
并行复制:指的是从库可以开启多个线程,并且读取relay log里的日志,并行的放到不同库的日志,库级别的并行? 可以解决主从同步延时问题;也就是每个线程读某一个库的日志,可以同时读多个库 ,可以加快同步的效率
但是并行复制的意义并不是很大,如果只是针对单个库来操作的话,意义并不大
3.mysql主从同步延时问题(精华),多库并发重放relay日志,缓解主从延迟的问题
插入一条数据,立马去查数据,然后更新这条数据
一般来讲,如果主从延迟比较严重的话怎么解决?
1.分库,将主库拆分成几个表,那么主库的写并发就会降低很多,主从延迟可以忽略不计
2.打开mysql的并发复制,如果单个库的写并发很高,并不能真正的解决问题(但是还是要打开)
3.重写代码,插入一条数据以后,尽量不要马上去查数据,插入数据直接去更新,不要查询(如果用了主从架构,写代码的时候尽量不要马上去查询!)
4.如果确实存在这样的业务,必须插入数据后马上查询到,对这个查询设置直连主库(用数据库中间件,不推荐这种,导致读写分离的意义丧失)
确实主从延迟比较高了,就应该拆库拆表了