Sum*_*Deo 127 mysql innodb delete-row
我有一个使用InnoDB存储引擎的MySQL表; 它包含大约2M个数据行.当我从表中删除数据行时,它没有释放分配的磁盘空间.运行optimize table命令后,ibdata1文件的大小也没有减少.
有没有办法从MySQL回收磁盘空间?
我情况很糟糕; 这个应用程序在大约50个不同的位置运行,现在几乎所有这些都出现了磁盘空间不足的问题.
Leo*_*ins 132
MySQL不会减小ibdata1的大小.永远.即使您optimize table用来释放已删除记录中使用的空间,它也会在以后重用它.
另一种方法是配置要使用的服务器innodb_file_per_table,但这需要备份,删除数据库和还原.积极的一面是,在表之后,表的.ibd文件减少了optimize table.
gil*_*ilm 37
我自己也遇到了同样的问题.
会发生什么,即使你删除数据库,innodb仍然不会释放磁盘空间.我不得不导出,停止mysql,手动删除文件,启动mysql,创建数据库和用户,然后导入.感谢上帝,我只有200MB的行,但它没有250GB的innodb文件.
设计失败.
Fli*_*McF 23
如果您不使用innodb_file_per_table,则可以回收磁盘空间,但是相当繁琐,并且需要大量的停机时间.
该如何为深入漂亮-但我粘贴下面的相关部分.
确保还在转储中保留模式的副本.
目前,您无法从系统表空间中删除数据文件.要减小系统表空间大小,请使用以下过程:
使用mysqldump转储所有InnoDB表.
停止服务器.
删除所有现有的表空间文件,包括ibdata和ib_log文件.如果要保留信息的备份副本,请在删除MySQL安装中的文件之前将所有ib*文件复制到另一个位置.
删除InnoDB表的任何.frm文件.
配置新的表空间.
重启服务器.
导入转储文件.
Ske*_*tor 14
我发现的最短方法是:
\nALTER TABLE YOURTABLE ENGINE=InnoDB\nRun Code Online (Sandbox Code Playgroud)\n截断或删除不需要的记录后,我运行了此命令,表空间缩小了。
\n这是 Shlomi Noach 写的一篇不错的文章,我在那里找到了(这篇文章和更多相关信息)。
\n感谢什洛米·诺奇。希望能帮助到你。以防万一我也将其粘贴到这里:
\n使用 InnoDB 时,您有两种管理表空间存储的方法:
\n将所有内容放入一个大文件中(可以选择拆分)。\n每个表一个文件。\n我将讨论这两个选项的优缺点,并努力说服 innodb_file_per_table 更可取。
\n单个表空间
\n将所有内容放在一个大文件中意味着所有方案中的所有表和索引都位于该文件中 \xe2\x80\x98mixed\xe2\x80\x99 中。
\n这允许以下良好的属性:可以在不同的表和不同的方案之间共享可用空间。因此,如果我从日志表中清除许多行,则现在未使用的空间可能会被任何其他表的新行占用。
\n这个同样好的属性也转化为一个不太好的属性:数据在表空间中可能会出现很大的碎片。
\nInnoDB\xe2\x80\x99s 表空间的一个恼人的特性是它们永远不会收缩。因此,从日志表中清除这些行后,表空间文件(通常是 ibdata1)仍然保留相同的存储。它不会释放文件系统的存储空间。
\n我\xe2\x80\x99不止一次地看到某些表是如何无人监视的,不断增长,直到磁盘空间达到90%,并且短信通知开始到处发出蜂鸣声。
\n在这种情况下,\xe2\x80\x99 没什么可做的。好吧,人们总是可以清除行。当然,该空间将被 InnoDB 重用。但是,拥有一个消耗大约 80-90% 磁盘空间的文件会带来性能灾难。这意味着盘针需要移动很大的距离。整体磁盘性能运行非常低。
\n解决此问题的最佳方法是设置一个新的从站(清除行后),并将数据转储到该从站中。
\nInnoDB热备份
\n有趣的是,ibbackup 实用程序将按原样复制表空间文件。如果是 120GB,其中仅使用了 30GB,您仍然可以获得 120GB 的备份和恢复。
\nmysqldump、mk-并行转储
\n如果您只有原始机器可以使用,mysqldump 将是您的最佳选择。假设您\xe2\x80\x99仅使用InnoDB,则使用\xe2\x80\x93单事务转储即可完成这项工作。或者您可以利用 mk-parallel-dump 来加快速度(取决于您的转储方法和可访问性需求,请注意锁定)。
\ninnodb_file_per_table
\n设置此参数后,将为每个表创建一个 .ibd 文件。我们得到的是这样的:
\n表空间不在不同的表之间共享,当然也不在不同的方案之间共享。\n每个文件都被视为自己的表空间。\n同样,表空间的大小永远不会减少。\n可以重新获得每个表空间的空间。\n等等。最后两个似乎是冲突的,不是\xe2\x80\x99吗?让\xe2\x80\x99s 解释一下。
\n在我们的日志表示例中,我们清除了许多行(最多删除 90GB 的数据)。.ibd 文件不会缩小。但我们可以这样做:
\n更改表日志引擎=InnoDB
\n将会发生的是创建一个新的临时文件,并在其中重建表。仅现有数据会添加到新表中。完成后,原始表将被删除,新表将重命名为原始表。
\n当然,这需要很长时间,在此期间表被完全锁定:不允许写入和读取。但仍然 \xe2\x80\x93 它允许我们重新获得磁盘空间。
\n使用新的 InnoDB 插件,执行 TRUNCATE TABLE 日志语句时也会重新获得磁盘空间。
\n碎片并不像单个表空间那样糟糕:数据被限制在较小文件的边界内。
\n监控
\ninnodb_file_per_table 的另一个好处是可以在文件系统级别监视表大小。您不需要访问 MySQL、使用 SHOW TABLE STATUS 或查询 INFORMATION_SCHEMA。您可以在 MySQL 数据目录(和子目录)下查找前 10 个最大的文件,并监控它们的大小。您可以看到哪个表增长最快。
\n备份
\n最后,还无法通过复制 .ibd 文件来备份单个 InnoDB 表。但希望工作能够朝着这个方向进行。
\n小智 7
十年后,我遇到了同样的问题。我通过以下方式解决了它:
就这些 :)
小智 6
今天遇到了这个问题(问题最初提出 11 年后),并能够通过删除表并再次创建它来修复它。我不必重新安装数据库或转储和恢复、修改存储、更改表空间等 - 都没有。
我使用的是 InnoDB,但不是 innodb_file_per_table,所以即使我从表中删除了 900K 行,数据库大小也没有改变。所以我删除了该表并重新创建了它。
就我而言,我的表被清理为零行,因此我很容易删除表,但保留我运行的结构
create table mynewtable as select * from myoldtable where 1=2;
Run Code Online (Sandbox Code Playgroud)
其次是
drop table myoldtable;
Run Code Online (Sandbox Code Playgroud)
这将我的数据库大小从 5G 减少到 400MB
| 归档时间: |
|
| 查看次数: |
127870 次 |
| 最近记录: |