ApexSQL Log中的Redo Script跟原始SQL不一致問題


最近遇到一個誤更新數據的問題,使用ApexSQL Log做挖掘事務日志的時候,發現ApexSQL Log生成的Redo Script跟原始SQL是有區別的。它們並不是完全一致的。只是邏輯上等價而已。如下所示,我們做一個測試,如下所示,創建一個表后,並模擬忘記添加條件,出現誤刪除數據的情況

 

SELECT * INTO KERRY_TEST FROM SYS.OBJECTS;
 
 
DELETE FROM KERRY_TEST

 

 

然后我們用ApexSQL Log挖掘事務日志,你會看到有很多對應的Delete記錄,而且對應的Redo Script跟原始SQL是不一樣的。如下所示,

 

 

image

 

 

下面是其中兩個Redo  Script(為了方便查看,對腳本進行了格式化)

 

 

--DELETE (0003F73C:000065FC:000D) done at 2019-06-13 10:35:56.876 by xxx\xxxx in transaction 0000:0ADF73EA (Committed)
BEGIN TRANSACTION;
DELETE  FROM [dbo].[KERRY_TEST]
WHERE   /*** WARNING: WHERE CLAUSE FOR THIS STATEMENT WAS GENERATED FOR A TABLE WITH NO PRIMARY KEY AND NO CLUSTERED INDEX ***/
        [name] = N'sysfgfrag' COLLATE Chinese_PRC_CI_AS
        AND [object_id] = 19
        AND [principal_id] IS NULL
        AND [schema_id] = 4
        AND [parent_object_id] = 0
        AND [type] = N'S ' COLLATE Latin1_General_CI_AS_KS_WS
        AND [type_desc] = N'SYSTEM_TABLE' COLLATE Latin1_General_CI_AS_KS_WS
        AND [create_date] = '20160101 10:46:55.060'
        AND [modify_date] = '20160101 10:46:55.100'
        AND [is_ms_shipped] = 1
        AND [is_published] = 0
        AND [is_schema_published] = 0;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;
 
 
 
--DELETE (0003F73C:000065FC:000A) done at 2019-06-13 10:35:56.876 by xxx\xxx in transaction 0000:0ADF73EA (Committed)
BEGIN TRANSACTION;
DELETE  FROM [dbo].[KERRY_TEST]
WHERE   /*** WARNING: WHERE CLAUSE FOR THIS STATEMENT WAS GENERATED FOR A TABLE WITH NO PRIMARY KEY AND NO CLUSTERED INDEX ***/
        [name] = N'sysseobjvalues' COLLATE Chinese_PRC_CI_AS
        AND [object_id] = 9
        AND [principal_id] IS NULL
        AND [schema_id] = 4
        AND [parent_object_id] = 0
        AND [type] = N'S ' COLLATE Latin1_General_CI_AS_KS_WS
        AND [type_desc] = N'SYSTEM_TABLE' COLLATE Latin1_General_CI_AS_KS_WS
        AND [create_date] = '20160101 10:47:02.050'
        AND [modify_date] = '20160101 10:47:02.057'
        AND [is_ms_shipped] = 1
        AND [is_published] = 0
        AND [is_schema_published] = 0;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;
 

 

 

如果有聚集索引,你會看到沒有WHERE條件的UPDATE、DELETE操作都會生成很多個對應的Redo Script,對應的WHERE條件則是聚集索引字段。如下測試所示:

SELECT  *
INTO    KERRY_TEST2
FROM    sys.objects;
 
CREATE CLUSTERED INDEX PK_KERRY_TEST2 ON KERRY_TEST2(OBJECT_ID);
 
UPDATE  KERRY_TEST2
SET     NAME = 'KERRY';
 
 
DELETE  FROM KERRY_TEST2;

 

 

image

 

下面是對應的UPDATE、DELETE操作的redo script

--UPDATE (0003F73C:0000700A:001F) done at 2019-06-13 11:27:26.036 by xxx\xxx in transaction 0000:0ADF7404 (Committed)
BEGIN TRANSACTION; 
UPDATE  [dbo].[KERRY_TEST2]
SET     [name] = N'KERRY' COLLATE Chinese_PRC_CI_AS
WHERE   [object_id] = 3;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;
 
 
 
--    DELETE (0003F73C:00007482:00D9) done at 2019-06-13 11:27:35.406 by xxx\xxx in transaction 0000:0ADF7405 (Committed)
BEGIN TRANSACTION;
DELETE  FROM [dbo].[KERRY_TEST2]
WHERE   [object_id] = 836302139;
IF @@ROWCOUNT <= 1
    COMMIT TRANSACTION;
ELSE
    BEGIN
        ROLLBACK TRANSACTION;
            PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.';
    END;

 

這里只是簡單記錄一下這個事情,千萬不要以為Redo Script跟原始SQL是完全一致的。如果遇到這種問題,如何判斷呢?可以查看Transaction ID,以及對應的Begin Time , End Time,如下所示,你會發現它們是一致的

 

 

clip_image001[4]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM