Начало работы. Первые трудностиДля работы с EBR мы установили несколько патчей от Oracle. Патч с исправлением некоторых ошибок нам пришлось ждать очень долго, из-за этого часть задач мы не успели сделать в срок.
Также, в процессе внедрения EBR, мы
поменяли джобы установки патчей в Jenkins
(Если вам интересно как работают процессы CI/CD в нашем банковском проекте - пишите в комментарии, я расскажу отдельно), чтобы установка автоматически происходила с созданием редакций EBR.
Самой главной нашей задачей было подготовить саму базу для внедрения, так как для корректной работы EBR существуют определенные требования к объектам и к процессу разработки:
- запрещено изменять объекты в родительских редакциях, для которых нет актуализированных версий в дочерних. В этом случае необходимо вначале актуализировать объект в дочерней редакции, которая является непосредственным потомком текущей;
- перед тем как выдать грант на объект, его нужно актуализировать в текущей редакции. Если пакет нельзя перекомпилировать (в случае, если выполняем выдачу грантов вручную на горячей базе), то для выдачи гранта необходимо определить редакцию, в которой объект был последний раз актуализирован, после чего дать ему грант в этой редакции. Для этого мы создали специальную функцию;
- для компиляции большого числа невалидов нам пришлось написать функцию валидации объектов, которая работает только с конкретной редакцией. Старую функцию, которая делала это в параллели, мы перестали использовать, так как она компилировала объекты во всех редакциях. Во время разработки на dev-среде необходимо запускать функцию валидации, если пакет используют связанные объекты;
- при непосредственной разработке на базе необходимо запускать процедуру валидации объектов (см. выше) после актуализации пакетов, на которые могут ссылаться другие пакеты, иначе это может привести к их развалу через некоторое время;
- неверсионируемые объекты не могут ссылаться на версионируемые, поэтому функциональные индексы для таблиц необходимо создавать, используя функции в специальных noneditionable пакетах;
- editionable abstract data type (ADT) не могут быть evolved (таким образом, типы в editioned схемах необходимо редактировать через drop/create);
- Все новые объекты PL/SQL при разработке обязательно должны создаваться как Editionable.
Также, по-хорошему, при использовании EBR, для каждой таблицы должно создаваться Editionable View, которое будет использоваться в объектах PL/SQL, так как таблица – это всегда Noneditionable объект, и, если этого не сделать, то в некоторых редакциях объекты будут ссылаться на несуществующие столбцы.
Расскажу на довольно распространенном в сети примере:
Предположим, у нас есть таблица TPERSON, в которой есть поле FULL_NAME, где хранятся ФИО клиентов. Но появилась задача разделить фамилию, имя и отчество на разные столбцы SONAME, NAME и MIDDLE_NAME. Если мы добавим данные столбцы, то пакеты в предыдущих редакциях станут невалидными. Для того, чтобы этого не происходило, необходимо, чтобы пакеты не обращались напрямую к таблице, а обращались к представлению VPERSON. Например, для старых редакций представление будет содержать следующий код:
Create or replace view VPERSON asSelect full_name, birthday, ... from TPERSON;А для новых редакций:
Create or replace view VPERSON asSelect name, soname, middle_name, birthday, ... from TPERSON;В дальнейшем мы помечаем столбец
FULL_NAME как
UNUSED. И этот столбец может быть удален при техническом обслуживании системы, когда мы уже точно будем знать, что откат на редакции, которые его используют, не будет произведен.
Следующей проблемой стало то, что в нашей системе много кода, и большую его часть написал вендор. И на предложение переделать все таблицы на Editionable view нам выкатили счет, сравнимый с ВВП небольшого города, и срок в пять лет. Такой вариант нас не устроил, поэтому изменения, требующие модификации таблиц, мы продолжаем производить с Downtime, как раньше. Благо, такие изменения производятся нечасто.
В итоге, на EDITIONABLE VIEW в старом коде мы решили не переходить, но некоторые преобразования все же сделать пришлось:
- мы вынесли все функции, используемые в функциональных индексах, в отдельный noneditionable пакет и перестроили индексы;
- написали новые правила разработки и обучили разработчиков;
- позаимствовали и доработали функции выдачи грантов, валидации объектов, проверки редакций и логирования у помогавшей нам с переводом системы команды;
- определили, какие объекты должны быть noneditionable, а какие нет. Noneditionable, например, были типы, которые отвечают за взаимодействие с другими системами;
- пересоздали публичные синонимы, такие как editionable. Если этого не сделать, то синоним может инвалидироваться. Попытка его перекомпилить ничего не дает, а если попытаться удалить в редакции, то он обозначится как non-existance, и пересоздать его не получится. Это одна из проблем, возникшая на тестовых контурах, и решить ее получается только удалением из корневой редакции ORA$BASE
Еще одна проблема, с которой мы столкнулись, – у нас есть интеграция с другими системами, которые сохраняют стабильное соединение долго и не переключаются на новые редакции. Их нужно было «насильно» вырубать, что означало необходимость Downtime для них. Пусть это и был Downtime, длящийся секунды, но иногда мы не могли себе позволить и этого. Было решено в дальнейшем избавиться от этого легаси и перенастроить взаимодействие.
Мы продолжили тестировать и исследовать. Сделали множество деплоев, проверяли как это будет работать. Заметили дополнительно следующие моменты:
- для того, чтобы PL/SQL developer начал открывать пакеты из новой редакции по умолчанию, его необходимо перезапустить. Если этого не делать, то новые окна открываются в старой редакции;
- объекты могут развалиться, если существуют несоответствия временных меток компиляции связанных объектов. Для обнаружения этих проблем мы сделали специальное представление VTIMESTAMP_MISMATCHES, которое сравнивает timestamp у связанных объектов и выводит их в случае несоответствия. Проблемные объекты, найденные с помощью данного представления, подлежат компиляции (для пакетов необходимо актуализировать и тело, и спецификацию в одной и той же редакции) и последующей валидации с помощью написанной процедуры
ЗапускСпустя 6 месяцев работы мы поняли, что готовы запустить и установить первый патч на продуктив с использованием EBR. И вот оно чудо. Все прошло гладко! Гладко на первый взгляд… Уже на следующий день мы словили ошибку - в какой-то момент пакеты развалились. В дальнейшем мы отловили еще море ошибок, по некоторым писали в службу поддержки Oracle, а некоторые задачки системы обеспечили бессонные ночи всей команде. Список ошибок, их описание и методы решения, которые мы нашли, смотрите в таблице ниже.
Описанные выше в статье проблемы я не стал включать в таблицу, так как с ними все уже более-менее ясно. К сожалению, мы не сразу начали вести реестр ошибок EBR, и, если вы знаете другие ошибки или способы решения, которые сработали бы лучше, - пишите в комментарии.