Мда, иногда мелкая недоработка в глубоко вспомогательной функции может вызвать падение сайта целиком. Так было и сегодня с 4xpro.ru. Когда-то я добавил тег blocklink для вставки ссылок с автоматической догрузкой названия/описания/картинки через OpenGraph, чтобы ссылки выглядели блоком с предпросмотром, как в соцсетях. Какое-то время это работало, потом обратил внимание, что почему-то для некоторых ссылок данные не подгрузились. Решил, что заглючил вызов скрипта cron.php по crontab и отложил выяснение этого вопроса до лучших времён, поскольку это было не столь критично.
Но увы, вместо лучших времён настали худшие: сегодня упал сайт целиком с очень необычной ошибкой — переполнение MEMORY-таблицы ib_online со списком тех, кто сейчас на форуме. В норме эта таблица должна была регулярно очищаться, и такое переполнение возможно разве что при slashdot-эффекте.
Видя это дело, зашёл с консоли, запустил скрипт cron.php вручную и очень удивился результату: он выпал с ошибкой. Оказалось, что когда я делал blocklink, я в при разборе ответа сервера на наличие тега og:type неправильно сделал проверку на то, что он пуст: вместо if (!empty($og_type[0])) написал if (!empty($og_url[0])) (видимо, результат копирования похожего кода парой строк выше). А дальше следовал вызов $og_type[0]->getAttribute('content'), который и приводил к тому, что скрипт падал. Причём срабатывало это только в том случае, если в списке задач для обработки была ссылка на страницу, где og:url есть, а og:type — нет, поэтому поймать такое на этапе тестирования было сложно.
В итоге из-за этой ошибки и падения скрипта задачи по очистке устаревших данных просто не запускались, MySQL ел всё больше и больше памяти (и дочерние процессы иногда падали по OOM), производительность деградировала, но пока сайт не упал целиком, я даже не представлял, насколько всё серьёзно (да и в голову не пришло бы, что нужно "копать" blocklink).

- Перово, Москва, Россия
- me@4xpro.ru
- x4_pro
- XXXXPro
Новости сайта в Telegram
t.me/4x_proЛог жизни
Лог моей жизни, где я фиксирую наиболее эмоционально значимые для меня события и текущее настроение. Является продолжением блога, который я вел в ЖЖ с ноября 2004 по апрель 2018 года.
Как мелкий баг может привести к большому падению

Непростое обновление сертификата WebMoney

Несколько дней назад получил сообщение о том, что нужно обновить сертификат для WebMoney. Казалось бы, рутинная процедура, которая прежде выполнялась неоднократно. Но в этот раз все пошло иначе. Началось все с того, что под Firefox сертификат новый просто отказался генерироваться. Я написал в техподдержку, где мне посоветовали воспользоваться попробовать в версии 68. Только вот ставить под Linux старую версию — занятие не самое приятное, поэтому перезагрузился в Windows. Там, поразмыслив, решил пойти другим путем — использовать IE.
В первый момент показалось, что все хорошо, сертификат сгенерировался, но на этапе «инсталлируем сертификат» все встало. Я уже думал, что все, теперь придется делать полную процедуру восстановления доступа. Но сегодня решил попробовать еще раз, и обнаружил, что если выждать час, то можно создать запрос на генерацию сертификата еще раз. Правда, он закончился тем же самым. Я стал разбираться, почему это может быть. Сначала обнаружил, что у меня не установлен корневой сертификат WebMoney (видимо, я его устанавливал только на старом ноутбуке, а когда купил новый, перевыпуск делал уже только под Firefox). Потом корневой сертификат установил, но по умолчанию он встал не в то хранилище — в пользовательское вместо «Центров доверенной сертификации», которое нужно было указывать явно. Пришлось ждать еще час.
Но и тут все пошло не так, но уже по-другому: если раньше Windows просто не принимал сертификат, то теперь выдал какую-то невнятную ошибку с hex-кодом. Я сделал поиск по нему, и на одном из сайтов нашел совет: проверьте, правильно ли выставлено системное время. (Вообще, при любых проблемах с сертификатами, SSL/TLS и прочими околокриптографическими вещами время — это первое, что следует проверять.) Оказалось, что Windows при загрузке его переставил (сказалась разница, что Windows считает, что в CMOS лежит местное время, а Linux — что UTC), и сертификат не принимался из-за этого. После того, как я это исправил, сертификат наконец-то поставился.
Но и на этом злоключения не закончились. Я подключил внешний жесткий диск, чтобы сделать туда backup сертификата, но тут началось что-то странное. Windows просто предлагал его отформатировать, а Linux упорно монтировал в read-only. Попробовал было сделать fsck, но не помогло: выдавалась ошибка чтения. Пришлось выгружать все с диска на компьютер, переформатировать файловую систему, и загружать заново. Но процесс этот довольно небыстрый.
В общем, казалось бы, замена сертификата — тривиальное действие, но заняло чуть ли не полдня. И самое главное, что-то подобное происходит всегда, когда я хочу что-то сделать по плану! (В частности, сегодня хотел либо написать заметку про отношение к животному началу и «темную триаду маркетологов», либо в Дзен про то, почему в современном Интернете не жизнь, а выживание.)
Ну и ночь!

Сегодня потребовалось обновить один клиентский VDS. Там стоит очень-очень старый Debian, который давно уже перестал обновляться. Но рисковать, переходя на новый релиз, да еще и не на следующий, не хотелось. Стал искать, что делать, и наткнулся на описание трюка, как можно обмануть систему и поставить пакеты из следующих версий.
Увы, это оказалось не просто плохой идеей. Это оказалось ОЧЕНЬ ПЛОХОЙ идеей. Началось все с того, что старая версия dpkg не понимала команду activate-nowait в пост-установочных триггерах и отказывалась ставить такие пакеты. Но не зря же я называюсь Настоящим Компьютерщиком. После недолгого поиска я узнал, как переупаковать deb-файлы (да и вообще про то, как они устроены, и как их собирать), и стал вручную в них исправлять activate-nowait на просто activate. После замены в нескольких библиотеках и ручной установки из исправленной версии выяснилась новая неприятность: в новых deb пути к библиотекам указывались иначе: не просто /lib, а /lib/i386-linux-gnu. Обнаружил я это не сразу, и к этому времени несколько утилит уже не работало. Пришлось немного почудить с symlinks, но в итоге все исправил почти со всем, кроме самой последней из установленных таким образом библиотек, про которую просто забыл.
Я уже собирался было идти спать, набрал exit и перешел из root-режима под обычного пользователя, как вдруг пришла в голову мысль проверить, работает ли ssh. И оказалось, что нет! Более того, отказал не только он, но еще и команда su, и одновременно обнаружилось, что на клиентских сайтах тоже все не работает.
Главное, сообрази я это минут на пять раньше, до того момента, как вышел из rootа, я бы исправил это элементарно. А теперь было непонятно что делать. Где-то час я лихорадочно пытался придумать различные обходные пути (например, запустить sshd под обычным пользователем на другом порту), но увы, все было бесполезно. Оставалось только написать в техподдержку хостинга в надежде, что там помогут, и лечь спать.
Заснуть так и не удалось. В голову лезли мысли о том, что backup на хостинге отключился из-за превышения квоты, а свой собственный у меня довольно-таки старый, и неизвестно, чем все это кончится. Около 7 утра я встал снова, проверил ответ от техподдержки, и о счастье: вопрос решили! Поставили Dropbear — более простой ssh-сервер, почти ни от каких библиотек не зависящий, и я снова смог подключиться к серверу и решить остальные вопросы.
В общем, узнал много нового (к счастью, не о себе), но ценой кучи нервов и бессонной ночи.