是否可以清理mysql innodb存储引擎,使其不存储已删除表中的数据?
还是我每次都必须重建一个新的数据库?
最佳答案
这是有关InnoDB的更完整答案。这是一个漫长的过程,但是值得付出努力。
请记住,/var/lib/mysql/ibdata1
是InnoDB基础架构中最繁忙的文件。它通常包含六种类型的信息:
表数据
表索引
MVCC (Multiversioning Concurrency Control)数据
回滚段
撤消空间
表元数据(数据字典)
双重写入缓冲区(后台写入,以防止依赖于OS缓存)
插入缓冲区(管理对非唯一二级索引的更改)
请参见Pictorial Representation of ibdata1
InnoDB架构
许多人创建了多个ibdata
文件,希望可以更好地管理磁盘空间并提高性能,但是这种想法是错误的。
我可以运行OPTIMIZE TABLE
吗?
不幸的是,对存储在共享表空间文件OPTIMIZE TABLE
中的InnoDB表运行ibdata1
有两件事:
使表的数据和索引在ibdata1
内连续
使ibdata1
增大,因为连续的数据和索引页被附加到ibdata1
但是,您可以将表数据和表索引与ibdata1
隔离,并分别进行管理。
我可以使用OPTIMIZE TABLE
运行innodb_file_per_table
吗?
假设您要将innodb_file_per_table
添加到/etc/my.cnf (my.ini)
。然后可以在所有InnoDB表上运行OPTIMIZE TABLE
吗?
好消息:在启用OPTIMIZE TABLE
的情况下运行innodb_file_per_table
时,将为该表生成一个.ibd
文件。例如,如果您的表mydb.mytable
的数据目录为/var/lib/mysql
,它将产生以下内容:/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibd
将包含该表的数据页和索引页。大。
坏消息:您所要做的就是从居住在mydb.mytable
中提取ibdata
的数据页和索引页。每个表(包括mydb.mytable
)的数据字典条目仍保留在数据字典中(请参见Pictorial Representation of ibdata1)。您不能在这一点上简单地删除ibdata1
!!!请注意,ibdata1
完全没有缩小。
InnoDB基础架构清理
要一劳永逸地缩小ibdata1
,您必须执行以下操作:
将所有数据库转储(例如,使用mysqldump
)到.sql
文本文件中(以下使用SQLData.sql
)
删除所有数据库(除了mysql
和information_schema
之外)CAVEAT:为慎重起见,请运行此脚本以确保完全拥有所有用户授权:
mkdir /var/lib/mysql_grants
cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/.
chown -R mysql:mysql /var/lib/mysql_grants
登录到mysql并运行
SET GLOBAL innodb_fast_shutdown = 0;
(这将完全清除ib_logfile0
和ib_logfile1
中所有剩余的事务更改)关闭MySQL
将以下行添加到
/etc/my.cnf
(或Windows上的my.ini
)[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],并分别以1G重新创建ib_logfile0
和ib_logfile1
)。导入
SQLData.sql
现在,
ibdata1
仍将增长,但仅包含表元数据,因为每个InnoDB表都将存在于ibdata1
之外。 ibdata1
将不再包含InnoDB数据和其他表的索引。例如,假设您有一个名为
mydb.mytable
的InnoDB表。如果查看/var/lib/mysql/mydb
,将看到代表该表的两个文件:mytable.frm
(存储引擎标题)mytable.ibd
(表数据和索引)使用
innodb_file_per_table
中的/etc/my.cnf
选项,您可以运行OPTIMIZE TABLE mydb.mytable
,文件/var/lib/mysql/mydb/mytable.ibd
实际上会缩小。在我作为MySQL DBA的职业生涯中,我做了很多次。实际上,我第一次这样做是将50GB
ibdata1
文件压缩到只有500MB!试试看。如果您对此还有其他疑问,请提出。相信我;从短期和长期来看,这都是可行的。
警告
在步骤6中,如果由于
mysql
模式开始删除而导致mysql无法重新启动,请回头看一下步骤2。您可以按以下方式还原它:mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
返回步骤6并继续
更新2013-06-04 11:13 EDT
关于在第5步中将innodb_log_file_size设置为innodb_buffer_pool_size的25%的原则,这是相当老套的规则。
回到
mysql
,Percona有一篇不错的文章why to choose a proper innodb_log_file_size。后来,在July 03, 2006
上,Percona跟进了关于how to calculate the proper size based on peak workload keeping one hour's worth of changes的另一篇文章。此后,我在DBA StackExchange中撰写了有关计算日志大小以及在其中引用这两篇Percona文章的文章。
Nov 21, 2008
:Proper tuning for 30GB InnoDB table on server with 48GB RAMAug 27, 2012
:MySQL 5.5 - Innodb - innodb_log_file_size higher than 4GB combined?就个人而言,我仍然会遵循25%的规则进行初始设置。然后,由于可以随着生产时间的推移更准确地确定工作负载,因此在维护周期内只需几分钟即可you could resize the logs。
关于mysql - 如何:清理mysql InnoDB存储引擎?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19688707/