Entenda o ciclo de vida de uma Query no SQL Server: Parte 2

Anteriormente, no último artigo, nós havíamos percorrido “todo” caminho de uma Query, da sua execução à entrega ao solicitante. Mas, será que algo além acontece nos bastidores? A resposta é, como quase sempre será, sim!

Neste artigo, vamos nos aprofundar no Storage Engine, Buffer Pool, Access Methods e Transaction Log. Pegue o café e venha desvendar mais uma etapa sobre a execução de processos DDL e DML.

Storage Engine – Access Methods

Como falamos anteriormente, nesta etapa há diferenças entre processos DDL e DML. Vamos começar pela primeira: DDL é uma abreviação de Data Definition Language (Linguagem de Definição de Dados), ou seja, uma linguagem que cria ou modifica estrutura de objetos no banco de dados. Um exemplo rápido são comandos do tipo CREATE, ALTER E DROP.

Neste caso, quando o procedimento chega no Query Executor há uma interação com o Storage Engine através do Access Methods, que é quem fornece as estruturas de armazenamento dos dados e índices, bem como a interface pela qual os dados são recuperados e modificados. Ele é responsável por armazenar operações de linha, índice, alocação de páginas e versionamento. Apesar de conter todo o código da operação, ele não executa, pois, neste ponto ele passa a requisição ao Buffer Manager.

Storage Engine – Buffer manager

Você se lembra que, no primeiro artigo, comentamos que na etapa do Command Parser, o SQL analisa se há um plano de execução pronto para aquela requisição? Pois esta é justamente uma das funções do Buffer Manager:

Ele é responsável por gerenciar o Buffer Pool, ou seja, ele cuida de toda parte de recebimento, armazenagem e entrega de dados. Se você precisar ler algumas linhas de uma página de dados, ele verificará se esta página já está na cache de memória e, caso não esteja, ele buscará esta página no disco, armazenará na cache e só então devolve o resultado ao Access Methods. É nesta última etapa que acontece o famoso Wait_Type PAGEIOLATCH, que representa o tempo  necessário para ler uma página do disco e guardar em memória.

Ele também é responsável por gerenciar funções de I/O de disco para trazer páginas de dados e índices para a cache de memória e compartilhar com os usuários, além de assegurar que o Transaction Log seja escrito antes que cada alteração de banco seja executada, garantindo que essas informações guardadas no Transaction Log tenham uma ordem específica e deixando claro quais blocos de registro devem ser processados em caso de falha de sistema, independentemente de quando ou onde houve a falha.

Storage Engine – Data Cache

Bom, já sabemos que existe Buffer Pool e que quem “gerencia” essa casinha é o Buffer Manager. Contudo, neste Pool não existe apenas a Plan Cache (aliás, esta é a menor parte), existe também o Data Cache e nós vamos falar um pouco mais sobre ele agora.

O Data Cache é a partição do Buffer Pool que ocupa mais espaço. É nele que todas (sim, todas) as páginas de dados são lidas a partir do disco antes de serem usadas. E quando eu digo disco, são os datafiles dos bancos. O tempo que as páginas permanecem em cache é determinado por uma política LRU, para a qual precisamos abrir um parênteses: LRU-K (Last Recently Used) é um algoritmo que mantém “fresco na memória” uma página que é referenciada K vezes.

Cada página de dados possui em seu cabeçalho detalhes das duas últimas vezes em que a página foi acessada e é feita uma varredura periódica para determinar se essa página deve ou não continuar em Cache. Essa varredura também é efetuada pelo Buffer Manager. Sempre que uma varredura é feita, um contador é colocado na página e é incrementado toda vez que a página não é acessada por um determinado período de tempo e quando o SQL Server precisa liberar espaço em cache. Então, as páginas com o contador mais baixo são retiradas da Cache. Um tempo recomendado para que todo esse processo deva ocorrer é de 1000s.

Storage Engine – Transaction Manager / Transaction Log

Agora vamos falar sobre comandos do tipo DML. DML é uma abreviação de Data Modification Language (Linguagem de modificação de Dados). Esta é uma linguagem que resgata, guarda, modifica, insere, deleta e atualiza dados no banco de dados. Exemplo disso são comandos do tipo SELECT, UPDATE, INSERT, DELETE e etc.

O que difere os processos de DML dos processos de DDL, é que, no DML, em paralelo atua também o Transaction Manager. Quando o Buffer Manager recebe uma requisição de alteração, ela encaminha antes ao Transaction Manager para que este guarde um log desta transação para que só então guarde as páginas em cache.

O Transaction Manager possui dois componentes para garantir a consistência da requisição: O Lock Manager e o Log Manager. O Lock Manager gerencia a concorrência de dados através de locks e o Log Manager armazena de fato o log da transação no logfile. Esse tipo de processo é chamado de WAL (Write-ahead Logging).

Mas, neste processo, ainda falta alguém. De maneira análoga, o Buffer Manager está para o Buffer Pool assim como o Transaction Manager está para o Transaction Log! O Transaction Log, utiliza o logfile através dos VLF’s (Virtual Log Files) para armazenar e ordenar esses dados “recuperáveis”. Essa arquitetura é relativamente simples e a receita que o SQL Server usa é basicamente o seguinte:

 

  • Se o próximo crescimento for menor que 1/8 do tamanho físico do log atual, crie 1 VLF que abranja o tamanho do crescimento (começando com SQL Server 2014 (12.x))
  • Se o próximo crescimento for maior que 1/8 do tamanho atual do log, use o método pré-2014:
  • Se o crescimento for menor que 64 MB, crie 4 VLFs que abranjam o tamanho do crescimento (por exemplo, para um crescimento de 1 MB, crie quatro VLFs de 256 KB)
  • Se o crescimento for de 64 MB a 1 GB, crie 8 VLFs que abranjam o tamanho do crescimento (por exemplo, para um crescimento de 512 MB, crie oito VLFs de 64 MB)
  • Se o crescimento for maior que 1 GB, crie 16 VLFs que abranjam o tamanho do crescimento (por exemplo, para um crescimento de 8 GB, crie dezesseis VLFs de 512 MB)

E com isso, finalizamos mais um artigo. Os métodos de Recovery (recuperação) serão abordados em outra ocasião, pois é um processo um tanto quanto extenso.

Então, fique atento ao Blog da Rox, pois em breve será publicada a parte 3 deste conteúdo superinteressante.

Até a próxima e se inscreva em nossa newsletter!

Learn More

Entenda o ciclo de vida de uma Query no SQL Server: Parte 1

Tão importante quanto ter um modelo de troubleshooting desenhado, é entender o que levou a acontecer o incidente. Muito se pode entender do problema, olhando todos os pontos da execução da requisição, e esse é o intuito deste artigo: explorar todo o ciclo de vida de uma query. Entre a solicitação do usuário e a entrega do resultado, muita coisa acontece no SQL Server e é o que veremos a seguir.

Protocol Layer

Tudo começa quando um usuário envia uma solicitação via SNI( SQL Server Network Interface) ao banco de dados a partir de uma query, e aqui vamos utilizar o exemplo de uma instrução do tipo SELECT. Esta solicitação é encaminhada ao SBGD através de um protocolo denominado TDS (Tabular Data Stream) que fica responsável por “desembrulhar” este pacote no client e analisar o que está sendo solicitado. Este mesmo protocolo é o responsável por retornar o resultado ao solicitante ao fim da execução.

Relational Engine – Command Parser

O próximo componente é o Command Parser e é onde a “mágica” começa. Nesta camada, o SQL lida com eventos de T-SQL, analisando sua sintaxe e devolvendo caso haja quaisquer erros de volta à camada do solicitante. Com a sintaxe validada, o próximo passo é criar um plano de execução ou reaproveitar um plano ja existente no Plan Cache. Neste caso é criado uma hash do T-SQL para verificar nesta partição do Buffer Pool se há um plano adequado. se houver, a instrução é designada diretamente ao Query Executor, e falaremos mais sobre ele logo abaixo.

Relational Engine – Query Optimizer

“Beleza, mas e se não houver um plano adequado para a solicitação?”, Neste caso o CMD Parser gerará uma árvore de consulta baseado no T-SQL e enviará à camada do Query Optimizer. Esta camada é uma das mais complexas e “misteriosas” do SQL Server. ele avalia a árvore baseando-se em custos e o objetivo é encontrar o plano mais eficiente, ou seja, um plano que terá o menor custo de execução. Em um plano, cada operador tem um custo de linha de base, que é então multiplicado pelo tamanho da linha e pelo número estimado de linhas para obter o custo desse operador — e o custo do plano é o custo total de todos os operadores. Este “Custo” é apenas um número arbitrário utilizado para representar o custo de recurso do plano em questão.

Esta otimização ocorre em 3 fases e são elas:

  • Fase 0 — Durante esta fase, o otimizador analisa os NESTED LOOP JOINS e não considerará operadores de paralelismo. O otimizador vai parar aqui se o custo do plano que encontrou for < 0.2. Um plano gerado nesta fase é conhecido como um processo de transação, ou TRIVIAL PLAN (Plano Trivial).
  • Fase 1 — A Fase 1 usa um subconjunto das possíveis regras de otimização e procura padrões comuns para os quais já possui um plano. O otimizador vai parar aqui se o custo do plano que encontrou for < 1.0. Planos gerados nesta fase são chamados de QUICK PLAN (planos rápidos).
  • Fase 2 — Esta fase final é onde o otimizador puxa todas as paradas e é capaz de usar todas as suas regras de otimização. Ele também olha para o paralelismo e as visualizações indexadas (se você estiver executando a Enterprise Edition) – FULL PLAN (otimização TOTAL).

Relational Engine – Query Executor

E assim chegamos ao Query Executor. Este componente é o responsável por de fato executar a query, trabalhando por cada etapa do plano e devolvendo o resultado ao usuário. Nesta parte do ciclo, há uma interação com o mecanismo de armazenamento para recuperar ou modificar dados. E nesta parte há diferenças entre instruções DML e DDL. Iremos explorar esta diferença no próximo artigo com mais detalhes.

 

Com isso, chegamos ao fim deste artigo. Espero que tenham gostado e nos vemos no próximo capitulo.

Learn More

Conheça o Delta Lake

O mundo de dados está em constante evolução e, por vezes, alguns conceitos já estabelecidos – como por exemplo, o armazenamento em nuvem e Data Warehouses – precisam ser revistos com a chegada de novas tecnologias. O Delta Lake é exatamente um desses casos. Mas, afinal, o que é o Data Lake e quais são suas vantagens? Confira essas informações e muito mais neste artigo! 

 

O que é Delta Lake?

Criado pelo time da Databricks, Delta Lake é um projeto opensource para armazenamento de arquivos, baseado no formato delta, persistidos no HDFS ou em Data Lakes (AWS, Azure, GCP), utilizando o Spark como motor de transformação e persistência. Esse formato trará algumas vantagens que veremos a seguir no artigo, como transações ACID e versionamento dos dados

 

Como funciona o Armazenamento no

Delta Lake?

Embora à primeira vista o delta se pareça um novo formato de armazenamento, de fato, ele nada mais é do que uma mescla de armazenamento físico em Parquet (compressão Snappy) -que é um formato colunar muito utilizado no mundo dos dados – junto à uma camada adicional de metadados/logs transacionais. Aqui cabem duas observações importantes: 

  1. Os metadados/logs são persistidos no mesmo diretório da tabela Delta que está sendo manipulada, portanto não é necessário nenhuma infraestrutura adicional para armazenar esses arquivos. Abaixo vemos um exemplo da estrutura do diretório de uma tabela chamada my_table, particionada pelo campo date:
  2.  Essa camada de logs (_delta_log) irá registrar todas as alterações realizadas na tabela, salvando o histórico de transformações em arquivos json/parquet e mantendo sempre a versão mais recente das alterações como padrão, porém permitindo acessar versões anteriores da tabela também.Com base nesses arquivos que o Delta nos permite viajar no tempo, pois nos permite acessar versões antigas da tabela para consultar ou até restaurar a tabela inteira para uma versão anterior.

Quais as Vantagens do Delta Lake?

Listamos aqui algumas grandes vantagens que o Delta Lake nos traz:

  • Transações ACID (atomicidade, consistência, isolamento e durabilidade) para as tabelas
  • Escalabilidade: por se utilizar de Data Lakes nativos da Cloud, ela permite escalabilidade de petabytes
  • Viagem no tempo e auditoria dos registros: possível ver versões antigas da tabela e também os registros da sessão que  a modificou
  • Reforço e evolução dos schemas da tabela
  • Suporte à operações de Updates, Merges e Deletes
  • Funciona tanto para jobs batch quanto para streaming
  • Estratégia eficaz para múltiplas leituras e escritas concorrentes nas tabelas Delta 
  • APIs de fácil acesso, podendo ser utilizado em Python, SQL ou Scala por meio do Spark
  • Permite remover arquivos antigos com o comando VACUUM

Utilização do Delta Lake

A utilização do formato delta é bem simples e está disponível por meio das APIs do Spark em Python (Pyspark), SQL e Scala. Abaixo alguns exemplos simples de como é possível utilizar o formato com SQL:

  • Criar tabela
CREATE TABLE tabela
date DATE
id INTEGER)
USING DELTA
PARTITION BY date
LOCATION "/delta"
  • Ver detalhes da tabela
DESCRIBE DETAIL tabela;
  • Ver histórico da tabela (últimas 5 versões)
DESCRIBE HISTORY tabela LIMIT 5;
  • Apagar versões históricas da tabela (maiores de 200 horas)
VACUUM tabela RETAIN 200 hours
  • Viajando no tempo (versão antiga número 4)
SELECT * FROM tabela VERSION AS OF 4
  • Operações DML

São permitidos comandos INSERT, UPDATE, MERGE e DELETE   Todas as possibilidades de Delta Lake para os times de dados!  Conforme visto, a tecnologia do Delta Lake e seu formato delta trazem inúmeros benefícios para os times de dados que já fazem utilização do Spark ou que gostariam de começar a utilizá-lo. Embora tenha sido desenvolvido pelo Databricks, o Delta Lake é open source e pode ser utilizado em diversos outros tipos de aplicações Spark como o EMR (AWS), Dataproc (Google Cloud), Kubernetes e On-premises.  A possibilidade de ter tabelas ACID em seu Delta Lake permitiu a criação de um novo conceito no mundo de dados, o Data Lakehouse, que se propõe a ser a fusão do Data Lake com o tradicional Data Warehouse (que será tema de um próximo artigo, fique ligado!).  Esperamos que esse artigo tenha ajudado a entender melhor os conceitos do Delta Lake e como ele pode ajudá-lo em seus projetos. Caso tenha interesse em implementar um projeto ou saber mais, entre em contato com nossos Roxperts , ficaremos felizes em ajudá-lo!

Learn More