Quantcast
Viewing all articles
Browse latest Browse all 15

Script – Pesquisando arquivos de backups em um diretório com T-SQL

Olá pessoal.

Hoje, vou compartilhar um dos scripts que escrevi e utilizo no meu ambiente (Migrações, atualização de ambientes, plano de Disaster Recovery).

Esta stored procedure busca no diretório informado por arquivos de uma determinada extensão e retorna os respectivos nomes físicos, podendo ser para um arquivo ou todos os arquivos ali contidos.

Script

-- ============================ --
-- Title: Search Backup Archive	--
-- Type: Stored Procedure		--
-- Author: Leandro Ribeiro		--
-- Create Date: 18/08/2011		--
-- ============================ --
-- Twitter: @sqlleroy			--
-- blog: sqlleroy.com			--
-- ============================ --
USE master
GO

IF OBJECT_ID('[prd_SearchBackupArchive]') IS NOT NULL
	DROP PROC [prd_SearchBackupArchive]
GO

CREATE PROC [prd_SearchBackupArchive](
  @Database			VARCHAR(30)
 ,@Extension		CHAR(4)
 ,@PathBackup		VARCHAR (100)
 ,@DbSystem			CHAR(1)
 -- Find backup archives with a last modified date less than or equal to the current date minus "@SeekDaysAgo" days.
 ,@SeekDaysAgo		VARCHAR(3)
 ,@LastBackup		VARCHAR(100) OUTPUT
 )
AS
BEGIN
	SET NOCOUNT ON;
	SET QUOTED_IDENTIFIER ON;
	SET ANSI_WARNINGS ON;

	DECLARE
		 @Command VARCHAR(1000)
		,@Error VARCHAR(100)

	DECLARE @Forfiles TABLE (CMD VARCHAR(200))

	-- ======================= --
	-- Create temporary tables --
	-- ======================= --
	IF OBJECT_ID ('tempdb..##ArqBck') IS NOT NULL DROP TABLE ##ArqBck

	CREATE TABLE ##ArqBck (PhysicalName VARCHAR(100), DatabaseName SYSNAME, DayTime VARCHAR(15))

	IF OBJECT_ID ('tempdb..#Forfiles') IS NOT NULL DROP TABLE #Forfiles

	CREATE TABLE #Forfiles (CMD VARCHAR(200))

	-- ============================================================ --
	-- MS-DOS Command for returning contained archives in directory --
	-- ============================================================ --
	IF @Database = ''
		SELECT @Command = 'forfiles /P ' + @PathBackup +
							CASE WHEN @SeekDaysAgo > 0 THEN ' /D -' + @SeekDaysAgo ELSE '' END +
							' /M *' + @Extension + ' /C "cmd /c echo @file"';
	ELSE
		SELECT @Command = 'forfiles /P ' + @PathBackup +
							CASE WHEN @SeekDaysAgo > 0 THEN ' /D -' + @SeekDaysAgo ELSE '' END +
							' /M ' + @Database + '*' + @Extension + ' /C "cmd /c echo @file"';

	EXEC sp_configure 'show advanced options', 1
	RECONFIGURE WITH OVERRIDE

	EXEC sp_configure 'xp_cmdshell', 1
	RECONFIGURE WITH OVERRIDE

	INSERT INTO #Forfiles
	EXEC xp_cmdshell @Command

	EXEC sp_configure 'xp_cmdshell', 0
	RECONFIGURE WITH OVERRIDE

	EXEC sp_configure 'show advanced options', 0
	RECONFIGURE WITH OVERRIDE

	SELECT @Error = CMD FROM #Forfiles WHERE CMD LIKE 'ERRO:%'

	IF @Error <> ''
	BEGIN
		SELECT @Error
		RAISERROR (@Error,10,1)
		DROP TABLE ##ArqBck
	END
	ELSE
	BEGIN
		-- Adjusting the field to facilitate the subsequent writing
		UPDATE #Forfiles SET CMD = REPLACE(CMD,'"','')

		-- =============================== --
		-- Store result in temporary table --
		-- =============================== --
			SELECT @Command =
				'INSERT INTO ##ArqBck
				 SELECT
					CMD PhysicalName,
					SUBSTRING(CMD, 0,CHARINDEX(''_backup'',CMD)) DatabaseName,
					CASE CONVERT(VARCHAR(2),SERVERPROPERTY(''productversion''))
					WHEN 9 THEN REPLACE(SUBSTRING(CMD, CHARINDEX(''_backup'',CMD) +7 ,13),''_'','''')
					ELSE REPLACE(SUBSTRING(CMD, CHARINDEX(''_backup'',CMD) +8 ,15),''_'','''')
					END DayTime
				 FROM #Forfiles
				 WHERE CMD IS NOT NULL' + CHAR(13)

		-- Whenever want exclude system databases when search all databases
		IF @DbSystem = 'N' AND @database = ''
			SELECT @Command = @Command + ' AND SUBSTRING(REPLACE(CMD,''"'',''''), 0,CHARINDEX(''_backup'',REPLACE(CMD,''"'',''''))) NOT IN (''master'',''msdb'',''model'',''tempdb'')'

		EXEC (@Command)

		-- ================== --
		-- Index result table --
		-- ================== --
		IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_ArqBck')
		CREATE NONCLUSTERED INDEX IX_ArqBck ON ##ArqBck (DayTime, DatabaseName) INCLUDE (PhysicalName)

		-- Return last backup name the database
		IF @Database <> ''
			SELECT @LastBackup = PhysicalName FROM ##ArqBck ORDER BY DayTime ASC

	END
END

EXEC sys.sp_MS_marksystemobject '[prd_SearchBackupArchive]'
go

Image may be NSFW.
Clik here to view.
Retorno da procedure prd_SearchBackupArchive

Retorno da procedure prd_SearchBackupArchive

Image may be NSFW.
Clik here to view.
Arquivos de backups no diretório.

Arquivos de backups no diretório.

O script está ajustado ao padrão de nome do arquivo de backup utilizado pelo plano de manutenção nativo do SQL Server.

Para utilizar a procedure, devemos ter permissões para:

  • Alterar as configurações do sql (sp_configure).
  • Executar o comando xp_cmdshell
  • Permissão de leitura no diretório informado.

Perceba que a procedure habilita o comando xp_cmdshell e tão logo o execute, o recurso é desabilitado.

Como não é recomendável (por questões de segurança) que o comando xp_cmdshell esteja habilitado, esta é uma forma de atenuar possíveis problemas.

Se tiver recomendações de ajustes no script, fique a vontade para comentar… Afinal, críticas construtivas são sempre bem vindas.

No próximo post, vou compartilhar outra procedure que gera o comando de restore dinamicamente utilizando esta procedure.

Como este é meu último post no ano de 2012, desejo a todos um ano novo de saúde , realizações pessoais e profissionais.

Até o próximo post.


Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 15