Quanto há de novo na Dúzia do Diabo?

Estamos falando apenas do PostgreSQL 13. Em 8 de abril, ocorreu um “congelamento” - o congelamento de recursos do PostgreSQL , agora apenas os recursos que são aceitos antes desta data serão incluídos nesta versão.

É difícil nomear uma versão revolucionária disso. Não há mudanças conceituais e cardinais nele. Além disso, patches importantes, como Tabela e Funções para o padrão JSON / SQL, que eu também queria ver na PG12 ao lado do patch JSONPath, não tiveram tempo para inseri-lo; o armazenamento incorporado pronto não apareceu - apenas a interface está sendo finalizada. Mas a lista de melhorias ainda é impressionante. Preparamos um resumo bastante completo dos patches incluídos na Dúzia do Diabo.




Alterações nos comandos SQL


CREATE DATABASE ... LOCALE

Utilitiesinitdb,createdbe a equipeCREATE COLLATIONtem uma configuraçãoLOCALEque permite que você especificar valores para a direitaLC_CTYPEeLC_COLLATE. Agora, a mesma oportunidade apareceu na equipeCREATE DATABASE:

CREATE DATABASE db_koi8r TEMPLATE template0 
    ENCODING 'KOI8R' LOCALE 'ru_RU.KOI8R';

ALTER VIEW ... COLUNA RENAME

O nome da coluna na vista agora pode ser alterado com o comandoALTER VIEW. Anteriormente, isso exigia a recriação da exibição.

Suponha que você esqueceu de dar um nome à coluna:

CREATE VIEW uptime AS SELECT current_timestamp, current_timestamp - pg_postmaster_start_time();
SELECT * FROM uptime;

       current_timestamp       |    ?column?     
-------------------------------+-----------------
 2020-03-23 15:37:00.088824+03 | 04:18:24.897856

Pode ser corrigido:

ALTER VIEW uptime RENAME COLUMN "?column?" TO uptime;
SELECT * FROM uptime;

       current_timestamp       |     uptime      
-------------------------------+-----------------
 2020-03-23 15:37:40.726516+03 | 04:19:05.535548


ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION

A coluna gerada da tabela agora pode ser normalizada, ou seja, excluir a expressão para avaliá-la:

CREATE TABLE payments (
    id integer PRIMARY KEY,
    amount numeric(18,2),
    income_tax numeric(18,2) GENERATED ALWAYS AS (amount*0.13) STORED
);
INSERT INTO payments(id, amount) VALUES(1, 42);
\d payments

                                     Table "public.payments"
   Column   |     Type      | Collation | Nullable |                   Default            
        
------------+---------------+-----------+----------+--------------------------------------
 id         | integer       |           | not null |
 amount     | numeric(18,2) |           |          |
 income_tax | numeric(18,2) |           |          | generated always as ((amount * 0.13))
 stored
Indexes:
    "payments_pkey" PRIMARY KEY, btree (id)

Posteriormente, eles decidiram que o imposto de renda deve ser definido explicitamente. Exclua a expressão:

ALTER TABLE payments ALTER COLUMN income_tax DROP EXPRESSION;
\d payments

                   Table "public.payments"
   Column   |     Type      | Collation | Nullable | Default
------------+---------------+-----------+----------+---------
 id         | integer       |           | not null |
 amount     | numeric(18,2) |           |          |
 income_tax | numeric(18,2) |           |          |
Indexes:
    "payments_pkey" PRIMARY KEY, btree (id)

Obviamente, os dados existentes da coluna não desapareceram:

SELECT * FROM payments;

 id | amount | income_tax
----+--------+------------
  1 |  42.00 |       5.46


DROP DATABASE ... FORCE
Se você deseja excluir um banco de dados sem aguardar a desconexão de todos os usuários, pode usar a nova opção deFORCEcomandoDROP DATABASE.

CREATE DATABASE db;

Conecte-se ao novo banco de dados:

CREATE EXTENSION IF NOT EXISTS dblink;
SELECT dblink_connect('dbname=db');

 dblink_connect
----------------
 OK

E agora excluiremos, interrompendo à força, também pg_terminate_backend, as conexões abertas:

DROP DATABASE db WITH (FORCE);

ALTER TYPE ... SET STORAGE
O comandoALTER TYPEpermite que tipos de dados básicos alterem várias propriedades, em particular a estratégia de armazenamento. Anteriormente, você só podia configurá-lo em uma equipeCREATE TYPE.

Para demonstração, não criaremos um novo tipo de base, mas usaremos o -tsquery. Mas primeiro, crie um banco de dados separado e conecte-se a ele:

CREATE DATABASE db;
\c db

Uma estratégia de armazenamento é usada para o tipo de dados tsquery plain, para que as colunas das tabelas desse tipo obtenham a mesma estratégia:

SELECT typname,typstorage FROM pg_type WHERE typname = 'tsquery';

 typname | typstorage
---------+------------
 tsquery | p

CREATE TABLE queries (query tsquery);
SELECT attname, attstorage FROM pg_attribute WHERE attrelid = 'queries'::regclass AND attname = 'query';

 attname | attstorage
---------+------------
 query   | p

Se você precisar usar uma estratégia diferente para novas tabelas, poderá alterar o tipo de base:

ALTER TYPE tsquery SET (storage=external);
SELECT typname,typstorage FROM pg_type WHERE typname = 'tsquery';

 typname | typstorage
---------+------------
 tsquery | e

O tipo de armazenamento nas novas tabelas também será alterado:

CREATE TABLE new_queries (query tsquery);
SELECT attname, attstorage FROM pg_attribute WHERE attrelid = 'new_queries'::regclass AND attname = 'query';

 attname | attstorage
---------+------------
 query   | e

Deve-se ter em mente que a alteração de uma estratégia envolvendo o uso do TOAST plainnão pode ser alterada novamente para :

ALTER TYPE tsquery SET (storage=plain);

ERROR:  cannot change type's storage to PLAIN

Portanto, os experimentos foram realizados em um banco de dados separado, o que não é uma pena excluir.

ALTER STATISTICS ... SET STATISTICS O

comando CREATE STATISTICSpermite coletar listas dos valores mais comuns para combinações selecionadas de colunas da tabela. O número de valores mais comuns recolhidas é determinado pelo parâmetro default_statistics_target. O valor para estatísticas específicas agora pode ser alterado com o comando:

ALTER STATISTICS  SET STATISTICS _;

RECEBA PRIMEIRO com a opção WITH TIES
Como você sabe, emSELECTvez de especificar umcomando,LIMITvocê pode usar a sintaxe definida no padrão SQL:

SELECT *
FROM (VALUES (1,'1.1'), (2,'2.1'), (2,'2.2'), (3,'3.1')) t(a,b)
ORDER BY a
FETCH FIRST 2 ROWS ONLY;

 a |  b  
---+-----
 1 | 1.1
 2 | 2.1
(2 rows)

Agora ele FETCHsuporta a frase WITH TIES, que adiciona à saída todas as linhas "relacionadas" (linhas iguais às já selecionadas, se apenas a condição de classificação for levada em consideração):

SELECT *
FROM (VALUES (1,'1.1'), (2,'2.1'), (2,'2.2'), (3,'3.1')) t(a,b)
ORDER BY a
FETCH FIRST 2 ROWS WITH TIES;

 a |  b  
---+-----
 1 | 1.1
 2 | 2.1
 2 | 2.2
(3 rows)

Funções internas e tipos de dados


get_random_uuid A
nova funçãoget_random_uuidretorna o valor UUID da versão 4 (valor aleatório):

SELECT gen_random_uuid();

           gen_random_uuid            
--------------------------------------
 25e02793-80c0-438c-be07-c94b966c43ab

A função é útil para gerar valores UUID exclusivos em sistemas distribuídos.
Anteriormente, era necessário usar as bibliotecas uuid-ossp ou pgcrypto.

min_scale e trim_scale para valores do tipo numérico

A função min_scaledetermina o número de dígitos significativos na parte fracionária do número e a função trim_scaledescarta zeros não significativos :

SELECT n, min_scale(n), trim_scale(n) FROM (VALUES(42.42000)) as t(n);

    n     | min_scale | trim_scale
----------+-----------+------------
 42.42000 |         2 |      42.42

gcd e lcm

Reabastecimento na seção de funções matemáticas. Agora você pode encontrar rapidamente o maior divisor comum (gcm) e o menor múltiplo comum (lcm):

SELECT gcd(54,24), lcm(54,24);

 gcd | lcm
-----+-----
   6 | 216

Funções agregadas min e max para o tipo pg_lsn As funções agregadas foram adicionadas ao

tipo de dadosepermitem executar consultas no formulário:pg_lsnminmax

SELECT min(restart_lsn) FROM pg_replication_slots;
SELECT min(sent_lsn) FROM pg_stat_replication;

Verificando o modificador de tipo do valor de retorno de uma função

Nas versões anteriores, o modificador de tipo não foi verificado quanto ao valor de retorno da função.

Suponha que exista um tipo para armazenar unidades monetárias e uma função que retorne o valor do imposto de renda:

CREATE TYPE currency AS (
    amount numeric(18,2),
    code   text
);
CREATE FUNCTION income_tax(quantity currency) RETURNS currency
    AS 'SELECT quantity.amount * 0.13, quantity.code' LANGUAGE SQL;

Chamando a função, esperamos obter duas casas decimais, no entanto, obtemos quatro. Mesmo a conversão explícita após uma chamada de função não ajuda (terceira coluna):

SELECT amount, code, amount::numeric(18,2)
FROM income_tax(ROW(42.42, ''))\gx

-[ RECORD 1 ]--
amount | 5.5146
code   | 
amount | 5.5146

Na versão 13, o resultado está correto:

SELECT amount, code, amount::numeric(18,2)
FROM income_tax(ROW(42.42, ''))\gx

-[ RECORD 1 ]
amount | 5.51
code   | 
amount | 5.51

Os nomes localizados em to_date () e to_timestamp ()

Funçõesto_datetambémto_timestampaprendeu a compreender os nomes localizados dos meses e dias da semana. Anteriormente, apenas nomes em inglês podiam ser usados:

SELECT to_date(', 24  2020', 'TMDay, DD TMMonth YYYY');

  to_date   
------------
 2020-03-24

normalize e IS NORMALIZED

Para estar em conformidade com o padrão SQL, a função normalize () foi adicionada para normalizar uma sequência Unicode e o predicado IS NORMALIZED para verificar se uma sequência é normalizada.

SELECT str, normalize(str, NFC) AS nfc,
       str IS NFC NORMALIZED AS is_nfc_normalized,
       normalize(str, NFKC) AS nfkc,
       str IS NFKC NORMALIZED AS is_nfkc_normalized
FROM (VALUES(U&'\0032\2075')) AS vals(str)\gx

-[ RECORD 1 ]------+---
str                | 2⁵
nfc                | 2⁵
is_nfc_normalized  | t
nfkc               | 25
is_nfkc_normalized | f

Leia mais sobre os formulários de normalização do UNICODE.

Função Xid8 type e xid8_current () para números de transações de 64 bits

Adicionado um novo tipo de dados xid8 para o número de transação de 64 bits. Mas não, isso não significa que o PostgreSQL mudou para transações de 64 bits: tudo funciona exatamente como antes. Mas algumas funções retornam um novo tipo, por exemplo, agora é recomendado para uso em vez das antigas funções pg_current_xact_id txid_current, que retornou int8, e assim por diante. N.

Novos tipos de dados polimórfica família anycompatible

tipos acrescentou anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange. Ao contrário dos tipos de família anyelement, novos tipos permitem que você use não exatamente o mesmo, mas tipos realmente compatíveis.

No exemplo a seguir, a funçãomaximumcomo argumentos definidos como anycompatiblesão passados integere numeric. O valor de retorno é convertido em um valor comum para esses dois tipos:

CREATE FUNCTION maximum(a anycompatible, b anycompatible) RETURNS anycompatible
	AS 'SELECT CASE WHEN a > b THEN a ELSE b END' LANGUAGE SQL;

SELECT f, pg_typeof(f) FROM maximum(42, 42.42) f;

   f   | pg_typeof
-------+-----------
 42.42 | numeric

Além disso, os tipos anycompatible- e any- são dois conjuntos independentes de tipos:

CREATE FUNCTION first_elems(a anyarray, b anycompatiblearray)
    RETURNS TABLE(a anyelement, b anycompatible) AS $$
        SELECT ROW(a[array_lower(a,1)], b[array_lower(b,1)]);
    $$ LANGUAGE sql;
SELECT first_elems(ARRAY[1,2,3], ARRAY['a','b','c']) AS str, 
       first_elems(ARRAY[1.1,2.2,3.3],ARRAY[true,false]) bool;

  str  |  bool   
-------+---------
 (1,a) | (1.1,t)

Línguas processuais


Transformação para o tipo bool no PL / Perl
Mais recentemente, TRANSFORM de Ivan Panchenko (Postgres Professional) - bool_plperl foi confirmado . O Postgres passa valores booleanos paratouem PL / Perlf, mas para Perl nãofé um falso booleano, mas apenas a letra f, ou seja, em um contexto lógico, verdade . Esse problema pode ser resolvido de diferentes maneiras (consulte a correspondência ), mas criar TRANSFORM para bool, de acordo com Tom Lane, é o mais prático.

Execução rápida de expressões simples em PL / pgSQL

Expressões simples (pelo menos não contendo chamadas de tabela e não exigindo bloqueios) serão mais rápidas. Anteriormente, nesses casos, o tempo era improdutivo em contato com o planejador em cada ciclo.

CREATE OR REPLACE FUNCTION slow_pi() RETURNS double precision AS $$
    DECLARE
        a double precision := 1;
        s double precision := 1;
        r double precision := 0;
    BEGIN
        FOR i IN 1 .. 10000000 LOOP
            r := r + s/a; a := a + 2; s := -s;
        END LOOP;
        RETURN 4*r;
    END;
    $$ LANGUAGE plpgsql;

Ligue para slow_pi () no PG12:

SELECT slow_pi();

          slow_pi      
    --------------------
     3.1415925535898497
    (1 row)
    Time: 13060,650 ms (00:13,061)

Agora na PG13:
SELECT slow_pi();

          slow_pi      
    --------------------
     3.1415925535897915
    (1 row)
    Time: 2108,464 ms (00:02,108)

Extensões confiáveis ​​em vez de pg_pltemplate

O diretório do sistema diminuiu uma tabela. Excluídopg_pltemplate. Ele armazenou as propriedades das linguagens procedurais necessárias durante a execuçãoCREATE LANGUAGE. Agora decidimos registrar as propriedades nos scripts de extensões dos idiomas correspondentespg_pltemplatee nos livrar da própria tabela. Mas, para implementar o plano, é necessário prever a possibilidade do proprietário do banco de dados (sem direitos de superusuário) criar um idioma confiável a partir do script de extensão. De fato, agora para criar, por exemplo, plpgsql, o proprietário do banco de dados não precisa ser superusuário.

Recebido da seguinte forma. Um novo parâmetro lógico apareceu no arquivo de controle para extensõestrusted. Se ambos os parâmetrostrustedesuperuserincluída, a extensão pode ser criada não apenas pelo superusuário, mas também pelo usuário com direito CREATEao banco de dados atual (e, portanto, seu proprietário). Ao executar um script dessa extensão, serão utilizados os direitos de superusuário que inicializaram o cluster. Os objetos criados pela extensão pertencerão a ela, embora o proprietário da própria extensão seja o usuário criador.

Consequências importantes dessas mudanças:

  • As extensões confiáveis ​​abrem caminho para que desenvolvedores de terceiros criem outros idiomas confiáveis. Agora estamos limitados apenas a plpgsql, plperl e pltcl.
  • Foi pg_pltemplatedifícil escrever que plpython se refere à segunda versão da linguagem. Não pg_pltemplatefazer isso é uma etapa (necessária, embora não suficiente) para a transição para o python 3.

Índices


Compressão da árvore B
Um patch importante e aguardado (o trabalho já começou em 2015), escrito por Anastasia Lubennikova (Postgres Professional) e Peter Geigan (Peter Geoghegan), finalmente é comunicado por Peter. Nastya conseguiu falar sobre isso no PGconf Índia . O Postgres aprendeu a reduzir significativamente o tamanho dos índices da árvore B por meio da deduplicação, ou seja, economia em chaves de índice duplicadas. Esses índices foram seriamente redesenhados para que a compactação seja possível sem perda de compatibilidade com versões anteriores de índices. A idéia de desduplicação é retirada de uma arquitetura mais flexível de índices como GIN (índices reversos - Índice Invertido Generalizado).

Nestes índices mais frequentemente do que na árvore B, existe uma situação em que uma chave corresponde a um grande número de registros. No caso do processamento de texto, por exemplo, o mesmo token geralmente é encontrado em vários documentos. E é armazenado no índice apenas uma vez. Até recentemente, os índices das árvores B não sabiam como fazer isso.

Os índices das árvores B diferem dos índices GIN principalmente nas páginas de folha. Dependendo do número de registros relacionados ao mesmo valor-chave, são possíveis opções: a página contém apenas uma lista de lançamentos - uma lista de TIDs (identificadores de registros indexados), se a lista é pequena e se existem muitos TIDs, em vez de uma lista de valores ser armazenada novos "galhos de árvores" - links para outras páginas, como a lista de lançamentos ou outros galhos de árvores (eles são chamados de árvore de lançamentos).

Essa estrutura de árvore é semelhante a uma árvore B, mas difere em detalhes essenciais: por exemplo, as listas para mover-se pelas páginas do mesmo nível de árvore no GIN são unidirecionais e não bidirecionais. Portanto, não é fácil obter (inclusive) uma boa compatibilidade de novos índices deduplicados com versões antigas. E as melhorias realmente levaram mais de 3 anos. Também era necessário elaborar o mecanismo de limpeza (microvácuo) e outras nuances.

Nos testes de desempenho, todos os índices aos quais a deduplicação é aplicável diminuíram cerca de 3 vezes. A compactação de duplicatas também ajuda a índices exclusivos, eliminando o problema de aumento de índice em uma alta taxa de alterações na tabela. Um novo comportamento pode ser conectado e desconectado no nível de configurações do índice.

A verificação completa pelo índice GIN não é feita onde não é necessária
Esse patch permite, em alguns casos, evitar uma passagem completa por todo o índice GIN. Algumas operações, embora suportadas pelo índice GIN, são executadas por uma varredura completa do índice. Pegue, por exemplo, o índice para pesquisa de coluna em texto completo tsvector. Se a consulta de pesquisa tiver o formato "qualquer coisa, exceto uma palavra específica", o índice inteiro deverá ser lido na íntegra. Se, no entanto, houver outra condição na solicitação que não exija uma verificação completa do índice, o índice ainda será verificado completamente.

Com a nova otimização, uma condição mais precisa será usada primeiro, permitindo obter um ganho do índice e, em seguida, os resultados serão verificados duas vezes para levar em conta outra limitação. Compare o número de páginas que foram lidas na versão 12 (buffers):

EXPLAIN (ANALYZE, BUFFERS, COSTS OFF, TIMING OFF)
SELECT * FROM mail_messages WHERE tsv @@ to_tsquery('!vacuum') AND tsv @@ to_tsquery('analyze');

                                             QUERY PLAN                                             
------------------------------------------------------------------
Bitmap Heap Scan on mail_messages (actual rows=5864 loops=1)
   Recheck Cond: ((tsv @@ to_tsquery('!vacuum'::text)) AND (tsv @@ to_tsquery('analyze'::text)))
   Heap Blocks: exact=5167
   Buffers: shared hit=24 read=27405
   ->  Bitmap Index Scan on mail_messages_tsv_idx (actual rows=5864 loops=1)
         Index Cond: ((tsv @@ to_tsquery('!vacuum'::text)) AND (tsv @@ to_tsquery('analyze'::text)))
         Buffers: shared hit=24 read=22238
 Planning Time: 0.283 ms
 Execution Time: 3258.234 ms

com o número de buffers na nova versão:

EXPLAIN (ANALYZE, BUFFERS, COSTS OFF, TIMING OFF)
SELECT * FROM mail_messages WHERE tsv @@ to_tsquery('!vacuum') AND tsv @@ to_tsquery('analyze');

                                             QUERY PLAN                                             
---------------------------------------------------------------------------
Bitmap Heap Scan on mail_messages (actual rows=5864 loops=1)
   Recheck Cond: ((tsv @@ to_tsquery('!vacuum'::text)) AND (tsv @@ to_tsquery('analyze'::text)))
   Heap Blocks: exact=5156
   Buffers: shared hit=5179
   ->  Bitmap Index Scan on mail_messages_tsv_idx (actual rows=5864 loops=1)
         Index Cond: ((tsv @@ to_tsquery('!vacuum'::text)) AND (tsv @@ to_tsquery('analyze'::text)))
         Buffers: shared hit=23
 Planning Time: 0.250 ms
 Execution Time: 8.779 ms

Uma situação semelhante pode ser encontrada ao usar trigramas e ao verificar a ocorrência de matrizes.

Parâmetros das classes de operadores
No PostgreSQL, muitos métodos de acesso ao índice são uma “estrutura” que assume uma implementação de alto nível do algoritmo de busca, trabalhando com páginas e bloqueios, e o log do WAL. E a ligação a tipos e operadores de dados específicos é realizada usando classes de operadores.

Até agora, as classes de operadores não podiam ter parâmetros. Por exemplo, para uma pesquisa em texto completo, um índice GiST com uma classe de operadores pode ser usado tsvector_ops(sobre classes de operadores GiST aqui) Essa classe de operadores usa uma árvore de assinaturas e o comprimento da assinatura foi corrigido (124 bytes). Agora você pode especificar explicitamente o comprimento, o que permite controlar o equilíbrio entre o tamanho do índice e a eficiência (o número de colisões de hash):

CREATE INDEX ON mail_messages USING gist(tsv tsvector_ops(siglen=1024));

Alterações semelhantes para iniciantes foram feitas para outras classes de operadores GiST que usam uma árvore de assinaturas, que se aplica às extensões hstore, intarray, ltree e pg_trgm.
Mas a principal idéia para a qual essa alteração foi concebida é a capacidade de passar a expressão JSONPath para o índice GIN, para que nem todo o documento JSON seja indexado, mas apenas a parte necessária. Em muitos casos, isso reduzirá radicalmente o tamanho dos índices. Mas esse trabalho ainda precisa ser feito.

A idéia de Oleg Bartunov, a implementação de Nikita Glukhov e Alexander Korotkov (todos os três profissionais do Postgres).

O operador <-> (caixa, ponto) foi
adicionado.A operação ausente foi adicionada para uso no kNN para GiST e SP-GiST . Na PG12 ao trabalhar com tipos geométricos pointeboxvocê pode usar o operador de distância <->(point, box)e agilizará a pesquisa com os índices GiST e SP-GiST. Mas o operador simétrico para ele <->(box, point)não foi implementado, embora ele boxjá entendesse as distâncias para tipos mais complexos - polígonos e círculos.

CREATE TABLE points(point point);
CREATE TABLE boxes(box box);
INSERT INTO points VALUES('1,2','3,4');
INSERT INTO boxes VALUES(box(point(3,4),point(5,6)), box(point(13,14),point(15,16)));

No PG12:
SELECT p.point, b.box, b.box  <-> p.point distance FROM points AS p, boxes AS b ORDER BY distance;

:    : box <-> point

Se vice-versa, tudo está bem:

SELECT p.point, b.box, p.point  <-> b.box distance FROM points AS p, boxes AS b ORDER BY distance;

 point |       box       |      distance
-------+-----------------+--------------------
 (1,2) | (5,6),(3,4)     | 2.8284271247461903
 (2,1) | (5,6),(3,4)     | 3.1622776601683795
 (1,2) | (15,16),(13,14) | 16.970562748477143
 (2,1) | (15,16),(13,14) | 17.029386365926403

E no PG13:

SELECT p.point, b.box, b.box  <-> p.point distance FROM points AS p, boxes AS b ORDER BY distance;

 point |       box       |      distance
-------+-----------------+--------------------
 (1,2) | (5,6),(3,4)     | 2.8284271247461903
 (2,1) | (5,6),(3,4)     | 3.1622776601683795
 (1,2) | (15,16),(13,14) | 16.970562748477143
 (2,1) | (15,16),(13,14) | 17.029386365926403

Os índices GiST e SP-GiST serão acelerados nesta operação.

Observe que na PG13, se você perguntar:

SELECT count(*) FROM pg_operator WHERE oprname = '<->';
 count 
-------
    28

e se fizermos o mesmo na PG12, obteremos 20 entradas: na 13ª versão, a lista foi reabastecida com até 8 operadores.

Json


Suporte ao método .datetime () para jsonpath

Esse é um dos patches malsucedidos de uma grande série de patches JSONPath que o PG12 não teve tempo para concluir. Parte do padrão JSON / SQL. O problema era que todas as funções da série de patches JSONPath são imutáveis, mas a comparação de datas leva em consideração o fuso horário atual, que pode mudar durante a sessão.

Nesses casos, permitimos que as funções imutáveis ​​existentes gerem um erro sobre comparações não imutáveis. Ao mesmo tempo, esse patch possui funções com o sufixo _tz que funcionam de maneira estável nas operações com o fuso horário.

Nova função - função jsonb_set_lax

Em geral, lax é um modo de operação não estrito (ao contrário de estrito) de funções com o jsonb. Nesse caso, essa função estará operacional em uma situação em que um dos argumentos necessários é NULL. Diferente da versão estrita - jsonb_set () - ele possui um argumento adicional que indica ações no caso de NULL. Opções: use_json_null / raise_exception / return_target / delete_key. Opções sugeridas pelos usuários interessados.

Otimizado algumas funções jsonb.

Otimizado muito., principalmente através dos esforços de Nikita Glukhov (Postgres Professional). Mas analisar cada ponto neste caso é inútil: primeiro, sua abundância inflará um artigo já curto; e segundo, as alterações estão relacionadas ao dispositivo interno e nem todo usuário está interessado. Portanto, listaremos apenas a maioria deles:

  1. Função otimizada JsonbExtractScalar ();
  2. Operador otimizado # >>, funções jsonb_each_text (), jsonb_array_elements_text ();
  3. O reconhecimento do tipo JsonbContainer em get_jsonb_path_all () é otimizado;
  4. A busca do primeiro token do iterador JsonbIterator é substituída pela macro leve JsonbContainerIsXxx ();
  5. Extração de chave mais conveniente - findJsonbKeyInObject ();
  6. Armazenamento otimizado do resultado findJsonbValueFromContainer () e getIthJsonbValueFromContainer ();
  7. get_jsonb_path_all(), ;
    JsonbValueAsText.

, SQL/JSON: JSON_TABLE SQL/JSON: functions. . , . . PG14. JSONPath .


pgbench


O utilitário para executar testes de desempenho recebeu uma série de melhorias. Havia estatísticas sobre o desempenho das tarefas na fase de inicialização, uma conclusão mais visual , a capacidade de ver o código dos scripts internos , testando em uma tabela de contas particionada .

Além disso, adicionamos um comando \asetsemelhante a \gset, mas permitindo definir valores para variáveis ​​de vários pedidos enviados por vez. A linha a seguir, enviada ao servidor para execução, define as variáveis onee two:
SELECT 1 AS one \; SELECT 2 AS two \aset

pg_dump


O pg_dump aprendeu a descarregar dados de tabelas de terceiros . Através do parâmetro, --include-foreign-datavocê pode especificar uma lista de servidores de terceiros, cujos dados das tabelas serão descarregados.

Use esta descarga com cuidado. Longe do fato de que os dados devem ser enviados para um servidor de terceiros. Além disso, é bem possível que um servidor de terceiros não esteja disponível durante a recuperação. Ou um servidor de terceiros pode permitir apenas a leitura, mas não a gravação de dados.

psql


Uma série de pequenas correções torna o psql mais confortável:

  • Conclusão de guia aprimorada para várias equipes.
  • Além de \echoenviar uma sequência para STDOUT, um novo comando \warnenvia uma sequência para a saída de erro padrão (STDERR).
  • \d toast- . \d+ .
  • \dt+ «Persistence» (unlogged) (permanent).
  • \e , ; ( \g*). , psql .
  • . PROMPT1 PROMPT2 %x.
  • Novos comandos para obter mais informações sobre métodos de acesso: \dAc, \dAf, \dAo,\dAp
  • \gAgora você pode especificar entre colchetes todas as opções suportadas \pset. Eles atuarão apenas na equipe atual.


libpq


Pequenas alterações em conexão com o PostgreSQL:
  • A imprecisão na descrição dos parâmetros host e hostadr e a inconsistência resultante na saída do \conninfocomando do utilitário psql foram corrigidas.
  • Se a chave do certificado do cliente estiver armazenada no formato criptografado, você poderá inserir a senha apenas no modo interativo. O novo parâmetro sslpassword permite descriptografar a chave de maneira não interativa.
  • Dois novos parâmetros, sslminprotocolversion e sslmaxprotocolversion, permitem especificar uma restrição na versão do protocolo SSL / TCL com a qual a conexão é permitida.

reindexdb


O novo parâmetro --jobs do utilitário reindexdb define o número de conexões com o banco de dados nas quais os índices serão reconstruídos ao mesmo tempo.

pg_rewind


As limitações do utilitário estão sendo gradualmente removidas e as possibilidades estão aumentando.
Primeiro, o pg_rewind agora pode registrar informações para recuperação (como o pg_basebackup pode fazer isso), bem como iniciar a recuperação e o desligamento subsequente de uma instância se não tiver sido interrompida por um ponto de verificação (isso tinha que ser feito manualmente antes).

Em segundo lugar, pg_rewind aprendeu a trabalhar com o arquivo WAL .
Depois que o utilitário encontrar o ponto de divergência do WAL entre os dois servidores, ele deverá criar uma lista de todas as páginas que precisam ser copiadas no cluster de destino para eliminar as diferenças. Para isso, o utilitário requer todos os arquivos WAL, começando no ponto encontrado. Se os arquivos WAL necessários não estiverem disponíveis no cluster de destino, o utilitário não poderá executar seu trabalho antes.

Com esse patch de Alexey Kondratov (Postgres Professional), o pg_rewind poderá ler os segmentos WAL ausentes do arquivo morto dos arquivos de log usando o parâmetro restore_command se uma nova opção -c ou --restore-target-wal for especificada.

pg_waldump


O pg_waldump descriptografará o registro de transação preparado.

amcheck


A extensão amcheck aprendeu a reconhecer melhor os danos nos índices das árvores B.
A propósito, agora as mensagens no log do servidor sobre páginas danificadas serão diferentes para índices e tabelas .

pageinspect


A heap_tuple_infomask_flagsfunção de extensão pageinspect descriptografa os valores dos campos infomask e infomask2retornados pela função heap_page_items. Útil na investigação de situações de corrupção de dados.

postgres_fdw


O superusuário no nível de mapeamento de nome de usuário pode permitir que usuários comuns usem uma conexão sem uma senha:

ALTER USER MAPPING FOR  SERVER 
    OPTIONS (ADD password_required 'false');

Isso é feito, entre outras coisas, para que sslkey e sslcert possam ser usados ​​como parâmetros de conexão .

adminpack


A extensão adminpack possui um novo recurso - pg_file_sync. Usando-o, você pode executar o fsync para arquivos gravados pelo servidor no disco, por exemplo, via pg_file_writeou COPY TO.

Monitoramento


pg_stat_slru


A memória compartilhada do servidor contém não apenas um cache de buffer grande, mas também vários outros caches mais simples (por exemplo, para o status da transação). Eles usam um algoritmo simples para agrupar as páginas menos usadas (simples, menos usada recentemente ou SLRU). Até agora, esses caches “apenas funcionavam”, mas havia a necessidade de monitorá-los, principalmente para os desenvolvedores do kernel do PostgreSQL descobrirem se algo precisa ser alterado neles. Para isso e para isso, uma nova exibição de pg_stat_slru apareceu .

pg_stat_activity


Na visualização, a pg_stat_activity nova coluna é leader_id. Para processos que participam de solicitações paralelas, ele é preenchido com o número do processo principal. E processo principal leader_idé um número de processo pid.
A consulta a seguir mostra quais consultas e quais processos estão sendo executados atualmente em paralelo:

SELECT query, leader_pid, 
    array_agg(pid) filter(WHERE leader_pid != pid) AS members
  FROM pg_stat_activity
 WHERE leader_pid IS NOT NULL
 GROUP BY query, leader_pid;

Há alterações na lista de eventos em espera. Adicionado dois novos eventos : BackupWaitWalArchivee RecoveryPause. E os outros dois receberam nomes mais precisos: RecoveryWalStream -> RecoveryRetrieveRetryInterval, RecoveryWalAll -> RecoveryWalStream.

E mais dois novos eventos de espera que ocorrem na réplica : RecoveryConflictSnapshot(conflito com VACUUM, que excluiu a versão necessária das linhas) e RecoveryConflictTablespace(conflito relacionado à remoção do espaço de tabela).

pg_stat_statements


Até agora, a extensão pg_stat_statementstratava solicitações com FOR UPDATEe sem uma frase como a mesma solicitação. Agora, os pedidos com FOR UPDATE são gravados separadamente .

A quantidade de informações coletadas aumentou. A partir de agora, não apenas as informações sobre recursos para a execução de comandos são registradas, mas também estatísticas sobre lançamentos contábeis manuais gerados . Novas colunas de apresentação: wal_bytes- volume de registros gerados, wal_records- número de registros gerados, wal_num_fpw- número de imagens de página inteira (gravação de página inteira).

Isso foi possível graças à infraestrutura preparada para rastrear o uso do WAL. Portanto, agora EXPLAINcom uma nova opção, ele WALmostrará o volume de registros gerados:

CREATE TABLE t (id int);
EXPLAIN (ANALYZE, WAL, COSTS OFF, TIMING OFF, SUMMARY OFF)
    INSERT INTO t VALUES(1);

              QUERY PLAN              
--------------------------------------
 Insert on t (actual rows=0 loops=1)
   WAL:  records=1  bytes=59
   ->  Result (actual rows=1 loops=1)

Extensão auto_explain, VACUUMs VERBOSE, e autovacuumtambém utilizar os volumes de infra-estrutura e de saída será criado de WAL.

Voltando para pg_stat_statements. Se o novo parâmetro pg_stat_statements.track_planning estiver ativado , serão registradas estatísticas adicionais relacionadas a cada operador para o planejador: o número de compilações do plano; tempo total de planejamento; tempo mínimo e máximo de um planejamento, bem como média e desvio padrão.

A contabilização dos recursos alocados ao planejador é refletida em outro patch que não está relacionado pg_stat_statements. EXPLAINcom a opção BUFFERSrelatará o número de buffers usados ​​no estágio de planejamento :

EXPLAIN (ANALYZE, BUFFERS, COSTS OFF, TIMING OFF) 
    SELECT * FROM pg_class;

                   QUERY PLAN                   
------------------------------------------------
 Seq Scan on pg_class (actual rows=386 loops=1)
   Buffers: shared hit=9 read=4
 Planning Time: 0.782 ms
   Buffers: shared hit=103 read=11
 Execution Time: 0.219 ms

Revista


  • log_statement_sample_rate SQL, , log_min_duration_sample( ).
    , log_min_duration_statement , .. log_min_duration_statement , log_min_duration_sample, , log_statement_sample_rate.
    , log_transaction_sample_rate , , .
  • , ( log_min_error_statement), . log_parameter_max_length_on_error. 0, .
    log_parameter_max_length_on_error SQL, , .
    ( log_statements log_duration) , : log_parameter_max_length, , .
  • Agora você pode gravar o tipo de processo ( pg_stat_activity.backend_type) no log do servidor . Para isso log_line_prefix, um símbolo especial é fornecido no parâmetro %b. E se o log for gravado no formato csv ( log_destination=csvlog), a coluna backend_typeestará incluída lá.


Progresso


Novas visualizações pg_stat_progress_analyzetambém pg_stat_progress_basebackuppermitem acompanhar o andamento da coleta de estatísticas pela equipe ANALYZEe criar uma cópia de backup do utilitário, pg_basebackuprespectivamente.

Otimização


Cálculo de funções imutáveis ​​na cláusula FROM no estágio de planejamento
O patch de Aleksandr Kuzmenkov e Aleksandr Parfyonov (ambos do Postgres Professional) ajuda nos casos em que aFROMchamada contém uma chamada de função que é realmente uma constante. Nesse caso, em vez de fazer a conexão, o valor constante é substituído nos locais necessários da solicitação.

Veja como isso acontece com um exemplo de consulta relacionada à pesquisa de texto completo:

EXPLAIN (COSTS OFF)
SELECT subject, ts_rank_cd(tsv, q) AS rank
FROM mail_messages, to_tsquery('english', 'tuple') q
WHERE tsv @@ q
ORDER BY rank DESC;

                              QUERY PLAN                              
------------------------------------------------------------------
 Sort
   Sort Key: (ts_rank_cd(mail_messages.tsv, '''tuple'''::tsquery)) DESC
   ->  Bitmap Heap Scan on mail_messages
         Recheck Cond: (tsv @@ '''tuple'''::tsquery)
         ->  Bitmap Index Scan on mail_messages_tsv_idx
               Index Cond: (tsv @@ '''tuple'''::tsquery)

Não há conexão, e o valor 'tuple' :: tsquery é substituído na consulta já no estágio de planejamento. A versão 12 tinha uma imagem completamente diferente:

EXPLAIN (COSTS OFF)
SELECT subject, ts_rank_cd(tsv, q) AS rank                            
FROM mail_messages, to_tsquery('english', 'tuple') q
WHERE tsv @@ q                            
ORDER BY rank DESC;

                          QUERY PLAN                         
-----------------------------------------------------
 Sort
   Sort Key: (ts_rank_cd(mail_messages.tsv, q.q)) DESC
   ->  Nested Loop
         ->  Function Scan on q
         ->  Bitmap Heap Scan on mail_messages
               Recheck Cond: (tsv @@ q.q)
               ->  Bitmap Index Scan on mail_messages_tsv_idx
                     Index Cond: (tsv @@ q.q)


Classificação incremental

Quando a classificação por muitas chaves é necessária (k1, k2, k3 ...), o planejador agora pode tirar proveito do conhecimento de que os dados já estão classificados por várias das primeiras chaves (por exemplo, k1 e k2). Nesse caso, não é possível reorganizar todos os dados novamente, mas dividi-los em grupos consecutivos com os mesmos valores k1 e k2 e "classificar" pela chave k3.

Assim, toda a classificação se divide em vários tipos consecutivos de tamanho menor. Isso reduz a quantidade de memória necessária e também permite que você forneça os primeiros dados antes que toda a classificação seja concluída.

Por exemplo, na desmobase da tabela de tickets, existe um índice na coluna ticket_id. Os dados recebidos do índice serão classificados por ticket_id, portanto, a seguinte consulta usará a classificação incremental:

EXPLAIN (analyze, costs off, timing off)
SELECT * FROM tickets ORDER BY ticket_no, passenger_id;

                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Incremental Sort (actual rows=2949857 loops=1)
   Sort Key: ticket_no, passenger_id
   Presorted Key: ticket_no
   Full-sort Groups: 92184 Sort Method: quicksort Memory: avg=31kB peak=31kB
   ->  Index Scan using tickets_pkey on tickets (actual rows=2949857 loops=1)
 Planning Time: 2.137 ms
 Execution Time: 2230.019 ms

A funcionalidade de classificação incremental pode ser desativada com o parâmetro enable_incrementalsort. Nesse caso, a classificação levará consideravelmente mais tempo:

SET enable_incrementalsort = off;
EXPLAIN (analyze, costs off, timing off)
SELECT * FROM tickets ORDER BY ticket_no, passenger_id;

                              QUERY PLAN                               
-----------------------------------------------------------------------
 Gather Merge (actual rows=2949857 loops=1)
   Workers Planned: 2
   Workers Launched: 2
   ->  Sort (actual rows=983286 loops=3)
         Sort Key: ticket_no, passenger_id
         Sort Method: external merge  Disk: 107024kB
         Worker 0:  Sort Method: external merge  Disk: 116744kB
         Worker 1:  Sort Method: external merge  Disk: 107200kB
         ->  Parallel Seq Scan on tickets (actual rows=983286 loops=3)
 Planning Time: 3.994 ms
 Execution Time: 12291.844 ms

A idéia de classificação incremental foi proposta em 2013 por Alexander Korotkov (Postgres Professional), e agora, sete anos depois, o patch foi levado por James Coleman a um estado aceito pela comunidade.

Acelerar TRUNCATE
Quando TRUNCATEocorre shared_buffersa varredura para remover os buffers da tabela da memória compartilhada. Anteriormente, a verificação era realizada três vezes, para cada camada da tabela: PRINCIPAL (camada de dados principal), FSM (mapa de espaço livre), VM (mapa de visibilidade). Agora a lógica mudou, em vez de operação tripla, os buffers são verificados apenas uma vez. Com valores grandes, shared_buffersisso proporciona um ganho tangível.

Descompressão parcial TOAST
Quando não há necessidade de ler completamente o TOAST, limitando-o a uma fatia no início ou perto do início, não faz sentido abri-lo completamente. O TOAST compactado é lido nas iterações: leia uma peça, se não houver dados necessários, expanda-a e continue lendo. Sugerido por um aluno do Google Summer of Code, Binguo Bao, que dá um exemplo:

CREATE TABLE slicingtest (
     id serial PRIMARY KEY,
     a text
);
INSERT INTO slicingtest (a) SELECT
    repeat('1234567890-=abcdefghijklmnopqrstuvwxyz', 1000000) AS a FROM
    generate_series(1,100);
\timing
SELECT sum(length(substr(a, 0, 20))) FROM slicingtest;

Time: 28.123 ms

Com o patch, uma ordem de magnitude mais rápida:

Time: 2.306 ms

VÁCUO paralelo
Em seu artigo sobre este assunto, Yegor Rogov explica em detalhes esse importante passo na paralelização. Em resumo: “Patch Masahiko Sawada, que permite executar a limpeza em paralelo. A tabela em si ainda é limpa por um processo (principal), mas, para limpar índices, agora pode iniciar fluxos de trabalho em segundo plano, um para cada índice. No modo manual, isso permite acelerar a limpeza de tabelas grandes com vários índices; a limpeza automática ainda não usa esse recurso. ”

Limpeza automática quando colado em uma tabela
Para este patch (também conhecido como vácuo automático do Berserk), precisamos agradecer a Dorofei Proleskovsky, que propôs uma solução para o seguinte problema: a limpeza automática não chega à tabela de acréscimo, porque eles não têm versões "mortas" das linhas. Por esse motivo, o mapa de visibilidade não é atualizado, tornando apenas as verificações apenas de índice ineficazes e, quando a limpeza ocorre para impedir o estouro do contador de transações, é necessário muito trabalho ao mesmo tempo. Agora esta situação foi corrigida: a limpeza automática também funcionará na adição de linhas. Dois novos parâmetros do servidor ( autovacuum_vacuum_insert_thresholde autovacuum_vacuum_insert_scale_factor) apareceram, semelhantes aos das modificações ( autovacuum_vacuum_thresholde autovacuum_vacuum_scale_factor).

Gerenciamento de memória agregada de hash
A agregação de hash pode exigir mais RAM do que o planejador pensou e do que é indicado em work_mem. Anteriormente, esse erro do agendador fazia com que o tamanho fosse work_memignorado e a memória fosse alocada o necessário para a operação ou chegada do OOM Killer. Agora, o algoritmo pode não ir além work_meme, se necessário, usar arquivos temporários no disco. Para controlar o comportamento do planejador, os parâmetros apareceram: enable_groupingsets_hash_diske enable_hashagg_disk.

Otimizando UPDATE para tabelas com colunas geradas
Na versão 12, as colunas geradas foram recalculadas durante qualquer atualização de linha, mesmo que essa alteração não as afetasse de forma alguma. Agora eles serão recalculados somente quando for realmente necessário (se suas colunas base foram alteradas).

Essa otimização, por exemplo, pode acelerar significativamente a atualização de tabelas com uma coluna de tipo gerada tsvector, pois a função é to_tsvector()bastante cara.

Acesso do acionador à lista de colunas alteradas
Um pequeno patch que adiciona um TriggerDatabitmap de colunas alteradas à estrutura . Essas informações podem ser usadas por funções gerais do acionador, como tsvector_update_trigger()ou lo_manage(), para não executar trabalhos desnecessários.

Uso de várias estatísticas avançadas ao avaliar
Na PG12, o planejador não conseguiu usar várias estatísticas avançadas para a mesma tabela ao mesmo tempo. Por exemplo, imagine uma situação em que duas estatísticas avançadas sejam construídas para conjuntos diferentes de colunas e as colunas de um conjunto e de outro participem da consulta. Agora o planejador tem acesso a todas as informações disponíveis.

Infraestrutura para paralelização e COPY (consulte também este patch ) .
A simultaneidade do PostgreSQL ainda funciona para consultas somente leitura. Existem dificuldades com os escritores, e um deles está bloqueando processos que executam simultaneamente uma tarefa (incluída em um grupo paralelo comum). Acredita-se que os bloqueios de tais processos não entrem em conflito - por exemplo, vários processos podem conter um bloqueio exclusivo na mesma tabela. Isso requer cuidados especiais dos desenvolvedores do kernel, mas, caso contrário, eles teriam constantemente impasses.
Mas há duas exceções:

  • bloqueio de extensão de relação, que é capturado quando novas páginas são adicionadas ao final do arquivo de dados e
  • bloqueio de página, usado ao mover itens de índice GIN da lista de espera para a árvore principal.

(Você pode ler mais neste artigo. )
Esses bloqueios devem entrar em conflito mesmo entre processos do mesmo grupo paralelo - o que implementa esse patch. Mas esses bloqueios nunca podem levar a conflitos, portanto, eles são excluídos da verificação.

Para o usuário, em geral, nada muda, mas esse patch é importante porque, em primeiro lugar, abre caminho para INSERT e COPY paralelos e, em segundo lugar, elimina um dos gargalos do PostgreSQL em condições de alta carga (o que pode ser ouvido no relatório HL ++ ).

Segurança


Os
primos SKH PRH substituíram os primos EDH substituídos (Diffie-Hellman Ephemeral Keys) usando o agora extinto protocolo SKIP.

initdb: as configurações padrão para autenticação
foram alteradas As configurações de acesso padrão para conexões locais e de rede foram alteradas quando o initdb é iniciado. Agora,pg_hba.confpara conexões locais, em vez do método de autenticação,trustserápeer(ou md5 se o par não for suportado) emd5para conexões de rede. Inicialmente, foram discutidas medidas mais liberais: aviso na documentação. Em seguida, mais difícil:scram-sha-256. Como resultado, decidimos nos limitar apeeremd5.

Usando o explic_bzero
Patch importante. As funções do SO bzero () e explícita_bzero () escrevem bytes que contêm nas áreas de memória indicadas '\0'(consulte, por exemplo , Linux). Esses patches são apenas o começo: existem muitas seções de memória nas quais senhas e outras informações confidenciais podem permanecer. Decidimos começar a partir de lugares como libpq, nos quais todo o arquivo com senhas pode permanecer na memória após a leitura de .pgpass e a limpeza após o fechamento da conexão. No be-secure-common.c, agora há uma substituição da frase secreta inserida no SSL, que aparece na linha (caminho) do erro.

Adicionado o parâmetro "password_protocol" no libpq
Esse patch permite que a libpq controle qual protocolo de transferência de senha é usado durante a conexão. Após receber este parâmetro, a libpq recusará a autenticação se o protocolo for mais fraco que o especificado. Por padrão, este parâmetro plaintext, ou seja, todos os protocolos são adequados.

Acesso obrigatório para TRUNCATE
Este patch permite que extensões incorporem o controle de acesso obrigatório (MAC) a uma operação TRUNCATE. Os direitos a ele agora serão verificados pela extensão sepgsql . A política de referência do SELinux e as distribuições Linux baseadas no Redhat não suportam a verificação do SELinux no db_table {truncate}. Nesse caso, o sepgsql será usado com 'deny_unknown' igual a 1 e TRUNCATE falhará.

Disponibilidade de GUC ssl_passphrase_command
Um patch simples, mas útil. Agora, o valor do parâmetro ssl_passphrase_command será visto apenas pelo superusuário. O parâmetro especifica um comando externo que é chamado quando uma senha é necessária para descriptografar um arquivo SSL, por exemplo, uma chave privada.

Localização


Regras de agrupamento da versão libc
Para regras de agrupamento de ICU, os números de versão são armazenados no banco de dados. Cada vez que a regra é usada (classificação, comparação de caracteres), o número da versão salva é verificado com a versão atual na biblioteca ICU no SO e, em caso de discrepâncias, é emitido um aviso. Isso permite que você descubra que determinados índices criados de acordo com as regras de classificação modificadas podem estar incorretos e devem ser reconstruídos. Ao recriar os índices com o comandoALTER COLLATION ... REFRESH VERSION, a versão da regra de classificação no banco de dados é atualizada e os avisos não são mais emitidos.

Mas isso foi apenas para a UTI. Agora, o número da versão também é armazenado para regras de classificação da libc:

SELECT collname, collversion FROM pg_collation WHERE collname = 'ru_RU';

 collname | collversion
----------+-------------
 ru_RU    | 2.27

O que possibilita emitir avisos quando uma biblioteca é alterada no sistema operacional. Muito relevante à luz da transição para a glibc 2.28, onde muitas regras de classificação foram alteradas e os índices correspondentes devem ser reconstruídos.

Mas até que eles mudaram para 2,28, tudo está calmo:
ALTER COLLATION "ru_RU" REFRESH VERSION;

NOTICE:  version has not changed
ALTER COLLATION

Pesquisa de texto completo


Pesquisa por texto completo do idioma grego
Sem comentários.

dict_int aprendeu a lidar com valores absolutos.O
dicionário de modelos dict_int (também conhecido como extensão) adicionou a capacidade de remover o sinal de um número.


CREATE EXTENSION dict_int;
SELECT ts_lexize('intdict', '-123');

ts_lexize
-----------
 {-123}
(1 row)

ALTER TEXT SEARCH DICTIONARY intdict (ABSVAL = true);
SELECT ts_lexize('intdict', '-123');

ts_lexize
-----------
 {123}
(1 row)

Ou seja, desta vez o valor absoluto foi reconhecido.

Particionamento


ANTES dos
gatilhos de linhaBEFOREem uma tabela particionadaNa versão 12, você não pode criar gatilhos de linhaem uma tabela particionada. Em seções separadas - por favor, mas não em toda a mesa de uma só vez. Agora, umBEFORE FOR EACH ROWgatilho criado em uma tabela particionada será automaticamente herdado e funcionará para todas as seções. Mas com a condição de que, se for um gatilho ativadoUPDATE, a chave de partição nele só poderá ser alterada na seção atual.

Suporte para tabelas particionadas na replicação lógica
Anteriormente, a inclusão de uma tabela particionada em uma publicação causava um erro:

CREATE PUBLICATION pub FOR TABLE p;

ERROR:  "p" is a partitioned table
DETAIL:  Adding partitioned tables to publications is not supported.
HINT:  You can add the table partitions individually.

Agora funciona.

Algoritmo JOIN secional aprimorado
A partir da 11ª versão, o planejador pode ingressar em tabelas particionadas seção por seção, mas apenas se os limites das seções corresponderem exatamente. Agora, o algoritmo foi aprimorado: funcionará se a seção de uma tabela estiver completamente incluída na seção de outra, mesmo que seus tamanhos não correspondam (por exemplo, se uma tabela for particionada por dia e a outra por mês). O novo algoritmo trabalha para particionar por intervalos e por listas.

JUNÇÃO EXTERNA COMPLETA SECIONAL A junção seccionada
agora funciona para junções externas completas registradas com uma frase USING.

tableam


Nesta área atraente e promissora, mas difícil, não há avanços radicais em relação ao PostgreSQL 12. Não há armazenamentos de plug-in prontos, como zheapoutros que não sejam heap), mas o trabalho continua na API.

Um nível mais alto de abstração na determinação do tamanho da tabela
Robert Haas reescreveu o código, alterando sua arquitetura em favor de camadas abstratas, para não duplicar o código no futuro. Esta peça refere-se ao estimate_rel_sizetamanho das camadas (garfos) da tabela.

Você pode usar os métodos de acesso à tabela com relcache.
Este patch traz os recursos de gerenciamento de memória dos métodos de acesso à tabela aos recursos dos métodos de índice.

tableam e TOAST
TOAST são projetados para armazenamentoheapPortanto, ao criar novos métodos de acesso à tabela, você pode seguir duas maneiras: ajudar os desenvolvedores de novos métodos a integrar inserir, atualizar e excluir registros TOAST neles ou delegar trabalho com o TOAST para codificar usando o heap tradicional de armazenamento PostgreSQL. Uma série de 5 patches usa slots de tupla para implementar operações de inserção / atualização / exclusão e pode ajudar aqueles que seguem os dois lados.

fsync


Manipulando erros de fsync em pg_receivewal e pg_recvlogical
A luta contra o fsync () continua. O PostgreSQL acredita que uma chamada fsync () bem-sucedida significa que todos os dados no arquivo foram liberados para o disco, mas isso nem sempre acontece (depende do SO) e pode levar à perda de dados. A PG13 decidiu que era necessário lidar com os serviços públicospg_receivewalepg_recvlogical. Atualmente, o comportamento padrão é este: esses utilitários gravam erros fsync nos logs, restauram a conexão e continuam como se nada tivesse acontecido. Como resultado, o WAL contém informações sobre os arquivos que foram copiados com êxito e que, na verdade, não foram corretamente liberados para o disco. Portanto, é melhor interromper o utilitário. O destino de pg_dump, pg_basebackup, pg_rewind e pg_checksums também foi discutido, mas até agora eles se limitaram a esses dois.

Proteção contra a configuração de sinalizadores incorretos para fsync ()
Este patch verifica se os sinalizadores estão definidos corretamente ao receber o descritor de arquivo para fsync () - os diretórios estão abertos apenas para leitura e os arquivos para gravação ou ambos.

Backup e replicação


Pausa durante a recuperação antes de atingir o ponto de recuperação
Se durante a recuperação os WALs terminaram, masrecovery_target_timenão atingiram oespecificado, o servidor conclui a recuperação e alterna para o modo de operação normal. Agora não será assim. O processo de recuperação será pausado, conforme relatado no log, e o administrador terá a oportunidade de inserir os segmentos WAL ausentes e continuar a recuperação.

O parâmetro ignore_invalid_pages
Quando o processo de recuperação em uma réplica encontra um link para uma página inválida no registro WAL,panic-aacontece. A inclusão do parâmetro ajudará a superá-lo.ignore_invalid_pages. A recuperação continuará com uma possível perda de integridade, dados e outras consequências mais graves. O parâmetro é destinado aos desenvolvedores de servidores e deve ser usado nesses casos quando você ainda precisa tentar concluir a recuperação e iniciar a réplica.

Alterar primary_conninfo sem reiniciar
o patch de Sergey Kornilov, que permite que você altere as configurações primary_conninfo, primary_slot_namee wal_receiver_create_temp_slotsem reiniciar o servidor. Na verdade, por causa disso, eles abandonaram o arquivo recovery.confno 12º lançamento. Os manifestos de

backup
Pg_basebackup agora criam um "manifesto" - um arquivo JSON contendo informações sobre o backup feito (nomes e tamanhos de arquivos, arquivos WAL necessários, além de somas de verificação para tudo e mais).
O novo utilitário pg_validatebackup verifica a conformidade dos backups com o manifesto e também verifica a disponibilidade e a correção dos arquivos WAL necessários para a recuperação usando o utilitário pg_waldump (isso se aplica apenas aos arquivos WAL dentro do próprio backup e não no arquivo morto).
Isso permitirá detectar situações em que os arquivos de backup foram danificados ou desapareceram ou quando a recuperação se tornou impossível devido à falta dos arquivos de log necessários.

Limitando o slot de replicação de dados não lidos O slot de replicação
é um mecanismo conveniente, mas perigoso: se o cliente não ler os dados do slot a tempo, os registros WAL não lidos poderão ocupar todo o espaço no servidor. Agora usando o parâmetromax_slot_wal_keep_sizeVocê pode definir um limite para a quantidade máxima de espaço em disco que pode ser ocupada por dados não lidos. Se, no próximo ponto de verificação, o tamanho for excedido, o slot será desativado e o local será liberado.

janelas


Suporte para soquetes Unix nos soquetes do
domínio Unix do Windows são suportados no Windows 10, embora estejam desativados por padrão.

Documentação


Existem dois novos aplicativos na documentação.
Após uma longa discussão , o Apêndice M. Glossário apareceu . Atualmente, existem 101 termos no glossário.

A capacidade de destacar a cor das mensagens de diagnóstico dos utilitários do console usando uma variável PG_COLORera anterior. Isso agora está documentado no Apêndice N. Suporte a cores . A intenção original de Peter Eisentrout nesse patch era ativar a saída colorida por padrão. E para quem não queria isso, foi proposto definir explicitamente a variávelNO_COLOR. Mas havia mais opositores à diferenciação de cores das mensagens entre os que discutiam o patch. Portanto, eles decidiram apenas documentar as oportunidades disponíveis. E temos uma nova seção do primeiro nível na documentação.



PG13, , PG14 . , . .

All Articles