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

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

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



В целом, решение этих вопросов сводится к двум основным техническим задачам: автоматизация управления секциями в СУБД 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

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

Комментарии (9)


  1. GlukKazan
    21.12.2017 21:03
    +1

    Мы разработали набор скриптов
    А где скрипты?


    1. Sleuthhound
      21.12.2017 22:20

      Сдается мне их зажали.


    1. SolarSecurity Автор
      22.12.2017 22:01

      Да, скрипты целиком выложить не можем — это часть продукта, и они раскрывают схему хранения.
      Но мы готовы отвечать на вопросы, если вам интересно, как реализованы какие-то конкретные вещи. Кусками можем проиллюстрировать.


      1. GlukKazan
        23.12.2017 10:40

        Я вполне понимаю, что вы не можете выложить скрипты целиком (бывает, хотя, что там именно надо так скрывать, мне не очень понятно), но без них (и без вообще каких либо технических деталей) статья выглядит несколько пустовато. Во всяком случае, у меня, после прочтения вашей статьи, никаких вопросов не возникло (ну настроили партиционирование и настроили). В общем, не зацепила статья.


        1. SolarSecurity Автор
          23.12.2017 14:34

          Что ж, спасибо за отзыв, постараемся учесть на будущее.


  1. Hamaruba
    22.12.2017 22:02

    Хм, а как вообще админить без знаний и опыта работы с СУБД?
    И как же вы запихнули в скрипты изменение формата хранения данных? Если структура таблицы изменилась, то все исторические данные придется конвертировать под новый формат, а это по-любому ручная работа. Если только специфика вашей БД подразумевает однотипные изменения, которые можно формализовать. Или может быть этот вопрос был поднят, но решался в рамках вашей разработки?

    А что касается админки — Oracle 18c все сильно упростит.


    1. SolarSecurity Автор
      23.12.2017 14:05

      Вот ровно в этом вопросе и заключен весь смысл сделанного.

      Все изменения структуры таблиц мы “запихнули” в скрипты. Да, исторические данные при подключении конвертируются автоматически. Там возникают ошибки, верно, мы отлаживали эту систему 5-7 лет в общей сложности. Изменения были разные, простые и сложные. Упор был именно на то, что обычный администратор (не DBA!) при нашей поддержке, не обладая знаниями и умениями (ну, или обладая начальными), сможет проводить работу по управлению секциями. Мы очень часто, особенно на раннем этапе, входили в организации, где не было Oracle, и должны были работать в таких условиях. 

      Часть скриптов обеспечивает трансформацию данных из старых форматов (не только перестроение структуры таблиц, но и их логическое наполнение ), и еще часть пытается обеспечить надежное выполнение этих действий в отсутствие ораклового специалиста. Понятно, что эта цель выглядит крайне амбициозной, но система доказала свою жизнеспособность и работает. На поддержке у нас есть проблемы, связанные с отключением/подключением секций, но, как правило, они связаны со внешними причинами технического характера.


      1. Hamaruba
        23.12.2017 21:28

        овации!!!… :)


  1. ReakTiVe-007
    23.12.2017 10:29

    Скриптов не будет Нас всех надули, расходимся!