如何使用Keycache避免修复?

时间:2009-07-01 05:11:06

标签: mysql mysqldump

我有一些优化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

6 个答案:

答案 0 :(得分:34)

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

如果您的tmpdir没有足够的空间,它将恢复为“通过密钥缓存修复”。这是非常糟糕的,因为它慢得多并且创建的索引不太理想。

还有一些其他条件,但我没有发现它们。

计算filesort()所需的tmpdir大小并不重要;格式数据存储在filesort缓冲区中与MYD文件不同,它通常会占用更多空间。

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

答案 1 :(得分:16)

只要表索引的最大可能大小大于变量myisam_max_sort_file_size的值,MySQL就会使用keycache对MyISAM表进行修复。

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

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

答案 2 :(得分:9)

我意外地在新数据库上快速运行了一个修复表,我没有将其设置为快速注册。 myisam_max_sort_file_size与.MID文件(大小为88279393280,大约88GB)相比太小了。数据文件是85GB。该表是12亿条记录,包括ID,两个日期,一个小文本,一些bigints和一个double。我的服务器(运行在windows7下的一个盒子里的2GB虚拟linux)在Windows服务器上只有4个核心,但运行3+ GHZ。我担心这个"通过keycache修复"事件将永远持续下去 - 鉴于恐怖故事的篇幅要小得多。

幸运的是,它只是"花了1天,10小时和20.72秒完成修复台的快速操作。

我最想念的是了解mysql的操作有多远,以及它可以在多长时间内完成。我仍然不知道这一点。

我现在已经更改了my.ini文件,并使用df进行了双重检查,表明我有足够的磁盘空间用于那些大型临时文件。

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

我会将此作为对其中一个解决方案的评论发布,但我似乎无法通过此处的用户界面来了解如何执行此操作,因此我将其删除作为解决方案。不要赞美我,这只是我喜欢在这里的一张纸条,我几乎要杀死我的"按键盘排序"因为我认为它可能需要一周或更长时间。每十亿条记录2天是可以管理的。

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

跟踪进度很难。在构建各个索引的同时,磁盘空间上下变化,但是有一小时的暂停,没有进行任何更改。磁盘空间使用情况(由df报告)。

答案 3 :(得分:5)

谢谢Mark,是的,这正是我最终尝试的,并且从日志中看到,这就是它切换到“使用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万条记录插入索引。

答案 4 :(得分: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

答案 5 :(得分:0)

这里没有任何解决方案适用于我:无论我增加了多少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更改为您拥有的任何可用空间。

作为一个额外的好处,它还会在搅拌数据时显示正在进行的进展。