33

我有一些优化 my.cnf 文件的经验,但我的数据库有大约 400 万条记录 (MyISAM)。我正在尝试从 mysqldump 恢复,但每次我最终都会得到可怕的“使用 Keycache 修复”,这可能需要几天时间。有什么办法可以解决这个问题并让它滚动为“通过排序修复”?

我有 2GB RAM、双核、大量额外的硬盘空间。

从 my.cnf 中剪掉:

set-variable = max_connections=650
set-variable = key_buffer=256M
set-variable = myisam_sort_buffer_size=64M
set-variable = join_buffer=1M
set-variable = record_buffer=1M
set-variable = sort_buffer_size=2M
set-variable = read_buffer_size=2M
set-variable = query_cache_size=32M
set-variable = table_cache=1024
set-variable = thread_cache_size=256
set-variable = wait_timeout=7200
set-variable = connect_timeout=10
set-variable = max_allowed_packet=16M
set-variable = max_connect_errors=10
set-variable = thread_concurrency=8
4

6 回答 6

36

“通过排序修复”使用文件排序例程,该例程反过来(通常)在您的 tmpdir 中创建几个临时文件。

如果您的 tmpdir 没有足够的空间供它们使用,它将恢复为“通过 keycache 修复”。这非常糟糕,因为它速度慢得多并且创建的索引不太理想。

还有一些其他情况,但我没有确定它们。

计算出 filesort() 所需的 tmpdir 的大小并非易事;存储在文件排序缓冲区中的格式数据与 MYD 文件不同,它通常使用更多空间。

因此,如果您的 tmpdir 指向较小的 /tmp(或 tmpfs),您可能希望将其更改为较大的 /var/tmp - 如果存在的话。

于 2009-07-01T06:10:59.073 回答
19

每当表索引的最大可能大小大于变量 myisam_max_sort_file_size 的值时,MySQL 将对 MyISAM 表使用 keycache 修复。

您可以通过将所有索引中所有键的字节大小值相加并将其乘以表中的行数来计算索引的最大大小。

增加 myisam_max_sort_file_size 并且您的索引将使用磁盘上的排序来重建,而不是使用慢速 keycache 方法。

于 2010-12-23T11:44:57.547 回答
10

我不小心在一个我没有设置为快速注册的新数据库上快速运行了一个修复表。myisam_max_sort_file_size 与 .MID 文件(88279393280 字节大,约 88GB)相比太小了。数据文件为85GB。该表有 12 亿条记录,由一个 ID、两个日期、一个 tinytext、几个 bigint 和一个 double 组成。我的服务器(在 windows7 下的一个盒子中运行 2GB 虚拟 linux)在 windows 服务器上只有一个 4 核心,但它运行 3+ GHZ。我担心这个“通过 keycache 修复”事件会持续很长时间——因为恐怖故事的桌子要小得多。

好在它“只”用了 1 天 10 小时 20.72 秒就完成了修复表的快速操作。

我最想念的是某种方式来了解 mysql 的操作有多远,以及它可能在多长时间内完成。这对我来说仍然是未知的。

我现在已经更改了 my.ini 文件,并使用 df 仔细检查了这些大型临时文件是否有足够的磁盘空间。

无论如何..我的主要观点,对于下一个落入这个陷阱的人来说可能是非常有用的知识..事实上......不要惊慌!它可能很慢,但在相当低于标准的硬件上,在一两天内整理出超过十亿条记录是可能的。得到三个索引,一个在日期字段上,一个在 bigint 字段上,一个在 ID 字段上。

我会将此作为对其中一个解决方案的评论发布,但我似乎无法弄清楚如何使用此处的用户界面执行此操作,因此我将其作为解决方案放弃。不要投票给我,这只是一个我很想在这里拥有的便条,我几乎要杀死我的“按 keycache 排序”线程,因为我认为这可能需要一周或更长时间。每十亿条记录有 2 天是可控的。

编辑:现在,同一数据库上的修复表,但具有足够大的 mysiam_max_sort_file_size 设置需要 10 小时 20 分钟,使用通过排序修复。使用的最大磁盘空间约为 250GB,但我将 myisam_max_sort_file_size 设置得更高,这反映了服务器上实际可用的磁盘空间。

跟踪进度很困难。磁盘空间在构建单个索引时上升和下降,但是有一个小时的停顿,没有对 reg 进行任何更改。磁盘空间使用情况(由 df 报告)。

于 2012-11-24T23:58:41.627 回答
5

谢谢马克,是的,这正是我最终尝试的,并且从日志中看到,这就是它切换到“使用 keycache 修复”的原因,是空间不足错误。

这就是我为解决问题所做的工作,因为我不会经历它指向的事实,它/tmp/mysqltmp/最大只有 2MB。

所以我这样做了:

mkdir /home/mysqltmp

chown mysql:mysql /home/mysqltmp

将 my.conf 中的 tmp 目录更改为 tmpdir=/home/mysqltmp/

现在,如果我使用df -h /home/mysqltmp,我看到的是 dir 有 285 GB 可用,所以这真的是一个很好的景象,有足够的可用空间,而且我可以很容易地看到 mysql 想要 20GB。因此,现在 12 小时前花费我的时间在 20 分钟内完成,即超过 300 万条记录插入到索引中。

于 2009-07-01T07:05:30.103 回答
1

这里没有一个解决方案对我有用:无论我增加了多少myisam_sort_buffer_size变量或变量指向哪里tmpdir,表总是用 keycache 修复。

有效的是使用命令行实用程序myisamchk

myisamchk --sort-recover --sort_buffer_size=14G /path/to/table

在哪里:

  • /path/to/table是没有扩展名的数据库文件的路径(因此,没有.MYI结尾)。它默认位于目录中/var/lib/mysql/your_database

  • 将缓冲区大小更改为14G您拥有的任何可用空间。

作为额外的奖励,它还显示了搅动数据时的持续进度。

于 2017-12-05T02:37:58.673 回答
0

根据 MySQL 参考手册,磁盘空间必须“在包含原始索引文件所在目录的文件系统中”可用(http://dev.mysql.com/doc/refman/5.5/en/server-system -variables.html#sysvar_myisam_max_sort_file_size)——这适用于(至少)v5.0 及更高版本。这与上述一些答案相矛盾,声称增加 tmp 目录的磁盘空间会有所帮助。

我可以确认参考手册中描述的行为:临时磁盘空间用于存储表的数据 ( *.MYD) 和索引文件 ( *.MYI) 的位置,但不在tmpdir.

于 2013-12-08T11:49:32.837 回答