【问题标题】:How To Avoid Repair With Keycache?如何避免使用 Keycache 进行修复?
【发布时间】:2009-07-01 05:11:05
【问题描述】:

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

我有 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

【问题讨论】:

  • 你应该接受 MarkR 的回答。
  • Marc Gear 的答案应该是被接受的,因为磁盘空间通常不是问题,而myisam_max_sort_file_size 设置为低值更有可能发生

标签: mysql mysqldump


【解决方案1】:

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

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

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

【讨论】:

  • 我正在使用 RHEL5 w/ MySQL w/my.cnf 的细微调整,导入一个 db 需要 15 小时,将相同的 db 导入 CentOS5(在具有不同 my.cnf 的更新机器上)需要大约 1.5 小时,我要试试你的 myisam_max_sort_file_size,因为现在它设置为 2G,我的桌子是 5G,我确实有足够的空间......我迫不及待想试试!
  • 我刚刚在 my.cnf 中将 myisam_max_sort_file_size 设置为 8G,但我仍然看到“Repair with keycache”我的“tmpdir”指向 /tmp 文件夹,其中有大约 90G 可用空间,我没有真的看到mysqld在使用它......有什么想法吗?我检查了权限,一切正常。
  • 你的表有多少行?和索引它有(超过什么大小的行)。要重建 4 Gb 表,我需要将其设置为大约 15gb(它没有使用这么多)
  • 似乎如果你有一列是 utf8 类型,那么 mysql 假定每个字符占用 4 个字节而不是 1。所以,即使你的表是 1GiB,而你有 1对于那种类型的列,MySQL 可能实际上认为它需要保留 4 GiB 而不是 1 GiB,这对我来说听起来有点浪费。
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 最重要的条件 - myisam_max_sort_file_size 变量。我有足够的可用磁盘空间,但始终运行“通过 keycache 修复”,并且只有将 myisam_max_sort_file_size 设置为 10G 时,才能获得“按排序修复”,这比“通过 keycache 修复”快四到五倍.感谢@Marc-Gear
  • 将 tmpdir 切换到不同的分区对我有用。从 2.5 天到 2.5 小时在大型表(约 8 亿行)上创建索引。
【解决方案3】:

我不小心在一个我没有设置为快速注册的新数据库上快速运行了一个修复表。 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 报告)。

【讨论】:

  • 我有 40 亿行的表,一个月后它不会被 keycache 修复。这是不可能的。这取决于索引的数量和复杂程度;即使使用 keycache,只有一个主键的大表也会很快构建,但如果您有 7 个多列索引,则不会。
【解决方案4】:

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

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

【讨论】:

    【解决方案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 万条。

    【讨论】:

    • 一件事不要忘记在更改 my.conf 后重新启动 mysql,这就是我在 Apache RedHat 中重新启动 mysql 的方式:service mysqld restart
    • 这应该是对您问题的更新,而不是答案。
    【解决方案6】:

    根据 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 中。

    【讨论】:

      猜你喜欢
      • 2011-06-28
      • 1970-01-01
      • 2016-10-11
      • 1970-01-01
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多