[TOC]
InnoDB
is a general-purpose storage engine that balances high reliability and high performance. In MySQL 5.7, InnoDB
is the default MySQL storage engine. Unless you have configured a different default storage engine, issuing a CREATE TABLE
statement without an ENGINE=
clause creates an InnoDB
table.
InnoDB
是一款通用的存储引擎, 同时具备高可靠性和高性能特征。 在MySQL 5.7中, InnoDB
是默认的存储引擎。 不带 ENGINE=
子句的 CREATE TABLE
语句, 默认创建的都是 InnoDB
表, 除非DBA修改了默认存储引擎的配置。
- Its
DML
operations follow theACID
model, withtransactions
featuringcommit
,rollback
, andcrash-recovery
capabilities to protect user data. See Section 14.2, “InnoDB and the ACID Model” for more information. - Row-level
locking
and Oracle-style [consistent reads] increase multi-user concurrency and performance. See Section 14.7, “InnoDB Locking and Transaction Model” for more information. InnoDB
tables arrange your data on disk to optimize queries based onprimary keys
. EachInnoDB
table has a primary key index called theclustered index
that organizes the data to minimize I/O for primary key lookups. See Section 14.6.2.1, “Clustered and Secondary Indexes” for more information.- To maintain data
integrity
,InnoDB
supportsFOREIGN KEY
constraints. With foreign keys, inserts, updates, and deletes are checked to ensure they do not result in inconsistencies across different tables. See Section 13.1.18.5, “FOREIGN KEY Constraints” for more information.
InnoDB
遵循ACID
标准模型, 支持事务(transactions
), 具有提交(commit
), 回滚(rollback
) 功能和保护用户数据的崩溃恢复(crash-recovery
)机制。 关于ACID的更多信息请参考 14.2 InnoDB和ACID模型。- 支持行级锁(Row-level locking), 以及类似于Oracle的 一致性读(consistent reads), 提高了多用户环境下的并发性能。 更多信息可参考 14.7 InnoDB的锁和事务模型。
InnoDB
表将数据存储到在磁盘上, 基于主键
进行查询优化。 每个InnoDB
表都有一个主键索引(primary key index), 称为聚集索引(clustered index
), 聚集索引可以有效降低主键查找需要的磁盘IO。 更多信息请参考 Section 14.6.2.1, “Clustered and Secondary Indexes”。- 为了维持数据完整性(
integrity
), InnoDB支持外键约束(FOREIGN KEY
)。 通过外键对 inserts, updates, 以及 deletes 操作进行检查, 以确保不同表之间的数据不会因为这些操作造成不一致。 更多信息请参考 Section 13.1.18.5, “FOREIGN KEY Constraints”。
Table 14.1 InnoDB Storage Engine Features
Feature | Support |
---|---|
B-tree indexes | Yes |
Backup/point-in-time recovery (Implemented in the server, rather than in the storage engine.) | Yes |
Cluster database support | No |
Clustered indexes | Yes |
Compressed data | Yes |
Data caches | Yes |
Encrypted data | Yes (Implemented in the server via encryption functions; In MySQL 5.7 and later, data-at-rest tablespace encryption is supported.) |
Foreign key support | Yes |
Full-text search indexes | Yes (InnoDB support for FULLTEXT indexes is available in MySQL 5.6 and later.) |
Geospatial data type support | Yes |
Geospatial indexing support | Yes (InnoDB support for geospatial indexing is available in MySQL 5.7 and later.) |
Hash indexes | No (InnoDB utilizes hash indexes internally for its Adaptive Hash Index feature.) |
Index caches | Yes |
Locking granularity | Row |
MVCC | Yes |
Replication support (Implemented in the server, rather than in the storage engine.) | Yes |
Storage limits | 64TB |
T-tree indexes | No |
Transactions | Yes |
Update statistics for data dictionary | Yes |
To compare the features of InnoDB
with other storage engines provided with MySQL, see the Storage Engine Features table in Chapter 15, Alternative Storage Engines.
要比对 InnoDB
与其他存储引擎的功能特征, 请参阅Chapter 15, Alternative Storage Engines。
For information about InnoDB
enhancements and new features, refer to:
- The
InnoDB
enhancements list in Section 1.3, “What Is New in MySQL 5.7”. - The Release Notes.
有关InnoDB
增强功能和新特性的信息, 请参阅:
- Section 1.3, “What Is New in MySQL 5.7”中的
InnoDB
增强功能列表。 - 版本发行说明.
- For
InnoDB
-related terms and definitions, see the MySQL Glossary. - For a forum dedicated to the
InnoDB
storage engine, see MySQL Forums::InnoDB. InnoDB
is published under the same GNU GPL License Version 2 (of June 1991) as MySQL. For more information on MySQL licensing, see http://www.mysql.com/company/legal/licensing/.
InnoDB
相关的术语和定义, 请参考 MySQL术语表.InnoDB
存储引擎论坛, 请参考 MySQL Forums::InnoDB。InnoDB
与MySQL都使用 GNU GPL License Version 2 (of June 1991) 许可协议。 有关MySQL许可的更多信息, 请参考 http://www.mysql.com/company/legal/licensing/ 。
You may find InnoDB
tables beneficial for the following reasons:
我们会发现使用InnoDB
表有这些好处:
-
If your server unexpectedly exits because of a hardware or software issue, regardless of what was happening in the database at the time, you don't need to do anything special after restarting the database.
InnoDB
crash recovery
automatically finalizes any changes that were committed before the time of the crash, and undoes any changes that were in process but not committed. Just restart and continue where you left off. -
The
InnoDB
storage engine maintains its ownbuffer pool
that caches table and index data in main memory as data is accessed. Frequently used data is processed directly from memory. This cache applies to many types of information and speeds up processing. On dedicated database servers, up to 80% of physical memory is often assigned to the buffer pool. -
If you split up related data into different tables, you can set up
foreign keys
that enforcereferential integrity
. Update or delete data, and the related data in other tables is updated or deleted automatically. Try to insert data into a secondary table without corresponding data in the primary table, and the bad data gets kicked out automatically. -
If data becomes corrupted on disk or in memory, a
checksum
mechanism alerts you to the bogus data before you use it. -
When you design your database with appropriate
primary key
columns for each table, operations involving those columns are automatically optimized. It is very fast to reference the primary key columns inWHERE
clauses,ORDER BY
clauses,GROUP BY
clauses, andjoin
operations. -
如果服务器由于硬件或者软件问题而意外崩溃, 不管当时数据库正在做什么操作, 重启数据库之后都不需要执行任何人工操作。
InnoDB
的崩溃恢复机制将自动完成崩溃前已提交的所有更改, 并撤消所有正在处理但尚未提交的更改。只需重新启动, 然后从上次中断的地方继续即可。 -
InnoDB
存储引擎维护自己的缓冲池(buffer pool
), 在访问数据时将表和索引数据缓存到内存中。经常使用的数据直接从内存中获取。 缓存适用于多种类型的信息, 可以加快处理速度。 在专用数据库服务器上(dedicated database servers), 最多可以将 80% 的物理内存分配给缓冲池。 -
如果将相关数据拆分到不同的表中, 可以设置
外键
来强制保证引用完整性(referential integrity
)。更新或删除主表数据时, 会自动更新或删除其他表中相关的数据。 尝试插入子表数据时, 如果在主表中没有相应的数据, 那么无效数据会自动失败。 -
如果磁盘或内存中的数据被破坏, 则在使用前, 校验和机制(
checksum
)会提醒我们注意虚假数据。 -
为每个表设计合适的
主键
之后, 涉及这些列的操作会自动进行优化。 在WHERE
条件,ORDER BY
,GROUP BY
子句以及join
操作中的主键列操作都特别快。 -
Inserts, updates, and deletes are optimized by an automatic mechanism called
change buffering
.InnoDB
not only allows concurrent read and write access to the same table, it caches changed data to streamline disk I/O. -
Performance benefits are not limited to giant tables with long-running queries. When the same rows are accessed over and over from a table, a feature called the
Adaptive Hash Index
takes over to make these lookups even faster, as if they came out of a hash table. -
You can compress tables and associated indexes.
-
You can create and drop indexes with much less impact on performance and availability.
-
Truncating a
file-per-table
tablespace is very fast, and can free up disk space for the operating system to reuse, rather than freeing up space within thesystem tablespace
that onlyInnoDB
can reuse. -
insert, update, 以及 delete 操作都通过
更改缓冲
(change buffering
) 的机制进行了自动优化。InnoDB
不仅支持对同一个表进行并发读写, 而且还将更改的数据缓存起来以简化磁盘I/O。 -
不仅长时间运行的巨型表查询性能会得到优化。 当从表中多次访问同一行时, 自适应哈希索引(
Adaptive Hash Index
)特性会让这些查询变得更快, 就像是从哈希表中取出来的一样。 -
可以压缩表和关联的索引。
-
创建和删除索引时, 对性能和可用性的影响要小得多。
-
对于
file-per-table
表空间的截断非常快, 并且可以释放磁盘空间, 而不是只释放InnoDB
中的system tablespace
空间。 -
The storage layout for table data is more efficient for
BLOB
and long text fields, with theDYNAMIC
row format. -
You can monitor the internal workings of the storage engine by querying
INFORMATION_SCHEMA
tables. -
You can monitor the performance details of the storage engine by querying
Performance Schema
tables. -
You can freely mix
InnoDB
tables with tables from other MySQL storage engines, even within the same statement. For example, you can use ajoin
operation to combine data fromInnoDB
andMEMORY
tables in a single query. -
InnoDB
has been designed for CPU efficiency and maximum performance when processing large data volumes. -
InnoDB
tables can handle large quantities of data, even on operating systems where file size is limited to 2GB. -
可以通过
INFORMATION_SCHEMA
中的表来监控存储引擎的内部状况。 -
可以通过
Performance Schema
中的表来监控存储引擎性能的详细信息。 -
即使在同一条SQL语句中, 也可以将
InnoDB
表与其他MySQL存储引擎的表自由组合。 例如, 可以在一个查询中使用join
来关联查询InnoDB
和MEMORY
表中的数据。 -
InnoDB
专门为CPU使用效率和最佳性能而设计, 能完美应对大规模的数据。 -
InnoDB
表支持很大的数据量, 即使在单个文件限制为2GB的操作系统中也不受影响。
For InnoDB
-specific tuning techniques you can apply in your application code, see Section 8.5, “Optimizing for InnoDB Tables”.
在应用程序中进行InnoDB调优的技术, 请参考 Section 8.5, “Optimizing for InnoDB Tables”。
This section describes best practices when using InnoDB
tables.
下面通过最佳实践来介绍怎么使用InnoDB
。
-
Specifying a
primary key
for every table using the most frequently queried column or columns, or anauto-increment
value if there is no obvious primary key. -
Using
joins
wherever data is pulled from multiple tables based on identical ID values from those tables. For fast join performance, defineforeign keys
on the join columns, and declare those columns with the same data type in each table. Adding foreign keys ensures that referenced columns are indexed, which can improve performance. Foreign keys also propagate deletes or updates to all affected tables, and prevent insertion of data in a child table if the corresponding IDs are not present in the parent table. -
Turning off
autocommit
. Committing hundreds of times a second puts a cap on performance (limited by the write speed of your storage device). -
Grouping sets of related
DML
operations intotransactions
, by bracketing them withSTART TRANSACTION
andCOMMIT
statements. While you don't want to commit too often, you also don't want to issue huge batches ofINSERT
,UPDATE
, orDELETE
statements that run for hours without committing. -
为每个表设置主键(
primary key
), 一般是查询最常使用的一列或多列, 如果没有很明显的业务主键, 则使用自增ID(auto-increment
)。 【最佳设计原则: 主键无意义, 或者说在生成之前无具体的业务含义, 这样能最大限度避免修改。】 -
使用
join
从多个表抽取数据时, 基于主键ID值进行关联。 为了提高连接性能, 可在 join 列上定义外键, 这些列在每个表中的数据类型都保持一致。 添加外键可确保对被引用的列添加索引, 从而提高性能。 外键还会将删除或更新传播到所有受影响的表, 如果父表中不存在相应的ID, 则可以防止在子表中插入数据。 【最佳设计原则: 当前基于Web应用的开发年代, 不要使用外键, 那是以数据库为中心的上一代程序的设计方式。】 -
如果每次业务操作都涉及大量的数据修改, 请关闭
autocommit
。 受存储设备的写入速度限制,可能一秒钟只支持几百次提交。 -
将相关的
DML
操作归集为“事务”, 放在START TRANSACTION
和COMMIT
中间。 需要掌握好每个批次的量, 我们不想频繁提交, 但也不能让一次提交需要耗费很长时间, 对吧。 -
Not using
LOCK TABLES
statements.InnoDB
can handle multiple sessions all reading and writing to the same table at once, without sacrificing reliability or high performance. To get exclusive write access to a set of rows, use theSELECT ... FOR UPDATE
syntax to lock just the rows you intend to update. -
Enabling the
innodb_file_per_table
option or using general tablespaces to put the data and indexes for tables into separate files, instead of thesystem tablespace
.The
innodb_file_per_table
option is enabled by default. -
Evaluating whether your data and access patterns benefit from the
InnoDB
table or pagecompression
features. You can compressInnoDB
tables without sacrificing read/write capability. -
Running your server with the option
--sql_mode=NO_ENGINE_SUBSTITUTION
to prevent tables being created with a different storage engine if there is an issue with the engine specified in theENGINE=
clause ofCREATE TABLE
. -
禁止使用
LOCK TABLES
语句。InnoDB
可以一次处理多个会话, 一次读写同一张表, 而不会牺牲可靠性或高性能。要获得对一组行的排他写访问权限, 请使用[SELECT ... FOR UPDATE
](https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html)语法仅锁定要更新的行。 -
启用
innodb_file_per_table
选项或者使用常规表空间, 将表数据和索引存放到单独的文件中, 而不要放到system tablespace
中。默认
innodb_file_per_table
选项是启用的。 -
评估数据和访问模式是否受益于
InnoDB
表或页压缩功能。 我们可以在不损害读/写性能的情况下压缩InnoDB
表。 -
如果
CREATE TABLE
的ENGINE=
子句中指定的引擎存在问题, 则使用选项--sql_mode=NO_ENGINE_SUBSTITUTION
来启动MySQL服务器, 阻止用其他存储引擎来创建表。
Issue the SHOW ENGINES
statement to view the available MySQL storage engines. Look for DEFAULT
in the InnoDB
line.
使用 SHOW ENGINES
语句可以查看MySQL支持的存储引擎。 我们需要关注 InnoDB
对应的行中是否有 DEFAULT
这个值。
mysql> SHOW ENGINES;
Alternatively, query the INFORMATION_SCHEMA.ENGINES
table.
或者查询 INFORMATION_SCHEMA.ENGINES
表。
mysql> SELECT * FROM INFORMATION_SCHEMA.ENGINES;
结果都是类似的。
If InnoDB
is not your default storage engine, you can determine if your database server or applications work correctly with InnoDB
by restarting the server with --default-storage-engine=InnoDB
defined on the command line or with default-storage-engine=innodb
defined in the mysqld
section of your MySQL server option file.
Since changing the default storage engine only affects new tables as they are created, run all your application installation and setup steps to confirm that everything installs properly. Then exercise all the application features to make sure all the data loading, editing, and querying features work. If a table relies on a feature that is specific to another storage engine, you receive an error; add the ENGINE=<other_engine_name>
clause to the CREATE TABLE
statement to avoid the error.
If you did not make a deliberate decision about the storage engine, and you want to preview how certain tables work when created using InnoDB
, issue the command ALTER TABLE table_name ENGINE=InnoDB;
for each table. Or, to run test queries and other statements without disturbing the original table, make a copy:
如果InnoDB
不是默认存储引擎, 则可以先在测试或者开发环境下,通过命令行参数 --default-storage-engine=InnoDB
, 或者在MySQL配置文件 mysqld
一节中定义 default-storage-engine=innodb
, 并重启MySQL服务器, 以确定 InnoDB
是否和数据库或应用系统兼容。
由于更改默认存储引擎只会影响新创建的表, 所以需要从头开始进行回归测试, 覆盖所有的系统功能, 包括数据加载, 编辑和查询功能都正常。 如果表依赖于某个特定存储引擎的功能特征, 则会产生错误信息; 这时候将 ENGINE=<other_engine_name>
子句加到CREATE TABLE
语句中即可。
如果不确定使用哪个存储引擎, 并且想看看 InnoDB
表的工作方式, 可以使用 ALTER TABLE table_name ENGINE=InnoDB;
语句。 或者, 在不干扰原始表的情况下, 复制一个表出来进行测试:
CREATE TABLE InnoDB_Table (...) ENGINE=InnoDB AS SELECT * FROM other_engine_table;
To assess performance with a full application under a realistic workload, install the latest MySQL server and run benchmarks.
Test the full application lifecycle, from installation, through heavy usage, and server restart. Kill the server process while the database is busy to simulate a power failure, and verify that the data is recovered successfully when you restart the server.
Test any replication configurations, especially if you use different MySQL versions and options on the source server and replicas.
要在实际工作负载下评估整个应用系统的性能, 请安装最新版的MySQL服务器并执行基准测试。
测试整个应用程序生命周期, 包括安装, 重型负载、以及服务器重启。 在数据库繁忙时模拟电源故障, 强制杀掉服务器进程, 并在重启服务器后验证数据是否成功恢复。
测试所有的主从复制配置, 尤其是源服务器和副本服务器使用了不同的MySQL版本和配置的情况下。
Oracle recommends InnoDB
as the preferred storage engine for typical database applications, from single-user wikis and blogs running on a local system, to high-end applications pushing the limits of performance. In MySQL 5.7, InnoDB
is the default storage engine for new tables.
Important
InnoDB
cannot be disabled. The --skip-innodb
option is deprecated and has no effect, and its use results in a warning. Expect it to be removed in a future MySQL release. This also applies to its synonyms (--innodb=OFF
, --disable-innodb
, and so forth).
Oracle公司建议将InnoDB
作为首选存储引擎, 包括本机运行的单用户Wiki和博客, 到需要极限性能的高端应用系统。 在 MySQL 5.7 中, InnoDB
是新建表时的默认存储引擎。
重要提示
InnoDB
无法被禁用。 --skip-innodb
选项已被弃用, 并且指定了也没有效果, 还会产生警告。 这个选项在将来的MySQL版本中预期会被删除。 这同样适用于同义词(--innodb=OFF
, --disable-innodb
, 等等)。