InnoDB
2020-09-22 21:38:08 0 举报
Mysql之InnoDB技术详情
作者其他创作
大纲/内容
通过设置一下两个参数调整链表innodb_old_blocks_pct:midpoint的位置(默认是37%)innodb_old_blocks_time:用于表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端。
redo log(页的物理变动)
关于Insert Buffer Bitmap
64个连续页,每个页16KB
ib_logfile2
ib_logfile1
文件
InnoDB通过辅组索引查询数据时,我们先查找辅助索引找到记录的主键id,然后通过主键id在聚集索引中找到记录。前面第二个查看聚集索引的过程就是回表操作。
innodb表空间(逻辑视图)
Purge Thread
物理文件
数据库实例
innoDB Table
对某热点页建立的hash索引,不适范围查询
表结构文件(无论哪种存储引擎,其中的表都对应个定义表结构的文件.frm)
慢查询日志(slow query log)
连接池组件
5个字节40位
Insert Buffer Bitmap追踪页剩余空间若insert buffer 插入到索引时,检测到剩余空间不足1/32的索引页将会前置merge page
重做日志组
该文件不仅记录了所有的错误信息,也记录一些警告信息或正确的信息。
后台线程
Page Cleaner Thread
数据库运行时InnoDB存储引擎内部使用Fuzzy Checkpoint进行页的刷新,即只刷新一部分脏页,而不是刷新所有的脏页回磁盘。
数据段索引段回滚段
联合索引
FLUSH链表包括在LRU链表中,包含的是脏页。LRU中被修改的页都将会加到该链表中去。当没有空闲页时系统会通过checkpoint机制将脏页刷新会磁盘
Bitmap页
缓存池页管理算法 LRU
Async/Sync Flush Checkpoint
ib_logfile0
内存
Mster线程每秒或每10秒都会合并一定量的insert buffer到索引中去
maker
InnoDB存储引擎体系结构
undo log segment
old(将会被淘汰的数据)
作用:事务被提交后,其所使用的undolog可能不再需要,因此需要PurgeThread来回收已经使用并分配的undo页。InnoDB1.1之前在Master Thread线程中完成,InnoDB1.1分离出单独的线程减轻了Master Thread压力,InnoDB1.2可以设置多个线程,提高离散读效率
为了防止数据库宕机导致数据的丢失,数据库采用了Write Ahead Log策略,即事务提交前先将事务写入日志的方式来保证事务的持久性的特征,即使数据库宕机依然可以通过日志来恢复。日志是否可以无限大:如果日志不加限制的增大,我们可能无法确定数据是否已经到达磁盘的阈值。为了解决我们合适更新日志,数据库宕机时恢复到哪里事宜,等一些不确定操作,我们出现了CheckPoint技术(将脏页刷新到磁盘)。
double write buffer(2M)
注意:从InnoDB 1.0.x版本开始,允许有多个缓冲池实例。每个页根据哈希值平均分配到不同缓冲池实例中。这样做的好处是减少数据库内部的资源竞争,增加数据库的并发处理能力。(innodb_buffer_pool_instances 可设置实例数, 默认为1)
FREE链表
查询日志(log)
IO Thread
插入时机
SQL接口组件
Dirty Page too much Checkpoint
InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页(默认大小16kB)的方式进行管理。
常见的存储引擎:InnoDB:1.支持事务和外键,行锁设计,OLTP(在线事务处理),支持非锁定读(读操作不加锁),支持裸设备建立表空间,使用MVCC(多版本并发控制)获得高并发性,实现四种隔离级别。2.InnoDB储存引擎还提供了插入缓冲(insert buffer)、二次写(double write)、自适应哈希索引(adaptive hash index)、预读(read ahead)等高性能和高可用的功能。MyISAM:1.不支持事务和外键、表锁设计,支持全文索引,主要面向一些OLAP(联机分析处理)数据库应用。(一个变量保存了整个表的行数)2.MyISAM存储引擎的另一个与众不同的地方是它的缓冲池只缓存(cache)索引文件,而不缓冲数据文件(数据文件的缓冲交给了操作系统来完成),数据文件的缓存交由操作系统本身来完成,,这点和大多数的数据库都非常不同。3.MyISAM存储引擎表由MYD和MYI组成,MYD用来存放数据文件,MYI用来存放索引文件NDB(NDB存储引擎是一个集群存储引擎):1.数据全部放在内存中,组件查询效率高。(5.1开始非索引文件放在磁盘上)2.关于NDB存储引擎,有一个问题值得注意,那就是NDB存储引擎的连接操作(JOIN)是在MySQL数据库层完成的,而不是在存储引擎层完成的。这意味着,复杂的连接操作需要巨大的网络开销,因此查询速度很慢。如果解决了这个问题,NDB存储引擎的市场应该是非常巨大的。Memory:1.表中数据放于内存中(数据库系统崩溃将导致数据丢失),适用于临时表或数据库厂库中的维度表。采用了hash索引不是b+树。2.只支持表锁,并发性能较差,并且不支持TEXT和BLOB列类型。存储变长字段(varchar)时是按照定常字段(char)的方式进行的,因此会浪费内存。3.MySQL数据库使用Memory存储引擎作为临时表来存放查询的中间结果集(intermediate result)。如果中间结果集大于Memory存储引擎表的容量设置,又或者中间结果含有TEXT或BLOB列类型字段,则MySQL数据库会把其转换到MyISAM存储引擎表而存放到磁盘中。之前提到MyISAM不缓存数据文件,因此这时产生的临时表的性能对于查询会有损失。Archive:1.Archive存储引擎只支持INSERT和SELECT操作,,从MySQL 5.1开始支持索引2.Archive存储引擎非常适合存储归档数据,如日志信息。Archive存储引擎使用行锁来实现高并发的插入操作,但是其本身并不是事务安全的存储引擎,其设计目标主要是提供高速的插入和压缩功能。Federated:1.Federated存储引擎表并不存放数据,它只是指向一台远程MySQL数据库服务器上的表。Maria:1.为替换MyISAM而设计,支持缓存数据和索引文件,应用了行锁设计,提供了MVCC功能,支持事务和非事务安全的选项,以及更好的BLOB字符类型的处理性能。其他:。。。。。。
数据库管理和服务组件
space
发生时机
操控
innoDB行锁的实现:1.innodb通过可重复读 + 间隙锁避免了幻读。2.当查询的索引含有唯一属性时,InnoDB存储引擎对Next-Key Lock进行优化,将其降级为Record Lock,即仅锁住索引本身,而不是范围。3.除了外键约束和唯一性检查依然需要的Gap Lock,其余情况仅使用Record Lock进行锁定。但需要牢记的是,上述设置破坏了事务的隔离性,并且对于replication,可能会导致主从数据的不一致。此外,从性能上来看,READ COMMITTED也不会优于默认的事务隔离级别READ REPEATABLE。
2
表空间id
infimun
字段长度偏移列表(实际也是记录每个字段长度的另外一种方式)
表定义文件.frm
作用:刷新缓存池中的数据,保证缓存池中数据是最新的,并且将修改后的数据刷入磁盘中去。
页:□ 数据页(B-tree Node)□ undo页(undo Log Page)□ 系统页(System Page)□ 事务数据页(Transaction system Page)□ 插入缓冲位图页(Insert Buffer Bitmap)□ 插入缓冲空闲列表页(Insert Buffer Free List)□ 未压缩的二进制大对象页(Uncompressed BLOB Page)□ 压缩的二进制大对象页(compressed BLOB Page)
1.重做日志没有写入事务没有提交数据库宕机:不进行任何恢复2.重做日志写入事务未提交数据库宕机进行相应的回滚3.重做日志写入事务提交单没有写入磁盘,即磁盘页的LSN小于重组日志的LSN进行事务的重做。
查询分析器组件
脏页太多时:当缓存池中脏页数达到百分之75时将会刷新一部分脏页到磁盘中去。
Cardinality : 索引的区分度,该值由数据引擎通过采样的方式(在数据1/16发生变化时或数据变动次数超过某个值时,取八个页采样进行计算)得到,并且只是一个估值,我们应该选择区分度高的数据创建索引。
存储引擎
Master Thread(总循环)
作用:主要负责IO请求的回调处理。(InnoDB中IO请求大量使用了AIO,提高处理性能)。有四类线程:write、read、insert buffer,log IO thread。
文件的集合
回滚段(位于共享表空间)128
dirty
InnoDB通过辅组索引查询数据时,我们查找辅助索引就可以找到我们想要的数据。没有回表操作减少了IO次数。
innoDB中锁类型:共享锁:共享锁也可称读锁,当事务进行读操作时其他事务无法对该资源进行写操作,但是可以读。排他锁:排他锁也可称写锁,当一个事务进行写操作时其他事务无法对该资源进行写或者读。意向锁:https://blog.csdn.net/weixin_41237676/article/details/89567398
offset
重做日志不可用时(重做日志循环的设计):如果未同步到磁盘的重做日志记录小于重做日志大小的75%不会引起Checkpoint,75% ~ 90% 引起 Async , 90%引起 Sync
检查索引页是否还有记录在insert buffer中
共享表空间文件(ibdata1)
叶子节点
1.参数文件
1
13个字节
缩短数据库恢复时间,数据库宕机时无需重做所有日志,只需重新做CheckPoint点之后的日志。
Buffer Bitmap每条记录格式
2.两次写(https://www.cnblogs.com/xuliuzai/p/10290196.html)
当前缓冲池中脏页比例大于90%时,刷新100个InnoDB的缓冲池中的脏页到磁盘(可能)
insert buffer B+树
CheckPoint作用
Redundant
稀疏目录(查看页中记录前先二分查看该目录确定大概范围)
1.提出当我们写入一个页到磁盘写到一半时数据库宕机了,此时称部分写失效,并且此时磁盘中被写的页的数据 是不完整的即该页已经被破坏了,即使我们通过日志进行数据库恢复,也是无效的因为该页本身已经被破坏,日志记录的是在页中操作。
Master Thread Checkpoint
innoDB中采用了非一致性读:当一个事务对行上写操作时,其他事务读取该行时是读取的快照(实际是undo页),之后再read commited 或 可重复读隔离级别下才会有该方式。外键和锁:当一个表中外键没有加索引时innodb回自动给他加上索引,向该表中插入数据时我们先查看主表,此时对主表不能采用非一致性读因为可能导致数据不一致的情况,需要先对主表加上一个共享锁。
检测
InnoDB特性
磁盘
new (活跃热点区数据)
innodb_data_file_path
与索引覆盖类似,当我们通过辅组索引再通过聚集索引找到记录时,此过程有回表操作,我们需要的只是记录中的一两列,我们可以将这一两列建立成辅组索引这样查询时可以减少回表操作了。
数据字典信息
记录插入insert buffer顺序
离散写
数据页 data_page
InnoDB 内存池
错误日志(error log)
检测过程中
Sharp Checkpoint
作用:InnoDB 1.2.x版本中引入的,将之前版本中脏页的刷新操作都放入到单独的线程中来完成,减轻原MasterThread的工作及对于用户查询线程的阻塞,提高性能。
表示该页有记录在insert buffer中
(full purge)删除无用的Undo页(总是(只有undo可以被删除时才会删除,如果之后有事务要用到之前的版本,该undo页将不会被删除))
二次写缓冲
关于锁升级:当某个事务锁定同一页中过多的记录数时,可以升级称页锁,同样页锁也可以升级称表锁,表锁可升级称数据库锁,粒度不断增大。好处:当我们锁粒度过小锁的数量可能回很多 ,锁信息占用的内存可能过大,升级减少了锁占内存。坏处:锁粒度过大并发性降低。
循环10次每次 sleep 1s(主循环)
刷新100个或者10个脏页到磁盘(总是)(如果有超过70%的脏页,则刷新100个脏页到磁盘,如果脏页的比例小于70%,则只需刷新10%的脏页到磁)
将日志缓冲刷新到磁盘(总是)
pidfile (记录数据库实例进程idshow variables like 'pid_file')
重做日志缓存redo_log_buffer
3.pid文件 表结构文件
每行数据除了用户定义的列外,还有两个隐藏列,事务ID列和回滚指针列,分别为6字节和7字节的大小。若InnoDB表没有定义主键,每行还会增加一个6字节的rowid列。
mysql体系结构
回表
undo页
。。。。。。1024
行记录是以链表的形式存在Infimun 作为链表的头Supremun 作为链表的尾部
区:一个区有16个连续的页,当我们设置innodb_file_per_table,初始情况下表空间96K(6个页),但是区大小总是64个连续的页。需要注意的是为了节省磁盘空间大小,对于一些小的表空间如undo此类的段,我们每必要一次性申请这么多空间。所以在申请64个连续的页空间之前我们先分配一些碎片页(32个页),当数据页达到32个页时之后的申请都是64个页(即之后表空间都是64个页的整数倍)。
二进制日志(binlog)
Compact
二进制日志和重做日志的区别:1.二进制日志时针对整个数据库(包括各个储存引擎)的对数据库变动的逻辑的记录,重做日志则是针对InnoDB存储引擎的对页上面物理变动的修改的记录。2.二进制日志仅在事务提交时进行一次的磁盘写操作(提交前放在缓冲中),重做日志是在事务进行过程中不断的进行写入磁盘。
Next-Key Lock
索引页中可用空间
如果启用了innodb_file_per_table的参数,需要注意的是每张表的表空间内存放的只是数据、索引和插入缓冲Bitmap页,其他类的数据,如回滚(undo)信息,插入缓冲索引页、系统事务信息,二次写缓冲(Double write buffer)等还是存放在原来的共享表空间内。注意:表空间大小会随需要增大 但是但是当空间又变得可用时不会变小。
作用:主要负责将缓存池中的数据异步刷新到磁盘中去(包括脏页刷新,合并缓存插入,回收UNDO页)
实际存记录的位置
Fuzzy Checkpoint
supremum
□ Master Thread每一秒将重做日志缓冲刷新到重做日志文件;□ 每个事务提交时会将重做日志缓冲刷新到重做日志文件;□ 当重做日志缓冲池剩余空间小于1/2时,重做日志缓冲刷新到重做日志文件。
☆重做日志(数据库宕机时恢复使用)
多个字段组成的一个索引。对于联合索引(a,b,c)我们可以对(a)进行索引,对(a,b)索引,对(a,b,c)索引,这就是所谓的最左匹配原则。该索引的好处在于如果我们固定a或固定a,b并且我们得到的结果对b或对c排序,我们可以省略 排序的过程因为得到的结果本来就是有序的。
锁定某个范围(对于使用辅组索引时)
索引下推
索引
合并至多5个插入缓冲(总是)
1.扁平事务:最普通的事务包括开始提交回滚,事务中间出错将回滚到最开始,对于写长的事务回滚到最开始重新开始事务似乎很浪费时间。2.带有保存点的扁平事务:相比扁平事务加入保存点,可以事务中止时可以回滚到指定的保存点。3.链事务:请一个事务的提交和下一个事务的开始是一个原子操作,实际上将链上所有事务看成同一个事务得话就是只能回滚到上一个事务。4.嵌套事务:层次结构的事务,父事务中包含子事务,父事务回滚将导致子事务回滚即使子事务已经提交。5.分布式事务:网络中多个不同的计算机共同完成同一个事务。(多个网络结点要么都完成要么都不完成)innodb支持1,2,3,5
merge page
定位页在哪个表的多少号
插入式存储引擎:Mysql区别其他数据的一个重要特征是插入式存储引擎,Mysql提供了各种各样的存储引擎来因对不同的场景,提高数据库系统性能。可以修改存储引擎的源码来提高性能,也可以根据存储引擎接口开发自己的存储引擎。(存储引擎是基于表的)
LRU : 最近最少使用,采用单链表进行实现,将新加入的页插入链表头部,淘汰尾部页(最久没有使用的页),InnoDB对其进行优化,引入midpoint点(大约在链表5/8的位置),新进来的页插入到该位置,midpoint前面的数据叫做活跃的热点数据new,后面的数据认为是不常用的数据old。
日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
innodb_data_file_path:所有基于InnoDB存储引擎的表的数据都会记录到该共享表空间中innodb_file_per_table:用户可以将每个基于InnoDB存储引擎的表产生一个独立表空间。独立表空间的命名规则为:表名.ibd。通过这样的方式,用户不用将所有数据都存放于默认的表空间中
格式:
使用插入缓存的前提条件:非唯一的辅助索引:为何非唯一,如果是唯一的辅助索引,当我们插入到辅助索引页时,我们还需要去检查其唯一性,而此过程将涉及到磁盘的随机读,插入缓存就是为了减少磁盘随机读,如果这样还将失去设计其原来的意义了。
兼容老版本
每个一表私有的表空间文件
对于char的null值会占用空间,对于varchar的null不会占用任何空间
自适应hash算法
对于char类型没有占的空间用0x20来填充
空闲空间
undo log
后台循环
后台线程流程:读取:读取请求时,先检查缓存池中是否已加载过该页,加载过直接读取,未加载时先读入缓存池中。修改:修改数据时,修改的数据先发生在缓存池中,并会按一定的频率来刷入磁盘(采用CheckPoint技术)
数据
★实现
数据库
插入缓冲 insert_buffer
重做日志组采用循环写入的方式,ib_logfile0写满写ib_logfile1,ib_logfile1写满写ib_logfile2,最后又写ib_logfile0.相关参数:innodb_log_file_size:指定每个重做日志文件的大小innodb_log_files_in_group:指定了日志文件组中重做日志文件的数量(默认2)innodb_mirrored_log_groups指定了日志镜像文件组的数量(默认1)注意重做日志大小设置:太大会导致数据库宕机时恢复时间太长,太小导致重做日志容易被覆盖进而导致频繁asyn flush checkpoint重做日志有一个阈值capacity超过阈值将强制刷新脏页
锁
镜像提高数据库高可用性
真正操控数据库的东西(进程)
行锁的3算法
Master 线程没秒或每10秒会刷新一部分线程到磁盘(该过程或开启新线程Page Cleaner,所以是异步的,用户线程不会被阻塞)
有
Record Lock
Record Lock + Gap Lock
表共享空间file(2M)
注意:自适应哈希索引、Lock信息、InsertBuffer等页,不存在于LRU列表中
innodb_file_per_table
1.当我们索引时唯一的时候,我们只需要锁定该行记录即可无需间隙锁,因为其他事务不可能插入该索引相同的值(唯一性约束),提高并发性。2.当索引时非唯一性索引时,我们需要gap lock对其进行向上或向下找到与其不同的(第一个小于或第一个大于其的值)进行范围的锁定,因为在这个范围内可以插入与该索引列相同的而唯一索引不同的记录,这样回产生幻读。
1.记录一些数据库中查询时间较长的一些SQL(参数long_query_time来设置,默认值为10,代表<10秒)2.log_queries_not_using_indexes,如果运行的SQL语句没有使用索引,则MySQL数据库同样会将这条SQL语句记录到慢查询日志文件。3.log_throttle_queries_not_using_indexes,用来表示每分钟允许记录到slow log的且未使用索引的SQL语句次数。该值默认为0,表示没有限制4.slow_log表的定义会发现该表使用的是CSV引擎5.用户可以通过额外的参数long_query_io将超过指定逻辑IO次数的SQL语句记录到slow log中。该值默认为100,即表示对于逻辑读取次数大于100的SQL语句,记录到slow log中
copy
FLUSH链表
内存池
该页为insert buffer的索引页
合并插入缓冲(可能)当前一秒IO次数小于5时认为当前IO压力小
对于重做日志的恢复操作:数据库启动时先查看磁盘的LSN和重做日志的LSN是否相同,大于不用管,小于将重做日志的那部分进行重做。
1.插入缓冲
...
☆2.日志文件
latch:轻量级锁,锁的是临界资源,没有死锁检测,主要有互斥量和读写锁。lock :锁的是事务,只有在事务回滚或提交时才会释放锁资源,有死锁检测机制,主要有行锁表锁意向锁。
缓存池不够用时刷新脏页到磁盘:LRU链表不够用时,依据LRU算法将链表末端的脏页刷新到磁盘,
锁信息lock_info
metadata
4字节
1.二进制日志:记录了对MySQL数据库执行更改的所有操作,但是不包括SELECT和SHOW这类操作2.作用:span style=\"font-size: inherit;\
一行中最多只用1023个列
。。。
1.What?是一个页,用来记录每个索引页(16384个页)的在Insert Buffer中的情况,以及索引页剩余可用空间。2.insert buffer插入时机如右图
一次申请4~5个区(相当于磁盘一个扇区512k)(一个区1MB)
删除无用的Undo页(总是)
2.两次写为了解决上面的问题,如右图所示,当我们写入一个脏页到磁盘中时,我们先将页拷贝到内存中double buffer中,然后分两次写入磁盘,先写道磁盘表共享空间,该过程时顺序写的因为所有的脏页都写在同一块区域,效率较高。接着才真正写入如磁盘表空间,此过程时随机写的。当数据库宕机时,我们可以先通过共享的表空间将表空间中页恢复完整然后再进行日志重写。
midpoint的加入避免了因全表搜索等加载大量页,并且可能只用一次导致的LRU的污染,即活跃的热点数据被刷出,下次再次需要时需重新IO,降低效率。
插入缓冲B+树结构(该树是一个全局的即在共享表空间中)
1.对内存的管理是通过一种称为内存堆(heap)的方式进行的。在对一些数据结构本身的内存进行分配时,需要从额外的内存池中进行申请,当该区域的内存不够时,会从缓冲池中进行申请2.帧缓冲(frame buffer) 以及对应的缓冲控制对象(buffer controll block,这些对象记录了一些诸如LRU、锁、等待等信息)这些数据对象本身的内存进行分配时,需要从额外的内存池中进行申请
midpoint
事务
FLUSH_LRU_LIST Checkpoint
重做日志信息先刷入该缓冲区,在刷入磁盘日志文件(innodb_log_buffer_size控制,默认为8MB)
页偏移量
额外内存池
Master Thread
跳回主循环
非叶子节点
InnoDB内存池
表空间
Select查询
用来记录行中变长字段长度的(顺序按照行中列逆顺序)该字段最多2个字节,因此varchar最大长度不能超过65535
单行锁定(唯一性约束和外键约束单行的锁定)
行溢出:由于行格式记录Varchar长度的信息最大只能有2个字节,因此行中最大列大小为65535 - 3个字节(3个字节其他开销),页的总大小只有16KB,因此当申请大于此值时的数据时会保存varchar的前768个字节(新出的Barracuda格式只保存blob页地址),通过一个地址指向blob页。注意:行中至少有两条记录 ,当满足两条记录时大数据记录不会转换成Blob页,
行(单页行数量限制:16k / 2 ~ 200)
page Directory
记录了数据库中所有的请求信息(查询)无论正确与否,甚至Access define
FILE_PAGE_LSN : 保证页被完整写入
Gap Lock
CPU和磁盘之间速度相差几个数量级,利用缓存池来提高数据库系统整体性能
缓冲器组件
优化器组件
如果当前没有用户活动,则切换到background loop 后台循环(可能
从重做日志缓冲往磁盘写入时,是按512个字节,也就是一个扇区的大小进行写入。因为扇区是写入的最小单位,因此可以保证写入必定是成功的。因此在重做日志的写入过程中不需要有doublewrite。innodb_flush_log_at_trx_commit:0:无论事务是否提交都等到master thread来处理缓存日志刷入磁盘1:事务提交时必定缓存日志写入磁盘2:事务提交时不一定已写入磁盘,会先写道文件缓存中,即使数据库崩了,只要操作系统没蹦仍然可以恢复
事务信息
以key = value 键值对的方式存在动态参数类型:数据库实例运行期间可以改变静态参数类型:数据库运行期间不可以改变(只读)@@global (全局有效,数据库实例关闭无效)@@seesion(会话有效)
缓冲池 innodb_buffer_pool
索引页 index_page
4.innoDB存储引擎文件(以上为数据库相关文件)
用户需要页时,LRU链表中没有足够的页或小于100,通过LRU算法会移除链表尾部的页,这些页中包括脏页将会导致CheckPoint,5.6放入Page Cleaner线程中用户线程不会阻塞
恢复
表空间文件
在数据库启动时,会有一个Free链表,该链表表示空闲的页,当LRU申请页时会先检查该链表是否有空闲页,如果有会将该链表中的页加入到LRU链表中。如果没有将会将LRU中页刷入磁盘。
LRU链表
每10s的操作
刷新100个脏页到磁盘(可能的情况下(10秒内IO次数小于200))
CheckPoint
优化器不选用索引的情况:某些范围查询当我们有非聚集索引(a,b)时,我们对a进行范围查询时,优化器没有通过a进行索引查询,而是进行的全表扫描。当我们选择a索引时,确实我们可以很快得到一个关于a索引的范围,但是我们通过a索引范围内数据再去聚集索引找对应的数据时,此过程是离散读的过程(因为记录不是依据非聚集索引顺序物理存放的),所以通过全表扫描的方式可能比走索引的方式快。关于MRR(Multi-Range Read)优化我们通过非聚集索引查询得到结果后缓存然后根据主键id进行排序,然后通排序结果去聚集索引查询。
3
标记行中字段为null的列(此时该列将不占行空间)
合并20个插入缓冲(总是)
Sharp Checkpoint发生在数据库关闭时将所有的脏页都刷新回磁盘,这是默认的工作方式,即参数innodb_fast_shutdown=1。
索引覆盖
页结构
顺序写
什么时插入缓冲?为什么插入缓冲?表中数据都是按照主键索引的顺序存储,当我们按照主键索引的顺序插入大量数据时,由于这些数据在磁盘中同一个页中,因此IO读取一个页就可以插入多条顺序的数据,IO效率高,但是表中可能还存在辅助索引,为了维护辅助索引结构,我们同样需要插入辅助索引页,而这个过程设计到随机读取,即多个记录不在一页中,导致IO次数多,效率低。对于上面情况我们可以通过插入缓冲来解决,即我们插入辅助索引页时,我们不立即插入而是等到合适的时间将多个在同一个页中的数据合并插入,这样就减少了IO次数。注意:插入缓冲是一个物理页,并不是内存池,Insert Buffer 采用了B+树来保存那些待插入的辅助索引。
重做日志不可用时刷新脏页到磁盘:(重做日志使用的循环结构,需被覆盖的部分无法被覆盖)
0 条评论
下一页