Странная архитектура
Через месяц после выхода на новое место руководство, предвидя очередную волну короновируса, нас разогнало по домам, обязав появляться в офисе по графику — один дома, второй в офисе и меняемся. Поэтому как выпал жребий я засел дома, снабженный корпоративной симкой и VPN.
Дома работать неудобно — монитор один, стол маленький, по комнате бродят жена и собака, выпрашивая ласку, внимание и еду, и если собака на место уходит послушно, то жена скалит зубы и рычит. Превозмогая трудности подключился к рабочему месту и стал разбирать почту.
Пришло письмо от второго сотрудника, находящегося в офисе, с текстом «Тут менеджер жалуется на deadlock, разберись». По тексту письма сразу понятно — чтобы я дома не скучал на меня сгрузили проблему, которую решать надо, но не сильно хочется. Скрин ошибки в письме был, но как это порой бывает из него можно было узнать название продукта, версию фреймворка, имя разработчика, дату рождения, его сексуальные предпочтения, имена родителей и положение солнца, когда собирался релиз. Ничего относящегося к делу там не было и мне пришлось пытать менеджера на предмет входных данных — что, когда и где. На удивление менеджер очень бодро рассказал, где лежит тестовая база с нужной таблицей и процедурой. Вооружившись студией, я начал изучать процедуру с таблицей, оказалось всё просто — из 50 входных параметров брался один, если такой был в базе — остальными 49 обновлялись имеющиеся данные, а если не был — просто дописывались. Просто и понятно. Из переписки выяснилось, что эти данные раз в n минут обновляются процедурой, но т.к. между обновлениями интервал невелик часто накладываются друг на друга, т.к. других желающих лезть в эту таблицу нет. Откладываю процедуру в сторону и лезу в таблицу. При изучении метаданных выпадает левый глаз от крайнего удивления — в базе нет ни одного индекса и порядка 20 тысяч записей, что гарантирует перебор всех данных в ней каждый запуск. Возвращаю глаз на место и согласовываю с менеджером создание уникального индекса на поле, которое проверяется в процедуре. Пытаюсь создать индекс и получаю ошибку создания из-за нарушения уникальности по полю, где должен быть порядковый номер сотрудника и по словам менеджера дубликатов там быть не должно. Ищу запросом совпадения номеров и теряю правый глаз — совпадений до 10 штук! Сразу вспомнился Гоголь Николай Васильевич, его матушка и «Мёртвые души». Против самого автора я ничего против не имел, читал всё с удовольствием, только «Мёртвые души», навязанные уроками литературы не пришлись ко двору, т.к. была непонятна первопричина, заставившая Чичикова мотаться по России. Это уже потом мне объяснили, что причина была в грядущем освобождении крестьян от крепостного права и похожа на схему с возвратом НДС через левую контору, но учительница литературы историю знала плохо и на мои вопросы невнятно мычала. Ну да бог с ним с Гоголем. Откуда взялись в таблице повторные записи о крестьянах… тьфу, сотрудниках? Пытаюсь выяснить у админов кто вообще это чудо писал, оказывается, что это было давно и неправда, описания таблиц нет, можно только догадываться, какое поле и за что отвечает. Ладно, поля name, surname, phone и подобные я пойму по названию и содержимому, а как быть с полями ID, PID, GID, SID? Где в varchar хранится целочисленные значения? Вообще все поля в таблице, кроме дат, имеют тип varchar (50) и varchar (100), удивительная согласованность.
Перехожу в общий чат и пытаюсь призвать коллективный разум на помощь. Самые старые сотрудники рассказывают, что это была интеграция сначала одной системы с другой, потом с другой, причем переписывать это особо никто и не пытался — работает же. Также никто не парился с индексами, ключами и прочим. Приплыли. Пытаюсь объяснить, что дубли выкосить можно, но сложно, индекс я создам, но наличие дублей попортит картину, ну и обновлять данные, размазанные по 10 строками не совсем правильно. Создаю индекс, пишу письмо менеджерам и пытаясь не использовать слова на «Х», «Б» и «Ж», дабы не сорваться и не написать лишнего, объясняю ситуацию, что индекс я создам, но надо проверить поможет или нет. Если не поможет — буду пытаться получить добро на чистку таблицы от «мертвых душ». Через 15 минут, потраченных на выпрашивание у жены капуччино и его последующее употребление получаю письмо, в котором менеджер радуется, что проблема сдвинулась с мертвой (опять это слово!) точки, рапортует, что на тестовом контуре всё «ок» и интересуется, когда я это перенесу на продуктив. Осторожно объясняю, что в таблице есть несостыковки с данными, нужно их приводить в порядок, и вообще может оказаться так, что то что работало на тестовом контуре на продуктиве покажет себя не так. И тут в голову приходит запоздалая мысль -, а что в продуктиве? При изучении рабочей базы я понимаю — вот тут то он и пришел, пушной зверь… 75 тысяч строк, из которых 15 тысяч дублей, от 2 до 10 копий одной строки… Что будет индекс, что не будет, ворочаться это будет очень долго. Ещё раз призываю коллективный разум, который высказывает те слова на «Х», «Б» и «Ж», которых я избегал и предлагает писать письмо руководителю — на благословление разгребать авгиевы конюшни. Менеджер присылает очередное письмо, в котором излагает желание пообщаться со мной по телефону. По телефону объясняю ситуацию, что в продуктиве данные сильно отличаются от тестовой базы и создание индекса на поле ID нам не сильно поможет, но можно попробовать, на что получаю изумительный ответ: конечно не поможет, я посмотрел процедуру и оказывается там используется поле PID! …Немая сцена. Оказывается продуктив отличался от тестовой площадки, причем сервисная шина передавала все данные в XML, а что ты будешь выбирать как первичный признак ты уже сам в процедуре базы прописывал. В какой-то момент процедуру поменяли, но кто, когда, зачем никто уже не знал. Наученый горьким опытом я проверил совпадения по этому полю, они нашлись и, о чудо, их было всего три. Причем, строки не отличались ничего, что естественно вызывало отдельные проблемы при их удалении, кто знает, что такое ACID и кто пытался удалить или изменить строки с полностью одинаковыми значениями во всех полях, поймут как это весело. В итоге данные были исправлены, индекс и первичный ключ созданы, менеджер отправлен контролировать процесс обмена данными и раньше следующей недели не писать мне, а я остался дальше думать о странной архитектуре системы обмена, которая работала годами, кривая и косая, без сбоев.