MySQL一条数据的物理存储及redolog

MySQL物理文件的概念

一行数据在磁盘上存储的时候,包含哪些东西?

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

如果有多个变长字段,如何存放他们的长度?

varchar(10) varchar(5) varchar(20) char(1) char(1),一共五个字段,其中三个是变长字段。

磁盘中存储的,必须在他开头的变长字段列表中存储几个变长字段的长度,是逆序存储。

带NULL值是如何存储?

一行数据里的NULL值不能直接存储,因为没必要,什么值都没有,还存个NULL.

会以bit位来存储,可以为NULL的字段,分别占一位,为NULL就是1,不为NULL就是0,然后null值列表是逆序存放的。

数据头是如何存储的?

数据头是40个bit,里面存储了这行数据的描述信息。

实际数据是如何存储的

在实际输入里,Innodb会插入几个默认字段,DB_ROW_ID(如果没指定主键或者唯一索引),DB_TRX_ID(事务ID),DB_ROL_PTR(回滚指针)。

将值按照编码存储起来

在这里插入图片描述

行溢出

如果一行数据在一个页放不下,那么就会有一个20字节的指针,来引用其他页,继续存放这一行的数据。

数据页到底长什么样

数据页默认16kb的大小。一个数据页被拆分成了很多部分,大体上包括文件头,数据页头、最小记录和最大记录,多个数据行、空闲空间、数据页目录、文件尾部。

如果往空白的数据库插入一条数据,就需要从磁盘加载数据页到BufferPool的缓存页中去。

缓存页和数据页是一一对应的,在磁盘就是数据页,在内存就是缓存页。多个数据行区域是用来存放数据的,直到将空闲区域用完,这个页就算用完了。

表空间以及划分多个数据页的数据区

平时我们创建的表,都有一个表空间的概念,在磁盘上对应着"表名.ibd"的磁盘数据文件。

表空间里又有一个数据区的概念,英文就是extent。一个数据区对应着连续的64个数据页,每个数据页是16kb,所以一个数据区是1mb,然后256个数据区被划分为了一个组。对于表空间而言,它的第一组数据区的第一个数据区的前3个数据页,都是固定的,里面存放了一些描述性的数据。

磁盘调度

在这里插入图片描述

MySQL性能抖动真实案例

大部分都是组RAID的,组RAID可以使用RAID卡的缓存,为了防止由于断电导致的缓存丢失,RAID卡通常有锂电池供电,但是锂电池需要充放电维持电池寿命,充放电期间RAID卡就不能用缓存,性能会降低,降低大概十几倍。可以用linux命令查看RAID硬件设备的日志,看看充放电记录。

三种解决方案:

1.给RAID卡换成电容,电容不需要充放电。

2.关闭自动充放电,写脚本凌晨触发手动充放电,推荐。

3.充放电不要关闭write back,这个是可以设置的。

MySQL too many connection故障的真实案例

linux的最大句柄数设置为1024,MySQL源码内部写死了,根据最大句柄数限制计算最大连接数。所以单纯设置max_connection参数导致设置无效,所以我们通常会设置文件句柄数为65535。

redo日志是做了什么

redo日志大致格式如下:对表空间XX中的数据页XX中的偏移量为XXX的地方更新了数据XXX。所以说redo日志是针对的数据页。

一条redo log看起来大致的结构如下所示:

日志类型,表空间ID,数据页号,数据页中的便宜量,具体修改的数据。日志类型按照修改了数据页的几个字节的值,划分了不同的类型,有MLOG_1BYTE,MLOG_2BYTE,MLOG_WRITE_STRING等。

redo log block

在这里插入图片描述

redo log buffer

innodb_log_buffer_size可以指定redo log buffer的大小,默认值是16MB。redo log都是先把事务里的一组redo log,先暂存在一个地方,之后再写入redo log buffer中,最后再写入到磁盘中。

什么时候将redo log buffer刷入磁盘

1.写入redo log buffer的日志占据了redo log buffer总容量的一半,超过8MB的redo log在缓冲里,此时就会把他们刷到磁盘文件里去。

2.一个事务提交的时候,必须把他的那些redo log所在的redo log block都刷入到磁盘文件里区。

3.后台线程定时刷新,后台线程每隔一秒就会把redo log buffer里的redo log block刷到磁盘文件里去。

4.MySQL关闭的时候,redo log block都会刷入到磁盘里去。

控制redo log file的磁盘空间占用

通过innodb_log_file_size可以指定每个redo log文件的大小,默认48MB,通过innodb_log_files_in_group可以指定日志文件的数量,默认是两个。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值