Anterior  Próximo

Navegação:  e-Forms NFC-e 4.8.0.0 > Manual de Manutenção de Banco de Dados e-Forms > Manual de Manutenção de Banco de Dados e-Forms - SQL Server > Guia de Configurações da Rotina de Manutenção de Banco de Dados > Preparação do ambiente

Pré-requisitos

Durante a manutenção, depois da reorganização de cada índice é realizado o backup do transaction log, dado ao fato de que essa operação infla o espaço físico do banco e compromete o desempenho. Os parâmetros de configuração do backup precisam ser configurados em uma tabela conforme explicação abaixo:

 

Tabela dos dados de configuração da limpeza do transaction log

 

CREATE TABLE [dbo].[TBPARMANDB](

 [LimTLog] [int] NOT NULL,

 [TipLimTLog] [varchar](4) NULL,

 [DirBkpTLog] [varchar](100) NULL,

 [NomJobTLog] [varchar](50) NULL,

) ON [PRIMARY]

GO

 

LimTLog – Especifica se o Transaction Log deve ser limpo ou não. Valor 1 para SIM e 0 para NÃO.

 

TipLimTLog – Este campo é referente ao tipo de limpeza do transaction log. Sendo que ele pode ser realizado pelo próprio job, neste caso o campo deve ser informado o valor PROC. Caso esse campo possua valor nulo será chamado outro job (informado no campo NomJobTLog) para realizar o trabalho de backup.

 

DirBkpTLog – Local onde o backup do Transaction Log será salvo.

 

NomJobTLog – Neste campo deve ser informado o nome do Job que executará o script de limpeza do Transaction Log.

 

Após criar a tabela devem ser inseridos os dados conforme modelo abaixo. Neste caso o backup é realizado pelo mesmo job que está executando a manutenção do banco.

 

INSERT INTO TBPARMANDB VALUES(1, 'PROC', 'D:\backup', NULL);

 

clip1244Importante:

Dependendo da configuração do ambiente do servidor SQL, o script de criação da procedure de limpeza do transaction log pode não compilar gerando erro na conexão do provedor OLEDB com o servidor vinculado, neste caso deve-se alterar o valor do campo server para o nome da instância SQL.

 

SELECT CURRENT_EXECUTION_STATUS FROM OPENROWSET ('SQLOLEDB','Server=(local);Trusted_Connection=yes','SET FMTONLY OFF EXEC msdb.dbo.sp_help_job') q WHERE NAME = 'Backup TLog.Subplan_1'

 

ou

 

SELECT CURRENT_EXECUTION_STATUS FROM OPENROWSET ('SQLOLEDB','Server=SERVSQLPD01\SQLNDD_PD;Trusted_Connection=yes','SET FMTONLY OFF EXEC msdb.dbo.sp_help_job') q WHERE NAME = 'Backup TLog.Subplan_1'

 

Tabela para registro de log dos índices que tiveram manutenção.

 

CREATE TABLE [dbo].[TK_IDX_HIST](

 [Db_name] [varchar](200) NULL,

 [Tb_name] [varchar](200) NULL,

 [Idx_name] [varchar](200) NULL,

 [Frag] [int] NULL,

 [Data] [datetime] NULL

) ON [PRIMARY]

 

GO

 

Tabela para registro de log das estatísticas que tiveram manutenção

 

CREATE TABLE [dbo].[TK_STAT_HIST](

 [Db_name] [varchar](200) NULL,

 [Tb_name] [varchar](200) NULL,

 [Stat_name] [varchar](200) NULL,

 [Last_Upd] [datetime] NULL,

 [Data] [datetime] NULL

) ON [PRIMARY]

 

GO

 

Após isso deve-se rodar o script de criação das procedures contidas abaixo. Existe uma diferenciação de versionamento de bancos, portanto verifique e ceritifque-se de que o script que estará utilizando é realmente o correto para sua base de dados.

 

Importante:

O horário da rotina de manutenção não deve coincidir com o horário de atividades de backup (dados ou de log). No escopo da rotina de manutenção já existe o backup de log. Se houver essa coincidência de horários a manutenção  será abortada.

 

Script de Rotina de Manutenção de Banco de Dados SQL 2008Script de Rotina de Manutenção de Banco de Dados SQL 2008

CREATE PROCEDURE [LIMPA_TRANSACTION_LOG] @DBName varchar(50)

AS

DECLARE

 @TipLimTLog        VARCHAR(4),

 @DirBkpTLog        VARCHAR(100),

 @NomJobTLog        VARCHAR(50),

 @arquivo VARCHAR(100),

 @RunStatus int

 

BEGIN

 SET NOCOUNT ON;

 SELECT @TipLimTLog = TipLimTLog FROM TBPARMANDB

 SELECT @DirBkpTLog = DirBkpTLog FROM TBPARMANDB

 SELECT @NomJobTLog = NomJobTLog FROM TBPARMANDB

 SET @DBName = (SELECT REPLACE(REPLACE(@DBName,'[',''),']',''))

 

 IF @TipLimTLog = 'PROC' -- gera backup do transaction log no diretório especificado com nome concatenado

 BEGIN

         SET @arquivo = @DirBkpTLog + '\' + @DBName + '_' + replace(replace(replace(convert(varchar(50), getdate(), 120),'-',''),':',''),' ','') + '.trn'

         BACKUP LOG @DBName TO DISK=@arquivo

 END

 ELSE -- executa job destinado para backup do transaction log, caso o status = 1 (rodando) a procedure aguarda a conclusão

 BEGIN

         -- verifica o status do job informado

         SET @RunStatus = (SELECT CURRENT_EXECUTION_STATUS

                         FROM OPENROWSET ('SQLOLEDB','Server=(local);Trusted_Connection=yes','SET FMTONLY OFF EXEC msdb.dbo.sp_help_job') q

                         WHERE NAME = 'Backup TLog.Subplan_1')

         -- enquando o job estiver executando, ele aguarda 5 segundos e verificad novamente o status

         WHILE @RunStatus = 1

         BEGIN

                 WAITFOR DELAY '00:00:05'

                 SET @RunStatus = (SELECT CURRENT_EXECUTION_STATUS

                         FROM OPENROWSET ('SQLOLEDB','Server=(local);Trusted_Connection=yes','SET FMTONLY OFF EXEC msdb.dbo.sp_help_job') q

                                 WHERE NAME = 'Backup TLog.Subplan_1')

         END

         -- executa o job informado

         EXEC msdb.dbo.sp_start_job @NomJobTLog;

         -- aguarda o job encerrar para voltar para a procedure de limpeza

         SET @RunStatus = (SELECT CURRENT_EXECUTION_STATUS

                 FROM OPENROWSET ('SQLOLEDB','Server=(local);Trusted_Connection=yes','SET FMTONLY OFF EXEC msdb.dbo.sp_help_job') q

                         WHERE NAME = 'Backup TLog.Subplan_1')

         WHILE @RunStatus = 1

         BEGIN

                 WAITFOR DELAY '00:00:05'

                 SET @RunStatus = (SELECT CURRENT_EXECUTION_STATUS

                         FROM OPENROWSET ('SQLOLEDB','Server=(local);Trusted_Connection=yes','SET FMTONLY OFF EXEC msdb.dbo.sp_help_job') q

                                 WHERE NAME = 'Backup TLog.Subplan_1')

         END

 END

END

 

 

 

 

USE [master]

GO

if exists (select name from sys.objects where name like 'TK_MAN_IDX') drop procedure TK_MAN_IDX

go

/****** Object:  StoredProcedure [dbo].[TK_MAN_IDX]    Script Date: 08/08/2013 19:25:42 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE procedure [dbo].[TK_MAN_IDX] @BASE varchar(100),@DIF_MIN INT,@MED_FRAG INT

as

begin

if exists (select name from tempdb.sys.objects where name like '##table_idx')drop table ##table_idx

 

set nocount on

 

DECLARE @TABLE_NAME VARCHAR(100),

@STATS_NAME VARCHAR(100),

@COMANDO NVARCHAR(500),

@HORA_INICIO DATETIME,

@DATABASE_ID int,

@DATABASE_NAME varchar(200),

@IDX_NAME varchar(200),

@Frag int,

@LimpaLog int

 

-- Carrega configurações da TBPARMANDB

SELECT @limpalog = LimTLog FROM TBPARMANDB

 

-- Definindo janela de manutenção

select  @HORA_INICIO= GETDATE()

-- Define comprimento da janela.

--select @DIF_MIN=4

--select @MED_FRAG =10

 

 

-------------------------------- Manutenção pata todas as bases de dados ------------------------

IF @BASE LIKE 'TODAS'

  BEGIn

 

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE  name <> 'MASTER'

        AND name <> 'MODEL'

        AND name <> 'MSDB'

        AND name NOT LIKE'REPORTSERVER%'

        AND name <> 'TEMPDB'

ORDER BY name

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

 

WHILE @@FETCH_STATUS = 0

BEGIN

--------------------------------- Início do tratamento de índices

SELECT @COMANDO = N'SELECT ''[''+obj.name+'']'' tb_name,''[''+b.name+'']'' idx_name,a.avg_fragmentation_in_percent

into ##table_idx FROM '+@DATABASE_NAME+'.sys.dm_db_index_physical_stats ('

+ CONVERT(VARCHAR(4), @DATABASE_ID)

+ ', NULL, NULL, NULL, NULL) AS a

JOIN '+@DATABASE_NAME+'.sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id

join '+@DATABASE_NAME+'.sys.objects as obj on a.object_id=obj.object_id

order by avg_fragmentation_in_percent desc;'

exec sp_executesql @comando

--select * from ##table_idx

 

DECLARE MAN_IDX CURSOR FOR

select tb_name,idx_name,avg_fragmentation_in_percent from ##table_idx where avg_fragmentation_in_percent >= @MED_FRAG

 

OPEN MAN_IDX

 

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = N'alter index '+@IDX_NAME+' on '+@DATABASE_NAME+'..'+@table_name+' REORGANIZE'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_IDX_HIST VALUES (@DATABASE_NAME,@table_name,@IDX_NAME,@Frag,GETDATE())

         end try

         begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

         end catch

         -- Limpeza do Log

         IF @Limpalog = 1 EXEC LIMPA_TRANSACTION_LOG @DATABASE_NAME

 END

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

END

 

CLOSE MAN_IDX

DEALLOCATE MAN_IDX

DROP TABLE ##table_idx

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

end

-- Fim do IF para @BASE='TODAS'

-------------------------------- Manutenção em base de dados específica ------------------------

IF @base <> 'TODAS'

  BEGIN

      SET @DATABASE_NAME='['+@base+']'

        IF EXISTS (SELECT Lower(name)

                  FROM   sys.databases

                  WHERE  name LIKE @base)

        BEGIN

        --select @DATABASE_NAME AS 'DATABASE'

           

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE  name like @BASE

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @base

 

WHILE @@FETCH_STATUS = 0

BEGIN

--------------------------------- Início do tratamento de índices

SELECT @COMANDO = N'SELECT ''[''+obj.name+'']'' tb_name,''[''+b.name+'']'' idx_name,a.avg_fragmentation_in_percent

into ##table_idx FROM '+@DATABASE_NAME+'.sys.dm_db_index_physical_stats ('

+ CONVERT(VARCHAR(4), @DATABASE_ID)

+ ', NULL, NULL, NULL, NULL) AS a

JOIN '+@DATABASE_NAME+'.sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id

join '+@DATABASE_NAME+'.sys.objects as obj on a.object_id=obj.object_id

order by avg_fragmentation_in_percent desc;'

exec sp_executesql @comando

--select * from ##table_idx

 

DECLARE MAN_IDX CURSOR FOR

select tb_name,idx_name,avg_fragmentation_in_percent from ##table_idx where avg_fragmentation_in_percent >= @MED_FRAG

 

OPEN MAN_IDX

 

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = N'alter index '+@IDX_NAME+' on '+@DATABASE_NAME+'..'+@table_name+' REORGANIZE'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_IDX_HIST VALUES (@DATABASE_NAME,@table_name,@IDX_NAME,@Frag,GETDATE())

         end try

         begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

         end catch

         -- Limpeza do Log

         IF @Limpalog = 1 EXEC LIMPA_TRANSACTION_LOG @DATABASE_NAME

 END

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

END

 

CLOSE MAN_IDX

DEALLOCATE MAN_IDX

DROP TABLE ##table_idx

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

 

end

 

ELSE

        BEGIN

            PRINT 'Base de dados ou opção não existe !

Use @base=''todas'' para manutenção em todas as bases de dados ou @base=''nomebase'' para uma base específica.'

        END

-- Fim da

end

-- End fim da procedure

end

 

 

use master

go

if exists (select name from sys.objects where name like 'TK_MAN_STATS') drop procedure TK_MAN_STATS

go

create procedure TK_MAN_STATS @BASE varchar(100),@DIF_MIN INT,@DUPD_STATS INT,@VNULL varchar(2)

as

begin

if exists (select name from tempdb.sys.objects where name like '##stats_table')drop table ##stats_table

 

set nocount on

DECLARE @TABLE_NAME VARCHAR(100),

@STATS_NAME VARCHAR(100),

@COMANDO NVARCHAR(500),

@HORA_INICIO DATETIME,

@DATABASE_ID INT,

@LAST_UPD DATETIME,

@DATABASE_NAME VARCHAR(200)

--@MED_FRAG INT,

--@DUPD_STATS INT,

--@DIF_MIN INT

 

-- Definindo janela de manutenção

select @HORA_INICIO= GETDATE()

-- Define comprimento da janela.

--select @DIF_MIN=4

--select @DUPD_STATS =50

 

-------------------------------- Manutenção pata todas as bases de dados ------------------------

IF @BASE LIKE 'TODAS'

  BEGIN

 

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE name <> 'MASTER'

        AND name <> 'MODEL'

        AND name <> 'MSDB'

        AND name NOT LIKE'REPORTSERVER%'

        AND name <> 'TEMPDB'

ORDER BY name

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

 

WHILE @@FETCH_STATUS = 0

BEGIN

-------------------------------- Início do tratamento de estatísticas --------------------

 

set @COMANDO=null

if @VNULL = 's'

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

else

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

and STATS_DATE(obj.OBJECT_ID, stat.stats_id) is not NULL

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

--select * from ##STATS_TABLE

 

 

DECLARE MAN_STATS CURSOR FOR

SELECT TABLENAME,STATNAME,LastUpdate FROM ##STATS_TABLE WHERE DATEDIFF(DAY,LASTUPDATE,GETDATE()) >= @DUPD_STATS

 

OPEN MAN_STATS

 

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = 'UPDATE STATISTICS '+@DATABASE_NAME+'..'+@TABLE_NAME+'('+@STATS_NAME+')'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_STAT_HIST VALUES (@DATABASE_NAME,@TABLE_NAME,@STATS_NAME,@Last_Upd,GETDATE())

         end try

      begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

      end catch

 END

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

END

 

CLOSE MAN_STATS

DEALLOCATE MAN_STATS

DROP TABLE ##stats_table

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

-- End fim da procedure

end

 

-- Fim do IF para @BASE='TODAS'

 

 

-- Manutenção em base de dados específica.

IF @base <> 'TODAS'

  BEGIN

      SET @DATABASE_NAME='['+@base+']'

        IF EXISTS (SELECT Lower(+name)

                  FROM   sys.databases

                  WHERE name LIKE @base)

        BEGIN

        --select @DATABASE_NAME AS 'DATABASE'

     

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE name like @BASE

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

 

WHILE @@FETCH_STATUS = 0

BEGIN

-------------------------------- Início do tratamento de estatísticas --------------------

 

set @COMANDO=null

if @VNULL = 's'

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

else

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

and STATS_DATE(obj.OBJECT_ID, stat.stats_id) is not NULL

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

--select * from ##STATS_TABLE

 

 

DECLARE MAN_STATS CURSOR FOR

SELECT TABLENAME,STATNAME,LastUpdate FROM ##STATS_TABLE WHERE DATEDIFF(DAY,LASTUPDATE,GETDATE()) >= @DUPD_STATS OR (LASTUPDATE is NULL AND @VNULL = 's')

 

OPEN MAN_STATS

 

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = 'UPDATE STATISTICS '+@DATABASE_NAME+'..'+@TABLE_NAME+'('+@STATS_NAME+')'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_STAT_HIST VALUES (@DATABASE_NAME,@TABLE_NAME,@STATS_NAME,@Last_Upd,GETDATE())

         end try

      begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

      end catch

 END

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

END

 

CLOSE MAN_STATS

DEALLOCATE MAN_STATS

DROP TABLE ##stats_table

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

 

end

 

ELSE

        BEGIN

            PRINT 'Base de dados ou opção não existe !

Use @base=''todas'' para manutenção em todas as bases de dados ou @base=''nomebase'' para uma base específica.'

        END

-- Fim da

end

-- End fim da procedure

end

Script de Rotina de Manutenção de Banco de Dados SQL 2008Script de Rotina de Manutenção de Banco de Dados SQL 2012 e 2014

CREATE PROCEDURE [LIMPA_TRANSACTION_LOG] @DBName varchar(50)

AS

DECLARE

 @TipLimTLog        VARCHAR(4),

 @DirBkpTLog        VARCHAR(100),

 @NomJobTLog        VARCHAR(50),

 @arquivo VARCHAR(100),

 @RunStatus int

 

BEGIN

 SET NOCOUNT ON;

 SELECT @TipLimTLog = TipLimTLog FROM TBPARMANDB

 SELECT @DirBkpTLog = DirBkpTLog FROM TBPARMANDB

 SELECT @NomJobTLog = NomJobTLog FROM TBPARMANDB

 SET @DBName = (SELECT REPLACE(REPLACE(@DBName,'[',''),']',''))

 

 IF @TipLimTLog = 'PROC' -- gera backup do transaction log no diretório especificado com nome concatenado

 BEGIN

         SET @arquivo = @DirBkpTLog + '\' + @DBName + '_' + replace(replace(replace(convert(varchar(50), getdate(), 120),'-',''),':',''),' ','') + '.trn'

         BACKUP LOG @DBName TO DISK=@arquivo

 END

 ELSE                                        -- executa job destinado para backup do transaction log, caso o status = 1 (rodando) a procedure aguarda a conclusão

 BEGIN

         -- verifica o status do job informado

         EXECUTE sp_MonitorProcessingJob @status = @RunStatus OUTPUT;

         -- enquando o job estiver executando, ele aguarda 5 segundos e verificad novamente o status

         WHILE @RunStatus = 1

         BEGIN

                 WAITFOR DELAY '00:00:05'

                 EXECUTE sp_MonitorProcessingJob @status = @RunStatus OUTPUT;

         END

         -- executa o job informado

         EXEC msdb.dbo.sp_start_job @NomJobTLog;

         -- aguarda o job encerrar para voltar para a procedure de limpeza

         EXECUTE sp_MonitorProcessingJob @status = @RunStatus OUTPUT;

         WHILE @RunStatus = 1

         BEGIN

                 WAITFOR DELAY '00:00:05'

                 EXECUTE sp_MonitorProcessingJob @status = @RunStatus OUTPUT;

         END

 END

END

 

 

USE [master]

GO

if exists (select name from sys.objects where name like 'TK_MAN_IDX') drop procedure TK_MAN_IDX

go

/****** Object:  StoredProcedure [dbo].[TK_MAN_IDX]    Script Date: 08/08/2013 19:25:42 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE procedure [dbo].[TK_MAN_IDX] @BASE varchar(100),@DIF_MIN INT,@MED_FRAG INT

as

begin

if exists (select name from tempdb.sys.objects where name like '##table_idx')drop table ##table_idx

 

set nocount on

 

DECLARE @TABLE_NAME VARCHAR(100),

@STATS_NAME VARCHAR(100),

@COMANDO NVARCHAR(500),

@HORA_INICIO DATETIME,

@DATABASE_ID int,

@DATABASE_NAME varchar(200),

@IDX_NAME varchar(200),

@Frag int,

@LimpaLog int

 

-- Carrega configurações da TBPARMANDB

SELECT @limpalog = LimTLog FROM TBPARMANDB

 

-- Definindo janela de manutenção

select  @HORA_INICIO= GETDATE()

-- Define comprimento da janela.

--select @DIF_MIN=4

--select @MED_FRAG =10

 

 

-------------------------------- Manutenção pata todas as bases de dados ------------------------

IF @BASE LIKE 'TODAS'

  BEGIn

 

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE  name <> 'MASTER'

        AND name <> 'MODEL'

        AND name <> 'MSDB'

        AND name NOT LIKE'REPORTSERVER%'

        AND name <> 'TEMPDB'

ORDER BY name

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

 

WHILE @@FETCH_STATUS = 0

BEGIN

--------------------------------- Início do tratamento de índices

SELECT @COMANDO = N'SELECT ''[''+obj.name+'']'' tb_name,''[''+b.name+'']'' idx_name,a.avg_fragmentation_in_percent

into ##table_idx FROM '+@DATABASE_NAME+'.sys.dm_db_index_physical_stats ('

+ CONVERT(VARCHAR(4), @DATABASE_ID)

+ ', NULL, NULL, NULL, NULL) AS a

JOIN '+@DATABASE_NAME+'.sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id

join '+@DATABASE_NAME+'.sys.objects as obj on a.object_id=obj.object_id

order by avg_fragmentation_in_percent desc;'

exec sp_executesql @comando

--select * from ##table_idx

 

DECLARE MAN_IDX CURSOR FOR

select tb_name,idx_name,avg_fragmentation_in_percent from ##table_idx where avg_fragmentation_in_percent >= @MED_FRAG

 

OPEN MAN_IDX

 

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = N'alter index '+@IDX_NAME+' on '+@DATABASE_NAME+'..'+@table_name+' REORGANIZE'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_IDX_HIST VALUES (@DATABASE_NAME,@table_name,@IDX_NAME,@Frag,GETDATE())

         end try

         begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

         end catch

         -- Limpeza do Log

         IF @Limpalog = 1 EXEC LIMPA_TRANSACTION_LOG @DATABASE_NAME

 END

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

END

 

CLOSE MAN_IDX

DEALLOCATE MAN_IDX

DROP TABLE ##table_idx

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

end

-- Fim do IF para @BASE='TODAS'

-------------------------------- Manutenção em base de dados específica ------------------------

IF @base <> 'TODAS'

  BEGIN

      SET @DATABASE_NAME='['+@base+']'

        IF EXISTS (SELECT Lower(name)

                  FROM   sys.databases

                  WHERE  name LIKE @base)

        BEGIN

        --select @DATABASE_NAME AS 'DATABASE'

           

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE  name like @BASE

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @base

 

WHILE @@FETCH_STATUS = 0

BEGIN

--------------------------------- Início do tratamento de índices

SELECT @COMANDO = N'SELECT ''[''+obj.name+'']'' tb_name,''[''+b.name+'']'' idx_name,a.avg_fragmentation_in_percent

into ##table_idx FROM '+@DATABASE_NAME+'.sys.dm_db_index_physical_stats ('

+ CONVERT(VARCHAR(4), @DATABASE_ID)

+ ', NULL, NULL, NULL, NULL) AS a

JOIN '+@DATABASE_NAME+'.sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id

join '+@DATABASE_NAME+'.sys.objects as obj on a.object_id=obj.object_id

order by avg_fragmentation_in_percent desc;'

exec sp_executesql @comando

--select * from ##table_idx

 

DECLARE MAN_IDX CURSOR FOR

select tb_name,idx_name,avg_fragmentation_in_percent from ##table_idx where avg_fragmentation_in_percent >= @MED_FRAG

 

OPEN MAN_IDX

 

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = N'alter index '+@IDX_NAME+' on '+@DATABASE_NAME+'..'+@table_name+' REORGANIZE'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_IDX_HIST VALUES (@DATABASE_NAME,@table_name,@IDX_NAME,@Frag,GETDATE())

         end try

         begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

         end catch

         -- Limpeza do Log

         IF @Limpalog = 1 EXEC LIMPA_TRANSACTION_LOG @DATABASE_NAME

 END

FETCH NEXT FROM MAN_IDX INTO @TABLE_NAME,@IDX_NAME,@Frag

END

 

CLOSE MAN_IDX

DEALLOCATE MAN_IDX

DROP TABLE ##table_idx

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

 

end

 

ELSE

        BEGIN

            PRINT 'Base de dados ou opção não existe !

Use @base=''todas'' para manutenção em todas as bases de dados ou @base=''nomebase'' para uma base específica.'

        END

-- Fim da

end

-- End fim da procedure

end

 

 

use master

go

if exists (select name from sys.objects where name like 'TK_MAN_STATS') drop procedure TK_MAN_STATS

go

create procedure TK_MAN_STATS @BASE varchar(100),@DIF_MIN INT,@DUPD_STATS INT,@VNULL varchar(2)

as

begin

if exists (select name from tempdb.sys.objects where name like '##stats_table')drop table ##stats_table

 

set nocount on

DECLARE @TABLE_NAME VARCHAR(100),

@STATS_NAME VARCHAR(100),

@COMANDO NVARCHAR(500),

@HORA_INICIO DATETIME,

@DATABASE_ID INT,

@LAST_UPD DATETIME,

@DATABASE_NAME VARCHAR(200)

--@MED_FRAG INT,

--@DUPD_STATS INT,

--@DIF_MIN INT

 

-- Definindo janela de manutenção

select @HORA_INICIO= GETDATE()

-- Define comprimento da janela.

--select @DIF_MIN=4

--select @DUPD_STATS =50

 

-------------------------------- Manutenção pata todas as bases de dados ------------------------

IF @BASE LIKE 'TODAS'

  BEGIN

 

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE name <> 'MASTER'

        AND name <> 'MODEL'

        AND name <> 'MSDB'

        AND name NOT LIKE'REPORTSERVER%'

        AND name <> 'TEMPDB'

ORDER BY name

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

 

WHILE @@FETCH_STATUS = 0

BEGIN

-------------------------------- Início do tratamento de estatísticas --------------------

 

set @COMANDO=null

if @VNULL = 's'

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

else

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

and STATS_DATE(obj.OBJECT_ID, stat.stats_id) is not NULL

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

--select * from ##STATS_TABLE

 

 

DECLARE MAN_STATS CURSOR FOR

SELECT TABLENAME,STATNAME,LastUpdate FROM ##STATS_TABLE WHERE DATEDIFF(DAY,LASTUPDATE,GETDATE()) >= @DUPD_STATS

 

OPEN MAN_STATS

 

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = 'UPDATE STATISTICS '+@DATABASE_NAME+'..'+@TABLE_NAME+'('+@STATS_NAME+')'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_STAT_HIST VALUES (@DATABASE_NAME,@TABLE_NAME,@STATS_NAME,@Last_Upd,GETDATE())

         end try

      begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

      end catch

 END

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

END

 

CLOSE MAN_STATS

DEALLOCATE MAN_STATS

DROP TABLE ##stats_table

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

-- End fim da procedure

end

 

-- Fim do IF para @BASE='TODAS'

 

 

-- Manutenção em base de dados específica.

IF @base <> 'TODAS'

  BEGIN

      SET @DATABASE_NAME='['+@base+']'

        IF EXISTS (SELECT Lower(+name)

                  FROM   sys.databases

                  WHERE name LIKE @base)

        BEGIN

        --select @DATABASE_NAME AS 'DATABASE'

     

DECLARE man_cursor CURSOR FOR

SELECT database_id,

        '[' + name + ']'

FROM   sys.databases

WHERE name like @BASE

 

OPEN man_cursor;

 

FETCH next FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

 

WHILE @@FETCH_STATUS = 0

BEGIN

-------------------------------- Início do tratamento de estatísticas --------------------

 

set @COMANDO=null

if @VNULL = 's'

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

else

begin

select @comando = 'select  ''[''+obj.name+'']'' TableName,''[''+stat.name+'']'' as StatName,STATS_DATE(obj.OBJECT_ID, stat.stats_id) AS LastUpdate

into ##stats_table

from '+@database_name+'.sys.stats stat inner join '+@DATABASE_NAME+'.sys.objects obj on stat.object_id=obj.object_id

where obj.type=''u''

and STATS_DATE(obj.OBJECT_ID, stat.stats_id) is not NULL

order by LastUpdate asc'

EXEC SP_EXECUTESQL @COMANDO

end

--select * from ##STATS_TABLE

 

 

DECLARE MAN_STATS CURSOR FOR

SELECT TABLENAME,STATNAME,LastUpdate FROM ##STATS_TABLE WHERE DATEDIFF(DAY,LASTUPDATE,GETDATE()) >= @DUPD_STATS OR (LASTUPDATE is NULL AND @VNULL = 's')

 

OPEN MAN_STATS

 

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

 

WHILE @@FETCH_STATUS = 0

BEGIN

 -- Controle de execução da rotina em horário próprio

 IF DATEDIFF(MINUTE,@HORA_INICIO,GETDATE()) <= @DIF_MIN

 BEGIN

         begin try

                 SET @COMANDO =NULL

                 select @COMANDO = 'UPDATE STATISTICS '+@DATABASE_NAME+'..'+@TABLE_NAME+'('+@STATS_NAME+')'

                 EXEC SP_EXECUTESQL @COMANDO

                 INSERT INTO MASTER..TK_STAT_HIST VALUES (@DATABASE_NAME,@TABLE_NAME,@STATS_NAME,@Last_Upd,GETDATE())

         end try

      begin catch

                 SELECT

                 ERROR_NUMBER() AS ErrorNumber,

                 ERROR_MESSAGE() AS ErrorMessage;

      end catch

 END

FETCH NEXT FROM MAN_STATS INTO @TABLE_NAME,@STATS_NAME,@Last_Upd

END

 

CLOSE MAN_STATS

DEALLOCATE MAN_STATS

DROP TABLE ##stats_table

 

FETCH NEXT FROM man_cursor INTO @DATABASE_ID, @DATABASE_NAME

END

 

CLOSE man_cursor

DEALLOCATE man_cursor

 

set nocount off

 

end

 

ELSE

        BEGIN

            PRINT 'Base de dados ou opção não existe !

Use @base=''todas'' para manutenção em todas as bases de dados ou @base=''nomebase'' para uma base específica.'

        END

-- Fim da

end

-- End fim da procedure

end

 

Voltar