Вы когда-нибудь сталкивались с базой данных в состоянии “Восстановление”? Если да, вам могли задать вопросы вашими начальниками или конечными пользователями: “Что нам делать?” или “Когда это будет завершено?” Важно спокойно и уверенно решать эту ситуацию, заверяя других, что вы контролируете ситуацию. В этой статье мы рассмотрим, как отслеживать прогресс восстановления базы данных и обеспечить некоторое спокойствие во время этого процесса.
Один из способов отслеживать прогресс восстановления базы данных – использовать запрос. Вот пример запроса, который может помочь вам отслеживать прогресс восстановления:
DECLARE @ErrorLog AS TABLE([LogDate] DateTime, [ProcessInfo] VARCHAR(64), [TEXT] VARCHAR(MAX))
INSERT INTO @ErrorLog
EXEC sys.xp_readerrorlog 0, 1, 'Recovery of database'
SELECT DB_NAME(dt.database_id) AS DBName, GETDATE() as currenttime, at.transaction_begin_time,
dt.transaction_id, at.name AS TranName, cx.PercentComplete, cx.MinutesRemaining,
d.log_reuse_wait_desc, database_transaction_log_record_count, database_transaction_log_bytes_used,
database_transaction_next_undo_lsn,
CASE at.transaction_state
WHEN 0 THEN 'Not Completely Initialized'
WHEN 1 THEN 'Initialized but Not Started'
WHEN 2 THEN 'Transaction is Active'
WHEN 3 THEN 'Read-Only tran has Ended'
WHEN 4 THEN 'Distributed Tran commit process has been initiated'
WHEN 5 THEN 'In prepared state and waiting resolution'
WHEN 6 THEN 'Transaction has been committed'
WHEN 7 THEN 'Transaction is being rolled back'
WHEN 8 THEN 'Transaction has been rolled back'
END AS TranState
FROM sys.dm_tran_database_transactions dt
LEFT OUTER JOIN sys.dm_tran_active_transactions at ON dt.transaction_id = at.transaction_id
INNER JOIN master.sys.databases d ON d.database_id = dt.database_id
CROSS APPLY (
SELECT TOP 1 [LogDate],
SUBSTRING([TEXT], CHARINDEX(') is ', [TEXT]) + 4, CHARINDEX(' complete (', [TEXT]) - CHARINDEX(') is ', [TEXT]) - 4) AS PercentComplete,
CAST(SUBSTRING([TEXT], CHARINDEX('approximately', [TEXT]) + 13, CHARINDEX(' seconds remain', [TEXT]) - CHARINDEX('approximately', [TEXT]) - 13) AS FLOAT)/60.0 AS MinutesRemaining,
db_name(SUBSTRING([TEXT], CHARINDEX('(', [TEXT]) + 1, CHARINDEX(')', [TEXT]) - CHARINDEX('(', [TEXT]) - 1)) as DBName,
CAST(SUBSTRING([TEXT], CHARINDEX('(', [TEXT]) + 1, CHARINDEX(')', [TEXT]) - CHARINDEX('(', [TEXT]) - 1) as Int) as DBID
FROM @ErrorLog
ORDER BY [LogDate] DESC
) cx
WHERE d.state_desc <> 'online'
AND cx.dbid = dt.database_id
Этот запрос предоставляет информацию, такую как имя базы данных, текущее время, детали транзакции, прогресс восстановления и многое другое. Он использует представления динамического управления sys.dm_tran_database_transactions
и sys.dm_tran_active_transactions
для получения необходимых данных.
Один важный аспект этого запроса – это LEFT OUTER JOIN к sys.dm_tran_active_transactions
. Это соединение необходимо, потому что процесс восстановления показан в двух транзакциях. Одна транзакция имеет номер и служит заполнителем, в то время как фактическая работа выполняется в транзакции без номера. Проверяя имя транзакции, вы можете определить, продвигается ли процесс восстановления.
Во время процесса восстановления полезно отслеживать два столбца в транзакции без номера: database_transaction_log_record_count
и database_transaction_next_undo_lsn
. Эти столбцы указывают на прогресс, поскольку изменение значений в этих полях означает, что восстановление продвигается. Регулярно запуская запрос и наблюдая за этими столбцами, вы можете демонстрировать конкретный прогресс и успокаивать других.
Стоит отметить, что этот запрос не предоставляет оставшееся время для отката или процент завершения без запроса журнала ошибок. Если у вас есть какие-либо идеи о том, как включить эту информацию непосредственно в запрос, пожалуйста, дайте нам знать.
В заключение, столкновение с базой данных в состоянии “Восстановление” может быть стрессовой ситуацией. Однако, используя предоставленный запрос и отслеживая прогресс процесса восстановления, вы можете уверенно заверить других, что база данных движется к использованию. Помните оставаться спокойными и предоставлять обновления, чтобы все были информированы.