Howto: Clean a mysql InnoDB storage engine?(如何:清理 mysql InnoDB 存储引擎?)
问题描述
是否可以清理 mysql innodb 存储引擎,使其不存储已删除表中的数据?
还是我每次都必须重建一个新的数据库?
这里有一个关于 InnoDB 的更完整的答案.这是一个有点漫长的过程,但值得付出努力.
请记住,/var/lib/mysql/ibdata1 是 InnoDB 基础架构中最繁忙的文件.它通常包含六种类型的信息:
- 表格数据
- 表索引
- ?
不幸的是,正在运行
OPTIMIZE TABLE针对存储在共享表空间文件ibdata1中的 InnoDB 表做了两件事:- 使表的数据和索引在
ibdata1 中连续 - 使
ibdata1增长,因为连续数据和索引页附加到ibdata1
但是,您可以将表数据和表索引与
ibdata1分开并独立管理.我可以运行
OPTIMIZE TABLE与innodb_file_per_table?假设您要添加
innodb_file_per_table到/etc/my.cnf (my.ini).然后你可以运行OPTIMIZE TABLE代码>在所有 InnoDB 表上?好消息:当您运行
OPTIMIZE TABLE使用innodb_file_per_table启用,这将为该表生成一个.ibd文件.例如,如果你有一个数据目录为/var/lib/mysql的表mydb.mytable,它会产生以下内容:/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文本文件(SQLData.sql在下面使用)删除所有数据库(
mysql和information_schema除外)CAVEAT :作为预防措施,请运行此脚本以确保绝对确保您拥有所有用户授权:mkdir/var/lib/mysql_grantscp/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_tableinnodb_flush_method=O_DIRECTinnodb_log_file_size=1Ginnodb_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模式的物理副本.您可以通过以下方式恢复它:mkdir/var/lib/mysql/mysqlcp/var/lib/mysql_grants/*/var/lib/mysql/mysqlchown -R mysql:mysql/var/lib/mysql/mysql返回第 6 步并继续
更新 2013-06-04 11:13 EDT
关于将 innodb_log_file_size 设置为步骤 5 中 innodb_buffer_pool_size 的 25%,即一揽子规则相当老派.
回到
2006 年 7 月 3 日,Percona 发表了一篇不错的文章 为什么选择合适的 innodb_log_file_size.后来,在2008 年 11 月 21 日,Percona 跟进了另一篇关于 如何根据保持一小时变化的峰值工作负载计算合适的大小.此后我在 DBA StackExchange 中写了一些关于计算日志大小的帖子,以及我在何处引用了这两篇 Percona 文章.
2012 年 8 月 27 日:正确调整具有 48GB RAM 的服务器上的 30GB InnoDB 表一个>2013 年 1 月 17 日:MySQL 5.5 - Innodb - innodb_log_file_size 大于 4GB 的总和?一个>
就我个人而言,我仍然会采用 25% 的规则进行初始设置.然后,由于可以在生产中随着时间的推移更准确地确定工作负载,您可以调整日志的大小 在短短几分钟的维护周期内.
Is it possible to clean a mysql innodb storage engine so it is not storing data from deleted tables?
Or do I have to rebuild a fresh database every time?
解决方案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/ibdata1is the busiest file in the InnoDB infrastructure. It normally houses six types of information:- Table Data
- Table Indexes
- MVCC (Multiversioning Concurrency Control) Data
- Rollback Segments
- Undo Space
- Table Metadata (Data Dictionary)
- Double Write Buffer (background writing to prevent reliance on OS caching)
- Insert Buffer (managing changes to non-unique secondary indexes)
- See the
Pictorial Representation of ibdata1
InnoDB Architecture
Many people create multiple
ibdatafiles hoping for better disk-space management and performance, however that belief is mistaken.Can I run
OPTIMIZE TABLE?Unfortunately, running
OPTIMIZE TABLEagainst an InnoDB table stored in the shared table-space fileibdata1does two things:- Makes the table’s data and indexes contiguous inside
ibdata1 - Makes
ibdata1grow because the contiguous data and index pages are appended toibdata1
You can however, segregate Table Data and Table Indexes from
ibdata1and manage them independently.Can I run
OPTIMIZE TABLEwithinnodb_file_per_table?Suppose you were to add
innodb_file_per_tableto/etc/my.cnf (my.ini). Can you then just runOPTIMIZE TABLEon all the InnoDB Tables?Good News : When you run
OPTIMIZE TABLEwithinnodb_file_per_tableenabled, this will produce a.ibdfile for that table. For example, if you have tablemydb.mytablewitha datadir of/var/lib/mysql, it will produce the following:/var/lib/mysql/mydb/mytable.frm/var/lib/mysql/mydb/mytable.ibd
The
.ibdwill 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.mytablefrom 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 DELETEibdata1AT THIS POINT !!! Please note thatibdata1has not shrunk at all.InnoDB Infrastructure Cleanup
To shrink
ibdata1once and for all you must do the following:Dump (e.g., with
mysqldump) all databases into a.sqltext file (SQLData.sqlis used below)Drop all databases (except for
mysqlandinformation_schema) CAVEAT : As a precaution, please run this script to make absolutely sure you have all user grants in place:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grantsLogin to mysql and run
SET GLOBAL innodb_fast_shutdown = 0;(This will completely flush all remaining transactional changes fromib_logfile0andib_logfile1)Shutdown MySQL
Add the following lines to
/etc/my.cnf(ormy.inion Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G(Sidenote: Whatever your set for
innodb_buffer_pool_size, make sureinnodb_log_file_sizeis 25% ofinnodb_buffer_pool_size.Also:
innodb_flush_method=O_DIRECTis 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_logfile0andib_logfile1at 1G each).Import
SQLData.sql
Now,
ibdata1will still grow but only contain table metadata because each InnoDB table will exist outside ofibdata1.ibdata1will 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_tableoption in/etc/my.cnf, you can runOPTIMIZE TABLE mydb.mytableand the file/var/lib/mysql/mydb/mytable.ibdwill 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
ibdata1file 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
mysqlschema begin dropped, look back at Step 2. You made the physical copy of themysqlschema. You can restore it as follows:mkdir /var/lib/mysql/mysql cp /var/lib/mysql_grants/* /var/lib/mysql/mysql chown -R mysql:mysql /var/lib/mysql/mysqlGo 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.
这篇关于如何:清理 mysql InnoDB 存储引擎?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
- 使表的数据和索引在
本文标题为:如何:清理 mysql InnoDB 存储引擎?
- 远程 mySQL 连接抛出“无法使用旧的不安全身份验证连接到 MySQL 4.1+"来自 XAMPP 的错误 2022-01-01
- 更改自动增量起始编号? 2021-01-01
- 以一个值为轴心,但将一行上的数据按另一行分组? 2022-01-01
- 使用 Oracle PL/SQL developer 生成测试数据 2021-01-01
- 导入具有可变标题的 Excel 文件 2021-01-01
- 如何将 Byte[] 插入 SQL Server VARBINARY 列 2021-01-01
- 如何将 SonarQube 6.7 从 MySQL 迁移到 postgresql 2022-01-01
- 如何使用 pip 安装 Python MySQLdb 模块? 2021-01-01
- 在SQL中,如何为每个组选择前2行 2021-01-01
- SQL 临时表问题 2022-01-01
