Как управлять секциями в БД Oracle и не сойти с ума

в 14:27, , рубрики: dlp, oracle, oracle database, Администрирование баз данных, Блог компании Solar Security, информационная безопасность, субд oracle, хранение данных

Мы уже рассказывали о том, почему секционирование баз данных очень важно для производительности DLP-системы и как мы реализовывали его в PostgreSQL. В этой статье речь пойдет об Oracle.

Специфика использования СУБД в DLP-решениях состоит в том, что объем данных прирастает очень быстро. Их невозможно держать в оперативном архиве, и долговременное хранение – это необходимость в компании численностью свыше хотя бы 50 человек. При этом оперативный архив наполняется так быстро, что отдавать информацию в долгосрочный архив приходится раз в 2 недели или чаще. Использование только встроенных средств СУБД требует знаний и опыта. Это главная сложность, и она, в общем-то, очевидна «на берегу».

Кроме того, возникают проблемы, не очевидные сразу. Как вернуть из долгосрочного архива партицию с данными более старой версии приложения и прицепить к более свежей? Что делать, если у них разных формат хранения данных? Что делать, если подключение секции было прервано, и она «зависла» между долговременным и оперативным архивом?

Как управлять секциями в БД Oracle и не сойти с ума - 1

В целом, решение этих вопросов сводится к двум основным техническим задачам: автоматизация управления секциями в СУБД Oracle (отключение и подключение) и система «отката» секций в случае, если при подключении что-то пошло не так.

Что не так со встроенными механизмами Oracle DB

Убирать данные на ленту и возвращать их из долговременного архива помогает опция Partitioning, с ее помощью можно разделить таблицу на части по какому-то принципу, например, по диапазону дат. Кроме управляемости и доступности, такое разделение еще позволяет повысить производительность. Каждый период хранится в отдельном табличном пространстве, что позволяет с помощью технологии transportable tablespace, достаточно быстро перемещать табличные пространства между различными отчетными и архивными БД с различными версиями и платформами. Но проблема в том, что стандартных механизмов не всегда достаточно: они позволяют только создавать базовые структуры без учета специфики приложения. А дальше администратор вынужден создавать вокруг них кучу инструментов управления. Да и сам процесс отключения-подключения-переноса требует навыков администрирования БД. Поэтому задача минимум – автоматизировать этот процесс, сделать его доступным для администраторов приложений.

Мы разработали набор скриптов, с помощью которых можно управлять секционированными таблицами, получать любую информацию о них и т.д. Не нужно знание команд, опыта работы с СУБД. Администратор приложения просто запускает скрипт или выбирает в интерфейсе нужное действие, указывает нужную партицию, и все происходит само собой.

(Не)совместимость версий

Итак, мы автоматизировали отключение секций и отправку их в долгосрочный архив. Но с долгосрочным архивом есть проблема: иногда его нужно вернуть.

Допустим, администратор перенес в него несколько секций в старой версии. Через год вышла новая версия, в которой добавились новые поля в таблицы, новые индексы, и в долгосрочный архив ушло еще некоторое количество секций. А потом безопасник расследует некий инцидент, и ему необходимо поднять данные двухлетней давности, т.е. поднять секцию несколько версий назад и каким-то образом подключить ее к БД.

Структура таблиц новой версии иногда отличается от исторической. Необходим ряд проверок и изменений для архивной секции. Проверка всегда начинается со сравнения текущей версии Solar Dozor и версии СУБД, и подключаемой партиции. Если есть различия, запускаются процедуры, корректирующие метаданные, добавляются необходимые поля, индексы, ключи, проверяется консистентность подключаемых данных, и пр., удаляется лишнее.

Дополнительные сложности приносит и использование для поиска в Solar Dozor текстовых индексов. Есть некоторые баги, связанные с EXCHANGE PARTITION для текстовых индексов, созданных в разных версиях СУБД или при использовании transportable tablespace (до 12 версии index metadata corruption). Патчи не всегда есть для нужной версии или платформы. Пересоздавать индексы при подключении – не быстрая и достаточно ресурсоемкая процедура. Пришлось «впилить» workaround-ы в процедуры подключения партиции. Структура DR$ таблиц текстовых индексов подключаемой партиции «выравнивается» с текущей, апдейтится поле таблицы ctxsys.dr$index.

Есть и защита от разных ошибок администраторов. Например, на уровне приложения запрещены любые действия с партицией, в которую в данный момент заливаются данные и имеющую статус «current».

«Хьюстон, у нас проблема»

В ходе реализации этих механизмов мы столкнулись с еще одной проблемой, неожиданно часто возникающей у заказчиков. В процессе отключения что-то может пойти не так, вплоть до банального отключения электричества, так что подключение секции может в любой момент прерваться. В результате получаем базу, которая находится в «промежуточном» состоянии.
В СУБД Oracle есть DDL и DML. В DML реализован механизм для обеспечения транзакционной целостности, который откатывает назад результаты, если транзакция не прошла. В DDL такого механизма нет, и любые действия с секцией – это путь в один конец.

Мы разработали механизм, который проверяет выполнение всех шагов по отключению-подключению партиции и корректирует возникающие проблемы. В случае возникновения проблем механизм перезапускает операции с партицией с того момента, когда что-то пошло не так. Ошибки при отключении-подключении логируются, и это позволяет в любой момент узнать, какие проблемы и когда возникали.

Как это работает для отключения партиции? Создается последовательность команд – отключаются внешние ключи, создается таблица, идентичная по структуре отключаемой партиции, для нее создаются необходимые индексы и primary key, команда exchange partition, включение внешних ключей. Каждая команда по мере выполнения логируется в служебную таблицу, для нее записывается операция отмены (disable constraint – enable constraint, create table –drop table и т.д.), время, когда была выполнена операция, статус операции. Если что-то пошло не так, после перезапуска процедуры выполняется проверка на каком шаге остановилось отключение, и либо выполняется следующая команда, либо происходит откат – записанные операции отмены выполняются в обратном порядке.

ID STATEMENT UNDO STATUS
4411 CREATE TABLE ADDRESS2_P10001 TABLESPACE DOZOR1_INDEXES AS SELECT * FROM ADDRESS2 WHERE 1 = 2 DROP TABLE ADDRESS2_P10001 OK
4412 CREATE  INDEX IX_ADDRESS2_MESSAGE_P10001 ON ADDRESS2_P10001 (MESSAGE) TABLESPACE DOZOR1_INDEXES NULL; OK
4413 CREATE UNIQUE INDEX IX_ADDRESS2_UNIQ2_P10001 ON ADDRESS2_P10001 (ADDR_TYPE, VALUE, MESSAGE) TABLESPACE DOZOR1_INDEXES NULL; OK
4414 ALTER TABLE ADDRESS2 EXCHANGE PARTITION p10001 WITH TABLE ADDRESS2_P10001 INCLUDING INDEXES WITHOUT VALIDATION ALTER TABLE ADDRESS2 EXCHANGE PARTITION p10001 WITH TABLE ADDRESS2_P10001 INCLUDING INDEXES WITHOUT VALIDATION OK

В результате получаем либо первоначальное состояние БД, либо успешное завершение процедуры отключения.

Автор: SolarSecurity

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js