Вход в личный кабинет:

Забыли пароль? | Регистрация

Адреса компании:

Санкт-Петербург

196158, Санкт-Петербург,
Пулковское шоссе, д. 30,
корп. 4, Лит. А, офис 203

Тел: +7 812 414 95 41

Москва

129085, г. Москва, проезд Ольминского, д. 3а, стр. 3, офис 706

Тел: +7 495 616 00 53

Блог

26.08.2015

Progress OpenEdge: промышленные средства репликации данных в Oracle и MS-SQL

Progress OpenEdge Pro2 Replication

Читать далее →




Десять причин перехода на новые версии OpenEdge (Progress)


Кто удалил запись из таблицы?

Вернуться к списку постов

23.12.2010

Если в вашей системе не используется OpenEdge Auditing, а само приложение не создает никаких собственных журналов аудита, как в такой ситуации можно узнать, кто и когда удалил конкретную запись из таблицы? В этом помогут архивы AI-экстентов, конечно же, если в этой базе данных работает механизм After-Imaging. Методика поиска «виноватого» описана далее на примере базы данных sports.

Скопируйте базу sports из каталога $DLC. Включите механизмы After-Imaging и AI File Management. Запустите базу данных. Сформируйте резервную копию базы sports в online и представьте, что это резервная копия промышленной базы, сделанная накануне вечером. Как всё это сделать, здесь я описывать не буду, т.к. об этом много рассказывалось в различных моих статьях и книгах.

Итак, чтобы найти требуемую информацию необходимо:

  • иметь доступ к архивам AI-экстентов, созданных в промежутке времени, во время которого мы предполагаем, что произошло удаление;

  • знать имя таблицы, из которой была удалена запись;

  • знать имя области хранения, в которой находится таблица;

  • знать RECID удаленной записи или номер блока, в котором она хранилась.

Для начала нужно удалить какую-нибудь запись из базы. В качестве «жертвы» возьмем запись с номером 54 из таблицы Family.

Подключитесь к базе sports в режиме редактора:

mpro sports

Выполните следующий ABL-код:

find last family where empnum = 54 exclusive-lock.
delete family.

Отключитесь от базы данных и дождитесь, когда сформируется очередной архив AI-экстента. Время формирования зависит от того, какой интервал архивирования AI-экстентов был выставлен для механизма AI File Management. А пока определим, какой RECID был у этой записи.

Восстановите базу данных sports в отдельный каталог из ранее созданной резервной копии:

prorest ./db1/sports ./backup/sports.bkp

Подключитесь к восстановленной базе в режиме редактора и выполните следующий ABL-код:

find last family where empnum = 54 no-lock.
displ recid(family).

Результатом работы этой программы будет значение RECID, выведенное на экран монитора. Оно будет равно 510.

Теперь нужно узнать, в какой области хранения находится эта таблица. Это можно сделать либо с помощью команды PROUTIL TABANALYS, либо с помощью Data Dictionary.

PROUTIL TABANALYS:

Выполните команду:

proutil sports –C tabanalys > tabanalys.txt

Откройте созданный файл tabanalys.txt и найдите в нем информацию о таблице Family. Пример для базы sports:

RECORD BLOCK SUMMARY FOR AREA "Employee" : 7
                             -Record Size(B)- --Fragments-- Scatter
Table          Records    Size Min Max Mean    Count Factor  Factor
PUB.Benefits        21  848.0B  39  41   40       21    1.0     1.0
PUB.Department       7  211.0B  26  35   30        7    1.0     2.0
PUB.Employee        55    6.2K  99 135  115       55    1.0     1.0
PUB.Family          70    3.0K  38  51   44       70    1.0     1.0 

Здесь мы видим, что таблица хранится в области «Employee», которая имеет порядковый номер 7.

Data Dictionary:

Подключитесь к базе данных sports в режиме редактора и перейдите в меню Tools -> Data Dictionary -> Database -> Reports -> Detailed Table. В появившемся диалоговом окне выберите название таблицы Family и нажмите клавишу «Enter». Откроется диалоговое окно «Report Options», которое позволяет настраивать параметры отчета. Ничего не меняйте, нажмите клавишу «F1». На экран будет выведен отчет с информацией по таблице Family. Найдите в отчете строку «Storage Area:», которая и будет указывать на имя области, в которой хранится таблица, в нашем случае это область хранения «Employee».

После того, как найдено имя области хранения, необходимо найти значение RPB для этой области. Воспользуйтесь структурным файлом базы данных (sports.st), предварительно обновив его командой:

prostrct list sports

Откройте файл sports.st и найдите в нем описание области «Employee». В ее описании значение RPB равно 32 (выделено жирным шрифтом на следующем примере):

d «Employee»:7,32;1

Получив значения RECID и RPB необходимо рассчитать значение DBKEY. Для этого разделите RECID на RPB, отбросьте дробную часть, результат умножьте на RPB. Это и будет DBKEY:

510 / 32 = 15,9375
DBKEY = 15 х 32 = 480

Теперь вам известно значение DBKEY, можно приступить к его поиску в сформированных к этому времени архивах AI-экстентов. Для этого перейдите в каталог с архивами AI-экстентов, выделите из них те, которые были сформированы в промежутке времени, охватывающем последний, по вашему мнению, момент существования записи и момент, когда ее уже не стало; или воспользуйтесь всеми архивами. После этого выгрузите AI-заметки из выбранных AI-экстентов в отдельный файл следующей командой:

rfutil sports -C aimage scan verbose -a  ai-file-name >>  scanai.txt

Чтобы не выполнять эту команду вручную для каждого AI-экстента, можно автоматизировать этот процесс с помощью следующей команды:

for ai in `ls -1 ./*.sports.a*`; do rfutil sports -C aimage scan verbose -a $ai >> scanai.txt ; done

После этого необходимо в файле scanai.txt найти все данные, связанные с DBKEY и с номером области хранения. В нашем случае ищем 480 (DBKEY) и отсекаем по номеру области 7:

cat scanai.txt | grep 480 | grep 7
Trid: 3942 area = 7   dbkey = 480   update counter = 35 (12529)
Trid: 3942 area = 7   dbkey = 480   update counter = 36 (12529)
Trid: 3942 area = 7   dbkey = 480   update counter = 37 (12529)

Теперь нужно найти все AI-заметки транзакции, в которой выполнялось удаление. В данном случае это «Trid: 3942»:

cat scanai.txt | grep «Trid: 3942»

Результат будет выглядеть так:

Trid: 3942 Thu May 27 14:42:48 2010. (2598)
Trid: 3942 User Id: val (12531)
Trid: 3942 code = RL_TBGN version = 1 (12528)
Trid: 3942 dbkey = 0 update counter = 0 (12530)
Trid: 3942 code = RL_IXDEL version = 2 (12528)
Trid: 3942 dbkey = 0 update counter = 0 (12530)
Trid: 3942 code = RL_BKREPL version = 1 (12528)
Trid: 3942 area = 7 dbkey = 192 update counter = 209 (12529)
Trid: 3942 code = RL_RMDEL version = 2 (12528)
Trid: 3942 area = 7 dbkey = 480 update counter = 35 (12529)
Trid: 3942 code = RL_RMCR version = 2 (12528)
Trid: 3942 area = 7 dbkey = 480 update counter = 36 (12529)
Trid: 3942 code = RL_BKBBOT version = 1 (12528)
Trid: 3942 area = 7 dbkey = 480 update counter = 37 (12529)
Trid: 3942 code = RL_BKMBOT version = 2 (12528)
Trid: 3942 area = 7 dbkey = 64 update counter = 62 (12529)
Trid: 3942 code = RL_BK2EB version = 2 (12528)
Trid: 3942 area = 7 dbkey = 512 update counter = 38 (12529)
Trid: 3942 Thu May 27 14:42:48 2010. (2598)
Trid: 3942 code = RL_TEND version = 1 (12528)
Trid: 3942 dbkey = 0 update counter = 0 (12530)

Жирным шрифтом выделена интересующая нас информация. Теперь мы знаем, что в четверг 27 мая 2010 года в 14 часов 42 минуты 48 секунд (Thu May 27 14:42:48 2010) запись была удалена пользователем val (User Id: val).

Строка с RL_RMDEL указывает на то, что была выполнена операция удаления, а следующая за ней строка содержит информацию с номером области хранения (area = 7) и с DBKEY (dbkey = 480).

Описанный пример явно демонстрирует, что механизм After-Imaging полезен не только с точки зрения дополнительного резервного копирования базы данных, но и с точки зрения «помощника» при разрешении таких инцидентов, как несанкционированное удаление информации из базы.


Добавить свой комментарий

Ваше имя*:
Ваш E-mail*:
Ваш комментарий*:

Компьютерные системы для бизнеса
© 2010 - 2017 Все права на материалы, находящиеся на этом сайте, охраняются в соответствии с законодательством РФ, в том числе, об авторском праве и смежных правах. При любом использовании материалов сайта ссылка на источник обязательна.