关于 InnoDB
配置的首要决策涉及数据文件、日志文件、页面大小和内存缓冲区的配置,这些都应在初始化 InnoDB
之前配置好。在 InnoDB
初始化后修改配置可能涉及非平凡的过程。
本节提供有关在配置文件中指定 InnoDB
设置、查看 InnoDB
初始化信息以及重要的存储注意事项的信息。
由于 MySQL 使用数据文件、日志文件和页面大小设置来初始化 InnoDB
,因此建议您在 MySQL 启动时读取的选项文件中定义这些设置,然后再初始化 InnoDB
。通常,InnoDB
在首次启动 MySQL 服务器时初始化。
您可以将 InnoDB
选项放在服务器启动时读取的任何选项文件的 [mysqld]
组中。MySQL 选项文件的位置在 第 6.2.2.2 节 “使用选项文件” 中进行了描述。
要确保 mysqld 仅从特定文件(和 mysqld-auto.cnf
)读取选项,请在启动服务器时使用 --defaults-file
选项作为命令行上的第一个选项。
mysqld --defaults-file=path_to_option_file
要在启动期间查看 InnoDB
初始化信息,请从命令提示符启动 mysqld,这会将初始化信息打印到控制台。
例如,在 Windows 上,如果 mysqld 位于 C:\Program Files\MySQL\MySQL Server 8.4\bin
中,请像这样启动 MySQL 服务器:
C:\> "C:\Program Files\MySQL\MySQL Server 8.4\bin\mysqld" --console
在类 Unix 系统上,mysqld 位于 MySQL 安装的 bin
目录中。
$> bin/mysqld --user=mysql &
如果您没有将服务器输出发送到控制台,请在启动后检查错误日志以查看 InnoDB
在启动过程中打印的初始化信息。
有关使用其他方法启动 MySQL 的信息,请参阅 第 2.9.5 节 “自动启动和停止 MySQL”。
InnoDB
不会在启动时打开所有用户表和关联的数据文件。但是,InnoDB
确实会检查数据字典中引用的表空间文件是否存在。如果未找到表空间文件,InnoDB
会记录错误并继续启动顺序。在崩溃恢复期间,可能会打开重做日志中引用的表空间文件以进行重做应用程序。
在继续进行启动配置之前,请查看以下与存储相关的注意事项。
在某些情况下,您可以通过将数据文件和日志文件放在单独的物理磁盘上来提高数据库性能。您还可以对
InnoDB
数据文件使用原始磁盘分区(原始设备),这可能会加快 I/O 速度。请参阅 对系统表空间使用原始磁盘分区。InnoDB
是一个事务安全(符合 ACID)的存储引擎,具有提交、回滚和崩溃恢复功能,可以保护用户数据。 但是,如果底层操作系统或硬件不能正常工作,它就无法做到这一点。 许多操作系统或磁盘子系统可能会延迟或重新排序写入操作以提高性能。 在某些操作系统上,fsync()
系统调用本应等到文件的所有未写入数据都被刷新,但实际上可能会在数据被刷新到稳定存储之前返回。 因此,操作系统崩溃或断电可能会破坏最近提交的数据,或者在最坏的情况下,甚至会因为写入操作被重新排序而损坏数据库。 如果数据完整性对您很重要,请在将任何内容用于生产环境之前执行 “拔掉插头” 测试。 在 macOS 上,InnoDB
使用特殊的fcntl()
文件刷新方法。 在 Linux 下,建议 禁用回写缓存。在 ATA/SATA 磁盘驱动器上,
hdparm -W0 /dev/hda
之类的命令可以用来禁用回写缓存。 请注意,某些驱动器或磁盘控制器可能无法禁用回写缓存。关于
InnoDB
保护用户数据的恢复功能,InnoDB
使用一种涉及称为 doublewrite 缓冲区 的结构的文件刷新技术,该技术默认启用(innodb_doublewrite=ON
)。 doublewrite 缓冲区提高了意外退出或断电后恢复的安全性,并通过减少对fsync()
操作的需求提高了大多数 Unix 系统上的性能。 如果您担心数据完整性或可能的故障,建议保持启用innodb_doublewrite
选项。 有关 doublewrite 缓冲区的更多信息,请参阅 第 17.11.1 节“InnoDB 磁盘 I/O”。在将 NFS 与
InnoDB
一起使用之前,请查看 在 MySQL 中使用 NFS 中概述的潜在问题。
innodb_data_file_path
选项定义 InnoDB
系统表空间数据文件的名称、大小和属性。 如果您在初始化 MySQL 服务器之前未配置此选项,则默认行为是创建一个名为 ibdata1
的自动扩展数据文件,该文件略大于 12MB。
mysql> SHOW VARIABLES LIKE 'innodb_data_file_path';
+-----------------------+------------------------+
| Variable_name | Value |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+
完整的数据文件规范语法包括文件名、文件大小、autoextend
属性和 max
属性。
file_name:file_size[:autoextend[:max:max_file_size]]
文件大小以千字节、兆字节或吉字节为单位指定,方法是在大小值后附加 K
、M
或 G
。 如果以千字节为单位指定数据文件大小,请以 1024 的倍数指定。 否则,千字节值将舍入到最接近的兆字节 (MB) 边界。 文件大小的总和必须至少略大于 12MB。
您可以使用分号分隔的列表指定多个数据文件。 例如:
[mysqld]
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
autoextend
和 max
属性只能用于最后指定的数据文件。
指定 autoextend
属性后,数据文件会在需要空间时自动以 64MB 的增量增加大小。 innodb_autoextend_increment
变量控制增量大小。
要为自动扩展数据文件指定最大大小,请在 autoextend
属性后使用 max
属性。 仅当限制磁盘使用量至关重要时,才使用 max
属性。 以下配置允许 ibdata1
增长到 500MB 的限制:
[mysqld]
innodb_data_file_path=ibdata1:12M:autoextend:max:500M
为 第一个 系统表空间数据文件强制执行最小文件大小,以确保有足够的空间用于 doublewrite 缓冲区页。 下表显示了每个 InnoDB
页面大小的最小文件大小。 默认的 InnoDB
页面大小为 16384(16KB)。
页面大小 (innodb_page_size) | 最小文件大小 |
---|---|
16384 (16KB) 或更小 | 3MB |
32768 (32KB) | 6MB |
65536 (64KB) | 12MB |
如果您的磁盘已满,您可以在另一个磁盘上添加数据文件。 有关说明,请参阅 调整系统表空间的大小。
单个文件的大小限制由您的操作系统决定。 在支持大文件的操作系统上,您可以将文件大小设置为大于 4GB。 您还可以使用原始磁盘分区作为数据文件。 请参阅 对系统表空间使用原始磁盘分区。
InnoDB
不知道文件系统的最大文件大小,因此在最大文件大小为 2GB 等小值的系统上要谨慎。
默认情况下,系统表空间文件在数据目录中创建(datadir
)。 要指定备用位置,请使用 innodb_data_home_dir
选项。 例如,要在名为 myibdata
的目录中创建系统表空间数据文件,请使用以下配置:
[mysqld]
innodb_data_home_dir = /myibdata/
innodb_data_file_path=ibdata1:50M:autoextend
为 innodb_data_home_dir
指定值时需要尾部斜杠。 InnoDB
不会创建目录,因此请确保在启动服务器之前指定目录存在。 此外,请确保 MySQL 服务器具有在目录中创建文件的适当访问权限。
InnoDB
通过将 innodb_data_home_dir
的值与数据文件名文本连接起来,形成每个数据文件的目录路径。 如果未定义 innodb_data_home_dir
,则默认值为 “./”,即数据目录。 (MySQL 服务器在开始执行时将其当前工作目录更改为数据目录。)
或者,您可以为系统表空间数据文件指定绝对路径。 以下配置与前面的配置等效:
[mysqld]
innodb_data_file_path=/myibdata/ibdata1:50M:autoextend
当您为 innodb_data_file_path
指定绝对路径时,该设置不会与 innodb_data_home_dir
设置连接。 系统表空间文件在指定的绝对路径中创建。 指定目录必须在您启动服务器之前存在。
InnoDB
doublewrite 缓冲区存储区域驻留在 doublewrite 文件中,这为 doublewrite 页的存储位置提供了灵活性。 在以前的版本中,doublewrite 缓冲区存储区域驻留在系统表空间中。 innodb_doublewrite_dir
变量定义 InnoDB
在启动时创建 doublewrite 文件的目录。 如果未指定目录,则会在 innodb_data_home_dir
目录中创建 doublewrite 文件,如果未指定,则默认为数据目录。
要在 innodb_data_home_dir
目录以外的位置创建 doublewrite 文件,请配置 innodb_doublewrite_dir
变量。 例如:
innodb_doublewrite_dir=/path/to/doublewrite_directory
其他 doublewrite 缓冲区变量允许定义 doublewrite 文件的数量、每个线程的页面数量以及 doublewrite 批处理大小。 有关 doublewrite 缓冲区配置的更多信息,请参阅 第 17.6.4 节“Doublewrite 缓冲区”。
重做日志文件占用的磁盘空间量由 innodb_redo_log_capacity
变量控制,该变量可以在启动时或运行时设置;例如,要在选项文件中将变量设置为 8GiB,请添加以下条目:
[mysqld]
innodb_redo_log_capacity = 8589934592
有关在运行时配置重做日志容量的信息,请参阅 配置重做日志容量。
innodb_redo_log_capacity
变量取代了已弃用的 innodb_log_file_size
和 innodb_log_files_in_group
变量。 定义 innodb_redo_log_capacity
设置后,将忽略 innodb_log_file_size
和 innodb_log_files_in_group
设置;否则,如果定义了这两个已弃用设置中的一个或两个,则它们将用于计算 Innodb_redo_log_capacity_resized
,计算公式为(innodb_log_files_in_group
* innodb_log_file_size
)。 如果未设置这些变量中的任何一个,则使用默认的 innodb_redo_log_capacity
值。
InnoDB
尝试维护 32 个重做日志文件,每个文件等于 1/32 * innodb_redo_log_capacity
。 重做日志文件位于数据目录中的 #innodb_redo
目录中,除非 innodb_log_group_home_dir
变量指定了不同的目录。 如果定义了 innodb_log_group_home_dir
,则重做日志文件位于该目录中的 #innodb_redo
目录中。 有关更多信息,请参阅 第 17.6.5 节“重做日志”。
您可以通过配置 innodb_log_files_in_group
和 innodb_log_file_size
变量,在初始化 MySQL 服务器实例时定义不同数量的重做日志文件和不同的重做日志文件大小。
innodb_log_files_in_group
定义日志组中的日志文件数。 默认值和建议值为 2。
innodb_log_file_size
定义日志组中每个日志文件的大小(以字节为单位)。 日志文件大小的总和(innodb_log_file_size
* innodb_log_files_in_group
)不能超过最大值,最大值略小于 512GB。 例如,一对 255 GB 的日志文件接近限制,但不会超过限制。 默认的日志文件大小为 48MB。 通常,日志文件的总大小应足够大,以便服务器能够平滑工作负载活动中的峰值和低谷,这通常意味着有足够的重做日志空间来处理一个多小时的写入活动。 日志文件大小越大,缓冲池中的检查点刷新活动就越少,从而减少了磁盘 I/O。 有关更多信息,请参阅 第 10.5.4 节“优化 InnoDB 重做日志记录”。
innodb_log_group_home_dir
定义 InnoDB
日志文件的目录路径。 您可以使用此选项将 InnoDB
重做日志文件放置在与 InnoDB
数据文件不同的物理存储位置,以避免潜在的 I/O 资源冲突;例如:
[mysqld]
innodb_log_group_home_dir = /dr3/iblogs
InnoDB
不会创建目录,因此请确保在启动服务器之前日志目录存在。 使用 Unix 或 DOS mkdir
命令创建任何必要的目录。
请确保 MySQL 服务器具有在日志目录中创建文件的适当访问权限。更一般地说,服务器必须在其需要创建文件的任何目录中都具有访问权限。
默认情况下,撤消日志驻留在初始化 MySQL 实例时创建的两个撤消表空间中。
innodb_undo_directory
变量定义了 InnoDB
创建默认撤消表空间的路径。如果未定义该变量,则会在数据目录中创建默认的撤消表空间。innodb_undo_directory
变量不是动态的。配置它需要重新启动服务器。
撤消日志的 I/O 模式使撤消表空间成为 SSD 存储的理想选择。
有关配置其他撤消表空间的信息,请参阅第 17.6.3.4 节“撤消表空间”。
全局临时表空间存储对用户创建的临时表所做的更改的回滚段。
默认情况下,innodb_data_home_dir
目录中有一个名为 ibtmp1
的自动扩展全局临时表空间数据文件。初始文件大小略大于 12MB。
innodb_temp_data_file_path
选项指定全局临时表空间数据文件的路径、文件名和文件大小。文件大小通过在大小值后附加 K、M 或 G 来指定,单位分别为 KB、MB 或 GB。文件大小或组合文件大小必须略大于 12MB。
要为全局临时表空间数据文件指定备用位置,请在启动时配置 innodb_temp_data_file_path
选项。
在 MySQL 8.4 中,InnoDB
始终用作内部临时表的磁盘存储引擎。
innodb_temp_tablespaces_dir
变量定义了 InnoDB
创建会话临时表空间的位置。默认位置是数据目录中的 #innodb_temp
目录。
要为会话临时表空间指定备用位置,请在启动时配置 innodb_temp_tablespaces_dir
变量。允许使用完全限定路径或相对于数据目录的路径。
innodb_page_size
选项指定 MySQL 实例中所有 InnoDB
表空间的页面大小。此值在创建实例时设置,之后保持不变。有效值为 64KB、32KB、16KB(默认值)、8KB 和 4KB。或者,您可以以字节为单位指定页面大小(65536、32768、16384、8192、4096)。
默认的 16KB 页面大小适用于各种工作负载,特别是涉及表扫描的查询和涉及批量更新的 DML 操作。对于涉及许多小型写入的 OLTP 工作负载,较小的页面大小可能更有效,因为当单个页面包含许多行时,争用可能成为一个问题。对于通常使用较小块大小的 SSD 存储设备,较小的页面也可能更有效。使 InnoDB
页面大小接近存储设备块大小可以最大程度地减少写入磁盘的未更改数据量。
innodb_page_size
只能在初始化数据目录时设置。有关此变量的更多信息,请参阅其描述。
MySQL 为各种缓存和缓冲区分配内存,以提高数据库操作的性能。为 InnoDB
分配内存时,请始终考虑操作系统所需的内存、分配给其他应用程序的内存以及分配给其他 MySQL 缓冲区和缓存的内存。例如,如果您使用 MyISAM
表,请考虑为键缓冲区分配的内存量 (key_buffer_size
)。有关 MySQL 缓冲区和缓存的概述,请参阅第 10.12.3.1 节“MySQL 如何使用内存”。
可以使用以下参数配置特定于 InnoDB
的缓冲区
innodb_buffer_pool_size
定义了缓冲池的大小,缓冲池是用于保存InnoDB
表、索引和其他辅助缓冲区的缓存数据的内存区域。缓冲池的大小对系统性能很重要,通常建议将innodb_buffer_pool_size
配置为系统内存的 50% 到 75%。默认的缓冲池大小为 128MB。有关其他指导,请参阅第 10.12.3.1 节“MySQL 如何使用内存”。有关如何配置InnoDB
缓冲池大小的信息,请参阅第 17.8.3.1 节“配置 InnoDB 缓冲池大小”。缓冲池大小可以在启动时或动态配置。在具有大量内存的系统上,您可以通过将缓冲池划分为多个缓冲池实例来提高并发性。缓冲池实例的数量由
innodb_buffer_pool_instances
选项控制。默认情况下,InnoDB
创建一个缓冲池实例。缓冲池实例的数量可以在启动时配置。有关更多信息,请参阅第 17.8.3.2 节“配置多个缓冲池实例”。innodb_log_buffer_size
定义了InnoDB
用于写入磁盘上的日志文件的缓冲区的大小。默认大小为 64MB。较大的日志缓冲区允许大型事务在事务提交之前无需将日志写入磁盘即可运行。如果您的事务更新、插入或删除了许多行,则可以考虑增加日志缓冲区的大小以节省磁盘 I/O。innodb_log_buffer_size
可以在启动时配置。有关信息,请参阅第 10.5.4 节“优化 InnoDB 重做日志记录”。
在 32 位 GNU/Linux x86 上,如果内存使用率设置过高,glibc
可能会允许进程堆增长超过线程堆栈,从而导致服务器故障。如果分配给 mysqld 进程用于全局和每个线程缓冲区和缓存的内存接近或超过 2GB,则存在风险。
可以使用类似于以下公式来计算 MySQL 的全局和每个线程内存分配,以估计 MySQL 内存使用量。您可能需要修改公式以考虑您的 MySQL 版本和配置中的缓冲区和缓存。有关 MySQL 缓冲区和缓存的概述,请参阅第 10.12.3.1 节“MySQL 如何使用内存”。
innodb_buffer_pool_size
+ key_buffer_size
+ max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size)
+ max_connections*2MB
每个线程使用一个堆栈(通常为 2MB,但在 Oracle Corporation 提供的 MySQL 二进制文件中仅为 256KB),并且在最坏情况下还使用 sort_buffer_size + read_buffer_size
的额外内存。
在 Linux 上,如果内核启用了大页面支持,则 InnoDB
可以使用大页面为其缓冲池分配内存。请参阅第 10.12.3.3 节“启用大页面支持”。