Você está na página 1de 16

Piores Prticas Utilizar o comando BACKUP LOG com a

opo WITH TRUNCATE_ONLY Parte I


https://gustavomaiaaguiar.wordpress.com/2009/08/01/piores-praticas-%e2%80%93-utilizar-o-comando-
backup-log-com-a-opcao-with-truncate_only-%e2%80%93-parte-i/

Publicado em 01/08/2009 | 13 Comentrios


Boa Noite Pessoal,
Nos ltimos dias estive um pouco ausente dos fruns e de diversas comunidades que participo, pois estou
ministrando um curso oficial de SQL Server 2008. Ontem durante a aula apresentei a parte de backups e
aps as explicaes, participei para os alunos uma situao muito comum que indiretamente est relacionada
com backups. Hoje nos fruns MSDN e Technet tambm presenciei a mesma situao acontecendo
novamente intitulando-se "Log Gigantesco".
Acredito que depois da dificuldade de conectar-se remotamente ao SQL Server (se algum estiver com essa
dificuldade leia esse excelente artigo "Como configurar Conexo Remota no SQL Server 2005") , problemas
com o log de transao que cresce assustadoramente representam provavelmente a dvida mais comum de
SQL Server que exista. De fato j vi inmeras dvidas relacionadas ao log do SQL Server que cresce,
cresce, cresce e deixa alguns desenvolvedores, dbas iniciantes e profissionais preocupados e aparentemente
sem ter o que fazer. Na maioria das vezes a soluo uma s conforme descrito abaixo (o texto foi adaptado
para preservar a identidade de seus participantes):
"Oi Gente,
Estou com um banco de dados com um arquivo de LOG com mais de 40Gb e preciso de espao.
O HD s tem mais 2GB e LOG continua crescendo. O que devo fazer ?"
"Oi Fulano,
Cara muito simples. Basta s rodar esses dois comandos:
Backup Log NomeDoSeuBanco WITH TRUNCATE_ONLY
GO
DBCC SHRINKFILE(NomeLogicoArquivoLog, 10)
GO
Se voc no souber o nome do arquivo lgico roda a sp_helpdb SeuBanco. importante rodar os dois
comandos conectado no seu banco."
De fato essa a soluo padro e realmente funciona. Na maioria das situaes, aqueles que aplicaram essa
soluo certamente viram seus arquivos de Log diminuir to assustadoramente quanto cresceram. Com uma
soluo to "eficiente" a receita de bolo escrita. Toda vez que o LOG atingir tamanhos absurdos, basta
ento rodar o BACKUP LOG com o TRUNCATE_ONLY e logo em seguida rodar o SHRINK FILE. A
eficincia desse comando parece ser tanta que no me estranha que ele seja contemplado em jobs, planos de
manuteno e nem que seja encapsulado em uma stored procedure.
Inquestionavalmente arquivos de Log gigantescos so um incmodo. No s pelo fato de ameaaram acabar
com todo o espao livre disponvel na unidade, mas tambm porque se um backup possui um arquivo de
LOG gigantesco, ser necessrio reservar um espao gigantesco em outro ambiente no momento da
restaurao. E como normalmente os ambientes de homologao e desenvolvimento tem menos recursos,
arquivos muito grandes podem ser verdadeiros inconvenientes. Aps ver tantas dezenas de threads com
problemas de arquivos de log que crescem alm da conta fico com duas preocupaes: Ser que aqueles que
simplesmente executam esses comandos tem a menor noo do problema que eles podem provocar ? E ser
que aqueles que repassam esses comandos sabem exatamente o tamanho do risco que podem estar
introduzindo em outros ambientes ?
"Afinal o que h de mal em executar esses dois comandos ? Eles sempre iro reduzir o log de transaes e
"resolver o problema" e essa a soluo que est escrita na maioria dos tutoriais, fruns, etc. Se o arquivo
de log no for limpo a sim que os problemas aparecem." No posso deixar de concordar com a afirmao,
mas vejamos algo um pouco mais apurado antes de tirar as concluses sobre algo praticamente
inquestionvel.
Um pouco sobre o Log de transaes
Todo banco de dados possui uma estrutura de log que registra tudo o que aconteceu que represente escrita
nesse banco de dados. Essa estrutura imprescindvel para que o banco de dados saiba o que aconteceu na
eventualidade de uma queda de energia entre outros problemas e mantenha-se consistente. De tempos em
tempos (mais precisamente a cada Checkpoint), as transaes registradas no Log de transaes so
efetivamente aplicadas no banco de dados mantendo sua consistncia. As entradas no Log possuem um
sequencial chamado LSN que o acrnimo de Log Sequence Number. medida que o Log recebe novas
instrues, novos LSNs so adicionados. A tabela abaixo mostra um hipottico exemplo de um Log de
transaes.

LSN Instruo
001 INSERT INTO Clientes VALUES (1,Alberto,2560.92,M)
002 DELETE FROM AjusteEstoque WHERE IDAjuste = 3097
CREATE TABLE Defeitos (IDDef INT, IDProd INT, Data
003
SMALLDATETIME)
004 CHECKPOINT
ALTER TABLE Produtos ADD DataUltimaAtualizacao
005
SMALLDATETIME
006 UPDATE Produtos SET DataUltimaAtualizacao = DataCadastro
007 GRANT SELECT ON Produtos TO UsrMarketing
008 EXEC sp_addrolemember db_datareader, UsrRelatorios
009 CHECKPOINT
010 DROP TABLE ProdutosHistorico
A propriedade RECOVERY MODEL
O Recovery Model de um banco de dados tem papel fundamental no funcionamento dessas estruturas de log
e nas estratgias possveis de Disaster Recover a partir de um backup. H trs opes para o Recovery
Model: Simple, Bulk Logged e Full. No explicarei os detalhes do funcionamento do Bulk Logged dada sua
proximidade com o Recovery Model Full. Para o entendimento desse artigo, o Recovery Model Bulk
Logged e Full podem ser interpretados como iguais embora no o sejam em alguns casos.
No Recovery Model Simple todas as transaes so gravadas no arquivo de Log, mas a cada Checkpoint
elas so excludas do arquivo de Log liberando espao para novas entradas. Se considerarmos que o arquivo
de log exemplificado tem capacidade para gravar 10 LSNs e que o Recovery Model est marcado como
Simple, aps o Checkpoint do LSN004, os LSNs 001, 002, 003 e 004 seriam eliminados do arquivo de log,
o mesmo valeria para os LSNs 005, 006, 007, 008 e 009 aps o Checkpoint em LSN009. Se nesse momento
aparecessem mais algumas entradas, elas seriam gravadas no incio do arquivo que foi liberado. Ex

LSN Instruo
011 TRUNCATE TABLE TMP
012 EXEC UspRelatorioVendas @DataInicio = 20090720
013 DBCC CHECKTABLE(RelatoriosConsolidados)
014 CHECKPOINT
015 DROP USER UsrApp

010 DROP TABLE ProdutosHistorico


Os LSNs 011, 012, 013 e 014 so posteriores ao LSN010, mas como o arquivo tem capacidade para 10
entradas, necessrio acomodar esses LSNs. Como h espao no incio do arquivo, as entradas podem ser
cadastradas perfeitamente sem prejudicar a consistncia desse Log. No Recovery Model Simple, o Log
recicla-se automaticamente e apaga as entradas que ficaram para trs e que foram contempladas no banco
pelo processo de Checkpoint. Aps o processo de Checkpoint, as transaes ficam refletidas no banco e
portanto so apagadas do Log de transaes. O checkpoint contemplado no LSN014 apagaria todos os LSNs
deixando somente o LSN015 e liberaria espao para mais nove entradas de Log (quatro na rea antes do
LSN015 e cinco aps a presena do LSN015). O Recovery Model Simple ir sempre reciclar as entradas do
log formando um circulo na qual hora determinadas posies estaram preenchidas, sero apagadas pelo
processo de Checkpoint, sero utilizadas novamente e excludas novamente. por esse comportamento em
forma de crculo que essa arquitetura chamada em alguns produtos de Log Circular.
No Recovery Model Full, as coisas funcionam um pouco diferentes. Ao contrrio do Recovery Model
Simple, o Recovery Model Full no ir apagar de forma automtica os LSNs do log de transaes
independente do que acontea. Mesmo que o processo de Checkpoint ocorra e as transaes j estejam
contempladas no banco de dados, o Log continuar a mant-las no arquivo de Log. Essa caracterstica de
arquivamento faz com que alguns chamem essa arquitetura de Archieve Log. Se admitirmos que esse
arquivo possui capacidade apenas para 10 LSNs, aps completar os 10 LSNs, o arquivo ficar
completamente cheio. O cadastro do LSN 011 ao LSN015 ir demandar que o arquivo de Log cresa
conforme a tabela abaixo:

LSN Instruo
001 INSERT INTO Clientes VALUES (1,Alberto,2560.92,M)
002 DELETE FROM AjusteEstoque WHERE IDAjuste = 3097
CREATE TABLE Defeitos (IDDef INT, IDProd INT, Data
003
SMALLDATETIME)
004 CHECKPOINT
ALTER TABLE Produtos ADD DataUltimaAtualizacao
005
SMALLDATETIME
006 UPDATE Produtos SET DataUltimaAtualizacao = DataCadastro
007 GRANT SELECT ON Produtos TO UsrMarketing
008 EXEC sp_addrolemember db_datareader, UsrRelatorios
009 CHECKPOINT
010 DROP TABLE ProdutosHistorico
011 TRUNCATE TABLE TMP
012 EXEC UspRelatorioVendas @DataInicio = 20090720
013 DBCC CHECKTABLE(RelatoriosConsolidados)
014 CHECKPOINT
015 DROP USER UsrApp
Uma vez que o Recovery Model Full faz com que o banco de dados no exclua as entradas antigas do log de
transaes, ou seja, as transaes que j esto contempladas no banco de dados, no de se esperar que o
log cresa de forma indefinida. Afinal novas transaes iro gerar novos LSNs e como esses no so limpos
de forma automtica o resultado final um arquivo de log de tamanhos acima do normal. O crescimento do
Log se dar na velocidade em que novas transaes ocorrem, mas fato que mais cedo ou mais tarde ele ir
incomodar.
Uma concluso inicial que se o arquivo de Log cresce de forma descomunal, o banco de dados no pode
estar em Recovery Model Simple. Se o Recovery Model Simple faz a devida excluso das entradas inativas
(aquelas j contempladas pelo Checkpoint), no h como o Recovery Model Simple fazer com que um
arquivo de Log cresa de forma desproporcional (muitas vezes ele no cresce). Se o banco de dados estiver
com o Recovery Model Simple, a nica preocupao ter um arquivo de log que consiga acomodar a
quantidade mdia de transaes entre um checkpoint e outro.
A primeira recomendao que se o arquivo de Log cresce demais, ao invs de simplesmente efetuar o
Truncate com o Shrink funcionem, mais factvel mudar o Recovery Model para Simple. Assim, o arquivo
de Log no ir crescer de forma descomunal e tender a ficar constante. Embora o Truncate com o Shrink
funcione, o problema voltar a acontecer, pois, se o Recovery Model Full o Log ir crescer novamente. Ao
invs de executar sucessivos Truncates e Shrinks mais sensato alterar o Recovery Model para Simple
eliminando a causa raiz do problema.
A ttulo de curiosidade, o truncate iria eliminar as entradas inativas do log, ou seja, todas aquelas anteriores
ao ltimo checkpoint e o shrink iria reduzir o arquivo, possivelmente devolvendo-o ao tamanho de 10 LSNs
ao invs de 15 conforme a tabela abaixo:

LSN Instruo
015 DROP USER UsrApp
O incio do arquivo ficaria pronto para receber novas entradas de LSN. Com o tempo, o Log cresceria e
provocaria sucessivas expanses at que um novo truncate e um novo shrink fossem executados.
Se a diferena entre o Recovery Model Simple e o Recovery Model fosse apenas a administrao do
tamanho do arquivo de log seria interessante perguntar qual a utilidade do Recovery Model Full. Enquanto o
Recovery Model Simple dispensa maiores preocupaes com o tamanho do arquivo de log, o Recovery
Model Full traz responsabilidades e preocupaes adicionais e isso um forte indcio para pensar porque os
bancos de dados no so criados com o Recovery Model Simple ? D muito menos trabalho.
sem dvida um raciocnio que faz sentido, mas vejamos a seguir porque o Recovery Model Full
importante mesmo com as implicaes e overheads administrativos.
A escolha do Recovery Model e o processo de restaurao
O Recovery Model tem papel fundamental no processo de backup e restaurao do banco de dados. Alguns
Recovery Models permitem a realizao de backups de log e posterior recuperao enquanto outro
simplesmente no permitem. O uso de backup de logs tambm imprecindvel para algumas estratgias de
backup e restore mais complexas como o Restore Online e o Piecemal Restore ambos utilizados em
conjunto com backups e filegroups. Por hora basta saber que o Recovery Model Simple no possibilita a
realizao de backups de logs enquanto que os demais Recovery Models possibilitam.
A razo para o Recovery Model Simple no permitir backups de logs um pouco bvia. Como ele exclui as
entradas mais antigas do Log de transaes a cada Checkpoint e como cada Checkpoint ocorre em mdia de
minuto em minuto, no faria muito sentido fazer o backup do log de transaes de uma base com o
Recovery Model Simple. No haveria o que gravar no backup, pois, provavelmente no momento de faz-lo
restariam apenas as entradas mais recentes (as que o Checkpoint) ainda no contemplou enquanto que
muitos outros LSNs teriam sido deixados de lado. Como o Recovery Model Full no exclui as entradas do
Log (mesmo as j contempladas pelo Checkpoint), faz sentido em falar de backups de log para bases com o
Recovery Model Full. Vejamos como isso funciona atravs do hipottico arquivo de log.

LSN Hora Instruo


BACKUP DATABASE BD TO DISK =
001 00:00
C:\Temp\BDFull.BAK
002 08:00 CREATE TABLE Tbl (Codigo INT)
003 09:00 INSERT INTO Tbl VALUES (1)
004 09:30 INSERT INTO Tbl VALUES (2)
005 10:00 BACKUP LOG BD TO DISK = C:\Temp\BDLog01.TRN
006 14:45 INSERT INTO Tbl VALUES (4)
007 15:20 INSERT INTO Tbl VALUES (5)
008 15:30 CHECKPOINT
009 16:00 INSERT INTO Tbl VALUES (6)
010 18:00 BACKUP LOG BD TO DISK = C:\Temp\BDLog02.TRN
Os backups contemplam a relao de LSNs conforme a tabela abaixo:

Backup Lsn Inicial Lsn Final


BDFull 001 001
BDLog01 002 005
BDLog02 006 010
Com essa relao de backups visvel que o banco de dados pode ser reconstrudo para parar em qualquer
posio possvel entre o LSN 001 e o LSN 010. A tabela abaixo mostra as sequncias necessrias para voltar
o banco em qualquer LSN, ou melhor dizendo qualquer milissegundo entre s 00:00 e s 18:00.

LSN Sequncia Necessria


001 Apenas o BDFull
002 Restaurar o BDFull e o BDLog01 com parada s 08:00
003 Restaurar o BDFull e o BDLog01 com parada s 09:00
004 Restaurar o BDFull e o BDLog01 com parada s 09:30
005 Restaurar o BDFull e o BDLog01 com aplicao total de BDLog01
Restaurar o BDFull, o BDLog1 com aplicao total e o BDLog02 com parada s
006
14:45
Restaurar o BDFull, o BDLog1 com aplicao total e o BDLog02 com parada s
007
15:20
Restaurar o BDFull, o BDLog1 com aplicao total e o BDLog02 com parada s
008
15:30
Restaurar o BDFull, o BDLog1 com aplicao total e o BDLog02 com parada s
009
16:00
010 Restaurar o BDFull, o BDLog1 e o BDLog02 com aplicao total para ambos
Segundo a tabela, possvel restaurar em qualquer LSN aplicando-se o backup full e restaurando-se os Logs
necessrios. Embora o exemplo pare em LSNs especficos, uma vez que os backups contemplem toda a
durao de 00:00 at s 18:00 possvel parar em qualquer posio nesse intervalo. totalmente factvel
voltar o banco s 12:00 mesmo que no haja nenhum LSN identificado.
Aps a realizao do backup de Log (BDLog01) os LSNs 001, 002, 003, 004 e 005 foram retirados do
arquivo de Log e copiados para o backup de Log BDLog01. O backup de Log BDLog02 ir contemplar
todos os LSNs gravados desde o ltimo backup de Log (no caso o BDLog01) e portanto ir retirar do
arquivo de Log os LSNs 006, 007, 008, 009 e 010. A realizao desses backups retirou as entradas de Log
inativas, liberou espao e fez com que o arquivo de Log possusse espao disponvel para acomodar futuras
transaes sem provocar um crescimento exagerado ou ainda o estouro do espao disponvel em disco.
Da mesma forma que um banco com o Recovery Model Simple no permite realizar backup de Log, ele
tambm no permite efetuar o truncate do Log. Ento situaes que exijam o uso do truncate do Log s
podem contemplar outros Recovery Models como no caso o Full. Vejamos como o uso do truncate
(independente do Shrink ou no) afetaria o exemplo.

LSN Hora Instruo


BACKUP DATABASE BD TO DISK =
001 00:00
C:\Temp\BDFull.BAK
002 08:00 CREATE TABLE Tbl (Codigo INT)
003 09:00 INSERT INTO Tbl VALUES (1)
004 09:30 INSERT INTO Tbl VALUES (2)
005 10:00 BACKUP LOG BD TO DISK = C:\Temp\BDLog01.TRN
006 14:45 CREATE TABLE EmpregadoMes (Nome VARCHAR(50))
007 15:20 INSERT INTO Tbl VALUES (5)
008 15:30 BACKUP LOG BD WITH TRUNCATE_ONLY
009 16:00 INSERT INTO EmpregadoMes VALUES (Fernando)
010 18:00 BACKUP LOG BD TO DISK = C:\Temp\BDLog02.TRN
A relao de LSNs conforme os backups ficaria da seguinte forma:

Backup Lsn Inicial Lsn Final


BDFull 001 001
BDLog01 002 005
BDLog02 009 010
possvel observar que o LSN 008 fez um truncate no Log e por isso o backup de Log BDLog02 s
contemplou o LSN subsequente ao LSN que efetuou o truncate. Vejamos agora as possibilidades de
restaurao:

LSN Sequncia Necessria


001 Apenas o BDFull
002 Restaurar o BDFull e o BDLog01 com parada s 08:00
003 Restaurar o BDFull e o BDLog01 com parada s 09:00
004 Restaurar o BDFull e o BDLog01 com parada s 09:30
005 Restaurar o BDFull e o BDLog01 com aplicao total de BDLog01
006 No possvel restaurar, pois, no h como chegar at o LSN 006
007 No possvel restaurar, pois, no h como chegar at o LSN 007
008 No possvel restaurar, pois, no h como chegar at o LSN 008
009 No possvel restaurar, pois, no h como pular para o LSN 009
010 No possvel restaurar, pois, no h como pular para o LSN 010
Como o log foi truncado no LSN 008, o backup de Log BDLog02 no ir contemplar os LSNs 006, 007 e
008 que so os LSNs subsequentes ao backup de Log BDLog01. Assim impossvel restaurar o banco em
uma posio que contemple esses LSNs, ou seja, no ser possvel restaurar o banco em nenhum horrio
entre s 10:00 (LSN 005) e s 16:00 (LSN 009). Embora os LSNs 009 e 010 estejam contemplados no
backup de Log BDLog02, tambm no ser possvel restaur-los, pois, a restaurao de backups de log no
permite que sequncias de log sejam quebradas. Se o Backup Full (BDFull) e o primeiro backup de Log
(BDLog) forem restaurados, o banco ficar parado no LSN 005 s 10:00. No ser possvel simplesmente
"pular" das 10:00 (LSN 005) para s 16:00 (LSN 009), pois, nesse tempo houve atividades no banco de
dados que no podem ser desconsideradas. Podemos ver que o LSN 006 cria a tabela EmpregadoMes e que
o LSN 009 faz um INSERT nessa tabela. Se os LSNs 006, 007 e 008 pudessem ser ignorados, o LSN 009
iria gerar um erro, pois, se o LSN 006 foi ignorado, a tabela EmpregadoMes no exisitiria. A verdade que
mesmo que essa tabela fosse criada em um LSN contemplado no backup (digamos o LSN 004), no
possvel fazer a restaurao, pois, a nica forma de garantir a consistncia passando por todos os LSNs
contemplados sem "pular" (ou melhor desconsiderar) etapas da histria do banco de dados. A verdade que
no momento em que se trunca o Log todo o processo de restaurao invalidado a partir do ltimo backup
de log antes do truncate (no caso aps o LSN 005 o banco no pode ser recuperado).
Observa-se que um simples comando de backup com a opo truncate_only inviabilizou parte do processo
de restaurao. Inegavelmente o truncate do log de transaes liberou espao e talvez tenha "resolvido o
problema do log de transaes grande demais". Sim, essa justamente a parte que todos conhecem e
esperam como resultado do comando. Se o Shrink for executado em seguida, a rea livre do arquivo de Log
ser devolvida ao Windows fazendo com que o arquivo seja efetivamente reduzido. O que maioria das
pessoas efetivamente no avalia ou simplesmente desconhece o efeito colateral desse comando. De fato ele
liberou espao, mas acabou de invalidar parte do processo de restaurao. Possivelmente o executor do
comando no ir descobrir isso aps truncar o log, mas sim em uma situao futura quando seu banco de
dados estiver com problemas e ele precisar restaurar um backup. Nesse hora ele encher o peito e falar a si
prprio (ou ao chefe se ele estiver prximo): "Tenho uma rotina de backups full e de Log e posso portanto
restaurar o backup em qualquer posio desejada". Mal sabe ele que aps rodar o inocente comando de
truncate do log sua rotina de backups de Log foi jogada no lixo. O problema que essa descoberta se dar
no momento em que o backup ser o mais imprescindvel possvel e infelizmente no ser possvel contar
com ele.
Dada as limitaes atuais do Spaces, no pude publicar nesse artigo um exemplo prtico. Eu o apresento
logo a seguir na parte II do artigo.
[ ]s,
Gustavo

Piores Prticas Utilizar o comando BACKUP LOG com a


opo WITH TRUNCATE_ONLY Parte II
https://gustavomaiaaguiar.wordpress.com/2009/08/01/piores-praticas-%e2%80%93-utilizar-o-comando-backup-log-
com-a-opcao-with-truncate_only-%e2%80%93-parte-ii/#comments

Publicado em 01/08/2009 | 36 Comentrios


Boa Noite Pessoal,
Dada as limitaes do Spaces (eu nem sabia que existiam) no espao do post, no pude colocar tudo em um
nico artigo sobre as consequncias do uso da opo TRUNCATE_ONLY para truncar e diminuir o tamanho
do Log. Aps explicar as teorias necessrias para o entendimento dessas consequncias na parte I do artigo,
apresento agora um exemplo prtico.
Um exemplo prtico
Para tornar prticos alguns dos conceitos apresentados aqui, vejamos um exemplo:
Cria um banco de dados
CREATE DATABASE SisMtr

Garante que o Recovery Model Full


ALTER DATABASE SisMtr SET RECOVERY FULL

Cria alguns objetos no banco de dados SisMtr


CREATE TABLE SisMtr.dbo.Disciplinas (
IDDisciplina INT, NomeDisciplina VARCHAR(100))

CREATE TABLE SisMtr.dbo.Cursos (


IDCurso INT, NomeCurso VARCHAR(80))
Faz um backup full da base
BACKUP DATABASE SisMtr TO DISK = C:\Temp\SisMtrFull.BAK

Verifica informaes do backup recm gravado


RESTORE HEADERONLY FROM DISK = C:\Temp\SisMtrFull.BAK

A exceo do ltimo comando, esse script no faz nada demais. Ele apenas cria um banco, duas tabelas e faz
um backup full. O ltimo comando l as informaes do cabealho do backup full e mostra algumas
informaes de LSN sobre esse backup. Existem vrias colunas, mas em especial duas merecem ateno:

FirstLSN LastLSN
22000000008400155 22000000015000001
Possivelmente os LSNs exibidos no sero os mesmos obtidos, pois, a sua numerao depende de vrias
caractersticas prprias de cada instncia, bancos de dados criados, etc. A coluna FirstLSN mostra o LSN
mais antigo encontrado no backup (22000000008400155) e o mais recente (22000000015000001). As
transaes que esto contempladas no backup full (juntamente com os dados), so todas as que ocorreram
entre os LSNs 22000000008400155 e 22000000015000001.
Seguindo com o exemplo, sero realizadas algumas inseres nessas tabelas e ser realizado um backup de
log.
Insere registros nas tabelas de Disciplinas e Cursos
INSERT INTO SisMtr.dbo.Disciplinas VALUES (1,Histria e Formao do Direito)
INSERT INTO SisMtr.dbo.Disciplinas VALUES (2,Introduo Economia)
INSERT INTO SisMtr.dbo.Disciplinas VALUES (3,Administrao Contempornea)
INSERT INTO SisMtr.dbo.Disciplinas VALUES (4,tica)
INSERT INTO SisMtr.dbo.Disciplinas VALUES (5,Metodologia Cientfica)

INSERT INTO SisMtr.dbo.Cursos VALUES (1,Direito)


INSERT INTO SisMtr.dbo.Cursos VALUES (2,Economia)

Faz um backup de Log


BACKUP LOG SisMtr TO DISK = C:\Temp\SisMtrLog01.TRN

Verifica as informaes do backup de Log


RESTORE HEADERONLY FROM DISK = C:\Temp\SisMtrLog01.TRN

O comando de RESTORE mostra as seguintes informaes:

FirstLSN LastLSN
22000000008400155 22000000016900001
A coluna FirstLSN mostra que o primeiro LSN contemplado no backup de log 22000000008400155. A
coluna LastLSN mostra que o ltimo LSN contemplado 22000000016900001. Isso significa que esse
backup de Log contempla todas as transaes ocorridas entre os LSNs 22000000008400155 e
22000000016900001. Pode parecer estranho, pois, o backup full contemplava as transaes entre o LSN
22000000008400155 e o LSN 22000000015000001 e o de Log de transaes tambm contempla essas
transaes j que se inicia no LSN 22000000008400155 e termina no LSN 22000000016900001 que
superior ao LSN 22000000015000001 (LastLSN) do backup full. Isso esperado porque esse foi o primeiro
backup de log de transaes e todo o contedo do arquivo do Log de transaes foi "despejado" para o
backup de Log.
Cria uma tabela Associativa
CREATE TABLE SisMtr.dbo.DisciplinaCurso (
IDDisciplina INT, IDCurso INT)

Insere alguns registros na tabela recm criada


INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (1,1)
INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (2,1)
INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (4,1)
INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (5,1)
INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (2,2)
INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (3,2)
INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (4,2)
INSERT INTO SisMtr.dbo.DisciplinaCurso VALUES (5,2)

Faz um backup de Log


BACKUP LOG SisMtr TO DISK = C:\Temp\SisMtrLog02.TRN

Verifica as informaes do backup de Log


RESTORE HEADERONLY FROM DISK = C:\Temp\SisMtrLog02.TRN

O comando de RESTORE mostra as seguintes informaes:

FirstLSN LastLSN
22000000016900001 22000000018800001
O primeiro LSN contemplado no arquivo o LSN 22000000016900001 e o ltimo LSN contemplado o
22000000018800001. Isso significa que esse backup de Log contempla todos os LSNs entre
22000000016900001 e 22000000018800001. As sequncias de LSNs aps a realizao dos backups so
mostradas na tabela abaixo:

Backup Lsn Inicial Lsn Final


SisMtrFull 22000000008400155 22000000015000001
SisMtrLog01 22000000008400155 22000000016900001
SisMtrLog02 22000000016900001 22000000018800001
Com esses trs backups possvel "refazer" a histria do banco, pois, todas as transaes esto
contempladas e no h quebras nas sequncias de LSN. O script abaixo conta quantos registros existem em
cada uma das tabelas e faz a excluso do banco de dados:
Verifica quantos registros tem em cada tabela
SELECT
(SELECT COUNT(*) FROM SisMtr.dbo.Disciplinas) As Disciplinas,
(SELECT COUNT(*) FROM SisMtr.dbo.Cursos) As Cursos,
(SELECT COUNT(*) FROM SisMtr.dbo.DisciplinaCurso) As DisciplinaCurso

Efetua a excluso do Banco


DROP DATABASE SisMtr

A tabela Disciplinas tem 5 registros, a tabela Cursos tem 2 registros e a tabela DisciplinasCurso tem 8
registros. Ao final do processo de restaurao, esse mesmo resultado deve ser obtido.
Restaura o Backup Full
RESTORE DATABASE SisMtr FROM DISK = C:\Temp\SisMtrFull.BAK WITH NORECOVERY
Verifica o status dos arquivos de dados do banco
SELECT
DB_Name(Database_ID) As Banco, Name As ArquivoLogico,
Differential_Base_LSN As LSN_Inicial, Redo_Start_Lsn As LSN_Final
FROM sys.master_files
WHERE Database_ID = DB_ID(SisMtr) And Data_Space_Id > 0

Aps restaurar o backup full, verifica-se que os LSNs contemplados no banco so justamente os mesmos
obtidos pelo processo de restaurao:

Banco Arquivo LSN_Inicial LSN_Final


SisMtr SisMtr 22000000008400155 22000000015000001
O banco encontra-se indisponvel e em processo de restaurao. O prximo passo a aplicao do primeiro
Log.
Restaura o primeiro Log
RESTORE LOG SisMtr FROM DISK = C:\Temp\SisMtrLog01.TRN WITH NORECOVERY

Verifica o status dos arquivos de dados do banco


SELECT
DB_Name(Database_ID) As Banco, Name As ArquivoLogico,
Differential_Base_LSN As LSN_Inicial, Redo_Start_Lsn As LSN_Final
FROM sys.master_files
WHERE Database_ID = DB_ID(SisMtr) And Data_Space_Id > 0

Aps a restaurao do primeiro backup de Log, verifica-se que o banco parou no LSN final (Last LSN) do
backup de Log:

Banco Arquivo LSN_Inicial LSN_Final


SisMtr SisMtr 22000000008400155 22000000016900001
Embora o backup de Log tivesse as transaes anteriores ao LSN final do backup Full
(22000000015000001), apenas as transaes entre o LSN 22000000015000001 e o LSN
22000000016900001 foram aplicadas, pois, as anteriores j estavam contempladas no backup full. O banco
ainda est indisponvel e necessita da aplicao do segundo log.
Restaura o segundo Log
RESTORE LOG SisMtr FROM DISK = C:\Temp\SisMtrLog02.TRN WITH NORECOVERY

Verifica o status dos arquivos de dados do banco


SELECT
DB_Name(Database_ID) As Banco, Name As ArquivoLogico,
Differential_Base_LSN As LSN_Inicial, Redo_Start_Lsn As LSN_Final
FROM sys.master_files
WHERE Database_ID = DB_ID(SisMtr) And Data_Space_Id > 0

Aps a aplicao do segundo backup de Log, verifica-se que o banco parou no LSN final (Last LSN) do
backup de Log:

Banco Arquivo LSN_Inicial LSN_Final


SisMtr SisMtr 22000000008400155 22000000018800001
Embora o segundo Log tenha sido aplicado, o banco de dados ainda no encontra-se plenamente
operacional. O comando abaixo solicita ao SQL Server que o banco fique operacional.
Deixa o banco operacional
RESTORE LOG SisMtr WITH RECOVERY

Verifica o status dos arquivos de dados do banco


SELECT
DB_Name(Database_ID) As Banco, Name As ArquivoLogico,
Differential_Base_LSN As LSN_Inicial, Redo_Start_Lsn As LSN_Final
FROM sys.master_files
WHERE Database_ID = DB_ID(SisMtr) And Data_Space_Id > 0

Aps o banco de dados ficar OnLine e disponvel no possvel mais determinar qual o LSN final, pois,
nunca se sabe quando em qual LSN as transaes iro parar de ocorrer, pois, esperado que o banco de
dados no tenha nenhum tipo de problema que afete o seu funcionamento e que transaes futuras venham a
ser realizadas. Essa a razo pela qual o valor da coluna LSN_Final nula nesse caso. O objetivo foi
demonstrar que os backups foram aplicados e que os LSNs estavam sendo contemplados. O processo de
restaurao foi possvel porque as sequncias de LSNs estavam ntegras e refletidas no backup.
O exemplo prtico com o BACKUP LOG WITH TRUNCATE_ONLY
Como ser que o uso do truncate pode afetar o processo de backup ? Vou utilizar um outro exemplo para
simular o que costuma ocorrer em ambiente de produo quando esse comando utilizado.
Cria o banco de dados
CREATE DATABASE BDCargas ON (
NAME=BDCargas_Data, SIZE=10MB,
FILENAME=C:\Temp\BDCargas_Data.MDF)
LOG ON (
NAME=BDCargas_Log, SIZE=1MB,
FILENAME=C:\Temp\BDCargas_Log.LDF)

Muda o Recovery Model para Full


ALTER DATABASE BDCargas SET RECOVERY FULL

Verifica o tamanho dos arquivos


SELECT
DB_Name(Database_ID) As Banco, Name As ArquivoLogico,
Physical_Name As ArquivoFisico, (Size * 8) / 1024.00 As TamanhoMB
FROM sys.master_files WHERE Database_ID = DB_ID(BDCargas)

Realiza um Backup Full


BACKUP DATABASE BDCargas TO DISK = C:\Temp\BDCargasFull.BAK

Verifica as informaes do Backup Full


RESTORE HEADERONLY FROM DISK = C:\Temp\BDCargasFull.BAK

O script simplesmente cria um banco de dados chamado BDCargas, muda o Recovery Model para Full (caso
j no esteja) e verifica o tamanho dos arquivos utilizados respectivamente 10MB para dados e 1MB para
Log. As informaes do Backup Full em relao ao LSN so:

FirstLSN LastLSN
23000000005900037 23000000007700001
O prximo passo fazer com que o Log encha fazendo-se "necessrio" o comando de TRUNCATE. O script
abaixo cria uma tabela e efetua vrios Inserts e Deletes. O tamanho do arquivo de dados no ir se alterar,
pois, cada insero gera uma excluso, mas como as duas aes so logadas, o arquivo de log ficar muito
grande.
Cria uma tabela
CREATE TABLE BDCargas.dbo.Registros (
ID INT IDENTITY(1,1), Mascara UNIQUEIDENTIFIER DEFAULT NEWID())

Faz um backup de Log


BACKUP LOG BDCargas TO DISK = C:\Temp\BDCargasLog01.TRN

Insere e exclui 200.000 registros


DECLARE @i INT
SET @i = 1

WHILE @i <= 200000


BEGIN
INSERT INTO BDCargas.dbo.Registros DEFAULT VALUES
DELETE FROM BDCargas.dbo.Registros
SET @i = @i + 1
END

Verifica o tamanho dos arquivos


SELECT
DB_Name(Database_ID) As Banco, Name As ArquivoLogico,
Physical_Name As ArquivoFisico, (Size * 8) / 1024.00 As TamanhoMB
FROM sys.master_files WHERE Database_ID = DB_ID(BDCargas)
Aps aproximadamente cinco minutos, possvel notar que houve um aumento considervel do tamanho do
Log que passou de 1MB para pouco mais de 214MB conforme a tabela abaixo:

Banco ArquivoLogico ArquivoFisico TamanhoMB


C:\Temp\BDCargas_Data.
BDCargas BDCargas_Data 10.0000000
MDF
C:\Temp\BDCargas_Log.L
BDCargas BDCargas_Log 214.1250000
DF
No acho que 214MB seja um espao absurdo, mas para realmente mostrar os malefcios do truncate do log,
adicionei mais algumas transaes antes de truncar o log.
Insere dois registros
INSERT INTO BDCargas.dbo.Registros DEFAULT VALUES
INSERT INTO BDCargas.dbo.Registros DEFAULT VALUES

Trunca o Log
BACKUP LOG BDCargas WITH TRUNCATE_ONLY

Muda o contexto de banco de dados


USE BDCargas;

Diminui o tamanho do arquivo de LOG


DBCC SHRINKFILE(BDCargas_Log,1)
Verifica o tamanho dos arquivos
SELECT
DB_Name(Database_ID) As Banco, Name As ArquivoLogico,
Physical_Name As ArquivoFisico, (Size * 8) / 1024.00 As TamanhoMB
FROM sys.master_files WHERE Database_ID = DB_ID(BDCargas)

Muda o contexto de banco de dados


USE MASTER;

Aps executar o comando de truncagem e em seguida o Shrink notvel a diminuio do arquivo de Log de
214MB para o seu tamanho original:

Banco ArquivoLogico ArquivoFisico TamanhoMB


C:\Temp\BDCargas_Data.
BDCargas BDCargas_Data 10.0000000
MDF
C:\Temp\BDCargas_Log.L
BDCargas BDCargas_Log 1.0000000
DF
Aps as 200.000 linhas terem sido inseridas e excludas, o Log de transaes cresceu rapidamente. Para
diminu-lo, utilizou-se o comando de truncate em conjunto com o Shrink devolvendo-o ao tamanho original.
Antes do truncate haviam duas linhas que foram inseridas. Irei inserir mais trs linhas e prosseguirei com
um backup de Log e excluirei o banco de dados.
Insere trs registros
INSERT INTO BDCargas.dbo.Registros DEFAULT VALUES
INSERT INTO BDCargas.dbo.Registros DEFAULT VALUES
INSERT INTO BDCargas.dbo.Registros DEFAULT VALUES

Verifica os registros que esto na tabela


SELECT ID, Mascara FROM BDCargas.dbo.Registros

Faz um backup de Log


BACKUP LOG BDCargas TO DISK = C:\Temp\BDCargasLog02.TRN

Exclui o banco de dados


DROP DATABASE BDCargas

Antes de excluir o banco de dados, o SELECT mostrou que haviam cinco registros cadastrados com os
respectivos IDs 200.001, 200.002, 200.003, 200.004 e 200.005. Porm, ao tentar fazer um novo backup de
Log, o SQL Server advertiu uma mensagem de erro.
Msg 4214, Level 16, State 1, Line 1
BACKUP LOG cannot be performed because there is no current database backup.
Msg 3013, Level 16, State 1, Line 1

BACKUP LOG is terminating abnormally.

No foi possvel fazer o backup de Log, pois, ele est sem referncias. Como o log foi truncado entre o
ltimo backup de Log e a tentativa de um novo backup, transaes foram descartadas do Log sem terem
sido copiadas. Isso significa que embora esteja tudo certo com o banco, a estratgia de backups baseada em
Logs ficou inviabilizada, pois, houve uma quebra de sequncia. Uma forma de tornar a estratgia de Logs
possvel novamente a realizao de um novo backup full.
Efetua um novo Backup Full
BACKUP DATABASE BDCargas TO DISK = C:\Temp\BDCargasFull02.BAK
Efetua um novo Backup de Log
BACKUP LOG BDCargas TO DISK = C:\Temp\BDCargasLog02.TRN

At pode-se tirar um novo backup full para viabilizar os logs posteriores, mas o fato que algumas
possibilidades foram perdidas. A tabela abaixo mostra o resumo dos backups e seus LSNs.

Backup Lsn Inicial Lsn Final


BDCargasFull 23000000005900037 23000000007700001
BDCargasLog01 23000000005900037 23000000010400001
BDCargasFull02 183000000008600037 183000000010200001
BDCargasLog02 183000000008600037 183000000010800001
possvel restaurar o primeiro backup full e aplicar o primeiro backup de log ou restaurar o segundo
backup full e aplicar o segundo backup de log. As transaes entre o primeiro backup de log e o segundo
backup full no podem ser recuperadas por um processo de backup, pois, a truncagem do log fez com que
elas fossem perdidas e no pudessem ser copiadas. Se o DBA necessitar de restaurar o banco em algum
momento desse intervalo, ele no conseguir. Possivelmente se isso acontecer, ser uma demanda de
extrema importncia e o DBA descobrir que esse intervalo foi perdido somente quando for "tarde demais".
Se por um lado o truncate do log pode realmente liberar espao, por outro lado ele poder causar um grave
problema para o futuro. Utilizar o TRUNCATE_ONLY semelhante a plantar uma bomba relgio para
algum momento posterior. Pode ser que ela no exploda, pois, no necessariamente algum ir solicitar um
backup exatamente em um trecho no coberto, mas de qualquer forma, aqueles que o fazem com frequncia,
esto plantando no somente uma mas vrias bombas relgio e nesse caso as chances de alguma delas
explodir aumenta. Ser terrvel ter de dizer que no foi possvel restaurar um backup no porque o arquivo
corrompeu-se, porque a mdia foi roubada, etc mas simplesmente porque "utilizou-se um comando que no
se sabia as consequncias".
Alternativas para evitar o uso do BACKUP LOG com o TRUNCATE_ONLY
Acho que os benefcios e os malefcios desse comando j esto demonstrados. A regra geral bem simples:
"Se voc realmente necessita de restauraes em momentos especficos e (ou) depende dos backups de log,
a soluo ter uma rotina para fazer esses backups. Se eles forem feitos, o log no ir encher. Se voc
realmente no necessita de restauraes em momentos especficos e (ou) no depende dos backups de log,
simplesmente altere o Recovery Model para Simple, pois, nesse modelo, as entradas de log sero eliminadas
automaticamente dispensando a necessidade de truncar o log".
Ainda assim podem ocorrer situaes em que o log fuja ao controle. Um processo de carga mal planejado,
uma tentativa de invaso, uma falha no job de backups so algumas razes pelas quais um arquivo de log
pode crescer rapidamente e talvez no haja tempo de esperar que o backup de log seja concludo. Nesse
caso, pode ser tentador executar o TRUNCATE_ONLY, mas ainda assim essa deve ser a ltima alternativa e
no a primeira. Algumas solues paleativas que podem ser usadas.
Se houver mais arquivos no mesmo drive que o log cresceu, faa o backup de log dos arquivos
menores e execute um shrink. Isso deve dar algum tempo para que o log que estourou possa ser
copiado.
Se houver espao disponvel em outras unidades, considere efetuar um backup de log dividido em
vrios arquivos. Isso faz com que ele seja executado mais rapidamente.
Se houver espao disponvel em outra unidade, crie um segundo arquivo de log para que as
transaes sejam gravadas nesse arquivo enquanto o backup de log realizado.
Se realmente for imprescindvel fazer um truncate do log, lembre-se de fazer um backup full e (ou)
diferencial logo em seguida para que as perdas sejam menores. No esvazie o log e deixe por isso
mesmo, pois, quanto mais tempo o backup demorar a ser feito depois do truncate, maior ser o
perodo de no recuperao. Ao meu ver, se o profissional que trabalha com o banco tiver
conhecimento e o ambiente for organizado, o truncate_only passa a ser um comando completamente
dispensvel. Se algum precisa utiliz-lo porque houve falta de planejamento e organizao do
ambiente ou h falta de conhecimento daquele que o utiliza. Tive a chance de ver um ambiente com
mais de 600 bases em SQL Server de misso altamente crtica e simplesmente h mais de dois anos
que a equipe de DBAs sequer sentiu a necessidade de executar esse comando em ambiente de
produo. Problemas de espao em disco e Logs estourando aconteceram, mas foram contornados
com as solues corretas e no com o truncate do log. Acredito que se um ambiente desses consegue
viver sem o TRUNCATE_ONLY, qualquer um pode organizar-se para no utiliz-lo.
Alguns podem at considerar exagero, mas vale a pena lembrar que o SQL Server 2008 no aceita o uso do
BACKUP LOG com a opo WITH TRUNCATE_ONLY. No SQL Server 2008 necessrio mudar o
Recovery Model para Simple se o log necessitar ser truncado. Se o banco realmente no necessita dos
backups de Log, mudar o recovery model para Simple a soluo definitiva. A Microsoft tambm percebe
que esse comando completamente dispensvel e que no deve ser utilizado.
"We recommend that you never use NO_LOG or TRUNCATE_ONLY to manually truncate the transaction
log, because this breaks the log chain. Until the next full or differential database backup, the database is not
protected from media failure. Use manual log truncation in only very special circumstances, and create
backups of the data immediately"
Aqueles que tem problemas com o Log de transaes e ao procurar ajuda se depararam com o BACKUP
LOG WITH TRUNCATE_ONLY no devem simplesmente execut-lo, mas sim avaliar se ele realmente a
soluo. Aqueles que "aconselham" usar o BACKUP LOG WITH TRUNCATE_ONLY devem pensar
melhor antes de dar um conselho desses, pois, a vontade de ajudar pode acabar atrapalhando.
Quando algum aparecer gritando "Socorro meu log cresceu demais. Como fao para zer-lo ou diminuir o
Log ?", espero que haja questionamentos e no simplesmente "use o BACKUP LOG WITH
TRUNCATE_ONLY com o SHRINK que resolve".
[ ]s,
Gustavo
https://gustavomaiaaguiar.wordpress.com/2009/08/01/piores-praticas-%e2%80%93-utilizar-o-comando-
backup-log-com-a-opcao-with-truncate_only-%e2%80%93-parte-ii/#comments

Você também pode gostar