Неверный ключевой файл MySQL для таблицы tmp при создании нескольких соединений

Я не часто прихожу сюда за помощью, но я очень расстроен этим, и я надеюсь, что кто-то столкнулся с ним раньше.

Всякий раз, когда я пытаюсь извлечь записи из таблицы, используя более одного соединения, я получаю эту ошибку:

#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it

Таким образом, этот запрос приведет к ошибке:

SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1

Но этого не будет:

SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1

И не будет и этого:

SELECT * FROM `core_username`
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1

Что может быть причиной этого? Я действительно не знаю, как сделать ремонт tmp-таблицы, но я действительно не думаю, что проблема в том, что это новая таблица tmp каждый раз. Таблица имени пользователя довольно большая (233 718 записей прямо сейчас), но я сомневаюсь, что это имеет к этому какое-то отношение.

Любая помощь будет высоко оценена.

UPDATE. После некоторого дополнительного тестирования, кажется, что ошибка возникает только при попытке упорядочить результаты. То есть, этот запрос даст мне то, что я ожидаю:

SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
LIMIT 1

Но если я добавлю:

ORDER BY `core_username`.`name` ASC

Ошибка инициируется. Это происходит только на конкретном веб-сервере, который я использую в настоящее время. Если я загружу базу данных и попробую то же самое на своем локальном хосте, а также на других серверах, он работает нормально. Версия MySQL 5.0.77.

Зная это, я довольно уверен, что происходит то, что создаваемая таблица tmp слишком велика, и MySQL дросселирует как описано в этом сообщении в блоге. Я все еще не уверен, каким будет решение, хотя...

Ответ 1

Иногда, когда эта ошибка происходит со временными таблицами:

#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it

Это может быть из-за нехватки места в папке /tmp. На некоторых установках Linux /tmp находится в своем собственном разделе и не имеет большого пространства - большие запросы MySQL будут заполнять его.

Вы можете использовать df -h, чтобы проверить, находится ли \tmp в своем собственном разделе и сколько места ему выделено.

Если он находится в своем собственном разделе и не хватает места, вы можете:

(a) modify/tmp, чтобы его палитра имела больше места (либо путем перераспределения, либо перемещения его в основной раздел - например см. здесь)
 (б) изменение конфигурации MySql, чтобы он использовал другую папку temp на другом разделе, например. /var/tmp

Ответ 2

Проверьте доступное пространство MySQL tmpdir (/tmp в вашем случае) во время выполнения запросов, поскольку он может есть сотни МБ при работе с большими таблицами. Что-то вроде этого сработало для меня:

$ while true; do df -h /tmp; sleep .5; done

Ответ 3

запустите это

REPAIR TABLE `core_username`,`core_site`,`core_person`;

или выполните следующее:

select * from (
 SELECT * FROM `core_username`
 INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
 INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
 LIMIT 1)
ORDER BY `name` ASC

Ответ 4

Вы можете найти, что работает "ANALYZE TABLE".

Мы столкнулись с этой проблемой, которая внезапно появилась на большой таблице (~ 100M строк), и MySQL попыталась использовать /tmp для записи временной таблицы размером более 1 ГБ, которая не удалась, поскольку /tmp был ограничен ~ 600M.

Оказалось, что статистика таблицы InnoDB была довольно устаревшей. После запуска "ANALYZE TABLE..." статистика была обновлена, и проблема была устранена. С более точной статистикой MySQL смог оптимизировать запрос правильно, и большой файл tmp больше не требуется.

Теперь мы запускаем "mysqlcheck -Aa", чтобы сохранить всю статистику таблицы.

Ответ 5

У меня была эта проблема с запросом в таблице с 500K + записями. Это давало мне тот же самый точный тип ошибки, указывающий на файл .MYI в каталоге /tmp, который редко присутствовал при проверке. Я уже увеличил размеры файлов кучи и временных файлов в файле /etc/my.cnf.

Проблема с запросом заключалась в том, что он действительно содержал предложение ORDER в конце, опустив его, он запустил запрос без ошибок. У него также был LIMIT. Я пытался посмотреть последние 5 записей в таблице. С включением предложения ORDER он задохнулся и дал ошибку.

Что происходит, mysqld создавал внутреннюю временную таблицу со всеми записями из гигантской таблицы, чтобы применить ORDER.

Способ, которым я обходился, - применить дополнительное условие WHERE, ограничив записи с гигантской таблицы на какой-то меньший набор. Мне удобно иметь поле datetime для фильтрации.

Я надеюсь, что это поможет кому-то.

Ответ 6

В Unix MySQL использует значение переменной среды TMPDIR как путь к каталогу, в котором хранятся временные файлы. Если TMPDIR не установлен, MySQL использует системный по умолчанию, который обычно равен /tmp,/var/tmp или/usr/tmp.

В Windows, Netware и OS2 MySQL проверяет значения переменных среды TMPDIR, TEMP и TMP. Для первого найденного набора MySQL использует его и не проверяет оставшиеся. Если ни один из TMPDIR, TEMP или TMP не установлен, MySQL использует системный стандарт Windows, который обычно является C:\windows\temp.

Если файловая система, содержащая ваш временный каталог файлов, слишком мала, , вы можете использовать опцию -tmpdir для mysqld, чтобы указать каталог в файловой системе, где у вас достаточно места.

В MySQL 5.0 параметр -tmpdir может быть установлен в список из нескольких путей, которые используются в циклическом режиме. Пути должны быть разделены символами двоеточия ( ":" ) на символах Unix и с запятой ( ";" ) в Windows, NetWare и OS/2.

Ответ 7

У меня такая же проблема.

Вот мое решение: 1. Не используйте "select *". Просто выберите поле, которое вам нужно. 2. Разделите запрос. Если выбранное вами поле слишком велико, результатом может быть разделение на какой-то запрос. Вы можете "array_merge()" результат позже, если вы хотите, чтобы переменная, содержащая результат, не была изменена.

В моем случае я разбил запрос на 5 запросов, затем массив объединил его с помощью PHP.

Проблема лежит на сервере mysql. Это просто то, что разработчик приложений (такой, как я, я) не имеет преувеличения.

Ответ 8

У меня была аналогичная проблема. В моем случае проблема возникла из-за неправильного владельца/разрешения. Мне просто пришлось сменить владельца в моем каталоге данных на пользователя mysql, и это решило проблему.

Ответ 9

Увеличьте только файл tmp, потому что mysql не имеет места в нем, для запросов...

mount -o remount,size=[NEW MAX SIZE HERE] tmpfs /tmp

Ссылка ссылки:

Общая ошибка: 126 Неверный файл ключа для таблицы '/tmp/#sql_254c_0.MYI; попробуйте отремонтировать его

[ERROR]/usr/sbin/mysqld: неверный файл ключа для таблицы '/mysqltmp/#sql_ca1a_0.MYI'; попробуйте отремонтировать его

Как увеличить размер раздела tmp

Ответ 10

индексные ключи для одной из трех таблиц могут быть плохими, попробуйте запустить команду восстановления на всех трех таблицах.

Ответ 11

Использование ключевого слова EXPLAIN может помочь выяснить, как наилучшим образом оптимизировать этот запрос. По сути, вам нужно как можно быстрее установить набор результатов как можно меньше. Если у вас есть набор результатов из каждой строки в имени core_username до конца, когда вы его заказываете, вы рискуете... этим.

Если вы можете сделать заказ только по имени core_username без проблем, вы можете захотеть получить строку min() в качестве подзапроса.