Sql-Server

完整恢復模型和 tabblock 插入日誌記錄

  • October 9, 2019

在測試一些查詢時,我在數據庫上將恢復模式設置為完全,並執行兩個相同的 1M 行插入,有和沒有TABLOCK.

在第一個帶有TABLOCKsql 9295server 2008 實例8714上的日誌記錄和 SQL Server 2017 實例上的日誌記錄。

在沒有 tabblock 的情況下執行插入時,我得到1035659了 2008 實例的1068599記錄和 2017 實例的記錄。

在 sql server 2008 上進行測試的原因是為了匹配數據載入性能指南中關於 ML 操作的恢復模型的聲明:

僅當您的數據庫處於批量記錄或簡單恢復模式時,最少記錄的操作才可用。

那麼,如果不是最小日誌記錄,這裡會看到什麼?

Use DatabaseName

ALTER DATABASE DatabaseName SET RECOVERY FULL;
GO
BACKUP DATABASE DatabaseName TO DISK = '\\location\DatabaseName.bak';

BACKUP LOG DatabaseName TO DISK = '\\location\DatabaseName_log.trn';
GO

IF OBJECT_ID(N'dbo.Accounts', N'U') IS NOT NULL
BEGIN
   DROP TABLE dbo.Accounts;
END;
GO

CREATE TABLE dbo.Accounts( AccountID INT PRIMARY KEY NOT NULL,
                           AccountName varchar(255),
                           DateCreated DATETIME2);

-- Insert 1M Rows into dbo.Account without TABLOCK
GO
SET STATISTICS IO, TIME ON;
INSERT INTO dbo.Accounts  (AccountID,AccountName,DateCreated)
SELECT TOP(1000000)
       ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
       'Name N ' + CAST(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS varchar(255)),
       DATEADD(MINUTE,-ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),GETDATE())
FROM MASTER..SPT_VALUES SPT1
CROSS APPLY MASTER..SPT_VALUES SPT2;
GO
-- check the amount of records in the log file
SELECT count(*)
FROM
fn_dbLog(NULL,NULL);
--1035659 rows
GO

-- clear the log
BACKUP LOG DatabaseName to disk = '\\location\DatabaseName_log2.trn';

GO

--drop the table

IF OBJECT_ID(N'dbo.Accounts', N'U') IS NOT NULL
BEGIN
   DROP TABLE dbo.Accounts;
END;
GO
-- create the table
CREATE TABLE dbo.Accounts( AccountID INT PRIMARY KEY NOT NULL,
                           AccountName varchar(255),
                           DateCreated DATETIME2);

-- Insert 1M Rows into dbo.Account WITH TABLOCK
GO
SET STATISTICS IO, TIME ON;
INSERT INTO dbo.Accounts WITH(TABLOCK) (AccountID,AccountName,DateCreated)
SELECT TOP(1000000)
       ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),
       'Name N ' + CAST(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS varchar(255)),
       DATEADD(MINUTE,-ROW_NUMBER() OVER (ORDER BY (SELECT NULL)),GETDATE())
FROM MASTER..SPT_VALUES SPT1
CROSS APPLY MASTER..SPT_VALUES SPT2;
GO
-- check the amount of records in the log file
SELECT count(*)
FROM
fn_dbLog(NULL,NULL);

--9295 rows

當使用TABLOCK你的loggingeven infull model被稱為“高效日誌記錄”時,它不是insert逐行記錄整個pages記錄。

它將僅minimally loggedsimplebulk logged模式下page allocationslog但在full您已完全格式化pages的恢復模式中data

所以在插入時records進入登錄simplefull模型的數量tablock幾乎相同,但內容不同:在simple/bulk logged中只有頁碼,完整的會有完整pages的。

確實是full logging因為insert 可以使用這些日誌記錄完全重構操作,而simplebulk logged只有足夠rollback的資訊insert

引用自:https://dba.stackexchange.com/questions/250644