mysql磁盘数据存储 + sql执行过程

2021/9/29 19:12:42

本文主要是介绍mysql磁盘数据存储 + sql执行过程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

磁盘存储 

null值列表

头字段

数据落盘

sql流转过程

​存储引擎(innodb)

1. 事务未提交,mysql宕机

​ 2. 事务提交,redoLog更新策略

2.1 innodb_flush_log_at_trx_commit = 0

2.2 innodb_flush_log_at_trx_commit = 1 

 2.3 innodb_flush_log_at_trx_commit = 2

 3. binlog

3.1 sync_binlog = 0

3.2 sync_binlog = 1

crud


磁盘存储 

CREATE TABLE `teach` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(64) DEFAULT NULL,
  `sex` char(1) DEFAULT NULL,
  `phone` char(11) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

该表的数据类型分别为:

int varchar(64) char(1) char(11) varchar(255)

“1 yang 男 13866668888 河南省”   第一行数据

“2 zhang 女 13899990000 内蒙古维吾尔族自治州”  第二行数据

在磁盘上存储数据的时候,数据是挨着存储的

“1 yang 男 13866668888 河南省 2 zhang 女 13899990000 内蒙古维吾尔族自治州“

如果字段是varchar类型可变类型的时候,就会造成无法知道第一行与第二行数据的切分点在哪里

真实的磁盘上存储的数据为:

0x03 0x11 0x4 null值列表 头字段 1 yang 男 13866668888 河南省 0x10 0x11 0x05 null值列表 头字段 2 zhang 女 13899990000 内蒙古维吾尔族自治州

标注变长字段的顺序是 逆序 说明

表结构为:

CREATE TABLE customer (
name VARCHAR(10) NOT NULL,
address VARCHAR(20),
gender CHAR(1),
job VARCHAR(30),
school VARCHAR(50)
) ROW_FORMAT=COMPACT;

假设一条数据为: “jack NULL m NULL zzuSchool”

0x09 0x04 0000 0101 0000000000000000000010000000000000011001 jack m zzuSchool

null值列表

00000101 

0101 对应的是可以为空的四个字端,是NULL的时候,标注为1,不是标注为0

address gender job school, gender 和 school不为空 0101,NULL标记位以8bit为基本单位进行扩容,不够的前面补零

头字段

00000000 00000000 00001000 00000000 00011001

0 标记该条数据是否删除

0 标记min_rec_mask,在B+树里每一层的非叶子节点里的最小值都有这个标记

0000 n_owned,记录了一个记录数,这个记录数的作用,后续我们讲到对应的概念时会告诉大家的

00000000 00001 heap_no,他代表的是当前这行数据在记录堆里的位置

000 record_type,这行数据的类型,0代表的是普通类型,1代表的是B+树非叶子节点,2代表的是最小值数据,3代表的是最大值数据

00000000 00011001 是指向他下一条数据的指针

数据落盘

在经过mysql操作后,行数据的字符串会被转换为数据库指定的字符集编码

0x09 0x04 00000101 0000000000000000000010000000000000011001 616161 636320 6262626262

0x09 0x04 000001010000000000000000000010000000000000011001 00000000094C(DB_ROW_ID)00000000032D(DB_TRX_ID)EA000010078E(DB_ROL_PTR) 616161 636320 6262626262

DB_ROW_ID 一个行的唯一标识(唯一索引),是他数据库内部给你搞的一个标识,不是你的主键ID字段。如果我们没有指定主键和unique key唯一索引的时候,他就内部自动加一个ROW_ID作为主键

DB_TRX_ID 事务相关的,他是说这是哪个事务更新的数据

DB_ROL_PTR 回滚指针,是用来进行事务回滚

sql流转过程

存储引擎(innodb)

先操作的是缓冲池中的数据,这个时候事务没有提交,磁盘和缓冲池数据不一致,暂时出现数据不一致的情况(脏数据)

1. 事务未提交,mysql宕机

这个时候,事务未提交,该事务的所有操作都不会被保存到磁盘上,调用方会显示异常信息

 2. 事务提交,redoLog更新策略

2.1 innodb_flush_log_at_trx_commit = 0

事务提交,redo log buffer 不会将数据,刷入到磁盘

缓冲池操作的数据,在没有刷到磁盘之前,mysql服务宕机,数据丢失

2.2 innodb_flush_log_at_trx_commit = 1 

事务每次提交,都会将 redo log buffer 刷入到磁盘

缓冲池操作的数据,在没有刷到磁盘之前,mysql服务宕机,数据不会丢失,在重启mysql服务后会读取redo log 日志进行数据修改

 2.3 innodb_flush_log_at_trx_commit = 2

事务提交,不会每次都将将 redo log buffer 刷入到磁盘 ,可能1秒刷一次

缓冲池操作的数据,在没有刷到磁盘之前,mysql服务宕机,数据有可能会丢失,因为:redo log日志有可能刷入到redo日志文件(这个时候数据不糊i丢失),没有刷入到redo日志文件(此时数据会发生丢失)

 3. binlog

5和6两个步骤,是从你提交事务开始的,属于提交事务的阶段

1、2、3、4几个步骤,其实本质是执行更新语句的时候干的事

只有当步骤7完成之后,整个事务才算完成,否则事务的提交是失败的

binlog刷盘策略

3.1 sync_binlog = 0

binlog写入磁盘的时候,其实不是直接进入磁盘文件,而是进入os cache内存缓存,这个时候mysql服务宕机,缓存中的数据会丢失

3.2 sync_binlog = 1

在提交事务的时候,会强制把binlog直接写入到磁盘文件里去,那么这样提交事务之后,哪怕机器宕机,磁盘上的binlog是不会丢失的

mysql 脏数据(缓存中的数据)刷到磁盘,是通过一个 IO 线程进行的,后台的IO线程,会在之后某个时间里,随机的把内存buffer pool中的修改后的脏数据给刷回到磁 盘上的数据文件里去

crud

你执行crud的时候,先会把磁盘上的数据加载到Buffer Pool

里缓存,然后更新的时候也是更新Buffer Pool的缓存,同时维护一堆链表



这篇关于mysql磁盘数据存储 + sql执行过程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程