复制概念
- Mysql内建的复制功能是构建大型,高性能应用程序的基础。
- 将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。
- 复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。
- 当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
需要注意的是:在进行mysql复制时,所有对复制中的表的更新必须在主服务器上进行。否则必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
Mysql支持 哪些复制
- 基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时,会自动选着基于行的复制。
- 基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
- 混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
Mysql复制能解决的问题
- 数据分布 (Data distribution )
- 负载平衡(load balancing)
- 数据备份(Backups) ,保证数据安全
- 高可用性和容错行(High availability and failover)
- 实现读写分离,缓解数据库压力
主从复制原理
- master节点将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制binlog日志中;
- salve节点会在一定时间间隔内对master二进制binlog日志进行探测其是否发生改变
- 如果发生改变,salve节点则开启一个I/O线程请求读取master二进制binlog日志数据
- 同时master节点为每个slave请求启动一个dump线程,用于向slave发送日志数据
- slave节点接受并保存至本地的中继日志relay log中
- slave节点将启动SQL写库线程从中继日志中读取二进制日志数据,在本地重放,使得其数据和主节点的保持一致
- 最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。
注意几点
- master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
- slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
- Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
- Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)
- master和slave两节点间时间需同步
流程图如下:
如上图所示:
- Mysql复制过程的第一部分就是master记录二进制日志。
在每个事务更新数据完成之前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事务写入二进制日志完成后,master通知存储引擎提交事务。 - 第二部分就是slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。
- SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
- 此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。
复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。
Mysql复制的模式
- 主从复制:主库授权从库远程连接,读取binlog日志并更新到本地数据库的过程;主库写数据后,从库会自动同步过来(从库跟着主库变);
- 主主复制:主从相互授权连接,读取对方binlog日志并更新到本地数据库的过程;只要对方数据改变,自己就跟着改变;(如何解决冲突?)
Mysql主从复制的优点
- 在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)
- 在从主服务器进行备份,避免备份期间影响主服务器服务;(确保数据安全)
- 当主服务器出现问题时,可以切换到从服务器。(提升性能)
Mysql主从复制总结
-
主从复制条件
- 开启Binlog功能
- 主库要建立账号
- 从库要配置master.info(CHANGE MASTER to...相当于配置密码文件和Master的相关信息)
- start slave 开启复制功能
需要了解的:
1)3个线程,主库IO,从库IO和SQL及作用
2)master.info(从库)作用
3)relay-log 作用
4)异步复制
5)binlog作用(如果需要级联需要开启Binlog)需要注意:
1)主从复制是异步的逻辑的SQL语句级的复制
2)复制时,主库有一个I/O线程,从库有两个线程,I/O和SQL线程
3)实现主从复制的必要条件是主库要开启记录binlog功能
4)作为复制的所有Mysql节点的server-id都不能相同
5)binlog文件只记录对数据库有更改的SQL语句(来自主库内容的变更),不记录任何查询(select,show)语句
Mysql主从环境部署一段时间后,发现主从不同步时,如何进行数据同步至一致?(请往下看)
主从同步中可能存在的问题
slave运行过慢不能与master同步,也就是MySQL数据库主从同步延迟
MySQL数据库slave服务器延迟的现象是非常普遍的,这就导致了有了以下一些潜规则:“实时性要求不高的读取操作可以放到slave服务器,实时性要求高的读取操作放到master服务器”,“从机仅能做前一天的统计类查询”。
slave同步延迟的原理
MySQL的主从复制都是单线程的操作,主库对所有DDL和DML产生的日志写进binlog,由于binlog是顺序写,所以效率很高。
Slave的IO Thread线程从主库中bin log中读取取日志。
Slave的SQL Thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是随即的,不是顺序的,成本高很多。
由于SQL Thread也是单线程的,如果slave上的其他查询产生lock争用,又或者一个DML语句(大事务、大查询)执行了几分钟卡住了,那么所有之后的DML会等待这个DML执行完才会继续执行,这就导致了延时。也许有人会质疑:主库上那个相同的DDL也会执行几分钟,为什么slave会延时?原因是master可以并发执行,而Slave_SQL_Running线程却不可以。slave同步延迟的可能原因
1--slave的I/O线程推迟读取日志中的事件信息;最常见原因是slave是在单线程中执行所有事务,而master有很多线程可以并行执行事务。
2--带来低效连接的长查询、磁盘读取的I/O限制、锁竞争和innodb线程同步启动等。
3--Master负载;Slave负载
4--网络延迟
5--机器配置(cpu、内存、硬盘)
(主从同步延迟怎么产生的?)总之,当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能处理的承受范围时,主从同步就会产生延时;或者当slave中有大型query语句产生了锁等待也会产生延时。
-
如何查看同步延迟
1--可以通过比对master、slave上的日志位置
2--通过"show slave status"查看Seconds_Behind_Master的值,这个值代表主从同步延迟的时间,值越大说明延迟越严重。值为0为正常情况,正值表示已经出现延迟,数字越大从库落后主库越多。
3--使用percona-toolkit的pt-hearbeat工具进行查看。 -
减少同步延迟的操作方案
1--减少锁竞争
如果查询导致大量的表锁定,需要考虑重构查询语句,尽量避免过多的锁。
2--负载均衡
搭建多少slave,并且使用lvs或nginx进行查询负载均衡,可以减少每个slave执行查询的次数和时间,从而将更多的时间用于去处理主从同步。
3--salve较高的机器配置
4--Slave调整参数
为了保障较高的数据安全性,配置sync_binlog=1,innodb_flush_log_at_trx_commit=1等设置。而Slave可以关闭binlog,innodb_flush_log_at_trx_commit也可以设置为0来提高sql的执行效率(这两个参数很管用)
5--并行复制
即有单线程的复制改成多线程复制。
从库有两个线程与复制相关:io_thread 负责从主库拿binlog并写到relaylog, sql_thread 负责读relaylog并执行。
多线程的思路就是把sql_thread 变成分发线程,然后由一组worker_thread来负责执行。
几乎所有的并行复制都是这个思路,有不同的,便是sql_thread 的分发策略。
MySQL5.7的真正并行复制enhanced multi-threaded slave(MTS)很好的解决了主从同步复制的延迟问题。
Mysql主从环境部署一段时间后,发现主从不同步时,如何进行数据同步至一致?
1 使用数据库监测监测工具percona-toolkit
2 人工对比日志
Mysql最常用的三种备份工具:
- mysqldump:
通常为小数据情况下的备份
innodb: 热备,温备
MyISAM, Aria: 温备
单线程备份恢复比较慢 - Xtrabackup(通常用innobackupex工具):
备份mysql大数据
InnoDB热备,增量备份;
MyISAM温备,不支持增量,只有完全备份
属于物理备份,速度快; - lvm-snapshot:
接近于热备的工具:因为要先请求全局锁,而后创建快照,并在创建快照完成后释放全局锁;
使用cp、tar等工具进行物理备份;
备份和恢复速度较快;
很难实现增量备份,并且请求全局需要等待一段时间,在繁忙的服务器上尤其如此;