数据记录存在页(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.随机主键