Berapa banyak yang baru di dalam Devil's Dozen?

Kita hanya berbicara tentang PostgreSQL 13. Pada tanggal 8 April, terjadi "pembekuan" - Pembekuan fitur PostgreSQL , sekarang hanya fitur-fitur yang diterima sebelum tanggal ini yang akan dimasukkan dalam versi ini.

Sulit untuk menyebutkan versi revolusioner dari ini. Tidak ada perubahan kardinal dan konseptual di dalamnya. Selain itu, tambalan penting seperti Tabel dan Fungsi untuk standar JSON / SQL, yang ingin saya lihat di PG12 di sebelah tambalan JSONPath, tidak punya waktu untuk memasukkannya; penyimpanan tertanam yang sudah jadi tidak muncul - hanya antarmuka yang diselesaikan. Namun daftar perbaikannya masih mengesankan. Kami telah menyiapkan ringkasan yang cukup lengkap dari tambalan yang termasuk dalam Devil's Luszen.




Perubahan Perintah SQL


BUAT DATABASE ...

Utilitas LOCALEinitdb ,createdbdan timCREATE COLLATIONmemiliki pengaturanLOCALEyang memungkinkan Anda menentukan nilai untuk hakLC_CTYPEdanLC_COLLATE. Sekarang kesempatan yang sama muncul di timCREATE DATABASE:

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

ALTER VIEW ... RENAME COLUMN

Nama kolom dalam tampilan sekarang dapat diubah dengan perintahALTER VIEW. Sebelumnya, ini diperlukan untuk menciptakan kembali tampilan.

Misalkan Anda lupa memberi nama pada kolom:

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

Itu bisa diperbaiki:

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

Kolom yang dihasilkan dari tabel sekarang dapat dibuat normal, yaitu, hapus ekspresi untuk mengevaluasinya:

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)

Selanjutnya, mereka memutuskan bahwa income_tax harus ditetapkan secara eksplisit. Hapus ekspresi:

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)

Tentu saja, data yang ada dari kolom belum hilang:

SELECT * FROM payments;

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


JATUHKAN DATABASE ... FORCE
Jika Anda ingin menghapus database tanpa menunggu semua pengguna untuk memutuskan sambungan, Anda dapat menggunakan opsiFORCEperintahbaruDROP DATABASE.

CREATE DATABASE db;

Terhubung ke database baru:

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

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

Dan sekarang kita akan menghapus, secara paksa menyela, juga pg_terminate_backendmembuka koneksi:

DROP DATABASE db WITH (FORCE);

ALTER TYPE ... SET STORAGE
Perintah iniALTER TYPEmemungkinkan tipe data dasar untuk mengubah berbagai properti, khususnya, strategi penyimpanan. Sebelumnya, Anda hanya bisa mengaturnya di timCREATE TYPE.

Untuk demonstrasi, kami tidak akan membuat tipe basis baru, tetapi menggunakan yang ada -tsquery. Tapi pertama-tama, buat database terpisah dan hubungkan ke sana:

CREATE DATABASE db;
\c db

Strategi penyimpanan digunakan untuk tipe data tsquery plain, sehingga kolom tabel jenis ini mendapatkan strategi yang sama:

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

Jika Anda perlu menggunakan strategi yang berbeda untuk tabel baru, Anda bisa mengubah tipe dasar:

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

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

Jenis penyimpanan di tabel baru juga akan berubah:

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

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

Harus diingat bahwa mengubah strategi yang melibatkan penggunaan TOAST plaintidak dapat diubah kembali ke :

ALTER TYPE tsquery SET (storage=plain);

ERROR:  cannot change type's storage to PLAIN

Oleh karena itu, percobaan dilakukan dalam database yang terpisah, yang tidak sayang untuk dihapus.

ALTER STATISTICS ... SET STATISTICS

Perintah ini CREATE STATISTICSmemungkinkan Anda untuk mengumpulkan daftar nilai paling umum untuk kombinasi kolom tabel yang dipilih. Jumlah nilai paling umum yang dikumpulkan ditentukan oleh parameter default_statistics_target. Nilai untuk statistik spesifik sekarang dapat diubah dengan perintah:

ALTER STATISTICS  SET STATISTICS _;

FETCH FIRST with WITH TIES option
Seperti yang Anda ketahui,SELECTalih-alih menentukanperintah,LIMITAnda dapat menggunakan sintaks yang didefinisikan dalam standar 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)

Sekarang FETCHmendukung frasa WITH TIES, yang menambahkan ke semua garis "terkait" pada output (garis sama dengan yang sudah dipilih, jika hanya kondisi penyortiran diperhitungkan):

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)

Fungsi dan Tipe Data Internal


get_random_uuid Fungsi
baruget_random_uuidmengembalikan nilai UUID versi 4 (nilai acak):

SELECT gen_random_uuid();

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

Fungsi ini berguna untuk menghasilkan nilai UUID unik dalam sistem terdistribusi.
Sebelumnya, Anda harus menggunakan pustaka uuid-ossp atau pgcrypto.

min_scale dan trim_scale untuk nilai-nilai tipe numerik

Fungsi min_scalemenentukan jumlah digit signifikan di bagian fraksional dari angka, dan fungsi trim_scalemembuang nol yang tidak signifikan :

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 dan lcm

Pengisian di bagian fungsi matematika. Sekarang Anda dapat dengan cepat menemukan pembagi umum terbesar (gcm) dan kelipatan umum terkecil (lcm):

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

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

Fungsi agregat min dan maks untuk tipe pg_lsn Fungsi agregat telah ditambahkan untuk

tipe datadanyang memungkinkan Anda melakukan kueri formulir:pg_lsnminmax

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

Memeriksa pengubah tipe dari nilai balik suatu fungsi

Pada versi sebelumnya, pengubah tipe tidak diperiksa untuk nilai balik fungsi.

Misalkan ada jenis penyimpanan unit moneter dan fungsi yang mengembalikan jumlah pajak penghasilan:

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;

Memanggil fungsi, kami berharap mendapatkan dua tempat desimal, namun, kami mendapatkan empat. Bahkan casting eksplisit setelah pemanggilan fungsi tidak membantu (kolom ketiga):

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

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

Di versi 13, hasilnya benar:

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

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

Nama-nama yang dilokalkan dalam

fungsi to_date () dan to_timestamp ()to_date jugato_timestampbelajar untuk memahami nama-nama yang dilokalkan dari bulan dan hari dalam seminggu. Sebelumnya, hanya nama bahasa Inggris yang dapat digunakan:

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

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

normalize dan IS NORMALIZED

Untuk memenuhi standar SQL, fungsi normalize () telah ditambahkan untuk menormalkan string Unicode, dan predikat IS NORMALIZED untuk memeriksa apakah string tersebut dinormalisasi.

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

Baca lebih lanjut tentang formulir normalisasi UNICODE.

Tipe xid8 dan fungsi xid8_current () untuk nomor transaksi 64-bit

Menambahkan tipe data xid8 baru untuk nomor transaksi 64-bit. Tapi tidak, ini tidak berarti bahwa PostgreSQL beralih ke transaksi 64-bit: semuanya berjalan persis seperti sebelumnya. Tapi beberapa fungsi kembali jenis baru, misalnya, kini direkomendasikan untuk digunakan sebagai pengganti fungsi tua pg_current_xact_id txid_current, yang kembali int8, dan sebagainya. N.

New tipe data polimorfik keluarga anycompatible

menambahkan jenis anycompatible, anycompatiblearray, anycompatiblenonarray, anycompatiblerange. Tidak seperti tipe keluarga anyelement, tipe baru memungkinkan Anda untuk menggunakan tidak persis sama, tetapi tipe yang benar-benar kompatibel.

Pada contoh berikut, fungsinyamaximumsebagai argumen yang didefinisikan sebagai anycompatibledisahkan integerdan numeric. Nilai pengembalian dikonversi ke nilai umum untuk dua jenis ini:

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

Selain itu, tipe anycompatible- dan any- adalah dua set tipe independen:

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)

Bahasa Prosedural


Transformasi untuk tipe bool di PL / Perl
Baru-baru ini, TRANSFORMASI dari Ivan Panchenko (Postgres Professional) - bool_plperl dilakukan . Postgres meneruskan nilai boolean ketataudalam PL / Perl sepertif, tetapi untuk Perl itufbukan boolean salah , tetapi hanya huruf f, mis. dalam konteks logis, kebenaran . Masalah ini dapat diselesaikan dengan cara yang berbeda (lihat korespondensi ), tetapi membuat TRANSFORM untuk bool, menurut Tom Lane, adalah yang paling praktis.

Eksekusi cepat ekspresi sederhana di PL / pgSQL

Ekspresi sederhana (setidaknya tidak mengandung panggilan meja dan tidak memerlukan kunci) akan lebih cepat. Sebelumnya, dalam kasus ini, waktu dihabiskan secara tidak produktif untuk menghubungi penjadwal pada setiap siklus.

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;

Panggil slow_pi () di PG12:

SELECT slow_pi();

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

Sekarang di PG13:
SELECT slow_pi();

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

Ekstensi tepercaya alih-alih pg_pltemplate

Direktori sistem telah berkurang sebanyak satu tabel. Dihapuspg_pltemplate. Ini menyimpan properti bahasa prosedural yang diperlukan selama eksekusiCREATE LANGUAGE. Sekarang kami memutuskan untuk mendaftarkan properti dari dalam skrip ekstensi bahasa yang sesuaipg_pltemplate, dan menyingkirkan tabel itu sendiri. Tetapi untuk mengimplementasikan rencana, perlu menyediakan kemungkinan bagi pemilik basis data (tanpa hak pengguna super) untuk membuat bahasa tepercaya dari skrip ekstensi. Memang, sekarang untuk membuat, misalnya, plpgsql, pemilik basis data tidak harus superuser.

Diterima sebagai berikut. Parameter logis baru telah muncul di file kontrol untuk ekstensitrusted. Jika kedua parametertrusteddansuperuserdisertakan, maka tidak hanya superuser dapat membuat ekstensi, tetapi juga pengguna dengan hak CREATEke database saat ini (dan karenanya pemiliknya). Saat menjalankan skrip ekstensi seperti itu, hak pengguna super yang menginisialisasi cluster akan digunakan. Objek yang dibuat oleh ekstensi akan menjadi miliknya, meskipun pemilik ekstensi itu sendiri akan menjadi pengguna yang membuat.

Konsekuensi penting dari perubahan ini:

  • Ekstensi tepercaya membuka jalan bagi pengembang pihak ketiga untuk membuat bahasa tepercaya lainnya. Sekarang kita hanya terbatas pada plpgsql, plperl dan pltcl.
  • Hal pg_pltemplateitu sulit tertulis bahwa plpython mengacu pada versi kedua bahasa. Kegagalan untuk pg_pltemplatemelakukannya adalah langkah (perlu, meskipun tidak cukup) untuk transisi ke python 3.

Indeks


Compression of B-tree
Sebuah tambalan yang penting dan sudah lama ditunggu-tunggu (pekerjaan sudah dimulai pada tahun 2015) yang ditulis oleh Anastasia Lubennikova (Postgres Professional) dan Peter Geigan (Peter Geoghegan) akhirnya dikomunikasikan oleh Peter. Nastya berhasil membicarakan hal ini di PGconf India . Postgres telah belajar untuk secara signifikan mengurangi ukuran indeks B-tree melalui deduplikasi, yaitu penghematan pada kunci indeks duplikat. Indeks ini telah dirancang ulang secara serius sehingga kompresi dimungkinkan tanpa kehilangan kompatibilitas dengan versi indeks sebelumnya. Gagasan deduplikasi diambil dari arsitektur indeks yang lebih fleksibel seperti GIN (indeks terbalik - Generalized Inverted Index).

Dalam indeks ini lebih sering daripada di B-tree, ada situasi di mana kunci terkait dengan sejumlah besar catatan. Dalam kasus pengolah kata, misalnya, token yang sama biasanya ditemukan di beberapa dokumen. Dan itu disimpan dalam indeks hanya sekali. Sampai saat ini, indeks B-tree tidak tahu bagaimana melakukan ini.

Indeks B-tree berbeda dari indeks GIN terutama di halaman daun. Bergantung pada jumlah catatan yang terkait dengan nilai kunci yang sama, opsi dimungkinkan: halaman hanya berisi daftar posting - daftar TUT (pengidentifikasi catatan terindeks), jika daftar kecil, dan jika ada banyak TUT, maka alih-alih daftar nilai disimpan "cabang pohon" baru - tautan ke halaman lain seperti daftar posting atau cabang pohon lainnya (mereka disebut posting tree).

Struktur pohon seperti itu mirip dengan B-tree, tetapi berbeda dalam detail penting: misalnya, daftar untuk bergerak melalui halaman-halaman dengan tingkat pohon yang sama di GIN adalah searah, bukan dua arah. Oleh karena itu (termasuk) kompatibilitas yang baik dari indeks deduplicated baru dengan versi lama tidak mudah untuk dicapai. Dan perbaikannya benar-benar membutuhkan waktu lebih dari 3 tahun. Itu juga perlu untuk memperbaiki mekanisme pembersihan (microvacuum) dan nuansa lainnya.

Dalam tes kinerja, semua indeks yang menerapkan deduplikasi telah menyusut sekitar 3 kali. Mengkompresi duplikat juga membantu indeks unik, menghilangkan masalah pembengkakan indeks pada tingkat tinggi perubahan tabel. Perilaku baru dapat dihubungkan dan diputus pada tingkat pengaturan indeks.

Pemindaian penuh dengan indeks GIN tidak dilakukan di tempat yang tidak perlu
Patch ini memungkinkan dalam beberapa kasus untuk menghindari lulus penuh seluruh indeks GIN. Beberapa operasi, meskipun didukung oleh indeks GIN, dilakukan oleh pemindaian penuh indeks. Ambil, misalnya, indeks untuk pencarian kolom teks lengkap tsvector. Jika permintaan pencarian memiliki bentuk "apa pun kecuali kata yang diberikan", maka seluruh indeks harus dibaca secara keseluruhan. Namun, jika ada kondisi lain dalam permintaan yang tidak memerlukan pemindaian penuh indeks, maka indeks akan tetap dipindai sepenuhnya.

Dengan optimasi baru, kondisi yang lebih akurat akan digunakan terlebih dahulu, memungkinkan Anda untuk mendapatkan keuntungan dari indeks, dan kemudian hasilnya akan diperiksa ulang untuk memperhitungkan batasan lain. Bandingkan jumlah halaman yang dibaca di versi 12 (Buffer):

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

dengan jumlah buffer dalam versi baru:

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

Situasi serupa dapat ditemui saat menggunakan trigram, dan ketika memeriksa terjadinya array.

Parameter kelas operator
Di PostgreSQL, banyak metode akses indeks adalah "kerangka kerja" yang mengambil implementasi algoritma pencarian tingkat tinggi, bekerja dengan halaman dan kunci, dan log WAL. Dan mengikat untuk tipe data tertentu dan operator dilakukan menggunakan kelas operator.

Hingga saat ini, kelas operator tidak dapat memiliki parameter. Misalnya, untuk pencarian teks lengkap, indeks GiST dengan kelas operator dapat digunakan tsvector_ops(tentang kelas operator GiST di sini) Kelas operator ini menggunakan pohon tanda tangan, dan panjang tanda tangan diperbaiki (124 byte). Sekarang Anda dapat menentukan panjang secara eksplisit, yang memungkinkan Anda untuk mengontrol keseimbangan antara ukuran indeks dan efisiensi (jumlah tabrakan hash):

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

Perubahan serupa untuk permulaan dibuat untuk kelas lain dari operator GiST yang menggunakan pohon tanda tangan, yang berlaku untuk ekstensi hstore, intarray, ltree, dan pg_trgm.
Tapi ide utama perubahan ini adalah kemampuan untuk meneruskan ekspresi JSONPath ke indeks GIN sehingga tidak seluruh dokumen JSON diindeks, tetapi hanya bagian yang diperlukan saja. Dalam banyak kasus, ini secara radikal akan mengurangi ukuran indeks. Tetapi pekerjaan ini masih harus dilakukan.

Gagasan Oleg Bartunov, implementasi Nikita Glukhov dan Alexander Korotkov (ketiga Postgres Professional).

Operator <-> (kotak, titik)
ditambahkan. Operasi yang hilang ditambahkan untuk digunakan dalam kNN untuk GiST dan SP-GiST . Di PG12 saat bekerja dengan tipe geometris pointdanboxAnda dapat menggunakan operator jarak <->(point, box), dan itu akan mempercepat pencarian dengan indeks GiST dan SP-GiST. Tetapi simetris operator kepadanya <->(box, point)tidak diterapkan, meskipun ia boxsudah memahami jarak ke tipe yang lebih kompleks - poligon dan lingkaran.

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)));

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

:    : box <-> point

Jika sebaliknya, maka semuanya baik-baik saja:

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

Dan dalam 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

Indeks GiST dan SP-GiST akan dipercepat dalam operasi ini.

Perhatikan bahwa dalam PG13, jika Anda bertanya:

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

dan jika kami melakukan hal yang sama di PG12, kami mendapatkan 20 entri: dalam versi ke-13, daftar itu diisi ulang dengan sebanyak 8 operator.

Json


Dukungan untuk metode .datetime () untuk jsonpath

Ini adalah salah satu patch yang gagal dari serangkaian besar patch JSONPath yang PG12 tidak punya waktu untuk menyelesaikannya. Bagian dari standar JSON / SQL. Masalahnya adalah bahwa semua fungsi dalam seri patch JSONPath tidak dapat diubah, tetapi perbandingan tanggal memperhitungkan zona waktu saat ini, yang dapat berubah selama sesi.

Dalam kasus seperti itu, kami mengizinkan fungsi yang sudah ada untuk melakukan kesalahan tentang perbandingan yang tidak bisa diubah. Pada saat yang sama, tambalan ini memiliki fungsi dengan akhiran _tz yang bekerja secara stabil dalam operasi dengan zona waktu.

Fungsi baru - fungsi jsonb_set_lax

Secara umum, lax adalah mode operasi fungsi dengan jsonb yang tidak ketat (tidak seperti ketat). Dalam hal ini, fungsi ini akan operasional dalam situasi di mana salah satu argumen yang diperlukan adalah NULL. Berbeda dengan versi ketat - jsonb_set () - ia memiliki argumen tambahan yang menunjukkan tindakan dalam kasus NULL. Opsi: use_json_null / rais_exception / return_target / delete_key. Opsi disarankan oleh pengguna yang tertarik.

Dioptimalkan beberapa fungsi jsonb.

Dioptimalkan banyak., terutama melalui upaya Nikita Glukhov (Postgres Professional). Tetapi untuk menganalisis setiap poin dalam kasus ini tidak ada gunanya: pertama, kelimpahan mereka akan mengembang artikel yang sudah pendek; dan kedua, perubahan terkait dengan perangkat internal, dan tidak setiap pengguna tertarik. Karena itu, kami hanya akan mencantumkan sebagian besar dari mereka:

  1. Fungsi yang dioptimalkan JsonbExtractScalar ();
  2. Operator yang dioptimalkan # >>, berfungsi jsonb_each_text (), jsonb_array_elements_text ();
  3. Pengenalan tipe JsonbContainer di get_jsonb_path_all () dioptimalkan;
  4. Mengambil token pertama dari iterator JsonbIterator digantikan oleh makro JsonbContainerIsXxx ();
  5. Ekstraksi kunci yang lebih nyaman - findJsonbKeyInObject ();
  6. Penyimpanan dioptimalkan findJsonbValueFromContainer () dan getIthJsonbValueFromContainer ();
  7. get_jsonb_path_all(), ;
    JsonbValueAsText.

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


pgbench


Utilitas untuk menjalankan tes kinerja menerima serangkaian perbaikan. Ada statistik tentang pelaksanaan tugas pada tahap inisialisasi, kesimpulan yang lebih visual , kemampuan untuk melihat kode skrip bawaan , pengujian pada tabel akun yang dipartisi .

Selain itu, kami menambahkan perintah yang \asetmirip dengan \gset, tetapi memungkinkan untuk menetapkan nilai untuk variabel dari beberapa permintaan yang dikirim sekaligus. Baris berikut, dikirim ke server untuk dieksekusi, menetapkan kedua variabel onedan two:
SELECT 1 AS one \; SELECT 2 AS two \aset

pg_dump


pg_dump belajar melepaskan data dari tabel pihak ketiga . Melalui parameter, --include-foreign-dataAnda dapat menentukan daftar server pihak ketiga, data dari tabel yang akan diturunkan.

Gunakan bongkar ini dengan hati-hati. Jauh dari kenyataan bahwa data harus diunggah ke server pihak ketiga. Selain itu, sangat mungkin bahwa server pihak ketiga tidak akan tersedia selama pemulihan. Atau server pihak ketiga hanya bisa mengizinkan membaca, tetapi tidak menulis data.

psql


Serangkaian tambalan kecil membuat psql lebih nyaman:

  • Penyempurnaan tab yang ditingkatkan untuk beberapa tim.
  • Selain \echomengirim string ke STDOUT, perintah baru \warnmengirim string ke output kesalahan standar (STDERR).
  • \d toast- . \d+ .
  • \dt+ «Persistence» (unlogged) (permanent).
  • \e , ; ( \g*). , psql .
  • . PROMPT1 PROMPT2 %x.
  • Perintah baru untuk informasi lebih lanjut tentang metode akses: \dAc, \dAf, \dAo,\dAp
  • Anda \gsekarang dapat menentukan dalam kurung opsi apa saja yang didukung \pset. Mereka hanya akan bertindak pada tim saat ini.


libpq


Perubahan kecil sehubungan dengan PostgreSQL:
  • Ketidaktepatan dalam deskripsi parameter host dan hostadr dan inkonsistensi yang dihasilkan dalam output \conninfoperintah utilitas psql telah diperbaiki.
  • Jika kunci sertifikat klien disimpan dalam bentuk terenkripsi, Anda dapat memasukkan kata sandi hanya dalam mode interaktif. Parameter sslpassword baru memungkinkan Anda mendekripsi kunci secara non-interaktif.
  • Dua parameter baru, sslminprotocolversion dan sslmaxprotocolversion, memungkinkan Anda untuk menentukan batasan pada versi protokol SSL / TCL yang memungkinkan koneksi.

reindexdb


Parameter --jobs baru pada utilitas reindexdb menetapkan jumlah koneksi database di mana indeks akan dibangun kembali pada saat yang sama.

pg_rewind


Keterbatasan utilitas secara bertahap dihapus, dan kemungkinan meningkat.
Pertama, pg_rewind sekarang dapat merekam informasi untuk pemulihan (seperti pg_basebackup dapat melakukan ini), serta memulai pemulihan dan pematian instance dari instance jika tidak dihentikan melalui pos pemeriksaan (ini harus dilakukan secara manual sebelumnya).

Dan kedua, pg_rewind belajar bekerja dengan arsip WAL .
Setelah utilitas menemukan titik divergensi WAL antara dua server, itu harus membangun daftar semua halaman yang perlu disalin ke cluster target untuk menghilangkan perbedaan. Untuk ini, utilitas memerlukan semua file WAL, mulai dari titik yang ditemukan. Jika file WAL yang diperlukan tidak tersedia di cluster target, utilitas tidak dapat melakukan pekerjaannya sebelumnya.

Dengan tambalan ini oleh Alexey Kondratov (Postgres Professional) pg_rewind akan dapat membaca segmen WAL yang hilang dari arsip file log menggunakan parameter restore_command jika switch baru -c atau - restore-target-wal ditentukan.

pg_waldump


pg_waldump akan mendekripsi catatan transaksi yang disiapkan.

amcheck


Ekstensi amcheck telah belajar mengenali kerusakan yang lebih baik dalam indeks B-tree.
Omong-omong, sekarang pesan di log server tentang halaman yang rusak akan berbeda untuk indeks dan tabel .

Halamaninspect


The heap_tuple_infomask_flagsfungsi ekstensi pageinspect mendekripsi nilai-nilai bidang infomask dan infomask2dikembalikan oleh fungsi heap_page_items. Berguna dalam menyelidiki situasi korupsi data.

postgres_fdw


Pengguna super di tingkat pemetaan nama pengguna dapat memungkinkan pengguna biasa untuk menggunakan koneksi tanpa kata sandi:

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

Ini dilakukan, antara lain, sehingga sslkey dan sslcert dapat digunakan sebagai parameter koneksi .

adminpack


Ekstensi adminpack memiliki fitur baru - pg_file_sync. Dengan menggunakannya, Anda dapat melakukan fsync untuk file yang ditulis oleh server ke disk, misalnya melalui pg_file_writeatau COPY TO.

Pemantauan


pg_stat_slru


Di memori bersama server, tidak hanya ada cache buffer yang besar, tetapi juga sejumlah cache lain yang lebih sederhana (misalnya, untuk status transaksi). Mereka menggunakan algoritme sederhana untuk mengeluarkan halaman yang paling jarang digunakan (sederhana yang belum lama digunakan, atau SLRU). Sampai sekarang, cache seperti itu "baru saja bekerja", tetapi ada kebutuhan untuk memonitor mereka, pertama-tama untuk pengembang kernel PostgreSQL untuk mencari tahu apakah ada sesuatu yang perlu diubah di dalamnya. Untuk ini dan untuk tujuan, tampilan baru pg_stat_slru telah muncul .

pg_stat_activity


Dalam tampilan, pg_stat_activity kolom baru adalah leader_id. Untuk proses yang berpartisipasi dalam permintaan paralel, diisi dengan jumlah proses utama. Dan proses memimpin leader_idadalah nomor proses pid.
Kueri berikut menunjukkan kueri dan proses mana yang saat ini berjalan secara paralel:

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;

Ada perubahan pada daftar acara yang menunggu. Menambahkan dua acara baru : BackupWaitWalArchivedan RecoveryPause. Dan dua lainnya diberi nama yang lebih akurat: RecoveryWalStream -> RecoveryRetrieveRetryInterval, RecoveryWalAll -> RecoveryWalStream.

Dan dua peristiwa menunggu baru yang terjadi pada replika : RecoveryConflictSnapshot(konflik dengan VACUUM, yang menghapus versi baris yang diperlukan) dan RecoveryConflictTablespace(konflik terkait dengan penghapusan ruang tabel).

pg_stat_statements


Hingga saat ini, ekstensi telah pg_stat_statementsmemperlakukan permintaan dengan FOR UPDATEdan tanpa frasa sebagai permintaan yang sama. Sekarang permintaan dengan FOR UPDATE dicatat secara terpisah .

Jumlah informasi yang dikumpulkan telah meningkat. Mulai sekarang, tidak hanya informasi tentang sumber daya untuk menjalankan perintah dicatat, tetapi juga statistik pada entri jurnal yang dihasilkan . Kolom presentasi baru: wal_bytes- volume rekaman yang dihasilkan, wal_records- jumlah rekaman yang dihasilkan, wal_num_fpw- jumlah gambar halaman penuh (penulisan halaman penuh).

Ini dimungkinkan berkat infrastruktur yang disiapkan untuk melacak penggunaan WAL. Oleh karena itu, sekarang EXPLAINdengan opsi baru WALakan menampilkan volume catatan yang dihasilkan:

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)

Perluasan auto_explain, VACUUMs VERBOSE, dan autovacuumjuga menggunakan infrastruktur yang dibuat dan akan menghasilkan volume WAL.

Kembali ke pg_stat_statements. Jika parameter baru pg_stat_statements.track_planning diaktifkan , maka statistik tambahan yang terkait dengan penjadwal akan dicatat untuk setiap operator: jumlah paket yang dibuat; total waktu perencanaan; waktu minimum dan maksimum dari satu perencanaan, serta mean dan standar deviasi.

Akuntansi untuk sumber daya yang dialokasikan untuk penjadwal tercermin dalam tambalan lain yang tidak terkait pg_stat_statements. EXPLAINdengan opsi BUFFERSakan melaporkan jumlah buffer yang digunakan pada tahap perencanaan :

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

Majalah


  • 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, , .
  • Anda sekarang dapat menulis jenis proses ( pg_stat_activity.backend_type) ke log server . Untuk ini log_line_prefix, simbol khusus disediakan dalam parameter %b. Dan jika log ditulis dalam format csv ( log_destination=csvlog), maka kolom backend_typesudah termasuk di sana.


Kemajuan


Gagasan baru pg_stat_progress_analyzedan pg_stat_progress_basebackupmemungkinkan Anda untuk melacak kemajuan pengumpulan perintah statistikANALYZE dan utilitas cadanganpg_basebackup , masing-masing.

Optimasi


Perhitungan fungsi-fungsi yang tidak dapat diubah dalam klausa FROM pada tahap perencanaan
. Patch Aleksandr Kuzmenkov dan Aleksandr Parfyonov (keduanya dari Postgres Professional) membantu dalam kasus-kasus di manaFROMpanggilan tersebut berisi panggilan fungsi yang sebenarnya merupakan konstanta. Dalam hal ini, alih-alih membuat koneksi, nilai konstan diganti di tempat yang diperlukan dari permintaan.

Begini cara ini terjadi dengan contoh kueri yang terkait dengan pencarian teks lengkap:

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)

Tidak ada koneksi, dan nilai 'tuple' :: tsquery diganti dalam kueri yang sudah pada tahap perencanaan. Versi 12 memiliki gambaran yang sangat berbeda:

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)


Penyortiran bertahap

Saat menyortir dengan banyak kunci diperlukan (k1, k2, k3 ...), penjadwal sekarang dapat memanfaatkan pengetahuan bahwa data sudah diurutkan berdasarkan beberapa kunci pertama (misalnya, k1 dan k2). Dalam hal ini, Anda tidak dapat mengurutkan kembali semua data lagi, tetapi membaginya menjadi kelompok-kelompok berturut-turut dengan nilai yang sama k1 dan k2, dan "urutkan" dengan kunci k3.

Dengan demikian, seluruh penyortiran terbagi menjadi beberapa jenis ukuran yang lebih kecil berturut-turut. Ini mengurangi jumlah memori yang dibutuhkan, dan juga memungkinkan Anda untuk memberikan data pertama sebelum semua penyortiran selesai.

Misalnya, dalam demobase di tabel tiket ada indeks di kolom ticket_id. Data yang diterima dari indeks akan diurutkan berdasarkan ticket_id, jadi permintaan berikut akan menggunakan pengurutan tambahan:

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

Fungsionalitas penyortiran inkremental dapat dinonaktifkan dengan parameter enable_incrementalsort. Dalam hal ini, pengurutan akan terasa lebih lama:

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

Gagasan penyortiran bertahap diusulkan kembali pada tahun 2013 oleh Alexander Korotkov (Postgres Professional), dan sekarang, tujuh tahun kemudian, tambalan itu dibawa oleh James Coleman ke negara yang diterima oleh masyarakat.

TRUNCATE akselerasi
Ketika TRUNCATEpemindaian terjadi shared_buffersuntuk menghapus buffer tabel dari memori bersama. Sebelumnya, pemindaian dilakukan tiga kali, untuk setiap lapisan tabel: MAIN (lapisan data utama), FSM (peta ruang bebas), VM (peta visibilitas). Sekarang logikanya telah berubah, daripada operasi tiga kali lipat, buffer hanya dipindai sekali. Dengan nilai besar, shared_buffersini memberikan keuntungan nyata.

TOAST dekompresi parsial
Ketika tidak perlu membaca TOAST sepenuhnya, membatasi ke irisan di awal atau dekat dengan awal, maka tidak masuk akal untuk melepasnya sepenuhnya. TOAST terkompresi dibaca dalam iterasi: baca sepotong, jika tidak ada data yang diperlukan, kemudian perluas dan baca terus. Disarankan oleh siswa Google Summer of Code, Binguo Bao, yang memberikan contoh:

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

Dengan tambalan, urutan besarnya lebih cepat:

Time: 2.306 ms

VACUUM Paralel
Dalam artikelnya tentang hal ini, Yegor Rogov menjelaskan secara rinci langkah penting ini dalam paralelisasi. Singkatnya: “Masahiko Sawada Patch, yang memungkinkan Anda untuk melakukan pembersihan secara paralel. Tabel itu sendiri masih dibersihkan oleh satu proses (memimpin), tetapi untuk membersihkan indeks, sekarang dapat memulai alur kerja latar belakang, satu untuk setiap indeks. Dalam mode manual, ini memungkinkan Anda untuk mempercepat pembersihan tabel besar dengan banyak indeks; pembersihan otomatis belum menggunakan fitur ini. "

Bersihkan otomatis saat disisipkan ke dalam tabel
Untuk tambalan ini (juga dikenal sebagai vakum-otomatis Berserk), kita perlu berterima kasih kepada Dorofei Proleskovsky, yang mengusulkan solusi untuk masalah berikut: pembersihan otomatis tidak datang ke tabel append-only, karena mereka tidak memiliki versi baris "mati". Karena itu, peta visibilitas tidak diperbarui, membuat hanya scan indeks saja tidak efektif, dan ketika pembersihan memang datang untuk mencegah konter transaksi meluap, itu perlu melakukan banyak pekerjaan sekaligus. Sekarang situasi ini telah diperbaiki: Pembersihan otomatis juga akan bekerja pada penambahan saluran. Dua parameter server baru ( autovacuum_vacuum_insert_thresholddan autovacuum_vacuum_insert_scale_factor) muncul, mirip dengan yang untuk modifikasi ( autovacuum_vacuum_thresholddan autovacuum_vacuum_scale_factor).

Manajemen Memori Agregat Hash
Agregasi hash mungkin memerlukan RAM lebih dari pikiran scheduler dan daripada yang ditunjukkan di work_mem. Sebelumnya, kesalahan penjadwal seperti itu menyebabkan fakta bahwa ukurannya work_memdiabaikan dan memori dialokasikan sebanyak yang diperlukan untuk operasi atau kedatangan OOM Killer. Sekarang algoritme mungkin tidak melampaui work_mem, dan jika perlu, gunakan file sementara pada disk. Untuk mengontrol perilaku penjadwal, parameter berikut muncul: enable_groupingsets_hash_diskdan enable_hashagg_disk.

Mengoptimalkan UPDATE untuk tabel dengan kolom yang dihasilkan
Dalam versi 12, kolom yang dihasilkan dihitung ulang selama setiap pembaruan baris, bahkan jika perubahan ini tidak memengaruhi mereka dengan cara apa pun. Sekarang mereka akan dihitung ulang hanya ketika itu benar-benar diperlukan (jika kolom dasar mereka telah berubah).

Optimasi ini, misalnya, dapat secara signifikan mempercepat pembaruan tabel dengan kolom tipe yang dihasilkan tsvector, karena fungsinya to_tsvector()cukup mahal.

Akses dari pelatuk ke daftar kolom yang diubah Tambalan
kecil yang menambahkan TriggerDatabitmap kolom yang diubah ke struktur . Informasi ini dapat digunakan oleh fungsi pemicu umum, seperti tsvector_update_trigger()atau lo_manage(), agar tidak melakukan pekerjaan yang tidak perlu.

Gunakan beberapa statistik lanjutan saat mengevaluasi
Di PG12, penjadwal tidak dapat menggunakan beberapa statistik lanjutan untuk tabel yang sama secara bersamaan. Misalnya, bayangkan situasi di mana dua statistik canggih dibangun untuk kumpulan kolom yang berbeda, dan kolom dari satu kumpulan dan dari yang lain berpartisipasi dalam kueri. Sekarang perencana memiliki akses ke semua informasi yang tersedia.

Infrastruktur untuk paralelisasi dan COPY (lihat juga tambalan ini. )
Konkurensi postgreSQL masih berfungsi untuk kueri hanya-baca. Ada kesulitan dengan penulis, dan salah satunya adalah memblokir proses yang secara bersamaan melakukan satu tugas (termasuk dalam kelompok paralel yang sama). Dipercaya bahwa kunci dari proses tersebut tidak bertentangan - misalnya, beberapa proses dapat menahan kunci eksklusif pada tabel yang sama. Ini membutuhkan perhatian khusus dari pengembang kernel, tetapi jika tidak, mereka akan selalu mengalami kebuntuan.
Tetapi ada dua pengecualian:

  • kunci ekstensi hubungan, yang ditangkap ketika halaman baru ditambahkan ke akhir file data, dan
  • kunci halaman, yang digunakan saat memindahkan item indeks GIN dari daftar tunggu ke pohon utama.

(Anda dapat membaca lebih lanjut di artikel ini. )
Kunci seperti itu harus bertentangan bahkan antara proses dari kelompok paralel yang sama - yang mengimplementasikan tambalan ini. Tetapi kunci ini tidak pernah dapat menyebabkan kebuntuan, sehingga mereka dikeluarkan dari pemindaian.

Bagi pengguna, secara umum, tidak ada yang berubah, tetapi tambalan ini penting karena, pertama, ia membuka jalan untuk paralel INSERT dan COPY, dan kedua, menghilangkan salah satu hambatan PostgreSQL di bawah kondisi beban tinggi (yang dapat didengar dalam laporan HL ++ ).

Keamanan


Primer SKH PRH diganti Primer
EDH tergantikan (Diffie-Hellman Ephemeral Keys) menggunakan protokol SKIP yang sekarang sudah tidak aktif.

initdb: pengaturan default untuk otentikasi
telah berubah Pengaturan akses default untuk koneksi lokal dan jaringan telah berubah ketika initdb dimulai. Sekarangpg_hba.confuntuk koneksi lokal, bukan metode otentikasitrustakanpeer(atau MD5 jika peer tidak didukung), danmd5untuk koneksi jaringan. Awalnya, langkah-langkah yang lebih liberal dibahas: peringatan dalam dokumentasi. Kemudian ketat:scram-sha-256. Akibatnya, kami memutuskan untuk membatasi diri padapeerdanmd5.

Menggunakan eksplisit_bzero
Tambalan penting. Fungsi bzero () dan eksplisit_bzero () menulis byte yang berisi ke dalam area memori yang ditunjukkan '\0'(lihat, misalnya , Linux). Tambalan ini hanyalah permulaan: ada banyak bagian memori yang dapat digunakan untuk menyimpan kata sandi dan informasi sensitif lainnya. Kami memutuskan untuk memulai dari tempat-tempat seperti libpq, di mana seluruh file dengan kata sandi dapat tetap tersimpan dalam memori setelah membaca .pgpass, dan dari pembersihan setelah menutup koneksi. Di be-secure-common.c sekarang ada penulisan ulang frase rahasia yang dimasukkan dalam SSL, yang muncul di baris (path) kesalahan.

Menambahkan parameter "password_protocol" ke libpq
Patch ini memungkinkan libpq untuk mengontrol protokol transfer kata sandi mana yang digunakan selama koneksi. Setelah menerima parameter ini, libpq akan menolak otentikasi jika protokolnya lebih lemah dari yang ditentukan. Secara default, parameter ini plaintext, yaitu, semua protokol cocok.

Akses wajib untuk TRUNCATE
Patch ini memungkinkan ekstensi untuk menanamkan Kontrol Akses Wajib (MAC) untuk operasi TRUNCATE. Hak untuk itu sekarang akan diperiksa oleh ekstensi sepgsql . Kebijakan Referensi SELinux dan distribusi Linux berbasis Redhat tidak mendukung SELinux memeriksa db_table {truncate}. Dalam kasus ini, sepgsql akan digunakan dengan 'deny_unknown' sama dengan 1, dan TRUNCATE akan gagal.

Ketersediaan GUC ssl_passphrase_command
Patch yang sederhana namun bermanfaat. Sekarang nilai parameter ssl_passphrase_command hanya akan dilihat oleh superuser. Parameter menentukan perintah eksternal yang dipanggil ketika kata sandi diperlukan untuk mendekripsi file SSL, misalnya, kunci pribadi.

Lokalisasi


Versioning libc collation rules
Untuk aturan collation ICU, nomor versi disimpan dalam database. Setiap kali aturan digunakan (penyortiran, perbandingan karakter), nomor versi yang disimpan diperiksa dengan versi saat ini di perpustakaan ICU di OS, dan jika ada perbedaan, peringatan dikeluarkan. Ini memungkinkan Anda menemukan bahwa indeks tertentu yang dibuat sesuai dengan aturan penyortiran yang dimodifikasi mungkin salah dan harus dibangun kembali. Dengan membangun kembali indeks dengan perintahALTER COLLATION ... REFRESH VERSION, versi aturan penyortiran dalam database diperbarui dan peringatan tidak lagi dikeluarkan.

Tapi itu hanya untuk ICU. Sekarang nomor versi juga disimpan untuk aturan penyortiran libc:

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

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

Yang memungkinkan untuk mengeluarkan peringatan ketika perpustakaan berubah di OS. Sangat relevan mengingat transisi ke glibc 2.28, di mana banyak aturan penyortiran telah berubah, dan indeks yang sesuai harus dibangun kembali.

Tetapi sampai mereka beralih ke 2.28, semuanya tenang:
ALTER COLLATION "ru_RU" REFRESH VERSION;

NOTICE:  version has not changed
ALTER COLLATION

Pencarian Teks Lengkap


Pencarian teks lengkap untuk bahasa Yunani
Tidak ada komentar.

dict_int belajar menangani nilai absolut.
Kamus template dict_int (alias ekstensi) menambahkan kemampuan untuk menghapus tanda dari angka.


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)

Artinya, kali ini nilai absolutnya diakui.

Partisi


SEBELUM
pemicu barisBEFOREpada tabel dipartisiDalam versi 12, Anda tidak bisa membuat pemicu barispada tabel dipartisi. Pada bagian yang terpisah - tolong, tetapi tidak pada seluruh tabel sekaligus. Sekarang,BEFORE FOR EACH ROWpemicu yang dibuat pada tabel dipartisi akan secara otomatis diwarisi dan berfungsi untuk semua bagian. Tetapi dengan ketentuan bahwa jika itu adalah pemicu aktifUPDATE, maka kunci partisi di dalamnya hanya dapat diubah dalam bagian saat ini.

Dukungan untuk tabel yang dipartisi dalam replikasi logis
Sebelumnya, termasuk tabel yang dipartisi dalam publikasi menyebabkan kesalahan:

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.

Sekarang berhasil.

Algoritma JOIN sectional yang disempurnakan
Mulai dari versi 11, penjadwal dapat bergabung dengan tabel dipartisi bagian demi bagian, tetapi hanya jika batas-batas bagian sama persis. Sekarang algoritme telah ditingkatkan: ini akan berfungsi jika bagian dari satu tabel sepenuhnya dimasukkan dalam bagian yang lain, bahkan jika ukurannya tidak cocok (misalnya, jika satu tabel dipartisi berdasarkan hari dan yang lainnya berdasarkan bulan). Algoritma baru berfungsi untuk mempartisi berdasarkan rentang dan daftar.

SECTional FULL OUTER JOIN Sectionalized join
sekarang berfungsi untuk gabungan luar penuh yang direkam dengan frasa USING.

tableam


Dalam bidang yang menarik dan menjanjikan ini, tetapi sulit, tidak ada kemajuan radikal terkait PostgreSQL 12. Tidak ada penyimpanan plug-in yang sudah jadi seperti zheapselain heap), tetapi pekerjaan terus dilakukan pada API.

Tingkat abstraksi yang lebih tinggi dalam menentukan ukuran tabel
Robert Haas menulis ulang kode, mengubah arsitekturnya menjadi lapisan abstrak, agar tidak menduplikasi kode di masa depan. Bagian ini mengacu pada estimate_rel_size- ukuran lapisan (garpu) dari tabel.

Anda dapat menggunakan metode akses tabel dengan relcache.
Patch ini membawa kemampuan manajemen memori dari metode akses tabel ke kemampuan metode indeks.

tableam dan TOAST
TOAST sebagian besar dirancang untuk penyimpananheapOleh karena itu, ketika membuat metode akses tabel baru , Anda bisa menggunakan dua cara: membantu pengembang metode baru mengintegrasikan menyisipkan, memperbarui, dan menghapus catatan TOAST ke dalamnya atau mendelegasikan pekerjaan dengan TOAST ke kode menggunakan penyimpanan PostgreSQL tradisional - heap. Serangkaian 5 tambalan menggunakan slot tuple untuk mengimplementasikan operasi sisipan / perbarui / hapus dan dapat membantu yang berjalan dua arah.

fsync


Menangani kesalahan fsync di pg_receivewal dan pg_recvlogical
Pertarungan melawan fsync () berlanjut. PostgreSQL percaya bahwa panggilan fsync () yang berhasil berarti bahwa semua data dalam file telah dibilas ke disk, tetapi ini tidak selalu terjadi (tergantung pada OS) dan dapat mengakibatkan hilangnya data. PG13 memutuskan bahwa itu perlu untuk menangani utilitaspg_receivewaldanpg_recvlogical. Saat ini, perilaku default adalah ini: utilitas ini akan menulis kesalahan fsync ke log, memulihkan koneksi dan melanjutkan seolah-olah tidak ada yang terjadi. Sebagai hasilnya, WAL berisi informasi tentang file yang berhasil disalin, yang, pada kenyataannya, tidak benar dibilas ke disk. Jadi lebih baik untuk mengganggu utilitas. Nasib pg_dump, pg_basebackup, pg_rewind, dan pg_checksums juga dibahas, tetapi sejauh ini telah membatasi diri pada keduanya.

Perlindungan terhadap pengaturan flag yang salah untuk fsync ()
Patch ini memeriksa apakah flag-flag tersebut diset dengan benar ketika menerima deskriptor file untuk fsync () - direktori terbuka hanya untuk membaca, dan file untuk menulis atau keduanya.

Cadangkan dan replikasi


Jeda selama pemulihan sebelum mencapai titik pemulihan
Jika selama pemulihan, WAL telah berakhir, tetapirecovery_target_timebelum mencapai yangditentukan, server menyelesaikan pemulihan dan beralih ke mode operasi normal. Sekarang tidak akan begitu. Proses pemulihan akan berhenti, seperti yang dilaporkan dalam log, dan administrator akan memiliki kesempatan untuk memasukkan segmen WAL yang hilang dan melanjutkan pemulihan.

Parameter ign_invalid_pages
Ketika proses pemulihan pada replika menemukan tautan ke halaman yang tidak valid dalam catatan WAL,panic-aterjadi. Dimasukkannya parameter akan membantu mengatasinya.ignore_invalid_pages. Pemulihan akan berlanjut dengan kemungkinan hilangnya integritas, data, dan konsekuensi paling serius lainnya. Parameter ini ditujukan untuk pengembang server dan harus digunakan dalam kasus-kasus ketika Anda masih perlu mencoba untuk menyelesaikan pemulihan dan memulai replika.

Mengubah primary_conninfo tanpa me-restart
patch Sergey Kornilov, yang memungkinkan Anda untuk mengubah pengaturan primary_conninfo, primary_slot_namedan wal_receiver_create_temp_slottanpa me-restart server. Sebenarnya, demi ini, mereka meninggalkan file recovery.confdalam rilis ke-12. Manifes

cadangan
Pg_basebackup sekarang membuat "manifes" - file JSON yang berisi informasi tentang cadangan yang dibuat (nama dan ukuran file, file WAL yang diperlukan, serta checksum segala sesuatu dan segala sesuatu).
Utilitas pg_validatebackup baru memeriksa cadangan untuk kepatuhan dengan manifes, dan juga memeriksa ketersediaan dan kebenaran file WAL yang diperlukan untuk pemulihan menggunakan utilitas pg_waldump (ini hanya berlaku untuk file WAL di dalam cadangan itu sendiri, dan bukan di arsip).
Ini akan memungkinkan Anda untuk mendeteksi situasi di mana file cadangan rusak atau hilang, atau ketika pemulihan menjadi tidak mungkin karena kurangnya file log yang diperlukan.

Membatasi slot replikasi data yang belum dibaca Slot replikasi
adalah mekanisme yang nyaman tetapi berbahaya: jika klien tidak membaca data dari slot tepat waktu, catatan WAL yang belum dibaca dapat mengambil semua ruang di server. Sekarang menggunakan parametermax_slot_wal_keep_sizeAnda dapat menetapkan batas jumlah ruang disk maksimum yang dapat ditempati oleh data yang belum dibaca. Jika pada pos pemeriksaan berikutnya ternyata ukurannya terlampaui, slot dinonaktifkan, dan tempat itu dibebaskan.

Windows


Dukungan untuk soket Unix pada Windows
Soket domain Unix didukung pada Windows 10, meskipun soket dinonaktifkan secara default.

Dokumentasi


Ada dua aplikasi baru dalam dokumentasi.
Setelah diskusi panjang , Lampiran M. Daftar Istilah muncul . Saat ini ada 101 istilah dalam glosarium.

Kemampuan untuk menyorot warna pesan diagnostik utilitas konsol menggunakan variabel PG_COLORlebih awal. Ini sekarang didokumentasikan dalam Lampiran N. Dukungan Warna . Maksud asli Peter Eisentrout dalam tambalan ini adalah untuk membuat keluaran berwarna dihidupkan secara default. Dan bagi mereka yang tidak menginginkan ini, diusulkan untuk secara eksplisit mengatur variabelNO_COLOR. Tetapi ada lebih banyak penentang diferensiasi warna pesan di antara mereka yang membahas tambalan. Karena itu, mereka memutuskan hanya untuk mendokumentasikan peluang yang tersedia. Dan kami mendapat bagian baru dari tingkat pertama dalam dokumentasi.



PG13, , PG14 . , . .

All Articles