为啥报告的数据库大小(在磁盘上?)与内存中的不同

Posted

技术标签:

【中文标题】为啥报告的数据库大小(在磁盘上?)与内存中的不同【英文标题】:Why is reported database size (on disk?) different from that in memory为什么报告的数据库大小(在磁盘上?)与内存中的不同 【发布时间】:2012-09-27 20:01:41 【问题描述】:

我的数据库包含三个表,分别有 50k、50k 和 5m 行。它们都是 InnoDB。 (最大的一个包含 varchar[256])。我的数据库大小是 214MB,我是通过查询 information_schema.TABLES 得到的(我猜这给出了磁盘上数据+索引的大小?)

我有 1.5GB 的 RAM,我想我会将所有表的引擎转换为 MEMORY。但是当我开始转换最大的表时,我得到了 1114 错误。

经过一番研究,我发现max_heap_table_size 只有 16MB。所以,我将max_heap_table_sizetmp_table_size 设置为1GB。

当我再次尝试转换时,我看到 mysqld.exe 进程的内存使用量超过 1.2GB,然后在转换一半行之前再次抛出同样的错误!我从最大的表中删除了一半的行,它终于适应了 - 内存为 700MB!

为什么 214MB 的数据库,甚至无法容纳超过 4 倍的内存?

除了数据+索引之外,进程中还有什么东西在消耗内存吗?

机器:Intel P4 - 1.9GHz,1.5GB RAM,Win7 Ultimate。

【问题讨论】:

@Randy 但不会停止将表完全加载到 RAM 中。 @OP 可能有大量 RAM 分配给缓存或其他东西。看看top 和/或htop 看看有什么在使用你的RAM。您是在共享主机还是 VPS 上运行? 是的,但是我报告的内存使用仅针对 mysqld.exe 进程。我系统中的其他所有内容都非常适合剩余的几百兆。即使我喜欢 4GB 并且以某种方式使其完全适合,我的主要问题是:为什么 214MB 在 RAM 中占用 >1.2GB @JamWaffles 实际上这发生在我的临时 Win7 开发机器上。我在看任务管理器。开始转换前mysqld.exe的内存稳定在144M。转换开始后,在 20 秒内放大到 1.2G,然后出错。 您可以通过导出数据、使用 MEMORY 引擎创建新表并尝试导入该数据来检查您是否有类似的行为。但是您必须记住,重新启动 mysql 进程将删除这些表中的所有数据。 @Zefiryn 我尝试了两种方式。 1)更改表属性中的引擎,以及 2)创建一个 MEMORY 表并从旧表插入到其中。 相同的行为,相同的内存使用模式!。唯一的区别是我在不同的对话框中遇到了同样的错误:| 【参考方案1】:

我找到了this dba.se question,其中接受的答案有一个指向this dev.mysql page 的链接,上面写着:

MEMORY 表使用固定长度的行存储格式。可变长度 VARCHAR 等类型使用固定长度存储。

就像我在问题中提到的那样,我有一个 5m 行的表,其中有一个 varchar[256] 列。

5,000,000 x 256 = 1.19G(假设每个字符 1 个字节),所以我认为这就是答案!

仅该特定列就占了 95% 的空间,其余的则来自其他数字列。我猜 InnoDB 没有将它以固定长度存储在磁盘上。而且由于该字段的测试值大多不超过 10 - 15 个字符,因此它在磁盘上占用的空间非常小。

【讨论】:

出于好奇,您为什么要从 InnoDB 转换为 MEMORY?如果是因为性能问题,最好增加innodb_buffer_pool_size 其实,是的!我拼命尝试这样做之前我为我的数据库找到了正确的 InnoDB 缓冲区大小;我以前从未在一个表中处理过 500 万条记录。现在我的 InnoDB 工作正常,但我仍然想知道为什么会这样:)

以上是关于为啥报告的数据库大小(在磁盘上?)与内存中的不同的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的应用程序在设备上的大小与 APK 或 Play 商店的大小不同

为啥我们需要数据仓库?

Android中图片的压缩

Android中图片的压缩

为啥用C#在磁盘上写入文件后内存没有释放

AudioKit/DSP:了解磁盘上未压缩音频的大小与内存中的差异