paint-brush
Postgres TOAST: Compreendendo o mecanismo de compactação de dados e suas limitaçõespor@timescale
7,544 leituras
7,544 leituras

Postgres TOAST: Compreendendo o mecanismo de compactação de dados e suas limitações

por Timescale11m2023/11/03
Read on Terminal Reader

Muito longo; Para ler

Este artigo discute as limitações do mecanismo TOAST do PostgreSQL para compactação de dados, que foi originalmente projetado para gerenciar valores grandes em uma página PostgreSQL. Embora o TOAST tenha seus méritos, ele é insuficiente em termos de otimização da eficiência de armazenamento para aplicativos modernos com grandes conjuntos de dados. O artigo apresenta a funcionalidade de compactação colunar do TimescaleDB como uma solução para reduzir significativamente o tamanho do banco de dados e, ao mesmo tempo, melhorar o desempenho da consulta. Esta abordagem permite um armazenamento mais eficiente, tornando o PostgreSQL uma escolha mais formidável para gerenciamento de dados em aplicações contemporâneas.
featured image - Postgres TOAST: Compreendendo o mecanismo de compactação de dados e suas limitações
Timescale HackerNoon profile picture


Se você estiver trabalhando com grandes bancos de dados no Postgres , esta história lhe parecerá familiar. À medida que seu banco de dados Postgres continua crescendo, seu desempenho começa a diminuir e você começa a se preocupar com espaço de armazenamento – ou, para ser mais preciso, quanto pagará por ele. Você adora o PostgreSQL, mas há algo que gostaria de ter: um mecanismo de compactação de dados altamente eficaz.


O PostgreSQL possui um mecanismo de compactação: BRINDE 🍞. Neste post, mostraremos como funciona o Postgres TOAST e as diferentes estratégias de TOASTing. Por mais que gostemos de um bom TOAST, discutiremos por que esse não é o tipo de recurso de compactação necessário para reduzir o espaço de armazenamento de grandes bancos de dados modernos - e como, como entusiastas do PostgreSQL que estamos aqui no Timescale, decidimos construir um mecanismo de compressão mais adequado para PostgreSQL, inspirado no design colunar de bancos de dados NoSQL.


O que é Postgres TOAST?

Mesmo que possa reduzir o tamanho dos conjuntos de dados, o TOAST (The Oversized Attribute Storage Technique) não é o seu mecanismo tradicional de compactação de dados. Para entender o que é TOAST, temos que começar falando sobre como os dados são armazenados no PostgreSQL .


As unidades de armazenamento do Postgres são chamadas de páginas e têm tamanho fixo (8 KB por padrão). Ter um tamanho de página fixo dá ao Postgres muitas vantagens, nomeadamente a sua simplicidade, eficiência e consistência de gestão de dados, mas tem uma desvantagem: alguns valores de dados podem não caber nessa página.


É aqui que entra o TOAST. TOAST refere-se ao mecanismo automático que o PostgreSQL usa para armazenar e gerenciar com eficiência valores no Postgres que não cabem em uma página. Para lidar com esses valores, o Postgres TOAST irá, por padrão, compactá-los usando um algoritmo interno. Se, após a compactação, os valores ainda forem muito grandes, o Postgres irá movê-los para uma tabela separada (chamada tabela TOAST), deixando ponteiros na tabela original.


Como veremos mais adiante neste artigo, você pode modificar essa estratégia como usuário, por exemplo, informando ao Postgres para evitar a compactação de dados em uma coluna específica.


Tipos de dados compatíveis com TOAST

Os tipos de dados que podem ser submetidos ao TOAST são principalmente aqueles de comprimento variável que têm o potencial de exceder os limites de tamanho de uma página PostgreSQL padrão. Por outro lado, tipos de dados de comprimento fixo, como integer , float ou timestamp , não estão sujeitos ao TOAST, pois cabem confortavelmente em uma página.


Alguns exemplos de tipos de dados que podem estar sujeitos ao TOAST são:


  • json e jsonb

  • Sequências text grandes

  • varchar e varchar(n) (se o comprimento especificado em varchar(n) for pequeno o suficiente, os valores dessa coluna poderão sempre permanecer abaixo do limite do TOAST.)

  • bytea armazenando dados binários

  • Dados geométricos como path e polygon e tipos PostGIS como geometry ou geography


Como funciona o Postgres TOAST?

Compreender o TOAST não está relacionado apenas ao conceito de tamanho de página, mas também a outro conceito de armazenamento do Postgres: tuplas. Tuplas são linhas em uma tabela PostgreSQL. Normalmente, o mecanismo TOAST entra em ação se todos os campos dentro de uma tupla tiverem um tamanho total superior a 2 kB aproximadamente.


Se você está prestando atenção, pode estar se perguntando: “Espere, mas o tamanho da página é de cerca de 8 KB – por que essa sobrecarga?” Isso ocorre porque o PostgreSQL gosta de garantir que pode armazenar múltiplas tuplas em uma única página: se as tuplas forem muito grandes, menos tuplas caberão em cada página, levando a um aumento nas operações de E/S e redução no desempenho.


O Postgres também precisa manter espaço livre para acomodar dados operacionais adicionais: cada página armazena não apenas os dados da tupla, mas também informações adicionais para gerenciar os dados, como identificadores de itens, cabeçalhos e informações de transações.


Portanto, quando o tamanho combinado de todos os campos em uma tupla excede aproximadamente 2 kB (ou o parâmetro limite TOAST, como veremos mais tarde), o PostgreSQL toma medidas para garantir que os dados sejam armazenados de forma eficiente. TOAST lida com isso de duas maneiras principais:


  1. Compressão. O PostgreSQL pode compactar os valores de campos grandes dentro da tupla para reduzir seu tamanho usando um algoritmo de compactação que abordaremos mais adiante neste artigo. Por padrão, se a compactação for suficiente para reduzir o tamanho total da tupla abaixo do limite, os dados permanecerão na tabela principal, embora em formato compactado.


  2. Armazenamento fora de linha. Se a compactação por si só não for eficaz o suficiente para reduzir o tamanho dos valores grandes dos campos, o Postgres os moverá para uma tabela TOAST separada. Este processo é conhecido como armazenamento "fora de linha" porque a tupla original na tabela principal não contém mais os valores grandes dos campos. Em vez disso, ele contém um "ponteiro" ou referência para a localização dos grandes dados na tabela TOAST.


Estamos simplificando um pouco as coisas neste artigo— leia a documentação do PostgreSQL para uma visão completa e detalhada.


O algoritmo de compactação Postgres: pglz

Mencionamos que o TOAST pode compactar valores grandes no PostgreSQL. Mas qual algoritmo de compactação o PostgreSQL está usando e quão eficaz ele é?


O pglz (PostgreSQL Lempel-Ziv) é o algoritmo de compactação interna padrão usado pelo PostgreSQL especificamente adaptado para o TOAST.


Veja como funciona em termos muito simples:


  • pglz tenta evitar dados repetidos. Quando vê dados repetidos, em vez de escrever a mesma coisa novamente, apenas aponta para onde os escreveu antes. Esse “evitar repetição” ajuda a economizar espaço.


  • À medida que pglz lê os dados, ele se lembra de alguns dos dados recentes que viu. Essa memória recente é chamada de “janela deslizante”.


  • À medida que novos dados chegam, pglz verifica se os viu recentemente (dentro de sua janela deslizante). Se sim, ele grava uma referência curta em vez de repetir os dados.


  • Se os dados forem novos ou não forem repetidos o suficiente para tornar uma referência mais curta que os dados reais, pglz apenas os anota como estão.


  • Quando chega a hora de ler os dados compactados, pglz usa suas referências para buscar os dados originais. Este processo é bastante direto, pois procura os dados referidos e coloca-os no seu devido lugar.


  • pglz não precisa de armazenamento separado para sua memória (a janela deslizante); ele o constrói em movimento durante a compactação e faz o mesmo durante a descompactação.


Esta implementação foi projetada para oferecer um equilíbrio entre eficiência de compactação e velocidade dentro do mecanismo TOAST. Em termos de taxa de compressão, a eficácia do pglz dependerá em grande parte da natureza dos dados.


Por exemplo, dados altamente repetitivos serão compactados muito melhor do que dados de alta entropia (como dados aleatórios). Você pode ver taxas de compactação na faixa de 25 a 50 por cento, mas esta é uma estimativa muito geral – os resultados variam amplamente com base na natureza exata dos dados.


Configurando o TOAST

Estratégias de brinde

Por padrão, o PostgreSQL passará pelo mecanismo TOAST de acordo com o procedimento explicado anteriormente (primeiro a compactação e depois o armazenamento fora de linha, se a compactação não for suficiente). Ainda assim, pode haver cenários em que você queira ajustar esse comportamento por coluna. O PostgreSQL permite que você faça isso usando as estratégias TOAST PLAIN , EXTERNAL , EXTENDED e MAIN .


  • EXTENDED : Esta é a estratégia padrão. Isso implica que os dados serão armazenados fora de linha em uma tabela TOAST separada se for muito grande para uma página de tabela normal. Antes de mover os dados para a tabela TOAST, eles serão compactados para economizar espaço.


  • EXTERNAL : Esta estratégia diz ao PostgreSQL para armazenar os dados desta coluna fora de linha se os dados forem muito grandes para caber em uma página de tabela normal, e estamos pedindo ao PostgreSQL para não compactar os dados - o valor será apenas movido para o Tabela TOAST como está.


  • MAIN : Esta estratégia é um meio termo. Ele tenta manter os dados alinhados na tabela principal por meio de compactação; se os dados forem definitivamente muito grandes, ele os moverá para a tabela TOAST para evitar um erro, mas o PostgreSQL não moverá os dados compactados. Em vez disso, armazenará o valor na tabela TOAST em sua forma original.


  • PLAIN : Usar PLAIN em uma coluna diz ao PostgreSQL para sempre armazenar os dados da coluna em linha na tabela principal, garantindo que não sejam movidos para uma tabela TOAST fora de linha. Leve em consideração que se os dados ultrapassarem o tamanho da página, o INSERT falhará porque os dados não caberão.


Se quiser inspecionar as estratégias atuais de uma tabela específica, você pode executar o seguinte:


 \d+ your_table_name


Você obterá uma saída como esta:

 => \d+ example_table                     Table "public.example_table" Column |    Data Type  | Modifiers | Storage | Stats target | Description ---------+------------------+-----------+----------+--------------+-------------  bar  | varchar(100000) |      | extended |       |


Se desejar modificar a configuração de armazenamento, você pode fazer isso usando o seguinte comando:

 -- Sets EXTENDED as the TOAST strategy for bar_column ALTER TABLE example_blob ALTER COLUMN bar_column SET STORAGE EXTENDED;

Parâmetros principais

Além das estratégias acima, estes dois parâmetros também são importantes para controlar o comportamento do TOAST:


TOAST_TUPLE_THRESHOLD


Este é o parâmetro que define o limite de tamanho para quando as operações TOASTing (compactação e armazenamento fora de linha) são consideradas para tuplas superdimensionadas.


Como mencionamos anteriormente, por padrão, TOAST_TUPLE_THRESHOLD é definido para aproximadamente 2 kB.


TOAST_COMPRESSION_THRESHOLD


Este é o parâmetro que especifica o tamanho mínimo de um valor antes que o Postgres considere compactá-lo durante o processo TOASTing.


Se um valor ultrapassar esse limite, o PostgreSQL tentará compactá-lo. No entanto, só porque um valor está acima do limite de compactação, isso não significa automaticamente que será compactado: as estratégias TOAST orientarão o PostgreSQL sobre como lidar com os dados com base em se eles foram compactados e em seu tamanho resultante em relação à tupla e limites de página, como veremos na próxima seção.


Juntando tudo

TOAST_TUPLE_THRESHOLD é o ponto de gatilho. Quando o tamanho dos campos de dados de uma tupla combinados exceder esse limite, o PostgreSQL avaliará como gerenciá-lo com base na estratégia TOAST definida para suas colunas, considerando compactação e armazenamento fora de linha. As ações exatas tomadas também dependerão se os dados da coluna ultrapassam TOAST_COMPRESSION_THRESHOLD :


  • EXTENDED (estratégia padrão): Se o tamanho de uma tupla exceder TOAST_TUPLE_THRESHOLD , o PostgreSQL tentará primeiro compactar as colunas superdimensionadas se elas também excederem TOAST_COMPRESSION_THRESHOLD . Se a compactação reduzir o tamanho da tupla abaixo do limite, ela permanecerá na tabela principal. Caso contrário, os dados serão movidos para uma tabela TOAST fora de linha e a tabela principal conterá ponteiros para esses dados externos.


  • MAIN : Se o tamanho da tupla ultrapassar TOAST_TUPLE_THRESHOLD , o PostgreSQL tentará compactar as colunas superdimensionadas (desde que ultrapassem TOAST_COMPRESSION_THRESHOLD ). Se a compactação permitir que a tupla caiba na tupla da tabela principal, ela permanecerá lá. Caso contrário, os dados serão movidos para a tabela TOAST em seu formato descompactado.


  • EXTERNAL : O PostgreSQL ignora a compactação, independentemente do TOAST_COMPRESSION_THRESHOLD . Se o tamanho da tupla for superior a TOAST_TUPLE_THRESHOLD , as colunas superdimensionadas serão armazenadas fora de linha na tabela TOAST.


  • PLAIN : Os dados são sempre armazenados na tabela principal. Se o tamanho de uma tupla exceder o tamanho da página (devido a colunas muito grandes), um erro será gerado.


Estratégia

Compactar se tupla > TOAST_COMPRESSION_THRESHOLD

Armazenar fora de linha se tupla > TOAST_TUPLE_THRESHOLD

Descrição

ESTENDIDO

Sim

Sim

Estratégia padrão. Compacta primeiro e depois verifica se o armazenamento fora de linha é necessário.

PRINCIPAL

Sim

Somente na forma descompactada

Comprime primeiro e, se ainda estiver superdimensionado, passa para a tabela TOAST sem compactação.

EXTERNO

Não

Sim

Sempre passa para TOAST se for superdimensionado, sem compressão.

SIMPLES

Não

Não

Os dados sempre ficam na tabela principal. Se uma tupla exceder o tamanho da página, ocorrerá um erro.


Por que o TOAST não é suficiente como mecanismo de compactação de dados no PostgreSQL

Até agora, você provavelmente já entenderá por que o TOAST não é o mecanismo de compactação de dados que você gostaria de ter no PostgreSQL. As aplicações modernas implicam grandes volumes de dados consumidos diariamente, o que significa que os bancos de dados (sobre)crescem rapidamente.


Esse problema não era tão proeminente quando nosso querido Postgres foi criado décadas atrás, mas os desenvolvedores de hoje precisam de soluções de compactação para reduzir o espaço de armazenamento de seus conjuntos de dados.


Embora o TOAST incorpore a compactação como uma de suas técnicas, é crucial entender que sua função principal não é servir como mecanismo de compactação de banco de dados no sentido tradicional. TOAST é principalmente uma solução para um problema: gerenciar grandes valores dentro dos limites estruturais de uma página Postgres.


Embora essa abordagem possa levar a alguma economia de espaço de armazenamento devido à compactação de grandes valores específicos, seu objetivo principal não é otimizar o espaço de armazenamento em todos os aspectos.


Por exemplo, se você tiver um banco de dados de 5 TB composto de pequenas tuplas, o TOAST não ajudará você a transformar esses 5 TB em 1 TB. Embora existam parâmetros no TOAST que podem ser ajustados, isso não transformará o TOAST em uma solução generalizada de economia de armazenamento.


E há outros problemas inerentes ao uso do TOAST como mecanismo de compactação tradicional no PostgreSQL, por exemplo:


  • Acessar dados TOASTed pode adicionar sobrecarga, especialmente quando os dados são armazenados fora de linha. Isso se torna mais evidente quando muitos textos grandes ou outros tipos de dados compatíveis com TOAST são acessados com frequência.


  • O TOAST carece de um mecanismo fácil de usar e de alto nível para ditar políticas de compactação. Ele não foi desenvolvido para otimizar os custos de armazenamento ou facilitar o gerenciamento do armazenamento.


  • A compressão do TOAST não foi projetada para fornecer taxas de compressão especialmente altas. Ele usa apenas um algoritmo ( pglz ) com taxas de compactação variando normalmente de 25 a 50 por cento.

Adicionando compactação colunar ao PostgreSQL com escala de tempo

Através da extensão TimescaleDB , os usuários do PostgreSQL têm uma alternativa melhor. Inspirado no design de compactação de bancos de dados NoSQL, adicionamos funcionalidade de compactação colunar ao PostgreSQL . Essa abordagem transformadora transcende o paradigma convencional de armazenamento baseado em linhas do PostgreSQL, introduzindo a eficiência e o desempenho do armazenamento colunar.


Ao adicionar uma política de compactação às suas tabelas grandes, você pode reduzir o tamanho do banco de dados PostgreSQL em até 10x (alcançando taxas de compactação de +90 por cento) .


Ao definir uma política de compactação baseada em tempo, você indica quando os dados devem ser compactados. Por exemplo, você pode optar por compactar dados com mais de sete (7) dias automaticamente:


 -- Compress data older than 7 days SELECT add_compression_policy('my_hypertable', INTERVAL '7 days');


Através desta política de compressão, o Timescale transformará a tabela partições ( que na escala de tempo também são criados automaticamente ) em um formato colunar nos bastidores, combinando muitas linhas (1.000) em uma matriz. Para aumentar a compressibilidade, o Timescale aplicará diferentes algoritmos de compactação dependendo do tipo de dados:


  • Compressão Gorilla para carros alegóricos

  • Delta-de-delta + Simples-8b com codificação de comprimento de execução compactação para carimbos de data e hora e outros tipos semelhantes a números inteiros

  • Compactação de dicionário de linha inteira para colunas com alguns valores repetidos (+ compactação LZ na parte superior)

  • Compressão de array baseada em LZ para todos os outros tipos


Este design de compactação colunar oferece uma solução eficiente e escalonável para o problema de grandes conjuntos de dados no PostgreSQL. Ele permite que você use menos armazenamento para armazenar mais dados sem prejudicar o desempenho da consulta (melhora). E nas versões mais recentes do TimescaleDB, você também pode INSERT , DELETE e UPDATE diretamente sobre dados compactados.

Embrulhar

Esperamos que este artigo tenha ajudado você a entender que, embora o TOAST seja um mecanismo bem pensado para gerenciar grandes valores em uma página PostgreSQL, ele não é eficaz para otimizar o uso do armazenamento de banco de dados no âmbito dos aplicativos modernos.


Se você está procurando uma compactação de dados eficaz que possa impulsionar sua economia de armazenamento, experimente o Timescale. Você pode experimentar nossa plataforma em nuvem que impulsiona o PostgreSQL a novos patamares de desempenho, tornando-o mais rápido e poderoso. é grátis e não é necessário cartão de crédito -ou você pode adicionar a extensão TimescaleDB ao seu banco de dados PostgreSQL auto-hospedado.


Escrito por Carlota Soto .