MySQL 单表容量 100T,怎么处理这个需求?
去年我们有个金融核心业务上了腾讯云团队的 TDSQL-C MySQL数据库,也就是之前的 CynosDB,该数据库的详细介绍可见:https://cloud.tencent.com/product/cynosdb。
TDSQL-C 是一款云原生 NewSQL 数据库,是当前流行的存算分离架构。由于存储层与计算层的分离,可以非常容易做到各层之间的横向扩展(Scale Out)。
在目前的NewSQL数据库产品中,大致可以分为以下三种类型:
SQL代理 + MySQL关系型存储:典型产品有腾讯云的 TDSQL-D、中兴的 GoldenDB;
SQL代理 + LSM KV存储:典型产品有腾讯云的 TDSQL-D、蚂蚁的 OceanBase、PingCAP 的 TiDB;
云原生(Cloud Native)数据库产品:典型产品有腾讯云的 TDSQL-C、Amazon的 Aurora、阿里云的 PolarDB;
由于云原生数据库的分布式是在存储层面实现,因此业务无需关注数据的分片逻辑,SQL 可以做到 100% 的 MySQL 兼容。
不好意思,发错图了,应该是:
所以,小于 10T 容量的业务可以通过 TDSQL-C 得到很好地支持。
与此同时,TDSQL-C 也在支持复杂 SQL 的并行查询功能支持,因此,TDSQL-C 也能作为 HTAP 数据库使用。
综上考虑,我们开始逐步尝试在核心业务中使用云原生数据库 TDSQL-C 。
然而,我们遇到一个挑战:单表存储容量大于 100T。
请注意,是单表大于 100T,而不是数据库总容量大于 100T。这是两个完全不同的概念。
因为 TDSQL-C 是基于 MySQL InnoDB存储引擎做的修改,因此单表上限受 InnoDB 存储引擎的限制。
对 MySQL 熟悉的同学应该知道,InnoDB 单表限制是 64T。
没错,默认情况下 MySQL InnoDB存储引擎单表上限的确是 64T。所以,今天的问题就变成了为什么 InnoDB 存储引擎的单表限制是 64T ?
给同学们 5 分钟的思考时间。
时间到,不知道你们想到没有?
其实很简单,看 InnoDB 数据页的结构就能一窥究竟。
每个数据页都有一个File Header,其中有部分内容保存每个数据页的前一个页和后一个页,也就是上图中的 FIL_PAGE_PREV 和 FIL_PAGE_NEXT ,他们都占用 4 个字节。
这意味着 InnoDB 最多有 4G(0xFFFFFFFF)个数据页,默认一个页的大小为16K,因此:
innodb_table_max_size = 4G * 16K = 64T
当然,用户可以通过参数 innodb_page_size 设置 InnoDB 的页大小,因此单表的最大上限也会有所不同。官方文档中对单表上限的说明如下图所示:
PostgreSQL 9.6版本前单表最大限制为 32TB,PostgreSQL 10版本开始单表最大限制为 2EB (=2048PB)。
2EB,PostgreSQL 真的好大啊!
最后,在弄清 InnoDB 单表上限这个问题后就能明白这并不是 TDSQL-C 数据库的问题,这是所有基于 MySQL 数据库改造为云原生数据库后都会遇到的问题。Aurora MySQL、PolarDB MySQL 也都有类似问题。
所以,对于单表 100T 的业务可以通过分区表,也可以通过分表的方式进行处理。也就是说,业务要做一定的改造适配。
总之,实现逻辑就是将一张大表拆分为小表。但是亲,是到 64T 才做的分表,而不是仅 64G !
当然,很少有业务会遇到上述单表的限制问题。对绝大部分业务来说,单表 64T 已足够满足业务需求。64T 还不够大么?
最后的最后,姜老师强烈推荐腾讯云的 TDSQL-C 产品,存储容量 10T 以下的数据库,闭着眼睛用就好了。
TDSQL-C,这才是未来云原生数据库该有的样子!
思考题
1. TDSQL-C MySQL、Aurora MySQL、PolarDB 单实例的存储容量上限分别是多少?
2. 如何在 innodb_page_size 设置为16K的情况下,创建一个页大小为8K或32K的表?
3. 可以向表空间添加新文件,这样是否能突破单表 64T 的限制呢?为什么呢?
突破微信群人数500的限制,以后所有高端群小伙伴可以在一起吹水;
提供 IMG 公众号每篇技术文章最后遗留问题的标准答案;
技术圈的江湖八卦,比如某数据库出局某行的原委,某大V被新领导GZ;
IMG社区技术嘉年华大会门票5折优惠;
姜老师夫妇的私密分享,包括技术、工作、投资、相亲、移民等热门话题;
会员每邀请新会员入群,可以享受59元的返利(把年费赚回来😄);
往期推荐