网易首页 > 网易号 > 正文 申请入驻

这么哇塞的 MySQL 功能,你确定不用么?

0
分享至

大家好,今天我们来聊聊 MySQL 数据库中的压缩功能。

先问一个问题,压缩会导致性能下降么?

通过压缩页面会减少存储空间的开销,但是会有额外 CPU 的开销,因此性能会有影响。

想必大部分同学都是类似如上的回复。

然而,答案却是:以上全错。

这好比你买了套 500 万的房子,贷款 350W。30 年等额本息还款,算上 30 年的利息,实际你要还 700W。

所以你说,买房肯定是亏的。

很显然,这个推理是不对的。

因为 30 年后,随着物价的上涨,你所持有的房子大概率至少涨了 1 倍。

因此你的房子市值将会是 1000W,除去 700W 的连本带利的还款,实际你还赚了 150 万。

有同学肯定会说,万一 30 年没有涨 1 倍呢?

是的,如果你不小心脑残地入手了三亚、丽江、鹤岗等地的房产,入手了号称租售比 10%的沿街商铺,那么的确存在 30 年涨不到 1 倍的风险可能(其实也很小)。

所以,房产取决于你购买标的的选择。

对于数据库的压缩,性能是否下降取决于压缩功能的实现。

的确,MySQL 5.7 版本之前的压缩功能设计存在缺陷,压缩可能会导致性能严重的下降。

但 MySQL 5.7 版本开始 InnoDB 存储引擎提供了一种新的压缩功能,称为透明页压缩(Transparent Page Compression,下简称 TPC )。

下面我们就来讲讲这种对性能几乎没有影响的压缩功能。

旧的 InnoDB 页压缩功能

我们先来看看旧的 InnoDB 页压缩功能。

旧的 InnoDB 压缩页是指在建表或者修改表时加上如下的 KEY_BLOCK_SIZE 选项:

CREATE TABLE `t` (
`a` int NOT NULL,
`b` varchar(128) DEFAULT NULL,
`c` datetime(6) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB KEY_BLOCK_SIZE = 8

KEY_BLOCK_SIZE 可以是 1、2、4、8、16,表示启用页压缩,然后按照 1K、2K、4K、8K、16K 的页大小存储数据。

压缩算法使用常见的 zlib。

由于 InnoDB 页的大小是 16K,zlib 的压缩比通常在 50%左右,因此一般 KEY_BLOCK_SIZE 设置为 8 比较常见。

设置得再小,压缩比例也不一定会提高。

因为其本质是将 16K 的页压缩后,根据 KEY_BLOCK_SIZE 大小存储。

假设页 16K,压缩后的大小是 7K,则设置 KEY_BLOCK_SIZE 为 8,一个 8K 压缩页存储即可。

若 KEY_BLOCK_SIZE 为 4,则拆分成 2 个 4K 页存储。占用存储空间不会有太大的变化。

前面姜老师谈到,旧的 InnoDB 页压缩功能设计存在缺陷,启用压缩功能后,性能下降比较明显。

然而,它的实现思想初衷是提升性能,甚至借用了其他数据库的一些理念:日志即数据

什么意思呢?也就是对于压缩页的数据修改,他首先并不会修改页本身,而是将日志存储在这个页中。

所以压缩页的格式大致如下所示:

的确,这样的实现对于页的变更比较好,无需每次插入记录进行压缩。

但是除了数据库除了写入操作,库还有大量的读取操作。

显然,对于压缩的数据,是无法直接读取的。

因此,旧的 InnoDB 页压缩算法还会在内存中有一个解压后 16K 的页,以供数据的读取,如:

这时你会发现一个页在缓冲池存在两个版本,压缩的版本和非压缩的版本。

这样会导致一个非常严重的问题,即缓冲池中能缓存页的数量大大减少

数据库的性能随之就会有极大的下降。

接着,我们来看下 MySQL 5.7 版本后新的 TPC 压缩是如何实现的,它又是如何保证性能尽可能保持原有水平呢?

新的 InnoDB TPC 页压缩

MySQL 5.7 版本推出的 TPC 页压缩是一种极其高效的压缩算法,其使用相当简单,只要在建表的时候添加压缩选项即可,如:

CREATE TABLE `t` (
`a` int NOT NULL,
`b` varchar(128) DEFAULT NULL,
`c` datetime(6) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB COMPRESSION='zlib'

除了 zlib 压缩,TPC 还可以选择 lz4 压缩算法。

我们来看下 TPC 的具体实现过程:

可以看到 TPC 压缩下,一个压缩页在缓冲池中都是一个 16K 的非压缩页。

只有在刷新到磁盘的时候,会进行一次压缩,对于压缩后剩余的空间,页中都填写 0x00。

最后写入到磁盘后,调用文件系统空洞(Hole Punch)特性对文件进行“裁剪”,释放 0x00 占用的稀疏空间。

当前 Linux 内核以及绝大部分的文件系统,如 XFS、EXT4、ZFS、btrfs、NTFS 等,都支持空洞特性,具体内核版本以经文件系统可见官方文档的具体说明。

TPC 虽然好,但是他依赖的 Hole Punch 有一个限制,即原始文件裁剪后的大小是根据文件系统块大小对齐的,也就是 4K 对齐。

对于上图的例子,压缩后页的大小是 9K,那么实际占用的空间是 12K

可以通过下面的命令查看表空间占用的实际磁盘空间:

SELECT
SPACE, NAME, FS_BLOCK_SIZE,
FILE_SIZE, ALLOCATED_SIZE
FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE NAME='sbtest/sbtest1'

下面是我写的一段 C 代码,用于描述透明页压缩在内核层的实现,看懂这几行,你也就弄明白 MySQL InnoDB 中代码的实现本质:

图 - 函数 hole_punch_compress

上面的代码和我们之前介绍的 O_DIRECT 写入方式基本一样。不同点在于:

  1. 使用 zlib 的 compress 函数对 16K 的页进行压缩(第 16 行);
  2. 对于压缩后的页剩余部分用 0x00 进行填充(第 19 行);
  3. 调用函数 pwrite 进行原子写入后,再调用函数 fallocate 对文件进行空洞压缩(第 29 行);

好吧,既然姜老师把 TPC 压缩说的这么好,怎么能少得了最具实战意义的测试呢?

接下去,Let's go ~~~

TPC 性能测试

这里我们选择 sysbench 工具进行性能测试。

测试的表是一张有 3200W 行记录的表,数据量 7G,压缩后表的大小分别为:

从压缩比例来看,旧的 InnoDB 压缩算法有着更好的压缩比例,但是实际数据导入时间却是 TPC 压缩算法的数倍。

此外,真实的生产环境下,TPC 的压缩比例和旧的压缩算法其实差不多,都能在 40% ~ 50%之间。

下图就是最为关键的性能测试结果,这里选取了主键读取测试:

可以看到由于 sysbench 测试中有热点,BP 为 8G、4G 基本都能缓存住热点数据,因此两者性能几乎没有区别,都能跑到 100W QPS。

但是老的压缩算法即便在 8G 的缓冲池大小下,性能也有较为明显的下降。

所以说,这么香的 TPC 压缩功能,你确定不在生产环境中使用么?

总结

今天姜老师带大家深入浅出了 InnoDB TPC 页压缩的实现,总结来说:

  1. TPC 压缩不占用额外的缓冲池空间,所有压缩页在缓冲池中都是 16K;
  2. 页的压缩仅在写入磁盘时进行,不会在缓冲池中对一个页进行反复的压缩尝试;
  3. 使用文件系统空洞特性进行压缩,释放磁盘空间;
  4. 对比旧的压缩算法,性能极其优秀。

最后,老规矩,留几个思考题,以小伙伴们供茶余饭后约上三五知己,讨论一下:

  1. 如何不压缩表,预估出启用 TPC 压缩后,表的压缩比例大概有多少?please show me your code
  2. 对于图中函数 hole_punch_compress,尝试编写单元测试,验证函数的正确性。please show me your code

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
被曝离婚才3天,离谱往事就扒出来了,原来李小冉早就留好了退路

被曝离婚才3天,离谱往事就扒出来了,原来李小冉早就留好了退路

疯狂的豆芽
2026-07-16 18:12:23
过分!阿根廷球迷公然侮辱中国博主:恶毒种族歧视 太猖狂了 不能忍

过分!阿根廷球迷公然侮辱中国博主:恶毒种族歧视 太猖狂了 不能忍

风过乡
2026-07-17 12:57:15
回归“一页纸”,清华大学录取通知书到了

回归“一页纸”,清华大学录取通知书到了

澎湃新闻
2026-07-17 11:58:10
特朗普要是拿不下伊朗,中国之后会干什么,西方已经想都不敢想

特朗普要是拿不下伊朗,中国之后会干什么,西方已经想都不敢想

共工之锚
2026-07-17 00:26:45
SK海力士美股股价盘前拉升涨5.5%

SK海力士美股股价盘前拉升涨5.5%

每日经济新闻
2026-07-17 18:33:06
世界杯半决赛与梅西争吵内幕曝光,贝林厄姆:能够与他交手是我的荣幸

世界杯半决赛与梅西争吵内幕曝光,贝林厄姆:能够与他交手是我的荣幸

红星新闻
2026-07-17 15:44:23
1-1!蓉城三连平!约翰不会赢球了,王鹏致命失误,胡荷韬这么踢难进国家队

1-1!蓉城三连平!约翰不会赢球了,王鹏致命失误,胡荷韬这么踢难进国家队

刀锋体育
2026-07-17 21:11:23
知名手机品牌宣布退出中国市场

知名手机品牌宣布退出中国市场

大象新闻
2026-07-16 21:50:11
歼-20超过500架,西方发现“巨大隐患”:不是发动机,更不是雷达

歼-20超过500架,西方发现“巨大隐患”:不是发动机,更不是雷达

利刃号
2026-07-14 22:53:26
烧了1000亿还没炸服伊朗,万斯坦言武力赢不了,特朗普想谈遭拒绝

烧了1000亿还没炸服伊朗,万斯坦言武力赢不了,特朗普想谈遭拒绝

国际法大视野
2026-07-16 20:03:14
内塔尼亚胡:只想对伊朗领导人说一句话,若伊朗袭击以色列,就别指望风平浪静,也别指望会和以前一样

内塔尼亚胡:只想对伊朗领导人说一句话,若伊朗袭击以色列,就别指望风平浪静,也别指望会和以前一样

政知新媒体
2026-07-15 14:09:04
军校跌麻了!低分考生赢了!

军校跌麻了!低分考生赢了!

勋哥教你填志愿
2026-07-17 10:19:01
大量融资客爆仓

大量融资客爆仓

财叔有料
2026-07-17 16:30:52
广东6月新冠确诊超2.6万例,流感超27万例

广东6月新冠确诊超2.6万例,流感超27万例

新浪财经
2026-07-15 17:05:02
人贩子彭洪菊,逃亡中被卖深山折磨12年,被捕时哭诉:你们怎么才来

人贩子彭洪菊,逃亡中被卖深山折磨12年,被捕时哭诉:你们怎么才来

从零到一研究所
2026-07-17 11:13:46
局势反转,内贾德再度出山,伊朗正式宣战,万斯直言美国难以取胜

局势反转,内贾德再度出山,伊朗正式宣战,万斯直言美国难以取胜

云上乌托邦
2026-07-17 15:28:26
被许家印坑得最惨的4个人,曾经都是他称兄道弟的好朋友

被许家印坑得最惨的4个人,曾经都是他称兄道弟的好朋友

动物奇奇怪怪
2026-07-15 15:21:19
A股:不用等下周开盘了,两个消息来临,周一或开启新的行情

A股:不用等下周开盘了,两个消息来临,周一或开启新的行情

财经大拿
2026-07-17 15:04:03
张靓颖与冯轲相爱15年,被骗走亿万身家,离婚8年后两人天差地别

张靓颖与冯轲相爱15年,被骗走亿万身家,离婚8年后两人天差地别

一盅情怀
2026-07-14 16:03:54
他是百年难遇的跨界天才,凭一己之力改写了人类文明进程

他是百年难遇的跨界天才,凭一己之力改写了人类文明进程

月光作笺a
2026-07-15 21:37:43
2026-07-17 21:36:49
破产码农 incentive-icons
破产码农
IT圈最会讲故事的码农
161文章数 7037关注度
往期回顾 全部

科技要闻

Kimi K3突然登顶!价格也涨到了美国档

头条要闻

西班牙首相将出席世界杯决赛 阿根廷总统因为迷信不去

头条要闻

西班牙首相将出席世界杯决赛 阿根廷总统因为迷信不去

体育要闻

30亿欧对决,世界杯季军战毫无意义?

娱乐要闻

曲婉婷自爆患癌!全网喊“苍天绕过谁”

财经要闻

多只宽基ETF显著放量!大资金再度出手?

汽车要闻

把中国超跑卖到英国,比亚迪正在被世界看见

态度原创

时尚
本地
房产
数码
健康

放暑假的中学生,挤满医院整形科

本地新闻

十年了,为什么鬼怪CP还能让人美美嗑上?

房产要闻

炸场!十五五定调黄埔!科学城真正的红利赢家,藏不住了

数码要闻

亮源新创姜旭:世界模型的最终目标是让机器人理解并参与物理世界

刮痧也会刮出脑梗?讲个真实案例

无障碍浏览 进入关怀版