大负载
InnoDB存储
Table space:
- leaf node segment
- non-leaf node segment
- rollback segment
Segment
- Extent 1M
- Page
Extent:
- Page 16K,1M / 16K = 64个Page
Page:
- Record,单向链表
- extra info,定长
- Page directory,槽,按主键顺序存放,一个槽可以放多个主键,二分,定长
每个记录大小不同
InnoDB索引
主键
InnoDB的存储是按照主键来存储的,每个表必须有一个主键,不指定的话会自动生成隐藏主键。
B+树
节点单位是页
通常删除都是做逻辑删除而不是物理删除,因为真删除的话会导致页和页之间的合并,影响效率。
哈希索引
当一个页被加载到内存后,可以通过哈希,让主键key作为key,对应的内存地址作为value构建哈希索引。
辅助索引
尽量减少辅助索引的个数,因为插入会不可避免的带来分裂问题
高并发
InnoDB事务
隔离级别
- Read Uncommited,不做隔离,acid全都没有
- Read Commited,隔离性不好,一个事务期间读相同的数据可能值不同(因为别的事务修改,自己修改不算),好的隔离性是说如果一个事务期间自己没有对一个数据做修改那么每次读到的数据都应该是一致的,排它锁
- Repeatable Read,会有幻读情况,排它锁+共享锁
- 串行化,表锁
MVCC
记录的隐藏字段
- DB_TRX_ID:事务id,通常是一个数
- DB_ROLL_PTR
快照
每个事务的快照包含:
- trx_ids:当前事务开始前所有活跃的事务id集合
- low_limit_id:下一个事务id
- up_limit_id:trx_ids集合当中的最小值
Repeatable Read的快照:事务开始时产生
Read Commited:每次select的时候生成Read View
如果读到记录中的事务id比up_limit_id还小,说明在我事务开始前这个事务已经提交了,记录可看
同理,如果读到记录中的事务id大于等于low_limit_id,说明你这个事务虽然提交了,但是在你开始之前我就开始了,所以这条记录不能被我看见
如果事务id大于等于up_limit_id小于low_limit_id,那么要分情况讨论,如果事务id在trx_ids集合中,说明我开始之前已经开始但没有提交修改的事务在我还没提交之前提交了修改,所以我不能看(因为我开始的时候这条数据没有提交);否则说明我事务开始的时候修改这个数据的事务已经提交了,所以可以看
MVCC只能解决读的问题,写的问题无法解决
还有一个问题,比如库存的减少场景
标签:事务,Read,Page,id,limit,MySQL,主键 From: https://www.cnblogs.com/antidogmatist/p/16949263.html