it_worker365

   ::  ::  ::  ::  :: 管理

innodb_file_per_table = ON 表示的是,每个 InnoDB 表数据存储在一个以 .ibd 为后缀的文件中, drop table 命令,系统就会直接删除这个文件

删除行标记记录为删除态,不回收空间,如果后续插入在B+记录相同位置可复用,记录的复用,只限于符合范围条件的数据,跟整页复用不同,整页复用是整个页所有记录删除,空间整体复用

按索引顺序插入没有空洞,否则也可能也分裂产生空洞,更新相当于删除+插入,也会造成空洞,解决方法是重建表,回收空间

Online DDL  建立临时文件,扫描主键数据页生成B+树存入临时文件,期间中间的数据操作记日志,完成后将日志应用到临时文件,将临时文件替换为数据文件

 

InnoDB ,执行 count(*) 需要把数据一行一行地从引擎里面读出来,然后累积计数,为什么不记录在磁盘,因为可重复读用到多版本并发控制(MVCC)同一时刻结果未必相同,需要根据会话判断是否可见,另外,由于主键索引树的叶子节点是数据,而普通索引树的叶子节点是主键值,所以结果相同的情况下,扫描少的

缓存计数的问题,缓存丢失更新,db和redis不一致

计数表记录可以考虑,也需要用事务处理一致性问题

count(字段)<count(主键 id)<count(1)≈count(*)

count(主键 id) ,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加

count(1),InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加,好于上面

count(字段),not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加,允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加

count(*) 是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count(*) 肯定不是 null,按行累加

 

包括 MySQL 高可用在内的很多系统机制都依赖于 binlog,redo log 是循环写,写到末尾是要回到开头继续写的。这样历史日志没法保留,redo log 也就起不到归档的作用

redo log 并没有记录数据页的完整数据,所以它并没有能力自己去更新磁盘数据页,也就不存在“数据最终落盘,是由 redo log 更新过去”的情况

正常运行的实例的话,数据页被修改以后,跟磁盘的数据页不一致,称为脏页。最终数据落盘,就是把内存中的数据页写盘

在崩溃恢复场景中,InnoDB 如果判断到一个数据页可能在崩溃恢复的时候丢失了更新,就会将它读到内存,然后让 redo log 更新内存内容。更新完成后,内存页变成脏页,落盘将内存写盘

redo log buffer 就是一块内存,用来先存 redo 日志的,真正把日志写到 redo log 文件(文件名是 ib_logfile+ 数字),是在执行 commit 语句的时候做的

posted on 2021-03-11 08:56  it_worker365  阅读(45)  评论(0编辑  收藏  举报