Fala pessoal!
Nesse post de hoje, gostaria de compartilhar uma solução que criei para responder uma dúvida em um dos grupos do Telegram em que participo, que foi a pergunta de como saber há quanto tempo um database está online no SQL Server. Isso não é há quanto tempo a instância está online e sim há quanto tempo um database está online.
Para resolver essa dúvida, pensei em utilizar o próprio log do SQL Server para identificar quando cada database foi iniciado e retornar para o usuário. A query abaixo irá retornar todos os bancos que estão no último arquivo de log, junto com a data da última vez que o banco foi inicializado e o tempo decorrido desde então até a hora atual.
IF (OBJECT_ID('tempdb..#StartupDB') IS NOT NULL) DROP TABLE #StartupDB
CREATE TABLE #StartupDB (
[LogNumber] TINYINT,
[LogDate] DATETIME,
[ProcessInfo] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI,
[Text] NVARCHAR(MAX) COLLATE SQL_Latin1_General_CP1_CI_AI,
[Database] AS (REPLACE(REPLACE(SUBSTRING([Text], CHARINDEX('''', [Text]), 128), '''', ''), '.', ''))
)
INSERT INTO #StartupDB (LogDate, ProcessInfo, [Text])
EXEC master.dbo.sp_readerrorlog 0, 1, N'Starting up database ', NULL
SELECT
[Database],
MAX(LogDate) AS LogDate,
(CASE WHEN DATEDIFF(SECOND, MAX(LogDate), GETDATE()) > 86400 THEN CAST(DATEDIFF(SECOND, MAX(LogDate), GETDATE()) / 86400 AS VARCHAR) + 'd ' ELSE '' END) +
RIGHT('00' + CAST((DATEDIFF(SECOND, MAX(LogDate), GETDATE()) / 3600) % 24 AS VARCHAR), 2) + ':' +
RIGHT('00' + CAST((DATEDIFF(SECOND, MAX(LogDate), GETDATE()) / 60) % 60 AS VARCHAR), 2) + ':' +
RIGHT('00' + CAST(DATEDIFF(SECOND, MAX(LogDate), GETDATE()) % 60 AS VARCHAR), 2) + '.' +
RIGHT('000' + CAST(DATEDIFF(SECOND, MAX(LogDate), GETDATE()) AS VARCHAR), 3)
AS TimeRunning
FROM
#StartupDB
GROUP BY
[Database]
ORDER BY 1
Caso você queira analisar todo o histórico de inicialização dos databases, varrendo por todos os arquivos de logs (não somente o último):
IF (OBJECT_ID('tempdb..#Arquivos_Log') IS NOT NULL) DROP TABLE #Arquivos_Log
CREATE TABLE #Arquivos_Log (
[idLog] INT,
[dtLog] NVARCHAR(30) COLLATE SQL_Latin1_General_CP1_CI_AI,
[tamanhoLog] INT
)
IF (OBJECT_ID('tempdb..#StartupDB') IS NOT NULL) DROP TABLE #StartupDB
CREATE TABLE #StartupDB (
[LogNumber] TINYINT,
[LogDate] DATETIME,
[ProcessInfo] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI,
[Text] NVARCHAR(MAX) COLLATE SQL_Latin1_General_CP1_CI_AI,
[Database] AS (REPLACE(REPLACE(SUBSTRING([Text], CHARINDEX('''', [Text]), 128), '''', ''), '.', ''))
)
INSERT INTO #Arquivos_Log
EXEC sys.sp_enumerrorlogs
DECLARE
@Contador INT = 0,
@Total INT = (SELECT COUNT(*) FROM #Arquivos_Log)
WHILE(@Contador < @Total)
BEGIN
INSERT INTO #StartupDB (LogDate, ProcessInfo, [Text])
EXEC master.dbo.xp_readerrorlog @Contador, 1, N'Starting up database ', NULL, NULL, NULL
-- Atualiza o número do arquivo de log
UPDATE #StartupDB
SET LogNumber = @Contador
WHERE LogNumber IS NULL
SET @Contador += 1
END
SELECT *
FROM #StartupDB
ORDER BY LogDate DESC
Nas duas soluções apresentadas, você pode usar a coluna de “Database” para filtrar os bancos selecionados e acredito que a dúvida original foi respondida por esses 2 scripts.
É isso aí, pessoal! Espero que tenham gostado dessa dica. Você conhece alguma outra solução para responder essa dúvida? Deixe aqui nos comentários 🙂
Um grande abraço e até a próxima!


Comentários (0)
Carregando comentários…