Windows 上的 MariaDB - InnoDB 在表转换为 MyISAM 时挂起

Windows 上的 MariaDB - InnoDB 在表转换为 MyISAM 时挂起

这篇文章有点奇怪(而且很长,抱歉),我正在与一位在 Windows(Server 2008 R2)上运行 MariaDB 的客户合作。他们有几个大型 MyISAM 表(每个表高达 30 GB,2 亿多行),出于多种原因,我将它们转换为 InnoDB。大多数表转换得很好,但其中少数表完全锁定了 InnoDB 引擎。当我说完全锁定时,我的意思是进度百分比停止增加,mysqld 的所有 CPU/磁盘活动都停止,并且大多数与 InnoDB 相关的任务都停止工作。甚至运行“SHOW ENGINE InnoDB STATUS”也会挂起。我让它静置了一天,它仍然保持在相同的百分比。

需要注意以下几点:

  • 它在 ESXi VM 中运行并且是其生产 VM 的克隆,因此绝对没有流量(单独的硬件,没有客户端连接)。
  • 该虚拟机有 8 个 CPU 核心和 16 GB RAM,两者都没有受到任何压力。
  • 我尝试禁用查询缓存,结果没有变化
  • 如前所述,转换过程将在第 1 阶段(复制到 tmp 表)的中间某处挂起,百分比将停止增加。此时,mysqld 不再有 CPU 或磁盘活动。
  • 挂起时没有任何记录,只有之前有关长信号量等待的消息。
  • 我们正在运行 innodb_file_per_table。
  • 凭直觉,我确认临时的 .ibd 文件没有变得太碎片化,在上次转换尝试中它有 99 个碎片。
  • 并非所有表都发生这种情况,也并非只发生在最大的表上。我有一个 7 GB 的表(有 100m 行)失败,而一个 30 GB 的表(有 200m 行)成功。
  • 它总是在桌子上的同一个地方失败。
  • 所有表都已完成完整的 MyISAM 检查/修复
  • Windows 系统日志中未记录任何错误
  • 我们正在运行最新的 10.2 分支(稳定版)。我考虑升级到 10.3,但我在发行说明中没有看到任何与之相关的内容。
  • 检查 procexp,mysqld 中有两个活动线程,均显示 ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a。两个堆栈的屏幕截图如下。
  • 检查 procmon,mysqld.exe 中绝对没有任何活动。
  • 当它挂起时,可以查询 MyISAM 表,但任何 InnoDB 查询都会挂起。
  • 我确实找到了此主题并设置 innodb_adaptive_hash_index=0 但没有任何区别。
  • 系统的其他方面都运行良好(尽管它只是一个 SQL 服务器),并且已经重新启动过几次。
  • 有些人可能注意到我已经关闭了 doublewrite,这仅用于测试并且将在生产中被禁用。

一些截图: 流程统计 线程堆栈 1 线程堆栈2

日志中可能重要的数据摘录:(重复多次)

InnoDB:######启动 InnoDB Monitor 30 秒以打印诊断信息:
InnoDB:待处理读取 0,写入 0

=====================================
2017-12-28 15:54:44 0x3c8 INNODB 监视器输出
=====================================
从过去 17 秒计算出的每秒平均值
-----------------
背景线程
-----------------
srv_master_thread 循环:1788 srv_active、0 srv_shutdown、67 srv_idle
srv_master_thread 日志刷新并写入:1854
----------
信号量
----------
OS WAIT ARRAY INFO:预留计数 59085
--线程 3892 已在 ibuf0ibuf.cc 行 3460 等待信号量 247.00 秒:
在文件 buf0buf.cc 第 1471 行中,在 00000000975EFC68 处的 RW 闩锁上创建了 S 锁
一个编写器(线程 ID 3800)已将其保留为独占模式
读者数量 0,等待者标志 1,lock_word:0
上次读取锁定在文件 ibuf0ibuf.cc 第 3460 行
上次写入锁定在文件 mtr0mtr.ic 第 147 行
--线程 2944 已在 ibuf0ibuf.cc 行 4578 等待信号量 247.00 秒:
在文件 buf0buf.cc 第 1471 行中,在 00000000975EFC68 处的 RW 闩锁上创建了 S 锁
一个编写器(线程 ID 3800)已将其保留为独占模式
读者数量 0,等待者标志 1,lock_word:0
上次读取锁定在文件 ibuf0ibuf.cc 第 3460 行
上次写入锁定在文件 mtr0mtr.ic 第 147 行
--线程 3700 已在 buf0flu.cc 行 1246 等待信号量 246.00 秒:
在文件 buf0buf.cc 第 1471 行中,在 00000000975EFC68 处的 RW 闩锁上创建了 SX 锁
一个编写器(线程 ID 3800)已将其保留为独占模式
读者数量 0,等待者标志 1,lock_word:0
上次读取锁定在文件 ibuf0ibuf.cc 第 3460 行
上次写入锁定在文件 mtr0mtr.ic 第 147 行
--线程 3800 已在 buf0buf.cc 行 4136 等待信号量 247.00 秒:
在文件 buf0buf.cc 第 1471 行中,在 000000018299B078 处的 RW 闩锁上创建了 S 锁
一个写入器(线程 ID 0)已将其保留为独占模式
读者数量 0,等待者标志 1,lock_word:0
上次读取锁定文件尚未保留第 0 行
上次写入锁定在文件 buf0buf.cc 第 5363 行
--线程 2564 已在 ibuf0ibuf.cc 行 4578 等待信号量 247.00 秒:
在文件 buf0buf.cc 第 1471 行中,在 00000000975EFC68 处的 RW 闩锁上创建了 S 锁
一个编写器(线程 ID 3800)已将其保留为独占模式
读者数量 0,等待者标志 1,lock_word:0
上次读取锁定在文件 ibuf0ibuf.cc 第 3460 行
上次写入锁定在文件 mtr0mtr.ic 第 147 行
--线程 3484 已在 ibuf0ibuf.cc 行 4578 等待信号量 247.00 秒:
在文件 buf0buf.cc 第 1471 行中,在 00000000975EFC68 处的 RW 闩锁上创建了 S 锁
一个编写器(线程 ID 3800)已将其保留为独占模式
读者数量 0,等待者标志 1,lock_word:0
上次读取锁定在文件 ibuf0ibuf.cc 第 3460 行
上次写入锁定在文件 mtr0mtr.ic 第 147 行
--线程 3200 已在 ibuf0ibuf.cc 行 2720 等待信号量 246.00 秒:
互斥锁位于 00000001406064F8,互斥锁 IBUF 创建 ibuf0ibuf.cc:516,锁定变量 2

OS 等待数组信息:信号计数 46563
RW 共享旋转 0,轮数 53529,操作系统等待 24403
RW-excl 旋转 0,轮次 480664,OS 等待 7825
RW-sx 旋转 2641 次,循环 24044 次,操作系统等待 184 次
每次等待的旋转轮数:53529.00 RW-共享,480664.00 RW-排除,9.10 RW-sx
------------
交易
------------
Trx ID 计数器 94794
清除 trx 的 n:o < 94152 已完成,撤消 n:o < 0 状态:正在运行但空闲
历史列表长度 0
每次交易的清单:
---TRANSACTION 281476765058824,未开始
0 个锁结构、堆大小 1136、0 个行锁
---交易 94793,活动 247 秒插入
mysql 表正在使用 1,锁定 1
1 个锁结构、堆大小 1136、0 个行锁、撤消日志条目 1930
MySQL 线程 ID 8、OS 线程句柄 3892、查询 ID 1 ::1 根复制到 tmp 表
改变表 dbname.table_being_converted 引擎=innodb
--------
文件输入/输出
--------
I/O 线程 0 状态:完成 buf 页的 io(插入缓冲区线程)
I/O 线程 1 状态:完成 buf 页的 io(日志线程)
I/O 线程 2 状态:完成 buf 页的 io(读线程)
I/O 线程 3 状态:完成 buf 页的 io(读线程)
I/O 线程 4 状态:本机 aio 句柄(读取线程)
I/O 线程 5 状态:本机 aio 句柄(读取线程)
I/O 线程 6 状态:本机 aio 句柄(写线程)
I/O 线程 7 状态:本机 aio 句柄(写线程)
I/O 线程 8 状态:本机 aio 句柄(写线程)
I/O 线程 9 状态:本机 aio 句柄(写线程)
待处理的正常 aio 读取:[0, 0, 2, 4] ,aio 写入:[0, 0, 0, 0],
 ibuf aio 读取:,记录 i/o:,同步 i/o:
待处理刷新 (fsync) 日志:0;缓冲池:0
108072 次 OS 文件读取、2437337 次 OS 文件写入、23912 次 OS fsync
0.00 读取/秒、0 平均字节/读取、0.00 写入/秒、0.00 fsyncs/秒
-------------------------------------
插入缓冲区和自适应哈希索引
-------------------------------------
InnoDB:###### 诊断信息打印到标准错误流
2017-12-28 15:55:09 3240 [警告] InnoDB:长时间信号量等待:
--线程 3892 已在 ibuf0ibuf.cc 行 3460 等待信号量 272.00 秒:
在文件 buf0buf.cc 第 1471 行中,在 00000000975EFC68 处的 RW 闩锁上创建了 S 锁
一个编写器(线程 ID 3800)已将其保留为独占模式
读者数量 0,等待者标志 1,lock_word:0
上次读取锁定在文件 ibuf0ibuf.cc 第 3460 行
上次写入锁定在文件 mtr0mtr.ic 第 147 行
(剪辑,上面的数据重复了很多次)

my.ini 内容:

[mysqld]
datadir=D:/SQLData
端口=3306
默认存储引擎=InnoDB
innodb_buffer_pool_size=4096M
innodb_log_file_size=256M
innodb_doublewrite = 0
表 1. innodb_file_per_table
innodb_force_recovery=1

最大连接数=500
查询缓存大小=4096M
跳过名称解析
慢查询日志
日志错误=Errors.log

myisam_sort_buffer_size=768M
临时表大小=768M
密钥缓冲区大小=2048M
读取缓冲区大小=5M
排序缓冲区大小=32M

相关内容