Howto:清理 mysql InnoDB 存储引擎?
是否可以清理 mysql innodb 存储引擎,使其不存储已删除表中的数据?
或者我每次都必须重建一个新的数据库?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
是否可以清理 mysql innodb 存储引擎,使其不存储已删除表中的数据?
或者我每次都必须重建一个新的数据库?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(4)
这是关于 InnoDB 的更完整的答案。这是一个有点漫长的过程,但值得付出努力。
请记住,
/var/lib/mysql/ibdata1
是 InnoDB 基础架构中最繁忙的文件。它通常包含六种类型的信息:ibdata1 的图示
InnoDB 架构
许多人创建多个
ibdata
文件,希望获得更好的磁盘空间管理和性能,但是这种信念是错误的。我可以运行
OPTIMIZE TABLE
?不幸的是,运行
OPTIMIZE TABLE
针对存储在共享表空间文件ibdata1
中的 InnoDB 表执行两件事:ibdata1
内连续ibdata1
但是,您可以将表数据和表索引与
ibdata1
分离code> 并独立管理它们。我可以运行
OPTIMIZE TABLE
与 <代码>innodb_file_per_table?假设您要添加
innodb_file_per_table
到/etc/my.cnf (my.ini)
。然后你可以运行OPTIMIZE TABLE
在所有 InnoDB 表上?
好消息:当您运行
使用
rel="noreferrer">
innodb_file_per_table
启用,这将为该表生成一个.ibd
文件。例如,如果表mydb.mytable
的数据目录为/var/lib/mysql
,它将生成以下内容:/var/lib/mysql/ mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibd
将包含该表的数据页和索引页。伟大的。坏消息:您所做的只是从
ibdata
中提取mydb.mytable
的数据页和索引页。每个表的数据字典条目(包括mydb.mytable
)仍然保留在数据字典中(请参阅ibdata1 的图形表示)。 此时您不能简单地删除ibdata1
!!!请注意,ibdata1
根本没有缩小。InnoDB 基础设施清理
要一劳永逸地缩小 ibdata1,您必须执行以下操作:
将所有数据库转储(例如,使用 mysqldump)到
.sql< /code> 文本文件(下面使用
SQLData.sql
)删除所有数据库(
mysql
和information_schema
除外)CAVEAT< /strong> :作为预防措施,请运行此脚本以绝对确保您拥有所有用户授权:登录 mysql 并运行
SET GLOBAL innodb_fast_shutdown = 0;
(这将完全刷新ib_logfile0
中的所有剩余事务更改和ib_logfile1
)关闭 MySQL
将以下行添加到
/etc/my.cnf
(或my.ini
在 Windows 上)<前><代码>[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
(旁注:无论您设置什么
innodb_buffer_pool_size
,请确保innodb_log_file_size
是innodb_buffer_pool_size
的 25%。另外:
innodb_flush_method=O_DIRECT
在 Windows 上不可用)删除
ibdata*
和ib_logfile*
,或者,您可以删除中的所有文件夹/var/lib/mysql
,/var/lib/mysql/mysql
除外。启动 MySQL(这将重新创建
ibdata1
[默认情况下为 10MB] 以及ib_logfile0
和ib_logfile1
,各 1G)。导入
SQLData.sql
现在,
ibdata1
仍然会增长,但只包含表元数据,因为每个InnoDB表将存在于 ibdata1 之外。ibdata1
将不再包含其他表的 InnoDB 数据和索引。例如,假设您有一个名为
mydb.mytable
的 InnoDB 表。如果您查看/var/lib/mysql/mydb
,您将看到代表该表的两个文件:mytable.frm
(存储引擎标头)mytable.ibd
(表数据和索引)使用
/etc/my.cnf
中的innodb_file_per_table
选项,您可以运行OPTIMIZE TABLE mydb.mytable
文件/var/lib/mysql/mydb/mytable.ibd
实际上会缩小。在我作为 MySQL DBA 的职业生涯中,我曾多次这样做过。事实上,我第一次这样做时,我将 50GB
ibdata1
文件缩小到只有 500MB!尝试一下。如果您对此还有其他疑问,请询问。相信我;这无论是在短期还是长期都将发挥作用。
警告
在步骤 6 中,如果 mysql 由于
mysql
架构开始被删除而无法重新启动,请返回步骤 2。您创建了mysql
架构的物理副本。您可以按如下方式恢复:返回步骤 6 并继续
UPDATE 2013-06-04 11:13 EDT
关于设置 innodb_log_file_size 为 innodb_buffer_pool_size 在第 5 步中,这是相当老派的一揽子规则。
早在
2006年7月3日
,Percona 有一篇不错的文章 为什么要选择合适的innodb_log_file_size。后来,2008 年 11 月 21 日
,Percona 又发表了另一篇关于如何根据峰值工作负载保持一小时的更改来计算适当的大小。此后,我在 DBA StackExchange 中撰写了有关计算日志大小的帖子,并在其中引用了这两篇 Percona 文章。
2012 年 8 月 27 日
: 在 48GB RAM 的服务器上正确调整 30GB InnoDB 表就个人而言,我仍然会采用 25% 规则进行初始设置。然后,由于在生产中随着时间的推移可以更准确地确定工作负载,您可以调整日志大小< /a> 在维护周期内仅需几分钟。
Here is a more complete answer with regard to InnoDB. It is a bit of a lengthy process, but can be worth the effort.
Keep in mind that
/var/lib/mysql/ibdata1
is the busiest file in the InnoDB infrastructure. It normally houses six types of information:Pictorial Representation of ibdata1
InnoDB Architecture
Many people create multiple
ibdata
files hoping for better disk-space management and performance, however that belief is mistaken.Can I run
OPTIMIZE TABLE
?Unfortunately, running
OPTIMIZE TABLE
against an InnoDB table stored in the shared table-space fileibdata1
does two things:ibdata1
ibdata1
grow because the contiguous data and index pages are appended toibdata1
You can however, segregate Table Data and Table Indexes from
ibdata1
and manage them independently.Can I run
OPTIMIZE TABLE
withinnodb_file_per_table
?Suppose you were to add
innodb_file_per_table
to/etc/my.cnf (my.ini)
. Can you then just runOPTIMIZE TABLE
on all the InnoDB Tables?Good News : When you run
OPTIMIZE TABLE
withinnodb_file_per_table
enabled, this will produce a.ibd
file for that table. For example, if you have tablemydb.mytable
witha datadir of/var/lib/mysql
, it will produce the following:/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
The
.ibd
will contain the Data Pages and Index Pages for that table. Great.Bad News : All you have done is extract the Data Pages and Index Pages of
mydb.mytable
from living inibdata
. The data dictionary entry for every table, includingmydb.mytable
, still remains in the data dictionary (See the Pictorial Representation of ibdata1). YOU CANNOT JUST SIMPLY DELETEibdata1
AT THIS POINT !!! Please note thatibdata1
has not shrunk at all.InnoDB Infrastructure Cleanup
To shrink
ibdata1
once and for all you must do the following:Dump (e.g., with
mysqldump
) all databases into a.sql
text file (SQLData.sql
is used below)Drop all databases (except for
mysql
andinformation_schema
) CAVEAT : As a precaution, please run this script to make absolutely sure you have all user grants in place:Login to mysql and run
SET GLOBAL innodb_fast_shutdown = 0;
(This will completely flush all remaining transactional changes fromib_logfile0
andib_logfile1
)Shutdown MySQL
Add the following lines to
/etc/my.cnf
(ormy.ini
on Windows)(Sidenote: Whatever your set for
innodb_buffer_pool_size
, make sureinnodb_log_file_size
is 25% ofinnodb_buffer_pool_size
.Also:
innodb_flush_method=O_DIRECT
is not available on Windows)Delete
ibdata*
andib_logfile*
, Optionally, you can remove all folders in/var/lib/mysql
, except/var/lib/mysql/mysql
.Start MySQL (This will recreate
ibdata1
[10MB by default] andib_logfile0
andib_logfile1
at 1G each).Import
SQLData.sql
Now,
ibdata1
will still grow but only contain table metadata because each InnoDB table will exist outside ofibdata1
.ibdata1
will no longer contain InnoDB data and indexes for other tables.For example, suppose you have an InnoDB table named
mydb.mytable
. If you look in/var/lib/mysql/mydb
, you will see two files representing the table:mytable.frm
(Storage Engine Header)mytable.ibd
(Table Data and Indexes)With the
innodb_file_per_table
option in/etc/my.cnf
, you can runOPTIMIZE TABLE mydb.mytable
and the file/var/lib/mysql/mydb/mytable.ibd
will actually shrink.I have done this many times in my career as a MySQL DBA. In fact, the first time I did this, I shrank a 50GB
ibdata1
file down to only 500MB!Give it a try. If you have further questions on this, just ask. Trust me; this will work in the short term as well as over the long haul.
CAVEAT
At Step 6, if mysql cannot restart because of the
mysql
schema begin dropped, look back at Step 2. You made the physical copy of themysql
schema. You can restore it as follows:Go back to Step 6 and continue
UPDATE 2013-06-04 11:13 EDT
With regard to setting innodb_log_file_size to 25% of innodb_buffer_pool_size in Step 5, that's blanket rule is rather old school.
Back on
July 03, 2006
, Percona had a nice article why to choose a proper innodb_log_file_size. Later, onNov 21, 2008
, Percona followed up with another article on how to calculate the proper size based on peak workload keeping one hour's worth of changes.I have since written posts in the DBA StackExchange about calculating the log size and where I referenced those two Percona articles.
Aug 27, 2012
: Proper tuning for 30GB InnoDB table on server with 48GB RAMJan 17, 2013
: MySQL 5.5 - Innodb - innodb_log_file_size higher than 4GB combined?Personally, I would still go with the 25% rule for an initial setup. Then, as the workload can more accurate be determined over time in production, you could resize the logs during a maintenance cycle in just minutes.
InnoDB引擎不存储已删除的数据。当您插入和删除行时,未使用的空间将在 InnoDB 存储文件中分配。随着时间的推移,总体空间不会减少,但随着时间的推移,“删除和释放”的空间将被数据库服务器自动重用。
您可以通过手动重新组织表来进一步调整和管理引擎使用的空间。为此,请使用 mysqldump 转储受影响表中的数据,删除这些表,重新启动 mysql 服务,然后从转储文件重新创建表。
The InnoDB engine does not store deleted data. As you insert and delete rows, unused space is left allocated within the InnoDB storage files. Over time, the overall space will not decrease, but over time the 'deleted and freed' space will be automatically reused by the DB server.
You can further tune and manage the space used by the engine through an manual re-org of the tables. To do this, dump the data in the affected tables using mysqldump, drop the tables, restart the mysql service, and then recreate the tables from the dump files.
我按照本指南进行完全重置(以 root 身份):
I follow this guide for a complete reset (as root):
似乎没有人提到 innodb_undo_log_truncate 设置可能产生的影响。
看看我的答案 如何收缩/清除MySQL 中的 ibdata1 文件。
What nobody seems to mention is the impact
innodb_undo_log_truncate
setting can have.Take a look at my answer at How to shrink/purge ibdata1 file in MySQL.