третьего дня приключилась неприятность, которую пришлось расхлёбывать допольно продолжительное время. после неудачного обновления форума smf (между версиями rc -< release в файлах произошли изменения, которые сделали напрочь нерапотоспособной тему), было решено откатить всё обратно. бекапы базы и файлов форума, естественно, имелись. но поджидающая засада сорвала все планы.
казалось бы, что может быть проще, нежели восстановить базу из резервной копии? но и тут поджидал подводный камень номер раз. через некоторое время после начала восстановления (база всего несколько сотен мегабайт, но даже на её обработку требуется ощутимое время), mysql поругался на дублирующие ключи. в принципе, неожиданностью это не стало, т. к. дамп создавался при работающем форуме и в процессе пользователи, естественно, форум активно пользовали. ключ -f вполне помог справиться с данной проблемой. и уже после успешной отработки процедуры развёртывания и копирования старых файлов форум вроде как заработал.
проработав пару минут, процесс апача увёл в даун сервер, употребив по максимуму оперативную память с процессорным временем. после перезагрузки всё вроде заработало, но ненадолго. не доставлял тот факт, что обновления страниц форума в браузере иногда приводило к отображению страницы, а иногда можно было безуспешно дожидаться загрузки. при этом начинала отъедаться оперативная память. попытка создать тему/написать ответ однозначно приводила к «зависанию браузера», что наводило на мысли о зацикливании.
пришлось включать вывод ошибок в браузер и отрабатывать их. но и тут яснее не стало: ошибки сыпались в нескольких файлах на разных строках. выполнение скрипта заканчивалось по достижению максимального времене выполнения или окончанию квоты оперативной памяти (что быстрее срабатывало). но среди ошибок таки проявилась одна закономерность: они все крутились возле работы с базой данных. сделал наугад вывод нескольких запросов, были получены несколько, натолкнувшие на мысль о причине происходящего.
т. к. в smf стояла запись ошибок в таблицу базы, запросы с записью ошибок содержали ошибки о невозможности записи. после этого естественно было проверить наличие автоинкрементов на таблицах. и каково же было удивление, когда ни в одной из таблиц AUTO_INCREMENT обнаружен не был.
причина зацикливания стала понятна: скрипт пытался добавить сообщение, но не мог этого сделать (из-за наличию дублирующих ключей). эта ошибка записывалась в таблицу ошибок, но операция снова отклонялась (опять дублирующие ключи), и уже генерировалась ошибка на эту ошибку. и длилась бы это вечно, если бы не лимиты. после восстановления автоинкрементов по базе из инсталляционного скрипта, форум заработал.
теперь осталось разобраться с базами, точнее, с тем моментом, почему же бекапы создаются, мягко говоря, не совсем рабочими. несколько проверенных резервных копий показали, что во всех отсутствует ключевое слово AUTO_INCREMENT. отсюда сам-собой напрашивался вывод: всё дело в mysqldump.
дело оказалось действительно в нём. по умолчанию дамп создавался в режиме совместимости с ansi, в котором полей с автоинкрементом просто нет (при этом, имена полей заключаются в обратные апострофы). чтобы всё-таки учесть данную несуразицу, в скрипте, занимающемся бекапом, для mysqldump`а пришлось явно это указать — за это отвечает опция —create-options, которая добавляет дополнительную информацию в оператор CREATE TABLE, в частности тот самый злополучный AUTO_INCREMENT.
днём интернета
шоколадкой для работы мозга
коробочкой ароматного чая для бодрости
продлением хостинга на +1 месяц