为什么要使用innodb_file_per_table?


26

有许多文章夸大了(当然是恕我直言)对的需要innodb_file_per_table。我知道使用innodb_file_per_table,应该可以更好地控制各个表;例如分别备份每个表。但是,关于获得更好性能的要求令人怀疑。

在我的测试中,在性能没有差异innodb_file_per_table,并ibdata1为60GB的数据库。当然,这是对普通查询的简单测试,现实生活中复杂查询的情况可能有所不同(这就是我问这个问题的原因)。具有64位linux ext4可以有效处理大文件。

使用innodb_file_per_table,需要更多的磁盘I / O操作;这对于复杂的JOINs和FOREIGN KEY约束非常重要。

表空间在单个共享ibdata;单独表的专用表空间如何节省磁盘空间?当然,使用释放每个表的表空间更为容易ALTER,但是这仍然是一个昂贵的过程(使用表锁)。

问题:是否innodb_file_per_table对更好的mysql性能有影响?如果是,为什么?


看到这个问题的答案:dba.stackexchange.com/questions/7924/…可能也有帮助。
KM。

Answers:


19

我认为这不是性能问题,而是管理问题。

每个表具有单独的文件,例如,您可以将不同的数据库存储在不同的存储设备中。

您可以处理无法处理大文件的文件系统中非常大的数据库的情况(至少将问题推迟到一个表达到文件大小限制为止)。

您没有不受控制的表空间增长。如果删除了一些大表,该ibdata文件将保持很小。

可能会对性能产生影响的一个方面是表数据和索引的碎片化,每个表将受到限制。但这需要测试才能确定。


表空间的增长正是您想要的原因innodb_file_per_table
sjas 2015年

13

为什么要使用innodb_file_per_table?

因为可以在文件级完成,所以更易于管理个人。这意味着,即使服务器关闭,你仍然可以通过复制表文件,而使用一个共享的表空间的方式,无论复制拷贝数据可以是不必要的块状,或找到一些方法来获取服务器上运行提取数据(您确实不想使用十六进制编辑器手动提取数据)。

有人警告说,您不能简单地将.ibd文件从一台服务器复制并粘贴到另一台服务器。这可能是正确的,但它不适用于同一服务器上的备份(我在这里使用术语“ 备份”是指制作副本的传统意义;即,不是彻底更改整个内容)。此外,ibdata1它会在启动时自动重新创建(如大多数“转换为每个表的文件”指南的删除ibdata1步骤所示)。这样,你就不会需要复制ibdata1,除了你的.ibd文件(及其相应的.frm,等文件)。

如果尝试恢复丢失的表,则复制它.ibd.frm文件,以及information_schema小于ibdata1)就足够了。这样,您可以将它们放在虚拟服务器中并提取表,而不必复制整个庞大的东西。

但是,关于获得更好性能的要求令人怀疑。…使用innodb_file_per_table,需要更多的磁盘I / O操作;这在复杂的JOIN和FOREIGN KEY约束中意义重大。

毫不奇怪,性能将完全取决于所使用的特定数据库。一个人与另一个人会有(甚至很大)不同的结果。

这是事实,会有用的文件每个表的更多的磁盘I / O操作,而只是稍微多。考虑一下系统如何工作。

  • 对于整体数据库:

    1. 服务器启动
    2. ibdata1 开了
    3. 读取标头和元数据
    4. 结构和元数据缓存在内存中
    5. 查询发生
      1. 服务器访问磁盘并从已打开的磁盘中读取数据 ibdata1
      2. 服务器可能会将数据缓存在内存中
  • 对于每个表的数据库:

    1. 服务器启动
    2. ibdata1 开了
    3. 读取标头和元数据
    4. 每个单独的.ibd文件都打开
    5. 从每个.ibd文件读取标头和元数据
    6. 结构和元数据缓存在内存中
    7. 查询发生
      1. 服务器访问磁盘并从已打开的.ibd文件中读取数据
      2. 服务器可能会将数据缓存在内存中

您会注意到,当服务器运行时,您无法移动数据文件,因为服务器已打开它们的句柄。这是因为启动时会打开它们并使它们保持打开状态。它不会为每个查询打开和关闭它们。

这样,当服务器启动时,开始时只需要进行更多的I / O操作。它不在运行时。此外,尽管每个.ibd文件都有其自己单独的开销(文件签名,结构等),但它们会缓存在内存中,并且不会为每个查询重新读取。而且,即使使用共享的表空间,也可以读取相同的结构,因此几乎不需要(如果有的话)更多的内存。

innodb_file_per_table是否会对mysql的更好性能产生影响?

实际上,如果有的话,性能实际上可能更差

使用共享表空间时,有时/经常可以合并读写操作,以便服务器从中一次读取多个表中的数据样本ibdata

但是,如果数据分散在多个文件中,则必须分别为每个文件执行单独的I / O操作。

当然,这再次完全取决于所讨论的数据库。实际的性能影响将取决于共享表空间的大小,查询频率和内部碎片。有些人可能会注意到差异很大,而其他人可能根本看不到任何影响。

表空间在单个ibdata上共享;单独表的专用表空间如何节省磁盘空间?

它不是。如果有的话,它会增加磁盘使用率。

我没有要测试的60GB数据库,但是我的“微不足道”的个人数据库包含我的WordPress安装和一些用于个人使用和开发测试的小表,使用共享表空间时的重量约为30MB。将其转换为每个表的文件后,它膨胀到约85MB。即使删除所有内容并重新导入,它仍然大于60MB。

该增加是由于两个因素:

  • 出于某种原因,即使您什么也没有存储,它的绝对最小大小ibdata1都是10MB information_schema

  • 在共享表空间中,仅ibdata1具有文件签名,元数据等开销,但在每个表中,每个单独的.ibd文件都具有所有这些开销。这意味着总数(即使假设<10MB ibdata1)至少要大一些:

    GetTotalSizeofOverhead() * GetNumTables()

显然,这些增加不会很大(除非您正在使用限制数据库大小的主机或将其存储在闪存驱动器上等),但是无论如何,这些增加都是通过将(每个)表切换到文件来实现的。 -per表可以收缩ibdata1到10MB,整体总都不可避免地更多比它。


11

这是我始终使用innodb_file_per_table的原因:

如果没有每个表的文件,则ibdata文件永远不会压缩,缩小或减少空间。删除行,删除表或数据库时不行。如果您有活动的排队系统,则2GB的数据可以立即变成20GB的文件。

假设您要在更改之前先备份当前1GB表,然后再将其删除。您在ibdata中留出了GB的未使用空间。笨蛋

可能有无数的实例,其中临时措施使单个数据文件膨胀,但足以说明我认为,从来没有理由不使用innodb_file_per_table

另外,这里有个不错的文章可供阅读:http : //code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table


1
我意识到永远也这样做是件好事。由SSD支持的磁存储阵列可以针对表的较小文件更有效地处理读/写缓存。对于一堆%99.99的时间仅被“读”但未被写入的表,它们始终位于存储控制器的缓存中,这大大缩短了响应时间。
sdkks

5

我之所以不使用innodb_file_per_table是因为性能。

我在mysql 5.5.45 Linux CentOS版本6.7上用450个表对数据库做了一些测试

对于单元测试,该单元测试在每次测试之前将固定装置插入数据库中(每次都不会使用所有表),并且测试本身也确实对数据库有效(插入,更新,删除,选择),在不使用数据库表的情况下,性能提高了3-5倍分成更多文件。

我建议您在决定使用innodb_file_per_table之前,使用要使用的查询来测试数据库并进行比较

也许您会发现,对于生产服务器,您可以使用innodb_file_per_table,但对于CI环境(持续集成),它可以启动单元测试(大量使用DB),并且很多启动单元测试的开发人员最好不要使用它,因为它会提高性能。


2
我猜这是由于为所有450个表分配初始文件而不是分配一个文件所需要的时间。在生产中,这种情况只会发生一次,因此不应该成为问题,但是您要指出的一点是,对于快速创建数据库然后将其完全拆解并在单个ibdata文件中重复一遍是更好的选择。
ColinM '17年

2

它使数据更易于管理,因为您可以回收未使用的空间,这很好。

我认为,如果您的数据库主要用于选择查询,则不会对性能产生太大影响。它仍然必须读取大约相同数量的数据。我认为从哪个文件读取数据并不重要。

但是,这可能会使执行大量插入和更新的数据库的性能变差。这是因为在您提交事务后,mysql在存储文件上调用了fsync()。如果只有一个文件,它将发出一个呼叫并等待呼叫完成。如果有很多文件,则必须多次进行调用,并等待所有这些调用返回,然后才能提交commit命令。

这是来自遇到此问题的人的帖子:http : //umangg.blogspot.com/2010/02/innodbfilepertable.html



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.