MySQL 8.0.33创建InnoDB表过慢问题排查(Ubuntu 22.04)
问题:InnoDB创建简单空表耗时0.6-1秒的原因分析
环境:空服务器(Ubuntu 22.04)、空数据库(MySQL 8.0.33),使用InnoDB引擎。创建仅3-4列的空表时,每次耗时0.6-1秒,附上SHOW PROFILE结果及建表语句,求原因。
SHOW PROFILE执行结果
mysql> show profile for query 1; +-------------------------------+----------+ | Status | Duration | +-------------------------------+----------+ | starting | 0.000181 | | Executing hook on transaction | 0.000181 | | starting | 0.000030 | | checking permissions | 0.000013 | | creating table | 0.733726 | | After create | 0.000674 | | waiting for handler commit | 0.000025 | | waiting for handler commit | 0.088327 | | query end | 0.000022 | | closing tables | 0.000008 | | waiting for handler commit | 0.000035 | | freeing items | 0.000037 | | cleaning up | 0.000047 | +----------------------+----------+ 14 rows in set, 1 warning (0.00 sec)
建表语句
CREATE TABLE IF NOT EXISTS tbl ( id smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT, type tinyint(3) UNSIGNED NOT NULL, limit int(10) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (id), KEY type (log_type) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
原因分析
从SHOW PROFILE的耗时分布来看,主要瓶颈集中在两个阶段:
creating table阶段(耗时0.73秒):InnoDB创建表时需要完成多步磁盘IO操作——生成专属表空间文件(.ibd)、将表结构元数据写入MySQL 8.0新增的InnoDB数据字典表、初始化主键索引的底层结构。如果服务器使用低速存储(比如机械硬盘)、磁盘IO队列存在阻塞,或者文件系统配置(如ext4的barrier特性)导致写入延迟,这个阶段的耗时会被显著拉长。waiting for handler commit阶段(最长一次耗时0.088秒):这是InnoDB事务提交时的等待环节,涉及redo log的刷盘操作、表结构变更的事务确认。如果innodb_flush_log_at_trx_commit保持默认值1,每次事务都需要等待redo log同步刷盘到磁盘,磁盘写入的延迟会直接反映在这个阶段的耗时上。
另外还有几个细节需要排查:
- 建表语句中存在字段名错误:索引
KEY type (log_type)引用了未定义的字段log_type,实际定义的字段是type,虽然MySQL会在执行时抛出错误,但如果这是实际执行的语句,可能额外增加了错误处理的开销(不过从profile看,主要耗时还是在表创建本身)。 - 服务器的磁盘调度策略、数据字典所在表空间的IO性能,也会间接影响表创建的速度——MySQL 8.0的数据字典是InnoDB表,创建新表时需要对数据字典表加锁并写入数据,若该表空间IO效率低,也会拖慢
creating table阶段。
内容的提问来源于stack exchange,提问作者IvanV
相关产品推荐
相关产品推荐

