You are currently viewing SQL Server recovery time
Microsoft SQL Server

SQL Server recovery time

SQL Server Recovery time is the time it takes for SQL Server to rollback or roll-forward transaction not yet persisted to the database after a service restart. Transactions that are uncommitted are rolled back, and transactions that are committed but not yet persisted are rolled forward.

Depending on the volume of transactions that needs to be handled during recovery, recovery may take a long time to perform. This affects the time it takes for a SQL Server restart. Another example when recovery times become a factor is when a failover is done in a SQL Server cluster.

So how can we know how long the recovery time will be?

Unfortunately, there is no exact way to predict the time a recovery will take. As a guide, try not to restart or failover (assuming, of course, a manual failover) during peak hours when the system is heavily utilized. Remember also to consider batch processes in this, as they tend to issue large transactions.

That said, the latest recovery times can (with a little work) be viewed from the SQL Server error log. If historical recovery times are stored, an educated guess about recovery times can be made.

The system stored procedure (undocumented) xp_readerrorlog can be used to get the events when a recovery is started and completed from the error log:

--RECOVERY START
EXEC xp_readerrorlog 0, 1, N'(c) Microsoft Corporation.', NULL, NULL, NULL, N'ASC'
--RECOVERY COMPLETE
EXEC xp_readerrorlog 0, 1, N'Recovery is complete. This is an informational message only. No user action is required.', NULL, NULL, NULL, N'desc'

The calls to xp_readerrorlog are capsuled into a stored procedure called GetRecoveryTime:

CREATE PROCEDURE dbo.GetRecoveryTime

AS

SET NOCOUNT ON

DECLARE @RecoveryStart DATETIME, @RecoveryStop DATETIME

IF (SELECT OBJECT_ID('tempdb..#TMP_RECOVERY_START')) IS NOT NULL BEGIN
	DROP TABLE #TMP_RECOVERY_START
END

IF (SELECT OBJECT_ID('tempdb..#TMP_RECOVERY_STOP')) IS NOT NULL BEGIN
	DROP TABLE #TMP_RECOVERY_STOP
END

CREATE TABLE #TMP_RECOVERY_START (LogDate DATETIME, ProcessInfo NVARCHAR(MAX), Text NVARCHAR(MAX))
CREATE TABLE #TMP_RECOVERY_STOP (LogDate DATETIME, ProcessInfo NVARCHAR(MAX), Text NVARCHAR(MAX))

INSERT #TMP_RECOVERY_START EXEC xp_readerrorlog 0, 1, N'(c) Microsoft Corporation.', NULL, NULL, NULL, N'ASC'
INSERT #TMP_RECOVERY_STOP EXEC xp_readerrorlog 0, 1, N'Recovery is complete. This is an informational message only. No user action is required.', NULL, NULL, NULL, N'desc'

SELECT @RecoveryStart = LogDate FROM #TMP_RECOVERY_START
SELECT @RecoveryStop = LogDate FROM #TMP_RECOVERY_STOP

SELECT DATEDIFF(SECOND, @RecoveryStart, @RecoveryStop) AS RecoveryTimeSeconds
GO

Tomas Lind

Tomas Lind - Consulting services as SQL Server DBA and Database Developer at High Coast Database Solutions AB.

Leave a Reply