Mostrando postagens com marcador Microsoft SQL Server. Mostrar todas as postagens
Mostrando postagens com marcador Microsoft SQL Server. Mostrar todas as postagens

sexta-feira, 5 de janeiro de 2018

#19 – Para que serve

Por Junior Galvão em 02/01/2018




Neste primeiro post de 2018 não vou trazer nenhuma novidade para o Microsoft SQL Server ou banco de dados, mas sim compartilhar como faço em alguns momentos, conceitos já conhecidos da grande maioria.
Hoje quero trazer para vocês um dos assuntos mais discutidos quando estamos trabalhando com nossos servidores de banco de dados, estou me referindo ao período de processamento do comando select dentro de um bloco de transação conhecido como Ciclo de Vida de Query através do comando Select.
Sendo assim, chegou a hora de conhecer um pouco mais sobre o primeiro post de 2018, post de número 19 da sessão Para que serve. Entã seja bem vindo ao #19 – Para que serve – Ciclo de Vida de Query através do comando Select.

Introdução

Um dos comandos mais utilizados em qualquer Sistema Gerenciador de Banco de Dados ou propriamente um Banco de Dados é o comando Select, sendo este responsável em recuperar linhas do banco de dados e permite a seleção de uma ou várias linhas ou colunas de uma ou várias tabelas, no Microsoft SQL Server isso não é diferente.
Basicamente ao se executar um comando Select podemos estar trabalhando com uma simples query ou conjunto de querys que podem formar uma ou mais transações, é com base neste cenário que o comando Select composto por sua conjunto de argumentos e opções permite estabelecer um ciclo de vida dedicado exclusivamente ao seu período de compilação, execução e encerramento.
Desta forma, algumas perguntas podem surgir decorrentes do seu processo de processamento, dentre as quais destaco:
  1. Quais são as etapas para o processamento de um select? 
  2. Onde inicia e onde termina cada processo?
De uma maneira bastante simples e direta vou tentar responder estas questões, iniciando pela organização da estrutura de componentes utilizadas pelo comando Select, conhecidos como:
  • Relation Engine;
  • Storage Engine; e
  • Buffer Pool.
  1. Relational Engine é responsável pelos processos de Query OptmizerQuery Executor e Parse entre outros, avaliando toda a parte algébrica, sintaxe e plano de execução da Query.
  2. Storage Engine é o cara do I/O, responsável pelo gerenciamento e requisições de disco, alocações, Access Methods CodeBuffer Manager e Transaction MGR.
  3. Buffer Pool tem vários papeis, mas, um dos mais importantes é o gerenciamento de memória para o plano de execução e alocação de páginas no data cache.
A Figura 1 apresentada abaixo ilustra um modelo básico da estrutura de relação entre estes componentes:
Figura 1 - Estrutura dos componentes utilizados pelo comando select.
Logicamente, dentro de cada componente podemos encontrar diversos subcomponentes que formam sua estrutura, responsáveis por diversas ações e procedimentos, formando um ecossistema único para cada elemento, dentre eles destaco o Query Optimizer com suas diversas fases de otimização para gerar o plano de execução mais assertivo.
O Ciclo (Select)
O primeiro passo é estabelecer a conexão entre aplicação (ERP, CRM, Web, etc...) e o SQL Server. Para isso, é utilizado um protocolo chamado Network Interface (SNI). No fundo o SNI utiliza um outro protocolo, na verdade, podem existir vários protocolos e o mais conhecido é o famoso TCP/IP.
Figura 2 abaixo ilustra o inicio do ciclo de vida do comando select através do acesso feito por uma aplicação:
Figura 2 - Representação do inicio do ciclo de vida do comando select.
Ao realizar a conexão através da comanda e do protocolo (TCP/IP), os pacotes TDS (Tabular Data Stream Endpoints) são encaminhados ao Protocolo Layer, que tem como papel “reconhecer e interpretar” o pacote e validar a informação, assim como sua origem (client). Após isso o conteúdo (SQL Command) do pacote é enviado ao Command Parse.
A Figura 3 apresenta o comportamento do Command Parse após o processo de reconhecimento e interpretação do pacote contendo o comando select ser realizado:
Figura 3 - Comportamento do Command Parse após o processo de reconhecimento dos pacotes.
Neste cenário o CMD Parser vai fazer o seu trabalho, primeiro validando o T-SQL, checando sintaxe, nomes de objetos, parâmetros, palavras chaves. A segunda parte é procurar no Buffer Pool se já existe um plano de execução compatível para está query, se sim, ele recupera este plano e executa (Query Executor), caso contrário, passa o result da análise (Query Tree) para o Query Optmizer que é o responsável por gerar o Execution Plan (plano de execução) que será usado na execução (próxima etapa) do ciclo.
Ao receber as instruções o Query Optimizer,  identifica a query realizando diversas etapas (fases 0,1,2) de otimização, afim de encontrar o plano mais eficiente, com base no “cost-based” (I/O, CPU). Nesta etapa as estatísticas são utilizadas servindo como Input de informação para tomada de decisão do Query Optimizer. Após o termino desta etapa, o plano de execução está pronto, passando o bastão para o Query Executor
O Query Executor é quem executa a Query, na verdade ele executa o plano de execução, colocando os operadores para trabalhar. É neste ponto também que ocorre a interação com a Storage Engine via interface Access Methods (OLE DB).
Seguindo em frente, Access Methods passa a solicitação para o Buffer Manager recuperar a página de dados, se a página especifica estiver em memória, o Buffer Pool solicita ao Data Cache que recupere a pagina, e retorna ao Access Methods (leituras logicas). Ao contrário, os dados são recuperados do disco (leituras físicas), colocados em cache e devolvendo o controle para o Access Methods. 
De posse dos dados, o Access Methods devolve a informação para o Relational Engine que será enviada ao Client que a solicitou, assim o resultando do comando select é apresentado na tela da aplicação exibindo assim os dados solicitados pelo usuário. Desta maneira, nosso ciclo ou melhor o ciclo de vida do comando select esta concluído, conforme a Figura 4 apresenta abaixo:
Figura 4 - Ciclo de vida do comando select concluído e dados apresentados para o usuário.
Com isso chegamos ao final do primeiro post de 2018 e post de número 19 da sessão Para que serve.

Referências

sábado, 16 de dezembro de 2017

#18 – Para que serve

Por Junior Galvão em 15/12/2017.

Resultado de imagem para sql server 2017

Este é mais um post da sessão Para que serve, nesta última sexta-feira de aulas aqui na Fatec São Roque, hoje meu queridos pimpolhos não estão presentes, final de semestre é sempre assim eles somem, mas eu estou aqui vivinho da silva e pronto para compartilhar um pouco do conhecimento adquirido nos alguns dias.
Hoje não vou destacar novidades adicionadas ao Microsoft SQL Server em suas últimas versões, ao contrário quero trazer para você um exemplo de código que poderá lhe ajudar muito ainda mais com um novo ano que esta se aproximando rapidamente. Sempre nesta época do ano diversos estabelecimentos comerciais, lojas e demais locais de compra e venda gostam de ofertar aos seus clientes aquele tradicional folhinha ou calendário mensal do próxima ano.
É justamente isso que este novo post da sessão Para que serve tem o objetivo de trazer, apresentar como podemos através de um script desenvolvido no Microsoft SQL Server criar um calendário mensal ou anual igualzinho aqueles que ganhamos nos finais de ano.
O melhor ainda neste calendário é que nossa tabela será estrutura respeitando rigorosamente os dias da semana e seus respectivos nomes. Sendo assim, chegou a hora de conhecer um pouco mais sobre estas novas funções, desta forma, seja bem vindo ao #18 – Para que serve – Criando um calendário mensal com dias da semana.

Introdução
Um dos elementos mais comuns de se encontrar nas casas, apartamentos, escolas e demais locais de convivência é um calendário ou folhinha de meses e dias pregada nas paredes, afixada em geladeiras, portas retratos entre outros locais de fácil acesso e visualização para todos.
O elemento chamado de calendário criado a milhares de anos tem como principal função ajudar nós pessoas a nos identificar no tempo, ou seja, trata-se de um recurso tão básico mas de extrema importância no que diz respeito ao dia-a-dia das pessoas e suas atividades.
Este tipo de recurso não poderia estar ausente no Microsoft SQL Server, não que ele esteja totalmente presente, mas através das funcionalidades existentes na linguagem Transact-SQL ou simplesmente T-SQL temos total capacidade de criarmos o nosso calendário mensal ou até mesmo anual contendo os dias da semana, o número da semana e posteriormente demais dados necessários que possam compor o seu calendário.
Para que você possa acompanhar o processo de criação deste calendário personalizado, vamos utilizar como base para nosso cenário uma simples tabela denominada CalendarioMensal, nome mais do que sugestivo, começamos então pela criação desta tabela conforme apresenta o Bloco de Código 1 a seguir:
-- Bloco de Código 1 - Criando a Tabela CalendarioMensal --
Create Table CalendarioMensal
(Contador TinyInt Identity(1,1) ,
Semana SmallInt,
Segunda TinyInt Null,
Terca TinyInt Null,
Quarta TinyInt Null,
Quinta TinyInt Null,
Sexta TinyInt Null,
Sabado TinyInt Null,
Domingo TinyInt Null)
Go
Show nossa tabela CalendarioMensal esta criada e pronta para ser utilizada, nosso próxima passo é começar a estruturar o ambiente para darmos inicio a inserção dos dados que vão compor o calendário, neste caso, vamos estabelecer o dia inicial da semana e evitar a contagem de linhas a cada manipulação de dados, para tal vamos o Bloco de Código 2 conforme apresentado abaixo:
-- Bloco de Código 2 - Definindo o dia inicial da semana e evitando a contagem de linhas --
-- Definindo o dia inicial da semana --
Set DateFirst 7
Go
-- Desativando a contagem de linhas após manipulação de dados --
Set NoCount On
Go
Nosso próximo passo consiste na declaração das variáveis que iremos utilizar para definir o período de dias ou período mensal que queremos criar, desta forma, vamos utilizar as variáveis: @InicioDeMes, @FinalDeMes e @Contador, conforme o Bloco de Código 3apresentado abaixo:
-- Bloco de Código 3 - Definição e atribuição das variáveis --
-- Declarando e definindo as variáveis --
Declare @InicioDeMes Datetime,
@FinalDeMes Datetime,
@Contador TinyInt
-- Atribuindo os valores para as variáveis --
Set @InicioDeMes = '2018-01-01'
Set @FinalDeMes = '2018-01-31'
Set @Contador = 1
Observe que estou definindo o período de dias que correspondem ao mês de janeiro de 2018, sendo assim, nosso calendário mensal será criado respeitando a quantidade de dias e períodos de semana específicos do próximo mês de janeiro.
Ufa, estamos caminhando bem, vamos em frente, agora já se aproximando do processo de inserção do respectivo período de dias informado anteriormente e na sequência a atualização de cada dia de acordo com o exclusivo e respectivo dia da semana, vamos então conhecer o Bloco de Código 4 apresentado abaixo, não se esqueça de executar este bloco pois ele é o mais importante:
-- Bloco de Código 4 - Loop para inserção e atualização dos dias referentes ao mês informando --
While @InicioDeMes <= @FinalDeMes
Begin
-- Inserindo os valores na Tabela Calendário --
Insert Into CalendarioMensal Default Values
While 1<=@Contador
Begin 
Update CalendarioMensal 
               Set Segunda = Case When DatePart(WeekDay,@InicioDeMes) = 2 Then DatePart(Day,@InicioDeMes) Else Segunda End,
              Terca = Case When DatePart(WeekDay,@InicioDeMes) = 3 Then DatePart(Day,@InicioDeMes) Else Terca End,
             Quarta = Case When DatePart(WeekDay,@InicioDeMes) = 4 Then DatePart(Day,@InicioDeMes) Else Quarta End,
             Quinta = Case When DatePart(WeekDay,@InicioDeMes) = 5 Then DatePart(Day,@InicioDeMes) Else Quinta End,
              Sexta = Case When DatePart(WeekDay,@InicioDeMes) = 6 Then DatePart(Day,@InicioDeMes) Else Sexta End,
              Sabado = Case When DatePart(WeekDay,@InicioDeMes) = 7 Then DatePart(Day,@InicioDeMes) Else Sabado End,
              Domingo = Case When DatePart(WeekDay,@InicioDeMes) = 1 Then DatePart(Day,@InicioDeMes) Else Domingo End,
              Semana = IsNull(DatePart(Week, Segunda),Year(GetDate()-1))
Where Contador = @Contador 
And DatePart(Month,@InicioDeMes) = DatePart(Month,@FinalDeMes)
If DatePart(WeekDay,@InicioDeMes) = 1 
Break
Set @InicioDeMes = Dateadd(Day,1,@InicioDeMes) 
End
Set @InicioDeMes = Dateadd(Day,1,@InicioDeMes) 
Set @Contador = @Contador + 1
End
Go
Observação: Você pode estar se perguntando o porque estou utilizando o comando Update no bloco de código 4, a resposta é bem simples, analise que no comando Update estou tratando cada dia da semana de forma única para identificar ao qual dia da semana o dia que foi inserido anteriormente pertence e desta forma é feita a atualização do dia na coluna ao qual ele corresponderia na calendário impresso.
Já estamos no final, o mais complicado e talvez difícil de ser feito foi realizado e espero que tudo tenha ocorrido corretamente que se relaciona a inserção dos dados na tabela CalendarioMensal, se você chegou até é porque conseguiu, então vamos avançar mais um passo e agora ver como nossos dados forma inseridos e serão apresentado em tela, para tal procedimento utilize o Bloco de Código 5 declarado na sequência:
-- Bloco de Código 5 - Visualizando o Calendário Mensal e seus respectivos dias e semanas --
Select Semana As 'Numero da Semana',
            Segunda As 'Segunda-Feira',
            Terca As 'Terça-Feira',
            Quarta As 'Quarta-Feira', 
            Quinta As 'Quinta-Feira',
            Sexta As 'Sexta-Feira',
            Sabado As 'Sábado',
            Domingo As 'Domingo'
From CalendarioMensal
Go
Afim de ilustrar e comprovar o resultado apresentado pelo Bloco de Código 5, apresento a seguir a Figura 1 abaixo:

Figura 1 - Calendário Mensal correspondente ao mês de janeiro de 2018.
Show, show, sensacional é isso ai, conseguimos, chegamos ao final de mais um post da sessão Para que serve.

Referências

quarta-feira, 27 de setembro de 2017

Microsoft anuncia disponibilidade e detalha novos recursos do SQL Server 2017

Por Redação Computerworld
Em 25/09/2017.

Resultado de imagem para sql server 2017

Integração da linguagem de programação Python voltada à ciência de dados, processamento de gráfico com funcionalidade semelhante a NoSQL (bancos de dados não relacionais de alto desempenho) e a capacidade de rodar tanto em Linux quanto em Windows. Estes, pode se dizer, são os novos truques agregados ao novo SQL Server 2017, sistema gerenciador de banco de dados relacional da Microsoft que já tem quase 30 anos de idade.

As novas features foram detalhadas pela companhia nesta segunda-feira, 25, durante a sua conferência Ignite, voltada para empresas e profissionais de TI, que acontece esta semana em Orlando, nos EUA. A Microsoft anunciou também a disponibilidade imediata da nova versão.

O SQL Server foi desenvolvido pela Microsoft em 1988, em parceria com a Sybase, inicialmente para a plataforma OS/2. Esta parceria durou até 1994, com o lançamento da versão para Windows NT e desde então a Microsoft mantém a manutenção do produto.

Entre as principais novidades da nova versão apontadas pela Microsoft estão a possibilidade de escolha da linguagem e plataformas, ou seja, o usuário poderá criar aplicativos usando a linguagem que quiser, na própria empresa ou na nuvem, e agora nos contêineres Windows, Linux e Docker; e o BI de autoatendimento e relatórios empresariais, tudo em um. Ou seja, ele permite transformar os dados brutos em relatórios que podem ser entregues a qualquer dispositivo — e, segundo a Microsoft, por um quinto do custo de outras soluções de autoatendimento.

Outra característica do SQL Server 2017 é o fato de ser o banco de dados menos vulnerável dos últimos sete anos, ressalta a Microsoft, citando testes de vulnerabilidade feitos pelo NIST, órgão do governo americano responsável por padrões e tecnologia. A empresa também destaca o uso do SQL em máquinas virtuais, o que, segundo ela, possibilita a migração fácil de cargas de trabalho do SQL Server para nuvem.

segunda-feira, 28 de agosto de 2017

Dica do Mês – Simulando a inserção de uma massa de dados aleatória

por Junior Galvão - MVP
Em 26/08/2017

Resultado de imagem para microsoft sql server management studio
Olá pessoal, boa tarde.
Estou retornando com mais um post da sessão Dica do Mês, onde hoje vou particular algo que poderá lhe ajudar de maneira simples e direta em suas atividades relacionadas a simulação de manipulação de dados no Microsoft SQL Server.
Acredito que em algum momento você já teve a necessidade de inserir dezenas, centenas ou até mesmo milhares de linhas em uma determinada tabela em seus bancos de dados, se você ainda não passou por esta necessidade pode ter a certeza que em algum momento isso poderá lhe acontecer.
Pensando justamente nisso, vou compartilhar no post de hoje um script de minha autoria que utilizo justamente para realizar esta inserção de dados aleatórios em uma tabela específica sem levar em consideração a qualidade e veracidade dos dados, como também regras de integridade referencial ou normalização.
Sendo assim, seja bem vindo ao post - Dica do Mês - Simulando a inserção de uma massa de dados aleatória.
Bom divertimento......

Introdução

A necessidade de se trabalhar com um volume considerável de dados pode ser algo bastante comum para muitos profissionais de bancos de dados, para outros nem tanto.
Este pode parecer um cenário bastante complexo, que venha a exigir um grande conhecimento técnico ou até mesmo o uso de ferramentas de terceiros para tal finalidade. Mas na sua grande maioria os recursos existentes no próprio Microsoft SQL Server nos permite criar scripts ou blocos de códigos capazes de realizar tão procedimento sem requerer a obtenção ou exigência de um alto nível de conhecimento.
Nosso Cenário
Afim de tentar ilustrar como podemos realizar este tipo de procedimento em um ambiente de banco de dados, vamos trabalhar com um ambiente de banco de dados bastante simples e que apresenta baixa complexidade.
Nosso ambiente será forma por uma única tabela denominada MassaDeDados, composta pela seguinte estrutura de colunas:
  • Codigo;
  • ClienteID;
  • VendedorID;
  • Quantidade;
  • Valor; e
  • Data
A coluna denominada Codigo será definida como nossa coluna chave primária artificial numerada de forma sequência próprio SQL Server, tento como finalidade evitar a duplicação de registros e principalmente ser utilizada como atributo de busca e pesquisa de nossos dados. As demais colunas estarão sendo utilizadas como atributos complementares para ilustrar a capacidade de geração de dados aleatórios e posteriormente inseridos em nossa tabela MassaDeDados.
A seguir apresento o Bloco de Código 1, utilizado para criação da tabela MassaDeDados:
-- Bloco de Código 1 --
Create Table MassaDeDados
(Codigo int IDENTITY(1,1) NOT NULL Primary Key,
ClienteId int NOT NULL,
VendedorId varchar(10) NOT NULL,
Quantidade smallint NOT NULL,
Valor numeric(18, 2) NOT NULL,
Data date NOT NULL)
Go

Perfeito, note que este bloco de código é bastante simples, nosso próximo passo será justamente trabalhar com o bloco de código que nos permitirá gerar o volume de dados aleatórios inseridos na sequência dentro da tabela MassaDeDados, para tal procedimentos vamos utilizar o Bloco de Código 2 apresentado abaixo:
-- Bloco de Código 2 --
Declare @Texto Char(130), @Posicao TinyInt, @ContadorLinhas Int
Set @Texto = '0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyzŽŸ¡ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåæçèéêëìíîïðñòóôõöùúûüýÿ' -- Existem 130 caracteres neste texto --
Set @ContadorLinhas = Rand()*100000 -- Definir a quantidade de linhas para serem inseridas --
While (@ContadorLinhas >=1)
Begin

Set @Posicao=Rand()*130

If @Posicao <=125
Begin
Insert Into MassaDeDados (ClienteId, VendedorId, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao+2,2),SubString(@Texto,@Posicao-4,4),SubString(@Texto,@Posicao+2,4)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End
Else
Begin
Insert Into MassaDeDados (ClienteID, VendedorID, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao-10,1),SubString    (@Texto,@Posicao+4,6),SubString(@Texto,@Posicao-12,3)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End
Set @ContadorLinhas = @ContadorLinhas - 1
End

Agora basta executar o bloco de código e verificar o resultado obtido, no meu caso após a execução deste mesmo exemplo obtive o resultado apresentado pela Figura 1apresentada abaixo:
Figura 1 - Massa de Dados aleatórios inseridos na tabela MassaDeDados.
Observando a Figura 1, torna-se fácil analisar o conjunto de dados aleatórios inseridos em cada coluna de nossa tabela, como também, a quantidade de linhas inseridas sendo um total de 41.857 linhas de registros.
Inicialmente o tamanho do bloco de código poderá parecer complexo ou até mesmo confuso, mas na verdade não é bem assim, o grande segredo esta justamente no uso da variável @Texto que apresenta um conjunto de 130 caracteres que podemos utilizar no processo de geração do nosso volume aleatório de dados.
Outro fator muito importante é o uso da função RAND() que nos possibilidade o sorteio de números decimais, algo que ajuda bastante quando queremos trabalhar com faixas de valores distintos.
Vale ressaltar que a função RAND trabalhar com valores decimais, para que seja possível realizar o sorteio aleatório de números e depois transformar em números inteiros temos a necessidade de utilizar variáveis que trabalhem com tipos de dados inteiros, neste caso: TinyInt, SmallInt, Int ou BigInt, caso contrário os valores retornados por esta função será sempre tratados e apresentados no formato de números decimais.
Com isso chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado.
Referências
Posts Anteriores
Conclusão
Em diversos cenários temos a necessidade de imaginar diversas possibilidades para se obter a solução de um problema que inicialmente se apresenta com algo de outro muito, por outro lado realizando uma análise com calma e simulando diversos cenários esta possível solução tão "misteriosa" e "complexa" pode estar na frente de nossos olhos.
No post de hoje isso não foi diferente, realizar a inserção de um volume aleatório e fictício de dados dentro do Microsoft SQL Server pode ser feito de forma bastante simples e prática, sem requerer qualquer tipo ferramentas adicionais ou conhecimento de alto nível.

terça-feira, 18 de julho de 2017

Análise de eventos de espera pode solucionar mais rápido problemas de banco de dados

Thomas LaRock *

Publicada em 17 de julho de 2017 no site CIO


Resultado de imagem para deadlock sistemas operacionais
Oficina da Net

A maioria dos administradores de banco de dados, independentemente da plataforma, está familiarizada com o conceito de eventos de espera. Os eventos de espera são uma parte natural de um mecanismo de banco de dados que processa solicitações. Quando uma conexão é feita para o mecanismo de banco de dados, uma identificação de sessão (SPID) é atribuída, o que permite que as solicitações sejam enviadas; muitas vezes as chamamos simplesmente de consultas.
Cada solicitação pode estar em um dos três estados possíveis: em execução, executável ou suspensa. Suspensa significa apenas que o SPID está aguardando um recurso, como uma página a ser lida do disco para a memória. Quando um SPID está suspenso, o motivo pelo qual ele está aguardando é registrado como um evento de espera. Executável significa que o SPID está aguardando um agendador disponível, geralmente chamado de processador ou CPU. "Em execução" quer dizer isso mesmo: o SPID está atualmente em execução.
Como bacharel em matemática, gosto de organizar as coisas em grupos. É por isso que, quando explico o conceito de eventos de espera, gosto de pensar neles em grupos. Já discutimos os primeiros: em execução, executável e suspenso. O próximo conjunto de grupos consiste nos próprios eventos de espera, que vou categorizar usando os seguintes nomes: esperas internas, por recursos e externas.
dba
Vamos analisar o que cada um desses grupos significa para mim:
Esperas internas
As esperas internas são geralmente chamadas de travamento, bloqueio e deadlock. O motivo pelo qual o bloqueio, o travamento e o deadlock ocorrem é o isolamento da transação, uma configuração necessária para os bancos de dados relacionais, pois eles mantêm as propriedades de ACID de uma transação. Ao longo dos anos, tenho sido chamado para investigar problemas de desempenho e descobri que os usuários simplesmente experimentam os efeitos do nível de isolamento escolhido: o padrão para Microsoft SQL Server é LEITURA CONFIRMADA, e para o banco de dados do Microsoft Azure SQL, INSTANTÂNEO DE LEITURA CONFIRMADA.

As diferenças nos níveis de isolamento podem afetar o desempenho e a taxa de transferência de aplicativos. Isso não significa que, ao perceber bloqueio e travamento, você deve alterar seu nível de isolamento de transação. Você precisa investigar por que o bloqueio está ocorrendo. O ponto que defendo aqui é que esse grupo de esperas internas (provavelmente) não será resolvido adicionando mais hardwares para tratar o problema. Embora seja possível que a causa raiz seja uma restrição de recursos (veja abaixo), é aconselhável investigar mudanças em seu código e esquema antes de gastar milhares de dólares em novo hardware para "corrigir" o bloqueio, o travamento ou o deadlock.
Esperas por recursos
Essas são as esperas mais comumente conhecidas que vimos ou sobre as quais ouvimos, com nomes como PAGEIOLATCH_EX ou CXPACKET. Elas são registradas quando uma sessão está na fila suspensa conforme descrito acima. Eu as agrupo como esperas por recursos porque elas são vinculadas a um dos quatro recursos de hardware físicos principais: CPU, memória, disco e rede.

Veja o que você precisa compreender sobre as esperas por recursos: só existem duas soluções possíveis. Em primeiro lugar, use menos. Em segundo lugar, compre mais. Considere, por exemplo, a memória física. Se você tivesse uma consulta que consumisse seu pool de buffers inteiro, causando problemas de desempenho para cerca de metade das consultas, você ajustaria a consulta ou adicionaria mais memória à instância. Quando você começa a pensar nas esperas por recursos dessa maneira, fica mais fácil decidir quais ações adotar para resolver um problema.
Esperas externas
Essas esperas são registradas quando uma sessão está em execução (!) e são facilmente identificadas porque os nomes de todas elas começam com a palavra PREEMPTIVE. Essas esperas são conhecidas como esperas não cooperativas, porque o SQL Server está sendo forçado a abandonar o controle da programação dessas tarefas. Muitas vezes, isso é o resultado da necessidade do SQL Server de fazer uma chamada externa (daí o nome do grupo) para o sistema operacional com vistas a algo como um procedimento armazenado externo ou o uso de objetos de SQL CLR. É interessante observar que, no que diz respeito ao SQL Server, a tarefa está em execução, mas o SQL Server não conhece o status da chamada remota. Isso torna difícil a solução de problemas dessas esperas.

Para complicar ainda mais as coisas, essas esperas não são muito bem documentadas. A melhor forma de pesquisar essas esperas é fazer uma pesquisa pelo nome da espera, mas remova "PREEMPTIVE". Por exemplo, para o evento de espera PREEMPTIVE_OS_GETADDRINFO, vá para o Windows® Dev Center e pesquise GETADDRINFO.
Conclusão
Na minha opinião, pensar em grupos ajuda a chegar à causa raiz dos problemas de modo mais rápido. Quando se trata de eventos de espera, essa forma de pensar associada ao uso de ferramentas de análise baseadas em espera foi proveitosa para mim ao longo dos anos. No mesmo processo, como uma árvore de decisões, podemos usar o evento de espera, atribuí-lo a um grupo e, nele, conhecer as opções de otimização que temos. O resultado final é um uso eficiente de recursos para resolver o problema, mas, de forma mais importante, teremos um tempo menor para resolução dos problemas.


(*)Thomas LaRock é Head Geek da SolarWinds

quarta-feira, 12 de julho de 2017

Docker e SQL Server – Container as a Service

Por Waldemar Dibiazi Junio
Em 11/07/2017 no site Profissionais TI

Resultado de imagem para docker

Este artigo abordará como configurar e executar um serviço do SGBD Microsoft SQL no sistema operacional Linux sob um container Docker, utilizar a persistência de volumes de dados sob o container, bem como, explorar a execução de binários como o sqlcmd para estabelecer uma sessão com o serviço do SQL Server e realizar o processo de backup e restore de uma base de dados.

Um pouco de história

Docker é um projeto open source que permite automatizar o desenvolvimento, distribuição e execução de aplicações em Linux containers.
Um Linux container é um método para executar isoladamente um ou mais binários em um único host (hospedeiro), sem a necessidade de um hipervisor (que demandaria a instalação de um sistema operacional convidado).
projeto Docker pode ser instalado e configurado com facilidade não apenas em sistemas GNU/Linux, mas também em sistemas como Windows e Mac OS/X.
Diferentemente de uma tecnologia de virtualização como Linux KVM, VMWare vSphere, Xen e Hyper-V que demandam a instalação de um sistema operacional convidado, compartilham apenas o Kernel do host no qual estão sendo executados, onde binários e bibliotecas dentro de cada container são a priori restritos ao ambiente de execução de cada container.
Deste modo, cada aplicação/serviço em execução dentro de um container poderá ter seus binários e bibliotecas atualizados sem a preocupação de prejudicar outros containers.
Docker é baseado na tecnologia LXC (Linux Containers), mas temos outras tecnologias de containers como o Jails de sistemas BSD, assim como, temos tecnologias muito mais simples para criação de sandbox (que é base para a idéia empregada em Linux Containers), por exemplo, chroot, onde é possível isolar serviços como o Web Service Apache e o DNS Service Bind.
Deste modo, através do chroot podemos criar uma árvore de filesystem apenas com os arquivos necessários para o serviço, isolando um ou mais processos do serviço em questão, evitando que estes processos tenham acesso aos filesystems do host. Essa abordagem é muito útil em situações onde um serviço tem uma ou mais vulnerabilidades e uma delas foi explorada permitindo que um atacante obtenha um shell.
A partir do momento que este shell for obtido pelo atacante, o processo deste shell visualizará apenas a árvore do filesystem disponibilizada via chroot, criando assim uma sandbox que ajudará na contenção do ataque, contenção essa que se não fosse realizada permitiria ao atacante explorar outros arquivos e serviços no mesmo host.
O Docker foi desenvolvido inicialmente como uma API de alto nível que complementaria o LXC , mas a partir da versão 0.9 introduziu sua própria biblioteca, desenvolvida utlizando a linguagem GO.
Através do Docker é possível executar aplicações diversas como, por exemplo, servidores de banco de dados, web application service, servidores de banco de dados (alvo deste artigo).
Supondo que temos um host com Debian, é possível executarmos containers que disponibilize um sistema/distribuição Ubuntu, Suse ou CentOS, pois toda a árvore de filesystem contendo binários, arquivos de configuração, bibliotecas (dinâmicas e estáticas) particulares para cada distribuição estarão isoladas em cada container, onde o único elemento utilizado em comum por cada container é o kernel.

Iniciando os trabalhos:

A imagem de container Docker disponibilizada pela Microsoft que será utilizada é: microsoft/mssql-server-linux
Para este artigo utilizaremos o Docker Hub para realizar o pull da imagem acima mencionada.
A seguir temos os requisitos mínimos para poder utilizar a imagem de container Docker disponibilizada pela Microsoft:
  • Docker Engine 1.8 ou superior
  • Mínimo de 4 GB de espaço em disco
  • Mínimo de 4 GB de RAM
  • Configurar uma senha forte para a conta de administrador do serviço do SQL Server, senha essa contendo pelo menos 8 caracteres utilizando letras maiúsculas e minúsculas, números e/ou símbolos não alfanuméricos.
Para este artigo foi utilizada a distribuição Debian 9.
A instalação do Docker pode ser realizada de maneira simples através da etapas abaixo:
– Instale os pacotes que serão dependências no restante do processo de instalação do Docker Engine:
– Adicione a chave do repositório:
– Adicione o repositório ao sistema:
 – Atualize o banco de dados de referência de pacotes do sistema:
 – Instale o pacote do Docker Engine:
 – Execute os daemons do Docker e ative o serviço na inicialização do sistema:
 – Adicione o atual usuário logado no grupo de usuário Docker. Essa ação fará com que não seja necessária a utilização do comando sudo para utilização docker.
– Reinicie o sistema para testar a inicialização do serviço do Docker:
– Liste os containers criados (em execução e também que não estão em execução):
Obviamente a listagem não retornará nada pois não existem container criados.
– Crie e execute um container utilizando uma imagem de teste chamada hello-run
Esta ação fará com que o engine do Docker realize o pull da imagem diretamente do Docker Hub.
Após a execução do conteiner ele exibirá algumas mensagens, dentre elas: Hello from Docker !
Você poderá verificar que o host possui um container que não está em execução, pois o container criado e que entrou em execução apenas exibiu algumas mensagens relacionadas a teste e em seguida teve a execução finalizada.
Da mesma forma que existe um container que não está em execução, temos uma imagem que sofreu o download para o host, imagem essa utiliza de base para execução do nosso container de teste:
Vamos realizar o pull da imagem de container do SQL Server e utiliza-la para criar e executar o container que proverá um serviço de banco de dados da Microsoft sob o host atual.
Entretanto, antes disso iremos criar uma estrutura de diretórios que permitirá termos persistência dos dados do container, especificamente, do diretório /var/opt/mssql que no caso é o diretório dentro da estrutura do container que armazenará os datafiles dos bancos de dados do SQL Server.
É muito importante a configuração da persistência, pois ao finalizar o container por padrão os dados serão perdidos e em muitas situações a perda dos dados gerados durante a execução do container não é aceitável. Entretanto, tudo dependerá da finalidade do container, afinal, podemos executar um container, gerar informações nele, mas tais informações poderem ser descartadas ou as mesmas já terem sido armazenadas em outro host ou container que utiliza persistência de dados.
Portanto, crie a seguinte estrutura de diretórios:
Em seguida execute o container, que será nomeado como SQLServer01.
Aguarde o pull (download) da imagem para que o container seja criado e entre em execução.
O comando acima pode ser entendido da seguinte maneira:
run – esta opção realiza três ações: pull da imagem, criação do container e em seguida execução do container criado.
-e – permite a criação de variáveis de ambiente sob o ambiente de execução do container. No caso acima, foram criadas duas variáveis de ambiente: ACCEPT_EULA recebendo o valor Y e SA_PASSWORD recebendo o valor #AdminSQLServer2017 (que será a senha da conta System Administrator do SQL Server). Deste modo, durante a execução do binário existente na imagem que sofreu o pull, este binário irá verificar a existências destas variáveis e utilizar os valores setados nelas.
A variável ACCEPT_EULA permite que definir se os termos da licença de uso serão aceitos.
-p – permite realizar o mapeamento de portas. No caso acima, qualquer conexão a porta 1433 (  valor numérico a esquerda dos :  ) será redirecionada para a porta 1433 (  valor numérico a direita dos :  ) em listening no container.
-d – executará o container em modo background.
-v – anexará um volume externo a um volume dentro do container, no caso, teremos o mapeamento do diretório /data/containers/SQLServer01/mssql existente no host para o diretório /var/opt/mssql existente no container.
Portanto ação de criação, exclusão e alteração ocorrida em /var/opt/mssql dentro do container também ocorrerá em /data/containers/SQLServer01/mssql (que encontra-se acessível no host que executa o container).
–name – Define o nome que o container terá ao ser criado.
Em seguida verifique se o container está em execução:
Caso o container não seja listado, então execute novamente o comando docker run sem a opção -d para podermos visualizar no console qualquer mensagem de erro durante a inicialização dos binários do container.
Um erro muito comum é a falta de memória no host, lembrando que a recomendação mínima são 4 GB.
Verificada a existência de algum erro (por exemplo, quantidade de memória insuficiente), abra outro terminal e pare o container com o comando:
Para executar novamente o container, basta executar:
Verifique novamente se o container está em execução:
Com o container em execução iremos estabelecer uma sessão de usuário com o serviço em execução sob o Container.
Dentro das das vantagens clássicas de container temos isolamento, portabilidade e flexibilidade e graças a isso podemos não apenas executar binários e bibliotecas existentes em uma imagem na forma de um container que atuará como serviço, mas também podemos simplesmente realizar a chamada a outros binários existentes no container já em execução, por exemplo, um binário que represente uma ferramenta de linha de comando que faz parte da solução empacotada dentro da imagem.
Iremos iniciar o binário bastante conhecido por DBAs que trabalham com SQL Server, o sqlcmd para estabelecermos uma sessão de usuário com o serviço do SQL Server.
A opção exec realiza a chamada a binários existentes dentro de um container em execução, ou seja, sem precisar criar um novo container apenas para executar um binário já existente na imagem que foi utilizada de base para a criação do container anterior.
Já as opções -it permitem que durante a execução do binário sqlcmd seja possível estabelecer a interação entre entre o shell e o binário em execução no momento.
Após a execução do binário sqlcmd será exibido o prompt
1>
Execute a instrução SQL select a seguir acompanhada da instrução GO:
 Serão exibidos os databases padrão do SQL Server, no caso:
  • master
  • tempdb
  • model
  • msdb
Realizaremos a seguir algumas operações simples em SQL:
  • Criação de um database;
  • Abertura do database;
  • Criação de uma tabela;
  • Inserção de registros nesta tabela;
  • Consulta de registros;
Com a sessão finalizada com a instrução exit, iremos parar o container e inicia-lo novamente para comprovar que a persistência de dados está sendo realizada corretamente.
Verifique se o container não encontra-se mais em execução:
Liste os arquivos e diretórios criados no nosso diretório utilizado para persistência de dados do container:
Podemos constatar que os datafiles do nosso database empresa, bem como os datafiles dos bancos de dados default do SQL Server foram criados efetivamente no diretório de persistência.
Inicie o container novamente e verifique que o binário do serviço do SQL Server em execução sob o container irá obter acesso aos datafiles:
Execute o binário do cliente sqlcmd novamente:
Liste os databases existentes:
Executando backup completo do database empresa:
Devido o mapeamento de volume de dados no container, podemos copiar o arquivo backup-empresa.sql (existentente em /data/containers/SQLServer01/mssql) para outro local.
Restaurando o backup completo do database empresa:
Este é um exemplo simples de backup e restore, entretanto, vale salientar que existem outras opção relacionadas ao backup como, por exemplo, backup do log de transações, entre outras.
O objetivo do artigo foi apenas demonstrar a chamada de binários existentes no container não apenas para prover um serviço de banco dados, mas também utilizar ferramentas como sqlcmd existente na árvore do filesystem do container.
No próximo artigo iremos ver a instalação e configuração de um Cluster utilizando Docker Swarm e o gerenciamento de containers utilizando uma web interface.