PG12: Uma dúzia de patches do Postgres Professional

É bom ver nomes conhecidos na lista de Agradecimentos da versão oficial do PostgreSQL 12. Decidimos reunir as inovações e algumas correções de bugs nas quais nossos desenvolvedores trabalhavam.

1. Suporte ao JSONPath


(Nas notas de versão, isso soa como Adicionar suporte à linguagem de caminho SQL / JSON (Nikita Glukhov, Teodor Sigaev, Alexander Korotkov, Oleg Bartunov, Liudmila Mantrova)

Esse patch em si, os recursos JSONPath e o histórico do problema foram discutidos em detalhes em um artigo separado aqui no hub O JSONPath é uma grande conquista do Postgres Professional e uma das principais inovações do PostgreSQL 12 em geral.

Em 2014, A. Korotkov, O. Bartunov e F. Sigaev desenvolveram a extensão jsquery , que foi incluída como resultado no Postgres Pro Standard 9.5 (e em versões posteriores do Standard e Enterprise). Ele fornece recursos adicionais muito amplos para trabalhar com o json (b).

Quando o SQL: 2016 padrão apareceu, descobriu-se que sua semântica não é tão diferente da nossa na extensão jsquery. É possível que os autores do padrão tenham olhado para jsquery, inventando o JSONPath. Nossa equipe teve que implementar um pouco diferente do que já tínhamos e, é claro, muitas coisas novas também.

Embora um patch especial com funções ainda não tenha sido confirmado, o patch JSONPath já possui funções importantes para trabalhar com JSON (B), por exemplo:

jsonb_path_query('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 2)')  3, 4, 5 jsonb_path_query('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 5)')  0  

Além disso, algumas funções que já tinham trabalhado com JSON antes foram otimizadas . Isso foi feito com sucesso por Nikita Glukhov.

Por exemplo, o operador #>> , correspondente às funções jsonb_each_text() e jsonb_array_elements_text() , usado para converter rapidamente JsonbValue em texto, mas trabalhou lentamente com outros tipos. Agora tudo está funcionando rápido.

2. Suporte para pesquisa rápida de vizinhos mais próximos nos índices SP-GiST (KNN)


(Adicione suporte para pesquisas do vizinho mais próximo (KNN) dos índices SP-GiST. Nikita Glukhov, Alexander Korotkov, Vlad Sterzhanov)

Nikita Glukhov e Alexander Korotkov da nossa empresa continuaram o trabalho iniciado por Vlad Sterzhanov de Minsk (também conhecido como Quadrocube). O Postgres foi o primeiro DBMS a procurar seus vizinhos mais próximos - anteriormente Oracle e MS, e de uma maneira muito mais direta e conveniente - e esse foi o mérito de Oleg Bartunov e sua equipe. A idéia dessa pesquisa está no algoritmo de passagem em árvore original, que na maioria dos casos fornece um enorme ganho. A busca por vizinhos mais próximos é muito usada onde, mas no GIS é especialmente comum.

Vlad fez um patch de pesquisa KNN para trabalhar com índices espaciais SP-GiST para árvores quádruplas, quando o avião é dividido em quadrados de tamanho fixo, e para árvores KD, ou seja, árvores k-dimensionais.

Alexander Korotkov, mentor do GSoC de Vlad (Google Summer of Code), continuou o desenvolvimento com uma colega da Nikita Glukhov, profissional do Postgres. A funcionalidade foi seriamente enriquecida: o cache interno de dados foi aprimorado ao percorrer a árvore, foram adicionadas classes de operador para círculos e polígonos com ordenação por distância.

Para usar o algoritmo de busca do vizinho mais próximo, basta escrever ORDER BY [, ] e o otimizador conectará automaticamente esse algoritmo. Por exemplo

 SELECT * FROM polygons ORDER BY poly <-> point '(0,0)'; 

Patches de Nikita Glukhov podem ser vistos no github .

3. Otimização de bloqueios para acelerar a inserção nos índices da Árvore B


(Nas notas de versão, isso é Melhore a velocidade das inserções de índice btree reduzindo a sobrecarga do bloqueio. Alexander Korotkov)

Alexander Korotkov, arquiteto-chefe de sistemas do Postgres Professional, conseguiu criar um algoritmo de bloqueio mais razoável ao inserir nos índices da árvore B. O ganho após a aplicação desse patch é perceptível nos casos em que a inserção ocorre mais ou menos "em uma linha". As medições em um servidor de 72 núcleos mostraram que, nesse caso, o ganho chega a 50%. Com uma inserção caótica, o ganho não é tão perceptível.

4. WAL econômico


(Reduza a sobrecarga de gravação do WAL da criação do índice GiST, GIN e SP-GiST. Anastasia Lubennikova, Andrey V. Lepikhov)

Essa série de correções reduz o tráfego WAL gerado ao criar índices GiST, GIN e SP-GiST. Agora você pode registrar páginas desses índices apenas uma vez - no final, quando o índice já estiver criado. E, no caso de um erro ao criar o índice de entradas no WAL, as tentativas com falha não aparecerão. Anteriormente, isso só era possível ao criar uma árvore B e um RUM. Os patches usam o mecanismo WAL genérico .

Scripts estão xlog para verificar o tamanho do xlog . Os testes no banco de dados IMDB (formato JSON), no qual 4M + registros ocupando 4GB, mostraram:

 CREATE INDEX ON imdb USING gin(jb jsonb_path_ops); 

a maneira antiga executada 205 segundos, WAL 3,2 GB, e o novo algoritmo deu 133 segundos, e WAL 0,4 GB.

5. Otimização da varredura apenas de índice no caso de muitas colunas.


(Permita que as verificações apenas de índice sejam mais eficientes em índices com muitas colunas. Konstantin Knizhnik)

Ao analisar a operação do banco de dados de um dos clientes de nossa empresa, verificou- se que a mesma consulta é executada em alguns casos em mais de 25% com varredura apenas de índice do que com varredura de índice (enable_indexonlyscan = off).
Isso aconteceu quando o SELECT foi realizado em muitos campos, principalmente do tipo bytea , e seu deslocamento não foi armazenado em cache, pois esses campos não têm um deslocamento fixo (consulte também o relatório de Nikolai Shaplov “What's Inside It” ). Para descompactar o atributo k-th, você deve descompactar o k-1 anterior. Descompactar um registro por um atributo requer tempo O (N * N), em que N é o número de campos. Esses 25% já aconteceram em 10 campos.

Konstantin Knizhnik usou o algoritmo usado ao trabalhar com quadril: ao acessar o atributo k-ésimo, os k-1s anteriores são tomados e lembrados, o tempo cresce linearmente com o número de campos. Após a aplicação do patch, o tempo de execução com varredura de índice e varredura apenas de índice é praticamente o mesmo.

6. Controle de dumping de segmentos WAL para o disco


(Adicione um evento de espera para fsync dos segmentos WAL. Konstantin Knizhnik)

O kernel do PostgreSQL monitora a gravação no WAL, mas não monitora a liberação dos segmentos WAL da memória para o disco, ou seja, fsync . K. Knizhnik fez um patch que cria um novo tipo de evento, agora é chamado WALSync (o nome interno da variável é WAIT_EVENT_WAL_SYNC). Você pode vê-lo no rótulo do evento PG com a explicação “Aguardando que o arquivo WAL seja despejado em um armazenamento confiável”. Esse problema foi discutido na lista de hackers .

Quanto tempo a redefinição leva geralmente é desconhecida: o PostgreSQL padrão não sabe como agregar essas estatísticas. Mas há uma extensão pg_wait_sampling escrita no Postgres Professional. Ele pode falar sobre quais eventos o Postgres gasta tempo. Agora que o evento foi adicionado, você pode seguir o fsync .

7. Suporte para novos idiomas em dicionários stemmer


(Atualize os dicionários stemball do Snowball com suporte para novos idiomas. Arthur Zakirov)

Como as conferências do Postgres estão sendo realizadas no Nepal, é muito mais natural adicionar o Nepali ao banco de dados! Isso foi feito. Graças aos esforços de Arthur Zakirov, agora você pode usar o dicionário nepalês sobre bola de neve .

8. As funções to_timestamp () / to_date () tornaram-se mais tolerantes com os dados


(Ajuste as funções to_timestamp () / to_date () para perdoar melhor as diferenças de modelo, Artur Zakirov, Alexander Korotkov, Liudmila Mantrova)

A função to_timestamp() não funcionaria se a cadeia de formato fosse processada com espaços extras. A discussão do bug em to_timestamp() resultou em uma longa discussão sobre qual comportamento das funções to_timestamp() e, ao mesmo tempo, to_date() ser considerado correto. Para benefício de todos, ambas as funções tornaram-se mais tolerantes a espaços extras na linha de formato e na linha de entrada.

9. Os logs podem ser rotacionados via pg_ctl


(Permite o controle da rotação do arquivo de log via pg_ctl. Kyotaro Horiguchi, Alexander Kuzmenkov, Alexander Korotkov)

Em outras palavras, o utilitário pg_ctl adquiriu uma nova opção:

 pg_ctl logrotate [-D _] [-s] 

Quando esse comando é executado, o servidor alterna para um novo arquivo de log ou reabre o existente, dependendo da configuração do log . Isso pode ser necessário em situações de emergência, especialmente quando grandes arquivos de log de rápido crescimento precisam, digamos, ser transferidos para diagnóstico.

10. A capacidade de criar novos tipos de tabelas (armazenamento conectável)


(Adicione o comando CREATE ACCESS METHOD para criar novos tipos de tabela. Andrés Freund, Haribabu Kommi, Álvaro Herrera, Alexander Korotkov, Dmitry Dolgov)

Esse patch importante é uma parte essencial da infraestrutura da API de armazenamento plugável, portanto, a composição internacional dos desenvolvedores de patch. O comando CREATE ACCESS METHOD está em execução no Postgres desde a versão 9.6. Mas até o dia 12, você só podia criar métodos de acesso ao índice. Aqui está a documentação para a 11ª versão :

 CREATE ACCESS METHOD  TYPE __ HANDLER _ < ... > __       .      INDEX. 

E na documentação do dia 12 já lida : atualmente apenas TABLE e INDEX são suportados. Aliás, no 11º comando CREATE ACCESS METHOD foi fornecido pela extensão do Postgres Pro, e no 12º já PostgreSQL.

A execução da operação depende do tipo de método de acesso; se for do tipo TABLE, o table_am_handler o table_am_handler e, se for do tipo INDEX, index_am_handler (anteriormente: para métodos de acesso do tipo INDEX, deve ser index_am_handler ). Um capítulo inteiro apareceu na documentação sobre métodos de tabela.

Ao criar uma tabela, agora você pode especificar seu tipo:

 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] _ ( [ < ... > [ USING  ] 

o método é do tipo TABLE - esta é uma referência ao armazenamento conectável. Agora é heap por padrão, e antes do outro, de fato, não era. Sobre as classes de operadores aqui

default_table_access_method (string)

Este parâmetro define o método de acesso à tabela padrão que será usado ao criar tabelas ou visualizações materializadas se o método de acesso não for especificado explicitamente no comando CREATE ou ao executar o comando SELECT ... INTO, no qual o método de acesso não pode ser definido explicitamente. O valor padrão é heap . A grande discussão dos hackers ajuda a divulgar os detalhes.

Até o momento, conversamos sobre inovações. Mas as correções de erros também consomem os recursos do tempo dos programadores. Os principais são:

11. Bug: um erro em uma das estruturas


Quote_all_identifiers extras em _dumpOptions. Arthur Zakirov)

Em geral, nada de especial, um erro foi encontrado em uma das estruturas que o pg_dump usa - foi perdido pelo compilador. Mas o próprio Bruce Momjyan elogiou a descoberta.

Outros problemas com o DumpOptions podem ser encontrados aqui .

12. Erro na replicação:


(xlogreader: não leia um bloco de arquivos duas vezes. Arthur Zakirov)

Outro funcionário de nossa empresa, o desenvolvedor do pg_probackup, Grigory Smolkin, descobriu que um de nossos utilitários fica mais lento quando o xlogreader lê os arquivos zlib. Acontece que às vezes ele lê blocos de arquivos WAL duas vezes.

Se os arquivos forem lidos inconsistentemente, o desempenho será ruim. A leitura repetida do bloco é sempre inconsistente, pois você precisa retornar à posição passada chamando a função gzseek() . Agora, releitura desnecessária não ocorre.

PS: Não vou dissimular: uma dúzia de patches (falando estritamente uma série de patches) não são apenas uma coincidência acidental com o número da versão do Postgres. A lista poderia muito bem ser uma dúzia ou mais de uma dúzia. Eu pensei que seria mais bonito, e a beleza é em parte o motor da programação, sem mencionar outras áreas da atividade humana.

Source: https://habr.com/ru/post/pt472072/


All Articles