Добро пожаловать обратно в нашу серию статей об исследовании журнала транзакций SQL Server! В предыдущей статье мы обсудили, как ведут себя операции INSERT в журнале транзакций. В этой части мы сосредоточимся на операторах DELETE и узнаем, как можно выяснить, кто удалил определенную запись в нашей таблице.
Прежде чем мы углубимся в детали, давайте настроим нашу тестовую среду. Если вы следовали предыдущему туру, вы можете пропустить эти шаги. В противном случае давайте создадим простую тестовую базу данных:
CREATE DATABASE [TlogTest] ON PRIMARY (
NAME = N'TlogTest',
FILENAME = N'E:\Data\TlogTest.mdf',
SIZE = 3072KB,
FILEGROWTH = 1024KB
) LOG ON (
NAME = N'TlogTest_log',
FILENAME = N'E:\Log\TlogTest_log.ldf',
SIZE = 1024KB,
FILEGROWTH = 10%
);
GO
USE [TlogTest]
CREATE TABLE [Table01] (
[n1] INT IDENTITY,
[n2] CHAR DEFAULT 'a'
);
INSERT INTO Table01 DEFAULT VALUES;
GO 1000
Теперь, когда наши тестовые данные готовы, давайте перейдем к интересной части – отслеживанию оператора DELETE. В предыдущей статье мы использовали функцию `fn_dblog` для чтения журнала транзакций, и мы будем использовать ее снова здесь. Давайте удалим запись из нашей тестовой базы данных:
USE [TlogTest]
DELETE FROM Table01 WHERE n1 = 1;
GO
Для отслеживания операции DELETE мы будем использовать аналогичный запрос, как в предыдущей статье. На этот раз мы будем искать операции DELETE или LOP_DELETE_ROWS, и мы добавили столбец ‘Begin Time’, чтобы увидеть, когда было выполнено удаление:
USE [TlogTest]
SELECT [Begin Time], [Current LSN], [Operation], [Transaction Name], [Transaction SID], [Page ID], [Slot ID]
FROM fn_dblog(DEFAULT, DEFAULT)
WHERE [Operation] = 'LOP_DELETE_ROWS' OR [Description] LIKE '%DELETE%'
ORDER BY [Current LSN] DESC;
При выполнении вышеприведенного запроса вы получите результаты, аналогичные следующим:
Begin Time Current LSN Operation Transaction Name Transaction SID Page ID Slot ID
------------------- ------------------- ------------------ ------------------ ---------------------------------- ----------- -------
2022-01-01 12:34:56 00000001:00000002 LOP_BEGIN_XACT NULL NULL NULL NULL
2022-01-01 12:34:56 00000001:00000002 LOP_DELETE_ROWS NULL NULL 1234 5678
Операция `LOP_BEGIN_XACT` представляет фактическую команду SQL DELETE, а операция `LOP_DELETE_ROWS` представляет транзакцию, выполнившую удаление. Изучая время начала события `LOP_BEGIN_XACT`, мы можем определить дату и время выполнения удаления.
Теперь давайте выясним, кто на самом деле выполнил операцию DELETE. Скопируйте Transaction SID из результата предыдущего запроса и используйте его в следующем запросе:
SELECT SUSER_SNAME('вставьте сюда Transaction SID');
Замените `’вставьте сюда Transaction SID’` на скопированный Transaction SID. При выполнении запроса вы увидите имя пользователя Windows, который выполнил операцию удаления.
В нашем следующем туре по журналу транзакций мы еще глубже проникнем и изучим, как узнать, кто удалил запись после сброса журнала транзакций. Следите за обновлениями!