数据记录存在页(16k)
页头
双向链表找最大最小
介于最大和最小之间(最大虚记录比页内最大主键大
,最小虚记录比页内最小主键小)
知道要找的数据是不是在此页
记录堆
Rec1.Rec2.Rec.3…..
其中包含删除记录Rec(逻辑删除,由自由空间链表串起来)
未分配区间
slot区
页尾(校验正确用)
物理有序还是逻辑有序
物理有序:数组,读(二分查找)快写慢
逻辑有序:链表,写(移动指针)快读(遍历)慢
物理有序写是无法解决的
逻辑有序的读慢是可以解决的慢。
太底层的东西不需要用策略
链表的二分
类似于跳表
内存池:分配内存
内存页面管理:空闲页(free),有数据(clean),有数据(dirty,有修改)
数据淘汰
数据预热:内存中尽量放访问次数多的数据,防止磁盘到内存的IO
LRU 策略,把最久没被使用的页面淘汰,谁被访问就把谁放到头部
全表扫描会导致热数据缓存被污染。
访问频率 LFU redis
两个LRU:热表LRU,冷表LRU
InooDB LRU实现
冷热分离
FREE LIST > LRU 尾部 (否则为脏页)>LRU FLUSH
old->new时机
innodb-old_blocks_time old区 page存活时间,如果大于3s,移到热表head
new->old
利用mid point始终5/8的特性
事务
特性 ACID
脏读:读到没有提交的数据(严重)
不可重复读:两次数据读取的结果不一样
幻读:select操作数据得到的结果无法支撑后续业务操作(A读123,B插入4,A插入4,A报错,A幻读)
MVCC:多版本并发控制;解决读写冲突的问题
隐藏列:事务id,回滚指针
当前读:加锁 select for update
快照读:不加锁
快照读每次都判断该事务能看到的最新的版本,如果不能看回滚到直至能看到的最新版本。
undo log 存历史版本
redo log 实现书屋持久性
随机写磁盘到顺序写redo log优化了。
锁
锁是怎么加的?
行锁
唯一索引/非唯一索引 * RR,RC 四种情况
间隙锁,两次读之间不会让其他事务插入新的相同记录,避免幻读
表锁:全表扫描缩表
删除没有索引的条件,全表加锁(mysql自己有优化,会自动释放锁,但性能也有消耗)
行级锁作用到索引上(聚簇索引 二级索引)
死锁
表怎么设计,sql怎么写的,针对性解决
为什么innoDB count(*)很慢,因为它没把记录数放在元数据里
有事务,导致数据可见性问题,会影响数据统计,需要实时来统计
离线信息表:离线信息放到表里面,用户上线后再拉出来,离线信息表删除记录。
并发场景主键
主键选择
1.自增主键
2.随机主键
