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 записей), но я сомневаюсь, что это как-то связано с ней.
Любая помощь приветствуется.
ОБНОВЛЕНИЕ: После некоторого дальнейшего тестирования, кажется, что ошибка происходит, только когда я пытаюсь упорядочить результаты. То есть этот запрос даст мне то, что я ожидаю:
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 задыхается, как описано в этом сообщении в блоге. Я все еще не уверен, каким будет решение, хотя...
11 ответов
Иногда, когда эта ошибка происходит с временными таблицами:
#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it
Это может быть потому, что /tmp
в папке не хватает места. На некоторых установках Linux, /tmp
находится в своем собственном разделе и не имеет много места - большие запросы MySQL заполнят его.
Ты можешь использовать df -h
проверить, \tmp
находится в своем собственном разделе, и сколько места выделено для него.
Если он находится в своем собственном разделе и не хватает места, вы можете:
(a) измените /tmp так, чтобы его раздел имел больше места (перераспределяя или перемещая его в основной раздел - например, см. здесь)
(б) изменение конфигурации MySql так, чтобы он использовал другую временную папку в другом разделе, например /var/tmp
Проверяйте доступное пространство MySQL tmpdir (в вашем случае /tmp) во время выполнения запросов, так как оно может потреблять сотни МБ при работе с большими таблицами. Как-то так у меня сработало
$ while true; do df -h /tmp; sleep .5; done
Запустить это
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
Вы можете найти подсказки "ANALYZE TABLE ".
Эта проблема внезапно возникла в большой таблице (~100M строк), и MySQL пытался использовать /tmp для записи временной таблицы размером более 1 ГБ, что не удалось, так как /tmp был ограничен ~600M.
Оказалось, что статистика для таблицы InnoDB была довольно устаревшей. После запуска "ANALYZE TABLE ..." статистика была обновлена и проблема устранена. Благодаря более точной статистике MySQL смог правильно оптимизировать запрос, и большой файл tmp больше не требовался.
Теперь мы периодически запускаем mysqlcheck -Aa, чтобы сохранить всю статистику таблицы свежей.
У меня была эта проблема с запросом к таблице с 500K+ записями. Он выдавал мне точно такой же тип ошибки, указывая на файл.MYI в каталоге /tmp, который редко появлялся при проверке. Я уже увеличил размеры кучи и временного файла в файле /etc/my.cnf.
Проблема с запросом заключалась в том, что он действительно содержал предложение ORDER в конце, опуская его, чтобы запрос работал без ошибок. Это также имело предел. Я пытался посмотреть на последние 5 записей в таблице. С включенным предложением ORDER он задохнулся и дал ошибку.
Происходило то, что mysqld создавал внутреннюю временную таблицу со ВСЕМИ записями из гигантской таблицы, чтобы применить ORDER.
Способ, который я обошел, заключается в применении дополнительного условия WHERE, ограничивающего записи из гигантской таблицы каким-то меньшим набором. У меня было удобное поле datetime для фильтрации.
Я надеюсь, что это помогает кому-то.
В 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.
Только увеличивайте файл tmp, потому что в mysql нет места для запросов...
mount -o remount,size=[NEW MAX SIZE HERE] tmpfs /tmp
Ссылки ссылки:
Общая ошибка: 126 Неверный ключевой файл для таблицы '/tmp/#sql_254c_0.MYI'; попробуй починить
[ОШИБКА] / usr / sbin / mysqld: неверный ключевой файл для таблицы '/mysqltmp/#sql_ca1a_0.MYI'; попробуй починить
Я испытываю ту же проблему.
Вот мое решение: 1. Не используйте "select *". Просто выберите поле, которое вам нужно. 2. Разделите запрос. Если выбранное вами поле слишком много, результатом может быть разбиение его на какой-либо запрос. Вы можете "array_merge()" результат позже, если вы хотите, чтобы переменная, содержащая результат, не изменялась.
В моем случае я разделил запрос на 5 запросов, затем слил массив, используя PHP.
Проблема заключается в сервере MySQL. Просто у разработчика приложений (такого как я) нет преимуществ.
У меня была похожая проблема. В моем собственном случае проблема возникла из-за неправильного владельца / разрешения. Мне просто пришлось сменить владельца в моем каталоге данных на пользователя mysql, и это решило проблему.
Ключи индекса для одной из трех таблиц могут быть неправильными, попробуйте выполнить команду восстановления для всех трех таблиц.
Использование ключевого слова EXPLAIN может помочь выяснить, как лучше оптимизировать этот запрос. По сути, вам нужно как можно быстрее получить набор результатов как можно меньше. Если у вас есть результирующий набор каждой строки в core_username до конца, при заказе вы рискуете... этим.
Если вы можете без проблем выполнить упорядочивание только для core_username, вы можете получить строку min() в качестве подзапроса.