innoDB
2022-12-30 15:37:10 0 举报
AI智能生成
innodb知识点总结
作者其他创作
大纲/内容
体系架构
后台线程
master Thread
主要负责将缓冲池中额数据刷新到磁盘,保证数据一致性,包括脏页的刷新,合并插入缓冲,UNDO页的回收等
IO Thread
innodb中大量使用了AIO处理写IO请求来提高数据库性能,此线程负责这些IO请求的回调处理
purge Thread
回收已经使用并分配的undo页,可以独立董单独的线程中进行,减轻maste线程的压力
配置innodb_purge_threads=1 可启动此线程
page cleaner Thread
刷新脏页,减轻master Thread的工作及对于用户查询线程的阻塞,进一步提升innodb的性能
内存
缓冲池
内存区域,弥补磁盘速度缺陷,缓冲池的大小影响数据的整体性能
innodb_buffer_pool_size配置大小
缓冲池中的数据页类型:索引页,数据页,undo页,插入缓冲,自适应哈希搜艳遇,innodb存储的锁信息,数据字典信息等
可以有多个缓冲池实例,以减轻数据库内部的资源竞争,增加数据库的并发处理处理能力,innodb_buffer_pool_instances 进行配置,默认为1
内存管理
数据库中缓冲池通过LRU(latest recent used ,最近最少使用)算法管理,频繁使用的放在列表前段,最少使用的放在尾段,
innodb中缓冲池中页默认大小16KB,使用改进的 LRU算法管理,加入midpoint位置,新读取的页,并不直接放入LRU列表首部,而是放入到LRU列表的midpoint位置,innodb下称为minpoint insertion_strategy算法,默认在LRU列表的5/8处,由参赛innodb_old_blocks_pct控制
数据直接放入LRU中可能造成缓冲池中的页被刷新出,影响缓冲池效率,如索引或者数据的扫描操作,可能访问大量数据,但并不活跃,为了解决此类问题引入参数:innodb_old_bolcks_time ,用于表示读取到mid位置需要等待多久才会被加入到LRU列表的热断
buffer pool hit rate 表示缓冲池的命中率,当小于95%时,需要观察是否是由于全表扫描引起的LRU列表被污染的问题
INNODB_BUFFER_POOL_STATS观察缓冲池的 运行状态
INNODB_BUFFER_PAGE_LRU观察每个LRU列表中每个页的具体信息
压缩页,可将原本16kb的页压缩为1,2,4,8KB, 对于非16KB的页,通过unzip_LRU列表管理,通过伙伴算法进行其内存分配
在LRU列表中的页被修改后,该页被称为脏页,即缓冲池中的页和磁盘上的页的数据产生了不一致,此时会通过CHECKPOINT机制将脏页刷新回磁盘,而Flush列表中的 页即为脏页列表,脏页即存于LRU列表,也存于Flush列表,LRU列表管理缓冲池中页的可用性,Flush列表哟管理管理将页刷新回磁盘,两者互不影响
重做日志缓冲
innodb存储引擎首先将重做日志信息放入到这个缓冲区,然后按一定频率将其刷新到重做日志文件,一般重做日志缓冲不需要设置很大,一般1秒钟会将重做日志缓冲刷新到日志文件,innodb_log_buffer_size 控制,默认8MB
将重做日志缓冲中的内容刷新到外部磁盘的重做日志文件的请求
MASTER THREAD 每一秒将重做日志缓冲刷新到重做日志
每个事务提交时会将重做日志缓冲刷新到重做日志文件
当重做日志缓冲池剩余空间小于1/2时
额外内存池
innodb中对雷池的管理通过内存对的方式进行,对一些数据结构本身的内存分配杀死,需要从额外内存池中进行申请,当该区域不够时,从缓冲池中申请
checkpoint技术
目的
缩短数据库恢复时间
数据库宕机时不需要重做所有的日志,只需对checkpoint后的重做日志进行恢复
缓冲池不够用时,将脏页刷新到缓存
重做日志不可用是,刷新脏页
sharp checkpoint
数据库关闭时将所有的脏页刷新会磁盘,默认工作方式,参数:innodb_fast_shutdown=1
fuzzy checkpoint
数据库运行时期 ,刷新一部分脏页到磁盘
类型
master Thread checkpoint
每秒或者每十秒的速度从缓冲池的脏页列表刷新一定比例的页回磁盘,异步操作
FLUSH_LRU_LIST checkpoint
保证LRU列表中需要差不多有100个空闲页可供使用,5.6版本后通过innodb_lru_scan_depth 控制LRU列表中可用页的数量,默认1024
async/sync flush checkpoint
重做日志文件不可用时,强制将一些从脏页列表选取的页刷新会磁盘,保证重做日志的循环使用的可用性
dirty page to much checkpoint
脏页数量太多,强制进行checkpoint,参数innodb_max_dirty_pages_pct控制 ,表示当脏页数量占据百分之多少时,强制进行checkpoint,默认75
Master Thread 工作方式
循环方式
主循环(loop)
每秒钟的操作
每10秒的操作
后台循环(backgroup loop)
刷新循环(flush loop)
暂停循环(suspend loop)
InnoDB 关键特性
插入缓冲(insert buffer)
和数据页一样,是物理页的一部分
对应非聚集索引的插入或者更新,不是每一次都直接插入到索引页中,而是先判断插入的非聚集索引是否在缓冲池中,若在则直接插入,若不在则先放入到一个insert buffer对象中,然后再以一定的频率和情况进行insert buffer和辅助索引页子节点的merge操作,将多个插入合并到一个操作中(在同一个索引页中),大大提高非聚集索引插入的性能
使用条件
索引是辅助索引
索引不是唯一的
辅助索引不能是唯一的,因为插入缓冲时,数据库并不去查找索引页来判断插入记录的唯一性,如果去查找肯又有会离散读取的情况发发生,从而导致insertbuffer 失去了意义
缺点
写密集时,插入缓冲会占用过多的缓冲池内存,默认最大可以占用到1/2的缓存池内存 IBUF_POOL_SIZE_PER_MAX_SIZE 对缓冲池进行控制,代表占用缓冲池内存的多少分之一
大量写时,如果宕机,可能有大量的insert buffer没有合并到实际的非聚集索引中,这时恢复可能需要很长的时间
change buffer
insert buffer的升级
innodb1.0以后,innodb引擎对DML操作 insert,delete,update 都进行缓冲,分别是insert buffer ,delete buffer ,purge buffer
innodb_change_buffering 开启各种buffer 选项,可选值:inserts,deletes,purge,changes,all,none,changes表示启用inserts和deletes ,all 表示启用所有,none 表示都不启用,该参数默认=all
使用条件
非唯一的辅助索引
innodb_change_buffer_max_size控制change buffer 最大使用内存的数量,默认25,代表最大使用1/4的缓存池内存空间, 最大有效值50
内部实现
B+树,由节点页和非节点页注册,非节点页存放的是查询的search key(占用9个字节)
search key 组成:
space,占用4个字节,记录带插入记录所在表的空间id(innodb中,每个表有唯一的space id)
marker,占用 1字节,用来兼容老版本的insert buffer
offset 占用4字节,表示页所在的偏移量
merge insert buffer
发生情况
辅助索引页被读取到缓冲池中时
insert buffer bitmap 页追踪到该辅助索引页已无可用空间时
Master Thread
两次写(double write)
提高了数据页的可靠性
在应用重做日志前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原页,再进行重做
double write 由两部分组成
一部分是内存中的double buffer ,大小为2MB
一部分是物理磁盘上共享表空间中连续的128个页,即2个区(extent),大小为2MB
在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。在这个过程中,因为doublewrite页是连续的,因此这个过程是顺序写的,开销并不是很大,在完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,此时的写入则是离散的。
skip_innodb_doublewrite可用禁用doublewrite功能
自适应哈希索引(adaptive hash index)
通过缓冲池的B+树页构造而来,速度很快,不需要对整张表构建哈希索引
要求:这个页的连续访问模式必须是一样的
默认开启,innodb_adaptive_hash_index 控制是否启用
异步IO(async IO)
提高磁盘操作性能
可以进行IO Merge操作,将多个IO合并为1个IO,提高IOPS的性能
用户可以在一个IO请求发出后立即再发送另一个IO请求,当全部IO请求发送完毕后,等待所有IO操作完成
刷新邻接页(flush neighbor page)
工作原理
当刷新一个脏页时,InnoDB存储引擎会检测该页所在区(extent)的所有页,如果是脏页,那么一起进行刷新。这样做的好处显而易见,通过AIO可以将多个IO写入操作合并为一个IO操作,故该工作机制在传统机械磁盘下有着显著的优势
innodb_flush_neighbors控制是否开启
问题
是不是可能将不怎么脏的页进行了写入,而该页之后又会很快变成脏页
固态硬盘有较高的IOPS,是否需要此特性
文件
参数文件
作用
告诉MySQL实例启动时在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还会介绍各种参数的类型
MySQL启动时不需要参数文件
参数文件以文本方式存储,可直接更改文本编辑器修改参数
参数类型
动态参数
可以在MySQL运行中进行更改
静态参数
整个实例周期内不能更改
日志文件
作用
用来记录MySQL实例对某种条件做出响应时写入的文件,如错误日志文件、二进制日志文件、慢查询日志文件、查询日志文件等
类型
错误日志
对mysqld的启动、运行、关闭进行了记录,用户可以通过命令SHOW VARIABLES LIKE 'log_err'定位
二进制日志
记录了对MySQL数据库执行更改的所有操作,不包括select和show这里操作
作用
恢复
复制
审计
通过二进制日志信息判断是否有对数据库进行注入的攻击
默认关闭,需手动开启
参数
sync_binlog
表示每写缓冲多少次就同步到磁盘,当==1表示,采用同步写磁盘的方式写二进制文件,默认为0
binlog_format
STATEMENT
记录了逻辑sql语句
ROW
记录表的行更改情况,此时当隔离级别设置为 read committed 可以可获得更好的并发性
MIXED
默认采用STATEMENT格式记录日志,但在一些情况下也会使用ROW格式
表的存储引擎为NDB
是用来额UUID(),USER(),CURRENT_USER(),FOUND_ROWS,ROW_COUNT()等不确定函数
是用来额INSERT DELAY语句
使用了用户定义函数(UDF)
使用了临时表
动态参数,可以在数据库运行时更改
慢查询日志
long_query_time 默认10,sql执行超过此时间的都会被记录
log_queries_not_using_indexes 如果sql没有使用所以,也会记录到慢查日志
log_throttle_queries_not_using_indexes 表示每分钟允许记录到slow log的且未使用所以的sql语句次数,默认为0,表示没有限制,
查询日志
查询日志记录了所以对mysql数据库请求的信息,无论这些请求失败都得到了正确的执行,默认文件名:主机名.log
套接字文件
作用
当用UNIX域套接字方式进行连接时需要的文件
pid文件
作用
MySQL实例的进程ID文件
表结构定义文件
作用
用来存放MySQL表结构定义文件
MySQL数据的存储是根据表进行的,每个表都会有与之对应的文件。无论采用何种引擎,MySQL都会有一个以frm为后缀的文件,此文件记录了该表的表结构定义,frm还用来存放视图的定义,frm文件属于文本文件
innodb存储引擎文件
作用
每个存储引擎自己的文件来保存各种数据,正在存储了记录和索引等数据
分类
表空间文件
默认大小为10Mb的ibdata1文件
innodb_data_file_path指定路径,不同的文件位于不同的磁盘,可以提升性能
innodb_file_per_table 可以将每个基于innodb的表产生一个独立表空间,命名规则:表名.ibd,仅仅=存储该表的数据,所以,和插入缓存BITMAP等信息,其余的信息还是存放在默认的表空间
重做日志文件
默认会有ib_logfile0 和ib_logfile1,记录了innodb的事务日志
innodb_log_file_size
指定每个重做日志文件的大学
innodb_log_files_in_group
指定日志文件组中重做日志文件的数量,默认为2
innodb_mirrored_log_groups
指定了日志精选文件组的数量,默认1,表示只有一个日志文件组,没有镜像
innodb_log_group_home_dir
指定日志文件组所在的路径,默认./,表示在MySQL数据库的数据目录下
表
索引组织表
在innodb中,表是根据主键顺序组织存放的,每张表都有一个主键,如果创建时没有显式的定义主键,根据情况选择或创建
首先判断表中是否有非空的唯一索引,如果有,则该列即为主键
如果不符合上述条件,则自动创建一个6字节大小的指针
当表中有多个非空唯一主键是,将在建表时,选择第一个定义的非空唯一索引为主键
innodb逻辑存储结构
innodb汇总所有数据都被落脚点额存放在同一个空间内,称之为表空间,表空间由段,区,页(或者称为块)组成
表空间
innodb存储引擎逻辑结构的最高层,所有的数据都放在表空间内,默认表空间ibdata1
innodb_file_per_table启用后,每张表内的数据可以单独放在一个表空间内,值存放数据,索引,插入缓存bitmap页,其他数据,如回滚信息,插入缓存索引页,系统事务信息,二次写缓存,还是放在原来的共享空间内
段
表空间是由各个段组成,常见段有数据段,索引段,回滚段等
对段的管理由引擎自身完成
区
由连续页组成的空间,任何情况下每个区的大小都为1MB
页
默认大小16kb,innodb1.2后通过参数innodb_page_size可将页设置为4k,8k,16k,一旦设置完成,不可再次进行修改,除非通过mysqldump导入和导出操作来产生新的库
常见页类型
数据页
undo页
系统页
事务数据页
插入缓存位图页
插入缓存空闲列表页
未压缩的二进制大对象页
压缩的二进制大对象页
行
innodb存储引擎是面向列的,即按行进行存放,每个页存放的行,最大允许存放16kb/2—200行的记录,即7992行记录
innodb行记录格式
行溢出数据
所有VARCHAR列的长度总和不能超过65535字节
一般情况下,innodb存储引擎的数据都存放在页类型为B-tree node中,当发生行溢出是,数据存放在页类型为Uncompress BLOB页中
旧文件格式(Antelope文件格式)
compact
mysql5.0中引入,设计目标是高效的存储数据,一个页中放的行数据越多,其性能也越高
redundant
mysql5.0之前的版本的存储方式,5.0支持此格式是为了兼容之前版本的页格式
新文件格式(Barracuda文件格式)
Compressed
存储在其中的行数据会以zlib的算法进行压缩,对于BLOB,TEXT,VARCHAR这类大长度类型的数据能够进行有效的存储
Dynamic
新记录格式对存放在BLOB中的数据采用了完全行溢出的方式
char的行结构存储
存储固定长度的字符类型
多字符集情况下,和VARCHAR的实际存储基本是没有区别的,对于未能占满长度的字符填充0x20
innodb数据页结构
组成结构
FileHeader(文件头)
固定38字节
记录页的头信息
Page Header(页头)
固定56字节
记录数据页的状态信息
Infimun 和Supremum Records
User Records(用户记录,即行记录)
Free Space(空闲空间)
Page Directory(页目录)
File Trailer(文件结尾信息)
固定8字节
named file formats机制
Named File Formats机制
解决不同版本下页结构兼容性的问题
新的文件总是包含之前版本的页格式
innodb_file_format: 查看文件格式
innodb_file_format_check :用来检测当前innodb存储引擎文件格式的支持度,默认ON
约束
数据的完整性
三种形式
实体完整性
一个表中有一个主键
域完整性
选择合适的数据类型确保一个数据值满足特定条件
外键约束
编写触发器
考虑使用DEFAULT约束作为强制域完整性的一个方面
参照完整性保证两张表之间的关系
主键
唯一索引
外键
default
NOT NULL
约束的创建和查找
创建的方式
表建立时进行约束
alter table 创建
约束和索引的区别
对错误数据的约束
设置sql_model = STRICT_TRANS_TABLES 确保数据对合法性严格校验
ENUM 和SET
触发器与约束
外键约束
视图
虚表
作为抽象数据,安全层
分区表
支持水平分区,不支持垂直分区
支持局部分区索引
一个分区中即存放数据又存放了索引
全部分区——不支持
数据存放在各个分区中,但是所有数据的所有放在一个对象中
分区类型
RANGE分区
行数据基于属于一个给定连续区间的列值被放入分区
LIST分区
和RANGE分区类似,只是LIST分区面向的是离散的值
HASH分区
根据用户自定义的表达式的返回值来进行分区,返回值不能为负数
KEY分区
根据MySQL数据库提供的哈希函数来进行分区
无论何种分区,如果表中存在主键或者唯一索引时,分区列必须是唯一索引的一个组成部分
唯一索引可以允许NULL值,并且分区列只要是唯一索引的一个组成部分,不需要整个唯一索引列都是分区列
如果建表时没有指定主键,唯一索引,可以指定任何一个列为分区列
子分区
在分区的基础上再进行分区,也称为复合分区
mysql允许在Range 和List的分区上再进行hash 或Key的子分区
注意问题
每个子分区的数量必须相同
要在一个分区表的任何分区上使用SUBPARTITION来明确定义任何子分区,就必须定义所有的子分区
每个SUBPARTITION子句必须包括子分区的一个名字
子分区的名字必须是唯一的
分区中的NULL值
MySQL允许对NULL值分区
对于RANGE分区,如果插入了null值,会将该值放到最左边的分区
在LIST分区下,使用null值,必须显式的指出放在哪个分区中,否则会报错
HASH和KEY分区中放入空值时,任何分区函数都会将含有NULL值的记录返回为0
索引与算法
常见索引
B+索引
并不能找到给定的具体行,只是找到行数据的所在页,然后把该页读到内存,再再内存中查找到需要的数据
不是二叉树,是平衡树
全文索引
哈希索引
数据结构与算法
二分查找法
二叉查找树和平衡二叉树
B+树
s所有记录节点都是按键值大小顺序放在同一层的叶子节点上,有各个子节点指针进行链接
插入操作
1(leafPage不满,indexPage不满)
直接将记录插入到叶子节点
2(leafPage满,indexPage不满)
1,拆分leafPage
2,将中间节点放入到indexPage中
3,小于中间节点的记录放左边
4,大于或等于中间节点的记录放右边
3(leafPage满,indexPage满)
1,拆分leafPage
2,小于中间节点的记录放左边
3,大于或等于中间节点的记录放右边
4,拆分indexPage
5,小于中间节点的记录放左边
6,大于中间节点的记录放右边
7,中间节点放入上一层indexPage
删除操作
1(也在节点不小于填充因子,中间节点不小于填充因子)
直接将记录从叶子节点删除,如果该叶子节点还是IndePage节点,用该节点的右节点代替
2(叶子节点小于填充因子,中间节点不小于填充因子)
合并叶子节点和它的兄弟节点,同时更新IndexPage
3(叶子节点小于填充因子,中间节点小于填充因子)
1,合并叶子节点和它的兄弟节点
2,更新IndexPage
3,合并IndexPage和他的兄弟节点
B+树索引
聚集索引
按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页
每张表中只能有一个聚集索引
辅助索引
叶子节点并不包含行记录的数据
B+树索引的分裂
B+树索引的管理
Cardinality值
表示索引中不重复记录数量的预估值(不是准确值),实际中,此值应尽可能的接近1
innodb 村粗引擎额Cardinality统计
统计是放在存储引擎层进行的
统计通过采样法完成(否则大表统计会耗时长)
统计的更新发生在insert和update
不是每次都统计
表中1/16的数据已发生过变化
stat_modified_counter>2000000000
哈希算法
哈希表
利用哈希函数,根据关键字计算出槽的位置
多个哈希值相同时,使用链接法
innodb存储引擎中的哈希算法
关键字K=space_id<<20+space_id+offset,然后通过除法散列到各个槽中
自适应哈希索引
由innodb存储引擎自己控制
innodb_adaptive_hash_index开关控制,默认开启
全文检索
通常使用倒排索引实现
在辅助表中存储了单词与单词自身在一个或多个文档中所在位置之间的映射
innodb全文检索
innodb从1.2.x开始支持全文索引,采用full inverted index 的方式
锁
特性描述
用于管理对共享资源的并发访问,提供数据的额完整性和一致性
lock与latch
latch
轻量级锁,要求锁定的时间必须非常段,若持续时间长,则性能会变差
分为mutex(互斥锁)和 relock(读写锁)
保证并发线程操作临界资源的正确性,并且通畅没有死锁检测的机制
lock
对象是事务,用来锁定数据库中的对象,如表,页,行
一般lock的对象仅在事务commit和rollback后进行释放
比较
lock
对象:事务
保护:数据库内容
持续时间:整个事务过程
模式:行锁,表锁,意向锁
死锁:通过waits-for graph,time out等机制进行死锁检测与处理
存在于:Lock Manager的哈希表中
latch
对象:线程
保护:内存数据结构
持续时间:临界资源
模式:读写锁,互斥量
死锁:无死锁检测越处理机制,仅通过应用程序加锁的顺序报错无死锁的情况发生
存在于:每个数据结构的对象中
innodb中的锁
锁类型
行锁
共享锁(S Lock)
允许事务读一行数据
排他锁(X Lock)
允许事务删除或更新一行数据
表锁
意向锁(Intention Lock)
将锁定的对象分为多个层级,意向锁意味着事务希望在更细粒度上进行加锁
意向共享锁
事务想要获得一张表中某几行的共享锁
意向排他锁
事务想要或得一张表中某几行的排它锁
查询事务状态
SELECT * FROM information_schema.`INNODB_TRX`;
一致性非锁定读
指innodb存储引擎通过多版本控制的方式来读取当前执行时间数据库中行的数据
如果读取的行正在执行DELETE或UPDATE操作,这是读取操作不会因此去等待行上的锁释放,而且去读取行的一个快照数据
提高了数据库的并发性,是innodb的默认读取方式,读取不会占用和等待表上的锁,但在不同的事务隔离级别下,读取方式不同
READ COMMITTED下对于快照数据,非一致性读总是读取被锁定行最新的一份快照数据
REPEATABE READ对于快照数据,非一致性读总是读取事务开始是行数据版本
一致性锁定读
支持类型
SELECT 。。。 FOR UPDATE
对读取的行记录加一个X锁,其他事务不能对已锁定的行加任何锁
SELECT ... LOCK IN SHARE MODE
对读取的行记录加一个S锁,其他事务可以向被锁定的行加S锁,但如果加X锁,则会被阻塞
必须在同一个事务中,当事务提交后,锁也会被释放
自增长与锁
外键和锁
外键主要用于完整性额约束检测,如果没有显示的对这个列加锁,innodb会自动对其加一个索引
锁的算法
行锁的3种算法
Record Lock
单个行记录上的锁
Gap Lock
间隙锁
Next-Key Lock
Gap Lock +Record Lock,锁定一个范围,并锁定记录本身
Phantom Problem问题(幻读问题)
Phantom Problem指在同一事务下,连续执行两次同样的SQL语句可能导致不同的结果,第二次SQL语句可能返回之前不存在的行
在默认的事务隔离级别 即Repeatable Read下,INNODB采用Next-Key Locking机制来避免幻读问题
READ COMMITED下采用的是Record Lock
锁问题
脏读
脏数据指事务对缓冲池中的行记录的修改,并且被没有被提交
脏页指在缓冲池中的已经被修改的页,但还没有刷新到磁盘中,即数据库实例内存中的页和磁盘中的页的数据不一致
脏读值在不同的事务下,当前事务可以读到另外事务为提交的数据
不可重复读
在一个事务内两次读取的数据不一样,读到了另一个事务修改的数据
脏读是读到未提交的数据,不可重复读指读到的是已提交的数据,违反了数据库事务的一致性
丢失更新
一个事务的更新操作会被另一个事务的更新操作覆盖,从而导致熟的金额不一致
阻塞
因为不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另个事务中的锁释放它所占用的资源
INNODB中参数innodb_lock_wait_timeout用来控制等待的时间,默认是50秒,可动态修改,innodb_rollback_on_timeout用来设定是否在等待超时是对进行中的事务进行回归操作,默认OFF,代表不回滚,不可动态修改
死锁
死锁值两个或两个以上的事务在执行过程中,因争夺锁资源儿造成的一种互相等待的现象
解决方法
超时机制
wait-for graph 等待图的方式来进行死锁检测
要求数据库保存两种信息1:锁的信息链表,2:事务等待链表
通过链表可以构造出一张图,如图中存在回路,则代表存在死锁
锁升级
指当前锁的粒度降低
锁升级会造成并发性能降低
innodb中不存在锁升级的问题,其不是根据每个记录来产生行锁,是根据每个事务访问的每个页对锁进行管理,采用的是位图的方式,因为不管一个事务锁住页中的一个还是多个记录,开销都是一致的
事务
认识事务
事务特性
原子性
一致性
隔离性
持久性
事务分类
扁平事务
所有操作都在同一层次,有BEGIN WORK开始,有COMMIT WORK或ROLLBACK WORK结束,期间的操作时原子的,要么都执行,要么都回滚
限制:不能提交或者回滚事务的某一部分或者分几个步骤提交
带有保存点的扁平事务
支持扁平事务,运维在事务执行过程中回滚到同一事务中较早的一个状态
链事务
在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式的传给下一个要开始的事务。
带有保存点的扁平事务能回滚到任意正确的额保存点,而链式事务中的回滚仅限于当前事务,即只能恢复到最近的一个保存点,对于锁的处理,链事务在执行COMMIT后即释放了当前事务所持有的锁,而带有保存点的扁平事务不影响迄今为止锁持有的锁
嵌套事务
是一个层次结构框架,有一个顶层事务控制着各个层次的事务
定义
1,嵌套事务是由若干事务注组成的一棵树,子树既可以是嵌套事务也可以是扁平事务
2,处于叶节点的事务是扁平事务,但每个子事务从根到叶节点的距离可以使不同的
3,位于根节点的事务称为顶层事务,其他事务称为子事务
4,子事务皆可以额提交也可以回滚,但是它的提交操作并不会马上生效,除非其父事务已经提交。于是推论出,任何子事务都在顶层事务提交后才会真正提交
5,树中的任意一个事务的回滚会引起它的所有子事务一同回滚,故子事务仅保留A,C,I特性,不具有D的特性
分布式事务
指在分布式环境下运行的扁平事务,需要根据数据所在位置访问网络中的不同节点
事务的实现
redo
物理日志,恢复提交事务修改的页操作
作用:实现事务的持久性
组成
内存中的重做日志缓存(redo log buffer),易失
重做日志文件(redo log file),持久
每次将重做日志缓冲写入到重做日志文件后,innodb因此需要调用异常fsync操作。fsync的效率取决于磁盘的性能,因此磁盘的性能觉得了事务提交的性能,即数据库的性能
日志刷新磁盘策略
innodb_flushh_log_at_trx_commit
1
表示事务提交时必须调用异常fsync操作
0
事务提交时不进行写入重做日志操作,这个操作仅在master thread中完成, 在master thread中每1秒回进行一次重做日志文件的fsync操作
2
事务提交时将重做日志写入重做日志文件,但仅写入文件系统的缓存中,不进行fsync操作,此操作在数据库库宕机而非操作系统宕机时,不会丢失事务数据,当操作系统宕机时,重启数据库会丢失从文件系统缓存刷新到重做日志文件的那部分事务数据
和二进制日志的不同
内容形式不同
二进制日志是逻辑日志,记录的是对应的SQL语句,重做日志是物理格式日志,记录的是对每个页的修改
写入磁盘时间点不同
二进制日志只在事务提交完成后进行一次写入,重做日志在事务进行中不断的被写入
innodb中,重做日志已512字节存储,重做日志缓存,重做日志文件都是以快的方式进行报错,称作 log block,每块大小512字节,此大小和磁盘扇区大小一致,因此重做日志的写入可以保证原子性,不需要doublewrite技术
LSN(日志系列号),8字节,单调递增
代表
重做日志写入的总量
checkpoint的位置
页的版本
不仅记录在重做日志中,还存在每个页中,每个页的头部值FIL_PAGE_LSN,在页中时代表该页最后刷新是LSN的大小
undo
逻辑日志,根据某行记录进行记录,回滚行记录到某个特定版本,在回滚之后,数据结构也页本身可能不相同
存储在数据库内部的一个特殊段中(undo段),位于共享表空间内
除了回滚,另一个作用是实现MVCC
undo log 会产生redo log 因为undo log 也需要持久性的保护
格式
insert undo log
在插入时操作的记录,对其他事务不可见,可以在事务提交后直接删除
update undo log
在delete和update操作时产生的undo log ,该undo log 可能需要提供MVCC机制,不能在事务提交时就进行删除,提交时放入undo log 链表,等待purge线程进行最后的删除
purge
用于最终删除delete和unpdate操作,因为innodb支持MVCC,是否可删除该条记录通过purge进行判断,如果不被任何事务引用就进行真正的删除操作
group commit
一次fsync可以刷新确保多个事务日志被写入文件
事务控制语句
隐式提交的sql语法
对于事务操作的统计
事务的隔离级别
分布式事务
长事务
备份与恢复
性能调优
0 条评论
下一页