concurrent_insert=2 表示无论MyISAM表是否存在删除空洞,均允许在表尾并发插入;需在my.cnf中[mysqld]段配置concurrent_insert=2或运行时执行SET GLOBAL concurrent_insert=2,并确认表为MyISAM、插入语句简单且未启用binary log限制。

concurrent_insert 是 MyISAM 存储引擎控制并发插入行为的核心系统变量,它不需“开启”动作,而是通过配置值生效。默认值为 1(即 AUTO 模式),已启用基础并发插入能力;若要强制启用更宽松的并发插入(包括有删除空洞的表),需显式设为 2。
concurrent_insert=2 怎么配才真正生效
- 修改必须在 MySQL 服务启动前写入配置文件,或运行时动态设置(但部分场景下需重启才完全生效)
- 配置位置:MySQL 配置文件(如
/etc/my.cnf或my.ini)的[mysqld]段落内 - 正确写法(MySQL 5.7+ 推荐用无
set-variable前缀形式):
[mysqld] concurrent_insert = 2
-
若使用旧版配置语法(如 MySQL 5.6 及更早),可能需写成:
set-variable = concurrent_insert=2
运行时临时设置(仅当前会话/实例有效,重启丢失):
SET GLOBAL concurrent_insert = 2;验证是否生效:
SELECT @@concurrent_insert;—— 返回2即表示已应用
⚠️ 注意:该变量对 InnoDB 表完全无效;只作用于 MyISAM 表,且仅影响
INSERT追加到数据文件末尾的行为,不改变锁粒度或事务语义。
为什么设成 2 后有时还是没并发效果
- 表必须是 MyISAM 类型:
SHOW CREATE TABLE table_name;确认引擎不是InnoDB或MEMORY -
INSERT必须是简单插入(无子查询、非INSERT ... SELECT);一旦涉及SELECT,即使表是 MyISAM,也会退化为普通写锁(binary log 开启时尤其如此) - 不支持
DELAYED(MySQL 5.6+ 已移除该语法),别再依赖INSERT DELAYED - 如果表上有
FULLTEXT索引,MyISAM 会禁用并发插入(即使concurrent_insert=2) - 使用
LOAD DATA INFILE时,需额外指定CONCURRENT关键字才能触发并发读取,否则仍会锁表:
LOAD DATA CONCURRENT INFILE '/path/to/data.txt' INTO TABLE t1;
concurrent_insert=2 带来的实际代价
- 数据文件碎片加剧:删除行留下的“洞”不会被新插入数据复用,所有新行都追加到末尾
-
OPTIMIZE TABLE成为必需维护操作,但执行时会锁全表,影响线上读写 - 并发插入的可见性延迟:其他连接执行
SELECT可能暂时看不到刚插入的数据(MyISAM 不保证 MVCC,依赖文件系统刷新时机) - 无法与
INSERT ... ON DUPLICATE KEY UPDATE共存(该语法在 MyISAM 中不支持,会报错)
真正需要高并发写入的场景,MyISAM + concurrent_insert=2 只是权宜之计。如果业务允许,迁移到 InnoDB 并合理设计主键/索引,比调这个变量更能解决根本问题。


















