在SQL Server 2012(11.0.7001.0)下面在還原一個數據庫(備份文件40多G大小,實際數據庫大小300G),在還原過程中,出現一直等待ASYNC_IO_COMPLETION,如下測試截圖所示,已經等待了72分鍾了,但是還原比例依然為0%
SELECT r.session_id ,
r.command ,
r.start_time,
r.status,
r.wait_type,
CONVERT(NUMERIC(6, 2), r.percent_complete) AS [Percent Complete(%)] ,
CONVERT(VARCHAR(20), DATEADD(ms, r.estimated_completion_time,
GETDATE()), 20) AS [ETA Completion Time] ,
CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0) AS [Elapsed Min] ,
CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0) AS [ETA Min] ,
CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0
/ 60.0) AS [ETA Hours] ,
CONVERT(VARCHAR(1000), ( SELECT SUBSTRING(text,
r.statement_start_offset / 2,
CASE WHEN r.statement_end_offset = -1
THEN 1000
ELSE ( r.statement_end_offset
- r.statement_start_offset )
/ 2
END)
FROM sys.dm_exec_sql_text(sql_handle)
)) AS CommandText
FROM sys.dm_exec_requests r
WHERE command IN ( 'RESTORE DATABASE', 'BACKUP DATABASE','RESTORE LOG' );
當然,這里是實驗,如果還要繼續等待的話,相信這個時間會更長。這個是比較讓人奇怪的現象。后面查了一下這個跟即時文件初始化(Instant File Initialization (IFI))有關。關於這個概念,可以參考官方文檔數據庫文件初始化 ,摘抄部分內容如下所示:
數據庫文件初始化
初始化數據和日志文件以覆蓋之前刪除的文件遺留在磁盤上的任何現有數據。 執行以下其中一項操作時,應首先通過零填充(用零填充)數據和日志文件來初始化這些文件:
· 創建數據庫。
· 向現有數據庫添加數據或日志文件。
· 增大現有文件的大小(包括自動增長操作)。
· 還原數據庫或文件組。
文件初始化會導致這些操作花費更多時間。 但是,首次將數據寫入文件后,操作系統就不必用零來填充文件
即時文件初始化 (IFI)
在SQL Server中,可以在瞬間對數據文件進行初始化,以避免零填充操作。即時文件初始化可以快速執行上述文件操作。 即時文件初始化功能將回收使用的磁盤空間,而無需使用零填充空間。 相反,新數據寫入文件時會覆蓋磁盤內容。 日志文件不能立即初始化。
備注
只有在 Microsoft Windows XP Professional 或 Windows Server 2003 或更高版本中才可以使用即時文件初始化功能。
重要
只有在數據文件中才可以使用即時文件初始化功能。 創建日志文件或其大小增長時,將始終零填充該文件。
即時文件初始化功能僅在向SQL Server服務啟動帳戶授予了 SE_MANAGE_VOLUME_NAME 之后才可用。 Windows Administrator 組的成員擁有此權限,並可以通過將其他用戶添加到 執行卷維護任務 安全策略中來為其授予此權限。
重要
某些功能使用(如透明數據加密 (TDE))可以阻止即時文件初始化。
因為這個案例中,啟動SQL Server的服務啟動賬號為NT Service\MSSQLSERVER,所以沒有權限即時文件初始化的,如果將啟動SQL Server的服務啟動賬號改為具有管理員權限的域賬號,就不會出現這種情況。另外,如果一定要以NT Service\MSSQLSERVER為啟動賬號,可以按如下步驟操作:
要向一個帳戶授予 Perform volume maintenance tasks 權限:
- 在將要創建備份文件的計算機上打開本地安全策略應用程序 (secpol.msc)。
- 在左側窗格中,展開“本地策略” ,然后單擊“用戶權限指派” 。
- 在右側窗格中,雙擊“執行卷維護任務”。
- 單擊“添加用戶或組” ,添加用於備份的任何用戶帳戶。
- 單擊“應用” ,然后關閉所有“本地安全策略” 對話框。
設置后,重啟SQL Server服務,然后還原數據庫就會正常化,此時的等待事件為BACKUPTHREAD,而不是ASYNC_IO_COMPLETION, 如果版本是SQL Server 2012 SP4或以上版本,可以通過下面SQL查看識別是否啟用了即時文件初始化
SELECT servicename ,
startup_type ,
instant_file_initialization_enabled
FROM sys.dm_server_services;
另外,從SQL Server 2016 (13.x) 開始,可在安裝期間授予服務帳戶此權限。 如果使用命令提示符安裝,請添加 /SQLSVCINSTANTFILEINIT 參數,或選中安裝向導中“授予 SQL Server 數據庫引擎服務執行卷維護任務權限”復選框。
參考資料:
https://docs.microsoft.com/zh-cn/sql/relational-databases/databases/database-instant-file-initialization?view=sql-server-2017