Palestra Windows Internals

Enquanto não sai o próximo post da série Inside the Machine, fiz uma apresentação sobre fundamentos de Windows Internals para alguns DBAs SQL Server.

Nessa palestra falei, entre outras coisas, sobre um pequeno segredo para gerar dumps “full” do SQL Server sem que se tenha que suspender o processo original do mesmo. Isso é bastante interessante em cenários onde você tem uma instância com um Buffer Pool relativamente grande (30 GB+) e não pode manter o processo parado enquanto gera um dump.

Pretendo (um dia haha) postar sobre isso, mas por enquanto veja nos slides para maiores informações. Vale ressaltar que essa funcionalidade não é documentada, não é suportada pela Microsoft e pode destruir o processo da sua instância SQL, corromper os bancos de dados, explodir o seu data center e ainda por cima matar alguns gatinhos! Não use em produção.

Segue o link para download do pdf: http://bit.ly/1KgXElG

Se você quer se aprofundar mais nos assuntos, recomendo dar uma olhadinha nas referências ao fim da apresentação e também o meu treinamento on-demand de Windows Internals na Sr. Nimbus.

No mais, fique à vontade para deixar seus comentários sobre o material!

Pin It

Hyper-Threading (SMT) e SQL Server

Semana passada postaram uma pergunta muito interessante na lista de SQL Server Nimbus Advanced, que participo. Pela própria natureza do assunto que o torna interessante para um grupo de pessoas além dos que participam da lista, e o fato de que a resposta que eu estava escrevendo acabou crescendo um pouco, acabei decidindo transformá-lo em um post. :)

Hyper-Threading (SMT) e SQL Server

Muito interessante o asssunto. Vamos por partes…

O principal fator que vai definir o impacto do HT no seu ambiente é o seu workload – tanto positivamente quanto negativamente.

Intel Core i7 logoA própria Intel limita o ganho teórico do HT a 30% [1]. Isso é, no melhor do melhor dos casos, o máximo de desempenho que você vai “ganhar” com HT é 30%. É pouco? Não acho. Mas o que eu acho é que HT é muitas 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 caso não houvesse um “pipeline” substituto pronto para entrar em cena. Não há ganho, e sim “controle de perda”. :)

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 wih and w/o SMT

Pipeline (SMT)

Teoria 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 “núcleos lógicos” (por falta de nome melhor) compartilharem os mesmos ALUs o seu desempenho vai 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.

Mito

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.

Processadores

Agora vamos para a questão de desempenho de processadores…

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 forma “aleatória”. Na teoria [5], esses tipos de cenários são excelentes candidatos a fazer um bom 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 influenciar mais que o próprio clock do seu processador… Nada de comprar processadores olhando apenas os GHz!

Workloads de OLAP e aplicações científicas , por outro lado, tendem a ser mais sensíveis à “força bruta” do processador.

Enfim… No final das contas, a única coisa que vai te dizer se o HT pode ou não beneficiar o seu ambiente é 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

Pin It

Está chegando! SQLSaturday #253 Brasília

Como alguns já sabem, esse ano teremos o evento PASS SQLSaturday de número 253, aqui em Brasília!

PASS SQLSaturday #253 - Brasília Logo

PASS SQLSaturday #253 – Brasília

Organizado por um dos regional mentors do PASS no Brasil, Luciano Moreira, o evento contará com  a participação de diversos palestrantes de renome e algumas novas caras que são muito bem vindas à nossa comunidade.

Tive a honra de participar da organização do evento e montamos a agenda da melhor forma possível para que os participantes pudessem aproveitar ao máximo o conteúdo de alto nível digno de um evento desse calibre.

Teremos, além das tradicionais trilhas de Desenvolvimento (Dev), Administração (DBA) e Business Intelligence (BI), uma trilha especial Acadêmica para quem está iniciando no mundo de SQL Server e Bancos de Dados em geral:

Agenda SQLSat #253

Agenda provisória do evento

O evento ocorrerá no dia 28 de Setembro de 2013 e já possui mais de 400 inscritos. Portanto  se você tem interesse em participar, não deixe de fazer sua inscrição o mais rápido possível!

Para mais informações, acesso o blog do Luti e o site do evento.

Te espero lá!

Pin It

SQL Server XTP (Hekaton) – Hash Indexes

Recentemente no TechEd 2013 a Microsoft anunciou o SQL Server 2014, e a funcionalidade do momento com certeza é o Extreme Transaction Processing (conhecido anteriormente pelo codinome Hekaton).

Eu gostaria de tomar esse momento e falar um pouco sobre uma característica da implementação do XTP em particular que me chamou a atenção: é o primeiro mecanismo do SQL Server que permite trabalharmos com índices hash (mas não apenas hash! Mais sobre isso adiante.)

Um ponto interessante em relação aos indexes hash é que, em geral, os DBAs SQL Server não estão muito acostumados com eles, justamente por ser uma “novidade” no produto.

Novidade?

Apesar de no SQL Server não termos índices Hash para dados (apenas B+Trees), a hash table é uma estrutura de dados bastante comum na ciência da computação. A própria engine do SQL Server utiliza hash tables (internamente) para diversas tarefas de gerenciamento. Alguns exemplos que me vêm a mente são a manutenção de lista de estruturas BUF (que apontam para as páginas do Data Cache) e também o Plan Cache, mas com certeza existem (diversos) outros.

E não sou nenhum especialista no assunto, mas acredito que no Oracle é possível criar índices tanto B+Tree como Hash há algum tempo.

Mas o que vem a ser uma estrutura de Hash table e como ela se compara com estruturas B+Tree?

Hash tables – Conceitos gerais

Primeiramente, e diferentemente das B+Trees, as hash tables são estruturas que se encaixam na definição de vetores associativos. Isto é, elas armazenam dados de forma não ordenada e no formato de pares de Key-Value: chaves e valores.

Hash Table - Collision Chain

Hash Table - Cadeia de Colisão

Alguns desses pontos são bastante importantes, portanto vamos discutir um pouco mais sobre eles e diferenciá-los da B+Tree.

Os valores em vetores associativos, em particular as hash tables, são divididos em slots chamados de Buckets. Cada bucket corresponde a um valor de hash único: a chave. Cada Bucket pode conter diversas entradas. Se duas linhas geram valores de hash iguais (e portanto apontam para o mesmo Bucket) nós temos o que chamamos de colisão.

Se houver uma colisão a implementação da hash table deve realizar algum tipo de esforço adicional para garantir a integridade dos dados (eg. não sobreescrever o valor já contido no bucket). No paper [1] a Microsoft fornece alguns detalhes sobre a implementação do mecanismo de gerenciamento de colisão do XTP. Se você tiver interesse em saber mais sobre o assunto em particular e a implementação do mecanismo de MVCC, dê uma olhada nesse paper.

Função de Hash

A escolha de uma função de hash adequada é de suma importância para uma implementação efetiva de uma hash table. Uma função muito forte pode gerar hashes muito grandes e consumir muito espaço, além de maior utilização da CPU para aplicá-la. Já uma função hash muito fraca pode salvar espaço e CPU, mas fará com que exista um número muito grande de conflitos, causando o que chamamos de clustering, onde grande quantidade de dados é mapeada para poucos Buckets, o que também não é desejável.

Função de Hash

Função de Hash

Como são os valores dos hashes que determinam a posição na tabela onde o valor será armazenado, é através desse hash que a estrutura é “fisicamente ordenada”, e não através do valor em si. Na teoria, é possível construir uma função de hash que preserve a ordem das suas chaves, mas na prática isso geralmente é inviável. Para todos os efeitos, assuma que hash tables não mantém chaves de forma ordenada. Portanto temos uma tabela onde a chave “1” pode estar armazenada no meio da estrutura, enquanto a chave “8192032” poderia estar armazenada no primeiro Bucket.

A escolha de uma função de hash adequada é de suma importância para uma implementação efetiva de uma hash table.

Pela sua própria estrutura as hash tables são ótimas candidatas para realizar buscas de igualdade.

SELECT * FROM table WHERE key = 8192032

No geral a complexidade de uma busca de igualdade em uma hash table é O(1), ou seja, é constante¹. Basta que a função de hash seja aplicada ao valor de search argument (SARG), nesse caso 8192032, para gerar o endereço do Bucket e então recuperar o valor do mesmo.

Em comparação à B+Tree, não existe navegação entre diversos níveis da estrutura², uma vez que a mesma não é uma árvore e sim um vetor, como dito no início do artigo.

Existe porém a navegação entre a cadeia de colisão, já que há a possibilidade de que existam vários valores para o mesmo hash (Bucket), ou ainda vários valores repetidos para a mesma chave (caso a coluna não seja chave primária).

Para buscas de desigualdade (ex.: maior que, menor que, !=, NOT IN, etc.), porém, as hash tables não trabalham bem.

SELECT * FROM table WHERE key > 10

Se você não sabe exatamente qual é o valor que está procurando, não é possível calcular o hash desse valor (uma vez que é desconhecido) e portanto não é possível encontrar o valor desejado a menos que se percorra toda a estrutura do índice, ie. realize um scan. Isso é o que chamamos de complexidade linear: O(n) onde n é o número de linhas (pares key-value) armazenados nessa hash table. Para encontrar um valor desconhecido X é necessário percorrer todas as n linhas da tabela.

Esse ponto é importante pois esclarece a principal fraqueza das hash tables em cenários de bancos de dados: não é possível realizar buscas por ranges de forma eficiente em hash tables!

O que isso quer dizer, afinal? Quer dizer que um banco de dados implementado apenas com hash tables não seria um banco de dados eficiente³. E é por isso que a Microsoft introduz também no XTP (Hekaton) uma nova estrutura de índice chamada de Bw-Trees[2].

Mas vamos deixar as Bw-Trees para outro post… Nesse momento quero entrar na parte prática das hash tables como implementadas no SQL Server 2014.

Implementação no SQL Server 2014

Aproveitei os testes que estive realizando no Windows Azure esse mês e hoje configurei uma nova máquina virtual com o SQL Server 2014 CTP1 pré-instalado.

Aqui estão alguns itens interessantes que verifiquei nesse primeiro momento. De forma alguma essa lista é exaustiva, e tenha em mente que pelo fato dos testes terem sido realizados em uma versão pré-release do SQL Server, algumas coisas  podem mudar até a release final.

Algumas limitações que notei na implementação atual:

  • Colunas Nullable não são suportadas com índices
  • Nada de default constraints para tabelas XTP
  • Identity também ainda não é suportado, mas pela mensagem de erro deve ser implementado em breve.
  • STATISTICS IO é ignorado em tabelas XTP
  • Não consegui criar índices hash em campos char e varchar
  • Hash indexes são permitidos apenas em tabelas XTP (o que era de se esperar, mas nunca se sabe… ;))

Na criação da tabela a sintaxe permite configurar um valor qualquer para a quantidade de Buckets de um determinado índice hash, mas efetivamente o SQL Server sempre vai criar com 16 ou mais Buckets.

CREATE TABLE TabelaXTP (
 C1 INT NOT NULL,
 C2 CHAR(100) NOT NULL,
 C3 VARCHAR(100) NOT NULL
 CONSTRAINT PK_TabelaXTP PRIMARY KEY HASH (C1)
  WITH (BUCKET_COUNT = 16)
) WITH (MEMORY_OPTIMIZED = ON);
GO

A quantidade de Buckets por hash table cresce de forma exponencial com base 2, começando pelo valor mínimo de 16. Ou seja, podemos ter hash tables com um número de Buckets de 16, 32, 64, 128, 256, etc.

O número de buckets sempre arredonda para cima. Se você tentar criar um hash index com 17 buckets, o SQL Server irá criá-lo com 32, sem exibir nenhuma mensagem de alerta ou erro.

A maior hash table que consegui criar hoje tinha um total de 1.073.740.000 buckets. Na prática não acredito que eu vá usar essa quantidade de buckets tão cedo. Haha :)

O operador de Index Scan (NonClusteredHash) permite observar a quantidade de Buckets em um índice hash através do campo TableCardinality. Ou seja, a cardinalidade da hash table.

TableCardinality - Execution Plan Property

Cardinalidade da hash table

A utilização de memória por parte dos índices do Extreme Transaction Processing pode ser monitorada através dos novos Memory Objects MEMOBJ_XTPDB e MEMOBJ_XTPBLOCKALLOC e no Clerk MEMORYCLERK_XTP.

New SQL Server 2014 Memory Clerks

Novo Memory Clerk de XTP

Os índices hash utilizam espaço do Buffer Pool mesmo que vazios, por conta dos buckets. Por isso tome muito cuidado ao criar índices hash com um número excessivo de buckets! Nesse meu teste acima o índice consumiu sozinho mais de 10 GB de memória.Lembrando: ele estava vazio!

New SQL Server 2014 XTP Memory Objects

Novos Memory Objects do SQL Server 2014 - XTP

Se você tem interesse em se aprofundar mais em hash tables, em particular em relação à implementação da Microsoft de lock-free hash tables, recomendo o paper [3] além dos outros dois já referenciados nesse post.

Benchmarks

Infelizmente não é possível utilizar o STATISTICS IO para visualizar as leituras lógicas do acesso a um índice hash, mas já realizei alguns testes através dos Extended Events e assim que tiver resultados conclusivos pretendo compartilhá-los por aqui. Quem sabe aproveito e falo um pouco sobre os novos objetos de Extended Events do XTP também, se entender como funcionam até lá… Hahaha :)

¹ No geral, porque em alguns casos onde há conflito excessivo de chaves a complexidade será maior;
² Raiz, níveis intermediários e folhas;
³ Salvo cenários onde é desejável a realização de 100% scans no lugar de seeks por questões de eficiência de I/O sequencial;

[1]: http://research.microsoft.com/apps/pubs/default.aspx?id=193594
[2]: http://research.microsoft.com/apps/pubs/default.aspx?id=178758
[3]: http://www.research.ibm.com/people/m/michael/spaa-2002.pdf

 

Pin It

SQL Server – XEvents e ETW

Esse post é fruto de uma profunda investigação a respeito do funcionamento interno/implementação dos Extended Events no SQL Server.

O meu entendimento inicial dos XEvents era de que a funcionalidade havia sido implementada através do ETW.

ETW, ou Event Trace for Windows é um framework de tracing de eventos implementado no kernel do Windows para a análise de problemas e desempenho entre diversos mecanismos, subsistemas e aplicações do sistema operacional. O ETW permite a captura e correlação destes eventos de forma integrada e de altíssimo desempenho, permitindo a sua utilização mesmo em ambientes de produção.

Apesar de existir desde a versão 2000 do SO, uma das funcionalidades mais interessantes do ETW surgiu com a introdução do Windows 7/2008 R2, que permite a captura de stack traces do código em execução no momento em que foi gerado o evento, uma funcionalidade disponibilizada também nos XEvents do SQL Server.

Através dessas investigações descobri que minha impressão inicial a respeito da implementação dos XEvents estava incorreta.

A implementação dos XEvents é independente do ETW até que você utilize o target do mesmo, chamado etw_classic_sync_target. Ao informar o uso desse target na sua sessão de XEvents, você está informando ao SQL Server que gostaria de possibilitar a correlação de eventos da Database Engine com aqueles do sistema operacional.

Para entendermos a implementação dos ETW target, vamos primeiro revisar alguns conceitos dos XEvents.

Conceitos de Extended Events

A peça mais fundamental na arquitetura dos XEvents são os pacotes. Através dos pacotes é que são implementados os eventos em si, os alvos (targets), ações, tipos de dados e o mapeamento dos valores dos eventos com os valores do SQL Server.

Os pacotes são registrados na instância de SQL Server e estão disponíveis para consulta através da DMV sys.dm_xe_packages:

select * from sys.dm_xe_packages;
go
XEvents Packages

Pacotes do XEvents

Repare na coluna guid, pois voltaremos a falar dela mais tarde.

Nesse momento, o que nos é interessante é a coluna module_address, que informa qual o módulo executável (PE) é o responsável pelo registro desse pacote. Podemos conferir os módulos através do Windbg ou através da DMV sys.dm_os_loaded_modules:

select p.*, m.name
from sys.dm_xe_packages as p
join sys.dm_os_loaded_modules as m
 on p.module_address = m.base_address;
go

Módulos onde estão implementados os pacotes do XEvents

Todos os pacotes (atualmente) estão implementados nos módulos sqllang.dll, sqldk.dll e sqlmin.dll.

Podemos verificar quais os eventos de cada pacote através do seu guid:

select top 10 *
from sys.dm_xe_objects
where package_guid = '03FDA7D0-91BA-45F8-9875-8B6DD0B8E9F2';
go

Uma visão completa dos Extended Events está além do escopo desse artigo, e existem diversos materiais sobre o assunto disponíveis on-line. Eu mesmo já falei sobre isso anteriormente, inclusive.

Sessão de teste

Estarei utilizando a seguinte sessão de XEvents para teste ao longo do post:

CREATE EVENT SESSION test0
ON SERVER
ADD EVENT sqlserver.checkpoint_begin (ACTION (package0.callstack)),
ADD EVENT sqlserver.checkpoint_end (ACTION (package0.callstack))
WITH (MAX_DISPATCH_LATENCY = 1 SECONDS);
GO

Com um ring_buffer como target inicial:

ALTER EVENT SESSION test0
ON SERVER
ADD TARGET package0.ring_buffer;
GO

Targets do SQL Server

Alguns targets são implementados nos pacotes SecAudit, mas esses targets são específicos para aa implementação da solução de auditoria do SQL Server. Os targets que nos interessam são implementados em sqlserver e package0:

select p.name, o.*
from sys.dm_xe_objects as o
join sys.dm_xe_packages as p
 on p.guid = o.package_guid
where p.name <> 'SecAudit'
 and object_type = 'target';
go

Ao realizarmos a criação de uma nova sessão de XEvents com qualquer target do próprio SQL Server (isto é, qualquer target menos o etw_classic_sync_target), a sessão é completamente interna ao SQL Server, não existe qualquer tipo de interação entre o SQL Server e o framework de ETW do sistema operacional. A implementação dos XEvents não é baseada em ETW. Ela apenas o suporta.

Uma das features dos XEvents que me intrigou foi a captura dos stacktraces, que eu acreditava depender do framework de ETW, que também possui a funcionalidade, como dito anteriormente.

Utilizando a sessão descrita acima em conjunto com o Windbg podemos visualizar e entender como funciona o mecanismo para a coleta das stacktraces no SQL Server.

Stacktraces

A captura dos stacktraces de execução do SQL Server são realizados pela própria instância, através de chamadas à função RtlCaptureStackBackTrace em ntdll e passando como parâmetro FramesToSkip o número de frames correspondente ao processamento do evento (nesse caso 3) para que estes não apareçam na lista de eventos ocorridos, no target. Portanto no Windbg temos:

ntdll!RtlCaptureStackBackTrace
sqldk!XEPackage0::CallStackAction::Invoke
sqlmin!XeSqlPkg::checkpoint_begin::Publish
sqlmin!HardenAndLogCheckpoint
sqlmin!CheckpointRU
sqlmin!AsynchronousDiskAction::DoFlushCache
sqlmin!AsynchronousDiskAction::ExecuteDeferredAction
sqlmin!AsynchronousDiskWorker::ThreadRoutine
sqlmin!SubprocEntrypoint
...

Enquanto no ring_buffer da nossa sessão com a action callstack de XEvents nós temos:

sqlmin!HardenAndLogCheckpoint
sqlmin!CheckpointRU
sqlmin!AsynchronousDiskAction::DoFlushCache
sqlmin!AsynchronousDiskAction::ExecuteDeferredAction
sqlmin!AsynchronousDiskWorker::ThreadRoutine
sqlmin!SubprocEntrypoint
...

Portanto sem os 3 primeiros frames.

Até o momento o SQL Server realizou zero chamadas às APIs de ETW do sistema operacional.

Se não precisamos do ETW até agora, pra que ele serve? Antes de respondermos essa pergunta vamos investigar um pouco a implementação (peculiar) dos eventos de ETW no SQL Server.

ETW Target

A implementação de ETW no SQL Server é realizada através do objeto XEPackage0::XE_ETWTarget. Esse objeto realiza o registro dos pacotes XEvents (aqueles que vimos na DMV sys.dm_xe_packages) no sistema operacional através de chamadas a função não documentada EtwRegisterTraceGuidsW em ntdll.

Note que existe uma API documentada para realizar o mesmo procedimento em advapi32 chamada RegisterTraceGuidsW mas o SQL Server não a utiliza. Essa API documentada acabará chamando a mesma função que o SQL Server chama diretamente, portanto efetivamente o resultado será o mesmo.

Ao adicionarmos o target etw_classic_sync_target à nossa sessão, o SQL Server irá chamá-la:

ALTER EVENT SESSION test0
ON SERVER
ADD TARGET package0.etw_classic_sync_target;
GO

E aqui nós temos o stacktrace da chamada no Windbg:

Breakpoint 5 hit
sqldk!XEPackage0::XE_ETWTarget::Create:
000007fe`dcd09540 fff5            push    rbp
0:056> kc
Call Site
sqldk!XEPackage0::XE_ETWTarget::Create
sqldk!XE_PackageManager::InitTarget
sqldk!XE_ActualTargetEntry::Create
sqldk!XE_SingletonTargetManager::GetOrCreate
sqldk!XE_Session::AddTarget
sqldk!XE_Engine::AddTarget
sqllang!CXE_Target::AddTarget
sqllang!XEventController::AlterEventSession
...

Repare no topo da nossa stack onde temos o método Create do objeto XE_ETWTarget do “pacote” XEPackage0 (package0 nas DMVs).

A implementação do target etw_classic_sync_target é o que chamamos de singleton, isto é, só pode haver uma por instância. Mais à frente enderemos o porquê.

select name, object_type, capabilities_desc
from sys.dm_xe_objects
where name = 'etw_classic_sync_target';
go
Singleton XEvent ETW Target

Target singleton dos XEvent para ETW

Na arquitetura do ETW, o SQL Server é o que chamamos de controller e provider ao mesmo tempo. Ou seja, o SQL Server fornece eventos e controla quais as sessões que consomem esses eventos.

ETW Architecture

ETW Architecture (MSDN)

O SQL Server só registra os seus ETW providers no momento em que o usuário (DBA) configura o target etw_classic_sync_target na sessão de XEvents, se a mesma já estiver em execução, ou caso a sessão esteja parada os providers somente serão registrados no momento em que a sessão for iniciada. Ou seja, o SQL Server não mantém os providers registrados no Windows durante a sua execução, impossibilitando a sua ativação pelos controllers padrão do sistema: perfmon, logman, xperf, etc.

O único controller capaz de ativar e desativar os eventos ETW do SQL Server é ele mesmo.

Voltando nas guids que falei anteriormente, no momento em que a sessão é inicializada e o SQL Server registra os pacotes dos XEvents como ETW providers para que seja possível começar a produzir eventos através destes providers, os guids utilizados para registrá-los no ETW são os mesmos encontrados na DMV. Os pacotes são:

C:tempSQL Server Tracing>xperf -providers R | findstr /I "SQL XE"
sqlserver
sqlos
XEvent Package 0
SQL2012 Trace
C:tempSQL Server Tracing>

E podemos ver através do logman que o processo do SQL Server registrou esses providers através dos comandos abaixo:

C:tempSQL Server Tracing>tasklist /FI "SERVICES eq MSSQL$SQL2012"

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
sqlservr.exe                 12268 Services                   0     60,628 K

C:tempSQL Server Tracing>logman query providers -pid 12268

Provider                                 GUID
-------------------------------------------------------------------------------
...
Microsoft-Windows-User Profiles General  {DB00DFB6-29F9-4A9C-9B3B-1F4F9E7D9770}
Security: Kerberos Authentication        {6B510852-3583-4E2D-AFFE-A67F9F223438}
Security: NTLM Authentication            {5BBB6C18-AA45-49B1-A15F-085F7ED0AA90}
Security: SChannel                       {37D2C3CD-C5D4-4587-8531-4696C44244C8}
SQL2012 Trace                            {26773F6F-E7B5-4F58-9347-0347C998BA7D}
sqlos                                    {BD97CC63-3F38-4922-AA93-607BD12E78B2}
sqlserver                                {655FD93F-3364-40D5-B2BA-330F7FFB6491}
XEvent Package 0                         {60AA9FBF-673B-4553-B7ED-71DCA7F5E972}
{03FDA7D0-91BA-45F8-9875-8B6DD0B8E9F2}   {03FDA7D0-91BA-45F8-9875-8B6DD0B8E9F2}
...

The command completed successfully.

C:tempSQL Server Tracing>

Podemos conferir os GUIDs acima com os retornados pelo SQL Server na DMV sys.dm_xe_packages:

name        guid
package0    60AA9FBF-673B-4553-B7ED-71DCA7F5E972
sqlos       BD97CC63-3F38-4922-AA93-607BD12E78B2
XeDkPkg     52FC232C-03D5-4E1F-A6BF-BBC66FE20E6A
sqlserver   655FD93F-3364-40D5-B2BA-330F7FFB6491

Uma vez que os pacotes tenham sido registrados, o SQL Server utiliza a sessão XE_DEFAULT_ETW_SESSION para capturar os eventos.

ALTER EVENT SESSION test0
ON SERVER
STATE = start;
GO

C:tempSQL Server Tracing>xperf -loggers XE_DEFAULT_ETW_SESSION
Logger Name           : XE_DEFAULT_ETW_SESSION
Logger Id             : c
Logger Thread Id      : 000000000000291C
Buffer Size           : 128
Maximum Buffers       : 30
Minimum Buffers       : 8
Number of Buffers     : 8
Free Buffers          : 8
Buffers Written       : 1
Events Lost           : 0
Log Buffers Lost      : 0
Real Time Buffers Lost: 0
Flush Timer           : 0
Age Limit             : 0
Log File Mode         : Circular PagedMemory
Maximum File Size     : 20
Log Filename          : C:UsersMSSQL$~1AppDataLocalTempXEEtw.etl
Trace Flags           : 03fda7d0-91ba-45f8-9875-8b6dd0b8e9f2+b086c2f3-2738-4389-b119-d80b5362b5ca+1e99fe90-a4fe-45
e6-9dfd-a45041f02314+c0ab75c5-b1ea-445b-b7df-f897686f94e7+f235752a-d5c0-4c9a-a735-9c3b6f6e43b1+"sqlserver"+"sqlos"
+"XEvent Package 0"

C:tempSQL Server Tracing>

No campo Trace Flags podemos observar as guids e os nomes dos pacotes do SQL Server (providers, do ponto de vista do ETW).

Outro ponto importante é que, ao chamar a função para registrar os ETW providers um dos parâmetros passados pelo SQL Server é uma callback que será chamada sempre que algum controller tentar utilizar algum destes providers. O SQL Server irá negar o uso de controllers externos, impossibilitando a captura dos eventos por outra sessão além da sessão criada pelo próprio XEvents.

Podemos observar o mecanismo em ação:

Callback dos XEvents para o ETW

Portanto, mesmo conhecendo os nomes e a forma como o SQL Server realiza o registro das sessões de XEvents no ETW, não é possível capturar tais eventos através do sistema operacional.

Callback causado pela tentiva de ativação do provider sqlos externamente

Podemos verificar que durante o processamento da callback (em azul na imagem abaixo), o SQL Server está realizando uma escrita em um Ring Buffer através da chamada SOS_RingBuffer::StoreRecordInternalWithoutEvent (em verde). Presumidamente esta chamada não gera eventos pois a própria engine dos XEvents quem está realizando a escrita, caso contrário entraria em loop infinito ou deadlock.

Ring Buffer do SQL Server no Windbg

Logando o problema durante o processamento do callback

Através do valor do registrador rcx (em vermelho), podemos encontrar informações a respeito deste Ring Buffer e a mensagem armazenada, nas DMVs:

Ring Buffers no SQL Server (SSMS)

Is this cool or what?! =)

O fato do SQL Server não permitir que controllers externos tenham acesso aos eventos gerados por ele pode parecer ruim a princípio, mas na verdade é uma boa escolha. Se o mecanismo não fosse implementado dessa forma poderíamos ter um cenário onde o DBA inicia uma sessão de XEvents com o target de ETW e posteriormente alguém (um sysadmin, por exemplo) inicia uma sessão de ETW (de fora do SQL Server) e consegue “roubar” os eventos da sessão de XEvents do DBA, sem deixar vestígios.

O SQL Server utiliza o que chamamos de classic providers, que podem emitir eventos para uma sessão ETW apenas. Por isso temos a implementação singleton do target de ETW dos XEvents. Os providers baseados em manifestos, introduzidos no Windows Vista/2008 permitem que várias sessões capturem os eventos de um mesmo provider, mas por questões de compatibilidade o SQL Server não os utiliza.

Uma vez que a sessão de XEvents tenha sido interrompida, o SQL Server não irá remover a sessão ETW do sistema:

ALTER EVENT SESSION test0
ON SERVER
STATE = stop;
GO

Se não vamos mais utilizá-la, nós mesmos podemos realizar o flush da sessão e removê-la:

C:tempSQL Server Tracing>logman update XE_DEFAULT_ETW_SESSION
 -fd -ets
The command completed successfully.

C:tempSQL Server Tracing>logman stop XE_DEFAULT_ETW_SESSION -ets
The command completed successfully.

E para visualizar o conteúdo do arquivo de trace, no meu caso “C:UsersMSSQL$~1AppDataLocalTempXEEtw.etl” como retornado pelo comando xperf -loggers XE_DEFAULT_ETW_SESSION acima, utilizamos o xperfview:

C:tempSQL Server Tracing>xperfview C:UsersMSSQL$~1
 AppDataLocalTempXEEtw.etl
Checkpoints no XPerf

Bastante amigável, não?

Os pontos em azul representam os eventos sqlserver.checkpoint_begin da nossa sessão XEvents, e os pontos em vermelho representam sqlserver.checkpoint_end.

O Xperf e o seu sucessor Windows Performance Analyzer não são conhecidos pela sua facilidade de uso, mas permitem análises de desempenho extremamente precisas.

Um ponto em comum entre os artigos sobre XEvents que encontrei são o fato de todos comentarem a respeito do possível correlacionamento de eventos dos XEvents e do ETW, mas não encontrei nenhuma documentação de como podemos realizá-lo (muito menos de uma forma útil).

Apesar de não ser exatamente óbvio ou amigável, é sim possível fazê-lo. Nos próximos posts vamos entender como podemos correlacionar as informações dos XEvents e do sistema operacional e através dessas informações tentar visualizar o que realmente está acontecendo no processamento de nossas queries, pela visão do SO.

Se você estiver interessado em saber mais sobre o uso do ETW com os XEvents, aconselho que dê uma olhada também no post An XEvent a Day (10 of 31) – Targets Week – etw_classic_sync_target do Jonathan Kehayias.

Além disso, ainda tenho diversos testes e investigações a fazer com os XEvents e o ETW, que vou continuar postando aqui. :)

Pin It

Está chegando: 24 Horas de PASS Português!

Pessoal, esse mês teremos o primeiro evento 24 Hours de PASS em Português em conjunto com os nossos amigos de Portugal!

Logo - 24 Hours de PASS

24 Horas de PASS - Português

Para quem não conhece, o 24HOP é um evento gratuito e você pode acompanhar tudo on-line. Com duas rodadas de 12h non-stop de SQL Server entre os dias 27 e 28 desse mês, tendo início às 11h de Brasília (ou 13h de Portugal, se você estiver do lado de lá do Atlântico.)

As comunidades Brasileira e Portuguesa prepararam diversas apresentações, e como sempre a Sr. Nimbus não poderia deixar de participar. Nós vamos marcar presença com algumas palestras, sendo que a primeiríssima palestra do evento será nossa! Mais precisamente dos nossos amigos e colegas Fabiano Amorim (Twitter | Blog) e Gilberto Uchôa (Blog):

Sessão 01 – 11:00 (13:00 GMT)
"T-SQL Expert – Escrevendo códigos “like a Boss”"
Fabiano Amorim & Gilberto Uchôa

A agenda com todas as palestras pode ser encontrada no site do PASS. Dá só uma olhada no pessoal que estará apresentando!

Então não deixe de assistir e aproveite pra aprender bastante SQL Server com os melhores profissionais da área! :)

Pin It

Introdução ao WinDbg

WinDbg

O WinDbg é uma interface de ferramenta de depuração (debugger ou depurador) sofisticado desenvolvido pela Microsoft distribuído gratuitamente com o SDK (e o DDK) do Windows. Ele pode ser utilizado tanto para depuração em user-mode ou kernel-mode. Apesar de não ser um depurador por si só – por baixo da interface gráfica o WinDbg utiliza os depurados de linha de comando cdb (user-mode) e kd (kernel-mode) – para os nossos propósitos vamos tratá-lo como tal no restante desse post.

Símbolos

Durante a compilação de um software com as ferramentas do Visual Studio, através de parâmetros ao compilador é possível gerar arquivos .pdb que são bancos de símbolos do módulo que está sendo compilado. Sendo menos abstrato, o arquivo .pdb mapeia endereços de memória do módulo – ininteligíveis aos seres humanos – aos seus nomes originais, no código-fonte. Dessa forma é possível observar os nomes das funções, classes, métodos, parâmetros, tipos, entre diversas outras informações à respeito do módulo executável mesmo sem possuirmos acesso ao código-fonte original, desde que o software tenha sido compilado com os parâmetros para a geração do pdb e que tenhamos acesso aos símbolos.

A Microsoft, por sua vez, compila (quase) todos os seus módulos (inclusive os de SQL Server!) com símbolos e os distribui gratuitamente na internet para que os profissionais que tiverem necessidade (ou interesse) pela utilização desses símbolos tenham acesso a eles e possam utilizá-los nas suas sessões de depuração (entre outras coisas que são possíveis através dos símbolos, mas falarei sobre isso em outro post :)).

Símbolos privados e públicos

Nem tudo são flores, infelizmente.

Existem dois tipos de símbolos, os chamados de privados, que podem ser utilizados juntamente do código-fonte do software para debugging por parte do desenvolvedor do mesmo e contém todas as informações à respeito do módulo, e os símbolos públicos, que são símbolos que contém um número bem menor de informações e que são distribuídos ao público geral.

Os símbolos públicos não contém informações bastante relevantes como tipagem de dados, parâmetros, entre outras coisas, mas já fornecem informação o suficiente para possibilitar o uso do WinDbg na depuração de problemas ou para ganhar um insight no funcionamento interno (interno mesmo!) do software.

Servidor de símbolos

Qualquer empresa pode disponibilizar os símbolos de seus módulos da maneira que preferir. A Microsoft disponibiliza os símbolos através de um servidor através da URL http://msdl.microsoft.com/download/symbols. Apesar de parecer uma URL comum, essa URL não é utilizada para navegação e sim na configuração do WinDbg para que ele mesmo baixe os símbolos de forma preguiçosa (por default, apesar de eu preferir carga imediata para evitar delays durante a depuração.)

Configuração dos símbolos

Quando o WinDbg precisa de algum símbolo que não está carregado, ele primeiramente irá procurar no diretório padrão de símbolos e, caso não encontre neste diretório irá procurá-los no servidor de símbolos.

Para configurar o WinDbg de forma a carregar os símbolos através do servidor oferecido pela Microsoft, temos diversas opções:

  1. Configuração à nível de sistema e/ou usuário através da variável de ambiente _NT_SYMBOL_PATH.
  2. Configuração à nível de sessão no Command Prompt, também através da variável de ambiente _NT_SYMBOL_PATH.
  3. Na sessão de debugging dentro do WinDbg através do comando .sympath (ou ainda automaticamente através de .symfix.)
  4. Ou ainda através do parâmetro -y na linha de comando do WinDbg.

Particularmente, eu prefiro deixar o ambiente configurado por facilidade na hora da depuração e por haver o compartilhamento da configuração com outras ferramentas que façam uso dos bancos de símbolos, como Xperf por exemplo.

Setting environment variable using the System Properties Window

Variável de ambiente - System Properties

No WinDbg:

Setting symbols path using the .sympath WinDbg command

Configuração de símbolos no WinDbg

Como já mencionado, apesar dos símbolos públicos não oferecerem informações bastante relevantes para o processo de debugging como os símbolos privados, com assinaturas completas de funções e métodos, e exigir um pouco mais de esforço, ainda é possível identificar variáveis e parâmetros na memória do processo. A brincadeira fica muito mais fácil quando estamos falando de APIs documentadas, como a Windows API, com as assinaturas facilmente encontradas no MSDN, bastando apenas um pouquinho de conhecimento da convenção de chamadas da arquitetura em uso, que hoje em dia é na maioria dos casos o x64:

Breakpoint at VirtualAlloc

Breakpoint em VirtualAlloc

Windows API e x64 call convention

A VirtualAlloc é uma API utilizada para reservar ou confirmar (commit) endereço de memória virtual (VAS) do processo. Como é possível ver acima, não temos nenhuma informação à respeito dos parâmetros que estão sendo utilizados na chamada dessa API, mas através da sua documentação podemos observar quais parâmetros são esperados por ela:

LPVOID WINAPI VirtualAlloc(
   _In_opt_  LPVOID lpAddress,
   _In_      SIZE_T dwSize,
   _In_      DWORD flAllocationType,
   _In_      DWORD flProtect
 );

A convenção de chamadas x64 da Microsoft determina que os 4 primeiros parâmetros serão colocados nos registradores 64-bit rcx, rdx, r8 e r9, nesta ordem. À partir dos 4 primeiros parâmetros a brincadeira fica um pouco menos direta, mas como nesse caso temos exatamente 4 parâmetros, não vamos nos preocupar com isso agora.

Parameters for VirtualAlloc in Windbg

Registradores com os parâmetros de VirtualAlloc

Vamos primeiro verificar os valores dos parâmetros e depois tentar entendê-los:

  • (LPVOID) lpAddres: Podemos ver que o primeiro parâmetro, lpAddress, recebeu o valor 0 ou NULL em C/C++.
  • (SIZE_T) dwSize: O segundo parâmetro recebeu o valor 80000.
  • (DWORD) flAllocationType: O terceiro parâmetro recebeu o valor 101000.
  • (DWORD) flProtect: O quarto e último parâmetro recebeu o valor 4.

Segundo a documentação no MSDN, se a API VirtualAlloc recebe no primeiro parâmetro lpAddress o valor NULL, significa que o sistema deve determinar o endereço de destino onde realizar a alocação da memória:

“If this parameter is NULL, the system determines where to allocate the region.”

O parâmetro dwSize, por sua vez, determina a quantidade de memória a ser alocada. No nosso caso o valor é 80000h = 524288 / 1024 = 512 KB:

“The size of the region, in bytes.”

flAllocationType determina o tipo de alocação, mas a tabela na documentação não informa o valor 101000 que recebemos. É comum em C e C++ passarmos múltiplas flags em um único parâmetro realizando o que chamamos de opereação de OR lógico (| em C/C++), portanto 101000 equivale  a:

  • MEM_COMMIT – 0x00001000
  • MEM_TOP_DOWN – 0x00100000

Por fim o parâmetro flProtect recebe o valor 4, que indica a o tipo de proteção da memória:

  • PAGE_READWRITE – 0x04

Portanto a chamada que depuramos na screenshot corresponde a uma alocação de 512 KB de memória virtual com proteção de leitura e escrita realizada pelo processo do SQL Server!

Existem algumas considerações a serem feitas à respeito dessa chamada, mas não vou me adentrar nesse assunto neste post. A documentação do MSDN explica muito bem a chamada e seus parâmetros se você quiser se aprofundar um pouco mais nessa ou no restante das APIs do Windows.

Estou com alguns outros posts de WinDbg à caminho, mas não poderia ter começado a série sem dar uma introdução bem básica à ferramenta. Espero que eu tenha conseguido explicar e demonstrar um pouquinho da utilização do WinDbg e aberto caminho para mais investigações e sessões de debugging no futuro!

Pin It

Como encontrar o autor de um trace no SQL Server

Digamos que em uma bela manhã você encontre um trace estranho em seu ambiente SQL Server, através da catalog view sys.traces:

select *
from sys.traces;
go

Result set from sys.traces

Como você determina o autor do trace?

A sys.traces possui uma coluna chamada reader_spid que você pode utilizar juntamente com a DMV sys.dm_exec_sessions e descobrir qual o usuário que está atualmente recebendo as informações deste trace. Neste caso, porém, o usuário não está conectado (o status do trace é `0`) e portanto a coluna reader_spid retorna NULL.

Em casos como esse você pode recorrer ao Default trace do SQL Server para verificar quem foi o responsável pela criação do trace, filtrando pelo nome do objeto sp_create_trace (coluna ObjectName).

Você pode utilizar o horário de criação do trace na coluna start_time da sys.traces para ter uma idéia relativa de quando a definição do trace foi criada, mas vale lembrar que o horário de inicialização do trace nem sempre equivale ao seu horário de criação, uma vez que o usuário pode parar e reiniciar o mesmo.

Sendo assim:

select *
from fn_trace_gettable(‘C:Program FilesMicrosoft SQL ServerMSSQL10_50.MSSQLSERVERMSSQLLoglog_10.trc’, -1)
where ObjectName = ‘sp_trace_create’;
go

fn_trace_gettable on Default Trace filtered by object name
E assim você pode determinar que o usuário responsável pelo trace é o usuário usrTracer, e que o mesmo criou esta sessão de trace através do SQL Server Profiler. :)

Pin It

Ferramentas de um DBA SQL Server

Sempre acreditei que boas ferramentas ajudam na realização de um bom trabalho, e com o tempo e a experiência juntei algumas das ferramentas mais recorrentes no meu trabalho como DBA.

Algumas dessas ferramentas não estão diretamentes ligadas ao SQL Server, mas ajudam na hora de realizar algumas tarefas comuns aos administradores.

Essa lista não é de forma alguma exaustiva, mas quem sabe pode ser o primeiro post de uma série, não é? smile face

Vamos por ordem de mais genérica à mais pontual:

Command Prompt

Sem dúvida alguma a minha ferramenta favorita, independente de plataforma. Trabalhei alguns anos com Unices (BSDs, Solaris e Linux) e provavelmente a melhor lição que tirei dessa experiência foi o uso da linha de comando para tarefas repetitivas. Muita gente descarta o Command Prompt do Windows por não ser tão flexível como o shell (bash, zsh e cia.) dos Unices, mas acredito que quando utilizado juntamente com outras ferramentas (logo abaixo), ainda é bastante útil.

Sysinternals Tools

As melhores ferramentas para qualquer tipo de administração em plataformas Windows, em linha de comando ou GUI.
Estão disponíveis gratuitamente pela Microsoft aqui, ou melhor ainda, você pode mapear a unidade remota (chamado de Sysinternals Live) diretamente:

Command Prompt

Mapeando Sysinternals Live pelo Command Prompt

Dessa forma você terá acesso fácil sempre às versões mais recentes das ferramentas, pelo Command Prompt ou Windows Explorer:

Windows Explorer with Network Mapped Drive

Mapeamento do Sysinternals Live no Windows Explorer

SQLCMD

O SQLCMD é uma mão na roda para realizar tarefas repetitivas de setup de bancos de dados, por exemplo. Geralmente eu crio scripts T-SQL e os executo através de um arquivo de batch (.bat) pela linha de comando, através de um job, pelo Makefile, ou algo do gênero. O mais interessante do SQLCMD é que os scripts suportam parametrização, algo que também pode ser ativado de dentro do próprio SSMS:

SQL Server Management Studio - SQLCMD Mode

Ativando SQLCMD Mode no Management Studio

PowerShell

Logo PowerShell

Windows PowerShell

Seguindo a linha de prompt de comando, o PowerShell é tudo que o bash queria ser quando crescer (que venham os trolls! :)). Na minha opinião a troca de objetos entre comandos ao invés de texto-puro é uma grande sacada.

Eu utilizo com uma frequência menor do que gostaria, mas com a ajuda do maluco do Posh – também conhecido como Laerte Junior – eu estou aprendendo a ferramenta um pouco mais à fundo e pretendo acabar fazendo o upgrade total do Command Prompt para o PowerShell em breve. Com a chegada do v3, a popularização do PowerShell na comunidade – não só SQL Server, mas em geral – só tende a aumentar.

PerfMon

Indispensável para qualquer tipo de trabalho de planejamento de capacidade, troubleshooting de desempenho e tuning, entre diversas outras utilidades, o PerfMon é uma ferramenta essencial para qualquer DBA na plataforma Windows. Há quem diga que PerfMon é ferramenta de SysAdmin, mas eu discordo veementemente. Uma introdução legal feita pelo Brent Ozar pode ser encontrada aqui.

PAL

PAL ou Performance Analysis of Logs. Essa é a queridinha do meu amigo e colega de trabalho Fabiano Amorim. Dizem por aí que ele não vive sem o PAL por perto. Ele já demonstrou o uso da ferramenta em palestras, e eu deixo o link de um webcast sobre DBA Checklist que também pode te interessar que ele fez com o Luti aqui na Sr. Nimbus onde ele demonstra um pouco do uso da ferramenta. :)

 

Pin It

SQL Server + Nuvem

O blog ficou meio parado por algumas semanas… Após o último post tivemos dois cursos fantásticos (Internals e Indexing) na Sr. Nimbus, alguns projetos novos e bastante trabalho! E para quebrar o silêncio e a inércia, nada melhor do que falarmos sobre dois assuntos muito interessantes e que levamos bastante a sério aqui na Nimbus: SQL Server e cloud computing! Smile

Muito tem sido falado a respeito de bancos de dados “web scale” e NoSQL, e acho que esse vídeo resume bem a minha opinião sobre o assunto:

There ain’t no such thing as a free lunch

Após alguns anos de certa histeria entre a comunidade de desenvolvedores web pelo mundo afora, chegamos a um ponto onde percebemos que NoSQL não é exatamente a solução definitiva para todos os problemas, ou o que chamamos de silver bullet.

NuoDB Logo

NewSQL: NuoDB

A arquitetura dos bancos de dados NoSQL pode diferir significativamente uma da outra, porém em geral eles abrem mão das propriedades ACID (com exceções) em favor da “infinita” escalabilidade que tanto ouvimos falar, mas a verdade é que não existe nada inerente no SQL ou nas propriedades em si que não permitam o mesmo tipo de escalabilidade. Exemplo disso são os novos bancos de dados relacionais (chamados de NewSQL) que estão surgindo, como o NuoDB, que vem ganhando destaque pela sua escalabilidade e benchmarks.

No lado do SQL Server nós temos algumas opções quanto a nuvem.

A primeira delas, que vem sido bastante falada, é o Azure SQL Database (antigo SQL Azure).

O SQL Database não é exatamente SQL Server, mas é próximo o suficiente para podermos considerá-lo aqui. Apesar de ser limitado a bancos de dados de até 5 GB para a edição Web e 150 GB para a edição Business, o SQL Database possui um mecanismo muito interessante de escalabilidade “infinita” através de Federations (que hoje tem um soft-limit de 150 bancos de dados por servidor).

Outra opção é o serviço de bancos de dados relacionais da Amazon, o Amazon RDS.

O Amazon RDS nada mais é do que um servidor SQL Server fornecido e administrado pela Amazon, onde você pega em um modelo baseado em uso de infraestrutura (opcionalmente incluindo licenciamento), no modelo IaaS, ao contrário do Azure SQL onde pagamos pelo consumo propriamente dito. É mais ou menos como contratar um servidor EC2 na Amazon e instalar o SQL Server, porém sem ter que administrá-lo (até certo ponto). Apesar de ser SQL Server propriamente dito, nem todas as funcionalidades estão disponíveis e o custo é relativamente alto. (Vale dizer que o SQL Server está incluído no Free Usage Tier promocional de 1 ano para novos clientes. Mais informações aqui.)

Outra opção é, digamos, à moda antiga. Contratar um servidor EC2 com Windows Server e gerenciar seu próprio servidor de bancos de dados. Algo interessante nesse cenário é que a Amazon oferece imagens EC2 com SQL Server pré-instalado e com o licenciamento incluído no valor por hora da imagem, dessa forma eliminando a necessidade (e alto custo) de compra de uma licença para seu banco de dados, no formato pay-as-you-go. (A opção de utilizar uma licença já adiquirida também está disponível, com algumas restrições.)

Dessa forma você tem um servidor SQL Server com todas as suas funcionalidades, sem restrições (exceto, obviamente, as da sua licença).

Cenários

Azure SQL Database

Windows Azure Logo

Microsoft's Cloud

O mecanismo de Federations permite uma grande elasticidade no banco de dados, porém não funciona de forma transparente para as aplicações. É necessário tomar alguns cuidados na conexão do cliente ao banco e/ou realizar alterações em aplicações pré-existentes para que funcionem nesse tipo de cenário. Outro ponto importante é que mesmo sem utilizar Federations, o SQL Database não é 100% compatível com o SQL Server on-premise. Por esses motivos, o Azure SQL Database pode ser mais viável e vantajoso para novas aplicações. Outra importante vantagem do SQL Database em relação às outras opções é a alta-disponibilidade out-of-the-box oferecida pelo Windows Azure.

Amazon RDS

Apesar de ser efetivamente SQL Server, o RDS tem algumas limitações de funcionalidades que devem ser levadas em conta. O Jeremiah, da Brent Ozar PLF tem um post bem interessante à respeito do assunto.

SQL Server

SQL Server Logo Amazon Logo

SQL Server on Amazon

Provavelmente a minha opção favorita hoje é rodar o SQL Server em um servidor EC2 (ou em uma Windows Azure Virtual Machine) e ter o suporte completo de todas as funcionalidades que o seu licenciamento permite. Essa é a forma mais flexível e compatível de rodar o SQL Server na nuvem hoje e possibilita a migração das aplicações existentes hoje para a nuvem (por qualquer razão que seja), porém com o custo adicional de manutenção da instância (que feito corretamente pode ser bastante reduzido).

 

Com isso temos diversas opções de SQL Server na nuvem! A decisão de qual solução utilizar, porém, vai além da preferência pessoal e dos custos. Cada uma das opções tem um cenário bem perceptível e pré-definido, e que devem ser levados em consideração para evitar surpresas desagradáveis após colocar um sistema em produção. Winking smile

Pin It