Имеется скрипт. Выполняет довольно простую работу:
соединяется с базой данных (Informix, как водится), создаёт временную таблицу, заполняет её данными из других таблиц.
Потом запускает на эту таблицу SELECT COUNT(*)
, ну так, чисто для отчётности, и выводит это количество в лог.
Потом создаёт в таблице индекс для ускорения последующих операций и запускает UPDATE STATISTICS
, чтоб индекс заработал.
Затем удаляет из таблицы некоторые ненужные данные посредством DELETE
, опять запускает SELECT COUNT(*)
и… внезапно случается облом:
execute failed: SQL: -710: Table has been dropped, altered or renamed.
Сначала подумали, что в скрипте что-то не то. Но его не меняли уже больше года, а ошибка появилась лишь несколько месяцев назад, до этого всё нормально работало.
Потом появилась идея, что скрипт использует неуникальное имя таблицы, и какой-то другой процесс её случайно удаляет, приняв за свою. Но таблица-то временная, она из других сессий вообще не видна. Но на всякий случай попробовали переименовать. Фиг там, падает в том же месте.
Потом подумали, что может это на сервере регулярно проводятся какие-то работы как раз когда скрипт по крону запускается. Но нифига, он падает в одном и том же месте в любое время дня и ночи. Вот пока идёт первоначальный INSERT
, таблица есть, первый SELECT
— есть, DELETE
— всё ещё есть, а на следующем SELECT
‘е через пару секунд — уже нет. Мистика какая-то..
Чудес не бывает. Через пару недель исследований грабли были найдены. Они оказались очень красивыми. Естественно, я не смог мимо них пройти, не наступив. Попробуйте угадать, что это было.
Подсказка: скрипт использует перловый DBI. То есть, запросы сначала подготавливаются посредством prepare(), а потом уже выполняются вызовом execute(). Запрос про SELECT COUNT(*)
запускается несколько раз, после каждого изменения в таблице, но он всегда одинаковый, поэтому для него применяется prepare_cached(), это немножко ускоряет работу.
Оригинал этой записи в личном блоге.
Любые материалы из этого блога запрещается использовать на сайте livejournal.ru в любой форме и любом объёме.
no subject
А про загадку - я пас. С перлом и Informix не знаком.
no subject
no subject
это обычная ошибка
prepare
execute
меняем структуру таблицы
execute
исправляется
prepare
execute
unprepare
меняем структуру таблицы
prepare
execute
no subject
А главное - раньше-то оно работало, скрипт не менялся уже фиг знает сколько..
no subject
Если я ничего не путаю, то индекс создается с помощью ALTER TABLE... так что тут всё ясно.
Почему ломается? Да потому, что так задумано по дизайну. Чем отслеживать что там конкретно было altered он просто отказывается работать если что-то менялось. count(*) тоже не меняется от add column, но как-то это уже слишком сурово отслеживать подобные детали.
no subject
Задумано оно, может быть, и логично, но почему ж оно раньше работало, а потом перестало?
no subject
А почему работало - это другой вопрос. У меня нет на него ответа.