MySQL InnoDB-innodb_file_per_table缺点


32

默认情况下,MySQL InnoDB将所有数据库的所有表存储在一个全局文件中。您可以通过在配置中设置innodb_file_per_table来更改此设置,然后为每个表创建一个数据文件。

我想知道为什么innodb_file_per_table默认情况下不启用。使用它有不利之处吗?

Answers:


32

我对此有完整的答案。

一旦将innodb_file_per_table放置到位,并且可以使用来收缩新的InnoDB表,ALTER TABLE <innodb-table-name> ENGINE=InnoDB';这将.ibd保证新文件的收缩。

如果ALTER TABLE <innodb-table-name> ENGINE=InnoDB';在使用innodb_file_per_table之前创建的InnoDB表上运行,它将从ibdata1文件中提取该表的数据和索引,并将其存储在.ibd文件中,这将在ibdata1中留下永久的鸽子整体,无法重复使用。

ibdata1文件通常包含四种类型的信息

这是可以永久缩小ibdata1文件的保证方法...

步骤01)MySQL将所有数据库转储到SQL文本文件中(称为SQLData.sql)

步骤02)删除所有数据库(mysql,information_schema和performance_schema模式除外)

步骤03)关闭mysql

步骤04)将以下行添加到/etc/my.cnf

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
innodb_data_file_path=ibdata1:10M:autoextend

旁注:无论您为innodb_buffer_pool_size设置什么,请确保innodb_log_file_size为innodb_buffer_pool_size的25%。

  • 步骤05)删除ibdata1,ib_logfile0和ib_logfile1(删除之前请参见下面的更新!

此时,/ var / lib / mysql中应该只有mysql模式

  • 步骤06)重新启动mysql

这将重新创建10MB的ibdata1(不配置该选项),ib_logfile0和ib_logfile1分别为1G

  • 步骤07)将SQLData.sql重新加载到mysql中

ibdata1 将增长,但仅包含表元数据和间歇性MVCC数据。

每个InnoDB表将存在于 ibdata1

假设您有一个名为mydb.mytable的InnoDB表。如果进入/var/lib/mysql/mydb,您将看到代表该表的两个文件

  • mytable.frm (存储引擎标题)
  • mytable.ibd(表数据和表索引的主页mydb.mytable

ibdata1 将永远不再包含InnoDB数据和索引。

使用中的innodb_file_per_table选项/etc/my.cnf,您可以运行OPTIMIZE TABLE mydb.mytableOR ALTER TABLE mydb.mytable ENGINE=InnoDB;,文件/var/lib/mysql/mydb/mytable.ibd实际上会缩小。

在我作为MySQL DBA的职业生涯中,我已经做过很多次了,此后再也没有遇到任何问题。实际上,我第一次这样做是将50GB的ibdata1文件折叠为50MB。

试试看。如果您对此还有其他疑问,请给我发送电子邮件。相信我。这将在短期和长期内起作用。

更新2013-07-02 15:08 EDT

我在这方面有一个警告,我在我的其他帖子中进行了更新,但我错过了这一点:我用innodb_fast_shutdown更新了我的答案,因为我曾经重新启动mysql并停止了mysql来执行此操作。现在,这一步至关重要,因为每个未提交的事务在InnoDB事务日志的内部和外部可能都有其他活动部分(请参阅InnoDB基础结构)。

请注意,将innodb_fast_shutdown设置为2也会清除日志,但是在mysqld启动期间,仍存在更多运动部件,并且会在崩溃恢复中被选中。最好设置为0。


好信息-谢谢!50GB >> 50MB-令人印象深刻!
2011年

嗨,我已经尝试按照您在此处所做的那样做,唯一的问题是服务器此后无法启动。如果我做服务mysql启动它只是挂在那里。如果我切换回旧的cnf文件,一切正常。你有什么线索吗?
Nicola Peluchetti

这个问题是针对Nicola的:您是否做了第5步?
RolandoMySQLDBA 2011年

@Nicola的另一个问题:您的系统中有多少RAM?
RolandoMySQLDBA 2011年

2
小心!innodb_fast_shutdown=0必须先在MySQL中设置该选项,然后再关闭它才能删除日志文件!(ib_logfile0ib_logfile1),否则可能会丢失数据!
Totor

12

请参阅错误

使用它有不利之处吗?

  • 更多打开的文件
  • 打开/重新打开开销
  • 的.ibd文件不收缩(见12

我总是在大型数据库上使用innodb_file_per_table。


即使您不使用它,ibdata文件也不会收缩:(
minaev 2011年

1
谢谢。我也想知道为什么没有选择每个DB文件的选项?
2011年

1
@UpTheCreek,表是实体。数据库是实体的逻辑组,而不是本身具有实体的实体。使用MyISAM更为明显,其中数据库是目录,表是文件。
约翰·加迪尼尔

只想指出,虽然.ibd文件不会自动收缩,但也不会自动收缩,而是ibdata1每张表文件的替代方法。至少可以使用来缩小.ibd optimize table,这与缩小ibdata1相比是微不足道的。
RomanSt

8

默认情况下,在MariaDB中启用innodb_file_per_table。


1
不是我的(CentOS 7中的默认版本)。您需要等效的MySQL 5.6.6或更高版本。否则默认为关闭
与莫妮卡(Monica)

2

我之所以选择不使用innodb_file_per_table,是因为每个表都放在自己的文件中,这意味着每个表都有自己单独的开销(文件签名等),这会导致MySQL目录的总大小比使用共享表空间大。另外,当拥有多个小文件而不是一个大文件时,由于群集松弛而导致的浪费空间更大。

当然,在大型方案中,额外的开销并不是很大的,尤其是如果您使用大型驱动器或拥有庞大的数据库,但对于我自己(可能还有许多“家庭用户”)来说,这一切总和对于带有大型群集的小型驱动器来说,这仍然太多了,而我却保留了MySQL存储。

例如,我的数据库存储与我的WordPress数据库和其他一些小型数据库(phpBB的,开发者一些AMP测试等),转换为每个表的改变从32MB到50MB,而且甚至没有包括ibdata1仍然需要一个最小的10MB,总共至少 60MB。

就像我说的那样,对于某些人,尤其是企业来说,这可能不是太大的问题,但是如果您是仅托管您的网站,博客等内容的家庭用户,那么在选择诸如主机提供程序,因为除了总磁盘使用量之外,许多主机还会限制数据库的大小。


1
我一直以为你疯了(谁在乎十兆字节??),直到你明白托管提供商的配额紧张的问题。永远不会想到这一点。
丹·普里兹

@DanPritts,尤其是免费的主机。此外,您的驱动力可能很大,但并非所有人都有。去年,我已经将主数据分区从1GB扩展到了2GB,因为它太紧了,但是即使这里有10MB,那里有10MB(尤其是日志文件)也可以很快耗尽它。另外,别忘了群集废物也会加起来。最后,它甚至不一定是硬盘驱动器。例如,我目前正在“网站化”我的网站,以便可以从任何系统托管它,因此2GB闪存驱动器已经受到限制。因此,保持尺寸小和避免写入是至关重要的。然后是嵌入式系统!
Synetech

另外,它不是10MB(这是的绝对最小大小IBDATA1)。它从30MB增至〜85MB。通过删除整个内容并从头开始导入转储,我得到了69MB而不是之前的30MB(猜想哪个数据库占了一半以上)。由于某种原因,尽管使用每表,但我ibdata1仍然是18MB。☹
Synetech

从32M和50M的文件大小来看,听起来好像我安装了CMS而未启用selinux的安装。我真的不敢相信这些数字,在其他相同的系统上,您甚至有几个数据库的某些文件的元数据加起来相当于MEGABYTES的大小?
sjas 2015年


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.