1.关于日志
更新操作会先写redolog再集中落盘,这是为了减少io操作。redolog这种东西一般叫作wal(预写日志)。mysql 的redolog大小的是固定的一般是1g。redolog 的write pos是当前写入记录的位置,checkpoint是当前要擦除的位置,擦除之前需要先落盘,flink也有checkpoint的概念jvm也有相同的概念,但是不是知道是不是类似的设计。因为大小是固定的那么整体操作就像是操作一块环形资源,这么去看就发现这种设计的合理之处了。
如果说redolog是物理日志的话,那么binlog就是逻辑日志,redolog只能循环写,但是binlog可以追加写。那整个修改的流程就成了这样。
1.判断修改的数据是否在内存,不在的话的去磁盘捞到内存。
2.修改内存中的值,写入新行。
3.新行更新到内存(这里的更新有点类似更新状态机)。
4.写入redolog处于prepare的阶段。
5.写binlog。
6.提交事务处于commit阶段。
不保证两阶段提交的完整性会咋样。
1.先写redolog,binlog没写完系统崩溃了,在系统恢复的时因为少一条操作sql会导致数据与原来不一致(与redolog中不一致)。
2.先写binlog,redolog没写完系统崩溃了,在系统恢复时因为多了一条操作sql导致数据与原来不一致(与redolog中不一致)。
2.关于事务
事务每次对数据造成改变的时候都会生成一个read-view一个一个reda-view连在一起就形成了一个完整的回滚段,数据存在多个版本就是mvcc(多版本并发控制)。不同事务有不同的数据快照所以,就算在并发情况下也不会有影响。那回滚日志啥时候删除呢,我觉得当然是在commit的时候了,这时候当前事务已经finish了。
为啥不建议使用长事务?对滚日志可能太大。
对于隔离级别的解释
读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到。
读已提交:别人改数据的事务已经提交,我在我的事务中才能读到。
可重复读:别人改数据的事务已经提交,我在我的事务中也不去读。
串行:我的事务尚未提交,别人就别想改数据
3.关于索引
常见的索引类型:哈希表,有序数组,多叉树。
1.哈希表的缺点:因为数据的是无序的所以只适合等值查询不适合范围查询(范围查询需要全遍历)。
2.有序数组:虽然查询很快可以通过下标索引或二分法的方式查询,但是插入代价太大,所以数组只适合不变的数据存储。
3.现在用的最多的存储模型啦,但是要保持平衡,即整棵树所有的左子树的节点点要小于父节点,所有的有右子树的节点要大于父节点。如果这个“叉”的大小为1200,当树高是4的时候就有17亿数据了。查询一个字段只需要访问三次磁盘,又因为树的第二层大概率也在内存里,所以访问次数会更少。
主键索引也叫做聚簇索引,叶子子节点是具体的row。
那么非主键索引就是非聚簇索引,叶子节点存的是主键。
主键查询只需要一次b+树查询。非主键需要要先查非聚簇索引找到主键再去聚簇索引查询具体数据,这种操作也叫做回表。
所以说主键的大小,决定了非主键索引的大小。
如何理解覆盖索引?
如过我们的查询不得不先走二级索引再走主键索引,那是不是多了回表操作呢,如果二级索引的叶子节点对应的就是具体的数据的话,我们不就减去了回表操作了吗,这就是覆盖索引。与其说是覆盖索引,不如说的是联合索引覆盖了这条select语句。
最左前缀原则
这个最左可以是联合索引的最左的n个字段,也可以是字符串索引的最左m个字符。
索引下推
比如说我的联合索引包含两个字段(a,b),我的select语句是where a>10 and b=10,在这个查询过程过程中,在联合索引树中就会筛选出完全符合条件的主键id去回表,如果是老版本mysql的话会把符合>10全部的主键都去回表。增加了回表次数。
如果删除了太多数据需要重建主键怎么办
alter table T engine=InnoDB
如果是非主键索引可以drop->create
4.关于锁
mysql的锁大概可以分为:全局锁,表级锁,行锁三类。
网友评论