mysql-主从同步---(六)

mysql概述

MySQL是C/S架构模式的关系型数据,也就是Client和Server架构模式。MySQL Server提供数据库服务,完成客户端的请求和操作,Client负责连接到Server。MySQL和其他关系型数据库不一样的地方在于它的弹性以及可以通过插件形式提供不同种类的存储引擎,MySQL请求处理过程会根据不同的存储引擎发生变化,比如事务性的InnoDB和非事务性的MyISAM,数据的存储和SQL的执行会产生很大的差异。本文以MySQL5.7为例,简单介绍MySQL的物理和逻辑架构。

MySQL物理架构

mysql-主从同步---(六)
MySQL是通过文件系统对数据进行存储管理

MySQL从物理结构上可以分为日志文件和数据文件

1.日志文件(顺序IO):
MySQL通过日志记录了数据库操作信息和错误信息。常用的日志文件包括错误日志、二进制日志、查询日志、慢查询日志和事物Redo日志、中继日志等。
可以通过命令查看当前数据库中的日志使用信息
show variables like ‘log_%’;

错误日志(err log):
默认是开启的,而且从5.5.7以后无法关闭错误日志
记录了运行过程中遇到的所有有严重的错误的信息,以及MySQL每次启动和关闭的详细信息。
默认的错误日志名称:hostname.err
错误日志所记录的信息是可以通过log-error和log-warnings来定义的。

二进制日志:
默认是关闭的,需要通过配置:log-bin=mysql-bin进行开启。其中mysql-bin是binlog日志文件的basename,binlog 日志文件的名称:mysql-bin-000001.log
binlog记录了数据库所有的ddl语句和dml语句,但不包括select语句内容,语句以事件的形式保存,描述了数据的变更数据,binlog还包括了每个更新语句的执行时间信息,binlog主要作用是用于恢复数据,因此binlog对于灾难恢复和备份恢复来说至关重要。
如果是ddl语句,则直接记录到binlog日志,而dml语句,必须通过事物提交才能记录到binlog日志中。
binlog还用于实现mysql的主从复制

通用查询日志(general query log):
默认情况下是关闭的
由于通用查询日志会记录用户的所有操作,其中还包含增删改查等信息,在并发操作大的环境下会产生大量的信息从而导致不必要的磁盘IO,会影响mysql的性能,如若不是为了调试数据库的目的建议不要开启查询日志

慢查询日志(slow query log):
默认是关闭的。需要通过设置:slow_query_log=ON进行开启。
记录执行时间超时long_query_time秒所有的查询,便于收集查询时间较长的SQL语句

事物日志(redo/undo log):
事物日志(InnoDB特有的日志)也叫redo日志。
文件名为“ib_logfile0”和"ib_logfile1",默认存放在表空间所在目录
还有一个日志文件叫undo日志,默认存储在ib_data目录下

中继日志(relay log):
是在主从复制环境中产生的日志
主要作用是为了从机可以从中继日志中获取到主机同步过来的SQL语句,然后执行到从机中

2.数据文件(随机IO):

InnoDB数据文件:
.frm文件:主要存放与表相关的数据信息,主要包括表结构的定义信息
.idb文件:使用独享表空间存储表数据和索引信息,一张表对应一个idb文件
.idbdata文件:使用共享表空间存储表数据和索引信息,所有表共同使用一个或者多个idbdata文件。如:系统表数据

MyIsam数据文件:
.frm文件:主要存储与表相关的数据信息,主要包括表结构定义的信息
.myd文件:主要用来存储表数据信息
.myi文件:主要用来存储表数据文件中任何索引的数据树

MySQL逻辑架构

mysql-主从同步---(六)
第一层:服务层(为客户端服务):为请求做连接处理,授权认证,安全等。
第二层:Mysql核心服务层:主要提供,查询解析、分析、优化、缓存以及内置函数,跨存储引擎功能(存储过程、视图、触发器)
第三层:存储引擎层,负责数据的存储和提取

第一层为客户端的连接认证,C/S都有此架构
第二层为服务器层,包含MySQL的大多数核心服务功能
第三层包含了存储引擎,服务器通过API与其通信,API规避了不同存储引擎的差异,不同存储引擎也不会互相通信,另外存储引擎不会去解析SQL(InnoDB是例外,它会解析外键定义,因为服务器本身没有实现该功能)

MySQL服务架构

基本应用
mysql-主从同步---(六)

随着系统中业务访问量的增大,如果是单机部署数据库,就会导致I/O访问频率过高。有了主从复制,增加多个数据存储节点,将负载分布在多个从节点上,降低单机磁盘I/O访问的频率,提高单个机器的I/O性能。

MySQL 主从形式
一主一从
mysql-主从同步---(六)
一主多从,提高系统的读性能
mysql-主从同步---(六)
一主一从和一主多从是最常见的主从架构,实施起来简单并且有效,不仅可以实现HA,而且还能读写分离,进而提升集群的并发能力。
多主一从 (从5.7开始支持)
mysql-主从同步---(六)
多主一从可以将多个mysql数据库备份到一台存储性能比较好的服务器上。
双主复制
mysql-主从同步---(六)
双主复制,也就是互做主从复制,每个master既是master,又是另外一台服务器的slave。这样任何一方所做的变更,都会通过复制应用到另外一方的数据库中。
级联复制
mysql-主从同步---(六)
级联复制模式下,部分slave的数据同步不连接主节点,而是连接从节点。因为如果主节点有太多的从节点,就会损耗一部分性能用于replication,那么我们可以让3~5个从节点连接主节点,其它从节点作为二级或者三级与从节点连接,这样不仅可以缓解主节点的压力,并且对数据一致性没有负面影响。

MySQL 主从复制原理
MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点,如下图所示:
mysql-主从同步---(六)

l 主节点 binary log dump 线程
当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。

l 从节点I/O线程
当从节点上执行start slave命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。

l 从节点SQL线程
SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。

对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进程已经从主节点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。

要实施复制,首先必须打开Master 端的binary log(bin-log)功能,否则无法实现。
因为整个复制过程实际上就是Slave 从Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。如下图所示:
mysql-主从同步---(六)

复制的基本过程如下:

从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position;从节点的I/O进程接收到内容后,将接收到的日志内容更新到本机的relay log中,并将读取到的binary log文件名和位置保存到master-info 文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”;
Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在祝节点上实际执行过的操作,并在本数据库中执行。

MySQL 主从复制模式
MySQL 主从复制默认是异步的模式。MySQL增删改操作会全部记录在binary log中,当slave节点连接master时,会主动从master处获取最新的bin log文件。并把bin log中的sql relay。
l 异步模式(mysql async-mode)
异步模式如下图所示,这种模式下,主节点不会主动push bin log到从节点,这样有可能导致failover的情况下,也许从节点没有即时地将最新的bin log同步到本地。
mysql-主从同步---(六)

l 半同步模式(mysql semi-sync)
这种模式下主节点只需要接收到其中一台从节点的返回信息,就会commit;否则需要等待直到超时时间然后切换成异步模式再提交;这样做的目的可以使主从数据库的数据延迟缩小,可以提高数据安全性,确保了事务提交后,binlog至少传输到了一个从节点上,不能保证从节点将此事务更新到db中。性能上会有一定的降低,响应时间会变长。如下图所示:
mysql-主从同步---(六)

半同步模式不是mysql内置的,从mysql 5.5开始集成,需要master 和slave 安装插件开启半同步模式。

l 全同步模式
全同步模式是指主节点和从节点全部执行了commit并确认才会向客户端返回成功。

binlog记录格式
MySQL 主从复制有三种方式:基于SQL语句的复制(statement-based replication,SBR),基于行的复制(row-based replication,RBR),混合模式复制(mixed-based replication,MBR)。对应的binlog文件的格式也有三种:STATEMENT,ROW,MIXED。
MySQL的三种复制技术:
binlog_format=Statement:基于SQL语句的复制,在MySQL5.1.4之前的版本都是基于SQL语句的复制
binlog_format=ROW:基于行的复制
binlog_Mixed:混合复制模式,基于行的复制和基于SQL语句的复制。

l Statement-base Replication (SBR)就是记录sql语句在bin log中,Mysql 5.1.4 及之前的版本都是使用的这种复制格式。优点是只需要记录会修改数据的sql语句到binlog中,减少了binlog日质量,节约I/O,提高性能。缺点是在某些情况下,会导致主从节点中数据不一致(比如sleep(),now()等)。

l Row-based Relication(RBR)是mysql master将SQL语句分解为基于Row更改的语句并记录在bin log中,也就是只记录哪条数据被修改了,修改成什么样。优点是不会出现某些特定情况下的存储过程、或者函数、或者trigger的调用或者触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是修改table的时候会让日志暴增,同时增加bin log同步时间。也不能通过bin log解析获取执行过的sql语句,只能看到发生的data变更。

l Mixed-format Replication(MBR),MySQL NDB cluster 7.3 和7.4 使用的MBR。是以上两种模式的混合,对于一般的复制使用STATEMENT模式保存到binlog,对于STATEMENT模式无法复制的操作则使用ROW模式来保存,MySQL会根据执行的SQL语句选择日志保存方式。

GTID复制模式
@ 在传统的复制里面,当发生故障,需要主从切换,需要找到binlog和pos点,然后将主节点指向新的主节点,相对来说比较麻烦,也容易出错。在MySQL 5.6里面,不用再找binlog和pos点,我们只需要知道主节点的ip,端口,以及账号密码就行,因为复制是自动的,MySQL会通过内部机制GTID自动找点同步。
@ 多线程复制(基于库),在MySQL 5.6以前的版本,slave的复制是单线程的。一个事件一个事件的读取应用。而master是并发写入的,所以延时是避免不了的。唯一有效的方法是把多个库放在多台slave,这样又有点浪费服务器。在MySQL 5.6里面,我们可以把多个表放在多个库,这样就可以使用多线程复制。

基于GTID复制实现的工作原理
主节点更新数据时,会在事务前产生GTID,一起记录到binlog日志中。
从节点的I/O线程将变更的bin log,写入到本地的relay log中。
SQL线程从relay log中获取GTID,然后对比本地binlog是否有记录(所以MySQL从节点必须要开启binary log)。
如果有记录,说明该GTID的事务已经执行,从节点会忽略。
如果没有记录,从节点就会从relay log中执行该GTID的事务,并记录到bin log。
在解析过程中会判断是否有主键,如果没有就用二级索引,如果有就用全部扫描。

总结
Mysql 主从复制是mysql 高可用,高性能的基础,有了这个基础,mysql 的部署会变得简单、灵活并且具有多样性,从而可以根据不同的业务场景做出灵活的调整。

扩展:MySQL数据库之互联网常用架构方案(全) https://cloud.tencent.com/developer/article/1558484

实战

mysql-主从同步---(六)

上一篇:忘记 mysql 密码怎么办


下一篇:01 mysql 重要的系统参数