• 找出谁删除了某个表


    找出谁删除了某个表

    当实例没有做DDL Trigger和其它一些监控时,如何知道谁删除了某个表?通过系统函数fn_dblog,fn_dump_dblog和默认跟踪可以找到。
    1. 创建测试环境:新建个表,插入一条数据,然后drop掉
    CREATE DATABASE test
    go
    USE test
    go
    CREATE TABLE dbo.fnlog_test
    (id INT IDENTITY ,val VARCHAR(10) DEFAULT 'x')
    GO
    CREATE CLUSTERED INDEX IX_ft_id
    ON dbo.fnlog_test (ID)
    GO
    INSERT INTO dbo.fnlog_test
    VALUES (DEFAULT )
    GO
    DROP TABLE fnlog_test
    GO
    2. 通过sys.fn_dblog,找出相关信息:
    USE test
    go
    SELECT [Transaction ID],[Transaction Name],[Begin Time],[Server UID],SPID
    FROM sys.fn_dblog(NULL,null)
    WHERE [Transaction Name]='DROPOBJ'
    go


    3. 上一步中这里得到了事务ID,开始时间,Suid,SPID等,但是执行删除的SPID可以已经logout或者被重用了。所以要找出“当时”的这个SPID。
    先根据事务ID,找出被删除的对象吧。查询结果的“OBJECT: 9:245575913:0”,9是DB_ID,245575913是object_id,就是被删除的表的object_id.
    SELECT TOP(1) [Lock Information]
    FROM sys.fn_dblog(NULL,NULL)
    WHERE [Lock Information] LIKE '%SCH_M OBJECT%' AND [Transaction ID]='0000:000002e7'
    go

    4. 通常SQL Server实例安装后会开启一个默认跟踪(Default Trace),这个跟踪会记录一引起级别较高的重要信息。先找到默认跟踪
    SELECT id,status,path FROM sys.traces
    WHERE is_default=1

    5. 根据前几步中得到的trace path,事务ID,开始时间,SPID,object_id,通过默认跟踪得到进一步的信息:
    SELECT DatabaseID,NTUserName,HostName,ApplicationName,LoginName,
    SPID,ObjectID,StartTime, EventClass,EventSubClass
    FROM sys.fn_trace_gettable('D:Microsoft SQL ServerMSSQL11.MSSQLSERVERMSSQLLoglog_10.trc',1)
    WHERE SPID=52 AND  StartTime>'2013/07/15 11:32:44:133' AND ObjectID =245575913
    GO

    这一步中就得到了谁删除了这个表的更具体信息了。需要说明一下的是EventClass=47,EventSubclass=(0,1),这记录了跟踪事件的操作。
    SELECT te.trace_event_id,te.name,tsv.subclass_value,tsv.subclass_name
    FROM sys.trace_events te
    INNER JOIN sys.trace_subclass_values tsv
    ON te.trace_event_id=tsv.trace_event_id
    WHERE te.trace_event_id=47 AND tsv.subclass_value IN(0,1)

    6. 如果是生产环境的,事务日志可能被截断而被重用覆盖了。这里就需要从日志备份中读取日志信息来定位。需要用到fn_dump_dblog.
      重新构建测试环境:
    CREATE DATABASE test
    go
    USE test
    go
    CREATE TABLE dbo.fnlog_test
    (id INT IDENTITY ,val VARCHAR(10) DEFAULT 'x')
    GO
    CREATE CLUSTERED INDEX IX_ft_id
    ON dbo.fnlog_test (ID)
    GO
    INSERT INTO dbo.fnlog_test
    VALUES (DEFAULT )
    GO
    USE master
    go
    BACKUP DATABASE test
    TO DISK='D:SQLSample est.bak' 
    WITH init
    go
    USE test
    go
    DROP TABLE fnlog_test
    GO
    USE master
    go
    BACKUP LOG test
    TO DISK='D:SQLSample est.bck' 
    WITH init
    go
    2. 和3. 的查询要换成fn_dump_dblog,其它的步骤是一样的。这里我另外做的测试,所以事务ID与前面不同了。
    SELECT
    [Transaction ID],[Transaction Name],[Begin Time],[Server UID],SPID
    FROM fn_dump_dblog (NULL, NULL, N'DISK', 1, N'D:SQLSample est.bck',
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
    WHERE [Transaction Name] LIKE '%DROPOBJ%'
    SELECT TOP(1) [Lock Information]
    FROM fn_dump_dblog (NULL, NULL, N'DISK', 1, N'D:SQLSample est.bck',
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
    DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
    WHERE [Lock Information] LIKE '%SCH_M OBJECT%' AND [Transaction ID]='0000:000002b8'
    总结:
      1. 在SQL Server 2008 R2 SP2&SQL Server 2012 SP1测试通过
      2. trace文件是rollover的,所以要找对path,同样要从日志备份中查询的话,也要找对日志备份文件的时间
      3. fn_dblog和fn_dump_dblog是Undocumented Function.

  • 相关阅读:
    Mock Server 之 moco-runner 使用指南二
    Mock Server 之 moco-runner 使用指南一
    性能测试流程图
    从程序员到项目经理(11):每个人都是管理者【转载】
    从程序员到项目经理(10):程序员加油站 --要执着但不要固执【转载】
    从程序员到项目经理(9):程序员加油站 -- 再牛也要合群【转载】
    从程序员到项目经理(8):程序员加油站 -- 不要死于直率【转载】
    从程序员到项目经理(7):程序员加油站 -- 完美主义也是一种错【转载】
    从程序员到项目经理(6):程序员加油站 -- 懂电脑更要懂人脑【转载】
    从程序员到项目经理(5):程序员加油站 -- 不是人人都懂的学习要点【转载】
  • 原文地址:https://www.cnblogs.com/lrl45/p/5772234.html
Copyright © 2020-2023  润新知