为什么要使用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操作,而只是稍微多。考虑一下系统如何工作。
对于整体数据库:
- 服务器启动
ibdata1
开了
- 读取标头和元数据
- 结构和元数据缓存在内存中
- 查询发生
- 服务器访问磁盘并从已打开的磁盘中读取数据
ibdata1
- 服务器可能会将数据缓存在内存中
对于每个表的数据库:
- 服务器启动
ibdata1
开了
- 读取标头和元数据
- 每个单独的
.ibd
文件都打开
- 从每个
.ibd
文件读取标头和元数据
- 结构和元数据缓存在内存中
- 查询发生
- 服务器访问磁盘并从已打开的
.ibd
文件中读取数据
- 服务器可能会将数据缓存在内存中
您会注意到,当服务器运行时,您无法移动数据文件,因为服务器已打开它们的句柄。这是因为启动时会打开它们并使它们保持打开状态。它不会为每个查询打开和关闭它们。
这样,当服务器启动时,开始时只需要进行更多的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,整体总都不可避免地更多比它。