数据在磁盘上是怎么存储的? 格式长什么样? varchar变长字段怎么存储? 多个null字段怎么存储? 。。。。。。。

存储格式

变长字段的长度列表,null值列表,数据头,column01的值,column02的值,column0n的值……

单个变长字段的存储

:varchar(10) char(1) char(1),存了hello a a hi a a
存储样式:0x05 null值列表 数据头 hello a a 0x02 null值列表 数据头 a a

多个变长字段的存储

:varchar(10) varchar(5) varchar(20) char(1) char(1),存了hello hi hao a a
存储样式逆序存放,0x03 0x02 0x05 null值列表 头字段 hello hi hao a a

null如何存储

在null值列表以二进制存储,0否1是,一般8bit位的倍数,不足8位高位补0,逆序
表结构:name VARCHAR(10) NOT NULL,
address VARCHAR(20),
gender CHAR(1),
job VARCHAR(30),
school VARCHAR(50)
存储的数据为:jack null null worker null
存储样式:0x06 0x04 00000100 头信息 column1=value1,column2=value2….

头信息

由40bit位组成

  • 第一和第二个是预留位
  • delete_mask,是否被删除
  • min_rec_mask,在B+树立每一层的非叶子节点里的最小值标记
  • 4bit位n_owned,记录数
  • 13bit位heap_no,数据再记录堆里的位置
  • 3bit位record_type,行数据的类型,0代表的是普通类型,1代表的是B+树非叶子节点,2代表的是最小值数据,3代表的是最大值数据
  • 16bit位next_record,下一条数据指针

    真实长相

    数据:jack null m null xx_shool
    你以为:0x09 0x04 00000101 0000000000000000000010000000000000011001 jack m xx_school
    真实情况:0x09 0x04 00000101 0000000000000000000010000000000000011001 00000000094C(DB_ROW_ID)00000000032D(DB_TRX_ID) EA000010078E(DB_ROL_PTR) 616161 636320 6262626262
    解释:

  • 字符集需要编码

  • 真实数据部分假如一些隐藏字段,首先有一个db_row_id,行的唯一标识,是数据库的内部标识,如果我们没有指定主键和unique key唯一索引的时候,内部自动加一个row_id作为主键
  • db_trx_id,与事务相关
  • db_roll_ptr,回滚指针,用来进行事务回滚

    表空间

    创建的表,都有一个表空间的概念,在磁盘上都会对应着:表名.ibd一个磁盘数据文件,因为一个数据页不过16kb,所以衍生出数据区extent概念,一个数据区64个数据页,每个数据页16kb,一个数据区是1MB,256个数据区被划分为一个组。对于表空间而言,第一组数据区的第一个数据区前三个数据页是固定的,存放着描述性数据,FSP_HDR,存放了表空间和这一组数据区的一些属性;IBUF_BITMAP,存放的是这一组数据页所有insert buffer的信息;INODE,存放了一些特殊的信息。每一组数据区的头两个数据页,都存放特殊信息
    image.png

    随机读写/顺序读写

    增删改查操作时,把表空间的数据从磁盘中读取出来,是随机读操作,缓存直接写入磁盘的话就是随机写操作
    redo log日志就是顺序写,永远在末尾追加日志

RAID

磁盘冗余阵列,简单说就是用来管理磁盘的,当一块磁盘已经满了加另一块磁盘后,多个磁盘如何管理,就是raid去管理。为什么叫冗余阵列,是它会把同样的数据写到几块磁盘上出现冗余,因为假如一块磁盘坏掉后数据就丢掉了?有了冗余阵列,可以从另一块磁盘中把数据读取出来。具体来说,RAID还可以分成不同的技术方案,比如RAID 0、RAID 1、RAID 0+1、RAID2,等等,一直到RAID 10,很多种不同的多磁盘管理技术方案。
image.png
服务器有多块磁盘的时候,会有一个RAID卡,它带有一个缓存,是一种跟内存类似的SDRAM,把RAID的缓存模式设置为write back,所有写入磁盘阵列的数据回显缓存在RAID卡的缓存,然后再写入磁盘阵列中。而且RAID卡有锂电池,当出现断电时,它会把缓存的数据写入阵列的磁盘上去。注意:锂电池需要定期充放电,在充放电过程中,会把缓存级别调成write through,通过RAID写数据时,直接写入磁盘
RAID 0:使用SDRAM机制
RAID 1:两块磁盘为镜像关系,使用冗余数据机制
RAID 10 :RAID 0+RAID 1组合效果
image.png

数据抖动

使用RAID 10架构的服务器,必然内部有个锂电池,默认设定是30天进行一次充放电,充放电时因为不走缓存,导致性能急剧下降。
三种解决方案:

  1. 锂电池换成电容,电容支持透明充放电,自动检查电量,自动进行充电,但电容容易老化,更换还不方便
  2. 手动充放电,关闭RAID自动充放电,写脚本,每隔一段时间自动在晚上或者业务低峰时期,手动充放电。
  3. 充放电时不关闭write back