MySQL架构原理
2021-08-04 16:49:49 2 举报
AI智能生成
mysql架构原理
作者其他创作
大纲/内容
Mysql架构原理
体系架构:MySQLServer架构自顶向下大致可分为
1. 网络连接层
客户端连接器
提供与MySQL服务器建立的支持
目前几乎支持所有主流的服务端编程技术,例如常见的Java、C、Phython、.Net等,它们通过各自API技术与MySQL建立连接
2. 服务层 MySQL Server
服务层是MySQL_Server的核心,包含六个部分
连接池 Connection Pool
负责存储和管理客户端与数据库的连接,一个线程负责管理一个连接
系统管理和控制工具 Management Services & Utilities
例如备份恢复、安全管理、集群管理等
SQL接口 SQL Interface
用于接收客户端发送的各种SQL命令,并且返回用户需要查询的结果
如DML、DDL、存储过程、视图、触发器等
解析器 Parser
负责将请求的SQL解析生成一个“解析树”,然后根据一些MySQL规则进一步检查解析树是否合法
查询优化器 Optimizer
当“解析树”通过解析器语法检查后,将交由优化器将其转化成执行计划,然后与存储引擎交互
缓存 Cache & Buffer
缓存机制是由一系列小缓存组成的,如表缓存、记录缓存、权限缓存、引擎缓存等
如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据
3. 存储引擎层 Pluggable Storage Engines
存储引擎负责MySQL中数据的存储和提取、与底层系统文件进行交互
MySQL存储引擎是插件式的,服务器中的查询执行引擎通过接口与存储引擎进行通信,接口屏蔽了不同存储引擎之间的差异
现在有很多中存储引擎,各有各的特点,最常见的是MyISAM和InnoDB
4. 系统文件层 File System
该层服务将数据库的数据和日志存储在文件系统之上,并完成与存储引擎的交互,是文件的物理存储层
主要包含日志文件、数据文件、配置文件、pid文件、socket文件等
日志文件
错误日志
默认开启,show variables like ‘%log_error%’
通用查询日志
记录一般查询语句,show variables like ‘%general%’
二进制日志
记录了对MySQL数据库执行的更改操作,且记录了语句的发生时间、执行时长
但是不记录select、show等不修改数据库的SQL
主要用于数据库恢复和主从复制
show variables like ‘%log_bin%’,是否开启
show variables like ‘%binlog%’,参数查看
show binary logs,查看日志文件
慢查询日志
记录所有执行时间超时的查询SQL,默认是10s
show variables like ‘%slow_query%’,是否开启
show variables like ‘%long_query_time%’,超时时长
配置文件
用于存放MySQL所有的配置信息文件,比如my.cnf、my.ini等
数据文件
db.opt
记录这个库的默认使用字符集和校验规则
frm
存储与表相关的元数据信息,包括表结构的定义信息等,每一张表都会有一个frm文件
MYD
M有ISAM存储引擎专用,存放MyISAM表的数据,每一张表都会有一个.MYD文件
MYI
MyISAM存储引擎专用,存放MyISAM表的索引相关信息,每一张MyISAM表对应一个MYI文件
ibd和IBDATA
存放InnoDB的数据文件(包括索引)
InnoDB存储引擎有两种表空间方式
独享表空间
使用.ibd文件来存放数据,每一张InnoDB表对应一个ibd文件
共享表空间
使用ibdata文件,所有表共用一个(或多个,自行配置)ibdata文件
ibdata1
系统表空间数据文件、存储表元数据、Undo日志等
ib_logfile0/ib_logfile1
Redo Log日志文件
pid文件
是MySqld应用程序在Unix/Linux环境下的一个进程文件,和许多其他Unix/Linux服务端程序一样,它存放自己的进程id
socket文件
是Unix/Linux环境下特有的,用户在Unix/Linux环境下客户端连接可以不通过TCP/IP网络而直接使用Unix_Socket来连接MySQL
运行机制
1. 建立连接
通过客户端/服务器通信协议与MySQL建立连接。MySQL客户端与服务端的通信方式是“半双工”,对于每一个MySQL连接,时刻都有一个线程状态来标识这个连接在做什么
通讯机制
全双工
能同时发送和接收数据
例如打电话
半双工
指的是某一时刻,要么发送数据,要么接收数据,不能同时执行两类操作
如早期对讲机
单工
只能发送数据或只能接收数据
如单行道
线程状态
show processlist
查看用户正在运行的线程信息
root能查看所有线程
其他用户只能查看自己的线程
说明
id
线程ID,可以使用:kill xxxx;
user
启动这个线程的用户
host
发送请求的客户端的IP和端口号
db
当前命令执行的所在库
command
该线程正在执行的操作命令
Create DB
正在创建库操作
Drop DB
正在删除库操作
Execute
正在执行一个PreparedStatement
Close Stmt
正在关闭一个PreparedStatement
Query
正在执行一个语句
Sleep
正在等待客户端发送语句
Quit
正在退出
Shutdown
正在关闭服务器
time
表示该线程处于当前状态的时间,单位是s
state
线程状态
Updating
正在搜索匹配记录,进行修改
Sleeping
正在等待客户端发送新请求
Starting
正在执行请求处理
Checking table
正在检查数据表
Closing table
正在将表中数据刷新到磁盘中
Locked
被其他查询锁住了记录
Sending Data
正在处理Select查询,同时将结果发送给客户端
Info
一般记录线程执行的语句,默认显示前100个字符
想查询完整的使用show full processlist
2. 查询缓存
这个MySQL的一个可优化查询的地方
如果开启了查询缓存且在查询缓存中查询到完全相同的SQL语句,则将查询结果直接返回给客户端
如果没有开启查询缓存或没有查询到完全相同的SQL语句,则会由解析器进行语法语义解析,并生成“解析树”
缓存的是Select查询的结果和SQL语句
执行Select语句,先查询缓存,判断是否存在可用的记录集,要求SQL语句完全相同(包括参数值),这样才会匹配缓存数据命中
即使开启查询缓存,以下SQL也不能缓存
查询语句使用SQL_NO_CACHE
查询结果大于query_cache_limit设置
查询中有一些不确定的参数,如now()
优化
show variables ‘%query_cache%’,查看查询缓存是否启动,空间大小,限制等
show status ‘%Qcache%’,查看更详细的缓存参数,可用缓存空间、缓存块、缓存多少等
3. 解析器
将客户端发送的SQL进行语法解析,生成“解析树”
预处理器根据一些MySQL规则进一步检查“解析树”是否合法,如将检查数据表和数据列是否存在,还会解析名字和别名,看看它们是否有歧义,最后生成新的“解析树”
4. 查询优化器
根据“解析树”生成最优的执行计划
MySQL使用很多优化策略生成最有的执行计划,可以分为两类
静态优化(编译时优化)
动态优化(运行时优化)
策略
等价变换策略
5=5 and a>5 改成 a>5
a5 and a=5
基于联合索引,调整条件位置等
优化count、min、max等函数
InnoDB引擎min函数只需要找索引最左边
InnoDB引擎max函数只需要找索引最右边
MyISAM引擎count(*),不需要计算,直接返回
提前终止查询
使用了limit查询,获取limit所有的数据,就不再继续遍历后面数据
in的优化
MySQL对in查询,会先进行排序,再采用二分法查找数据
5. 执行引擎
查询执行引擎负责执行SQL语句,此时引擎会根据SQL语句中表的存储引擎类型,以及对应的API接口与底层存储引擎缓存或者物理文件的交互,得到查询结果并返回给客户端
若开启用查询缓存,这时会将SQL语句和结果完整地保存到查询缓存中,以后若有相同的SQL执行则直接返回结果
返回结果过多,会采用增量模式返回
存储引擎
概述
存储引擎是在MySQL体系架构中的第三层,负责MySQL中的数据存储和提取,是与文件打交道的子系统,它是根据MySQL提供的文件访问层抽象接口定制的一种文件访问机制,这种机制就叫做存储引擎
使用show engies命令,就可以查看当前数据库支持的引擎信息
v5.5之前默认采用MyISAM存储引擎,之后采用InnoDB存储引擎
类型
InnoDB
支持事务,具有提交、回滚和崩溃恢复能力,事务安全
MyISAM
不支持事务和外键,访问速度快
Memory
利用内存创建表,访问速度非常快,因为数据在内存,而且默认使用Hash索引
一旦关闭,数据就会丢失
Archive
归档类型引擎,仅能支持insert和select语句
csv
以csv文件进行数据存储,由于文件限制,所有列必须强制指定not null
不支持索引和分区,适合做数据交换的中间表
BlackHole
黑洞,只进不出,进来就是消失,所有插入数据都不会保存
Federated
可以访问远端MySQL数据库中的表,一个本地表,不保存数据,访问远程表内容
Merge MyISAM
一组MyISAM表的组合,这些表必须结构相同,Merge表本身没有数据,对Merge操作可以对一组MyISAM表进行操作
InnoDB
对比MyISAM
它们都是使用MySQL最常用的两种引擎类型
区别
事务和外键
InnoDB支持事务和外键,具有安全和完整性,适合大量insert或update操作
MyISAM不支持事务和外键,它提供高速存储和检索,适合大量的select查询操作
锁机制
InnoDB支持行级锁,锁定指定记录。基于索引来加锁实现
MyISAM支持表级锁,锁定整张表
索引结构
InnoDB使用聚集索引,索引和记录在一起存储,既缓存索引,也缓存记录
MyISAM使用非聚聚索引,索引和记录分开
并发处理能力
InnoDB读写阻塞可以与隔离级别有关,可以采用多版本并发控制(MVCC)支持高并发
MyISAM使用表锁,会导致写操作并发效率低,读之间并不阻塞,读写阻塞
存储文件
InnoDB表对应两个文件,一个.frm表结构,一个.ibd数据文件。最大支持64TB
MyISAM表对应三个文件,一个.frm表结构文件,一个MYD表数据文件,一个.MYI索引文件。从MySQL5.0开始默认限制是25TB
适用场景
MyISAM
不需要事务支持
并发相对较低(锁机制问题)
数据修改相对较少,以读为主
数据一致性要求不高
InnoDB
需要事务支持
行级锁对高并发有很好的适应能力
数据更新较为频繁的场景
数据一致性要求较高
硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,减少磁盘IO
总结
如何选择
是否需要事务
是否存在并发修改
是否追求快速查询,且数据修改少
在绝大多数情况下,推荐使用InnoDB
存储结构
内存结构
Buffer Pool
缓冲池,简称BP。以Page页为单位,默认大小16k,BP的底层采用链表数据结构管理Page
在InnoDB访问表记录和索引时会在Page页中缓存,以后使用可以减少磁盘IO操作,提升效率
Page管理机制
根据状态来分
free page
空闲页,未被使用
clean page
被使用页,数据没有被修改过
dirty page
脏页,被使用页,数据被修改过,页中数据和磁盘数据产生了不一致
InnoDB通过三种链表来维护和管理
free list
表示空闲缓冲区,管理free page
flush list
表示需要刷新到磁盘的缓冲区,管理dirty page
内部页按修改时间排序
Iru list
表示正在使用的缓冲区,管理clean page和dirty page
缓冲区以midpoint为基点,前面的链表成为new列表区,存放经常访问的数据占63%,后面的链表成为old列表区,存放使用较少的数据,占37%
脏页既存在flush链表,也在Iru链表中,但是互不影响,Lru链表负责管理页的可用性和释放,flush链表负责脏页的刷盘操作
改进型LRU算法维护
普通LRU
末位淘汰法,信数据从链表头部加入,释放空间时从末尾淘汰
改进LRU
链表分为new和old两个部分,加入元素时并不是表头插入,而是从中间midpoint位置插入
如果数据很快被访问,那么page就会向new列表头部移动,如果数据没有被访问,会逐步向old尾部移动,等待淘汰
每当有新的page数据读取到buffer_pool时,InnoDB引擎会判断是否有空闲页,是否足够
如果有,就将free_page从free_list删除,放入到LRU列表中
如果没有,就会根据LRU算法淘汰LRU链表末尾的页,将内存空间释放分配给新的页
配置参数
show variables like ‘%innodb_page_size%’,查看page页大小
show variables like ‘%innodb_old%’,查看LRU链表中old列表参数
show variables like ‘%innodb_buffer%’,查看buffer pool参数
建议
将innodb_buffer_pool_size设置为总内存大小的60-80%
innodb_buffer_pool_instances可以设置为多个,这样可以避免缓存争夺
Change Buffer
写缓冲区,简称CB
在进行DML操作时,如果BP没有其相应的Page数据,并不会立刻将磁盘页加载到缓冲池,而是在CB记录缓冲变更,等未来数据被读取时,再将数据合并恢复到BP中
CB占用BP空间,默认占25%,最大允许50%,可以根据读写业务量来进行调整
innodb_change_buffer_max_size
当更新一条记录时
该记录在BP中存在,直接在BP修改,一次内存操作
不存在,会直接在CB进行一次内存操作,不用再去磁盘查询数据,避免一次磁盘IO。当下次查询记录时,会先进行磁盘读取,然后再从CB中读取信息合并,最终载入BP中
写缓冲区,仅适用于非唯一普通索引页
如果在索引设置唯一性,进行修改时,InnoDB必须要做唯一性校验,因此必须查询磁盘,做一次IO操作
这会直接将记录查询到BP中,然后在缓冲池修改,不会在CB操作
Adaptive Hash Index
自适应哈希索引,用于优化对BP数据的查询
InnoDB存储引擎会监控对表索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应
InnoDB存储引擎会自动根据访问的频率和模式来为某些页建立哈希索引
Log Buffer
日志缓冲区,用来保存要写入磁盘上log文件(Redo/Undo)的数据,日志缓冲区的内容定期刷新到磁盘log文件中
日志缓冲区默认16M,缓冲区满时也会自动将其刷新到磁盘,当遇到BLOB或多行更新的大事务操作时,增加日志缓冲区可以节省磁盘IO
主要是用于记录InnoDB引擎日志,在DML操作时会产生Redo和Undo日志
LogBuffer空间满了,会自动写入磁盘,可以通过将innodb_log_buffer_size参数调大,减少磁盘IO频率
innodb_flush_log_at_trx_commit
控制日志刷新行为,默认为1
值
0
每隔1s写日志文件和刷盘操作,最多丢失1s数据
写日志文件LogBuffer->OS_cache
刷盘OS_cache -> 磁盘文件
1
事务提交,立刻写日志文件和刷盘,数据不丢失,但是会频繁IO操作
2
事务提交,立刻写日志文件,每隔1s进行刷盘操作
磁盘结构
Table Spaces
表空间,用于存储表结构和数据
类型
系统表空间 The System Tablespace
包含InnoDB数据字典、Doublewrite_Buffer、change_buffer,undo_logs的存储区域
也默认包含任何用户在系统表空间创建的表数据和索引数据
它是一个共享的表空间,被多个表共享,数据文件通过innodb_data_file_path控制,默认值是ibdata1:12M:autoextend(文件名:大小:自动扩展)
独立表空间 File-Per-Table Tablespaces
默认开启,是一个单表表空间,该表创建于自己的数据文件中,而非创建于系统表空间中
当innodb_file_per_table选项开启时,表将被创建于表空间中,否则将被创建于系统表空间中
每个表文件表空间由一个.ibd数据文件代表,该文件默认被创建于数据库目录中
表空间的表文件支持动态(dynamic)和压缩(compressed)行格式
通用表空间 General Tablespaces
为通过create_tablespace语法创建的共享表空间
可以创建于mysql数据目录外的其他表空间,其可以容纳多张表,且支持所有的行格式
撤销表空间 Undo Tablespaces
由一个或多个包含Undo日志文件组成
在MySQL5.7版本之前Undo占用的是系统表空间共享区,5.7开始将Undo从中分离出来
InnoDB使用的undo表空间由innodb_undo_tablespaces配置选项控制,默认为0
0代表使用系统表空间ibdata1
大于0表示使用undo表空间undo_001、undo_002等
临时表空间 Temporary Tablespaces
类型
Session Temporary Tablespaces
存储的是用户创建的临时表和磁盘内部的临时表
Global Temporary Tablespaces
存储yoghurt临时表的回滚段(rollback segments)
mysql服务器正常关闭或异常终止时,临时表空间将被移除,每次启动时会被重新创建
InnoDB Data Dictionary
InnoDB数据字典由内部系统表组成,这些表包含用于查找表、索引和表字段等对象的元数据
元数据物理上位于InnoDB系统表空间中,由于历史原因,数据字典元数据一定程度上与InnoDB表元数据文件(.frm文件)中存储的信息重叠
Doublewrite Buffer
双写缓冲区,位于系统表空间,是一个存储区域
在BP的page刷新到磁盘真正的位置前,会先将数据存在双写缓冲区
如果在page写入过程中出现操作系统、存储子系统或mysqld进程崩溃、InnoDB可以在崩溃恢复期间从双写缓冲区中找到页面的一个好备份
大多数情况下,默认启动双写缓冲区,如要禁用,可将innodb_doublewrite设置为0
使用双写缓冲区建议将innodb_flush_method设置为O_DIRECT
innodb_flush_method
控制innodb数据文件及redo_log的打开、刷写模式
值
fdatasync
默认,表示先写入操作系统缓存,然后再调用fsync()函数去异步刷数据文件和redo_log的缓存信息
O_DSYNC
InnoDB使用O_SYNC模式打开并更新日志文件,用fsync()函数去更新数据文件
O_DIRECT
表示数据文件写入操作会通知操作系统不要缓存数据,也不要用预读,直接从InnoDB_Buffer写到磁盘文件
Redo Logs
重做日志是一种基于磁盘的数据结构,用于在崩溃恢复期间更正不完整事务写入的数据
MySQL以循环方式写入重做日志文件,记录InnoDB中所有对BP修改的日志
当出现实例故障(如断电),导致数据未能更新到数据文件,则数据库重启时须redo,重新把数据更新到数据文件
读写事务在执行的过程中,都会不断产生redo_log
默认情况下,重做日志在磁盘上由两个名为ib_logfile0和lb_logfile1的文件物理表示
Undo Logs
撤销日志是在事务开始之前保存的被修改数据的备份,用于例外情况时回滚事务
它属于逻辑日志,根据每行记录进行记录
它存在于系统表空间、撤销表空间和临时表空间中
版本结构演变
v5.7
将Undo日志表空间从共享表空间ibdata文件中分离出来,可以在安装MySQL时由用户自行指定文件大小和数量
增加了temporary临时表空间,里面存储着临时表和临时查询结果集的数据
Buffer Pool大小可以动态修改,无需重启数据库实例
v8.0
将InnoDB表的数据字典和Undo都从共享表空间ibdata中彻底分离出来,以前需要ibdata中数据字典与独立表空间ibd文件中数据字典一致才行,8.0就不需要了
temporary表空间也可以配置多个物理文件,而且均为InnoDB存储引擎并能创建索引,这样加快了处理的速度
用户可以像Orable数据库那样设置一些表空间,每个表空间对应多个物理文件,每个表空间可以给多个表使用,但一个表只能存储在一个表空间中
将Doublewrite Buffer从共享表空间ibdata中也分离出来了
线程模型(后台线程)
IO Thread
在InnoDB中使用了大量的AIO来做读写处理,这样可以极大提高数据库的性能
在v1.0版本之前共有4个IO Thread
wirte
负责读取操作,将数据从磁盘加载到缓存页
read
负责写操作,将缓存脏数据刷新到磁盘
insert buffer
负责将日志缓冲区内容刷新到磁盘
log thread
负责将写缓冲内容刷新到磁盘
后来版本将read和write分别增大到4个,共有10个
Purge Thread
事务提交之后,其使用的undo日志将不再需要,因此需要Purge_Thread回收已经分配的undo页
show variables like '%innodb_purge_threads%'
Page Cleaner Thread
作用是将脏数据刷新到磁盘,脏数据刷盘后相应的redo_log也就可以覆盖,即可以同步数据,又能达到redo_log循环使用的目的
show variables like '%innodb_page_cleaners%'
会调用write_thread线程处理
Master Thread
是InnoDB的主线程,负责调度其他各线程,优先级最高
作用是将缓冲池中的数据异步刷新到磁盘,保证数据的一致性
包含
脏页的刷新
undo页回收
redo日志刷新
合并写缓冲
内部有两个主处理
每隔1s
刷新日志缓冲区,刷到磁盘
合并写缓冲区数据,根据IO读写压力来决定是否操作
刷新脏页数据到磁盘,根据脏页比例达到75%才操作
innodb_max_dirty_pages_pct
innodb_io_capacity
每隔10s
刷新脏页数据到磁盘
合并写缓冲区数据
刷新日志缓冲区
删除无用的undo页
数据文件
文件存储结构
一个ibd文件->Segment->Extent->Page-Row
Tablespace
表空间,用于存储多个ibd数据文件
ibd
用于存储表的记录和索引,一个文件包含多个Segment
Segment
段,用于管理多个Extent,分为数据段(Leaf_node_segment)、索引段(Non-leaf_node_segment)、回滚段(Rollback_segment)
一个表至少会有两个Segment,一个管理数据,一个管理索引。每多创建一个索引,会多两个Segment
Extent
区,一个区固定包含64个连续的页,大小为1M
当表空间不足,需要分配新的页资源,直接分配一个区
Page
页,用于存储多个Row行记录,大小为16K
包含很多类型
数据页
Undo页
系统页
事务数据页
大的Blob对象页
.....
Row
行,包含了记录的字段值,事务ID(Trx_id)、滚动指针(Roll_pointer)、字段指针(Field_pointer)等
Page是文件最基本的单位,无论何种类型的page,都是由page_header、page_trailer和page_body组成
文件存储格式
通过 show table status 命令
一般情况下,如果row_format为REDUNDANT、COMPACT,文件格式为Antelope
如果row_format为DYNAMIC和COMPRESSED,文件格式为Barracuda
通过 information_schema 查看指定表的文件格式
在创建表和索引时,文件格式都被用于每个InnoDB表数据文件(.ibd)
文件格式
在早期的InnoDB版本中,文件格式只有一种,随着发展,出现了新的文件格式,用于支持新的功能
Antelope
先前未命名的,最原始的InnoDB文件格式,支持两种行格式:COMPACT和REDUNDANT
MySQL5.6及其以前版本默认格式
MySQL8.0之后已丢弃
Barracuda
新的文件格式,支持InnoDB所有行格式,包括新的COMPRESSED和DYNAMIC
通过innodb_file_format参数可以设置文件格式,之前默认值是Antelope,5.7版本改为Barracuda
8.0之后弃用此参数
行格式
表的行格式决定了它的行是如何物理存储的,这反过来会影响查询和DML操作的性能
如果在单个页中容纳更多行,查询和索引查找可以更快地工作,缓冲池中所需的内存更少,写入更新时所需的IO更少
每个表的数据分为若干页来存储,每个页中采用B树结构
如果有些字段信息过长,无法存储在B树节点,这时会单独分配空间,此时被称为溢出页,该字段被称为页外列
InnoDB存储引擎支持四种行格式
REDUNDANT
表会将变长列值的前768字节存储在B树节点的索引记录中,其余的存储在溢出页上
对于大于等于768字节的固定长度字段,InnoDB会转换为变长字段,以便能够在页外存储
COMPACT
与REDUNDANT相比,减少了约20%的行存储空间,但代价是增加了某些操作的CPU使用量
如果系统负载是受缓存命中率和磁盘速度限制,那么COMPACT格式可能更快
如果系统负载受到CPU速度的限制,那么COMPACT可能会更慢一些
DYNAMIC
InnoDB会将表中长可变长度的列值完全存储在页外,而索引记录只包含指向溢出页的20字节指针
大于或等于768字节的固定长度字段编码为可变长度字段
支持大索引前缀,最多可以为3072字节,可通过inndb_large_prefix参数控制
COMPRESSED
提供与DYNAMIC相同的存储特性和功能,但增加了对表和索引数据压缩的支持
新格式引入的功能有
数据压缩、增强型长列数据的页外存储和大索引前缀
Undo Log
介绍
数据库事务开始之前,会将要修改的记录存放在Undo日志里
当事务回滚时或者数据库崩溃时,可利用Undo日志,撤销未提交事务对数据库产生的影响
产生和销毁
Undo_Log在事务开始前产生;事务提交时,并不会立刻删除Undo_log,innodb会将该事务对应的Undo_log放入到删除列表中,后面会通过后台线程purge进行回收处理
Undo_log属于逻辑日志,记录一个变化过程
如执行一个delete,Undo_log会记录一个insert
存储
采用Segment方式进行管理和记录。在innodb数据文件中包含一种rollback_segment回滚段,内部包含1024个Undo_log_segment
show variables like '%innodb_undo%'
作用
实现事务的原子性
Undo_log是为了实现事务的原子性而出现的产物
事务处理过程中,如果出现了错误或者用户执行了Rollback,MySQL可以利用Undo_log中的备份将数据恢复到事务开始之前的状态
实现多版本并发控制(MVCC)
Undo_log在MySQL_InnoDB存储引擎中用来实现多版本并发控制
事务未提交之前,Undo_log保存了未提交之前的版本数据,Undo_log中的数据可作为数据旧版本快照供其他并发事务进行快照读
Redo Log
介绍
指事务中修改的任何数据,将最新的数据备份存储的位置,被称为重做日志
生成和释放
随着事务操作的执行,就会产生Redo_log,在事务提交时会将产生Redo_log写入Log_buffer,并不是随着事务的提交就立刻写入磁盘文件
等事务操作的脏页写入到磁盘之后,Redo_log的使命也就完成了,Redo_log占用的控件就可以重用
工作原理
Redo_log是为了实现事务的持久性而出现的产物
防止在发生故障的时间点,尚有脏页为写入表的IBD文件中,在重启MySQL服务的时候,根据Redo_log进行重做,从而达到事务的未入磁盘数据进行持久化这一特性
写入机制
Redo_log文件内容是以顺序循环的方式写入文件,写满则回溯到第一个文件,进行覆盖写
相关配置
每个InnoDB存储引擎至少有1个重做日志文件组,每个文件组至少2个重做日志文件,默认为ib_logfile0和ib_logfile1
可以通过以下参数控制Redo_log存储
show variables like ’%innodb_log%‘
Redu_buffer持久化到Redo_log的策略,可通过inndb_flush_log_at_trx_commit设置
0
每秒提交Redo_buffer->OS_Cache->flush_cache_to_disk,可能丢失一秒的事务数据
由后台Master线程每隔1s执行一次操作
1
每次事务提交执行Redo_buffer->OS_Cache->flush_cache_to_disk,最安全,性能最差的方式
默认值
2
每次事务提交执行Redo_buffer->OS_Cache,然后由后台Master线程再每隔1s执行OS_Cache->flush_cache_to_disk
一般建议选择取值2,因为MySQL挂了数据没有损失,整个服务器挂了才会损失1秒的事务提交数据
Binlog
介绍
RedoLog是属于InnoDB引擎所特有的日志,而MySQL也有自己的日志,即Binary_log(二进制日志),简称BinLog
Binlog是记录所有数据库表结构变更以及表数据修改的二进制日志,不会记录Select和show这类操作
Binlog日志是以事件形式记录,还包含语句所执行的消耗时间
使用场景
主从复制
在主库中开启Binlog功能,这样主库就可以把Binlog传递给从库,从库拿到Binlog后实现数据恢复达到主从数据一致性
数据恢复
通过mysqlbinlog工具来恢复数据
记录模式
Binlog文件名默认为“主机名_binlog-序列号”格式,如oak_binlog-000001,也可以在配置文件中指定名称
模式
ROW(row-based replication,RBR)
日志会记录每一行数据被修改的情况,然后在slave端对相同的数据进行修改
优点
能清楚记录每一个行数据的修改细节,能完全实现主从数据同步和数据的恢复
缺点
批量操作,会产生大量的日志,尤其是alter table会让日志暴涨
STATMENT(statement-based replication,SBR)
每一条被修改数据的SQL都会记录到master的Binlog中,slave在复制的时候SQL进程会解析成和原来master端执行过的相同的SQL再次执行。简称SQL语句复制
优点
日志量小,减少磁盘IO,提升存储和恢复速度
缺点
在某些情况下会导致主从数据不一致,如last_insert_id()、now()等函数
MIXED(mixed-based replication,MBR)
以上两种模式的混合使用,一般会使用SBR保存binlog,对于SBR无法复制的操作使用RBR保存binlog,MySQL会根据执行的SQL语句选择写入模式
文件结构
Binlog文件中记录的是对数据库的各种修改操作,用来表示修改操作的数据结构是Log_event。
不同的修改操作对应不同的Log_event,binlog文件的内容就是各种Log_event的集合
比较常用的Log_event有:Query_event、Row_event、Xid_event等
Log_event结构
timestamp 4字节
事件开始的执行时间
Event Type 1字节
指明该事件的类型
server_id 1字节
服务器的server ID
Event size 4字节
该事件的长度
Next_log pos 4字节
固定4字节,下一个event的开始位置
Flag 2字节
固定2字节,event flags
Fixed part
每种Event Type对应结构体固定的结构部分
Variable part
每种Event Type对应结构体可变的结构部分
写入机制
根据记录模式和操作触发event事件生成log_event(事件触发执行机制)
将事务执行过程中产生的log_event写入缓冲区,每个事务线程都有一个缓冲区
Log_Event保存在一个binlog_cache_mngr数据结构中,该结构中有两个缓冲区
stmt_cache
用于存放不支持事务的信息
trx_cache
用于存放支持事务的信息
事务在提交阶段会将产生的log_event写入到外部binlog文件中
不同事务以串行方式将log_event写入binlog文件中,所以一个事务包含的log_event信息在binlog文件中是连续的,中间不会插入其他事务的log_event
文件操作
状态查看
show variables like ‘%log_bin%’
开启binlog功能
需要修改my.ini配置文件,然后重启MySQL服务
使用 show binlog events 命令
使用mysqlbinlog命令
使用binlog恢复数据
删除binlog文件
mysqldump
定期全部备份数据库数据
mysqlbinlog
可以做增量备份和恢复操作
可以通过设置expire_logs_days参数来启动自动清理功能
默认值,0,表示没启用
1,表示超出1天binlog文件会自动删除
与Redo Log区别
Redo_log属于InnoDB引擎功能,Binlog属于MySQL_Server自带功能,并且是以二进制文件记录
Redo_log是物理日志,记录该数据页更新状态内容,Binlog是逻辑日志,记录更新过程
Redo_log是循环写,日志空间大小固定,Binlog是追加写,不会覆盖使用
Redo_log作为服务器异常宕机后事务数据自动恢复使用,Binlog可以作为主从复制和数据恢复使用。Binlog没有自动crash-safe能力
0 条评论
下一页