mysql数据落盘       

mysql数据落盘

问题:

  1. mysql怎么组织数据,并存入ibd文件

  2. mysql如何从硬盘读取数据

文件

image-20200328113401175

操作系统扇区、块、页概念

硬盘

image-20200328113619102

每一层里分多个磁道,每个磁道分多个扇区,每个扇区是 512 个字节

硬盘分成相同大小的单元,我们称为块(Block)。一块的大小是扇区大小的整数倍,默认是 4K

文件内容放在各种块上,需要一个数据结构维护文件分成几块,每块在哪里,还有元数据部分,例如名字、权限等,这个结构就是 inode


struct ext4_inode {
  __le16  i_mode;    /* File mode */
  __le16  i_uid;    /* Low 16 bits of Owner Uid */
  __le32  i_size_lo;  /* Size in bytes */
  __le32  i_atime;  /* Access time */
  __le32  i_ctime;  /* Inode Change time */
  __le32  i_mtime;  /* Modification time */
  __le32  i_dtime;  /* Deletion Time */
  __le16  i_gid;    /* Low 16 bits of Group Id */
  __le16  i_links_count;  /* Links count */
  __le32  i_blocks_lo;  /* Blocks count */ 
  __le32  i_flags;  /* File flags */
......
  __le32  i_block[EXT4_N_BLOCKS];/* Pointers to blocks */ //某个文件分成几块、每一块在哪里
  __le32  i_generation;  /* File version (for NFS) */
  __le32  i_file_acl_lo;  /* File ACL */
  __le32  i_size_high;
......
};

image-20200328123822849

整个文件系统格式

image-20200328150037511

扇区:磁盘的最小存储单位;

磁盘块:文件系统读写数据的最小单位;

页:内存的最小存储单位;

一个磁盘块由连续几个(2^n)扇区组成;

页的大小为磁盘块大小的2^n倍;

如果虚拟文件系统要读1024个字节的inode块,内核并不是只分配一个单独的缓冲区,而是必须分配一整个页,从而存放4个缓冲区(假设页大小4k),这些缓冲区将存放块设备上相邻的四块数据。

InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万

在计算机中磁盘存储数据最小单元是扇区,一个扇区的大小是512字节,而文件系统(例如XFS/EXT4)他的最小单元是,一个块的大小是4k,而对于我们的InnoDB存储引擎也有自己的最小储存单元——页(Page),一个页的大小是16K

这里我们先假设B+树高为2,即存在一个根节点和若干个叶子节点,那么这棵B+树的存放总记录数为:根节点指针数*单个叶子节点记录行数。

上文我们已经说明单个叶子节点(页)中的记录数=16K/1K=16。(这里假设一行记录的数据大小为1k,实际上现在很多互联网业务数据记录大小通常就是1K左右)。

那么现在我们需要计算出非叶子节点能存放多少指针,其实这也很好算,我们假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,我们一个页中能存放多少这样的单元,其实就代表有多少指针,即16384/14=1170。那么可以算出一棵高度为2的B+树,能存放1170*16=18720条这样的数据记录。

根据同样的原理我们可以算出一个高度为3的B+树可以存放:1170*1170*16=21902400条这样的记录。所以在InnoDB中B+树高度一般为1-3层,它就能满足千万级的数据存储。在查找数据时 一次页的查找代表一次IO, 所以通过主键索引查询通常 只需要1-3次IO操作 即可查找到数据。

磁盘存取原理

磁盘是块设备。也就是说磁盘的读写单位是以块为单位,一般块大小从0.5K到4K。

一个扇区512byte,也就是0.5K,一页是4K,那就是一页是8个扇区的大小。

即使只读取一个字节,磁盘也会将包含该字节的所有数据读取。其中,最占用时间的是磁盘的寻道,也就是磁头在盘片上找到需要读取的块所在的位置,而在磁盘上顺序读取数据所花的时间是占比比较小的。

内存到磁盘

image-20200329093047996

平衡多路查找树(B-Tree):为磁盘等外存储设备设计的一种平衡查找树。

系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一磁盘块中的数据会被一次性读取出来,而不是按需读取。

InnoDB存储引擎使用页作为数据读取单位,页是其磁盘管理的最小单位,默认page大小是16k。

系统的一个磁盘块的存储空间往往没有这么大,因此InnoDB每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小16KB。

image-20200329161817942

image-20200329164745861

参考

https://time.geekbang.org/column/article/98440

https://blog.csdn.net/csdnlijingran/article/details/102309593

https://www.jianshu.com/p/e1c73b7c4531

https://qiuzhilin.cn/2019/06/MySQL-Fall-Data.html

https://www.zhihu.com/question/322109242