1. binlog 说明;用于记录数据库执行的写入性操作,以二进制保存在磁盘。binlog 是 mysql 的逻辑日志,由 Server 层进行记录,使用任何存储引擎的 mysql 数据库都会记录 binlog 日志。实际应用中,binlog 用于主从复制、数据备份。
2. binlog 分类;STATMENT、ROW、MIXED,mysql 5.7.7 之前默认格式为 STATMENT,5.7.7 之后默认为 ROW;可以通过命令查看 mysqlbinglog mysql-bin.00001 | more
2.1 STATMENT:基于 SQL 语句复制,每一条修改SQL语句都会记录到binlog
2.2 ROW:基于行复制
2.3 MIXED:基于 STATMENT、ROW 的混合模式
3. 主从复制:Mysql 主从复制需要三个线程:master(binlog dump thread)、slave(I/O thread 、SQL thread)
3.1 binlog dump线程: 主库中有数据更新时,根据设置的binlog格式,将更新的事件类型写入到主库的binlog文件中,并创建log dump线程通知slave有数据更新。当I/O线程请求日志内容时,将此时的binlog名称和当前更新的位置同时传给slave的I/O线程。
3.2 I/O线程: 该线程会连接到master,向log dump线程请求一份指定binlog文件位置的副本,并将请求回来的binlog存到本地的relay log中。
3.3 SQL线程: 该线程检测到relay log有更新后,会读取并在本地做redo操作,将发生在主库的事件在本地重新执行一遍,来保证主从数据同步。
4. 复制过程:
4.1 主库写入数据并且生成binlog文件。该过程中MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。
4.2 在事件写入二进制日志完成后,master通知存储引擎提交事务。
4.3 从库服务器上的IO线程连接Master服务器,请求从执行binlog日志文件中的指定位置开始读取binlog至从库。
4.4 主库接收到从库的IO线程请求后,其上复制的IO线程会根据Slave的请求信息分批读取binlog文件然后返回给从库的IO线程。
4.5 Slave服务器的IO线程获取到Master服务器上IO线程发送的日志内容、日志文件及位置点后,会将binlog日志内容依次写到Slave端自身的Relay Log(即中继日志)文件的最末端,并将新的binlog文件名和位置记录到master-info文件中,以便下一次读取master端新binlog日志时能告诉Master服务器从新binlog日志的指定文件及位置开始读取新的binlog日志内容。
4.6 从库服务器的SQL线程会实时监测到本地Relay Log中新增了日志内容,然后把RelayLog中的日志翻译成SQL并且按照顺序执行SQL来更新从库的数据。
4.7 从库在relay-log.info中记录当前应用中继日志的文件名和位置点以便下一次数据复制。
5. 并行复制 在Mysql 5.6之前,Salve服务器有两个线程I/O线程和SQL线程 I/O线程负责接收二进制日志,SQL线程进行回放二进制日志。如果在MySQL 5.6版本开启并行复制功能,那么SQL线程就变为了coordinator线程,coordinator线程主要负责以前两部分的内容。 不过到MySQL 5.7才可称为真正的并行复制,这其中最为主要的原因就是slave服务器的回放与主机是一致的即master服务器上是怎么并行执行的slave上就怎样进行并行回放。不再有库的并行复制限制,对于二进制日志格式也无特殊的要求。 为了兼容MySQL 5.6基于库的并行复制,5.7引入了新的变量slave-parallel-type,其可以配置的值有: DATABASE:默认值,基于库的并行复制方式 LOGICAL_CLOCK:基于组提交的并行复制方式
6. 主从延迟:根据前面主从复制的原理可以看出,两者之间存在一定时间的数据不一致,也就是所谓的主从延迟。 正常情况下,如果网络不延迟,那么日志从主库传给从库的实际非常短,基本可以忽略。而通常影响主从复制的原因包括: 1. 从库压力大,耗费CPU资源,影响同步速度,造成主从延迟。 2. 从库机器性能低于主库性能 3. 大事务执行,一次delete上万条数据,binlog接近几十G,复制延迟 4. 主库DDL(alter\drop\create) DDL 串行执行,耗时较大 5. 锁冲突,select...for update
7. 降低延迟
7.1 从库上的执行,即sql_thread更新逻辑,在5.6版本之前,是只支持单线程,那么在主库并发高、TPS高时,就会出现较大的主从延迟。 因此,MySQL自5.7版本后就已经支持并行复制了。可以在从服务上设置 slave_parallel_workers为一个大于0的数,然后把slave_parallel_type参数设置为LOGICAL_CLOCK
mysql> show variables like 'slave_parallel%';
+------------------------+----------+
- | Variable_name | Value |
+------------------------+----------+
| slave_parallel_type | DATABASE |
| slave_parallel_workers | 0 |
+------------------------+----------+
7.2 降低多线程大事务并发的概率,优化业务流程
7.3 优化SQL,避免慢查询,减少批量操作
7.4 提高从库机器配置
7.5 主从同机房、通网络、带宽、地域
7.6 主从切换,日志恢复