关于 InnoDB
配置的第一个决定涉及数据文件、日志文件、页面大小和内存缓冲区的配置,这些配置应该在初始化 InnoDB
之前进行。修改配置可能涉及非平凡的过程。
本节提供了在配置文件中指定 InnoDB
设置、查看 InnoDB
初始化信息以及重要的存储考虑的信息。
因为 MySQL 使用数据文件、日志文件和页面大小设置来初始化 InnoDB
,因此建议您在 MySQL 选项文件中定义这些设置,以便在启动时读取这些设置。通常,InnoDB
在 MySQL 服务器第一次启动时初始化。
您可以将 InnoDB
选项放在 [mysqld]
组中,任何 MySQL 服务器在启动时读取的选项文件中。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.3\bin
,请启动 MySQL 服务器,如下所示:
C:\> "C:\Program Files\MySQL\MySQL Server 8.3\bin\mysqld" --console
在 Unix-like 系统上,mysqld 位于 MySQL 安装的 bin
目录中:
$> bin/mysqld --user=mysql &
如果您不将服务器输出发送到控制台,请在启动后检查错误日志,以查看初始化过程中打印的InnoDB
信息。
有关使用其他方法启动 MySQL 的信息,请参阅 第 2.9.5 节,“自动启动和停止 MySQL”。
InnoDB
不会在启动时打开所有用户表和关联的数据文件。然而,InnoDB
会检查数据字典中引用的表空间文件的存在性。如果找不到表空间文件,InnoDB
将记录错误并继续启动序列。在崩溃恢复期间,可能会打开 redo 日志中引用的表空间文件以应用 redo。
在继续配置启动之前,请查看以下存储相关注意事项。
-
在某些情况下,您可以通过将数据和日志文件放在单独的物理磁盘上来提高数据库性能。您还可以使用原始磁盘分区(原始设备)作为
InnoDB
数据文件,这可能会加速 I/O。请参阅 使用原始磁盘分区 для系统表空间。 -
InnoDB
是一个事务安全(ACID 兼容)的存储引擎,具有提交、回滚和崩溃恢复功能,以保护用户数据。然而,它不能这样做,如果底层操作系统或硬件不按承诺工作。许多操作系统或磁盘子系统可能会延迟或重新排序写操作以提高性能。在某些操作系统上,fsync()
系统调用可能会在写操作被刷新到稳定存储之前返回。在这种情况下,操作系统崩溃或断电可能会破坏最近提交的数据,或者在最坏的情况下,甚至会损坏数据库,因为写操作被重新排序。如果数据完整性对您很重要,请在生产环境中进行 “拔插” 测试。在 macOS 上,InnoDB
使用特殊的fcntl()
文件刷新方法。在 Linux 上,建议 禁用写回缓存。在 ATA/SATA 磁盘驱动器上,命令
hdparm -W0 /dev/hda
可能会禁用写回缓存。请注意,一些驱动器或磁盘控制器可能无法禁用写回缓存。 -
关于
InnoDB
恢复功能保护用户数据,InnoDB
使用了一种称为 双写缓冲区 的文件刷新技术,默认情况下启用 (innodb_doublewrite=ON
)。双写缓冲区添加了恢复后的安全性,并在大多数 Unix 变体上提高了性能,因为它减少了fsync()
操作的需要。如果您关心数据完整性或可能的故障,请保持innodb_doublewrite
选项启用状态。有关双写缓冲区的信息,请参阅 第 17.11.1 节,“InnoDB 磁盘 I/O”。 -
在使用 NFS 与
InnoDB
之前,请查看 使用 NFS 与 MySQL 中概述的潜在问题。
选项 innodb_data_file_path
定义了 InnoDB
系统表空间数据文件的名称、大小和属性。如果您在初始化 MySQL 服务器之前没有配置该选项,默认行为是创建一个 slightly larger than 12MB 的自动扩展数据文件,名为 ibdata1
:
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
变量控制增量大小。
要指定自动扩展数据文件的最大大小,请使用 max
属性,紧跟在 autoextend
属性后。仅在磁盘使用情况非常重要时使用 max
属性。以下配置允许 ibdata1
增长到500MB的限制:
[mysqld]
innodb_data_file_path=ibdata1:12M:autoextend:max:500M
为了确保有足够的空间用于双写缓冲页面,第一个系统表空间数据文件的最小文件大小是强制执行的。以下表格显示了每个 InnoDB
页大小的最小文件大小。默认的 InnoDB
页大小是16384(16KB)。
Page Size (innodb_page_size) | Minimum File 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_dir
变量定义了 InnoDB 在启动时创建双写文件的目录。如果没有指定目录,双写文件将在 innodb_data_home_dir
目录中创建,该目录默认为数据目录,如果未指定。
要在其他位置创建双写文件,而不是在 innodb_data_home_dir
目录中,需要配置 innodb_doublewrite_dir
变量。例如:
innodb_doublewrite_dir=/path/to/doublewrite_directory
其他双写缓冲变量允许定义双写文件的数量、每个线程的页面数和双写批量大小。有关双写缓冲配置的更多信息,请参阅 第 17.6.4 节,“双写缓冲”。
重做日志文件占用的磁盘空间由 innodb_redo_log_capacity
变量控制,该变量可以在启动或运行时设置;例如,要将变量设置为 8GB 在选项文件中,添加以下条目:
[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
设置 (innodb_log_files_in_group
* innodb_log_file_size
= innodb_redo_log_capacity
)。如果没有设置这些变量,innodb_redo_log_capacity
将设置为默认值,即 104857600 字节(100MB)。最大设置为 128GB。
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 节,“重做日志”。
您可以在初始化 MySQL 服务器实例时定义不同的重做日志文件数量和重做日志文件大小,方法是配置 innodb_log_files_in_group
和 innodb_log_file_size
变量。
innodb_log_files_in_group
定义了日志组中的日志文件数量。默认值和推荐值为 2。
innodb_log_file_size
定义了日志组中的每个日志文件的大小(以字节为单位)。组合日志文件大小(innodb_log_file_size
* innodb_log_files_in_group
)不能超过最大值,稍小于 512GB。例如,两个 255GB 的日志文件接近限制但不超过限制。默认日志文件大小为 48MB。通常,组合日志文件大小应该足够大,以便服务器可以平滑工作负载的峰值和低谷,这意味着有足够的 redo 日志空间来处理超过一小时的写活动。较大的日志文件大小意味着缓冲池中的检查点刷新活动减少,从而减少磁盘 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 节,“撤销表空间”。
全局临时表空间存储用户创建的临时表的回滚段。
单个自动扩展的全局临时表空间数据文件名为 ibtmp1
,默认情况下位于 innodb_data_home_dir
目录中。初始文件大小略大于 12MB。
选项 innodb_temp_data_file_path
指定了全局临时表空间数据文件的路径、文件名和文件大小。文件大小以 KB、MB 或 GB 为单位,通过追加 K、M 或 G 到大小值来指定。
要指定全局临时表空间数据文件的备用位置,请在启动时配置 innodb_temp_data_file_path
选项。
在 MySQL 8.3 中,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 用于将日志写入磁盘的缓冲区的大小。默认大小为 16MB。大型日志缓冲区使大型事务可以在提交之前不写入磁盘日志。如果您有更新、插入或删除许多行的事务,可能需要增加日志缓冲区的大小以减少磁盘 I/O。innodb_log_buffer_size
可以在启动时配置。有关相关信息,请参阅 第 10.5.4 节,“优化 InnoDB 重做日志”。
在 32 位 GNU/Linux x86 上,如果内存使用量设置太高,glibc
可能允许进程堆栈增长超过线程栈,从而导致服务器失败。如果为 mysqld 进程分配的全局和每线程缓冲区和缓存的内存接近或超过 2GB,这是一个风险。
可以使用类似以下公式来估算 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 节,“启用大页支持”。