Escolar Documentos
Profissional Documentos
Cultura Documentos
MVTech |1
SQL Server: Além do Conceito
Blog Post Collection
MVTech |2
SQL Server: Além do Conceito
Blog Post Collection
MVTech |3
SQL Server: Além do Conceito
Blog Post Collection
MVTech |4
SQL Server: Além do Conceito
Blog Post Collection
MVTech |5
SQL Server: Além do Conceito
Blog Post Collection
MVTech |6
SQL Server: Além do Conceito
Blog Post Collection
Introdução
Estar envolvido em uma comunidade é sempre mais importante e proveitoso
de que viver de um modo isolado, seja nos âmbitos pessoais, profissionais e
quaisquer outros. A comunidade técnica de profissionais que trabalham com
produtos e ferramentas ligados à Plataforma de Dados da Microsoft é bem
atuante e unida, isso faz com que muito conteúdo seja gerado, seja com
vídeos, eventos, palestras, entrevistas e postagens em blogs.
SQL Server: Além do Conceito - Blog Post Collection" foi idealizado para
proporcionar uma experiência variada e com conteúdo idem, por isso
aprecie o conteúdo e se tiver alguma dúvida ou sugestão, fique à vontade
para entrar em contato direto com o autor, através do blog do mesmo que
está informado no interior desta publicação.
MVTech |7
SQL Server: Além do Conceito
Blog Post Collection
Boa Leitura,
Edvaldo Castro
MVTech |8
SQL Server: Além do Conceito
Blog Post Collection
Prefácio
A presente obra foi cuidadosamente produzida como fruto de diversos anos
de trabalho e conhecimento dos autores e corresponde a uma compilação
aprimorada de posts publicados por eles no decorrer dos últimos meses e
extensivamente testado como parte dos seus esforços em adquirir um
conhecimento avançado e aprofundado.
O material aqui apresentado tem como finalidade principal servir como base
de pesquisa para aqueles que têm interesse em entender sobre novas
funcionalidades e evoluir os seus conhecimentos. Neste livro, você verá
como o SQL Server 2014 utiliza funcionalidades como o Read Committed
Snapshot Isolation, Particionamento de Tabelas, Tuning no Sharepoint e SQL
Server, Importação de Dados com o Integration Services, Auditoria no SQL
Server, Erros de Instalação, Fragmentação do Transaction Log, uso de
Snapshots, Deadlocks, conversões e uso de tipos de dados de Datas,
Contadores de Performance e problemas de rede para entregar uma das
melhores ferramentas para a tomada de decisão e gerenciamento de bancos
de dados disponíveis no mercado.
MVTech |9
SQL Server: Além do Conceito
Blog Post Collection
Roberto Fonseca
M V T e c h | 10
SQL Server: Além do Conceito
Blog Post Collection
MVTech
O Minha Vida (http://www.minhavida.com.br) é uma empresa com um
grande propósito: melhorar a qualidade de vida da população. Queremos ser
capazes de despertar nas pessoas o cuidado com a sua própria saúde. E quando
falamos em saúde, nos referimos não só à prevenção ou ao tratamento de
doenças, mas também a pequenas mudanças de hábitos capazes de transformar
positivamente o dia a dia das pessoas.
M V T e c h | 11
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 12
SQL Server: Além do Conceito
Blog Post Collection
Sumário
EDVALDO CASTRO ............................................................................... 21
M V T e c h | 13
SQL Server: Além do Conceito
Blog Post Collection
DIEGO NOGARE................................................................................... 42
M V T e c h | 14
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 15
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 16
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 17
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 18
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 19
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 20
SQL Server: Além do Conceito
Blog Post Collection
Ed aldo Castro
www.edvaldocastro.com
Pelo fato de o SQL Server, diferente da maioria dos demais SGBDs, ter uma
interface amigável e bastante intuitiva, muitos dos DBAs do tipo supracitado,
ao executarem tarefas cotidianas e relativamente simples do dia-a-dia (tais
como: backup, restore, criação de base nova, etc), simplesmente se
acomodam e deixam de buscar conhecimento e entendimento a fundo do
funcionamento da ferramenta, de possíveis problemas e soluções para
poder atuar de forma mais rápida e efetiva.
Ainda que o Microsoft SQL Server ofereça uma interface super amigável e
fácil de trabalhar, uma boa forma de se livrar das armadilhas do vício na
interface gráficaà ueà fa ilita à uitoàaà idaàdoàDBá,à à o eça àaàolha à o oà
as coisas funcionam em background. Por exemplo, ao executar um backup
simples de uma base de dados via SSMS (SQL Server Management Studio),
M V T e c h | 21
SQL Server: Além do Conceito
Blog Post Collection
porque não gerar um script da execução deste backup e das próximas vezes
que se for executar um backup simples, fazê-lo via T-SQL apenas alterando o
script previamente gerado? Com o tempo, naturalmente este comando de
backup será memorizado e não haverá mais a necessidade da dependência
da interface para execuç oàdestaàati idade…
Além dos três fatores supracitados, existem outros diversos, porém não é a
intenção ficar enumerando o que considero melhor ou pior em cada um dos
meios de administração do SQL Server.
M V T e c h | 22
SQL Server: Além do Conceito
Blog Post Collection
Sinceramente, não tenho nada contra quem utiliza interface gráfica, desde
que o faça por preferência, e não por limitação de não saber fazer de outra
maneira. É fato que ninguém nasce sabendo, ou com Master degree em
nada, mas nunca é tarde para começar a co e àat asàdoàp ejuízo…
A intenção do texto realmente não foi em ser técnico, apenas externar algo
que penso com relação ao assunto que se faz presente nos meios
p ofissio ais…
Grande abraço,
Edvaldo Castro
http://edvaldocastro.com
M V T e c h | 23
SQL Server: Além do Conceito
Blog Post Collection
Acesse (https://msdn.microsoft.com/en-
us/library/ms189122(v=sql.105).aspx) para um overview nos Níveis de
Isolamento no SQL Server.
MUITO BOM
M V T e c h | 24
SQL Server: Além do Conceito
Blog Post Collection
C ENÁRIO 1
M V T e c h | 25
SQL Server: Além do Conceito
Blog Post Collection
Má“…
ádi io oà aisàu a…
M V T e c h | 26
SQL Server: Além do Conceito
Blog Post Collection
C ENÁRIO 2
O P ROBLEMA
João Castro, trabalhou por 10 anos na empresa referida, e um belo dia foi
chamado pelo RH que lhe agradeceu pelos serviços e o demitiu. Sabendo
João que a empresa tinha o programa de empréstimos e que o Depto
Financeiro era logo na sala ao lado, passou diretamente no financeiro e
pegou 20 mil reais que foi prontamente liberado. João acabava de ser
demitido e receber 20 mil reais em empréstimo, que não pagaria nunca, visto
que não teria mais vínculo com a empresa.
M V T e c h | 27
SQL Server: Além do Conceito
Blog Post Collection
Ainda assim, este não seria um empecilho para a habilitação do RCSI na base,
visto que é possível forçar com um HINT que a espera aconteça.
Foram criados Scripts para demonstração do caso citado que podem ser
baixados pelo endereço: http://edvaldocastro.com/rcsi-2/
M V T e c h | 28
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 29
SQL Server: Além do Conceito
Blog Post Collection
,(‘CANDIDO DUARTE’,‘S’)
–ALTERA O NÍVEL DE ISOLAMENTO PARA RCSI
USE master
ALTER DATABASE DEMO_RCSI SET READ_COMMITTED_S
NAPSHOT ON
–EXIBE DADOS DA TABELA PESSOA
SELECT * FROM TB_PESSOA
–
ID_PESSOA DATA_CONTRATACAO NOME_PESSOA
BOL_EMPREGADO
–1 2013-07-27 JOAO
CASTRO S
–2 2013-07-27 MANOEL
MAIA S
–3 2013-07-27 BENEDITO
LIMA N
–4 2013-07-27 MARIA
CASTRO N
–5 2013-07-27 CLEONTINA
OLIVEIRA S
–6 2013-07-27 CANDIDO
DUARTE S
–ALTERA NÍVEL DE ISOLAMENTO
–ALTER DATABASE DEMO_RCSI SET
READ_COMMITTED_SNAPSHOT ON
–ALTER DATABASE DEMO_RCSI SET
READ_COMMITTED_SNAPSHOT OFF
/*——————————————————————————*/
TRANSAÇÃO T1
–TRANSAÇÃO DE DEMISSÃO (T1)
–EXIBE INFORMAÇÃO SOBRE O NIVEL DE ISOLAMENTO
ATUAL
SELECT NAME
,CASE is_read_committed_snapshot_on
WHEN 1 THEN ‘ENABLED’
WHEN 0 THEN ‘DISABLED’
END AS ‘Read_Committed_Snapshot’
FROM
SYS.DATABASES
WHERE NAME = ‘DEMO_RCSI’
– PARA ALTERAR PARA O RCSI
–USE MASTER
–ALTER DATABASE DEMO_RCSI SET
M V T e c h | 30
SQL Server: Além do Conceito
Blog Post Collection
–ROLLBACK TRAN T1
–COMMIT TRAN T1
–ABRA A SEGUNDA TRANSAÇÃO EM UMA NOVA JANELA
(NEW QUERY)E FAÇA A OPERAÇÃO DE EMPRESTIMO
(T2)
/*——————————————————————————*/
TRANSAÇÃO T2
–TRANSAÇÃO DE EMPRÉSTIMO (T2)
—- GARANTIR QUE ESTEJA COM RCSI HABILITADO
–USE MASTER
–ALTER DATABASE DEMO_RCSI SET
READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK
IMMEDIATE
–GO
——————————————————————————————
–INICIO DA TRANSAÇÃO DE UPDATE
BEGIN TRAN T2
USE DEMO_RCSI
GO
INSERT INTO TB_EMPRESTIMO
SELECT ID_PESSOA, ‘20000’,‘S’
FROM TB_PESSOA P
WHERE NOME_PESSOA = ‘JOAO CASTRO’
COMMIT TRAN T2
——————————————————————————————
SELECT * FROM TB_EMPRESTIMO
SELECT * FROM TB_PESSOA
——————————————————————————————
M V T e c h | 31
SQL Server: Além do Conceito
Blog Post Collection
——————————————————————————————
–EXECUTE O COMMIT DA TRANSAÇÃO T1 E RODE
NOVAMENTE O RESULTADO. OBSERVER QUE HÁ ERRO
DE NEGÓCIO
–POIS FOI LIBERADO EMPRÉSTIMOI PARA UMA
PESSOA QUE NÃO ESTÁ EMPREGADA.
SELECT P.ID_PESSOA, P.NOME_PESSOA, E.VALOR_EM
PRESTIMO, P.BOL_EMPREGADO,E.LIBERACAO_EMPREST
IMO
FROM TB_EMPRESTIMO E
JOIN TB_PESSOA P
ON E.ID_PESSOA = P.ID_PESSOA
RESUMINDO:
M V T e c h | 32
SQL Server: Além do Conceito
Blog Post Collection
Pode resultar com algum erro negocial não esperado, caso não seja bem
mapeado.
CONCLUSÃO:
REFERÊNCIAS
http://msdn.microsoft.com/pt-br/library/ms173763.aspx
http://msdn.microsoft.com/en-us/library/tcbchxcb(v=VS.80).aspx
Grande abraço,
Edvaldo Castro
http://edvaldocastro.com
M V T e c h | 33
SQL Server: Além do Conceito
Blog Post Collection
M OTIVAÇÃO
R ISCOS E O PORTUNIDADES
M V T e c h | 34
SQL Server: Além do Conceito
Blog Post Collection
Q UANDO C OMEÇAR ?
P ESQUISE
M V T e c h | 35
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 36
SQL Server: Além do Conceito
Blog Post Collection
O ARTIGO TÉCNICO
D OCUMENTAÇÃO
Este tipo de artigo técnico visa dissertar sobre algum produto, feature ou
atividade, demonstrando sua finalidade sem se preocupar na apresentação
dos métodos ou passo a passo para implementação. Este tipo de artigo
técnico, geralmente é escrito quando são lançadas versões novas ou um
produto totalmente novo, com a finalidade principal de demonstrar tal
produto ou feature.
H OW T O ( S )
Artigos técnicos deste tipo, são como tutoriais onde normalmente é descrito
um passo a passo com detalhes de implementação, ativação ou quaisquer
alterações que objetivem o autor do artigo a criá-lo.
B ENCHMARKS E E XPERIÊNCIAS
M V T e c h | 37
SQL Server: Além do Conceito
Blog Post Collection
O ARTIGO TÉCNICO EM SI
E STRUTURA
Um artigo técnico (ou não) bem estruturado é muito importante, pois facilita
e contribui para que a leitura fique mais agradável e entendível. Se a ideia é
escrever muito, este tópico é especialmente importante, pois quanto maior
o texto, mais cansativa e desestimulante fica a leitura, caso a mesma não
esteja bem estruturada, sendo o inverso igualmente verdadeiro, quando
mais bem estruturado, melhor e mais agradável se torna a leitura do mesmo.
L INGUAGEM
P ÚBLICO A LVO
M V T e c h | 38
SQL Server: Além do Conceito
Blog Post Collection
GRAMÁTICA
M V T e c h | 39
SQL Server: Além do Conceito
Blog Post Collection
PRINCIPAIS PREOCUPAÇÕES
S EMPRE
Deixe claro que o texto é sua opinião, não uma verdade absoluta
N UNCA
P UBLICIDADE
Canais disponíveis
Blog Pessoal
Technet Wiki
M V T e c h | 40
SQL Server: Além do Conceito
Blog Post Collection
FAÇA BARULHO
CONCLUSÃO
Eu gostaria ainda de esclarecer que tudo o que foi escrito foi baseado em
minhas preocupações e minha opinião. De forma alguma é a representação
absoluta da verdade. Se você concorda, discorda ou tem algo a acrescer, será
uitoà e à i doà osà o e t ios….
Grande abraço,
Edvaldo Castro
http://edvaldocastro.com
M V T e c h | 41
SQL Server: Além do Conceito
Blog Post Collection
Diego Nogare
www.diegonogare.net
Partition Table
Particionamento de Tabelas
Fala galera, esses dias atrás estava fazendo uma apresentação sobre SQL
Server 2012 e surgiu uma dúvida de um dos participantes
sobre particionamento horizontal de tabelas. Decidi procurar alguns
materiais em português e não achei muitos, então resolvi dar minha
contribuição sobre esse assunto.
Esse script cria um banco que irá simular uma tabela de visitas de um museu,
imaginando que o museu foi inaugurado no dia 1º de Janeiro de 2012 e hoje
é dia 31 de Dezembro, totalizando neste 1 ano de atividades 1 milhão de
visitas. Com os próximos sub-capítulos vamos criar as partições, separar
esses dados e deixar cada agrupamento (visitas do mesmo mês) em uma
tabela específica. Depois podemos comparar os prós e contras desta técnica.
USE dbMuseu
GO
M V T e c h | 42
SQL Server: Além do Conceito
Blog Post Collection
Óti o,àago aà ueàj àte osà ossaà aseàpa aàsi ula …àVa osàe te de àoà ueà
é o particionamento!
M V T e c h | 43
SQL Server: Além do Conceito
Blog Post Collection
C ENÁRIOS /B ENEFÍCIOS
M V T e c h | 44
SQL Server: Além do Conceito
Blog Post Collection
histórico. Os dados quentes são os dados que você trabalha atualmente, por
exemplo, os dados do trimestre atual e os dados de histórico são os dados
dos trimestres passados. Se você separar os dados da sua tabela a cada 3
meses, você pode deixar os dados atuais em discos mais nobres do seu
storage (SSD) e os dados de histórico em outros discos menos nobres (SAS
ou SATA). Imagine a necessidade de consultar as vendas do ultimo ano, com
a tabela particionada, você faria isso sem ter nenhuma concorrencia com as
transações que estão acontecendo atualmente na tabela.
D EFINIÇÕES /T ERMINOLOGIAS
Desde o SQL Server 2005, quando criamos uma tabela e/ou índice no nosso
banco e não definimos onde ele será armazenado, ele fica no
filegroup default. Porém, podemos criar a tabela e/ou índice em um partition
scheme. O partition scheme faz um mapeamento de um ou mais filegroups,
mas para armazenar os dados nos arquivos físicos corretos (nos filegroups)
ele usa o partition function, que por sua vez, contém o algoritmo que
realmente identifica onde determinada linha será armazenada. A ordem
cronológica é mais ou menos assim:
M V T e c h | 45
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 46
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 47
SQL Server: Além do Conceito
Blog Post Collection
C RIANDO F ILEGROUP
M V T e c h | 48
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 49
SQL Server: Além do Conceito
Blog Post Collection
Vamos criar agora outros filegroups para o dbMuseu (criado no primeiro sub-
capitulo) para poder separar os dados da tabela tbVisitas e utilizar o
propósito destes capítulo, o Partition Table!
USE MASTER
GO
M V T e c h | 50
SQL Server: Além do Conceito
Blog Post Collection
USE dbMuseu
GO
sp_helpfilegroup
GO
M V T e c h | 51
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 52
SQL Server: Além do Conceito
Blog Post Collection
Devemos replicar esse ultimo código de Alter Table para todos os outros
Filegroups que precisamos criar, isso é: Fevereiro, Março, Abril …à
até Dezembro.
Para verificar que todos arquivos foram criados, outra alternativa é executar
o código T-SQL abaixo:
USE dbMuseu
GO
sp_helpfile
GO
M V T e c h | 53
SQL Server: Além do Conceito
Blog Post Collection
Veja o código abaixo como ficaria essa partition function com left.
CREATE PARTITION FUNCTION
QuebraPelaEsquerda(date)
AS
RANGE LEFT FOR VALUES ('20120630')
M V T e c h | 54
SQL Server: Além do Conceito
Blog Post Collection
Veja o código abaixo como ficaria essa partition function com right.
USE dbMuseu
GO
M V T e c h | 55
SQL Server: Além do Conceito
Blog Post Collection
em uma mesma partição, visto que não existe uma próxima partição que
encerra o range deste grupo iniciado em 1º de Dezembro.
M V T e c h | 56
SQL Server: Além do Conceito
Blog Post Collection
Por final, você precisa criar a tabela informando qual será o Partition
Scheme que irá controlar o armazenamento dos dados. No próximo sub-
capítulo vamos ver essa criação!
C RIANDO A TABELA
M V T e c h | 57
SQL Server: Além do Conceito
Blog Post Collection
Com isso, conseguimos separar em diversos Filegroups, que por sua vez
estão em discos separados, garantindo alta-performance nas consultas
realizadas nesta tabela.
M V T e c h | 58
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 59
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 60
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 61
SQL Server: Além do Conceito
Blog Post Collection
Caso alguém queira simular o processo que utilizei, segue abaixo a criação
do ambiente e a população das tabelas com menos dados. É claro que para
você simular a mesma coisa que fiz aqui, você precisa adaptar este código
abaixo para seu cenário.
/*******************************************/
/*********** CRIAÇÃO DO AMBIENTE ***********/
/*******************************************/
CREATE DATABASE ngrSolutionsDW
GO
USE ngrSolutionsDW
GO
/*******************************************/
/*********** LIMPEZA DO AMBIENTE ***********/
/*******************************************/
USE ngrSolutionsDW
GO
DROP SEQUENCE seq_Codigo
GO
DROP TABLE tabelaProducao
GO
DROP TABLE tabelaProducao_v2
GO
DROP PARTITION SCHEME ps_DataAtualizacao
GO
DROP PARTITION FUNCTION pf_DataAtualizacao
GO
/*******************************************/
/********** POPULAÇÃO DO AMBIENTE **********/
/*******************************************/
CREATE TABLE tabelaProducao(
id INT NOT NULL
, idOrigem INT NOT NULL
, nome VARCHAR(20) NOT NULL
M V T e c h | 62
SQL Server: Além do Conceito
Blog Post Collection
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-5, convert(datetime,
getdate())),
dateadd(month,-5, convert(datetime,
getdate())))
go 1000
M V T e c h | 63
SQL Server: Além do Conceito
Blog Post Collection
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-4, convert(datetime,
getdate())),
dateadd(month,-4, convert(datetime,
getdate())))
go 1000
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-3, convert(datetime,
getdate())),
dateadd(month,-3, convert(datetime,
getdate())))
go 1000
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-2, convert(datetime,
getdate())),
dateadd(month,-2, convert(datetime,
getdate())))
go 1000
M V T e c h | 64
SQL Server: Além do Conceito
Blog Post Collection
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-1, convert(datetime,
getdate())),
dateadd(month,-1, convert(datetime,
getdate())))
go 1000
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
go 500
/*******************************************/
/*********** DISABLE / REBUILD *************/
/*******************************************/
/************ CRIAÇÃO DO INDEX *************/
/*******************************************/
CREATE NONCLUSTERED COLUMNSTORE INDEX
[idx_csi_tabelaProducao]
ON tabelaProducao ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO
M V T e c h | 65
SQL Server: Além do Conceito
Blog Post Collection
/*******************************************/
/******** INSERIR NA TABELA DE PROD ********/
/*******************************************/
/* +1 em FEVEREIRO 2013 */
-- Forçar o erro por causa que a tabela está
com ColumnStore Index
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
/*******************************************/
/************ DISABLE / REBUILD ************/
/*******************************************/
ALTER INDEX idx_csi_tabelaProducao ON
tabelaProducao DISABLE
GO
/*******************************************/
/************ POPULAR A TABELA *************/
/*******************************************/
ALTER INDEX idx_csi_tabelaProducao ON
tabelaProducao DISABLE
GO
substring(convert(varchar(40),newid()),1,20),
M V T e c h | 66
SQL Server: Além do Conceito
Blog Post Collection
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-4, convert(datetime,
getdate())), getdate())
go 1000
/*******************************************/
/************** DROP / CREATE **************/
/*******************************************/
/************ CRIAÇÃO DO INDEX *************/
/*******************************************/
CREATE NONCLUSTERED COLUMNSTORE INDEX
[idx_csi_tabelaProducao]
ON tabelaProducao ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO
/*******************************************/
/******** INSERIR NA TABELA DE PROD ********/
/*******************************************/
/* +1 em FEVEREIRO 2013 */
-- Forçar o erro por causa que a tabela está
com ColumnStore Index
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
/*******************************************/
/************** DROP / CREATE **************/
/*******************************************/
DROP INDEX [idx_csi_tabelaProducao] ON
tabelaProducao
GO
M V T e c h | 67
SQL Server: Além do Conceito
Blog Post Collection
/*******************************************/
/************ POPULAR A TABELA *************/
/*******************************************/
DROP INDEX [idx_csi_tabelaProducao] ON
tabelaProducao
GO
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-4, convert(datetime,
getdate())), getdate())
go 1000
/*******************************************/
/************* PARTITION TABLE *************/
/*******************************************/
/********** CRIAÇÃO DAS PARTIÇÕES **********/
/*******************************************/
CREATE PARTITION FUNCTION
[pf_DataAtualizacao](date) AS RANGE RIGHT
FOR VALUES ('2012-09-01','2012-10-01','2012-
11-01',
'2012-12-01','2013-01-01','2013-
02-01','2013-03-01')
M V T e c h | 68
SQL Server: Além do Conceito
Blog Post Collection
GO
/*******************************************/
/************ CRIAÇÃO DOS INDEX ************/
/*******************************************/
CREATE CLUSTERED INDEX [idx_DataCodigo] ON
tabelaProducao(DataAtualizacao)
ON ps_DataAtualizacao(dataAtualizacao)
GO
/*******************************************/
/******** INSERIR NA TABELA DE PROD ********/
/*******************************************/
/* +1 em FEVEREIRO 2013 */
-- Forçar o erro por causa que a tabela está
com ColumnStore Index
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
/*******************************************/
/******** CRIAÇÃO DA SEGUNDA TABELA ********/
/*******************************************/
CREATE TABLE tabelaProducao_V2 (id INT NOT
NULL, idOrigem int NOT NULL,
M V T e c h | 69
SQL Server: Além do Conceito
Blog Post Collection
/*******************************************/
/************ CRIAÇÃO DOS INDEX ************/
/*******************************************/
CREATE CLUSTERED INDEX [idx_DataCodigo]
ON tabelaProducao_v2(DataAtualizacao) ON
[PRIMARY]
GO
/*******************************************/
/********* MOVIMENTAÇÃO DOS DADOS **********/
/*******************************************/
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao
GO
-- Movimenta os dados
ALTER TABLE tabelaProducao SWITCH PARTITION 7
TO tabelaProducao_v2
GO
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
M V T e c h | 70
SQL Server: Além do Conceito
Blog Post Collection
/* Fevereiro na TABELA 2 */
insert into tabelaProducao_V2(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
go 10
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao
GO
M V T e c h | 71
SQL Server: Além do Conceito
Blog Post Collection
GO
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao
GO
M V T e c h | 72
SQL Server: Além do Conceito
Blog Post Collection
De etrio Sil a
demetriosilva.wordpress.com
INTRODUÇÃO
Por padrão, este recurso é desabilitado e este artigo vai mostrar como
configurar e habilitar esta feature. Vale lembrar que o Developer Dashboard
não pode ser usado na Central Admin.
M V T e c h | 73
SQL Server: Além do Conceito
Blog Post Collection
C ONFIGURAÇÃO
1 – Noà e uài i ia ,àa aàaà o soleà “ha ePoi tà àMa age e tà“hell à
conforme figura 1
M V T e c h | 74
SQL Server: Além do Conceito
Blog Post Collection
Figura 2 – Script
$service =
[Microsoft.SharePoint.Administration.SPWebService]::ContentService
$dd = $service.DeveloperDashboardSettings
$dd.DisplayLevel = "On"
$dd.Update()
M V T e c h | 75
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 76
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 77
SQL Server: Além do Conceito
Blog Post Collection
à Estatísti asàág egadas à- Nela podemos ver o resumo das consultas SQL
executadas, exibindo o número de consultas, duração total das consultas,
etc.
M V T e c h | 78
SQL Server: Além do Conceito
Blog Post Collection
Figura 7 – ULS
Figura 8 – SQL
M V T e c h | 79
SQL Server: Além do Conceito
Blog Post Collection
Existem diversas outras abas no painel que mostram informações úteis. Para
mais informações acesse o link: http://technet.microsoft.com/pt-
br/library/jj219701(v=office.15).aspx.
CONCLUSÃO
M V T e c h | 80
SQL Server: Além do Conceito
Blog Post Collection
Esta é apenas uma das diversas maneiras que o SharePoint nos fornece para
analisar o ambiente e ajustar a performance da Farm.
M V T e c h | 81
SQL Server: Além do Conceito
Blog Post Collection
INTRODUÇÃO
R EQUISITOS
C OMO FUNCIONA
O acesso aos dados será realizado pela REST Interface, que permite acesso
M V T e c h | 82
SQL Server: Além do Conceito
Blog Post Collection
Para acessar os dados de uma lista específica, basta adicionar o nome da lista
no final da URL, deixando-a assim
http://palestras2013/_vti_bin/ListData.svc/Categorias/Categorias. Onde
Categorias é o nome da lista que foi importada da base
M V T e c h | 83
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 84
SQL Server: Além do Conceito
Blog Post Collection
Na tela seguinte, em Data Feed Url, informe a Url da lista que deseja acessar
via REST. Neste caso, http://palestras2013/_vti_bin/ListData.svc/Categorias.
A figura 5 ilustra o exemplo:
M V T e c h | 85
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 86
SQL Server: Além do Conceito
Blog Post Collection
dentro do PowerPivot.
Caso a Farm e o Site Collection que você esteja usando já tenha o PowerPivot
configurado, a importação da lista para o PowerPivot é ainda mais simples.
Basta selecionar a opção "Exportar como Feed de Dados" na lista desejada
conforme figura 8.
M V T e c h | 87
SQL Server: Além do Conceito
Blog Post Collection
Após clicar na opção Exportar como Feed de Dados selecione a opção "abrir"
que fica no fim da tela. Caso o tipo de extensão não esteja associado ao Excel,
selecione abrir com -> Excel.
M V T e c h | 88
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 89
SQL Server: Além do Conceito
Blog Post Collection
Por fim, acesse a guia PowerPivot e veja que o Data Model foi exportado para
o Excel.
M V T e c h | 90
SQL Server: Além do Conceito
Blog Post Collection
CONCLUSÃO
Este artigo mostra uma das muitas formas possíveis de gerar relatórios
usando os dados das listas do SharePoint. Após importar os dados, fica bem
fácil criar relatórios complexos e dinâmicos usando PowerPivot, Excel,
PowerView e PowerMap.
M V T e c h | 91
SQL Server: Além do Conceito
Blog Post Collection
Bem, vamos lá. Para realizar esta configuração nós precisamos configurar o
relay de e-mails no Windows Server através do IIS, usando SMTP Server:
M V T e c h | 92
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 93
SQL Server: Além do Conceito
Blog Post Collection
Deixe as demais opções com o valor padrão e clique em next até a aba final
onde tem a opção de instalar.
Após instalado, feche o Server Manager e abra o IIS 6.0: Menu iniciar / IIS /
Enter.
M V T e c h | 94
SQL Server: Além do Conceito
Blog Post Collection
Configure os PCs liberados para enviar e-mails através deste Relay. No meu
caso, liberei para todos da rede:
M V T e c h | 95
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 96
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 97
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 98
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 99
SQL Server: Além do Conceito
Blog Post Collection
Pronto. Após isso seu SharePoint está pronto para enviar e-mails de
notificações para listas, etc.
M V T e c h | 100
SQL Server: Além do Conceito
Blog Post Collection
Mar el I o e
4sqlserver.wordpress.com
Olá pessoal,
Para quem não conhece o Protheus é um dos maiores ERPs do mundo, ele é
desenvolvido pela empresa brasileira Totvs onde há alguns anos é líder de
mercado nacional. A grande vantagem do Protheus é que além dele ser bem
completo ele customizável, ou seja, você compra a licença do sistema e pode
contratar um desenvolvedor para customizá-lo a seu gosto, já imaginou isso?
Já pensou se você pudesse fazer isso com qualquer software que comprasse
ou utilizasse? Pois é, por aí dá para sentir o poder do produto e dá para
começar a perceber o porque ele é tão usado no mercado nacional, mas é
claro que nem tudo são flores e é obvio que esse produto tem seus pontos
fracos, algumas particularidades e é exatamente para discutir isso que
escrevi esse post.
V AMOS AS DICAS :
A aplicação não acessa o banco de dados diretamente ela usa uma camada
intermediária chamada Top Connect. O Top Connect quase sempre é
instalado no mesmo servidor que o banco de dados, porém há casos em que
ele é instalado em uma máquina exclusiva e então a aplicação se conecta ao
Top e o Top se conecta ao SQL Server;
M V T e c h | 101
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 102
SQL Server: Além do Conceito
Blog Post Collection
Não existe campo DateTime nas tabelas. Todos os campo data são
VARCHAR(8), nunca são nulos e são sempre preenchidos com 8 caracteres
em branco para informar que estão vazios;
Não existe campo NULL. Se o campo for numérico ele é preenchido com zero
e se for String/Char é preenchido com espaços em branco. Em ambos os
casos o preenchimento é feito via Constraint Default. Agora imaginem a
quantidade de Constraint que cada tabela tem!;
Muito cuidado ao criar índices nas tabelas, pois se você criar em uma terá
que criar em todas, por exemplo: Se criar um índice na tabela de cliente
SA1XX0 lembre-se de replicar esse índice para as demais tabelas de cliente
caso tenha;
Nunca crie um campo em uma tabela sem antes passar para o dicionário de
dados do Protheus, pois ao abrir uma tela que use a tabela onde o campo foi
criado, essa tela irá travar por não ter o campo no dicionário;
O desempenho das consultas não são grande coisa, pois a maioria dos
desenvolvedores Protheus não tem grandes habilidades e conhecimento
sobre indexação, então é sempre bom dar uma checada nas consultas mais
lentas e dar um help para a galera de desenvolvimento;
M V T e c h | 103
SQL Server: Além do Conceito
Blog Post Collection
Índices não usados e duplicados não é excessão e sim regra, então é válido
analisar isso e repassar para os desenvolvedores. Nunca apague um índice
sem antes apagar no dicionário, pois as telas fazem essa verificação também
em sua abertura e caso não encontre no banco elas travarão;
Não é possível fazer uma replicação merge das tabelas, devido fato da
replicação merge adicionar um campo de controle de unicidade chamado
rowguid e caso tenha um campo na tabela do banco e não tenha no
dicionário do Protheus isso causa sérios impactos. Mesmo que não houvesse
o impeditivo do campo rowguid, muitas tabelas ultrapassam 246 colunas e
seria impossível replicar com merge devido o limite de 246 colunas por
artigo;
Devido o padrão das tabelas do Protheus não terem campos NULL e todos
serem preenchidos com uma Constraint Default isso impede que as tabelas
sejam colocadas In-Memory a.k.a Hekaton que é o novo recurso do SQL
Server 2014. É possível desde que todas as Constraints Defaults sejam
excluídas e os campos que são Not Null passem a ser Null, porém isso
implicaria em uma grande mudança na modelagem do banco e os efeitos
colaterais nesse tipo de mudança são incontáveis;
Bom galera espero que essas dicas sejam úteis para todos. Conforme eu for
me lembrando de mais coisas eu vou atualizando o post.
M V T e c h | 104
SQL Server: Além do Conceito
Blog Post Collection
Mar os Fre ia
marcosfreccia.wordpress.com
Olá pessoal,
M V T e c h | 105
SQL Server: Além do Conceito
Blog Post Collection
Vo àde e àago aàa asta àoà o po e teà DataàFlo àTask ,àpoisà àde t oà
desse passo que vamos adicionar as fontes e destinos para realizar a cópia.
M V T e c h | 106
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 107
SQL Server: Além do Conceito
Blog Post Collection
ágo a,àdeàu àduploà li ueàe à OLEàDBàCo e tio àMa age àeà li ueàe à
New para criar a conexão com o banco de dados.
M V T e c h | 108
SQL Server: Além do Conceito
Blog Post Collection
Enquanto configura o destino dos seus dados, você tem a opção de escolher
uma tabela já existe, ou criar uma nova tabela para receber os dados a serem
importados. Neste exemplo vamos criar uma nova tabela.
M V T e c h | 109
SQL Server: Além do Conceito
Blog Post Collection
O pacote sendo executado com sucesso, você deverá ver isso no fluxo criado.
M V T e c h | 110
SQL Server: Além do Conceito
Blog Post Collection
Pronto, você já fez a sua primeira solução em SSIS. Agora basta você seguir
um tutorial de como agendar pacotes do SSIS no SQL Server Agent.
M V T e c h | 111
SQL Server: Além do Conceito
Blog Post Collection
Espero que tenham gostado e estarei montando mais tutoriais desse tipo
explicando pequenas funcionalidades.
M V T e c h | 112
SQL Server: Além do Conceito
Blog Post Collection
Olá pessoal,
O intuito dessa série de posts que vou iniciar agora é mostrar tudo de novo
que temos na parte de T-SQL no SQL Server 2012. Antes de iniciarmos é bom
deixar frisado que o intuito aqui não é mostrar nada mirabolante, mas sim o
SIMPLES! Então esqueçam de ver algo avançado, o que vocês irão ver aqui é
o básico.
Para não criar posts extensos que nos cansam de ler, vou fazê-lo por partes.
Hoje vamos falar de:
Sequence
Esse novo recurso surgiu no SQL Server 2012 como uma necessidade de
formatação de nossos conjuntos de dados, provenientes de uma stored
procedure. Então sua explicação e demonstração é bastante simples.
Pegamos um result set que está vindo como saída de uma procedure e
mostramos para o usuário da maneira que necessitamos através desse result
set personalizado.
M V T e c h | 113
SQL Server: Além do Conceito
Blog Post Collection
Como vemos aqui, podemos até trocar o tipo de dados que será retornado.
Vamos agora ver o resultado.
M V T e c h | 114
SQL Server: Além do Conceito
Blog Post Collection
Como podemos ver um recurso muito simples e que pode nos ajudar
bastante.
2) SEQUENCE
M V T e c h | 115
SQL Server: Além do Conceito
Blog Post Collection
temos o identity. Correto, porem o objeto Sequence vem para abrir mais
possibilidades de utilização e como a mesma é um objeto permite outros
tipos de gerenciamento que não temos no campo identity.
C OMO UTILIZAR ?
M V T e c h | 116
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 117
SQL Server: Além do Conceito
Blog Post Collection
R ESULTADO .
SELECT *
FROM Demo2
M V T e c h | 118
SQL Server: Além do Conceito
Blog Post Collection
Como puderam ver, a nossa sequence não deixou que realizássemos mais
inserções de dados no campo.
Bom pessoal por hoje era isso, espero que tenham gostado e no decorrer do
tempo estarei mostrando mais funcionalidades em T-SQL no SQL Server
2012.
M V T e c h | 119
SQL Server: Além do Conceito
Blog Post Collection
Olá pessoal,
Foi pensando nisso que no SQL Server 2012 foi implementado um novo
recurso juntamente a clausula Order By utilizando dois recursos de nome
OFFSET e FETCH.
Bom, vamos parar com a parte teórica e vamos demonstrar a parte pratica
dessa nova função.
USE master
GO
CREATE DATABASE DB_OrderByClause
GO
USE DB_OrderByClause
GO
CREATE TABLE tblPaginacao
(
id INT IDENTITY ,
M V T e c h | 120
SQL Server: Além do Conceito
Blog Post Collection
nome VARCHAR(100)
)
GO
INSERT INTO tblPaginacao
VALUES ( 'Registro 1' ),( 'Registro 2' ),
( 'Registro 3' ),( 'Registro 4' ),
( 'Registro 5' ),( 'Registro 6' ),
( 'Registro 7' ),( 'Registro 8' ),
( 'Registro 9' ),( 'Registro 10' ),
( 'Registro 11' ),( 'Registro 12' ),
( 'Registro 13' ),( 'Registro 14' ),
( 'Registro 15' ),( 'Registro 16' ),
( 'Registro 17' ),( 'Registro 18' ),
( 'Registro 19' ),( 'Registro 20' )
C ONSULTA 1
SELECT *
FROM tblPaginacao
ORDER BY id
OFFSET 5 ROWS
M V T e c h | 121
SQL Server: Além do Conceito
Blog Post Collection
C ONSULTA 2
SELECT *
FROM tblPaginacao
ORDER BY id
OFFSET 5 ROWS
FETCH NEXT 10 ROWS ONLY
M V T e c h | 122
SQL Server: Além do Conceito
Blog Post Collection
Bom pessoal como vocês puderam ver apenas duas demonstrações básicas
de como utilizar esse novo recurso no SQL Server 2012.
M V T e c h | 123
SQL Server: Além do Conceito
Blog Post Collection
I a Li a
www.ivanglima.com
Quando você pensa na memória do seu servidor, qual é a primeira coisa que
te vem à cabeça? Gigabytes? Terabytes? Enfim, espaço? E quando você
pensa em desempenho, a primeira coisa que você pensa são os Gigahertz da
CPU?
M V T e c h | 124
SQL Server: Além do Conceito
Blog Post Collection
C++ Herb Sutter escreveu o seu artigo homônimo em 2005 para o respeitado
jou alàD .àBo sà[ ].
M V T e c h | 125
SQL Server: Além do Conceito
Blog Post Collection
Intel CPU Trends 1970-2010. Fonte: The Free Lunch Is Over, Herb Sutter
Podemos observar na tabela acima que o desempenho geral do CPU continua subindo, mesmo que a
frequência esteja, de certa forma, estagnada. Medimos esse desempenho através de IPCs, ou Instructions
per Cycle.
Ou seja, em um processador de 2 GHz capaz de fazer o retirement de até 4 instruções por ciclo (IPC), como
é o caso da microarquitetura Nehalem, no caso ideal o seu desempenho pode chegar a 8 bilhões de
instruções por segundo! Nada mal.
M V T e c h | 126
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 127
SQL Server: Além do Conceito
Blog Post Collection
Então se o desempenho das CPUs efetivamente continua subindo (apesar de claramente em um ritmo
menor) mesmo que os clocks se mantenham estáveis, quem é o responsável por segurar o desempenho geral
dos sistemas?
‘efaze doàaàpe gu taàa te io àdeàout aàfo a…àE àu à o kloadào deàoàga galoà oàseàe o t aà e àe à
I/O nem na CPU, o que impede o seu processador de realizar o trabalho mais rapidamente?
Você provavelmente já deve ter matado a charada: no acesso à memória, ou o que chamamos de latência.
Mas esse fato não parece ser muito óbvio à primeira vista: memória não é só uma questão de quantidade.
putz...
A memória, porém, é o que previne que o seu sistema rode em seu desempenho máximo. Isso ocorre pois o
acesso à memória é significativamente inferior à velocidade do processador, e essa diferença só cresceu
ai daà aisà asàúlti asàd adas.àEsseàfe e oà à ha adoàdeà Memory Wall ,àte oà u hadoà oàpape à[ ].
Se pudéssemos trabalhar com dados apenas nos egist ado es,àaà e ia à o àaà e o àlat iaà oàCPU,à
o nosso processador poderia utilizar todo o seu potencial computacional. Infelizmente, principalmente em
servidores de bancos de dados, isso está muito longe da realidade. É comum trabalharmos com working sets
de dezenas ou centenas de GB. E por isso pagamos o custo de acesso à memória o tempo todo. Enquanto
esse acesso ocorre, o processador precisa ficar esperando pelos dados até que ele possa voltar a trabalhar,
efetivamente gastando ciclos de clock à toa. Um cache miss pode custar centenas de ciclos de clock do
processador, tempo que ele poderia gastar realizando operações ao invés de esperar por dados para serem
processados.
Com o fim da era de crescimento contínuo dos clocks dos processadores os engenheiros têm evoluído as
microarquiteturas a fim de amenizar o impacto da latência do acesso à memória principal do sistema. Os
processadores se utilizam de diversos artifícios para esconder essa latência, e assim diminuir a penalidade
causada pela disparidade entre o desempenho entre eles. Um deles é o Hyper-Threading (SMT), tópico de
um próximo artigo.
REFERÊNCIAS:
[1] Sutter – The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software
[2] Thompson – M th usti gà ode à ha d a eà toà gai à Me ha i alà “ path
[3] Moore – Data Processing in Exascale-class Computing Systems
[4] Wulf, McKee – Hitting the Memory Wall: Implications of the Obvious
M V T e c h | 128
SQL Server: Além do Conceito
Blog Post Collection
INTRODUÇÃO
Se você não viu a primeira parte da série, sugiro que leia antes de continuar, pois nessa parte vamos seguir
a linha de pensamento apresentado anteriormente.
P ROCESSADORES
Já que vamos falar sobre mecanismos internos das CPUs precisamos escolher alguma implementação, ou
microarquitetura específica como ponto de partida.
Escolhi a microarquitetura Nehalem [1] pelo simples fato de que tenho processadores baseados nessa
microarquitetura tanto nos servidores do ambiente onde trabalho quanto no meu notebook.
Apesar da Intel já ter lançado novas microarquiteturas desde então – Sandy Bridge, Ivy Bridge e o recém-
anunciado Haswell – as microarquiteturas Nehalem e Westmere são bastante comuns nos servidores que se
encontram em produção hoje.
O VERVIEW DA M ICROARQUITETURA
Nehalem foi uma microarquitetura particularmente importante em relação a tecnologias Intel. Foi nessa
microarquitetura que a Intel reintroduziu o hyper-threading ao seus processadores, após remover a
funcionalidade nos processadores baseados na microarquitetura Core. Outra tecnologia importante
introduzida pelo Nehalem foi o uso de um interconnect entre os processadores, similar ao que a AMD já
vinha oferecendo, para remover o gargalo do acesso à memória com o Front-Side Bus (FSB). Chamado
de QuickPath Interconnect (QPI), a Intel criou a tecnologia visando recuperar o mercado perdido para a AMD
durante o período.
Falaremos sobre o QPI no futuro, quando entrarmos no assunto de Non-Uniform Memory Access, ou NUMA.
M V T e c h | 129
SQL Server: Além do Conceito
Blog Post Collection
C ORE E U NCORE
Na terminologia dos designers e engenheiros de processadores, os processadores são divididos entre Cores
e Uncore.
Cores são desenhados como blocos reutilizáveis de lógica e hardware e não mudam entre um modelo e
outro.
O Uncore, por outro lado, são os componentes que não fazem parte do Core. Dependendo da literatura que
você ler isso inclui L3, I/O, IMC e QPI. Outros separam os componentes, portanto teríamos Uncore, QPI, IMC,
etc.
O Uncore pode mudar (e efetivamente muda) de um modelo para outro, mesmo entre modelos da mesma
microarquitetura.
P LANTA
Além disso, os Cores rodam em frequências e voltagens independentes entre si. O Uncore também roda em
uma frequência independente do restante dos cores. Nos slides da Intel, eles se referem ao Uncore e outros
componentes de forma distinta, mas ao se referirem à frequência e voltagem, chamam todos de Uncore
também.
M V T e c h | 130
SQL Server: Além do Conceito
Blog Post Collection
A diferença na frequência entre Cores e Uncore tem impacto direto no desempenho da máquina, através de
funcionaliades como Turbo Boost e SpeedStep.
Quando estiver abordando um assunto específico de cada modelo (uncore) darei preferência ao Xeon E7-
8870, o modelo com qual trabalho. Conhecido como Westmere-EX, este é o absoluto top de linha da Intel
em arquitetura x86 nesse ciclo de lançamentos.
X EON E7
M V T e c h | 131
SQL Server: Além do Conceito
Blog Post Collection
Note o aumento de cores na imagem do chip Westmere em relação ao Nehalem apresentado no início do
post. Se olhar atentamente, poderá perceber que se tratam dos mesmos cores, apenas replicados mais 2
vezes. É possível perceber também o aumento nos bancos de cache, abaixo dos cores.
C ORE I 5 460M
Já o meu notebook tem uma configuração bem mais modesta e é organizado de uma forma um pouco
diferente, apesar de ser baseado na mesma microarquitetura.
É um Intel Core i5 460M, codinome Arrendale, rodando a 2.53 GHz. Possui aproximadamente 382 milhões
de transístores divididos entre 2 cores e o LLC (aka L3) de 4 MB, porém somente 3 MB são habilitados para
esse modelo. A controladora de memória (IMC) e o gráfico ficam em outro chip no mesmo package,
interligados com o chip do processador através de uma interface QuickPath Interconnect. A controladora de
memória possui 2 canais DDR3 de 1.333 MHz e suportam DIMMs de até 8 GB.
Naài age àa ai oàpode osà isualiza àoà hipàdoàp o essado à ² àeàoà hipà No th idge àdeàap o . 177
milhões de transístores (114mm²) no mesmo package.
No diagrama de blocos podemos ver claramente a topologia entre o processador e o GPU, conectados por
uma interface QPI:
M V T e c h | 132
SQL Server: Além do Conceito
Blog Post Collection
M OORE S L AW
Como eu falei no artigo anterior o clock dos processadores parou de subir mas o desempenho dos cores
continua subindo, embora não no mesmo ritmo que subia anteriormente. Como isso é possível? Através da
lei de Moore.
Gordon Moore [4] é co-fundador da Intel, e a lei leva o seu nome pois ele foi o autor da frase que dizia que
o número de transistors em cada processador dobraria a cada 2 anos. Existem diversas versões e
interpretações das palavras ditas por Moore. Segue a frase original [5]:
Theà o ple it àfo à i i u à o po e tà ostsàhasài easedàatàaà ateàofà oughl àaàfa to àofàt oàpe à ea .à
Certainly over the short term this rate can be expected to continue, if not to increase. Over the longer term,
the rate of increase is a bit more uncertain, although there is no reason to believe it will not remain nearly
o sta tàfo àatàleastà à ea s.
A frase pode se encontrada no artigo escrito por Moore [14], mas sem entender a relação entre defeitos,
custo e integração na fabricação de chips a frase é difícil de ser digerida. Uma versão que gosto e que modifica
ao mínimo a frase foi publicada no Arstechnica, em 2008 [13]:
Theà u e àof transistors per chip that yields the minimum cost per transistor has increased at a rate of
oughl àaàfa to àofàt oàpe à ea .
Esse é o sentido original da frase, e a percepção do mercado de chips em geral nas últimas décadas. A frase
foi dita em 1965, e apesar de Moore ter previsto a continuidade por 10 anos, a lei continua em vigor até hoje.
M V T e c h | 133
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 134
SQL Server: Além do Conceito
Blog Post Collection
Essa quantidade extra de transístores é utilizada pelos engenheiros para aumentar a eficiência dos
processadores. Com cada ciclo de lançamentos, os processadores ficam mais e mais complexos.
Em alguns modelos Nehalem, por exemplo, quase 60% desses transístores são dedicados aos caches,
principalmente no cache L3 [12]. O restante é utilizado para adicionar mais lógica e mais funcionalidades,
aumentando assim a complexidade dos chips.
C OMPLEXIDADE
GPGPU
Uma forma alternativa de utilizar esses transístores seria a criação de núcleos pouco complexos, porém em
quantidades muito maiores do que vistos hoje, como por exemplo um processador com dezenas ou centenas
de cores.
Na verdade esse tipo de arquitetura existe e é muito utilizada. É encontrada em GPUs, que possuem centenas
de núcleos simples (em relação aos núcleos de uma CPU). Em geral, esses núcleos não servem para fazer o
processamento de qualquer tipo de código e operação e portanto não substituem os processadores comuns,
mas podem ser úteis para algoritmos onde é possível fazer paralelismo massivo do processamento. Existem
várias vertentes de desenvolvimento de dispositivos, linguagens e ferramentas para aproveitar melhor esses
recursos como o NVIDIA CUDA, OpenCL e mais recentemente o C++AMP da Microsoft, do qual já falei no
meu blog. Em (http://ivanglima.com/c-em-2012/)
C ACHE
Agora que já fizemos uma introdução básica às CPUs, no próximo artigo vamos nos aprofundar um pouco no
assunto dos caches.
REFERÊNCIAS
[1] http://en.wikipedia.org/wiki/Nehalem_(microarchitecture)
[2] http://en.wikipedia.org/wiki/Intel_Tick-Tock
M V T e c h | 135
SQL Server: Além do Conceito
Blog Post Collection
[3] http://forwardthinking.pcmag.com/pc-hardware/283044-intel-looks-ahead-nehalem-larrabee-and-atom
[4] http://en.wikipedia.org/wiki/Gordon_Moore
[5] http://e . ikipedia.o g/ iki/Moo e s_La
[6] http://www.xbitlabs.com/articles/cpu/display/core-i7-920-overclocking_3.html
[7] http://www.extremetech.com/extreme/133541-intels-64-core-champion-in-depth-on-xeon-phi
[8] http://sacan.biomed.drexel.edu/vldb2012/program/?volno=vol5no13&pid=1004&downloadpaper=1
[9] http://wiki.postgresql.org/images/6/65/Pgopencl.pdf
[10] http://asia.cnet.com/blogs/intel-invests-us7-billion-in-32nm-westmere-cpu-manufacturing-
62114335.htm
[11] http://www.intel.com/pressroom/kits/advancedtech/doodle/ref_HiK-MG/high-k.htm
[12] http://upcommons.upc.edu/e-prints/bitstream/2117/13932/1/hybrid_NUCA-hipc11.pdf
[13] http://arstechnica.com/gadgets/2008/09/moore/
[14] http://www.computerhistory.org/semiconductor/assets/media/classic-papers-
pdfs/Moore_1965_Article.pdf
M V T e c h | 136
SQL Server: Além do Conceito
Blog Post Collection
O principal fator que vai definir o impacto do HT no seu ambiente é o seu workload – tanto positivamente
quanto negativamente.
A própria Intel limita o ganho teórico do HT a 30% [1]. Isso é, no melhor do melhor dos casos, o máximo de
dese pe hoà ueà o à aià ga ha à o àHTà à %.àÉàpou o?àN oàa ho.àMasàoà ueàeuàa hoà à ueàHTà à uitasà
vezes confundido como uma funcionalidade de desempenho quando na realidade é uma funcionalidade que
visa melhorar a eficiência do seu processador. Ele vai utilizar alguns ciclos a mais que teriam sido perdidos
asoà oàhou esseàu à pipeli e àsu stitutoàp o toàpa aàe t a àe à e a.àN oàh àga ho,àeàsi à o t oleàdeà
pe da .
HT nada mais é do que a duplicação de alguns componentes do pipeline do núcleo, permitindo que esse, no
melhor caso, não pare totalmente de trabalhar quando houver uma dependência ainda não disponível
durante a execução, como um acesso de memória que resultou em cache miss, por exemplo.
Pipeline (SMT)
M V T e c h | 137
SQL Server: Além do Conceito
Blog Post Collection
T EORIA E PRÁTICA
Ok, mas saindo um pouco da teoria e indo para a parte prática, muitas coisas começam a influenciar na
brincadeira.
O próprio escalonamento do Windows (e de tabela o do SQL Server) afeta o desempenho do sistema com
o HT habilitado ou não. Por exemplo, se o algoritmo do scheduler não levar em conta o fato de dois
ú leosàl gi os à po àfaltaàdeà o eà elho à o pa tilha e àosà es osàáLUsàoàseuàdese pe hoà aià
piorar sensivelmente quando o scheduler escalonar duas threads no mesmo núcleo físico ao invés de
núcleos físicos distintos.
Esse cenário era muito comum nos primórdios do Windows Server [2], quando este não fazia distinção
entre núcleos físicos e lógicos. Ainda vemos algo parecido hoje nos processadores oriundos da
microarquitetura Bulldozer da AMD, que utiliza uma tecnologia que também afeta o comportamento do
pipeline, mas não é exatamente uma implementação do SMT. Os schedulers não estavam preparados
para lidar com isso durante o lançamento dos processadores dessa microarquitetura, fazendo a AMD
sofrer em alguns benchmarks [3].
Trocando em miúdos, existem muitos fatores e o impacto no desempenho final pode ser bem maior do
que os 30% teóricos, tanto positivamente quanto negativamente.
M ITO
Existe um mito que o Hyper-Threading é o mal encarnado para o SQL Server, devido a diversos fatores,
incluindo os citados acima. Um dos causadores (não intencional) desse rumor foi o Slava Oks [4] (ex-time
de produto, SQLOS), e se você quiser ver um ótimo exemplo de como fazer o HT não funcionar, sugiro que
leia o seu post e execute os testes você mesmo.
P ROCESSADORES
Observando o processo do SQL Server (sqlservr.exe) podemos notar que ele possui callstacks bastante
profundas, de pelo menos uns 8 níveis desde o início do processamento de uma consulta, e muitos
branches ao longo da execução dessa consulta, mesmo simples. Servidores OLTP, em geral, costumam ter
um working set de GBs de dados em memória e processar pequenas partes dessa massa à cada segundo,
de fo aà aleat ia .àNaàteo iaà[ ],àessesàtiposàdeà e iosàs oàe ele tesà a didatosàaàfaze àu à o àusoà
do SMT e também são bastante influenciados pelo tamanho dos caches do processador, a latência de
acesso da sua memória RAM e a eficiência do branch predictor. Esses fatores podem até mesmo
i flue ia à aisà ueà oà p p ioà lo kà doà seuà p o essado …à Nadaà deà o p a à p o essado esà olha doà
apenas os GHz!
M V T e c h | 138
SQL Server: Além do Conceito
Blog Post Collection
Wo kloadsàdeàOLáPàeàapli aç esà ie tífi asà,àpo àout oàlado,àte de àaàse à aisàse sí eisà à fo çaà uta à
do processador.
E fi …àNoàfi alàdasà o tas,àaàú i aà oisaà ueà aiàteàdize àseàoàHTàpodeàouà oà e efi ia àoàseuàa ie teà
é o teste. São fatores demais que influenciam no resultado final para fazer uma previsão para qualquer
direção. Se você tiver um processador com HT, teste seu workload com e sem o HT habilitado e colete
métricas que te dirão qual é preferível.
No caso do seu processador não possuir a funcionalidade, só posso dizer que não se preocupe com isso.
Há formas mais práticas e diretas de influenciar o desempenho do seu ambiente.
REFERÊNCIAS:
[1] http://en.wikipedia.org/wiki/Simultaneous_multithreading#Modern_commercial_implementations
[2] http://www.hardwaresecrets.com/article/Activating-the-Hyper-Threading/20
[3] http://www.hardwarecanucks.com/news/cpu/microsoft-tries-again-second-win-7-bulldozer-hotfix-
now-available/
[4] http://blogs.msdn.com/b/slavao/archive/2005/11/12/492119.aspx
[5] http://www.cs.washington.edu/research/smt/papers/smtdatabase.pdf
M V T e c h | 139
SQL Server: Além do Conceito
Blog Post Collection
Fa ia o Ne es A ori
www.blogfabiano.com
INTRODUÇÃO
No al e teà oà oti izado à deà o sultasà oà o side aà ush à pla s à doisà ope ado esà seà u e à aoà
resultado de outros joins). Isso significa que o SQL pode não produzir bons planos para alguns tipos de
consultas. Hints (dicas), por si só também não irão fazer isso. Para tal otimização, uma mágica mais
poderosa é necessária.
Pessoal,àatual e teàestouàsof e doà o à euà o flitoàe iste ialàdeà oti izado àsu ks ,àdei aàeuàe pli a à
melhor.
Quando você começa a trabalhar e estudar muito sobre o otimizador de consultas do SQL Server (ou de
qualquer outro DB) você passa por vários conflitos existenciais, são eles:
Preciso aprender a ler um plano de execução (já não chama mais de desenhinhos)
M V T e c h | 140
SQL Server: Além do Conceito
Blog Post Collection
Estatísticas sucks!
Joins sucks!
Otimizador sucks!
...
Não sei o que esta acontecendo (pode ser apenas uma fase), mas ultimamente 60% das consultas em que
trabalho na otimização tem um plano de execução ruim. Ok, muitas vezes isso é culpa de um ser humano
eà oà doà oti izado ,àpo àe e plo,àoà DBáà es ue eu à deàatualiza àasàestatísti as,àouà oà dese ol edo à
escreveu algum non-sarg. Mas ainda assim temos os casos onde simplesmente a culpa é do otimizador,
consultas onde ele deveria gerar um plano mais eficiente.
Veja bem, eu não estou dizendo que isso é um problema ou bug do SQL Server, essa é uma limitação de
todos os otimizadores existentes no mercado, a quantidade de alternativas para a geração de um plano
pode ser tão grande que fica completamente impossível pro otimizador analisar todas as opções, eu
entendo bem isso.
O otimizador de consultas do SQL Server é baseado em framework chamado Cascades [2], e ele executa
u aàse ieàdeàe plo aç esàe àu aà o sultaàpa aàte ta àge a àu àpla oàdeàe e uç oà o àoàsufi ie te à
utilizando a menor quantidade de recursos possíveis e, no menor tempo possível. No SQL Server essas
e plo aç esàs oàdi ididasàe àfases,àeàu aàdessasàfasesà à o he idaà o oà heu isti àjoi à eo de ào deàoà
SQL tenta definir qual será a ordem inicial de execução dos joins. A grande dificuldade no processo de
otimização de uma consulta é fazer isso na menor tempo possível, ou seja, preferencialmente o
otimizador nunca pode levar mais tempo para otimizar uma consulta do que irá gastar para executar o
plano. Isso pode parecer trivial, mas a quantidade de permutações possíveis para acessar uma consulta
com 12 joins seria de aproximadamente 479 milhões e considerando bushy plans teríamos uma variação
de 28 trilhões, ou seja, não da pra testar todas as possibilidades para qual é o melhor plano [5].
Dito isso, que fique claro que com este artigo não quero mostrar o quão ineficiente o otimizador de
o sultasàdoà“QLà“e e à ,àouàoà ua toàeleà su ks ,à asà ue oà ost a à ueà oà u doàoti izaç oàdeà
consultas, as coisas são sempre mais complicadas do que parecem .
Há muitos anos eu tento criar um exemplo prático para falar sobre bushy plans (veja referencias no fim
do artigo) no SQL Server. Em poucas palavras um bushy plan é uma das opções que o Otimizador tem para
poder executar os joins de sua consulta. Para efetuar uma operação de join o otimizador considera
algumas variações de execução de acesso as tabela e ordem de execução dos joins, essa ordem pode
seguir um left-deep (onde o resultado do join é utilizado como outer input para o próximo join) ou right-
M V T e c h | 141
SQL Server: Além do Conceito
Blog Post Collection
deep (onde o resultado do join é utilizado como inner input para o próximo join), ou um misto entre eles.
(veja a imagem abaixo para visualizar o que estou querendo dizer)
Atualmente o otimizador de consultas do SQL Server valida as opções que mencionei acima, porem existe
outra possibilidade de ordem de leituras das tabelas que não é considerada por default, o bushy trees.
Bushy trees podem ser interessantes em cenários em que o resultado de um join resulta em um filtro
considerável do resultset do join, ou seja, você lê várias linhas, mas depois de fazer o join poucas são
retornadas. Um bushy plan (um plano com uma bushy tree) é um plano que faz o join com base no
resultado de outros dois joins. Deixa eu tentar ilustrar para ver se fica mais claro:
SELECT *
FROM A
JOIN B ON A.ID = B.ID
JOIN C ON A.ID = C.ID
JOIN D ON A.ID = D.ID
A primeira árvore de joins contém um join em formato left-deep que executa os joins na seguinte ordem:
E a segunda árvore de joins contém o join em formato bushy que executa os joins na seguinte ordem:
O otimizador do SQL Server não avalia a possibilidade de bushy trees porque ela poderia gerar milhões de
possibilidades na ordem de execução dos joins, portanto para forçar a execução de um bushy plan no SQL
M V T e c h | 142
SQL Server: Além do Conceito
Blog Post Collection
Server temos 2 opções, usando CTEs (que eu prefiro) ou com uma sintaxe pouco convencional pra fazer
os joins, e ambas devem utilizar o hint FORCE ORDER.
Pois bem agora que você entendeu um pouco sobre bushy plans, deixa eu te mostrar um exemplo prático
de otimização que podemos ter. Suponha o seguinte cenário no banco Northwind, para criar este banco
utilize o meu script do skydrive: http://sdrv.ms/VaTL6W
Antes de começar os testes, vamos cadastrar um cliente novo e uma nova venda para este cliente:
E seguinte consulta:
-- Gerar "cold cache"
CHECKPOINT; DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;
GO
SELECT OrdersBig.OrderID,
OrdersBig.Value,
Order_DetailsBig.Quantity,
CustomersBig.ContactName,
ProductsBig.ProductName
M V T e c h | 143
SQL Server: Além do Conceito
Blog Post Collection
FROM OrdersBig
INNER JOIN CustomersBig
ON OrdersBig.CustomerID = CustomersBig.CustomerID
INNER JOIN Order_DetailsBig
ON OrdersBig.OrderID = Order_DetailsBig.OrderID
INNER JOIN ProductsBig
ON Order_DetailsBig.ProductID = ProductsBig.ProductID
WHERE CustomersBig.ContactName = 'Fabiano Amorim'
AND ProductsBig.ProductName = 'Outback Lager 1EA81379'
GO
A performance é a seguinte:
STATISTICS IO:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0
Table 'OrdersBig'. Scan count 0, logical reads 11776, physical reads 1, read-ahead reads 11576
M V T e c h | 144
SQL Server: Além do Conceito
Blog Post Collection
Table 'Order_DetailsBig'. Scan count 1, logical reads 10, physical reads 1, read-ahead reads 14
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Temos alguns problemas com relação a este plano, o primeiro e mais interessante é que por causa da
ordem que os joins serão efetuados o seek na tabela OrdersBig será executado centenas de vezes, mais
precisamente 2344 vezes, pois esse é o número de linhas que são retornados do join entre ProductsBig e
Orde Details_Big.àPo àsa e osà ueàe isteàape asàu aà o de àpa aàoà lie teà Fa ia oàá o i ,àouà
seja, eu esperava apenas uma operação de seek.
Como em tempo de compilação do plano o SQL Server não sabe qual é o valor de CustomerID do cliente
Fa ia oàá o i àeleà oà o segueàfaze àaàesti ati aàutiliza doàaàestatísti aàpo àO de sBig.Custo e ID.à
Ficou confuso? Deixa eu te mostrar com um exemplo mais simples, imagine a seguinte consulta:
P LANO ESTIMADO :
‘epa eà ueàaàesti ati aàdeàli hasà ueàse oà eto adasàap sàoàseekàpeloà Fa ia oàá o i à àdeà àli ha,à
porém ao consultar a tabela de OrdersBig ele estima que 1250000.00 (um milhão duzentos e cinquenta)
linhas serão retornadas, crazy ha? Pois este é um problema bem conhecido no mundo dos otimizadores,
M V T e c h | 145
SQL Server: Além do Conceito
Blog Post Collection
em tempo de compilação da consulta o SQL Server não sabe qual é o valor que será retornado de
CustomersBig.Contact_ID e por isso ele não consegue estimar corretamente, dai o que ele fez? Adivinha?
Chutou que 30% da tabela será retornada, neste caso como a tabela tem 5 milhões de linhas, ele estimou
um milhão duzentos e cinquenta linhas. Multi-Column Cross-Table Statistics ajudariam e muito neste
cenário, mas ainda não temos isso no SQL Server. Outra forma de resolver isso seria criar uma estatística
filtrada, mas isso não vem ao caso, fica pra outro post.
UPDATE: O SQL não chutou não, ele usou a densidade para obter o valor com base na quantidade média
de linhas duplicadas na distribuição dos dados. Deixe-me explicar melhor.
sp_helpstats OrdersBig
Na tabela OrdersBig temos uma estatística criada automaticamente pelo SQL Server, ou seja, ela foi criada
como uma distribuição de exemplo dos dados na tabela (WITH SAMPLE). Vamos rodar um DBCC
SHOW_STATISTICS para ver mais informações sobre ela:
Para fazer a estimativa o SQL Server usa essa informação da densidade, ele estimou o seguinte, ele faz
densidade * número de linhas da tabela, ou seja, 0.25 * 5000000 = 1250000, tai o valor estimado,
coincidentemente esse valor é 30% da tabela o que me levou a acreditar nos 30% (my bad).
M V T e c h | 146
SQL Server: Além do Conceito
Blog Post Collection
Na verdade a densidade da tabela é de 0.2 e não 0.25, se você atualizar a estatística com fullscan vera que
o valor vai mudar, e consequentemente a quantidade de linhas estimadas será de 0.2000 * 5000000, ou
seja, 100000 linhas.
Bom voltando ao plano que estamos analisando, por que o SQL Server estimou que 1.250000 linhas seriam
retornadas ele optou por não fazer o Join de CustomersBig + OrdersBig e isso está errado, sabemos que
apenas 1 linha será retornada ele deveria ter feito o seek em CustomersBig e apenas 1 seek em OrdersBig.
O mesmo se aplica para o join entre ProductsBig e Order_DetailsBig, porém neste caso o SQL estimou
utilizando a densidade da coluna Order_DetailsBig.ProductID, dai os 2328 estimados (veja no plano
estimado da consulta completa), só pra confirmar:
-- Calculando densidade
SELECT (1.0 / COUNT(DISTINCT ProductID)) FROM Order_DetailsBig
-- Calculando estimativa com base na densidade
SELECT ROUND(0.000465549348 * 5000000, 0)
Temos:
Neste caso estimar utilizando a densidade foi excelente, pois o número de linhas retornadas foi de 2344,
ou seja, bem próximo do estimado que foi de 2328.
A Fabiano, mas e o Bushy plan? Calma ai, vamos lá, sabendo que o Join entre CustomersBig + OrdersBig
irá retornar 1 linha, e o join entre ProductsBig + Order_DetailsBig irá retornar 2344 linhas, podemos forçar
a execução da seguinte ordem dos joins JOIN(JOIN(CustomersBig, OrdersBig), JOIN(ProductsBig,
Order_DetailsBig)), vamos testar utilizando CTEs:
M V T e c h | 147
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 148
SQL Server: Além do Conceito
Blog Post Collection
Como você pode observar, escrevendo as CTEs exatamente na ordem em que quero que os joins sejam
executados e utilizando o hint force order, conseguimos o plano que faz um merge join entre o resultado
dos dois joins.
A performance é a seguinte:
STATISTICS IO:
Table 'Order_DetailsBig'. Scan count 1, logical reads 10, physical reads 1, read-ahead reads 14
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Table 'OrdersBig'. Scan count 1, logical reads 4, physical reads 2, read-ahead reads 8
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
M V T e c h | 149
SQL Server: Além do Conceito
Blog Post Collection
A diferença é enorme, a consulta com o BushyPlan roda em meio segundo, isso é 24 vezes mais rápido
que a query original, porém essas duas operações de SORT (veja no plano) para fazer o Merge Join são de
assustar, SORT é uma das operações mais pesadas para fazer no banco de dados, principalmente se o
SORT for feito em disco. Para confirmar como esse sort é pesado, vamos fazer um teste utilizando um
CustomerName que retorna mais Orders e outro ProductName, ou seja, mais linhas serão ordenadas.
STATISTICS IO:
M V T e c h | 150
SQL Server: Além do Conceito
Blog Post Collection
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0
Table 'OrdersBig'. Scan count 0, logical reads 11702, physical reads 1, read-ahead reads 11664
Table 'Order_DetailsBig'. Scan count 1, logical reads 9, physical reads 2, read-ahead reads 6
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
M V T e c h | 151
SQL Server: Além do Conceito
Blog Post Collection
GO
STATISTICS IO:
Table 'Order_DetailsBig'. Scan count 1, logical reads 9, physical reads 2, read-ahead reads 6, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0, lob logical reads
0, lob physical reads 0, lob read-ahead reads 0.
Table 'OrdersBig'. Scan count 1, logical reads 5720, physical reads 4, read-ahead reads 5728, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0, lob logical reads
0, lob physical reads 0, lob read-ahead reads 0.
Ainda que o número de reads seja menor, o tempo foi de 13 segundos, contra 7 do plano sem bushy plan,
também podemos perceber que existe um sort warning no profiler, ou seja, a operação de sort foi escrita
em disco, provavelmente esse foi o motivo da performance ser tão ruim, o que podemos tentar fazer é
evitar esse SORT, como? Forçando o JOIN entre os resultados ser executado utilizando o algoritmo de
HASH JOIN, vejamos a diferença:
M V T e c h | 152
SQL Server: Além do Conceito
Blog Post Collection
ON OrdersBig.CustomerID = CustomersBig.CustomerID
),
JoinEntre_ProductsBig_e_Order_DetailsBig
AS
(
SELECT
Order_DetailsBig.OrderID,
Order_DetailsBig.Quantity,
ProductsBig.ProductName
FROM ProductsBig
INNER JOIN Order_DetailsBig
ON Order_DetailsBig.ProductID = ProductsBig.ProductID
)
SELECT JoinEntre_CustomersBig_e_OrdersBig.OrderID,
JoinEntre_CustomersBig_e_OrdersBig.Value,
JoinEntre_ProductsBig_e_Order_DetailsBig.Quantity,
JoinEntre_CustomersBig_e_OrdersBig.ContactName,
JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName
FROM JoinEntre_CustomersBig_e_OrdersBig
INNER HASH JOIN JoinEntre_ProductsBig_e_Order_DetailsBig
ON JoinEntre_CustomersBig_e_OrdersBig.OrderID =
JoinEntre_ProductsBig_e_Order_DetailsBig.OrderID
WHERE JoinEntre_CustomersBig_e_OrdersBig.ContactName = 'Karl
Jablonski 1E663869'
AND JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName =
'Ravioli Angelo D01AFCFC'
OPTION (FORCE ORDER, MAXDOP 1)
GO
Vejamos a performance:
STATISTICS IO:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0
Table 'Order_DetailsBig'. Scan count 1, logical reads 9, physical reads 2, read-ahead reads 6
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
M V T e c h | 153
SQL Server: Além do Conceito
Blog Post Collection
Table 'OrdersBig'. Scan count 1, logical reads 5720, physical reads 4, read-ahead reads 5728
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Repare que ainda que tenhamos a presença de um Hash Warning indicando que parte da operação de
hash utilizou tempdb (disco) ainda assim temos performance melhor que a consulta sem bushy join, neste
caso o tempo foi de de 4 segundos.
O que precisamos ter em mente é o seguinte, quanto menos linhas forem retornadas dos joins, melhor
será a performance do bushy plan, se você por exemplo utilizar um filtro de cliente ou produto que não
existe terá uma performance sensacional.
CONCLUSÃO
N OTA IMPORTANTE :
A demonstração acima é meramente ilustrativa, eu não estou dizendo pra você sair utilizando FORCE
ORCER ou qualquer outro hint em todas as consultas do seu ambiente, meu objetivo é te apresentar a
funcionalidade e dizer para usar com consciência, se não entendeu, não use, o efeito do mal uso dessa
técnica ou do uso de qualquer outro hint pode ser desastroso, portanto cuidado.
Bom é isso pessoal, o mundo otimização de consultas é enorme e muitas vezes consistem no processo de
tentativa e erro, porém conhecer bem as alternativas existentes e como o otimizador de consultas
funciona, nos ajuda a minimizar este processo árduo de tentar otimizar um plano.
Espero que você tenha chegado até aqui e gostado do artigo, trabalhei com conceitos importantes do
otimizador de consultas e saiba que nem sempre o resultado real é o que foi estimado.
That sàallàfolks.
REFERÊNCIAS:
ACM Paper: Left-deep vs. bushy trees: an analysis of strategy spaces and its implications for query
optimization
G. Graefe. The Cascades framework for query optimization. Data Engineering Bulletin, 18(3), 1995.
Wikipedia: http://en.wikipedia.org/wiki/Query_optimizer
M V T e c h | 154
SQL Server: Além do Conceito
Blog Post Collection
O PBM (Policy Based Management - Gerenciamento Baseado em Política) passou a ser utilizado a partir
da versão do SQL Server 2008, permitindo uma padronização das instâncias, uma vez que nas versões
anteriores, a mesma tinha que ser feita manualmente, ou seja, o BPM permite ao DBA ter o controle do
seu ambiente, aplicando as melhores práticas de organização e segurança, tornando mais fácil o seu
processo de manutenção.
Quando o servidor possui poucas instâncias, tudo bem, dá para o DBA administrar manualmente, mas e
quando são vários servidores e muitas instâncias em cada um deles? Já imaginou o trabalho que o DBA
tem para ter o controle?
Exemplo: se o DBA precisava criar uma rotina com as melhores práticas para saber quais bancos estavam
com o AutoShrink e AutoClose desabilitados, ele tinha quer ir manualmente, e olhar banco por banco nas
instâncias, ou criar scripts enormes para fazer tal verificação.
Através do PBM é possível verificar de imediato quais bancos em uma instância estão com o AutoShrink
e AutoClose desabilitados.
Facet - São o objeto básico sobre o qual os padrões são estabelecidos. Definem o tipo de objeto ou opção
a ser verificada, como banco de dados por exemplo.
Condition - São equivalentes a uma cláusula WHERE, que define os critérios que precisam ser verificados.
On Change: Prevent - Cria Triggers DDL, para impedir uma alteração que viole a diretiva.
On Change: Log Only - Verifica a diretiva automaticamente quando é feita uma alteração usando a
infraestrutura de notificação de evento.
On Schedule - Cria uma tarefa do SQL Server Agent para verificar a diretiva em um horário definido.
1 Hotek, Mike. Kit de treinamento MCTS(Exame 70-432): Microsoft SQL SERVER 2008: Implementação e
manutenção/ Mike Hotek.
M V T e c h | 155
SQL Server: Além do Conceito
Blog Post Collection
Após entender os conceitos acima, segue abaixo o exemplo: implementar uma política de melhores
práticas para um banco ou vários bancos(AutoShrink e AutoClose desabilitados):
- Ao Expandir a aba Management, clique em cima de Condition com o botão direito do mouse, selecione
new condition:
Facet: escolha uma das facetas que deseja usar para criar a política(nesse caso, será a Database).
M V T e c h | 156
SQL Server: Além do Conceito
Blog Post Collection
clique com o botão direito do mouse em cima de policie, selecione new policie
M V T e c h | 157
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 158
SQL Server: Além do Conceito
Blog Post Collection
Selecionar Evaluate
M V T e c h | 159
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 160
SQL Server: Além do Conceito
Blog Post Collection
Existem várias opções das facets, basta escolher qual deseja e criar!
M V T e c h | 161
SQL Server: Além do Conceito
Blog Post Collection
INTRODUÇÃO
Tenho um ambiente com SQL Server 2008 instalado em um Windows Server 2008 R2 Service Pack 1 em
Cluster, ao executar ao procedure SP_READERRORLOG é exibida uma mensagem de erro Failed to open
loopback connection.
S INTOMA
C AUSA
Ao executar o SP_READERRORLOG o SQL Server abre uma conexão com o próprio servidor (loopback) e
neste momento o erro ocorria, para identificar o erro iniciei o ProcessMonitor que pode ser baixado no
site da Microsoft, e ao executar o sp_readerrorlog juntamente com o ProcessMonitor notei o erro abaixo
no ProcessMonitor.
M V T e c h | 162
SQL Server: Além do Conceito
Blog Post Collection
Observando minha estrutura de cluster, o SQL Server está tentando abrir uma conexão com o nome do
meu recurso de MSDTC.
Sabemos que o SP_READERRORLOG faz uma conexão no loopback, mas por algum motivo recebi uma
tentativa de conexão no nome do recurso de MSDTC (MSDTCP12) do meu cluster, ao observar as
dependências do serviço do SQL observei que o serviço SQL dependia do nome MSDTCP12.
S OLUÇÃO
M V T e c h | 163
SQL Server: Além do Conceito
Blog Post Collection
Remova a dependência de qualquer recurso name que não seja o nome de sua instância SQL (no meu
caso o nome do DTC)
L EITURAS ADICIONAIS
O Fabricio Catae tem um artigo com o mesmo erro, mas com origens
distintas http://blogs.msdn.com/b/fcatae/archive/2010/03/03/problema-the-system-detected-a-
possible-attempt-to-compromise-security-parte-1.aspx
M V T e c h | 164
SQL Server: Além do Conceito
Blog Post Collection
HelloàF ie ds…
Thisà eekàIàfa edàa ài te esti gàe o …àM àPFEàf ie dàále à‘osaà blog) helped me to fix this problem and
I àsha i gàthisàp o le à/àsolutio à e auseàità ightàhelpà ou.
A Windows 2012 R2 on cluster with 2 nodes and my goal was to setup a SQL Server 2008 in cluster.
The problem
Firstly, I must say that since Jul/14 SQL 2K8 is no longer supported, SQL2K8 is in Extended Support.
When SQL Server 2008 was released the eà as tàWi do sà ,àsoà “QLà “e e à asà adeà asedà o à
Wi do sà k ,à I à otà sa i gà thatà “QLà k à isà otà suppo tedà o à Wi do sà ,à “QLà isà suppo tedà o à
Windows 2012. but some functionality were made based on Win2K8.
During the installation of SQL2K8 on Win12 on the first node I faced this error message:
M V T e c h | 165
SQL Server: Além do Conceito
Blog Post Collection
I do have my Cluster on online status and working well and I ran the cluster validation successfully, but
du i gàtheà“QLàsetupàIà fa edà aà essageà e o àsa i gàthatà à setupà ould tà he kà à luste à service,
bellow we have part of the detail of the Report Setup Validation:
InstallFailoverClusterGlobalRules: SQL Server 2008 Setup configuration checks for rules group
I stallFailo e Cluste Glo al‘ules
M V T e c h | 166
SQL Server: Além do Conceito
Blog Post Collection
nodes. To
continue,
determine
why the
cluster is
not online
and rerun
Setup. Do
not rerun
the rule
because
the rule
cannot
detect a
cluster
environme
nt.
M V T e c h | 167
SQL Server: Além do Conceito
Blog Post Collection
failures report.
reported Refer to
in the KB953748
verificati or SQL
on Server
report. Books
Online for
more
informatio
n.
I also tried running the setup from the command line using the SKIP_RULES:
á dàIàgotàtheàsa eàe o …
Looking at the detail of the first error, the message sa sàthatàtheà“QLà ould tà e if àtheà luste àse i e,à
theà luste à asào li eà utàsetupà ould tàa essà à luste .
http://blogs.msdn.com/b/clustering/archive/2012/04/06/10291601.aspx
During the SQL Server 2008 installations the setup tries to check cluster service using a deprecated
feature!
Checking my cluster installations using the articles from Rob I have this:
Get-WindowsFeature RSAT-Cluster*
M V T e c h | 168
SQL Server: Além do Conceito
Blog Post Collection
These is the features installed by default when we install the Cluster Feature.
The Solution
We just need to enable the Failover Cluster Automation Server, to achieve this you just need to run the
PowerShell command bellow.
M V T e c h | 169
SQL Server: Além do Conceito
Blog Post Collection
‘ega ds….
M V T e c h | 170
SQL Server: Além do Conceito
Blog Post Collection
Olá amigos, há um tempo atrás enfrente o famoso problema SSPI atípico e sempre adiava este post, bom
finalmente tomei decidi escrever o artigo.
P ROBLEMA
Um usuário sempre conectou ao SQL Server sem problemas, mas um dia ao tentar conectar-se ao mesmo
serviço de SQL ele recebeu a seguinte mensagem:
Não houve nenhuma mudança por parte de infraestrutura e DBAs no servidor, o usuário simplesmente
não consegue conectar mais, e o mais intrigante é que outros usuários conseguem conectar-se e alguns
não.
Bom, na grande maioria das vezes o erro SSPI Context é gerado por falta de SPN em uma tentativa de
conexão via kerberos com o SQL Server e para resolver este problema basta criar o SPN.
M V T e c h | 171
SQL Server: Além do Conceito
Blog Post Collection
SETSPN –L <domínio\conta_de_serviço_do_SQL>
Nota: Se ao executar o comando setspn –L você não receber o SPN para a sua instância de SQL Server,
você deve criar o SPN e você está recebendo o erro de SSPI Context, possivelmente o seu problema será
resolvido com a criação manual do SPN com o seguinte comando:
Como podemos observar no resultado do SETSPN –L no meu ambiente eu tenho os SPNs corretamente
criados!
O que justifica algumas conexões conseguirem conectar-se, pois o SPN está ok, e então por que algumas
conexões recebem o SSPI?
Para responder esta questão precisamos analisar o ticket do kerberos, executando a ferramenta tokensz
você poderá evidenciar o problema de token bloat com a seguinte sintaxe
M V T e c h | 172
SQL Server: Além do Conceito
Blog Post Collection
Como podemos notar na imagem acima, o tamanho máximo do Token é 12000 (12K) e o token do usuário
contoso\usuarioSQL que estou tentando conectar-se ao SQL e estou recebendo o erro SSPI contexto
ultrapassou o limite me 67 Bytes
Pois bem, se em um token temos a ACL (Access control List) vamos investigar os usuários criados:
M V T e c h | 173
SQL Server: Além do Conceito
Blog Post Collection
Os dois usuários são membros do grupo SQLacesso o qual foi criado o login no SQL Server, mas o segundo
usuário é membro de mais algumas centenas de grupos.
Até o Windows 2008 R2 o tamanho máximo default de um token é de 12K a partir do Windows 2012 este
valor foi alterado para 48K
Dependendo do tamanho de seu ambiente este limite de 12K é facilmente alcançado com um usuário
pertencendo a aproximadamente 150 grupos.
Em uma empresa multinacional onde como boa prática são criados diversos grupos para controlar acessos
a diversos compartilhamentos, servidores, aplicações etc. este limite é alcançado muito rapidamente.
Onde:
Existem diversos scripts que automatizam este cálculo, abaixo um bem simples que encontrei no artigo
http://www.cluberti.com/blog/2014/05/26/getting-kerberos-token-size-with-powershell/
# http://jacob.ludriks.com/getting-kerberos-token-size-with-powershell/
M V T e c h | 174
SQL Server: Além do Conceito
Blog Post Collection
#Reference: http://support.microsoft.com/kb/327825
Param(
[Parameter(Mandatory=$True)]
[String]$Username
$domain = ($username.split("\"))[0]
$user = ($username.split("\"))[1]
Import-Module ActiveDirectory
Write-Host "
M V T e c h | 175
SQL Server: Além do Conceito
Blog Post Collection
http://www.jhouseconsulting.com/2013/12/20/script-to-create-a-kerberos-token-size-report-1041
https://gallery.technet.microsoft.com/scriptcenter/Check-for-MaxTokenSize-520e51e5
C OMO R ESOLVER
Você tem duas maneiras de resolver o problema, aumentando o default do token size ou excluindo grupos
desnecessários.
E M CADA ESTAÇÃO :
Inicie Regedt32.exe
Nome: MaxTokenSize
tipo: REG_DWORD
Base: Decimal
Valor: 48000
M V T e c h | 176
SQL Server: Além do Conceito
Blog Post Collection
LEITURAS ADICIONAIS
http://support.microsoft.com/kb/938118
http://blogs.technet.com/b/shanecothran/archive/2010/07/16/maxtokensize-and-kerberos-token-
bloat.aspx
http://support.microsoft.com/kb/327825/en-us
http://blogs.technet.com/b/askds/archive/2012/07/27/kerberos-errors-in-network-captures.aspx
http://blogs.technet.com/b/askds/archive/2007/11/02/what-s-in-a-token.aspx
http://support.microsoft.com/kb/327825/en-us
http://blogs.technet.com/b/askds/archive/2012/09/12/maxtokensize-and-windows-8-and-windows-
server-2012.aspx
M V T e c h | 177
SQL Server: Além do Conceito
Blog Post Collection
Ci elle Castro
cibellecastro.wordpress.com
Auditoria
Descobrindo Auditoria no SQL Server 2008
Abordaremos neste artigo a auditoria em banco de dados, no entanto, antes de falarmos sobre isso, pense
no que a palavra auditoria quer dizer para você. Onde você ouviu falar a primeira vez nessa palavra? Mas
porque todas essas perguntas? O objetivo delas é demonstrar que independente da área que a auditoria
seja implementada, todas desejam um mecanismo para ajudar a descobrir algo sobre alguém, alguma
coisa, alguma ação, nos mostrar que tentaram entrar no sistema, enfim dar segurança aos nossos dados.
QualàDBáà u aàseàdepa ouà o àaàsegui teàsituaç o:à áhhhhhhàalgu àti ouàasà i hasàpe iss es! àouà
Que oàsa e à ue àalte ouàaàsto edàp o edu eà ueàeuàfiz,àse a aàpassadaàelaàesta a fu io a do ,àouà
qualquer relação que necessitamos rastrear as alterações que foram feitas nos dados. Quem fez, quando
fez e o que foi modificado? Dependendo da empresa, será primordial ter uma auditoria implementada,
seja ela exigida pelo ramo do negócio ou por determinação da lei.
Antes do SQL Server 2008, era necessário utilizar diversos recursos para fazer todo o conjunto de auditoria
para uma instância. Usávamos as triggers DDL como o próprio nome diz faziam a auditoria de alterações
DDL, as triggers DML faziam a auditoria dos dados modificados em tabelas ou views, tinha a opção de usar
o SQL Trace fazia a auditoria de instruções SELECT ou ainda algumas ferramentas de terceiros.
O SQL Server 2008 possui uma ferramenta excelente, o SQL Server Audit combina todos os recursos de
auditoria.
Você poderia estar se perguntando: quais as vantagens de implementar auditoria do SQL Server no meu
ambiente? SQL Server Audit possui várias características e benefícios, dentre elas:
Auditoria de atividades;
Alta granularidade;
Leve e rápido;
M V T e c h | 178
SQL Server: Além do Conceito
Blog Post Collection
N OTA 01:
O SQL Server Audit utiliza Extended Events Engine para capturar os dados da auditoria. Isso resulta em
um rápido desempenho e sobrecarga mínima em comparação ao uso de SQL Trace para capturar esse
tipo de atividade.
Nesta seção, vamos ver uma visão geral de como funciona o SQL Server Audit. O fluxograma mostrado na
Figura 1 deve fornecer uma visão ampla do que está envolvido na criação de auditoria.
Figura 01. Fluxograma que mostra como criar uma nova auditoria de servidor SQL
A auditoria do SQL Server permite que você crie várias auditorias diferentes, atendendo a maior parte
todas das atividades que ocorre dentro do SQL Server.
Existem quatro principais objetos para se configurar a auditoria, Server Audit Object, Target, Server Audit
Specification e o Database Audit Specification, vamos detalhar um pouco mais sobre cada item:
O primeiro passo ao criar uma nova auditoria em uma instância do SQL Server 2008 é criar um SQL Server
Audit Object, que é responsável por coletar e agrupar as ações que serão monitoradas.
M V T e c h | 179
SQL Server: Além do Conceito
Blog Post Collection
Quando você cria um SQL Server Audit Object, deve-se atribuir um nome, selecionar as opções de
configuração, e dizer qual é o TARGET.
O TARGET é o local onde os dados de auditoria serão armazenados que pode ser um arquivo no disco
(audit file), o log de aplicações do Windows (Application EVENT LOG) ou no log de segurança do Windows
(Security EVENT LOG). Se a forma de armazenamento escolhida fo à auditàfile ,à o àpode àes olhe àaà
pasta onde esses arquivos serão gerados e poderá especificar o tamanho máximo de um arquivo. Além
disso, é possível alocar previamente espaço em disco para o log de auditoria, em vez de fazer o arquivo
crescer à medida que as linhas de auditoria são adicionadas.
Quando o Application ou o Security Log são especificados, as únicas opções disponíveis para configuração
são:
Queue Delay: quantidade de tempo em milissegundos que os eventos são armazenados antes de serem
armazenados. Para permitir que a entrega de eventos seja síncrona, você deve preencher esse campo
o à à QUEUE_DELáYà=à .àOà alo àdefaultà à ,àoà ueàe ui aleàaà àsegu do.à“eàespe ifi a àu à
tempo de atraso, os registros de auditoria poderão ser acumulados, mas mesmo assim deverão ser
gravados dentro do intervalo especificado;
<audit_options>::=
{
[ QUEUE_DELAY = integer ]
[ , ON_FAILURE = { CONTINUE | SHUTDOWN } ]
M V T e c h | 180
SQL Server: Além do Conceito
Blog Post Collection
[ , AUDIT_GUID = uniqueidentifier ]
}
Se você prestar atenção na sintaxe, perceberá que pode ser facilmente configurado.
N OTA 02:
O log de segurança pode ser integrado com o ACS (AUDIT COLLECTION SERVICES) do System Center
Operations Manager 2007;
Qualquer usuário autenticado pode ler/escrever no log de aplicações do Windows. Este log requer menos
permissões e é menos seguro que o log de segurança do Windows.
O segundo passo é criar o que é chamado de Audit Specification. A auditoria do SQL Server oferece dois
tipos diferentes de especificações de auditoria:
Server e Database Audit Specification são criados de forma diferente. Vamos conhecer um pouco mais o
conceito de cada um desses tipos.
Define os grupos de ações (action groups) que ocorrem no nível de instância do SQL Server e os agrupa
e à auditàa tio àg oups .àPo àe e plo,àpode àse àusadosà ua doà o ê deseja auditar uma atividade, tais
como login, logout, alterações de senhas, quando um comando de backup ou restore é disparada dentre
outas coisas .
Existe um relacionamento um-para-um entre o Server Audit Specification Object e o Server Audit Object.
A regra é simples um SQL Server Audit Object só pode ser associado com um Audit Specification porque
ambos são criados no escopo da instância do SQL Server.
As ações auditadas são enviadas para o SQL Server Audit que grava essas ações no TARGET. Na tabela 01
estão descritos os audit actions groups.
M V T e c h | 181
SQL Server: Além do Conceito
Blog Post Collection
APPLICATION_ROLE_CHANGE_PASSWORD_GROUP
AUDIT_CHANGE_GROUP
BACKUP_RESTORE_GROUP
BROKER_LOGIN_GROUP
DATABASE_CHANGE_GROUP
DATABASE_MIRRORING_LOGIN_GROUP
DATABASE_OBJECT_ACCESS_GROUP
DATABASE_OBJECT_CHANGE_GROUP
DATABASE_OBJECT_OWNERSHIP_CHANGE_GROUP
DATABASE_OBJECT_PERMISSION_CHANGE_GROUP
DATABASE_OPERATION_GROUP
DATABASE_OWNERSHIP_CHANGE_GROUP
DATABASE_PERMISSION_CHANGE_GROUP
DATABASE_PRINCIPAL_CHANGE_GROUP
DATABASE_PRINCIPAL_IMPERSONATION_GROUP
DATABASE_ROLE_MEMBER_CHANGE_GROUP
DBCC_GROUP
FAILED_LOGIN_GROUP
FULLTEXT_GROUP
LOGIN_CHANGE_PASSWORD_GROUP
LOGOUT_GROUP
SCHEMA_OBJECT_ACCESS_GROUP
SCHEMA_OBJECT_CHANGE_GROUP
SCHEMA_OBJECT_OWNERSHIP_CHANGE_GROUP
SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP
SERVER_OBJECT_CHANGE_GROUP
SERVER_OBJECT_OWNERSHIP_CHANGE_GROUP
M V T e c h | 182
SQL Server: Além do Conceito
Blog Post Collection
SERVER_OBJECT_PERMISSION_CHANGE_GROUP
SERVER_OPERATION_GROUP
SERVER_PERMISSION_CHANGE_GROUP
SERVER_PRINCIPAL_CHANGE_GROUP
SERVER_PRINCIPAL_IMPERSONATION_GROUP
SERVER_ROLE_MEMBER_CHANGE_GROUP
SERVER_STATE_CHANGE_GROUP
SUCCESSFUL_LOGIN_GROUP
TRACE_CHANGE_GROUP
SELECT
--Action_in_log -> Indica se uma ação pode ser gravada em
um log de auditoria. Os valores são os seguintes: 1 = Sim e 0 =
Não
Action_in_log,
--Name -> Nome da ação de auditoria ou do grupo de ações de
auditoria. Não pode ser nulo.
Name
FROM
Sys.dm_audit_actions
WHERE
-- Class_desc -> O nome da classe do objeto ao qual a ação
de auditoria aplica-se
Class_desc ='SERVER'
-- Configuration_level ->Indica que a ação ou o grupo de
ações especificado nessa linha são configuráveis no nível do
Grupo ou da Ação
AND Configuration_level ='Group'
ORDER BY
Name
Ao criar qualquer tipo de Audit Specification (Nota 02), você primeiro atribuir-lhe um nome e associa o
Audit Specification com o SQL Server Audit Object criado na primeira etapa. O último passo para criação
de uma especificação de auditoria de servidor é atribuir-lhe um Audit Action type que nada mais é do que
uma atividade pré-definida que acontece dentro do SQL Server e podem ser auditadas.
M V T e c h | 183
SQL Server: Além do Conceito
Blog Post Collection
N OTA 03:
Usado quando você deseja auditar uma atividade dentro de um banco de dados, como quem está
selecionando dados de uma tabela particular.
A regra é a cada Database Audit Specification pode ser associado a apenas um Server Audit Object.
Entretanto um Server Audit Object pode ser associado a apenas um Database Audit Specification por
banco de dados. Ou seja, você pode criar múltiplos Database Audit Speficications por banco de dados
desde que cada um use um Server Audit Object separado. Veja Figura 02.
M V T e c h | 184
SQL Server: Além do Conceito
Blog Post Collection
No nível de instância, você pode especificar um ou mais Audit Action Group (para Database Audit
Specification você pode especificar ações de auditoria individual e filtros também).
Na tabela 02 estão descritos as ações ou grupos de ação que podem ser configurados.
DELETE APPLICATION_ROLE_CHANGE_PASSWORD_GROUP
EXECUTE AUDIT_CHANGE_GROUP
INSERT BACKUP_RESTORE_GROUP
RECEIVE DATABASE_CHANGE_GROUP
REFERENCES DATABASE_OBJECT_ACCESS_GROUP
SELECT DATABASE_OBJECT_CHANGE_GROUP
UPDATE DATABASE_OBJECT_OWNERSHIP_CHANGE_GROUP
DATABASE_OBJECT_PERMISSION_CHANGE_GROUP
DATABASE_OPERATION_GROUP
DATABASE_OWNERSHIP_CHANGE_GROUP
DATABASE_PERMISSION_CHANGE_GROUP
DATABASE_PRINCIPAL_CHANGE_GROUP
DATABASE_PRINCIPAL_IMPERSONATION_GROUP
DATABASE_ROLE_MEMBER_CHANGE_GROUP
DBCC_GROUP
SCHEMA_OBJECT_ACCESS_GROUP
SCHEMA_OBJECT_CHANGE_GROUP
SCHEMA_OBJECT_OWNERSHIP_CHANGE_GROUP
SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP
M V T e c h | 185
SQL Server: Além do Conceito
Blog Post Collection
Neste objeto podemos coletar dados como DELETE, INSERT, SELECT, UPDATE, EXECUTE, DBCC_GROUP
etc. Para visualizarmos todos os objetos descritos na Tabela 02, basta fazermos uma pesquisa na DMV
sys.dm_audit_actions.
SELECT
--Action_in_log -> Indica se uma ação pode ser gravada em
um log de auditoria. Os valores são os seguintes: 1 = Sim e 0 =
Não
Action_in_log,
--Name -> Nome da ação de auditoria ou do grupo de ações de
auditoria. Não pode ser nulo.
Name
FROM
sys.dm_audit_actions
WHERE
-- Class_desc -> O nome da classe do objeto ao qual a ação
de auditoria aplica-se
class_desc='DATABASE'
-- Configuration_level ->Indica que a ação ou o grupo de
ações especificado nessa linha são configuráveis no nível do
Grupo ou da Ação
AND configuration_level IN ('Action','Group')
ORDER BY name
Ao criar uma especificação de auditoria de banco de dados, você atribui um nome, então associa ao Audit
Specification com o SQL Server Audit Object e especifica o Audit Action Type como foi feito com o Server
Audit Specification. No entanto, além disso, deve-se especificar o Object Class (database, object ou
schema), o nome do objeto auditado e o security principal (ou seja, quem nós vamos auditar).
Uma vez que o Audit Specification for concluído, você deve habilitar o SQL Server Audit Object e o Audit
Specification. Apartir daí os eventos de auditoria começarão a ser coletados para o target designado.
N OTA 03:
M V T e c h | 186
SQL Server: Além do Conceito
Blog Post Collection
} [, ...n] ]
[ WITH ( STATE = { ON | OFF } ) ]
}
[ ; ]
<audit_action_specification>::=
{
action [ ,...n ]ON [ class :: ] securable BY principal [
,...n ]
}
Nesse exemplo vamos configurar os três targets disponíveis para configurar o Server Audit Objects. Iremos
demostrar como fazer isso logo abaixo:
a) O primeiro target que criaremos será Windows Application Event Log. Abra o Management Studio vá
em: Security/ Audits/New Audit. Veja Figura 03.
M V T e c h | 187
SQL Server: Além do Conceito
Blog Post Collection
A primeira coisa que você precisa fazer é atribuir o nome ou usar o nome que é gerado automaticamente.
Preencha a opção Audit Name(aconselho a colocar um nome intuitivo para que possa identificar do que
se trata), no nosso caso estou colocando o nome do target mais a forma que ele esta sendo criado. Ou
seja, ApplicationLog + SSMS = ApplicationLog SSMS . Veja Figura 04.
M V T e c h | 188
SQL Server: Além do Conceito
Blog Post Collection
Nesse exemplo estamos configurando o Queue delay para 3000 milissegundos. Na Tabela 03 descreve
todos os parâmetros existentes na Figura 04.
Parâmetros Descrição
M V T e c h | 189
SQL Server: Além do Conceito
Blog Post Collection
*Application_Log
*Security_Log
Reserve Disk Space Ativando essa opção você ira reservar todo espaço em disco rígido
M V T e c h | 190
SQL Server: Além do Conceito
Blog Post Collection
Naà opç oà áudità Desti atio à sele io eà áppli atio à Log .à áoà faze à issoà osà out osà pa et osà fi a a à
indisponíveis. Clique em OK. Veja Figura 05.
Por default o Server Audit Object é criado desabilitado. Para habilita-lo basta clicar com o botão direito
doà ouseàe àáppli atio Log““M“àeàsele io a àaàopç oà E a leàáudit .àVejaàFigu aà .
M V T e c h | 191
SQL Server: Além do Conceito
Blog Post Collection
Para criar o mesmo Server Audit demostrado acima usando T-SQL basta executar os comandos abaixo:
CREATE SERVER AUDIT [TargetApplicationLogTSQL]
TO APPLICATION_LOG
WITH
(
QUEUE_DELAY = 3000,
ON_FAILURE = CONTINUE
)
GO
O parâmetro ON_FAILURE só pode ser configurado para aqueles logins que possuem permissão
SHUTDOWN. Se o usuário que esta tentando executar esse comando não tiver essa permissão, a função
irá falhar com uma mensagem MSG_NO_SHUTDOWN_PERMISSION.
O segundo objeto que vamos configurar é para o Target FILE. Existem algumas opções adicionais que pode
ser especificada. Incluindo qual a pasta que os arquivos de auditoria serão gerados, o número máximo de
rollover files(Esse parâmetro é avaliado sempre que a auditoria é reiniciada ou quando um novo arquivo
é necessário porque o MAXSIZE foi atingido. Se o número de arquivos excede o MAX_ROLLOVER_FILES o
arquivos mais antigo é deletado), o tamanho máximo de cada arquivo e se é para reservar espaço em
disco para o audit file(arquivo de auditoria).
M V T e c h | 192
SQL Server: Além do Conceito
Blog Post Collection
F AREMOS ESSAS CONFIGU RAÇÕES DO S ERVER A UDIT ATRAVÉS DE TSQL E O M ANAGEMENT S TUDIO .
Va osàat i uiàu à o eàpa aàopç oà áudità a e .à Noà ossoà asoà oà o eàse :àTa getFileSSMS. Veja
Figura 07.
Por causa do aumento da latência, devido à rede pode ser necessário aumentar o parâmetro
QUEUE_DELAY para evitar afetar a instância. Colocaremos essa opção como 2000 milissegundos.
Noà pa et oà Fileà path à de e osà dize à oà o eà daà pastaà o deà se oà a aze adosà osà a ui osà daà
auditoria. Neste exemplo estamos especificando a pasta de destino para C: \ Auditoria \.
Po àfi ,àha iteà ‘ese eàdiskàspa e .àVejaà aàFigu aà à o oàfi a a àtodasàasà o figu aç es.
M V T e c h | 193
SQL Server: Além do Conceito
Blog Post Collection
Pronto! O Server Audit foi criado com sucesso. Você estar se perguntando: Como posso criar o mesmo
objeto através de comandos TSQL? Veja logo abaixo o script:
USE master
GO
M V T e c h | 194
SQL Server: Além do Conceito
Blog Post Collection
FILEPATH = N'C:\Auditoria',
/*MAXSIZE = Especifica o tamanho máximo para o qual o
arquivo de auditoria pode crescer*/
MAXSIZE = 3MB,
/*MAX_ROLLOVER_FILES = Número máximo de arquivos que pode
ser criados. O valor padrão é UNLIMITED. Lembrando que esse valor
deve ser um número inteiro. Portanto o valor UNLIMITED = 0.*/
MAX_ROLLOVER_FILES = 3,
/*RESERVE_DISK_SPACE = Esta opção de pré-aloca o arquivo no
disco para o valor definifo no MAXSIZE. Aplica-se somente se
MAXSIZE não é igual a UNLIMITED. O valor padrão é OFF*/
RESERVE_DISK_SPACE = ON
)
WITH
(
QUEUE_DELAY = 1000,
ON_FAILURE = CONTINUE
)
Para visualizarmos os objetos criados (Veja Figura 09) basta utilizar o seguinte consulta:
Observe que na coluna type_desc descreve o tipo do target de cada Server Audit.
Por fim o terceiro e último Target Windows Security Event Log. Antes de começamos a demonstrar como
faremos a criação desse objeto, será necessário efetuarmos algumas configurações no Windows a fim de
permitir que o SQL Server possa gravar eventos no Security Event Log. O servidor utilizado nessa
demonstração é o Windows Server 2008).
M V T e c h | 195
SQL Server: Além do Conceito
Blog Post Collection
Figura 10.
Clique em Local Polices\ Audit Policy. Com o botão direito do mouse selecione Audit object access\
Properties. Marque as opções: Success e Failure. Estamos permitindo o acesso ao objeto de auditoria em
casos de sucesso e falha. Veja Figura 11.
Precisamos atribuir direito de gerar Security Audits para a conta de serviço do SQL Server. Caso você não
lembre ou não saiba qual usuário esta inicializando o SQL Server basta ir em Iniciar \Microsoft SQL Server
2008 R2 \ Configuration Tools \ SQL Server Configuration Maganer. Selecione o serviço com o botão
direito e clique em Propriedades. Na aba Logon verifique a conta que está configurada o MSSQLSERVER.
Veja Figura 12.
M V T e c h | 196
SQL Server: Além do Conceito
Blog Post Collection
Depois de descoberto o usuário vamos finalmente atribuir a permissão para ele. Selecione User Rights
Assignment \ Generate security audits. Clique no botão Add User or Group e adicione o usuário
configurado na conta de serviço do SQL Server. Veja Figura 13.
M V T e c h | 197
SQL Server: Além do Conceito
Blog Post Collection
Uma vez que estas duas alterações foram feitas, reinicie o serviço do SQL Server e então você vai ser capaz
de criar um Server Audit no Windows Security Log. Observe que as opções definidas aqui podem muito
bem serem efetuadas via Group Policy direto no servidor de domínio. Esse tipo de configuração deve ser
discutido com os responsáveis pelo gerenciamento das Politicas de Segurança do Servidor e assim garantir
que os ajustes necessários sejam colocados em vigor para que o SQL Server seja capaz de gravar eventos
no Security Log.
Naàopç oà áuditàdesti atio àsele io eà“e u it àLog.àPe e aà ueàasàout asàopç esàdeà o figu aç oàs oà
desabilitadas assim que escolhemos essa opção. Veja Figura 14.
M V T e c h | 198
SQL Server: Além do Conceito
Blog Post Collection
Caso tenha interesse em criar esse mesmo Server Audit através de comandos TSQL faça conforme script
abaixo:
CREATE SERVER AUDIT TargetSecurityLogTSQL
TO SECURITY_LOG
WITH
(
QUEUE_DELAY = 2000,
ON_FAILURE = CONTINUE
)
GO
M V T e c h | 199
SQL Server: Além do Conceito
Blog Post Collection
Como vimos nos exemplos acima, é extremamente simples criar Server Audit Objects no SQL Server 2008
usando TSQL ou SSMS.
Agora que criamos o nosso Server Audit Objects precisamos adicionar especificação de auditoria
correspondente. Se quisermos fazer uma auditoria no nível de instância, teremos que criar um Server
Audit Specification. Vamos auditar toda vez que for gerado um backup ou restore no servidor. O nome do
Action Group utilizado nesse exemplo será BACKUP_RESTORE_GROUP.
Vamos criar o Server Audit Specification. Abra o SSMS vá em Security \Server Audit Specification \New
Server Audit Specification.. Veja Figura 15.
Naàopç oà áudit àde e osàpreencher com um dos Server Audit Objects criado anteriormente. Nesse caso
vou querer armazenar os dados auditados no Application Log. Selecione a opção
Ta getáppli atio LogT“QL .ààVejaàFigu aà .
M V T e c h | 200
SQL Server: Além do Conceito
Blog Post Collection
Figura 16.
No campo Action \Audit Action Type, selecione BACKUP_RESTORE_GROUP. Ao fazer isso as outras opções
de configuração seram desabilitadas. Clique no botão OK. Veja Figura 17.
M V T e c h | 201
SQL Server: Além do Conceito
Blog Post Collection
Agora vamos habilitar o Server Audit Specification criado, para iniciarmos a coleta dos dados. Podemos
fazer de duas maneiras, clicando com o botão direito em cima do objeto adicionado e selecionando a
opç oà E a leà“e e àáudità“pe ifi atio ,àouà iaàT“QL. Veja Figura 18.
M V T e c h | 202
SQL Server: Além do Conceito
Blog Post Collection
Figura 18.
Os scripts da Listagem 01 cria um banco de dados, uma tabela, faz a inserção dos dados e por fim faz o
backup e um restore para vermos se os dados realmente estão sendo auditados.
M V T e c h | 203
SQL Server: Além do Conceito
Blog Post Collection
Vamos verificar se o que acabamos de fazer foi realmente auditado, para isso selecione a guia
Management \SQL Server Logs \ View SQL Server Log. Veja Figura 19.
M V T e c h | 204
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 205
SQL Server: Além do Conceito
Blog Post Collection
Verifique que todas as linhas que possuem uma chave foram os dados auditados, no nosso caso o backup
e o restore que fizemos.
Nos próximo exemplo vamos criar um Database Audit Specification. O objetivo dessa auditoria será
auditar a utilização das clausulas SELECT, INSERT, UPDATE e DELETE em duas tabelas de um único banco
de dados. Você precisará do AdventureWorks instalado, para isso baixa baixar no site do Codeplex
(http://msftdbprodsamples.codeplex.com/releases/view/55926).
A primeira tarefa é criarmos um Server Audit, como nós já criamos na etapa 2b. Utilizaremos mesmo
quando for solicitado.
Para criar um Database Audit Specification você deve escolher o banco de dados que deseja fazer a
audito ia.à Noà ossoà asoà se à oà ád e tu eWo ks.à Cli ueà o à oà ot oà di eitoà e à Data aseà áudità
“pe ifi atio àeàsele io eà Ne àáudità“pe ifi atio ,à o oàmostrado na Figura 21.
M V T e c h | 206
SQL Server: Além do Conceito
Blog Post Collection
Naàja elaà C eateàData aseàáudità“pe ifi atio à o àpodeàa eita àoà o eàsuge idoàouà asoà uei aàpodeà
digitar seu próprio nome. Adotaremos o seguinte:
Em seguida selecione a partir da caixa suspensa o Server Audit Object que armazenaremos os dados da
auditoria. Dessa vez vamos armazenar os dados da auditoria em um arquivo, utilizaremos o Server Audit
Object criado anteriormente. Selecione o Target TargetFileSSMS. Veja Figura 22.
M V T e c h | 207
SQL Server: Além do Conceito
Blog Post Collection
Figura 22.
Na seção áuditàá tio àT pes ,à o àde eàespe ifi a àoàtipoàdeàaç oàdeàaudito iaà ueàdesejaà aptu a .àNoà
primeiro combo selecione a opção SELECT, com o objetivo de gravar toda atividade do comando SELECT
para a tabela Veja Figura 23.
M V T e c h | 208
SQL Server: Além do Conceito
Blog Post Collection
Figura 23.
ágo aàde e osàes olhe à O je tàClass .àVa osàaudita à aisàdeàu aàta elaàdeàu à a oàespe ifi oàe t oà
selecione a segunda opção dessa coluna, ou seja, OBJECT.
Devemos selecionar qual o OBJECT será auditado,àpa aàistoà li ueà oà ot oà … àdaà olu aàO je tàNa e.à
Veja Figura 24.
M V T e c h | 209
SQL Server: Além do Conceito
Blog Post Collection
Figura 24.
Escolha as tabelas que serão monitoradas do banco AdventureWorks. Selecione as seguintes tabelas:
HumanResources.Employee, Person.Contact, Production.Location e Production.UnitMeasure. Clique no
botão OK (Observe que temos a opção de escolher mais de um database).
áàp i aàetapaàse àes olhe àoà P i ipalàNa e ,àouàseja,à ualàoàusu ioà ueà ue e osàaudita .àNessaà
opç oàpode osàsele io a àUse sàeà‘oles.àPa aàfaze àisso,à li ueà oà ot oà ... àdaà olu aà P i ipalàNa e à
eà aàja elaà “ele tàO je ts à li ueà oà ot oà B o se .. .àágo aà o àpodeà e à uaisà P i ipals àpodeà
es olhe ,à esseà asoà osà a osàes olhe à àpu li à,àpoisàoào jeti oàdessaàaudito iaà àide tifi a àà ual ue à
pessoas que execute a cláusula SELECT na tabela xx , como mostrado na figura 25.
M V T e c h | 210
SQL Server: Além do Conceito
Blog Post Collection
Figura 25.
Concluímos o nosso primeiro filtro, vamos repetir as operações descritas acima para os comandos INSERT,
UPDATE e DELETE. Veja Figura 26.
Assim como Server Audit Specification a especificação de banco de dados é criado desabilitado, se você
observe vera que ele tem uma seta vermelha indicando que esta desativada, para habilita-la clique sobre
oà es oà o oà ot oàdi eitoàeàes olhaàaàopç oà E a leàData aseàáudità“pe ifi atio .
Agora vamos selecionar excluir, inserir e atualizar alguns registros das tabelas que estamos auditando
para ver se tudo aquilo que configuramos esta funcionando conforme o esperado. Execute os scripts da
Listagem 02.
M V T e c h | 211
SQL Server: Além do Conceito
Blog Post Collection
Os dados foram armazenadados em um arquivo que foi gerado na pasta C:\Auditoria. Veja Figura 27.
Vamos vizualizar os dados auditados utilizando a função fn_get_audit_file, que é responsável em retornar
as informações de um arquivo de auditoria. Execute o script da Listagem 03.
M V T e c h | 212
SQL Server: Além do Conceito
Blog Post Collection
*/
SELECT
convert(varchar(10),event_time,103) as [Data], --Data e
hora em que a ação auditável é acionada
convert(varchar(12),event_time,114) as [Hora], --Data e
hora em que a ação auditável é acionada
server_instance_name as [Nome Instância], --Nome da
instância de servidor no qual a auditoria ocorreu
database_name as [Nome do Banco], --O contexto do banco de
dados no qual a ação aconteceu. Permite valor nulo. Retorna NULL
para auditorias realizadas no nível de servidor.
server_principal_name as [Login], --Logon atual. Permite
valor nulo
object_name, --O nome da entidade na qual a auditoria
ocorreu.
statement as [Consulta Executada],
file_name as [Caminho do Arquivo]
FROM
fn_get_audit_file('C:\Auditoria\TargetFileSSMS_D59592D1-
4057-49EB-A421-
CF2DF6BB2F47_0_129603920978160000.sqlaudit',DEFAULT,DEFAULT)
CONCLUSÃO
Uma parte essencial de qualquer estratégia de segurança de dados é um plano de segurança que possui
regras com a capacidade de rastrear quem acessou ou tentou acessar dados, mas para ter essas
informações precisamos realizar auditorias regulamente. Isso permite ao DBA a capacidade de detectar
prevenir qualquer ação maliciosa, acessos ilegítimos.
Vimos no decorrer do artigo como criar uma auditoria nos mais diversos seguimentos, vimos também que
oà“QLà“e e àáudità àu aàfe a e taàpode osaà ueàosàDBá sàpode àutiliza àpa aà oleta à uaseàtodasàasà
atividades que acontece dentro dos nossos servidores ou banco de dados ou um objeto especifico.
REFERÊNCIAS
http://msdn.microsoft.com/pt-br/library/cc280386.aspx
M V T e c h | 213
SQL Server: Além do Conceito
Blog Post Collection
http://msdn.microsoft.com/pt-br/library/cc280425.aspx
http://msdn.microsoft.com/pt-br/library/cc280426.aspx
http://msdn.microsoft.com/en-us/library/dd392015(v=sql.100).aspx
sys.server_audits (Transact-SQL)
http://msdn.microsoft.com/pt-br/library/cc280727.aspx
M V T e c h | 214
SQL Server: Além do Conceito
Blog Post Collection
Performance e Desempenho
System Monitor & SQL Profiler
É muito comum nos dias de hoje enfrentarmos problemas com desempenho no trabalho ou até mesmo
no conforto de nossa casa. Você pode está se perguntando como assim? Imagine a seguinte situação:
Uma turma de amigos resolveu marcar um encontro on-line para disputar aquele jogo que acabou de ser
lançado. Caso você não tenha uma boa placa de vídeo, memória e um processador mais ou menos a
reuniãozinha vai ter que ficar para outro dia. Pois o jogo vai ficar lento, a imagem no seu monitor vai ficar
renderizando dentre outas coisas.
Falando no mundo do banco de dados, infelizmente vivemos sujeitos a falhas de hardware, bloqueio de
transações, paginação, dentre outras coisas que acarretam na degradação das nossas aplicações.
Resumindo isso tudo que eu disse é exatamente quando o Service Desk da sua empresa recebe aquelas
ligaç es:à Oà euàsiste aà oàa eà ada!! ,à T à uitoàle toà oà o sigoàt a alha àouà elho à áà ulpaà à
daàTI .à
Diante dessa situação, vou abordar nesse artigo como monitorar seu ambiente de SQL Server e a
diagnosticar tais problemas através de estudo de caso prático. O desafio é reunir o System Monitor com
o SQL Profiler de uma maneira coerente que nos permita fazer uma análise eficiente.
Vou criar um cenário fictício a fim de ajudar na compreensão dos conceitos. Imaginemos que somos
funcionários da AdventureWorks e parte das atribuições destinas a nós dentro da empresa, inclui ficarmos
encarregados de monitorar o ambiente de produção. Ou seja, verificar o desempenho do banco de dados
como um todo. Por exemplo: Analisar se está tendo I/O no disco, como está o processador ou a memória
do servidor, quantas conexões estão ativas, e assim por diante.
Ultimamente nosso atendimento nível 01 está recebendo muitas ligações reportando problemas de
lentidão com as aplicações. Resolvemos então investigar o motivo dessas reclamações.
A primeira coisa que vamos fazer é utilizar o System Monitor, para coletar as informações do servidor de
banco de dados.
O System Monitor mostra graficamente os dados em tempo real de desempenho, incluindo a utilização
do processador, cache, fila de impressão, sincronização, uso da largura de banda e milhares de outras
estatísticas. Ele utiliza uma arquitetura de sondagem para capturar e registrar dados numéricos expostos
pelos aplicativos. O DBA escolhe os contadores a serem capturados para análise de acordo com a análise
que ele necessita fazer. No nosso caso vamos escolher os contadores que nos ajudará a identificar o
motivo da queda de desempenho nas aplicações.
N OTA 1:
M V T e c h | 215
SQL Server: Além do Conceito
Blog Post Collection
A cada nova versão do Windows às vezes você tem que procurar as ferramentas que utilizava
anteriormente em um lugar diferente. Porque a Microsoft resolveu mudar o nome da ferramenta ou
mudou de lugar. Por exemplo, o System Monitor o pessoal que trabalha com TI há muito tempo conhece
esse utilit ioà o oà Pe f o ,à Pe fo a eàMo ito àouà “ ste àMo ito .
No entanto para entendermos como obter as informações desejadas é importante compreender os três
níveis fundamentais para os critérios de monitoramentos. Estes níveis são: object, counter e instance.
Veja a Figura 01.
COUNTERS: Counters são um subconjunto de um object. Para um determinado object, você pode ter
vários contadores. Por exemplo, o object Processor tem vários contadores para escolher: % Processor
Time, % User Time, Interrupts/sec, etc.
INSTANCES: Cada counter pode ter uma ou mais instances . Usando o exemplo acima do object Processor,
o %Processor Time teria 47 instâncias de um sistema - um para cada processador (0 até 47). Caso
necessite, você tem a capacidade de monitorar apenas uma instância de um counter de dados.
M V T e c h | 216
SQL Server: Além do Conceito
Blog Post Collection
N OTA 2:
Lembrando que para que os dados sejam coletados corretamente os únicos tipos de dados permitidos
pelo System Monitor são numéricos. (Fim Nota 2)
Antes de criarmos nosso primeiro Data Collector Sets queria chamar atenção para três contadores em
especial. São eles: System: Processor Queue Length, Network Interface: Output Queue Length e Physical
Disk: Avg Disk Queue Length. Se identificarmos alguma anormalidade neles, teremos sérios problemas no
sistema.
System: Processor Queue Length: Este contador, ao invés de avaliar o uso de um único processador, avalia
o enfileiramento de threads aguardando oportunidade de execução em todos os processadores. Se ele
excede 02 theads por cada processador durante períodos contínuos ou durante um período de
monitorização de 24 horas, você poder ter um gargalo de CPU. Por exemplo, se você possui 06 CPU´s no
seu servidor, o valor deste contador não deve ultrapassar quanto? A resposta é 12, que equivale ao
seguinte cálculo = 06 x 02 = 12. O resultado é a multiplicação de 06 CPU's com 02 theads(valor aceitável
por processador). Se este valor é ultrapassado por um período muito extenso e constante, pode indicar
que seus processadores não estão mais suportando a carga do sistema.
Network Interface: Output Queue Length: Este contador de desempenho indica o tamanho da fila de
pacotes de saída. Ou seja é quantos pacotes estão sendo mantidos em uma fila, esperando para ser
enviada a partir da placa de rede para rede. Geralmente esse valor é zero. Como regra geral, se o Output
Queue Length for superior a 2 por um período de 10 minutos ou mais de uma vez, provavelmente você
tem um problema de desempenho de rede e isso está causando gargalo na rede. As possíveis causas desse
problema pode estar em várias coisas como por exemplo: uma placa de rede lenta, um problema de rede,
um problema no hub ou switch, pode ser que o SQL Server é muito. muito ocupado e a carga é demias
para placa de rede ou até a própria rede.
Physical Disk: Avg Disk Queue Length: Uma thread pode fazer muitos pedidos de uma vez só ao IO
Manager(O IO Manager é orientado a pacotes. Resumindo em poucas palavras, sua função é receber os
pedidos de leitura/gravação dos processos, transformar estes pedidos em um pacote chamado de IRP –
IO Request Packet, e encaminhar este pacote ao driver responsável. Após feita essa operação, o driver
devolverá o IRP ao IO Manager com as informações de como foi o processamento) sem esperar que a
primeira seja completada. O IO Manager não irá recusar esses pedidos, mas irá organizá-los numa fila,
pois o disco só faz uma coisa de cada vez. O comprimento médio dessa fila é o "Avg Disk Queue Length".
O contador Avg. Disk Queue Length se for superior a dois por períodos contínuos (mais de 10 minutos ou
mais durante o período de monitoramento 24 horas) para cada unidade de disco em um array, então você
pode ter um gargalo de I/O para esse array. Você precisará calcular este valor, porque o Performance
Monitor não sabe quantas unidades físicas estão no seu array. Por exemplo, se você tem um array de 6
discos físicos e o Avg Disk Queue Length do disco é de 10 para uma disposição particular, então o Avg.
Disk Queue Length para cada unidade é de 1,66 (Cálculo: 06/10 = 1,66), que está bem dentro da 2
recomendado por disco físico.
M V T e c h | 217
SQL Server: Além do Conceito
Blog Post Collection
Após a compreensão dos níveis e aprendermos um pouco mais sobre contadores, poderemos em fim criar
o chamado Data Collector Sets, que nada mais é do que um bloco de monitoramento onde vamos colocar
nossos counters. A grosso modo é um conjunto de dados personalizados onde você decide quais
atividades serão monitoradas
Quando você usa o System Monitor, é possível ver os contadores de desempenho em tempo real. O Data
Collector Sets pode gravar estes dados para que você possa analisá-lo mais tarde.
No entanto, para a análise ser útil, aconselho a coletar e salvar os registros dos dados no momento da
queda de desempenho. Mas para que fazer isso? Por que podemos comparar como ficou o desempenho
antes de depois dos ajustes.
Clique em Data Collector Sets > User Defined, com o botão direito do mouse escolha New e em seguida
Data Collector Sets. Veja a Figura 02;
M V T e c h | 218
SQL Server: Além do Conceito
Blog Post Collection
O wizard para criação do Data Collector Sets irá aparecer socilitando que você digite um nome. Logo após
a escolha do nome, teremos duas opções: Create from a template (Recommentded) e Create manually
(Advanced). A opção default é Create from a template (Recommentded), mas no nosso contexto vamos
criar manualmente os contadores que queremos monitorar. Deste modo, selecione a segunda opção e
clique em Next. Veja a Figura 03;
Agora devemos escolher qual tipo de dados iremos incluir no Data Collector Set. A opção Create data log
> Performance Counter já vem selecionada por default, vamos mantê-lo assim. Clique em Next. (Figura
04);
M V T e c h | 219
SQL Server: Além do Conceito
Blog Post Collection
Na próxima tela encontramos as seguintes opções: Performance Counter, Event Trace Data e System
configuration information. Selecione Performance Counter. Essa opção permitirá escolher qualquer
contador disponível no Performance Monitor. Feito isso clique em Next;
Clique no botão Add. Selecione os contadores de performance que você deseja. Vamos monitorar a fila
atual dos discos (PhisicalDisk\Current Disk Queue Length) e o processador (Processor \%Processor time).
Em seguida clique em OK. Observe a Figura 05;
M V T e c h | 220
SQL Server: Além do Conceito
Blog Post Collection
Depois de incluir os contadores, o próximo passo é definir qual o intervalo que eles serão monitorados.
Veja na Figura 06 que existem duas opções a serem configuradas: Sample interval e Units. Em Sample
interval iremos deixar o número 15 e em Units informaremos seconds. Isso irá definir que de 15seg em
15seg será coletadas as informações referente aos contadores adicionados no passo anterior. Clique no
botão Finish.
M V T e c h | 221
SQL Server: Além do Conceito
Blog Post Collection
Depois de criar um Data Collector Set você pode salvá-lo no diretório padrão
(C:\PerfLogs\Admin\HostName_AnoMesDia) ou escolher outro local da sua preferência. Veja na Figura
07 que o podemos visualizar o caminho completo ao selecionarmos o SQLMagazine em Data Collector
Sets.
Figura
07.
Com isso nosso coletor de dados está pronto. Para iniciar a armazenamento das informações basta clicar
com o botão direito no Data Colletor Set > SQLMagazine e escolher opção Start. Observe a Figura 08.
M V T e c h | 222
SQL Server: Além do Conceito
Blog Post Collection
Para verificarmos se a coleta começou, selecione Reports > User > Defined >SQL Magazine. Veja a Figura
09.
M V T e c h | 223
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 224
SQL Server: Além do Conceito
Blog Post Collection
O Microsoft SQL Server Profiler é uma interface gráfica para a funcionalidade de Rastreamento, com ele
você pode capturar a atividade gerada por uma carga de trabalho em uma instância do SQL Server ou do
Analysis Service.
Podemos utilizar os dados capturados para monitorar os erros de uma instância ou problemas de
concorrência, como também capturar dados que são usados para otimizar o desempenho das consultas
que são executadas no ambiente, seja ele de produção ou de teste.
O QUE É O T RACE ?
SQL Server Profiler é o responsável por criar o chamado Trace. Estes traces incluem todos os scripts T-SQL
que são executados simultaneamente no SQL Server, quanto tempo eles estão levando, o tipo de
bloqueios sendo usado,e quaisquer erros que possam ocorrer no servidor monitorado.
Como o Trace contém todos os scripts T-SQL em execução no SQL Server, muitas vezes tende a se tornar
consideravelmente grande. Por isso, é sempre uma boa prática capturar apenas os dados que são
realmente necessários para análise.
Embora você possa criar um trace usando Transact-SQL (T-SQL), é mais comum usar SQL Server Profiler
para isso. E como fazer isso? Você pode iniciar o SQL Server Profiler através do menu File >New Trace do
SQL Server 2008 e em seguida se conectar em uma instância para começar a configurar um Trace. Veja
na Figura 10.
M V T e c h | 225
SQL Server: Além do Conceito
Blog Post Collection
Todo trace é obrigado a ter um nome e pelo menos um evento. Podemos especificar várias propriedades
para um Trace, como por exemplo: nome, modelo, hora de parada, tamanho máximo do arquivo e etc.
Veja Figura 11 .
M V T e c h | 226
SQL Server: Além do Conceito
Blog Post Collection
Muitas pessoas ignoram os Templates que o SQL Server Profiler fornece. O conhecimento sobre cada um
deles nos permite fazer uma análise útil dos traces. O SQL Server Profiler oferece esses modelos de
rastreamento predefinidos que permitem facilmente configurar as event classes que provavelmente
especificaremos no trace. Na tabela 1 descreve os templates prontos que pode ser utilizado para
rastreamentos sem qualquer modificação ou como ponto de partida para um novo onde podemos
adicionar colunas e eventos diferentes do padronizado.
Template Objetivo
Blank Um trace está vazio, ou seja, não possui nenhum evento ou coluna
selecionados para o rastreamento. Permite criar um rastreamento
inteiro a partir do zero.
SP_Counts Captura cada stored procedure executada para determinar o quanto
cada procedure está sendo executada.
Standard É o template mais comum para começar pois já possui alguns eventos
slecionados. Captura os seguintes eventos: Security Audit, Sessions,
Stored Procedures e TSQL.
TSQL Captura uma lista de todas as stored procedures e ad hoc SQL batch
executados, mas não inclui estatísticas de desempenho.
TSQL_Durantion Captura a duração de cada stored procedure e ad hoc SQL batch
executado.
TSQL_Grouped Captura login e logout, junto com as stored procedures e todas as
instruções Transact-SQL no momento em que foram emitidos. Use para
investigar consultas de um determinado cliente ou usuário. Não inclui
dados de desempenho.
TSQL_Locks Captura informações de bloqueio e deadlock, como blocked processes,
deadlock chains, gráficos de deadlock, lock escalation e lock timeouts.
TSQL_Replay Capta informações detalhadas sobre o Transact-SQL . Se é necessário o
rastreamento pode repetido nos servidores ou diferentes. Este template
é comumente usado para fazer testes de carga e regressão. Por exemplo:
realizar testes de benchmark.
TSQL_SPs Capta informações detalhadas sobre todos as Stored Procedures em
execução. Use para analisar os passos de componentes dos
procedimentos armazenados. Adicione o evento SP: Recompile se você
suspeitar que os procedimentos estão sendo recompilados.
Tuning Captura as informações sobre procedimentos armazenados Transact-
SQL e execução do lote. Use para produzir saída do trace que o Database
Engine Tuning Advisor pode usar como uma workload para ajustar
bancos de dados.
Tabela 1. Descrição Templates.
Por padrão, quando um trace é iniciado usando o SQL Profiler, todos os eventos aparecem em uma grid
dentro da interface. Podemos observe na Figura 12 como os eventos são listados no Trace.
M V T e c h | 227
SQL Server: Além do Conceito
Blog Post Collection
N OTA 4:
Podemos salvar os dados de um trace em uma tabela, em um arquivo ou em ambos. (Fim da Nota 4)
Você pode encontrar mais de 200 eventos que podem ser capturados no Trace SQL. A principal ação para
configurar um rastreamento é a seleção do conjunto de eventos que precisa ser monitorado. Tais eventos
são classificados em 21 grupos, alguns podem contem mais de 40 eventos. Os grupos de evento
disponíveis estão listados na Tabela 2.
M V T e c h | 228
SQL Server: Além do Conceito
Blog Post Collection
Os grupos mais utilizados são: Locks, Performance, Security Audit, Stored Procedures, e TSQL. Os grupos
de evento Stored Procedures e TSQL geralmente são capturados com eventos do grupo Performance para
ter um parâmetro e solucionar problemas de desempenho de consulta. O grupo de eventos Security Audit
é usado para definir auditoria rapidamente entre uma variedade de eventos de segurança embora a nova
featu e àdeàespe ifi aç oàdeàaudito iaàfo eçaà e u sosà aisàsegu os e flexíveis. Por fim os eventos do
grupo Locks são comumente usados para solucionar problemas de concorrência.
Como dito anteriormente, é preciso ter cuidado com quais eventos monitorar, pois alguns deles podem
ter uma carga significativa em uma instância. Os eventos que se deve ter muito cuidado são:
Performance | Showplan
M V T e c h | 229
SQL Server: Além do Conceito
Blog Post Collection
TSQL | StmCompleted
TSQL | StmStarting
Esses grupos de eventos devem ser incluídos em um trace se e somente se, estiverem em conjunto com
um ou vários filtros restritivos, que limite o trace a um único objeto ou string.
Após toda essa explicação sobre o que é Profiler, trace, template e grupo de eventos vamos ver como
adicionar filtros em um trace para finalmente começarmos a por a mão na massa e resolvermos o
problema da AdventureWorks.
Um filtro é essencialmente uma cláusula WHERE aplicada nos dados na API do SQL Trace. Os filtros
permitem especificar vários critérios a serem aplicados nas colunas de dados.
ásà olu asà ueàpossue à ha a te à dadosàalfa u i os àpe ite à ueàfilt osàseja àdefi idosàe àu aà
string, usando LIKE ou NOT LIKE, que podem conter um ou mais caracteres curingas. Ver Figura 13.
M V T e c h | 230
SQL Server: Além do Conceito
Blog Post Collection
As colunas de dados baseadas em tempo permitem especificar maior que ou menor que. As colunas de
dados numeric permitem especificar igual, diferente, maior ou igual e menor ou igual. As colunas de dados
binários não podem ser filtradas.
Múltiplos filtros para uma única coluna são tratados com a condição OR. Por outro lado os filtros que
possuem várias colunas são tratados com a condição AND.
Você pode iniciar, parar e fazer uma pausa em um trace. Depois que foi iniciado o SQL trace retorna os
eventos correspondentes a sua necessidade e descarta os eventos que não correspondem aos critérios
dos filtros selecionados. Quando um trace é parado, toda a coleta de eventos termina e, se o trace for
reiniciado, todos os dados anteriores do trace são apagados da tela do Profiler. Caso queira suspender a
coleta de dados temporariamente, você pode pausar o trace. Quando tirar do pause os eventos
subsequentes são anexados no final da tela do Profiler.
P ERFORMANCE X M ONITORAMENTO
O SQL Trace é usado para coletar informações que ocorrem dentro de uma instância do SQL Server. O
“ ste à Mo ito à à usadoà pa aà oleta à pe fo a eà ou te s à que fornece o estado dos recursos de
hardware e outros componentes em execução no servidor. O SQL Server não pode funcionar sem acessar
os recursos de hardware. O estado desses recursos afeta o funcionamento de um servidor SQL Server. Por
exemplo, uma query pode estar sendo executada lentamente, mas o Profiler só informa o quanto ela está
lenta. Porém, adicionando os contadores de desempenho (performance counters) você poderia encontrar
a razão que estaria fazendo a query estar lenta. Nesse caso o motivo é porque não existem recursos de
processamento suficientes.
Embora seja possível diagnosticar um problema usando somente System Monitor ou o SQL Trace, quando
usamos simultaneamente os dois conjuntos de dados ambos fornecem o contexto para qualquer análise.
D ICA :
Vo às àpode à o ela io a àu à oute àlog à “ ste àMo ito à o àu à t a eàfile à “QLàP ofile àseàti e à
capturado a coluna de dados StartTime no trace.
C RIANDO T RACES
Vamos configurar um trace para estabelecer um parâmetro de desempenho para verificar a execução das
querys no banco de dados afim de descobrirmos o motivo de lentidão na aplicação.
Para fins de demonstração adotaremos o banco exemplo da Microsoft o AdventureWorks. Caso ainda não
os possua você poderá baixar as bases de dados AdventureWorks2008 e AdventureWorksDW2008 no
site do Code Plex.
M V T e c h | 231
SQL Server: Além do Conceito
Blog Post Collection
Inicie o Profiler. Selecione File > New Trace e conecte-se em sua instância.
Especifique o nome do para: SQL Magazine Trace, template: Blank e opções para salvar em um arquivo,
como mostrado na Figura 14.
Marque os eventos Lock: DeadLock graph e TSQL: SQL:BatchCompleted. Ver Figura 15.
M V T e c h | 232
SQL Server: Além do Conceito
Blog Post Collection
Clique em Column Filters e especifique o filtro DatabaseName: AdventureWorks e Duration > Greater than
or equal: 10000. Ver Figura 16.
M V T e c h | 233
SQL Server: Além do Conceito
Blog Post Collection
Clique em Run.
Crie um Data Colletor Sets e adicione os seguintes contadores: PhisicalDisk\Current Disk Queue Length,
PhisicalDisk\%Disk Time e Processor\%Processor Time.
Abra o SQL server Management Studio(SSMS), conecte-se na instância e execute as seguinte query.
USE AdventureWorks
GO
GO
GO 10000
DECLARE @I INT
SET @I = 0
WHILE @I < 1000000
BEGIN
IF EXISTS (SELECT ID FROM TabTeste WHERE ID = @I)
BEGIN
PRINT 'ENTROU NO LOOP'
END
SET @I = @I + 1
END
GO
M V T e c h | 234
SQL Server: Além do Conceito
Blog Post Collection
SELECT
Name,
ReorderPoint
FROM
Production.Product
WHERE
ProductID = 317
SELECT
*
FROM
Production.ProductInventory
WHERE
ProductID = 317
AND LocationID = 1
M V T e c h | 235
SQL Server: Além do Conceito
Blog Post Collection
Irá ocorrer um erro de deadlock. Ver Figura 17. Conforme mensagem abaixo:
Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen
as the deadlock victim. Rerun the transaction.
M V T e c h | 236
SQL Server: Além do Conceito
Blog Post Collection
Inicie o Profile novamente e selecione File > Open > Trace File.
Clique em File > Import Performance Data. Selecione o counter log criado no System Monitor.
Na janela Performance Counters Limit Dialog, selecione Processor: %Processor Time, .PhysicalDisk:
%DiskTime e Avg.Disk Queue Length. Ver Figura 19.
M V T e c h | 237
SQL Server: Além do Conceito
Blog Post Collection
Percorra o trace no painel superior e observe as alterações que ocorreram dentro no gráfico do
performance counter e do rastreamento do Profiler. Ver Figura 20.
Figura
M V T e c h | 238
SQL Server: Além do Conceito
Blog Post Collection
Conforme podemos observar no gráfico da Figura 16 o maior consumo de CPU foi à consulta que contém
o loop. À medida que vamos selecionando as linhas do trace o curso que tem no gráfico vai
movimentando-se a fim de mostrar exatamente estava acontecendo no banco de dados. Com isso
conseguimos identificar que o problema de performance da empresa AdventureWorks é uma consulta
mal escrita que está entrando em um loop e mais que isso existe uma outra query que está provocando
deadlock os dois problemas juntos acontecendo várias vezes durante o dia acarretou nas constantes
reclamações ao nosso suporte de primeiro nível. A solução para esse problema é a correção de ambas as
consultas.
D ICA *:
Os níveis de isolamento afetam a maneira como o SQL Server manipula as transações, assim como a
du aç oàdosà lo ksàa ui ed lo ueiosàad ui idos .àOà“QLà“e e àpossuià i oà í eisàdeàisola e toàoà ueà
estamos utilizando nesse exemplo é o READ SERIALIZABLE. Esse nível de isolamento emula a execução
serial das transações, como se todas as transações fossem executadas uma após a outra, em série, em vez
de simultaneamente. Nenhuma outra transação pode modificar dados que foram lidos pela transação
atual até que a transação corrente terminar.
CONCLUSÃO
Por fim, podemos observar que a união dessas duas ferramentas nos ajuda a ter uma visão muito mais
ampla dos problemas que estão acontecendo na base de dados.
Como podemos observar são muitas variáveis a serem consideradas, mas o que vai influenciar na escolha
dos contadores ou eventos vai ser o problema que estamos enfrentando. No caso demonstrado no artigo
a dificuldade que a empresa enfrentava era perca de desempenho, mas poderia ser a rede mal
configurada ou um gargalo de CPU, memória, disco e etc. Por isso, deve-se tomar muito cuidado na hora
de averiguar os diversos cenários aparecem no dia a dia, porque a solução do problema vai depender de
uma avaliação bem feita.
REFERÊNCIAS
M V T e c h | 239
SQL Server: Além do Conceito
Blog Post Collection
http://msdn.microsoft.com/en-us/library/bb510705.aspx
http://blog.sqlauthority.com/2009/04/24/sql-server-introduction-to-sql-server-2008-profiler/
http://msdn.microsoft.com/en-us/library/ms187929.aspx
http://blog.sqlauthority.com/2009/08/03/sql-server-introduction-to-sql-server-2008-profiler-2/
http://msdn.microsoft.com/en-us/library/ms190176.aspx
http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=18407.
M V T e c h | 240
SQL Server: Além do Conceito
Blog Post Collection
Olá Pessoal!
O post de hoje será sobre uma das tarefas fundamentais de um administrador de banco de dados (DBA)
que é garantir que os dados possam ser recuperados no caso de um desastre. No nosso dia a dia,
adquirimos várias coisas que possam nos deixar tranquilos com nossos bens como por exemplo uma
apólice de seguro para carro ou para sua casa. Apesar de caro e rezarmos para nunca usarmos é uma
a ei aà ueàes olhe osàpa aà osàassegu a à o t aà ual ue à i p e isto .ààE fi ,à oltando para o nosso
assunto, os backups são as apólices de seguro contra qualquer eventualidade na empresa em que
trabalhamos. O backup será o responsável por recuperarmos os dados que foram perdidos e no final das
contas o negócio voltar a fazer as suas operações empresariais rotineiras. Costumo dizer que ele é o
espo s elàpeloà fi alàfeliz àdeà ual ue àsituaç o.à s s .
Muitas vezes precisamos fazer um restore de uma base em um ambiente diferente do que nós temos,
seja ele para fins de teste de backup ou para um ambiente de homologação para que a equipe de
desenvolvimento faça seus testes antes de subir uma versão nova. Nesses casos existem diversas formas
de resolver o problema como fazer um backup remoto e trazer a base para o ambiente que você precisa
ou criar um job para fazer um backup copy only e depois fazer o restore a partir do arquivo gerado. Nesse
post para de atender essa necessidade criaremos um pacote para fazer um restore através de um FTP que
encontra-se em um servidor de domínio diferente para isso utilizaremos o SSIS, WINSCP e um pouco de
powershell.No final da criação do pacote, o mesmo ficará assim:
M V T e c h | 241
SQL Server: Além do Conceito
Blog Post Collection
Para configurar os FTP devemos primeiro instalar o WinSCP e configurar um site. A imagem abaixo mostra
como ficará após essa configuração:
A criação desse arquivo de texto será o que o WinSCP utilizará para pegar o arquivo no diretório que foi
definido para o backup ser salvo e levá-lo para a pasta no outro servidor onde será feito o restore.
M V T e c h | 242
SQL Server: Além do Conceito
Blog Post Collection
option batch on
option confirm off
open FTP_DATABASE
get /BACKUP/DATABASE/NOME_DATABASE_FULL_201411301300.BAK
S:\RESTORE\RESTORE_DATABASE\
exit
ágo aà o àoà“QLà “e e àDataàToolsà a e toà a osà olo a àu à E e uteàP o essàTask àeà o figu a àasà
propriedades: Executable, Arguments e WorkingDirectory.
M V T e c h | 243
SQL Server: Além do Conceito
Blog Post Collection
áàp i ei aà oisaàaàfaze à àpega àu àoà E e uteàP o essàTask àe arrastarmos para o Control Flow, conforme
imagem abaixo:
M V T e c h | 244
SQL Server: Além do Conceito
Blog Post Collection
á tesàdeà odifi a osàoà E e uteàP o essàTask ,à a osà ia àoàs iptàpa aà odifi a osàoàa ui oàdeà
texto. A lógica é simples:
Substituir ela por uma data (A data especificada nesse caso é a data que o backup full foi criado);
Salvar o arquivo;
M V T e c h | 245
SQL Server: Além do Conceito
Blog Post Collection
Script:
(Get-Content C:\FTP\ftpdatabase.txt) |
Set-Content C:\FTP\ftpdatabase.txt;
Onde:
Get-Content = Ler e exibir o
conteúdo de um arquivo de
texto de forma rápida.
Retorna do dia
anterior, com o
fo atoà MMdd
ForEach-Object= Fornece uma
maneira para percorrer e executar
uma ação.
Cli ueà o àoà ot oàdi eitoàpa aàa i àaà ai aàdeàp op iedadeàdoà E e uteàP o essàTask àeà a osàp ee he à
osà alo esàeàa gu e tosà e ess ioàpa aàedita àoàa ui o.àNaàopç oà P o ess àdoàE e uteàP o essàTaskà
Editor vamos alterar os campos Executable e Arguments, conforme imagem abaixo:
M V T e c h | 246
SQL Server: Além do Conceito
Blog Post Collection
Executable C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Arguments -ExecutionPolicy ByPass -command ". 'C:\FTP\ftppowershell.ps1'"
Vamos criar algumas variáveis que irão armazenar o nome do arquivo e o diretório que iremos utilizar
para fazer o restore. No menu do SSIS, clique em Variáveis ou clique com o botão direito em qualquer
luga àdoàCo t olàFlo àeàsele io eàaàopç oàà Va ia les .
M V T e c h | 247
SQL Server: Além do Conceito
Blog Post Collection
Clique em 'Add Variable' e atualize os valores nas colunas name, Data Type e Value. Conforme imagem
abaixo:
Vamos utilizar um Foreach Loop Container, o mesmo é muito útil em situações onde é necessário
percorrer uma pasta para fazer carga de arquivos ou fazer uma tarefa onde terá que verificar uma lista
mais de uma vez. Dê dois cliques no Foreach Loop Container Task para abrir a janela de configuração e
sele io eàaàopç oà Colletio .àálte eàoà a i hoàdaàpastaàpa aà “:\RESTORE\‘E“TO‘E_DáTáBá“E à C ieà
essa pasta caso não exista). Altere o tipo dos arquivos para *.bak .
M V T e c h | 248
SQL Server: Além do Conceito
Blog Post Collection
Na guia Variable Mappings selecione a variável User::NM_ARQUIVO na coluna Variable. O Index 0 mapeia
o resultado do primeiro (e único) enumerador do Foreach. Clique em OK.
M V T e c h | 249
SQL Server: Além do Conceito
Blog Post Collection
Va osàadi io a àu à E e uteà“ iptàTask àpara darmos alteramos a base para SINGLE_USER, conforme
imagem abaixo:
Script:
USE MASTER
GO
M V T e c h | 250
SQL Server: Além do Conceito
Blog Post Collection
A primeira propriedade que você precisa definir é ScriptLanguage. Você pode criar seus scripts em uma
das duas línguas: Visual Basic 2010 ou Visual C# 2010. Iremos usar o C#, para o verificarmos se o nome do
arquivo e o diretório do backup estão corretos.
A próxima propriedade é EntryPoint. Este é o método (específico para a linguagem de script selecionado)
que o tempo de execução SSIS chama como o ponto de entrada em seu código. O método Main, na
maioria dos casos, deve funcionar bem.
M V T e c h | 251
SQL Server: Além do Conceito
Blog Post Collection
os nomes com vírgulas para múltiplas variáveis de qualquer tipo.) Vamos adicionar a variável
User::NM_ARQUIVO a propriedade ReadOnlyVariables e a variável User::CAMINHO_ARQUIVO à
propriedade ReadWriteVariables. Como resultado, o meu script C# será capaz de recuperar a o diretório
de backup a partir das variáveis.
Cli ueàe à Edità“ ipt.. .à“e àa e taàu aàp gi aà oàVisualà“tudioàpa aàp og a a àoà ueà o àp e isa,à oà
nosso caso vamos editar o método Main().
Script:
Dts.Variables["CAMINHO_ARQUIVO"].Value =
Dts.Variables["NM_ARQUIVO"].Value.ToString();
nome =
Dts.Variables["CAMINHO_ARQUIVO"].Value.ToString();
M V T e c h | 252
SQL Server: Além do Conceito
Blog Post Collection
MessageBox.Show(nome);
Dts.TaskResult = (int)ScriptResults.Success;
}
Va osà adi io a à aisà doisà E e uteà “QLà Task .à Noà p i ei oà taskà se à aà p o edu eà ueà fazà oà esto eà
recebendo o diretório como parâmetro.
Script:
EXECUTE [DBO].[USP_RESTORE_DATABASE] ?
Eà oàsegu doà E e uteà“QLàTask àse àasàpe iss esàpa aàoàusu ioà ueàa essaàaà aseà estau ada.
M V T e c h | 253
SQL Server: Além do Conceito
Blog Post Collection
Script:
USE NOME_DO_DATABASE
GO
M V T e c h | 254
SQL Server: Além do Conceito
Blog Post Collection
Po àfi ,ài e osà olo a àout oà E e uteàP o essàTask àpa aàalte a àaàdataà olo adaà oàa ui oàdeàte toà
responsável de passar o nome do arquivo de backup no FTP. O objetivo dessa task é fazer como que da
próxima vez que o pa oteàfo àe e utadoàoàpo e shellà o tidoà oào jetoà MODIFYàFTPàFILE àe o t eàaà
pala aà COLOCá‘DáTááQUI ,àpa aàissoà astaà ia àout oàa ui oà .ps àeàalte a àaào de àdoàs ipt.à
Script:
(Get-Content C:\FTP\ftpdatabase.txt) |
Set-Content C:\FTP\ftpdatabase.txt;
Com a modificação do nome do arquivo concluímos o post com a criação do pacote para restore de bases
via FTP. Espero que todos tenham gosto e qualquer, duvida ou critica só entrar em contato.
M V T e c h | 255
SQL Server: Além do Conceito
Blog Post Collection
Constantemente, apesar de um vasto material sobre o assunto na net, me deparo com problemas de
configuração do Transaction Log, tais como:
Este assunto motivou a última palestra que fiz com meu amigo Marcus Vinícius Bittencourt [Twitter | Blog]
no SQL Saturday 147 em Recife e abordarei neste post.
INTRODUÇÃO
Antes de entrarmos no universo do Transaction Log, preciso fazer uma pequena introdução de como os
dados são trabalhados pelo SQL Server.
A gravação lógica ocorre quando os dados são alterados em uma página do Buffer Cache.
A gravação física ocorrendo quando a página é armazenada no disco a partir do Buffer Cache.
Se o dado a ser alterado não está em memória, ele é lido do disco e armazenado no Buffer Cache.
A alteração é efetuada no Buffer cache e a página é marcada como dirty pages (página suja).
O Database Engine utiliza o protocolo Write Ahead Log (WAL) para garantir que as dirty pages sejam
armazenadas primeiro no Transaction Log antes de serem persistidas em disco.
M V T e c h | 256
SQL Server: Além do Conceito
Blog Post Collection
As dirty pages são armazenadas em disco de modo assíncrono através dos processos Eager
Writing, Lazy Writing e Checkpoint.
T RANSACTION L OG
De posse da informação de como os dados são persistidos, temos ideia da carga de trabalho do
Transaction Log que o caracteriza como um componente crítico do SQL Server.
Toda alteração realizada em um Database é registrada nele.
Database Mirroring
Log Shipping
Replicação Transacional
...
Não entrarei em detalhes do comportamento do Transaction Log em cada modelo recuperação, pois
independente do modelo utilizado, o arquivo de log pode fragmentar.
Internamente, o log é dividido em pequenos blocos chamados de Virtual Log Files (VLF).
Além de ser a unidade de divisão do Transaction Log, o VLF permite o efeito circular do log através de sua
reutilização.
M V T e c h | 257
SQL Server: Além do Conceito
Blog Post Collection
Usando o exemplo de uma carga de dados que force um crescimento do arquivo de Log em 1000MB,
podemos ter:
A partir do exemplo acima, fica claro que uma configuração ruim para o Auto Growth do arquivo de Log
gerará muitos VLFs, caracterizando o que chamamos de Fragmentação Interna do Transaction Log.
A fragmentação interna causa impactos em todos os processos que utilizam o Transaction Log e nas
aplicações. (Sim... seus Updates e Inserts!!!)
Lembram que No início do post, informei a configuração default de criação do banco de dados. Lembra-
se?
M V T e c h | 258
SQL Server: Além do Conceito
Blog Post Collection
Para verificar as informações de VLFs do arquivo de log, utilizamos o comando DBCC LOGINFO.
A quantidade de linhas retornadas é justamente a quantidade de VLFs existentes no Database.
CreateLSN - LSN no momento da criação dos VLFs. Quando igual a 0 (Zero) são VLFs criados no Create
Database.
Ok. Já sabemos conceitualmente como o Transaction Log fica fragmentado e como analisar informações
internas do arquivo de Log. Mas como resolver a fragmentação?
M V T e c h | 259
SQL Server: Além do Conceito
Blog Post Collection
No post anterior, abordei sobre o Transaction Log, como ocorre sua fragmentação e como podemos
identificá-la.
Como prometido, neste post vamos verificar como resolver a fragmentação interna do Log.
Mãos à massa!
Para exemplificar, vou criar os Databases LargeVLF_Full, LargeVLF_Simple e SmallVLF com as seguintes
configurações para os arquivos de Log:
LargeVLF_Full com Tamanho de 1MB e File Growth de 10% no recovery model FULL.
LargeVLF_Simple com Tamanho de 1MB e File Growth de 10% no recovery model SIMPLE.
SmallVLF com Tamanho de 8000MB e File Growth de 4000MB no recovery model FULL.
M V T e c h | 260
SQL Server: Além do Conceito
Blog Post Collection
Após criar os Databases, vamos analisar como estão os VLFs dos arquivos de log através do comando DBCC
LOGINFO.
M V T e c h | 261
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 262
SQL Server: Além do Conceito
Blog Post Collection
Após a criação da tabela e execução dos inserts, vamos analisar como estão os arquivos de log de cada
Database.
M V T e c h | 263
SQL Server: Além do Conceito
Blog Post Collection
D ICA :
Você pode verificar o que está retendo o arquivo de log (status = 2) e impedindo a reutilização dos VLFs
através das colunas log_reuse_wait e log_reuse_wait_desc na sys.databases.
Neste caso, é o Backup de Log!
M V T e c h | 264
SQL Server: Além do Conceito
Blog Post Collection
No modelo Simple o log é automaticamente truncado, mas isso não o impede de ficar fragmentado.
Cuidado!
Observe que o FileSize dos VLFs nos Databases LargeVLF_Full e LargeVLF_Simple são diferentes a cada
crescimento. Isto é motivado pela configuração do File Growth em percentual.
M V T e c h | 265
SQL Server: Além do Conceito
Blog Post Collection
M V T e c h | 266
SQL Server: Além do Conceito
Blog Post Collection
Podemos afirmar que os Databases LargeVLF_Full e LargeVLF_Simple estão fragmentados! (Utilizo como
"referência" o valor máximo de 50 para quantidade de VLFs. Fonte: Kimberly Tripp)
E em relação aos impactos das operações de Inserts e Updates mencionados no primeiro post por você
Leandro?!
O arquivo de log não se beneficia do recurso Instant File Initialization. Quando é necessário o seu
crescimento, seus Updates e Inserts ficarão bloqueados até a conclusão do crescimento do arquivo de
log.
V AMOS TESTAR !
Para este teste, vamos realizar um update em todos os registros da Tabela nos Databases LargeVLF_Full
e SmallVLF, medindo o tempo de execução.
M V T e c h | 267
SQL Server: Além do Conceito
Blog Post Collection
Para verificar o que motivou esta diferença, vamos ao Default trace Log (Se não estiver desabilitado!).
M V T e c h | 268
SQL Server: Além do Conceito
Blog Post Collection
Só para realizar o Auto Growth do arquivo de Log do Database LargeVLF_Full foram gastos 1486ms.
Backup de Log.
Para facilitar minha vida, criei o script "Analise de Fragmentação" que ao ser executado realiza as
seguintes atividades:
M V T e c h | 269
SQL Server: Além do Conceito
Blog Post Collection
Exibe o tamanho e o percentual de utilização dos arquivos de log através do comando DBCC
SQLPERF(LOGSPACE).
Monta através de "Print", os comandos de ajustes para os Databases que apresentam mais de 50 VLFs.
Checkpoint.
Comando para alterar o File Size e File Growth (Recuperando o nome lógico do arquivo)
M V T e c h | 270
SQL Server: Além do Conceito
Blog Post Collection
Após analisar o ambiente e copiar os comandos gerados para uma nova janela de query, informe:
Execute novamente o script "Análise de fragmentação" para verificar se seu ambiente está normalizado.
I NFORMAÇÃO ADICIONAL
Ter poucos VLFs e de tamanho "considerável" também é prejudicial ao seu ambiente, pois irá impactar na
liberação de espaço do arquivo de Log. VLFs de no máximo 400/500MB é o indicado.
M ELHORES PRÁTICAS :
M V T e c h | 271
SQL Server: Além do Conceito
Blog Post Collection
Ajuste a frequência de Backup de Log para controlar o tamanho do seu arquivo de Log.
Não faça "BACKUP LOG ... WITH TRUNCATEONLY pois ele quebrará a sequência do Backup de Log.
Utilize transações curtas para que não retenha os VLFs por muito tempo.
Até o próximo!
M V T e c h | 272
SQL Server: Além do Conceito
Blog Post Collection
Lu ia o Moreira
luticm.blogspot.com
Dia 30/06/2011 foi o último dia do Luan Moreno na Sr. Nimbus e durante o almoço estávamos
conversando sobre o SQL Server (para variar um pouco), quando ele disse uma frase muito interessante
Qua doà o àl àdoàs apshotàoà“QLà“e e àfazàaàleitu aàdi etaà oàdis o .àFiz uma cara de interrogação e
depois dele explicar melhor entendi o que ele quis dizer: quando você tem um snapshot, as páginas do
banco de dados de origem não são compartilhadas com as do snapshot dentro do data cache.
Muito interessante! O Luan comentou que leu isso junto ao time do SQLCAT (referência fina e confiável),
e esta pequena observação que pode passar despercebida me levou a escrever este artigo, onde podemos
ter um potencial problema de data cache thrashing.
Primeiramente vamos analisar o funcionamento do data cache no SQL Server quando utilizado o database
snapshot. Por simplicidade criamos uma tabela onde cada registro ocupa uma página e inserimos 20.000
páginas de dados (script 1).
USE master
go
USE DataCache
go
M V T e c h | 273
SQL Server: Além do Conceito
Blog Post Collection
Quando o snapshot é criado um arquivo de dados é utilizado e aparentemente possui o mesmo tamanho
do original, mas somente as páginas que foram alteradas desde a criação do snapshot serão levadas para
o novo arquivo (sparse file), conforme a figura 01. Então para o banco de dados DataCache_Snapshot um
mapa de bits é criado em memória, para o SQL Server saber se deve ler uma página do arquivo original
ou do snapshot, indicando onde está a página correta para leitura.
Neste momento não tivemos alteração alguma, então todas as páginas que precisamos para os dois
bancos estão no arquivo original, vamos então executar um DBCC DROPCLEANBUFFERS para limpar o data
cache e executar os comandos abaixo. O que você espera em termos de I/O?
SET STATISTICS IO ON
DBCC DROPCLEANBUFFERS
GO
SELECT *
FROM DataCache.dbo.Dados
SELECT *
FROM DataCache_Snapshot.dbo.Dados
go
M V T e c h | 274
SQL Server: Além do Conceito
Blog Post Collection
No primeiro select temos o esperado, uma série de leituras físicas (seja read-ahead ou não) colocando as
páginas de dados em cache. E a segunda consulta? Já que não houve alterações nos dados nenhuma das
páginas estará no novo arquivo, e como todas as páginas carregadas pelo primeiro SELECT estão em cache,
então não é necessário ler nada do disco, correto?
Table 'Dados'. Scan count 1, logical reads 20076, physical reads 51, read-ahead reads 20055, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Dados'. Scan count 1, logical reads 20075, physical reads 50, read-ahead reads 20075, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.
Na verdade não! O data cache referencia as páginas através da combinação: banco de dados, arquivo e
página (dbid, fileid, pageid). Quando procura por uma página do novo banco de dados que não está em
cache, resta a ele fazer uma leitura no disco, referenciando o mapa de bits para saber se deve ler a página
do arquivo original ou do novo.
Se as consultas forem executadas novamente não será necessária nenhuma operação de I/O, pois as
páginas estão em cache. Consultando sys.dm_os_buffer_descriptors (script 4) veremos que temos uma
s ieàdeàp gi asà dupli adas ,à o àdife e çaàape asà oàdata ase_idà figu aà .à
select *
from sys.databases
where name like '%datacache%'
go
select *
from sys.dm_os_buffer_descriptors
where database_id in (DB_ID('DataCache'),
DB_ID('DataCache_Snapshot')) and file_id <> 2
order by page_id, database_id
go
M V T e c h | 275
SQL Server: Além do Conceito
Blog Post Collection
Em termos Internals, o SQL Server não reusa a estrutura BUF entre páginas do snapshot e banco de dados,
então as páginas ficarão duplicadas em cache, mesmo que não estejam presentes no arquivo de dados do
snapshot.
Até agora foi apresentado o funcionamento do database snapshot em relação ao data cache, mas qual é
o problema que me levou a escrever este artigo? Uma possível pressão no data cache por conta do SQL
Server não reutilizar as páginas entre snapshots!
Imagine um caso onde um DBA decide manter alguns snapshots do banco de dados (ex.: um snapshot por
dia) em um ambiente onde o volume de alterações é pequeno, então o overhead da operação copy-on-
write não é tão significativo. Durante a semana os dados de uma tabela são comparados entre os dias em
que o snapshot é tirado, sendo que isso acontece diversas vezes ao dia. Viu o potencial problema?
Vamos aos scripts, primeiro vamos definir o tamanho do buffer pool do SQL Server para 1GB e criar mais
alguns snapshots. Tendo a tabela 20.000 páginas aproximadamente, temos 8K * 20.000 páginas,
aproximadamente 160MB.
M V T e c h | 276
SQL Server: Além do Conceito
Blog Post Collection
RECONFIGURE
SHUTDOWN
go
Com cinco snapshots criados, se executarmos uma consulta que obriga o SQL Server a varrer cada página
da tabela, será colocado aproximadamente 960 MB no data cache (script 6). Como todas as páginas
couberam em memória após a execução dos seis primeiros SELECTs (sim, o I/O foi pesado), se eu executar
todas as consultas 10 vezes em seguida o tempo total de execução ficará em torno de 4 segundos.
DBCC DROPCLEANBUFFERS
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot3.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot4.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot5.dbo.Dados
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
M V T e c h | 277
SQL Server: Além do Conceito
Blog Post Collection
DBCC DROPCLEANBUFFERS
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot3.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot4.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot5.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot6.dbo.Dados
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot3.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot4.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot5.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot6.dbo.Dados
go 10
O segundo loop que forçou uma série de operações de I/O demorou entre 2:30 min e 3:00 min em minha
máquina, uma diferença considerável para os 4 segundos. Se você quiser ver um comportamento
diferente, tente alterar a ordem das consultas, para que o SQL Server não favoreça as páginas de alguns
bancos por conta do LRU-K.
Esse efeito eu chamo de data cache thrashing, pois é similar a um memory thrashing em relação ao paging
file. Obviamente foi um exemplo estruturado para mostrar o overhead deste no SQL Server, mas pense
no impacto que isso pode causar no seu ambiente quando colocado em paralelo com outros bancos de
dados disputando um espaço data cache. Se você cria vários snapshots com o objetivo de acelerar as suas
consultas (o que não é justificável), cuidado, você pode ser pego de surpresa pelo caso dos snapshots e o
data cache thrashing.
M V T e c h | 278
SQL Server: Além do Conceito
Blog Post Collection
Na correria do dia eu recebi uma ligação de um DBA questionando-me sobre um problema de deadlock
e, mesmo com o dia atolado, eu separei uns minutinhos para ajudá-lo. Bom, vamos ao problema:
Cenário: O cliente possui um problema de deadlock em algumas tabelas e depois de adicionar alguns
índices o problema deixou de acontecer. Mas o DBA (de forma bem perspicaz) ainda não está satisfeito
com o resultado e procurou minha ajuda para uma recomendação mais embasada.
Resposta: quase isso! Uma indexação correta pode acelerar as consultas e operações que estavam
entrando em deadlock, resultando em uma possibilidade menor da situação se repetir, então uma
indexação correta pode sim DIMINUIR (não eliminar, talvez somente em um caso ou outro) os deadlocks!
É uma abordagem que utilizamos quando estamos lidando com alguns deadlocks que são "by design", isto
é, não podemos alterar o código que causa o problema.
Segue um script que simula o problema original, foi bater o olho nele que eu já vi o deadlock, mas para
você que quer praticar um pouco, coloque o script em um banco qualquer e mãos à obra!
USE Inside
go
M V T e c h | 279
SQL Server: Além do Conceito
Blog Post Collection
Como vocês podem notar acima, a trigger é responsável por definir a numeração sequencial dos registros
na tabela, pegando o maior número atual da tabela.
<!-- Se você quiser analisar o problema e descobrir qual o deadlock, pare aqui e vá
brincar com o SQL Server -->
E NCONTRANDO O DEADLOC K
Se utilizarmos o SSMS e executarmos um insert simples (script abaixo), o SQL Server vai inserir um registro
na tabela (lock X - exclusivo) e depois executar um select na tabela procurando pelo maior número
existente, que atualizará o registro corrente com esse valor. Essa busca é um table scan e como a própria
transação possui um bloqueio exclusivo no registro que foi inserido, a trigger funciona que é uma beleza!
Veja parte dos planos nas figuras abaixo...
M V T e c h | 280
SQL Server: Além do Conceito
Blog Post Collection
Adicionando um pouco de concorrência no nosso banco de dados, podemos ver o problema acontecendo,
para isso basta disparar o script abaixo em conexões diferentes e depois de alguns segundos vamos ver a
e sage :à Msgà ,àLe elà ,à“tateà ,àP o edu eàt gI_Deadlo kT igge ,àLi eà àT a sa tio à P o essà
ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock
victim. Re u àtheàt a sa tio .
WHILE 1=1
BEGIN
INSERT INTO DeadlockTrigger (Codigo, marca, numero, Qtde) VALUES
(1, 'Sr. Nimbus', '61 30102050', 300)
END
Quais foram os recursos que entraram em deadlock? Usando o profiler podemos capturar a seguinte
informação:
M V T e c h | 281
SQL Server: Além do Conceito
Blog Post Collection
Analisando a sequência das operações fica evidente que o temos o cenário onde a transação 1 insere um
registro e logo depois a transação 2 insere mais um registro. No momento em que a transação 1 volta a
executar a trigger e o update faz o select (table scan) a transação 1 fica bloqueada pelo lock exclusivo da
transação 2, quando a transação 2 entra para execução ela fica bloqueada pelo lock exclusivo da transação
01. Como resultado temos um deadlock.
A maneira encontrada pelo cliente de minimizar o problema foi criar um índice no campo Numeracao,
conforme o script abaixo:
O que muda com esse índice? Ao invés do update da trigger realizar um table scan, ele passa a fazer um
index seek no idx_Numeracao, então como o registro é inserido com numeração = 0 (constraint default),
ele estará em um ramo do índice diferente do MAX(numeracao), permitindo que a consulta seja feita sem
problema de bloqueio entre S e X (visto na figura 03).
Então estamos livres do problema? Aparentemente sim, mas basta executar novamente os loops
concorrentes que vemos a mesma mensagem 1205!
M V T e c h | 282
SQL Server: Além do Conceito
Blog Post Collection
O problema não está mais com o select MAX(numeracao) do update! Agora o problema está com a
atualização dos registros que possuem numeracao = 0, pois em determinado momento podemos ter dois
registros com o valor zerado (de transações diferentes) e enquanto o SQL Server está varrendo o índice à
procura do objeto (usando o lock de Update) ele vai encontrar um registro bloqueado por outra transação
e vice-versa.
Então a criação do índice nesse caso somente está mudando um pouco o tipo de deadlock que
encontramos, saindo de um X com S para um X com U. E potencialmente, com uma tabela grande, a
chance de encontrarmos um deadlock fazendo um table scan é MUITO maior do que utilizando um index
seek.
Resultado: O cliente pode estar com a falsa impressão de que resolveu o problema de deadlock. O que é
muito ruim, pois esse irá se tornar um erro intermitente, daqueles mais chatos de entender.
Outra abordagem que o pessoal poderia tentar, e vejo muito por aí, seria tentar evitar o problema do
deadlock X com S utilizando uma hint de NOLOCK durante a busca do update, da seguinte forma:
Dessa forma realmente não veríamos mais deadlocks S com X, mas cairíamos novamente no problema do
deadlock X com U e provavelmente com uma freqüência maior que a primeira abordagem, pois sendo um
update menos eficiente a transação toda levaria mais tempo, aumentado a chance do problema ocorrer.
Concorda?
M V T e c h | 283
SQL Server: Além do Conceito
Blog Post Collection
Por motivos de negócio ou até históricos é normal vermos algumas soluções que acabam deixando de
lado os recursos da ferramenta, que potencialmente são mais eficientes. No caso acima fica patente que
a utilização de um campo IDENTITY resolveria o problema do cliente, basta criar a tabela com o script
abaixo (e sem a trigger, claro!) que o problema do deadlock vai embora.
Caso a resolução do problema ainda não seja suficiente para convencer o cliente, podemos ver o lado de
desempenho da solução com a trigger. Após inserir uma pequena massa de dados (13.000 registros) eu
executei um insert e mostro na figura 05 o plano de execução:
M V T e c h | 284
SQL Server: Além do Conceito
Blog Post Collection
Note que aqui estou utilizando a versão inicial do problema (sem o índice), onde um table scan pesa muito
no custo relativo de update no batch, isto é, do custo total para se fazer o insert a trigger é responsável
por 95%.
E a solução com índice versus a solução com o campo IDENTITY, qual será mais barata? Para verificar a
resposta dessa questão eu criei o índice idx_Numeracao na tabela e criei a tabela DeadlockTrigger2, que
possui um IDENTITY no campo Numeracao e nenhuma trigger. Veja o resultado na figura 06.
O insert no primeiro caso é responsável por 86% do custo total de batch, enquanto o custo do segundo
insert é de 14%. Claramente podemos notar que a segunda abordagem é mais eficiente que a primeira,
além de resolver o problema de deadlock, então porque não utilizá-la?
CONCLUSÃO
M V T e c h | 285
SQL Server: Além do Conceito
Blog Post Collection
É importante analisarmos com cuidado quando um problema foi efetivamente resolvido, pois paliativos
podem nos enganar e criar problemas ainda maiores para o futuro. Sempre que existe uma abordagem
de implementação da solução utilizando recursos da própria ferramenta, eu dou preferência a eles, pois
existe uma boa probabilidade de e serem mais eficientes e livres de efeito colateral.
Abraços
M V T e c h | 286
SQL Server: Além do Conceito
Blog Post Collection
Como vocês já podem ter visto, nós na Nimbus gostamos de detalhes do SQL Server, quanto mais interno
(ou misterioso) mais divertido. Hoje mostro para vocês um pequeno aspecto relacionado aos tipos de
dados, que inclusive já encontramos em um cliente e um ajuste gerou um grande e positivo impacto no
desempenho do ambiente SQL Server.
A dúvida: VARCHAR(MAX) e TEXT são sinônimos no SQL Server? Se você olhar o que o tipo de dados pode
armazenar parecem ser idênticos, então se é só uma diferença de sintaxe tanto faz qual eu utilizo, mas
levando em conta que o TEXT está marcado como deprecated, e só trocar tudo por VARCHAR(MAX) e
correr para o abraço! Calma lá campeão, vamos a um exemplo simples (rode o script 01)...
USE tempdb
go
M V T e c h | 287
SQL Server: Além do Conceito
Blog Post Collection
GO 10000
Quando você executar o script acima vai encontrar o plano esperado para as duas consultas, um clustered
index scan pegando os 10.000 registros. O que pode te pegar de surpresa é o custo relativo, 2% contra
98% (figura 01). Isso mesmo, SÓ essa pequena diferença. Utilizando o STATISTICS IO, vemos o motivo
dessa diferença:
Mas qual o motivo dessa diferença? Quando você utiliza o VARCHAR(MAX), caso o seu large object (LOB)
caiba dentro da página de dados de 8K (nesse casso os 2.000 bytes cabem), o SQL Server vai favorecer
essa opção, diferente do TEXT! Isso é, se você está consultando na maioria do tempo outras colunas que
não a sua LOB, o SQL Server está carregando para o data cache páginas com baixa quantidade de registros,
minimizando a eficiência do seu cache e consequentemente, o desempenho geral do SQL Server. Então
existem diferenças e você pode ver o detalhe com algumas DMVs.
M V T e c h | 288
SQL Server: Além do Conceito
Blog Post Collection
SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go
Na figura 02 podemos ver que a tabela com TEXT possui poucas páginas de dados (IN_ROW_DATA),
contendo em seus registros ponteiros para unidades LOB onde efetivamente os dados estão. Já no
VARCHAR(MAX) as unidades de alocação de LOB_DATA não estão em uso, com used_pages igual a zero
(ROW_OVERFLOW pode ser ignorado para esse artigo).
Viu a diferença? Pequeno detalhe que pode impactar (e muito!) o seu ambiente. E agora você pode estar
se perguntando, como eu altero esse modo de operação? Simplesmente executar um REBUILD do índice
não vai fazer com que ele mude seu comportamento.
-- SP_TABLEOPTION!!
M V T e c h | 289
SQL Server: Além do Conceito
Blog Post Collection
-- rebuild
ALTER INDEX PK_TabelaVARMAX
ON dbo.TabelaVARMAX
REBUILD
go
SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go
UPDATE dbo.TabelaVARMAX
SET Texto = Texto
GO
-- E agora, 100%?
SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
M V T e c h | 290
SQL Server: Além do Conceito
Blog Post Collection
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go
SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go
-- Organizando a casa...
ALTER INDEX PK_TabelaVARMAX
ON dbo.TabelaVARMAX
REBUILD
go
SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
M V T e c h | 291
SQL Server: Além do Conceito
Blog Post Collection
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go
-- Agora sim...
SELECT ID, Nome FROM dbo.TabelaTEXT
SELECT ID, Nome FROM dbo.TabelaVARMAX
Go
Oàs iptàa i aà ost aàoàusoàdoàsp_ta leoptio à o àaàopç oà la geà alueàt pesàoutàofà o ,à ue definido
“egu doàoàBOLàsig ifi a:à à=à a ha a ,à a ha a ,à a i a a ,à làa dàla geàuse -defined
type (UDT) columns in the table are stored out of row, with a 16- teàpoi te àtoàtheà oot ,àe ata e teàoà
que queremos.
Um aspecto curioso que me chamou a atenção quando estávamos resolvendo o caso do cliente, e que
você vai poder notar no script completo que acompanha o artigo, é que uma vez habilitada essa opção o
rebuild do índice NÃO fez a organização que eu esperava. Foi necessário um UPDATE dummy da coluna
VARCHAR(MAX) em todos os registros para o SQL Server colocar efetivamente o ponteiro de 16 bytes para
o LOB nas sua devida unidade de alocação.
Mesmo assim você vai notar que os custos do plano de execução se mantiveram mesmo após o UPDATE,
pois não houve nenhuma operação para organizar os registros no índice cluster, então a baixíssima
densidade de registros por páginas se manteve, com uma gigante fragmentação interna. Com o UPDATE
+ REBUILD conseguimos o que queríamos e os planos agora são bem compatíveis! Ainda ficou uma
diferença entre o número total de páginas no índice cluster, mas agora essa diferença é pequena e
gerenciável, quem sabe não falamos sobre isso em outro post...
M V T e c h | 292
SQL Server: Além do Conceito
Blog Post Collection
Nilto Pi heiro
www.mcdabrasil.com.br/
Então, neste tópico veremos como esses tipos de dados se diferenciam um do outro, como eles
armazenam seus dados e como trabalhar com esses dados. Abordaremos também algumas funções
internas do SQL Server que simplificam muito o trabalho com estes tipos de dados.
Estes são dois tipos de dados bastante utilizados no SQL Server para trabalhar com valores data e hora. A
diferença básica entre os dois, está na quantidade de bytes utilizados para o armazenamento da
data/hora, o range de datas suportadas e suas precisões.
Enquanto o DateTime usa 8 bytes para o armazenamento, o SmallDateTime usa apenas 4 bytes e é por
essa razão que o DateTime consegue armazenar um range maior de datas e também possui uma maior
precisão que o SmallDateTime.
O DateTime armazena datas de 1 de Janeiro de 1753 até 31 de Dezembro de 9999 com uma precisão de
3.33 milissegundos ou 0.00333 segundos, sendo os valores arredondados para incrementos de .000, .003
ou .007 segundos, como mostrado na Tabela 1.
M V T e c h | 293
SQL Server: Além do Conceito
Blog Post Collection
Observe que os horários com milissegundos entre .990 e .991 foram arredondados para .990. Os valores
entre .992 e .994 foram arredondados para .993 e os valores entre .995 e .998 foram arredondados para
.997
O SmallDateTime armazena datas de 1 de Janeiro de 1900 até 6 de Junho de 2079 com precisão de 1
minuto. Valores SmallDateTime com 29.998 segundos ou menos, são arredondados para o minuto
anterior, valores com 29.999, são arredondados para o minuto superior. Alguns exemplos podem ser
vistos na Tabela 2.
Exemplo Arredondamento
2014-05-08 12:35:29.998 2014-05-08 12:35:00
2014-05-08 12:35:29.999 2014-05-08 12:36:00
Tabela 2. Exemplos de arredondamento com SmallDataTime
Um ponto importante para ter sempre em mente é que tanto o DateTime quanto o SmallDateTime
representam a data e hora como um valor que é igual ao número de dias decorridos desde a meia-noite
doàdiaà àdeàJa ei oàdeà ,à o he idaà o oà dataà ase .àNoàe ta to,à o oàdes itoàa te io e te,àoà
SmallDateTime somente pode representar datas a partir desta data base em diante. Já o DateTime,
também pode representar datas que estejam antes de 1 de Janeiro de 1900 e para fazer isso, ele armazena
os valores como números negativos.
Valores DateTime são armazenados internamente pelo SQL Server como sendo 2 inteiros de 4 bytes
(totalizando 8 bytes de armazenamento). Os primeiros quatro armazenam o número de dias decorridos
antes ou após a data base. Os outros quatro armazenam a hora do dia representada como unidades de
0.00333 segundos após a meia noite. Já valores para SmallDateTime são armazenados como sendo 2
inteiros de 2 bytes (totalizando 4 bytes de armazenamento). Os primeiros dois armazenam o número de
dias decorridos desde 1 de Janeiro de 1900. Os outros dois armazenam o número de minutos desde a
meia noite.
Para entender como os valores data e hora são armazenados no SQL Server, divida o valor data e hora em
duas partes a saber: a parte inteira e a parte fracional.
A parte inteira representa o número de dias decorridos desde a data base. A parte fracional representa a
parte horas, decorridas desde a meia-noite da data base.
Para que você possa entender melhor, imagine que estamos em 4 de Janeiro de 1900 ao meio-dia.
Internamente, o valor que representa essa data e hora é armazenado como 3.5. Ou seja, o número inteiro
três representa o número de dias decorridos desde a data base e a fração 0.5 representa a metade do dia
M V T e c h | 294
SQL Server: Além do Conceito
Blog Post Collection
transcorrido desde a meia-noite. Para simular isso no SQL Server, basta executar a consulta a seguir no
SQL Server Management Studio:
SELECT CAST(CAST('1900-01-04 12:00' AS DateTime) AS Float)
No exemplo, utilizamos a função CAST para converter a string 1900-01-04 12:00 para DateTime e depois
para Float. Como resultado temos o valor 3.5 do tipo Float representando então a data.
Se usarmos o mesmo SELECT passando como string a data 2015-01-30 12:00, teremos como resultado o
valor 42031.5 onde 42032 representa o número de dias decorridos desde a data base e 0.5 a metade do
dia desde a meia noite.
Uma característica destes dois tipos de dados é que eles não podem armazenar datas sem hora e nem
hora sem data. Como consequência, se você armazenar uma data sem informar a parte hora, a parte que
representa a hora será definida como 0.
Isso será representado como meia-noite utilizando o formato 00:00:00 se estiver utilizando um campo do
tipo SmallDateTime ou 00:00:00.000 se estiver utilizando um campo DateTime. Similarmente, se você
armazenar apenas a hora sem informar uma data, a parte que representa a data será definida como 0.
Isso será representado como 1 de Janeiro de 1900 para ambos os tipos de dados. Para entender melhor,
execute o código a seguir no SQL Server Management Studio:
O script cria a tabela TB_DATAS com as colunas Parte_Data (DateTime) e Parte_Hora (SmallDateTime) e
resultado de sua execução pode ser visto na Figura 1. No primeiro INSERT, observe que para na coluna
Parte_Data é informada apenas a parte referente à data (a hora está como 00:00:00.000) e para a coluna
Parte_Hora, apenas a parte referente à hora (a data está como 1900-01-01). No segundo INSERT é feito o
processo inverso.
M V T e c h | 295
SQL Server: Além do Conceito
Blog Post Collection
Observe que para ambos os tipos de dados, para as datas informadas sem a parte hora o SQL Server
considerou a hora como sendo 0 ou meia-noite. Já para as datas sem a parte data o SQL Server considerou
a data como sendo 1 de Janeiro de 1900. Ou seja, a data base.
É importante notar que o mesmo acontece quando você faz um SELECT em um campo data que usa estes
tipos de dados. Vejam o exemplo a seguir:
No exemplo, o primeiro SELECT utiliza a função CAST para converter a string representando a data para o
tipo DateTime, enquanto o segundo converte para o tipo SmallDateTime.
Observe que o primeiro CAST passa uma data sem informar a parte hora (2015-01-30), então o SQL Server
entende que a parte hora é meia-noite ou 00:00:00.000. O segundo CAST informa apenas a parte hora
(10:00), então o SQL Server entende que a data é 1 de Janeiro de 1900.
Entendido como o SQL Server trata e armazena as datas para estes tipos de dados, vamos ver então como
fazer pesquisas com datas no SQL Server. Para um melhor entendimento, considerem uma tabela de
pedidos com os registros apresentados na Figura 3.
M V T e c h | 296
SQL Server: Além do Conceito
Blog Post Collection
O script para criação da tabela e população dos dados de exemplo encontra-se na Listagem 1.
Uma pesquisa muito comum quando trabalhamos com data e hora é pesquisar por registros de uma
determinada data independente da hora. Usando os dados da tabela de pedidos, um exemplo seria
pesquisar por todos os pedidos enviados no dia 10-08-2014.
M V T e c h | 297
SQL Server: Além do Conceito
Blog Post Collection
Se a data na coluna estiver sendo armazenada com a parte hora sendo 0 (como no caso do registro 5),
não haverá problemas pois como vemos, quando você pesquisa por uma data sem informar a parte hora,
o SQL Server considera a hora como sendo 0 ou meia-noite. Dessa forma buscará por todos os registros
que contenham a data 10-08-2014 e a parte hora como 00:00:00.
No entanto, como podemos ver nos dados de exemplo, tanto a coluna Data_Pedido quanto a Data_Envio
são usadas de forma inconsistente, ou seja, as vezes a parte hora é informada e as vezes não. Isso pode
indicar que o objetivo do desenvolvedor era armazenar somente a parte data, mas isso não foi forçado
pela aplicação e acabou gerando registros com a parte hora diferente de 0.
A conseqüência disso é que se você disparar uma consulta querendo saber todos os pedidos com data de
envio igual a 10-08-2014 (sem informar a parte hora), o resultado obtido não será o esperado.
Ao executar, o resultado mostra somente o registro 5 quando o desejado seria retornar os registros 5 e 6.
Isso acontece porque como a parte hora não foi informada na pesquisa, o SQL Server pesquisará pela data
onde a parte hora seja 0. Uma vez que a hora para o registro 6 é 17:20:00, o mesmo não é retornado.
Sendo assim, como podemos fazer para contornar esse problema? Se esse tipo de consulta for muito
utilizada por sua aplicação, a sugestão é que você passe a trabalhar com range de valores. Exemplo:
Lembre-se que a cláusula BETWEEN obtém valores que estão entre o primeiro e o segundo valor
informado (também conhecidos como limites inferior e superior). Você não pode definir o limite superior
como 2014-08-10. Se o fizer, novamente obterá como retorno apenas o registro 5, pois o SQL Server
tratará a hora como sendo 0.
Observe que no exemplo, o limite superior foi defi idoà o oà -08- à : : . .àCo àisso,àoà“QLà
“e e à us a à po à todosà osà egist osà e t eà -08- à : : . à eà -08- à : : . ,à
pega doàassi àtodoàoà a geàdeàho ioàdoàdiaà -08- àeào te doàe t oàtodosàosà egist osàdesteàdia.
Veja o resultado na Figura 4.
M V T e c h | 298
SQL Server: Além do Conceito
Blog Post Collection
Um outro caminho para obter o resultado esperado é usando operadores de comparação >= (maior igual)
e < (menor), como demonstrado no código:
F UNÇÕES E C ONVERSÕES
Uma prática comum de muitos desenvolvedores é fazer uso de algumas funções internas do SQL Server
para simplificar o trabalho com datas e algumas das funções mais comuns estão listadas na Tabela 3.
M V T e c h | 299
SQL Server: Além do Conceito
Blog Post Collection
Caso sua consulta seja utilizada com pouca frequência, você pode realmente fazer uso de algumas dessas
funções para simplificar o trabalho com as datas. No entanto, de uma forma geral esta não deve ser
considerada uma boa prática. Isso porque embora a utilização de funções permita obter os resultados de
forma relativamente simples, quando você usa uma função em uma condição de busca, você acaba
matando o índice da tabela caso um índice exista sobre a coluna do tipo data. Ou seja, o SQL Server acaba
não usando o índice para otimizar a pesquisa ou acaba fazendo um SCAN no índice.
Usando ainda os dados de exemplos da tabela de pedidos (Figura 3), uma opção seria utilizar a função
CONVERT para obter todos os registros com Data_Pedido igual a 10-08-2014.
M V T e c h | 300
SQL Server: Além do Conceito
Blog Post Collection
Neste exemplo a função converte o campo Data_Pedido para um VarChar de 10 posições, pegando assim
apenas a parte data no formato dd/mm/yyyy e comparando com o valor 10/08/2014. Como resultado, o
SELECT retornará os registros 5 e 6, os mesmo retornados na Figura 4. Porém, ao verificar o plano de
execução desta consulta (Figuraà à àpossí elà e à la a e teà ueàoà“QLà“e e àe e utouàu à I de à“ a à
sobre o índice existente para a coluna Data_Pedido.
Observe então na Figura 6 que isso já não acontece quando uma função de conversão não é utilizada.
Podemos verificar isso com o script abaixo.
M V T e c h | 301
SQL Server: Além do Conceito
Blog Post Collection
Um outro exemplo para obter os mesmos resultados seria utilizar as funções MONTH e DAY e YEAR:
Novamente, embora o uso de funções seja uma solução possível, sua utilização deve ser extremamente
evitada. Isso porque como vocês devem imaginar a função será chamada para cada registro da tabela,
matando então o índice da tabela e gerando um alto consumo dos recursos do servidor. Para uma tabela
com milhões de registros, essa prática certamente resultará em possíveis impactos na performance.
Minha sugestão é que procurem utilizar a solução com o BETWEEN ou os operadores de comparação >=
(maior igual que) e < (menor que)
Realizar uma consulta que busque por uma hora específica é semelhante a realizar uma consulta que
busque apenas por uma data (sem a hora). Se a coluna armazenar apenas a parte referente a hora, a
busca pela hora será simples.
No entanto, diferente dos valores data, o valor referente a hora é representado por um valor numérico
aproximado. Podemos ver isso facilmente ao executarmos a seguinte instrução, onde o valor retornado
será 0,983321759259259:
Para ilustrar a pesquisa apenas pela hora, considerem uma tabela de apontamento de horas com os
registros apresentados na Figura 6.
M V T e c h | 302
SQL Server: Além do Conceito
Blog Post Collection
O script para criação da tabela e população dos dados de exemplo encontra-se na Listagem 2.
Aqui a coluna Hora_Entrada é utilizada de forma inconsistente, ou seja, algumas vezes armazenando
somente a hora (a parte data é definida como 1 de Janeiro de 1900), outras vezes armazenando a data e
a hora (registros 3 e 4).
Com isso, se você utilizar a consulta a seguir para obter apenas os registros com hora de entrada igual a
08:30, você terá como resultado apenas o registro de ID 1:
O registro de ID 3 não é retornado porque quando se pesquisa apenas pela hora o SQL Server entende
que a parte referente à data deve ser 1900-01-01 (zero), o que equivale à data base. Por outro lado, o
registro de ID 5 não é retornado porque embora o valor esteja bastante próximo, o mesmo não é 08:30.
Com a execução do código a seguir é possível ver como o SQL Server entende esses dois horários em
formato numérico:
M V T e c h | 303
SQL Server: Além do Conceito
Blog Post Collection
Caso execute o código acima você notará que a hora 08:30 é entendida pelo SQL Server como o valor
numérico 0,354166666666667, enquanto que a hora 08:30:01.997 é entendida como
0,354189776234568. Ou seja, realmente são bem diferentes.
Nesses casos, para ignorar a parte data de uma coluna DateTime ou SmallDateTime, você pode utilizar a
função CONVERT para separar o valor hora de seu componente data:
Se a parte hora for armazenada de forma inconsistente, então você também poderá considerar a
realização de pesquisas por range de valores hora. A seguinte instrução também retorna os registros 1, 3
e 5:
Infelizmente, para obter a parte hora não existe uma maneira de obter esse resultado sem usar uma ou
mais funções, mas como dito anteriormente, por razões de performance evite a utilização de funções em
campos utilizados em busca.
Se a parte hora for armazenada de forma consistente, ou seja, sem a parte referente a data, como é o
caso da coluna Hora_Saida. Você poderá evitar a utilização de funções fazendo uso de consultas como as
M V T e c h | 304
SQL Server: Além do Conceito
Blog Post Collection
apresentadas abaixo. Mas lembre que neste caso será retornado apenas os registros onde a parte data é
1900-01-01.
Nestes exemplos, ambas as consultas retornam os registros 2, 4 e 6. Um outro caminho para trabalhar
mais facilmente com valores hora é usar o data type SmallDateTime no lugar do DateTime.
Uma vez que o SmallDateTime sempre arredonda a parte hora para o minuto mais próximo (acima ou
abaixo), as horas que estiverem entre 08:59:29.999 e 09:00:29.998 serão armazenadas como 09:00. Se
esse tipo de arredondamento for possível para sua aplicação, então o uso do SmallDateTime evitará a
necessidade de buscas por range de valores hora.
CONCLUSÃO
Como vimos no decorrer deste artigo, o trabalho com data no SQL Server é relativamente simples quando
entendemos como o servidor armazena e trata os valores. Um dos primeiros pontos a saber quando
trabalhamos com data é se realmente precisará de uma precisão de milissegundos.
Com isso você já decidirá entre o tipo de dados DateTime ou SmallDateTime. Lembre-se que o DateTime
ocupa mais espaço (8 bytes) que o SmallDateTime (4 bytes) e quando seu objetivo é tratar apenas a parte
hora, pode lhe obrigar a trabalhar com ranges de valores hora.
O segundo ponto é sempre garantir a consistência dos valores, ou seja, quando o importante é a parte
data tente manter a parte hora sempre como 0, quando o importante for a parte hora, tente manter a
parte data sempre como 1 de Janeiro de 1900. Com certeza esses cuidados simplificarão muito seu
trabalho com valores data e hora.
M V T e c h | 305
SQL Server: Além do Conceito
Blog Post Collection
Uma necessidade bastante comum em um ambiente SQL Server está em monitorar as operações DML
executadas sobre uma tabela. A partir dpo SQL Server 2008 isso pode facilmente ser alcançado com o uso
do CDC (Change Date Capture). No entanto, isso também pode ser facilmente alcançado usando a cláusula
OUTPUT.
Então, para demonstrar a utilização da cláusula OUTPUT, usaremos como exemplo a tabela
CartaoDeCredito que pode ser criada em qualquer banco de dados utilizando o script da Listagem 1. O
script cria a tabela e a popula com dois regsitros e em nosso exemplo, esta será a tabela a ser auditada. A
auditoria tem como objetivo monitorar os usuários que fizeram alterações nos números dos cartões de
crétido.
Conhecendo os objetivos e a estrutura da tabela a ser auditada, é preciso então ter uma segunda tabela
que será usada para armazenar os dados da auditoria, chamaremos aqui de "tabela espelho". Uma
observação muito importante sobre esta tabela é que para receber as linhas da cláusula OUTPUT ela não
pode possuir triggers, check contraints ou qualquer foreign key referenciando suas colunas ou colunas de
outras tabelas.
Então, com o script apresentado na Listagem 2 é possível criar a tabela que armazenará os dados
auditados durante as operações de INSERT, UPDATE e DELETE sobre a tabela CartaoDeCredito. Notem
que esta tabela possui duas entradas para cada coluna da tabela a ser auditada. A coluna com o prefixo
INSERT armazenará os dados inseridos e a coluna com o prefixo DELETE os dados excluídos. Outro ponto
a ser observado são as duas últimas colunas do script (INSERT_Usuario e DELETE_Usuario). Estas colunas
existem apenas na tabela espelho e serão utilizadas para guardar a informação referente ao nome do
M V T e c h | 306
SQL Server: Além do Conceito
Blog Post Collection
usuário que modificou o registro na tabela CartaoDeCredito. Para obter esta informação será usada a
função de sistema SUSER_SNAME() que retorna o nome do usuário que executou a operação.
CREATE TABLE dbo.CartaoDeCredito_Espelho (
AuditoriaID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
ComandoDML varchar(10),
INSERT_CreditCardID int NULL,
DELETE_CreditCardID int NULL,
INSERT_CardType [nvarchar](50) NULL,
DELETE_CardType [nvarchar](50) NULL,
INSERT_CardNumber [nvarchar](25) NULL,
DELETE_CardNumber [nvarchar](25) NULL,
INSERT_ExpMonth [tinyint] NULL,
DELETE_ExpMonth [tinyint] NULL,
INSERT_ExpYear [smallint] NULL,
DELETE_ExpYear [smallint] NULL,
INSERT_ModifiedDate [datetime] NULL,
DELETE_ModifiedDate [datetime] NULL,
INSERT_Usuario varchar(50) NULL DEFAULT SUSER_SNAME(),
DELETE_Usuario varchar(50) NULL DEFAULT SUSER_SNAME()
)
Listagem 2: Script para criação da tabela CartaoDeCredito_Espelho
Agora que você conhece a estrutura da tabela espelho, com o script da Listagem 3 é possível executar um
INSERT sobre a tabela CartaoDeCredito para populá-la com um registro.
-- INSERT
INSERT dbo.CartaoDeCredito
(CardType,CardNumber,ExpMonth,ExpYear,ModifiedDate)
-- Início bloco OUTPUT
OUTPUT 'INSERT',
Inserted.CreditCardID,
Inserted.CardType,
Inserted.CardNumber,
Inserted.ExpMonth,
Inserted.ExpYear,
Inserted.ModifiedDate
INTO dbo.CartaoDeCredito_Espelho
(ComandoDML,INSERT_CreditCardID,INSERT_CardType,INSERT_CardNumber
,INSERT_ExpMonth,INSERT_ExpYear,INSERT_ModifiedDate)
-- Fim bloco OUTPUT
VALUES ('Amex','33333333333333',12,2020,'20150105')
Listagem 3: Script para carregar a tabela CartaoDeCredito
Note que a cláusula OUTPUT esta posicionada entre as palavras chaves INSERT e VALUES (em negrito na
Listagem 3). Em verdade, observando atentamente é possível notar que a instrução de INSERT é muito
semelhante a uma instrução de INSERT qualquer, a grande diferença no uso da cláusula OUTPUT está no
M V T e c h | 307
SQL Server: Além do Conceito
Blog Post Collection
fatoàdeàte à ueàa es e ta àoà digoàdesta adoàe t eàosà o e t iosà —Início bloco OUTPUT e –Fim bloco
OUTPUT). Tirando este bloco, a instrução de INSERT ficaria como abaixo:
INSERT dbo.CartaoDeCredito
(CardType,CardNumber,ExpMonth,ExpYear,ModifiedDate)
VALUES ('Amex','33333333333333',12,2020,'20150105')
Outro ponto importante, notem na Listagem 3 que após o INTO dbo.CartaoDeCredito_Espelho tem-se
então a lista das colunas da tabela CartaoDeCredito_Espelho onde os dados devem ser inseridos. Como a
operação de INSERT utiliza apenas a tabela virtual INSERTED, a lista de colunas possui apenas as colunas
correspondentes.
Assim como uma trigger de INSERT, a cláusula OUTPUT também faz uso da tabela virtual INSERTED para
obter os dados afetados pela operação DML de INSERT. Quando usamos uma trigger, esta faz uso de duas
tabelas chamadas INSERTED e DELETED. Estas tabelas são tabelas virtuais que existem apenas durante o
tempo de execução da trigger e podem ser usadas para capturar o antes e depois de uma operação DML.
As tabelas são afetadas de forma diferente dependendo da operação DML executada. Na Tabela 1 temos
o que contém em cada tabela de acordo com a operação DML.
A cláusula OUTPUT faz uso destas mesmas tabelas virtuais, então quando você executa um INSERT a
tabela virtual INSERTED possui o dados inseridos na tabela auditada, e a cláusula OUTPUT utiliza a tabela
virtual para capturar os dados e inserí-los na tabela CartaoDeCredito_Espelho.
O resultado da operação de INSERT executada sobre a tabela CartaoDeCredito com o script da Listagem
3 pode ser visto na Figura 1. Resultado da execução do script abaixo.
M V T e c h | 308
SQL Server: Além do Conceito
Blog Post Collection
Observe que o novo registro foi inserido sobre a tabela Sales.CartaoDeCredito e ao mesmo tempo um
registro também foi inserido sobre a tabela Sales.CartaoDeCredito_Espelho indicando ainda o usuário
que executou a operação.
Para uma operação de UPDATE, o que muda é que deve-se pegar os dados não apenas da tabela
INSERTED, mas também os da tabela DELETED. Isso porque quando ocorre uma operação de UPDATE o
que ocorre na prática é a exclusão do dados antigos e a inclusão dos novos dados sendo inseridos. Com
isso, durante uma operação de UPDATE a tabela INSERTED armazena os novos dados e a tabela DELETED
armazena os dados antigos ou excluídos.
Observando o script da Listagem 4 você notará que na lista de colunas passadas para a cláusula OUTPUT
é usado não apenas a tabela INSERTED, mas também a DELETED (bloco do OUTPUT). Bem como, após o
INTO dbo.CartaoDeCredito_Espelho é informado não apenas as colunas de prefixo INSERT, mas também
as de prefixo DELETE.
-- UPDATE
UPDATE dbo.CartaoDeCredito
SET CardNumber= '11111111112015'
OUTPUT 'UPDATE',
Inserted.CreditCardID,
Deleted.CreditCardID,
Inserted.CardType,
Deleted.CardType,
Inserted.CardNumber,
Deleted.CardNumber,
Inserted.ExpMonth,
Deleted.ExpMonth,
Inserted.ExpYear,
Deleted.ExpYear,
Inserted.ModifiedDate,
Deleted.ModifiedDate
INTO dbo.CartaoDeCredito_Espelho
(ComandoDML,INSERT_CreditCardID,DELETE_CreditCardID,INSERT_CardTy
pe,DELETE_CardType,
INSERT_CardNumber,DELETE_CardNumber,INSERT_ExpMonth,DELETE_ExpMon
th,INSERT_ExpYear,DELETE_ExpYear,
INSERT_ModifiedDate,DELETE_ModifiedDate)
WHERE CreditCardID=3
Listagem 4: Script para executar um UPDATE sobre a tabela CartaoDeCredito
M V T e c h | 309
SQL Server: Além do Conceito
Blog Post Collection
O resultado da operação de UPDATE pode ser visto na Figura 2. Note que na tabela CartaoDeCredito o
número do cartão de crédito para o CreditCardID 3 foi alterado de 33333333333333 para
11111111112015. Na tabela de auditoria CartaoDeCredito_Espelho podemos notar que tanto as colunas
de prefixo INSERT quanto as colunas de prefixo DELETE foram preenchidas. Na coluna DELETE_CreditCrad
temos então o número antes da alteração e na coluna INSERT_CredtCard o novo número do cartão de
crédito.
Para finalizar, um exemplo demonstrando o uso da cláusula OUTPUT em uma operação de DELETE. Como
você já deve ter notado, para uma operação de DELETE apenas as colunas com prefixo DELETE para a
tabela CartaoDeCredito_Espelho serão preenchidas. O script para a operação de DELETE pode ser visto na
Listagem 5 e o exemplo exclui o registro de CreditCardID 3 da tabela dbo.CartaoDeCredito
-- DELETE
DELETE FROM dbo.CartaoDeCredito
OUTPUT 'DELETE',
Deleted.CreditCardID,
Deleted.CardType,
Deleted.CardNumber,
Deleted.ExpMonth,
Deleted.ExpYear,
Deleted.ModifiedDate
INTO dbo.CartaoDeCredito_Espelho
(ComandoDML,DELETE_CreditCardID,DELETE_CardType,
DELETE_CardNumber,DELETE_ExpMonth,DELETE_ExpYear,
DELETE_ModifiedDate)
WHERE CreditCardID=3
Listagem 5: Script para executar um DELETE sobre a tabela CartaoDeCredito
M V T e c h | 310
SQL Server: Além do Conceito
Blog Post Collection
Podemos ver o resultado da operação na Figura 3. Note que o registro de CreditCardID 3 foi excluído da
tabela principal CartaoDeCredito. Para a tabela CartaoDeCredito_Espelho podemos notar também que as
colunas de prefixo INSERT estão como NULL e isso ocorre porque para as operações de DELETE não há
inserção de novos dados. Já para as colunas de prefixo DELETE, temos o registro dos dados excluídos e
quem o excluiu.
Como vocês devem ter notado, a cláusula OUTPUT pode ser utilizada nas instruções Transact-SQL de
INSERT, UPDATE ou DELETE. Isso proporciona uma excelente flexibilidade, pois podemos utilizá-la apenas
nas instruções que desejamos monitorar. Desta forma, qualquer processo que tenha permissão para
modificar uma tabela pode usar a cláusula OUTPUT para popular a tabela de auditoria. Algumas boas
práticas para a utilização da cláusula OUTPUT são as seguintes:
Seguir estas boas práticas garantirá que o usuário só conseguirá executar as operações através das stored
procedures e consequentemente não executará nenhuma operação sem passar pela auditoria. O ponto
de atenção ao trabalhar com a cláusula OUTPUT está em ficar sempre atento para não esquecer e fazer
as devidas modificações nas procedures quando houver mudanças na estrutura da tabela auditada ou até
mesmo não esquecer da cláusula OUTPUT quando estiver escrevendo novas procedures. Para evitar estes
problemas, minha sugestão é que sejam criadas regras que definam os passos envolvidos para a
modificação ou criação de operações que envolvam tabelas que precisem ser auditadas.
É verdade que ao invéz de trabalhar com a cláusula OUTPUT você também poderia executar esta auditoria
usando triggers sobre a tabela a ser auditada. No entando, quando trabalhamos com triggers, além de
termos os problemas de overhead sobre as tabelas afetas ainda temos que nos preocupar em lembrar
das trigger sempre que modificamos as tabelas ou geramos scripts de criação das tabelas. Este problema
não existe com a utilização da cláusula OUTPUT pois tudo está dentro das próprias stored procedures que
executam as operações de INSERT, UPDATE e DELETE. Se você alterar a tabela auditada, certamente terá
que alterar também as procedures que executam estas operações e neste momento verá a cláusula
OUTPUT. Se você gerar script de criação das tabelas, muito possivelmente irá gerar também os scripts de
criação das stored procedures e mais uma vez estará lá a cláusula OUTPUT.
M V T e c h | 311
SQL Server: Além do Conceito
Blog Post Collection
Abraços
Nilton Pinheiro
M V T e c h | 312
SQL Server: Além do Conceito
Blog Post Collection
Tiago Bala u h
www.tiagobalabuch.com
U TILIZAÇÃO DE D ISCO
Operações de I/O por segundo (IOPS) – Número de operações realizadas por segundo
Logical Disk: Disk Reads/sec e Disk Write/sec – São respectivamente ao número de operações de leitura
e escrita realizadas no volume ou disco. Valores abaixo de 100 IOPS são considerados baixos.
Logical Disk: Avg. Disk Read Bytes/Sec e Avg. Disk Write Bytes/Sec – Taxas de transferência para escrita e
leitura no subsistema de disco. Valores abaixo de 20MB são considerados baixos.
M V T e c h | 313
SQL Server: Além do Conceito
Blog Post Collection
O gráfico 1 mostra o consumo de IO do subsistema de disco, onde a utilização máxima chega perto dos
20 mil IOPS. Também é possível notar que a maior concentração na utilização do subsistema de disco para
leitura, visto que a gravação de dados consome pouco recurso.
T EMPO DE R ESPOSTA
Podemos definir latência ou tempo de resposta como: uma medida de delay (tempo de atraso) desde o
momento de uma requisição de IO é criado, até ao momento em que a requisição de IO é completada.
Logical Disk: Avg. Disk sec/Read e Avg. Disk sec/Write – É o tempo médio gasto em leitura e escrita de
uma operação de I/O no disco. Esse indicador corresponde ao tempo de resposta do disco, sendo
recomendado valores inferiores a 0.020 – equivalente a 20 milissegundos.
Logical Disk: Current Disk Queue Lenght – Informa a fila de cada volume ou disco. O valor ideal da fila de
disco é zero, porém, existe uma tolerância de até 2 operações de I/O por disco físico.
M V T e c h | 314
SQL Server: Além do Conceito
Blog Post Collection
O gráfico 3 mostra que a fila de disco está alta porém o tempo de resposta do subsistema de disco não
ultrapassa 8 milissegundos ou 0.08. Nesse caso o enfileiramento de disco não está atrapalhando o tempo
de resposta de IO.
REFERÊNCIAS:
http://blogs.technet.com/b/askcore/archive/2012/03/16/windows-performance-monitor-disk-
counters-explained.aspx
http://blogs.technet.com/b/askcore/archive/2012/02/07/measuring-disk-latency-with-windows-
performance-monitor-perfmon.aspx
M V T e c h | 315
SQL Server: Além do Conceito
Blog Post Collection
Há um tempo atrás, fiz uma análise em conjunto com um amigo, Rafael Carneiro Machado, de problemas
com lentidão em um site. O Rafael trabalha comigo, porém no time de Web e ajudou a identificar o
problema que estávamos tendo, assim como a escrever o texto abaixo.
O BJETIVO
Depois da análise realizada, foram identificadas evidências de um problema na rede que interliga os
ambientes de Web e Banco de Dados. Dessa maneira nossos esforços foram direcionados para tanto.
Foi realizada uma análise em cima da instância de banco de dados, que hospedava o site e foi identificado
um alto tempo de espera do tipo ASYNC_NETWORK_IO, quase 15%. Porque esse valor é alto? Em
particular, nunca tinha visto esse tipo de espera com um valor alto e isto me chamou a atenção, pois
sempre vi um valor próximo a 0% ou no máximo a 2%. Aqui foi o ponto que levou a nossa investigação a
se concentrar que poderia existir um problema relacionado à rede, mas o que era exatamente nesse
momento ainda não sabíamos.
Figura 1
Esse tipo de espera indica que o SQL Server está respondendo para a aplicação, porém a mesma não está
conseguindo processar no tempo correto.
M V T e c h | 316
SQL Server: Além do Conceito
Blog Post Collection
Figura 2
Algumas ações que podemos tomar para tentar identificar a causa raiz do problema:
Identificar results sets grandes e verificar com a equipe de sistema se isso realmente está de acordo com
o negócio.
Se nem todas as linhas do result set serão necessárias, devemos alterar o código para restringir essa
quantidade de linhas.
Devemos verificar as configurações de placa de rede e verificar se não existe nenhum problema.
Não foi identificado nenhum time-out no ambiente Web, o que tínhamos era a demora do Banco de Dados
em responder as requisições dos servidores de aplicação. Isso pode ser identificado pela quantidade de
o e esà o àoàestadoà “YN_“ENT ,àpo àestaài fo aç oàape asài di aà ueàaàp i ei aàaç oàdo Three-
Way-Handshake foi iniciada, onde a origem informou ao destino que deseja iniciar uma comunicação.
Normalmente não vemos este estado de conexão, pois as comunicações de SYN, SYN-ACK e ACK ocorrem
quase de forma instantânea exceto em casos como este, onde o servidor de destino demora a enviar a
resposta do SYN à origem, porém não existia registro de time-out. Monitoramos os pacotes entre os
servidores de aplicação e banco de dados e pudemos ver que o servidor de banco de dados estava
demorando para enviar a resposta, mas respondia a requisição dos servidores de aplicação:
M V T e c h | 317
SQL Server: Além do Conceito
Blog Post Collection
Figura 3
Nesse momento, suspeitávamos que o problema pudesse estar ocorrendo por falta de portas TCP para
realizar a comunicação devido a um alto trafego de dados. Foi realizado um monitoramento e a média de
conexões TCP em portas distintas em cada servidor era de 800, independente do destino. Se levarmos em
conta que por padrão a quantidade de portas dinâmicas no Windows 2008 é de 16384 portas (49152 a
65535), ainda sobram mais de 15 mil portas livres:
Figura 4
Figura 5
O que poderia estar acontecendo era uma limitação nas portas dinâmicas dos servidores de banco. Essa
nossa suspeitaà oà seà o fi ou,à poisà difi il e teà oà p o le aà esta aà aà faltaà deà po tasà altas à osà
servidores de aplicação.
Outro detalhe importante que não poderíamos deixar de lado, era que o tráfego entre Web e Banco de
Dados passava por um appliance de balanceamento, um intrusion prevention system (IPS), Firewall e
outros equipamentos de rede física.
A NÁLISE DETALHADA
Após análise inicial, foi constatada a possibilidade de um problema de rede, a partir desse ponto uma
nova investigação foi realizada com foco neste quesito utilizando as ferramentas de análise de
performance do próprio sistema operacional, o Perfmon.
M V T e c h | 318
SQL Server: Além do Conceito
Blog Post Collection
Bytes Total/sec
Current Bandwidth
Packets/secPackets Sent/sec
Packets Received/sec
DPCs Queued/sec
Segments/sec
Connections Established
Connections Reset
Segments Received/sec
Connections Passive
Connections Active
Segments Retransmitted/sec
Segments Sent/sec
M V T e c h | 319
SQL Server: Além do Conceito
Blog Post Collection
Figura 6
Os itens que mais se destacaram foram a quantidade de pacotes recebidos descartados e com erro, além
disso, o número de segmentos TCP retransmitidos e de conexões com falha também estão altos.
Figura 7
M V T e c h | 320
SQL Server: Além do Conceito
Blog Post Collection
Figura 8
A figura 8 mostra os segmentos TCP que precisaram ser retransmitidos por algum erro de rede.
Outro ponto de destaque é a quantidade de conexões TCP com falha. O fabricante recomenda que este
contador não ultrapasse o número de 10 conexões TCP com falha por hora. No ambiente de banco de
dados este valor está com uma média de 20. As figuras 9 e 10 mostram esse comportamento.
Figura 9
M V T e c h | 321
SQL Server: Além do Conceito
Blog Post Collection
Figura 10
AMBIENTE WEB
Figura 11
No ambiente Web não tínhamos qualquer indício na camada física de erros, porém o mesmo problema
identificado no ambiente de Banco de Dados ocorre no ambiente Web. Esse problema trata-se da camada
de transporte, várias conexões com falha e retransmitidas.
M V T e c h | 322
SQL Server: Além do Conceito
Blog Post Collection
Figura 12
O padrão de segmentos retransmitidos se repete no ambiente Web, consequência das conexões TCP com
falhas.
Figura 13
R ESOLUÇÃO
Esse comportamento foi enviado para equipe de rede, que realizou as ações necessárias na camada física
dos equipamentos fazendo assim com que o trafego de pacotes ocorresse com sucesso. O site em questão
apresentou uma melhora significante, onde seu carregamento inicial passou de 14 segundos para apenas
2,8 segundos.
CONCLUSÃO
Por algum motivo relacionado a rede, o Banco de Dados estava com muitos pacotes com erros e
descartados e isso gerava a necessidade de retransmissão dos mesmos, ocasionando demora na entrega
M V T e c h | 323
SQL Server: Além do Conceito
Blog Post Collection
das informações que a aplicação demandava. O resultado final era a lentidão no acesso e carregamento
do site.
Foi constatado que até mesmo para iniciar a comunicação entre Web e Banco de Dados o problema
ocorria.
O servidor Web enviava o pacote de SYN, o qual o servidor de banco de dados recebia o pacote e enviava
o ACK. Este pacote de ACK estava sendo corrompido em algum ponto e a aplicação informava ao banco
de dados que ainda não havia recebido sua confirmação (ACK), fazendo com que o Banco de Dados
tentasse enviá-lo novamente.
Este período entre tentativas e falhas até que o ACK seja enviado corretamente e a comunicação
estabelecida, é um exemplo de como a retransmissão de pacotes TCP pode impactar na performance do
site. Essaà et a s iss oà oào o eàape asàdu a teàoàp o essoàdeà Th eeàWa àHa dshake ,à asàta à
quando a comunicação já está estabelecida e efetivamente os dados estão sendo enviados do banco de
dados para os servidores de aplicação.
REFERÊNCIAS:
http://msdn.microsoft.com/pt-br/library/ms179984.aspx
http://en.wikipedia.org/wiki/Handshaking
http://support.microsoft.com/kb/929851/en-us
http://msdn.microsoft.com/pt-br/library/ms179984.aspx
M V T e c h | 324
SQL Server: Além do Conceito
Blog Post Collection
Em uma bela madrugada, onde todas as coisas obscuras aparecem, um dos servidores de um cluster
falhou e executou um failover para um outro nó. Até esse momento nada de estranho e esse é o
comportamento esperado.
PROBLEMA
áoà e ifi a àosà a osàdeàdadosàdaài sta iaà ueàsof euàoàfailo e à eàdepa eià o àoàstatusàdeà suspe t à
em um deles. Nesse ponto começou a investigação de como isso aconteceu e como resolver!
Attempting to initialize Microsoft Distributed Transaction Coordinator (MS DTC). This is an informational
message only. No user action is required.
Que I te fa eà failedà fo à IT a sa tio Dispe se :à failedà toà et ie eà text for this error.
Reason: 15105).
Attempting to initialize Microsoft Distributed Transaction Coordinator (MS DTC). This is an informational
message only. No user action is required.
á à e o à o u edà hileà e o e i gà data aseà XXX .à U a leà toà o e tà toà Mi osoftà Dist i utedà
Transaction Coordinator (MS DTC) to check the completion status of transaction (0:-222014414). Fix MS
DTC, and run recovery again.
á à e o à o u edà du i gà e o e ,à p e e ti gà theà data aseà XXX à data aseà IDà à f o à esta ti g.à
Diagnose the recovery errors and fix them, or restore from a known good backup. If errors are not
corrected or expected, contact Technical Support.
A aplicação que utilizava essa database também utilizava Microsoft Distributed Transaction Coordinator
(MSDTC) e tudo indicava que alguma coisa se perdeu no caminho da comunicação entre o MSDTC da
aplicação e do banco de dados.
No meu caso eu tinha um agravante: o cluster não possuía uma instância do MSDTC, ou seja, utilizava o
MSDTC local.
M V T e c h | 325
SQL Server: Além do Conceito
Blog Post Collection
Quando uma instância do SQL Server 2008 ou superior é inicializada em um cluster, ela tenta encontrar
uma instância do MSDTC para comunicação na seguinte ordem:
RESOLUÇÃO
Eu não sabia o que tinha acontecido com MSDTC e resolvi tomar uma ação para deixar meu banco de
dados online e depois tentar resolver qualquer problema.
reconfigure
go
reconfigure
go
reconfigure
go
Podem existir outras formas de resolver esse problema, porém essa ação permitiu que meu banco de
dados ficasse online e pude executar um DBCC CHECKDB que para meu alivio retornou sem nenhum erro!
Antes de liberar meu banco de dados para produção novamente voltei a configuração padrão
M V T e c h | 326
SQL Server: Além do Conceito
Blog Post Collection
reconfigure
go
Outra alterativa seria visualizar a view sys.dm_tran_active_transactions, essa view mostra algumas
informações sobre as transações com uso do MSDTC.
Os campos: transaction_uow, transaction_state, dtc_state são campos que devem ser olhados com
cuidado em uma análise pois contem informações importantes.
Assim você pode identificar o status da sua transação e pode tomar a ação necessária que cabe ao seu
ambiente.
CONCLUSÃO
Quando a instância SQL Server executou um failover para o outro nó do cluster, a instância passou a se
comunicar com o MSDTC local do novo nó, que não tinha informações das transações registradas no nó
anterior.
Ao tentar iniciar o processo de recovery do banco de dados, o SQL Server encontrou informações sobre
transações distribuídas que não haviam sido terminadas (confirmadas ou abortadas) antes da falha. O SQL
Server entrou no processo de validar as informações do LOG e questionou o MSDTC a respeito das
transações, e o novo MSDTC local não tinha informações a respeito destas transações. Por esse motivo o
SQL Server não foi capaz de resolve-las e desta forma interrompeu o processo de recovery ocasionando o
estadoàdeà suspe t
A melhor solução para que isso não ocorra é ter uma instancia do MSDTC dentro do cluster.
M V T e c h | 327
SQL Server: Além do Conceito
Blog Post Collection
R EFERÊNCIAS :
sys.dm_tran_active_transactions
M V T e c h | 328
SQL Server: Além do Conceito
Blog Post Collection
Felipe Ferreira
www.templar.com.br/blogs/Felipe
Com a popularidade da nuvem crescendo a cada dia uma das perguntas que eu recebo frequentemente
:à aà a ei aà deà DBáà est à o e do?à Oà ueà o à aià faze à daà idaà oà futuro? à
Neste artigo eu irei dar a minha opinião pessoal sobre o futuro da nossa amada profissão e tentar acalmar
aqueles que já começaram a procurar uma nova carreira.
A primeira coisa que eu gostaria de falar é que quando a gente começou a trabalhar com TI nós sabíamos
que esta era uma carreira diferente de muitas outras. Uma carreira dinâmica e empolgante que se
reinventa o tempo todo, com novidades tecnológicas aparecendo todos os anos e mudando todo o
panorama da área. Nós escolhemos uma profissão que nos obriga a continuar estudando, aprendendo e
evoluindo. E esse é o pensamento que eu gostaria que vocês leem este artigo.
O papel do Administrador de Banco de Dados não está desaparecendo, nós não somos uma espécime
ameaçada de extinção e não entraremos nesta lista em um futuro próximo. A nuvem não é a nossa
inimiga. O mercado de dados está apenas evoluindo e a nuvem está trazendo diversas novidades que irão
nos dar mais poder, mais opções.
Em um cenário como esse as ferramentas que a nuvem nos fornece servem tanto para melhorar nossa
produtividade como DBA e também para ajudar a empresa a economizar dinheiro. Vamos pensar um
pouco, quantas tarefas a gente realiza diariamente que não trazem nenhum valor real para o negócio?
Sem dúvida que quando estamos planejando uma nova solução de alta disponibilidade ou realizando
performance tuning naquela consulta lenta nós podemos ver o valor que isso irá trazer para a empresa.
M V T e c h | 329
SQL Server: Além do Conceito
Blog Post Collection
No primeiro caso, irá garantir que todas as aplicações estejam de pé e rodando quando a empresa precisa
e o segundo irá ajudar com que o servidor aguente a carga de trabalho, execute mais sessões
simultaneamente e fazer com que nossos clientes internos e externos fiquem mais felizes. Mas e aquele
tempo que você perdeu tentando encontrar mais espaço em disco para os seus bancos de dados?
Tentando encontrar espaço em disco para armazenar os backups porque o banco de dados cresceu mais
do que o previsto. E o tempo que você gasta instalando atualizações no Windows e no SQL? Em algumas
grandes empresas nós temos times de administradores de storage e infra-estrutura que irão se preocupar
com essas tarefas que usei como exemplo, mas essa não é a realidade de todo mundo. A grande maioria
de pequenas e médias empresas possui apenas um pequeno time que é responsável por múltiplas áreas.
E porque isso? Volte alguns parágrafos acima nos itens 1 e 2 da minha lista que você irá entender. Eu
espero você ler.
Agora vamos tentar imaginar uma outra realidade. Vamos imaginar um mundo onde eu recebo um alerta
de falta de disco para armazenar os meus backups. A nossa empresa adquiriu a pouco tempo uma outra
empresa, o que fez com que o crescimento dos bancos fosse muito maior do que o previsto originalmente
e nós ficamos sem espaço em disco. Então ao invés de esperar dias/meses por um processo de compra
de mais discos eu vou até um portal Web e alguns cliques do mouse depois eu tenho 1TB extra de disco
disponível. Tudo que preciso fazer agora é abrir o SQL Management Studio e alterar os meus Jobs de
backup para utilizar a nova área de disco. Problema resolvido em menos de 15 minutos.
Vamos imaginar um mundo onde eu possa pegar todos aqueles banco de dados pequenos que eu tenho,
bancos que não são muito importantes para o negócio (sim, nós todos temos vários desses bancos, não
tente mentir para você mesmo) e agora vamos mover esses bancos para a nuvem para economizar
recursos do servidor local para as bases mais críticas. Quem sabe eu consiga até diminuir o número de
servidores necessários localmente assim eu não preciso me preocupar com licenças, suporte, aplicar
patches naquela máquina. Isso não seria ótimo? E que tal se livrar completamente dos ambientes de
homologação e testes e substituir eles por máquinas virtuais na nuvem que eu posso simplesmente
desligar quando não estiverem em uso, economizando dinheiro para a empresa? E aquelas tabelas
enormes, que contem milhões de registros e nos causam problemas todos os dias, não seria ótimo
substituir aquela solução complexa de particionamento que nós desenvolvemos para gerenciar dados
históricos ou pouco acessados e ao invés disso permitir que o SQL Server gerencie automaticamente esses
dados, movendo os registros antigos para a nuvem, enquanto mantem os dados acessíveis para o cliente
de forma transparente?
A nuvem realmente é algo que vai mudar a carreira de muitos, mas não algo que irá matar o papel do
administrador do banco de dados e destruir famílias. Mas ao invés disso, é algo que irá nos tornar mais
eficientes, que irá nos fornecer ferramentas e opções que permitam que a gente nos foque em tarefas
que irão trazer realmente valor para a empresa, utilizar de forma mais eficiente o hardware existente,
para tornar nossas vidas mais fáceis. Então abrace as mudanças, da mesma forma que abraçamos todas
as outras novas tecnologias que vieram antes dela e use cada tecnologia como uma ferramenta para te
ajudar a ter sucesso no seu trabalho.
M V T e c h | 330
SQL Server: Além do Conceito
Blog Post Collection
Para fazer testes com bases de diferentes tamanhos eu utilizo o datawarehouse dos testes da TPC.
Rapidamente, para quem não conhece, a Transaction Processing Performance Council, ou TPC para os
íntimos (não pergunte o que aconteceu com o outro P), é a organização que define alguns benchmarks
que todos os fabricantes utilizam para fazer testes de performance, com isso ela mantem a lista das
configurações de Hardware + Software com a melhor performance, o melhor custo x benefício e assim
por diante.
Para os meus testes eu utilizo o TPC-H, que é um teste de Decision Support, ou seja, utiliza uma base no
formato datawarehouse, e não a base OLTP. Se você deseja fazer esse teste com uma base OLTP acredito
que possa usar o mesmo procedimento com o teste TPC-E, apesar de nunca ter procurado. Temos N
formas de criar as bases de dados da TPC-H, irei partir para a mais manual de todas por nos dar maior
liberdade para fazer N testes.
Então mãos na massa. Toda a estrutura da base de dados e tabelas está na documentação oficial do
bechmarch TPC-H, que vocês podem encontrar no endereço
http://www.tpc.org/tpch/spec/tpch2.14.0.pdf. Mas vamos facilitar as coisas.
P ASSO 1:
- Criar nossa base de dados. Aqui eu não vou colocar nada de dicas, melhores práticas de como criar, quais
opções habilitar e desabilitar na base de dados, porque isso vai ficar de lição de casa para vocês, testar
carregar os dados com diversas opções e ver a diferença de tempo entre uma forma e outra. Irei fazer
outros posts fazendo essas comparações futuramente. Então vamos apenas criar nossa base com os 2
filegroups que precisaremos para os próximos passos, o filegroup LOAD_FG será nosso filegroup de
Staging, muita gente cria uma base de dados separada para ser a área de Staging, nesse caso, estamos
criando na mesma base de dados em um filegroup separado; o filegroup DATA_FG é o filegroup com os
dados já tratados, nosso datawarehouse final.
M V T e c h | 331
SQL Server: Além do Conceito
Blog Post Collection
12:
13: LOG ON
14: (name=tpch1g_log,
filename='C:\TPC\tpch1G.ldf',size=1024mb)
Obs.: Lembre-se da dica do post anterior do Instant File Initialization para criar grandes bases de dados e
realizar as cargas: http://www.templar.com.br/blogs/felipe/2013/02/24/instant-file-initialization/
P ASSO 2:
M V T e c h | 332
SQL Server: Além do Conceito
Blog Post Collection
P ASSO 3:
M V T e c h | 333
SQL Server: Além do Conceito
Blog Post Collection
Feito isso já temos nossa base de dados e as tabelas no nosso filegroup de staging, agora precisamos dos
dados para carregar nessas tabelas. Para isso vamos usar o DBGen, a ferramenta fornecida pela TPC para
gerar os arquivos de dados. A TPC fornece esse aplicativo como uma solução do Visual Studio em C++,
o àpodeàfaze àoàdo loadàdoà digoàfo teàa ui,à o oàseià ueà e àtodosàosàDBá sàpossue àoàVisualà
Studio completo instalado, então vou disponibilizar os executáveis já compilados aqui no blog, você pode
baixar o aplicativo compilado aqui.
Para utilizar é só descompactar (ou compilar caso você tenha baixado o código fonte), abrir um prompt
de comando, navegar até a pasta com o código compilado e executar:
dbgen –vf –s 1
Sendo o –s 1, a quantidade de GB que você deseja gerar, no exemplo, serão criados arquivos para popular
todas as tabelas acima, totalizando 1Gb em tamanho. Para criar uma base de 10Gb, 50Gb, 100Gb você só
precisa alterar o valor no parâmetro
Os outros dois parametros, –vf é verbose para mostrar todos os passos na tela e o f de force para
sobreescrever arquivos existentes no disco. Digite dbgen –? para ver todas as opções.
P ASSO 4:
Carregar os dados! Aqui temos N opções, e é aqui que a brincadeira começa.. se você quiser pode
simplesmente usar um BULK INSERT e carregar direto os dados para as tabelas do filegroup LOAD_FG e
depois criar pacotes do SSIS ou scripts T-SQL para mover os dados para o filegroup Data_FG, pode criar
pacotes do Integration Services para carregar tudo, pode usar o BCP, enfim.. pode usar toda a criativade
ueàOdi àlheàdeu…àpa aàajuda àasàpessoasà ueàs à ue e àfaze àasà o sultas,àtesta àdese pe ho,àte ta à
criar um columnstore index, etc, aqui vai a sintaxe do comando BULK INSERT:
M V T e c h | 334
SQL Server: Além do Conceito
Blog Post Collection
E é isso pessoal, no arquivo compilado acima eu também adicionei o QGEN que gera 22 consultas pesadas
para vocês testarem os servidores. Só digite na linha de comando QGEN.exe > consultas.sql que ele irá
gerar a consulta, ou abra os arquivos .SQL que estão na pasta e editem os filtros/etc.
Nos próximos posts vou usar essa base de dados para realizar testes de carga e comparações de
desempenho.
M V T e c h | 335