كم هو جديد في دزينة الشيطان؟

نحن نتحدث فقط عن PostgreSQL 13. في 8 أبريل ، حدث "تجميد" - تم تجميد ميزة PostgreSQL ، والآن سيتم تضمين هذه الميزات فقط التي يتم قبولها قبل هذا التاريخ في هذا الإصدار.

من الصعب تسمية نسخة ثورية من هذا. لا توجد تغييرات جوهرية ومفاهيمية فيها. علاوة على ذلك ، فإن التصحيحات الهامة مثل الجدول والوظائف لمعيار JSON / SQL ، والتي أردت أيضًا رؤيتها في PG12 بجوار تصحيح JSONPath ، لم يكن لديها الوقت لإدخالها ؛ لم يظهر التخزين المضمن الجاهز - فقط يتم الانتهاء من الواجهة. لكن قائمة التحسينات لا تزال مثيرة للإعجاب. لقد أعددنا ملخصًا كاملًا إلى حد ما للبقع المضمنة في دزينة الشيطان.




التغييرات على أوامر SQL


إنشاء قاعدة بيانات ... LOCALE

المرافقinitdb،createdbوالفريقCREATE COLLATIONلديه إعدادLOCALEيسمح لك بتحديد القيم للحقLC_CTYPEوLC_COLLATE. الآن ظهرت الفرصة نفسها في الفريقCREATE DATABASE:

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

ALTER VIEW ... RENAME COLUMN

يمكن الآن تغيير اسم العمود في العرض باستخدام الأمرALTER VIEW. سابقًا ، تطلب هذا إعادة إنشاء العرض.

لنفترض أنك نسيت تسمية العمود:

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

يمكن إصلاحه:

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

يمكن الآن جعل العمود الذي تم إنشاؤه في الجدول عاديًا ، أي حذف التعبير لتقييمه:

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)

بعد ذلك ، قرروا أن ضريبة الدخل يجب تحديدها بشكل صريح. حذف التعبير:

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)

بالطبع ، لم تختف البيانات الموجودة في العمود:

SELECT * FROM payments;

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


DROP DATABASE ... FORCE
إذا كنت تريد حذف قاعدة بيانات دون انتظار قطع اتصال جميع المستخدمين ، يمكنك استخدام خيارFORCEالأمرالجديدDROP DATABASE.

CREATE DATABASE db;

الاتصال بقاعدة البيانات الجديدة:

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

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

والآن سنحذف pg_terminate_backendالاتصالات المفتوحة ونقطعها أيضًا قسرًا :

DROP DATABASE db WITH (FORCE);

ALTER TYPE ... SET STORAGE يسمح
الأمرALTER TYPEلأنواع البيانات الأساسية بتغيير الخصائص المختلفة ، على وجه الخصوص ، استراتيجية التخزين. في السابق ، كان بإمكانك تعيينه في فريق فقطCREATE TYPE.

للتوضيح ، لن ننشئ نوعًا أساسيًا جديدًا ، ولكن سنستخدم النوع الموجود -tsquery. ولكن أولاً ، أنشئ قاعدة بيانات منفصلة واتصل بها:

CREATE DATABASE db;
\c db

يتم استخدام إستراتيجية التخزين لنوع بيانات tsquery plain، بحيث تحصل أعمدة الجداول من هذا النوع على الإستراتيجية نفسها:

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

إذا كنت بحاجة إلى استخدام إستراتيجية مختلفة للجداول الجديدة ، يمكنك تغيير النوع الأساسي:

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

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

سيتغير نوع التخزين في الجداول الجديدة أيضًا:

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

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

يجب أن يوضع في الاعتبار أنه لا يمكن تغيير استراتيجية تنطوي على استخدام TOAST إلى plain:

ALTER TYPE tsquery SET (storage=plain);

ERROR:  cannot change type's storage to PLAIN

لذلك ، تم تنفيذ التجارب في قاعدة بيانات منفصلة ، وليس من المؤسف حذفها.

تغيير الإحصائيات ... تعيين الإحصائيات يسمح لك

الأمر CREATE STATISTICSبتجميع قوائم القيم الأكثر شيوعًا لمجموعات مختارة من أعمدة الجدول. يتم تحديد عدد القيم الأكثر شيوعًا التي تم جمعها بواسطة المعلمة default_statistics_target. يمكن الآن تغيير قيمة إحصائيات معينة باستخدام الأمر:

ALTER STATISTICS  SET STATISTICS _;

الخيار FETCH FIRST with WITH TIES
كما تعلمون ،SELECTبدلاً من تحديدأمر،LIMITيمكنك استخدام بناء الجملة المحدد في معيار 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)

الآن FETCHيدعم العبارة WITH TIES، التي تضيف إلى المخرجات جميع الأسطر "ذات الصلة" (خطوط تساوي الخطوط المحددة بالفعل ، إذا تم أخذ شرط الفرز فقط في الاعتبار):

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)

الوظائف المدمجة وأنواع البيانات


get_random_uuid تُرجع
الدالة الجديدةget_random_uuidقيمة UUID للإصدار 4 (قيمة عشوائية):

SELECT gen_random_uuid();

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

الوظيفة مفيدة لتوليد قيم UUID الفريدة في الأنظمة الموزعة.
في السابق ، كان عليك استخدام مكتبات uuid-ossp أو pgcrypto.

min_scale و trim_scale لقيم النوع الرقمي تحدد

الوظيفة min_scaleعدد الأرقام المهمة في الجزء الكسري من الرقم ، trim_scaleوتتجاهل الوظيفة الأصفار غير الهامة :

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

التجديد في قسم الوظائف الرياضية. الآن يمكنك العثور بسرعة على أكبر القاسم المشترك (gcm) والمضاعف المشترك الأصغر (lcm):

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

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

وظائف الكلي دقيقة والحد الأقصى لنوع pg_lsn تم إضافة وظائف تجميع ل

نوع البياناتوالتي تسمح لك لتنفيذ استعلامات النموذج:pg_lsnminmax

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

التحقق من مُعدِّل النوع لقيمة الإرجاع للدالة

في الإصدارات السابقة ، لم يتم التحقق من مُعدل النوع لقيمة الإرجاع للدالة.

افترض أن هناك نوعًا لتخزين الوحدات النقدية ووظيفة ترجع مبلغ ضريبة الدخل:

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;

باستدعاء الوظيفة ، نتوقع الحصول على منزلين عشريين ، ومع ذلك ، نحصل على أربعة. حتى الإرسال الصريح بعد استدعاء دالة لا يساعد (العمود الثالث):

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

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

في الإصدار 13 ، تكون النتيجة صحيحة:

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

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

أسماء محلية في TO_DATE () وto_timestamp ()

وظائفto_dateأيضاto_timestampعلمت أن نفهم أسماء المترجمة من الشهور وأيام الأسبوع. في السابق ، كان يمكن استخدام الأسماء الإنجليزية فقط:

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

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

تطبيع و NORMALIZED

للامتثال لمعيار SQL ، تمت إضافة وظيفة تطبيع () لتطبيع سلسلة Unicode ، والمسند IS NORMALIZED للتحقق مما إذا تم تطبيع سلسلة.

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

اقرأ المزيد عن نماذج تطبيع UNICODE.

نوع Xid8 ووظيفة xid8_current () لأرقام معاملات 64 بت

تمت إضافة نوع بيانات xid8 جديد لرقم المعاملات 64 بت. ولكن لا ، هذا لا يعني أن PostgreSQL تحول إلى معاملات 64 بت: كل شيء يعمل تمامًا كما كان من قبل. لكن بعض الدوال تُرجع نوعًا جديدًا ، على سبيل المثال ، يُنصح باستخدامه الآن بدلاً من الدوال القديمة pg_current_xact_id txid_current ، والتي أرجعت int8 ، وهكذا. N.

أنواع البيانات متعددة الأشكال الجديدة أي أنواع متوافقة من الأسرة

المضافة anycompatible، anycompatiblearray، anycompatiblenonarray، ، anycompatiblerange. على عكس أنواع العائلات anyelement، تسمح لك الأنواع الجديدة بعدم استخدام الأنواع نفسها تمامًا ، ولكن الأنواع المتوافقة في الواقع.

في المثال التالي ، الوظيفةmaximumكما الحجج المعرفة كما anycompatibleتم تمريرها integerو numeric. يتم تحويل القيمة المرجعة إلى قيمة مشتركة لهذين النوعين:

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

علاوة على ذلك ، فإن الأنواع المتوافقة - وأيًا - هي مجموعتان مستقلتان من الأنواع:

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)

اللغات الإجرائية


تحويل نوع bool في PL / Perl
مؤخرًا ، تم تنفيذ TRANSFORM من Ivan Panchenko (Postgres Professional) - bool_plperl . بوستجرس يمر القيم المنطقية لtأوفي PL / بيرل مثلf، ولكن لبيرل أنهfليست منطقية كاذبة ، ولكن فقط الرسالة و، أي في سياق منطقي ، الحقيقة . يمكن حل هذه المشكلة بطرق مختلفة (انظر المراسلات ) ، ولكن إنشاء TRANSFORM لبول ، وفقًا لتوم لين ، هو الأكثر عملية.

تنفيذ سريع للتعبيرات البسيطة في PL / pgSQL

التعبيرات البسيطة (على الأقل لا تحتوي على مكالمات طاولة ولا تتطلب أقفال) ستكون أسرع. في السابق ، في هذه الحالات ، تم قضاء الوقت بشكل غير منتج في الاتصال بالمجدولة في كل دورة.

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;

استدعاء slow_pi () في PG12:

SELECT slow_pi();

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

الآن في PG13:
SELECT slow_pi();

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

ملحقات موثوق بها بدلاً من pg_pltemplate

لقد انخفض دليل النظام بمقدار جدول واحد. تم الحذفpg_pltemplate. تم تخزين خصائص اللغات الإجرائية اللازمة أثناء التنفيذCREATE LANGUAGE. الآن قررنا تسجيل الخصائص من نصوص ملحقات اللغات المقابلةpg_pltemplate، والتخلص من الجدول نفسه. ولكن من أجل تنفيذ الخطة ، من الضروري توفير إمكانية لمالك قاعدة البيانات (بدون حقوق المستخدم الفائق) لإنشاء لغة موثوق بها من البرنامج النصي الملحق. في الواقع ، الآن لإنشاء plpgsql ، على سبيل المثال ، لا يجب أن يكون مالك قاعدة البيانات مستخدمًا فائقًا.

وردت على النحو التالي. ظهرت معلمة منطقية جديدة في ملف التحكم للملحقاتtrusted. إذا كلا المعلماتtrustedوsuperuserالمضمنة ، يمكن بعد ذلك إنشاء الامتداد ليس فقط من قبل المستخدم المتميز ، ولكن أيضًا من قبل المستخدم الذي لديه الحق CREATEفي قاعدة البيانات الحالية (وبالتالي مالكها). عند تنفيذ برنامج نصي لمثل هذا الامتداد ، سيتم استخدام حقوق المستخدم الفائق التي قامت بتهيئة المجموعة. ستنتمي إليه الكائنات التي تم إنشاؤها بواسطة الامتداد ، على الرغم من أن مالك الملحق نفسه سيكون المستخدم الذي تم إنشاؤه.

عواقب مهمة لهذه التغييرات:

  • تفتح الإضافات الموثوقة الطريق أمام مطوري الجهات الخارجية لإنشاء لغات موثوقة أخرى. نحن الآن مقيدون فقط بـ plpgsql و plperl و pltcl.
  • لقد pg_pltemplateكان مكتوبًا بشدة أن plpython يشير إلى الإصدار الثاني من اللغة. يعد الفشل في pg_pltemplateالقيام بذلك خطوة (ضرورية ، وإن لم تكن كافية) للانتقال إلى الثعبان 3.

المؤشرات


ضغط شجرة B
تم توصيل التصحيح المهم الذي طال انتظاره (بدأ العمل بالفعل في عام 2015) الذي كتبته Anastasia Lubennikova (Postgres Professional) و Peter Geigan (Peter Geoghegan) أخيرًا بواسطة Peter. تمكنت Nastya من التحدث عن هذا في PGconf India . لقد تعلمت Postgres تقليل حجم فهارس B-tree بشكل كبير من خلال إلغاء البيانات المكررة ، أي التوفير في مفاتيح الفهرس المكررة. تمت إعادة تصميم هذه الفهارس بشكل جدي بحيث يكون الضغط ممكنًا دون فقد التوافق مع الإصدارات السابقة من الفهارس. تؤخذ فكرة إلغاء البيانات المكررة من بنية أكثر مرونة للمؤشرات مثل GIN (الفهارس العكسية - الفهرس المعكوس العام).

في هذه المؤشرات أكثر من B-tree، هناك حالة عندما يتوافق المفتاح مع عدد كبير من السجلات. في حالة معالجة الكلمات ، على سبيل المثال ، عادة ما يتم العثور على نفس الرمز المميز في العديد من المستندات. ويتم تخزينه في الفهرس مرة واحدة فقط. حتى وقت قريب ، لم تكن فهارس B-tree تعرف كيفية القيام بذلك.

تختلف فهارس شجرة B عن فهارس GIN بشكل أساسي في صفحات الأوراق. اعتمادًا على عدد السجلات المتعلقة بنفس قيمة المفتاح ، هناك خيارات ممكنة: تحتوي الصفحة على قائمة نشر فقط - قائمة TIDs (معرفات السجلات المفهرسة) ، إذا كانت القائمة صغيرة ، وإذا كان هناك الكثير من TIDs ، فبدلاً من تخزين قائمة القيم "فروع الشجرة" الجديدة - روابط لصفحات أخرى مثل قائمة النشر أو فروع شجرة أخرى (تسمى شجرة الترحيل).

يشبه هيكل الشجرة هذا شجرة B ، ولكنه يختلف في التفاصيل الأساسية: على سبيل المثال ، قوائم التنقل عبر صفحات من نفس مستوى الشجرة في GIN هي أحادية الاتجاه ، وليست ثنائية الاتجاه. لذلك (بما في ذلك) التوافق الجيد للمؤشرات الجديدة المكررة مع الإصدارات القديمة ليس من السهل تحقيقه. واستغرقت التحسينات بالفعل أكثر من 3 سنوات. كان من الضروري أيضًا عمل آلية التنظيف (الفراغ الميكروي) والفروق الدقيقة الأخرى.

في اختبارات الأداء ، تقلصت جميع الفهارس التي ينطبق عليها إلغاء البيانات المكررة بنحو 3 مرات. كما أن ضغط التكرارات يساعد الفهارس الفريدة ، ويقضي على مشكلة انتفاخ الفهرس بمعدل مرتفع من تغيرات الجدول. يمكن توصيل سلوك جديد وفصله على مستوى إعدادات الفهرس.

لا يتم إجراء مسح كامل بواسطة فهرس GIN عندما لا يكون ذلك ضروريًا
يسمح هذا التصحيح في بعض الحالات بتجنب التمرير الكامل عبر فهرس GIN بأكمله. يتم تنفيذ بعض العمليات ، على الرغم من دعمها من قبل فهرس GIN ، عن طريق مسح كامل للفهرس. خذ ، على سبيل المثال ، فهرس البحث عن أعمدة النص الكامل tsvector. إذا كان طلب البحث يحتوي على النموذج "أي شيء ما عدا كلمة معينة" ، فيجب قراءة الفهرس بالكامل. ومع ذلك ، في حالة وجود شرط آخر في الطلب لا يتطلب مسحًا كاملاً للفهرس ، فسيظل الفهرس مسحًا كاملاً.

مع التحسين الجديد ، سيتم استخدام شرط أكثر دقة أولاً ، مما يسمح بالحصول على مكاسب من الفهرس ، وبعد ذلك سيتم التحقق من النتائج مرة أخرى لمراعاة قيود أخرى. قارن عدد الصفحات التي تمت قراءتها في الإصدار 12 (المخازن المؤقتة):

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

مع عدد المخازن المؤقتة في الإصدار الجديد:

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

يمكن مواجهة موقف مماثل عند استخدام trigrams ، وعند التحقق من حدوث المصفوفات.

معلمات فئات المشغل
في PostgreSQL ، تعد العديد من طرق الوصول إلى الفهرس "إطار عمل" يأخذ تنفيذًا عالي المستوى لخوارزمية البحث ، ويعمل مع الصفحات والأقفال ، وسجل WAL. ويتم إجراء الربط بأنواع بيانات وعوامل محددة باستخدام فئات عامل التشغيل.

حتى الآن ، لا يمكن أن تحتوي فئات عامل التشغيل على معلمات. على سبيل المثال ، للبحث عن نص كامل ، يمكن استخدام فهرس GiST مع فئة عوامل التشغيل tsvector_ops(حول فئات عوامل تشغيل GiST هنا) تستخدم هذه الفئة من المشغلين شجرة توقيع ، وتم إصلاح طول التوقيع (124 بايت). يمكنك الآن تحديد الطول بشكل صريح ، مما يسمح لك بالتحكم في التوازن بين حجم المؤشر والكفاءة (عدد تصادمات التجزئة):

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

تم إجراء تغييرات مماثلة للمبتدئين لفئات أخرى من عوامل تشغيل GiST التي تستخدم شجرة توقيع ، والتي تنطبق على ملحقات hstore و intarray و ltree و pg_trgm.
لكن الفكرة الرئيسية التي تم تصور هذا التغيير من أجلها هي القدرة على تمرير تعبير JSONPath إلى فهرس GIN بحيث لا تتم فهرسة مستند JSON بأكمله ، ولكن فقط الجزء الضروري منه. في كثير من الحالات ، سيقلل هذا بشكل جذري من حجم الفهارس. لكن هذا العمل لا يزال يتعين القيام به.

فكرة أوليغ بارتونوف ، تنفيذ نيكيتا جلوخوف والكسندر كوروتكوف (جميع Postgres Professional الثلاثة).

<-> و(مربع، ونقطة واحدة) المشغل
أضاف أضيف العملية في عداد المفقودين لاستخدامها في KNN ل. GIST و SP-جوهر . في PG12 عند العمل مع أنواع هندسية pointوboxيمكنك استخدام عامل تشغيل المسافة <->(point, box)، وسوف يسرع البحث باستخدام فهارس GiST و SP-GiST. لكن العامل المتماثل له <->(box, point)لم يتم تنفيذه ، على الرغم من أنه boxفهم بالفعل المسافات إلى أنواع أكثر تعقيدًا - المضلعات والدوائر.

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

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

:    : box <-> point

إذا كان العكس صحيحًا ، فكل شيء على ما يرام:

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

وفي 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

سيتم تسريع مؤشرات GiST و SP-GiST في هذه العملية.

لاحظ أنه في PG13 ، إذا سألت:

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

وإذا فعلنا الشيء نفسه في PG12 ، نحصل على 20 إدخالًا: في الإصدار الثالث عشر ، تم تجديد القائمة بما يصل إلى 8 عوامل تشغيل.

جسون


دعم طريقة .datetime () لـ jsonpath

هذه إحدى التصحيحات غير الناجحة لسلسلة كبيرة من تصحيحات JSONPath التي لم يكن لدى PG12 وقت لإكمالها. جزء من معيار JSON / SQL. كانت المشكلة أن جميع وظائف سلسلة التصحيح JSONPath غير قابلة للتغيير ، ولكن مقارنة التاريخ تأخذ في الاعتبار المنطقة الزمنية الحالية ، والتي يمكن أن تتغير خلال الجلسة.

في مثل هذه الحالات ، نسمح للوظائف الثابتة غير القابلة للتغيير بإلقاء خطأ حول المقارنات غير الثابتة. في الوقت نفسه ، يحتوي هذا التصحيح على وظائف مع اللاحقة _tz التي تعمل بثبات في العمليات مع المنطقة الزمنية.

وظيفة جديدة - دالة jsonb_set_lax

بشكل عام ، التراخي هو وضع غير صارم (بخلاف صارم) لتشغيل الوظائف مع jsonb. في هذه الحالة ، ستكون هذه الوظيفة جاهزة للعمل في موقف تكون فيه إحدى الحجج التي تأخذها هي NULL. على عكس النسخة الصارمة - jsonb_set () - لديها حجة إضافية تشير إلى الإجراءات في حالة NULL. الخيارات: use_json_null / lift_exception / return_target / delete_key. الخيارات المقترحة من قبل المستخدمين المهتمين.

الأمثل بعض الوظائف jsonb.

محسنة كثيرا.، بشكل رئيسي من خلال جهود نيكيتا جلوخوف (Postgres Professional). ولكن تحليل كل نقطة في هذه الحالة لا طائل من ورائه: أولاً ، سوف تؤدي وفرة هذه المواد إلى تضخيم مقالة قصيرة بالفعل ؛ وثانيًا ، تتعلق التغييرات بالجهاز الداخلي ، وليس كل مستخدم مهتمًا. لذلك ، سنقوم بإدراج معظمها فقط:

  1. وظيفة محسنة JsonbExtractScalar () ؛
  2. عامل مُحسَّن # >> ، وظائف jsonb_each_text () ، jsonb_array_elements_text () ؛
  3. تم تحسين التعرف على نوع JsonbContainer في get_jsonb_path_all () ؛
  4. يتم إحضار أول رمز مميز من مكرر JsonbIterator بواسطة الماكرو خفيف الوزن JsonbContainerIsXxx () ؛
  5. استخراج مفتاح أكثر ملاءمة - findJsonbKeyInObject () ؛
  6. تخزين محسّن لنتائج findJsonbValueFromContainer () و getIthJsonbValueFromContainer () ؛
  7. get_jsonb_path_all(), ;
    JsonbValueAsText.

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


pgbench


تلقت الأداة المساعدة لتشغيل اختبارات الأداء سلسلة من التحسينات. كانت هناك إحصائيات حول تنفيذ المهام في مرحلة التهيئة ، واستنتاج أكثر وضوحًا ، والقدرة على رؤية رمز النصوص البرمجية المضمنة ، والاختبار على جدول مقسم للحسابات.

بالإضافة إلى ذلك ، أضفنا أمرًا \asetمشابهًا لـ \gset، ولكن مع السماح بتعيين قيم لمتغيرات عدة طلبات مرسلة في المرة الواحدة. يقوم السطر التالي ، المرسل إلى الخادم للتنفيذ ، بتعيين المتغيرات oneو two:
SELECT 1 AS one \; SELECT 2 AS two \aset

pg_dump


تعلمت pg_dump تفريغ البيانات من جداول الطرف الثالث . من خلال المعلمة ، --include-foreign-dataيمكنك تحديد قائمة بخوادم الجهات الخارجية ، سيتم إلغاء تحميل البيانات من جداولها.

استخدم هذا التفريغ بعناية. بعيدًا عن حقيقة أنه يجب تحميل البيانات إلى خادم جهة خارجية. بالإضافة إلى ذلك ، من المحتمل جدًا ألا يكون خادم جهة خارجية متاحًا أثناء الاسترداد. أو يمكن أن يسمح خادم جهة خارجية بالقراءة فقط ، وليس كتابة البيانات.

psql


سلسلة من البقع الصغيرة تجعل psql أكثر راحة:

  • تم تحسين علامة التبويب للعديد من الفرق.
  • بالإضافة إلى \echoإرسال سلسلة إلى STDOUT ، \warnيرسل أمر جديد سلسلة إلى إخراج الخطأ القياسي (STDERR).
  • \d toast- . \d+ .
  • \dt+ «Persistence» (unlogged) (permanent).
  • \e , ; ( \g*). , psql .
  • . PROMPT1 PROMPT2 %x.
  • أوامر جديدة لمزيد من المعلومات حول طرق الوصول: \dAc، \dAf، \dAo، ،\dAp
  • يمكنك \gالآن تحديد أي خيارات مدعومة بين قوسين \pset. سيعملون فقط على الفريق الحالي.


libpq


تغييرات طفيفة فيما يتعلق بـ PostgreSQL:
  • \conninfoتم إصلاح عدم الدقة في وصف معلمات host و hostadr وعدم الاتساق الناتج في إخراج الأمر psql الأداة المساعدة.
  • إذا تم تخزين مفتاح شهادة العميل في نموذج مشفر ، فيمكنك إدخال كلمة المرور في الوضع التفاعلي فقط. تسمح لك معلمة sslpassword الجديدة بفك تشفير المفتاح بشكل غير تفاعلي.
  • تسمح لك معلمتان جديدتان ، sslminprotocolversion و sslmaxprotocolversion ، بتحديد تقييد على إصدار بروتوكول SSL / TCL الذي يُسمح بالاتصال به.

reindexdb


تعين المعلمة --jobs الجديدة للأداة المساعدة reindexdb عدد اتصالات قاعدة البيانات التي سيتم إعادة بناء الفهارس فيها في نفس الوقت.

pg_rewind


يتم إزالة قيود الأداة تدريجياً ، وتزداد الاحتمالات.
أولاً ، يمكن لـ pg_rewind الآن تسجيل المعلومات لاستردادها (كما يمكن أن تفعل pg_basebackup ذلك) ، وكذلك بدء الاسترداد وإيقاف التشغيل لاحقًا لمثيل إذا لم يتم إيقافه من خلال نقطة تفتيش (كان يجب القيام بذلك يدويًا من قبل).

وثانيًا ، تعلمت pg_rewind العمل مع أرشيف WAL .
بعد أن تعثر الأداة على نقطة اختلاف WAL بين الخادمين ، يجب أن تبني قائمة بجميع الصفحات التي يجب نسخها إلى الكتلة الهدف لإزالة الاختلافات. لهذا ، تتطلب الأداة جميع ملفات WAL ، بدءًا من النقطة التي تم العثور عليها. إذا لم تكن ملفات WAL الضرورية متاحة على الكتلة الهدف ، فلن تتمكن الأداة من أداء عملها من قبل.

باستخدام هذا التصحيح من Alexey Kondratov (Postgres Professional) ، ستتمكن pg_rewind من قراءة مقاطع WAL المفقودة من أرشيف ملفات السجل باستخدام المعلمة Rest_command إذا تم تحديد مفتاح جديد - c أو --restore-target-wal.

pg_waldump


ستقوم pg_waldump بفك تشفير سجل المعاملات المعد.

فحص


لقد تعلم ملحق amcheck أن يتعرف بشكل أفضل على الضرر في فهارس B-tree.
بالمناسبة ، ستختلف الآن الرسائل الموجودة في سجل الخادم حول الصفحات التالفة عن الفهارس والجداول .

الصفحة


تقوم heap_tuple_infomask_flagsدالة امتداد pageinspect بفك تشفير قيم الحقول infomask ويتم infomask2إرجاعها بواسطة الوظيفة heap_page_items. مفيد في التحقيق في حالات تلف البيانات.

postgres_fdw


يمكن للمستخدم الخارق على مستوى تعيين اسم المستخدم السماح للمستخدمين العاديين باستخدام اتصال بدون كلمة مرور:

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

يتم ذلك ، من بين أمور أخرى ، بحيث يمكن استخدام sslkey و sslcert كمعلمات اتصال .

adminpack


ملحق adminpack لديه ميزة جديدة - pg_file_sync. باستخدامه ، يمكنك إجراء fsync للملفات التي كتبها الخادم إلى القرص ، على سبيل المثال ، عبر pg_file_writeأو COPY TO.

المراقبة


pg_stat_slru


في الذاكرة المشتركة للخادم ، لا يوجد فقط ذاكرة تخزين مؤقت كبيرة ، ولكن أيضًا عدد من ذاكرة التخزين المؤقت الأبسط الأخرى (على سبيل المثال ، لحالة المعاملة). يستخدمون خوارزمية بسيطة لتزاحم الصفحات الأقل استخدامًا (بسيطة الأقل استخدامًا مؤخرًا ، أو SLRU). حتى الآن ، "عملت ذاكرة التخزين المؤقت هذه" للتو ، ولكن كانت هناك حاجة لمراقبتها ، في المقام الأول لمطوري نواة PostgreSQL لمعرفة ما إذا كان هناك شيء يجب تغييره فيه. لهذا الغرض والغرض ، ظهرت رؤية جديدة لـ pg_stat_slru .

pg_stat_activity


في طريقة العرض، و pg_stat_activity عمود جديد هو leader_id. بالنسبة للعمليات المشاركة في الطلبات المتوازية ، يتم ملؤها برقم العملية الرائدة. والعملية الرائدة leader_idهي رقم العملية pid.
يوضح الاستعلام التالي الاستعلامات والعمليات التي يتم تشغيلها حاليًا بالتوازي:

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;

هناك تغييرات في قائمة أحداث الانتظار. تمت إضافة حدثين جديدين : BackupWaitWalArchiveو RecoveryPause. وكان يطلق عليها أسماء اثنين آخرين أكثر دقة: RecoveryWalStream -> RecoveryRetrieveRetryInterval، RecoveryWalAll -> RecoveryWalStream.

و حدثين الانتظار أكثر الجديدة التي تحدث في النسخة المتماثلة : RecoveryConflictSnapshot(صراع مع الفراغ، الذي حذف إصدار الضرورية للصفوف) و RecoveryConflictTablespace(الصراع تتعلق إزالة مساحة الجدول).

pg_stat_statements


حتى الآن ، pg_stat_statementsتعامل الامتداد مع الطلبات بعبارة FOR UPDATEأو بدونها مثل الطلب نفسه. الآن FOR UPDATE يتم تسجيل الطلبات بشكل منفصل .

زادت كمية المعلومات التي تم جمعها. من الآن فصاعدًا ، لا يتم تسجيل المعلومات المتعلقة بالموارد لتنفيذ الأوامر فحسب ، بل أيضًا إحصاءات عن إدخالات دفتر اليومية التي تم إنشاؤها . أعمدة العروض التقديمية الجديدة: wal_bytes- حجم السجلات التي تم إنشاؤها ، wal_records- عدد السجلات التي تم إنشاؤها ، wal_num_fpw- عدد صور الصفحة الكاملة (يكتب صفحة كاملة).

وقد تم ذلك بفضل البنية التحتية المعدة لتتبع استخدام WAL. لذلك ، الآن EXPLAINمع خيار جديد WALسيظهر حجم السجلات التي تم إنشاؤها:

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)

الإضافة auto_explain، VACUUMs VERBOSE، autovacuumوأيضاً استخدام البنية التحتية التي تم إنشاؤها وستخرج أحجام WAL.

نعود إلى pg_stat_statements. إذا تم تمكين المعلمة الجديدة pg_stat_statements.track_planning ، فسيتم تسجيل إحصائيات إضافية تتعلق بالمجدولة لكل مشغل: عدد إصدارات الخطة ؛ إجمالي وقت التخطيط ؛ الوقت الأدنى والأقصى للتخطيط واحد ، وكذلك المتوسط ​​والانحراف المعياري.

ينعكس احتساب الموارد المخصصة للجدولة في تصحيح آخر لا علاقة له pg_stat_statements. EXPLAINمع الخيار BUFFERSسيبلغ عدد المخازن المؤقتة المستخدمة في مرحلة التخطيط :

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

مجلة


  • 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, , .
  • يمكنك الآن كتابة نوع العملية ( pg_stat_activity.backend_type) في سجل الخادم . لهذا log_line_prefix، يتم توفير رمز خاص في المعلمة %b. وإذا تمت كتابة السجل بتنسيق csv ( log_destination=csvlog) ، فسيتم backend_typeتضمين العمود بالفعل هناك.


تقدم


رؤى جديدة pg_stat_progress_analyzeأيضا pg_stat_progress_basebackupيسمح لك لتتبع التقدم المحرز في جمع الإحصاءات من قبل فريق ANALYZEو إنشاء نسخة احتياطية من فائدة، pg_basebackupعلى التوالي.

الاقوي


حساب الدالات غير القابلة للتغيير في بند FROM في مرحلة التخطيط
يساعد التصحيح الخاص بآليكسندر كوزمينكوف وأليكسندر بارفيونوف (كلاهما من Postgres Professional) في الحالات التيFROMتحتويفيهاالمكالمة على استدعاء دالة يكون في الواقع ثابتًا. في هذه الحالة ، بدلاً من إجراء الاتصال ، يتم استبدال القيمة الثابتة في الأماكن الضرورية للطلب.

إليك كيفية حدوث ذلك بمثال استعلام يتعلق بالبحث عن نص كامل:

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)

لا يوجد اتصال ، ويتم استبدال القيمة 'tuple' :: tsquery في الاستعلام الموجود بالفعل في مرحلة التخطيط. كان للإصدار 12 صورة مختلفة تمامًا:

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)


الفرز التزايدي

عند الحاجة إلى الفرز حسب العديد من المفاتيح (k1 ، k2 ، k3 ...) ، يمكن للجدولة الآن الاستفادة من معرفة أن البيانات قد تم فرزها بالفعل من خلال العديد من المفاتيح الأولى (على سبيل المثال ، k1 و k2). في هذه الحالة ، لا يمكنك إعادة ترتيب جميع البيانات مرة أخرى ، ولكن تقسيمها إلى مجموعات متتالية بنفس القيم k1 و k2 و "الفرز" بالمفتاح k3.

وهكذا ، ينقسم التصنيف بالكامل إلى عدة أنواع متتالية من الحجم الأصغر. هذا يقلل من كمية الذاكرة المطلوبة ، ويسمح لك أيضًا بإعطاء البيانات الأولى قبل اكتمال جميع الفرز.

على سبيل المثال ، في demobase على جدول التذاكر ، يوجد فهرس في العمود Tick_id. سيتم فرز البيانات المتلقاة من الفهرس بواسطة Tick_id ، لذلك سيستخدم الاستعلام التالي الفرز التدريجي:

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

يمكن تعطيل وظيفة الفرز التزايدي باستخدام معلمة Enable_incrementalsort. في هذه الحالة ، سيستغرق الفرز وقتًا أطول بشكل ملحوظ:

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

تم اقتراح فكرة التصنيف التدريجي مرة أخرى في عام 2013 من قبل ألكسندر كوروتكوف (Postgres Professional) ، والآن ، بعد سبع سنوات ، أحضر جيمس كولمان التصحيح إلى دولة قبلها المجتمع.

TRUNCATE تسريع
عند TRUNCATEحدوث المسح shared_buffersلإزالة المخازن المؤقتة الجدول من الذاكرة المشتركة. في السابق ، تم إجراء المسح ثلاث مرات ، لكل طبقة جدول: MAIN (طبقة البيانات الرئيسية) ، FSM (خريطة المساحة الحرة) ، VM (خريطة الرؤية). الآن تغير المنطق ، بدلاً من التشغيل الثلاثي ، يتم فحص المخازن المؤقتة مرة واحدة فقط. مع القيم الكبيرة ، shared_buffersهذا يعطي مكاسب ملموسة.

تخفيف الضغط الجزئي
عندما لا تكون هناك حاجة لقراءة توست تمامًا ، وقصرها على شريحة في البداية أو بالقرب من البداية ، فمن غير المنطقي فكها تمامًا. يُقرأ التوست المضغوط في التكرارات: اقرأ قطعة ، إذا لم تكن هناك بيانات ضرورية ، فقم بتوسيعها وقراءتها. تم اقتراحه بواسطة أحد طلاب Google Summer of Code ، Binguo Bao ، الذي يقدم مثالًا:

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

مع التصحيح ، ترتيب حجم أسرع:

Time: 2.306 ms

الفراغ المتوازي
في مقاله حول هذا الموضوع ، يشرح إيجور روجوف بالتفصيل هذه الخطوة المهمة في التوازي. باختصار: “Patch Masahiko Sawada ، الذي يسمح لك بإجراء التنظيف بالتوازي. لا يزال يتم مسح الجدول نفسه من خلال عملية واحدة (رائدة) ، ولكن لتنظيف الفهارس ، يمكنه الآن بدء سير عمل الخلفية ، واحد لكل فهرس. في الوضع اليدوي ، يتيح لك هذا تسريع تنظيف الجداول الكبيرة بفهارس متعددة ؛ التنظيف التلقائي لا يستخدم هذه الميزة حتى الآن. "

التنظيف التلقائي عند اللصق في طاولة
بالنسبة إلى هذا التصحيح (المعروف أيضًا باسم Berserk auto-vacuum) ، نحتاج إلى شكر Dorofei Proleskovsky ، التي اقترحت حلاً للمشكلة التالية: لا يأتي التنظيف التلقائي إلى جدول الإلحاق فقط ، لأنه ليس لديهم إصدارات "ميتة" من الصفوف. وبسبب هذا ، لا يتم تحديث خريطة الرؤية ، مما يجعل عمليات المسح فقط على الفهرس فقط غير فعالة ، وعندما يأتي التنظيف لمنع تجاوزات عداد المعاملات ، فإنه يحتاج إلى القيام بالكثير من العمل في وقت واحد. الآن تم إصلاح هذا الموقف: التنظيف التلقائي سيعمل أيضًا على إضافة خطوط. ظهرت معلمتان جديدتان للخادم ( autovacuum_vacuum_insert_thresholdو autovacuum_vacuum_insert_scale_factor) ، على غرار معلمات التعديلات ( autovacuum_vacuum_thresholdو autovacuum_vacuum_scale_factor).

تجزئة إدارة الذاكرة
قد تتطلب تجزئة تجميع RAM أكثر من الفكر جدولة ومما هو مذكور في work_mem. في السابق ، أدى مثل هذا الخطأ في المجدول إلى حقيقة أنه تم work_memتجاهل الحجم وتم تخصيص الذاكرة بقدر الحاجة لتشغيل أو وصول OOM Killer. الآن قد لا تتجاوز الخوارزمية work_mem، وإذا لزم الأمر ، استخدم الملفات المؤقتة على القرص. للتحكم في سلوك المجدول ، ظهرت المعلمات التالية: enable_groupingsets_hash_diskو enable_hashagg_disk.

تحسين UPDATE للجداول مع الأعمدة التي تم إنشاؤها
في الإصدار 12 ، تم إعادة حساب الأعمدة التي تم إنشاؤها أثناء أي تحديث للصف ، حتى لو لم يؤثر هذا التغيير عليها بأي شكل من الأشكال. الآن سيتم إعادة حسابها فقط عندما تكون هناك حاجة إليها حقًا (إذا تغيرت أعمدتها الأساسية).

هذا التحسين ، على سبيل المثال ، يمكن أن يسرع بشكل كبير تحديث الجداول بعمود من النوع الذي تم إنشاؤه tsvector، لأن الوظيفة to_tsvector()مكلفة للغاية.

الوصول من المشغل إلى قائمة الأعمدة المتغيرة
تصحيح صغير يضيف TriggerDataصورة نقطية للأعمدة المتغيرة إلى الهيكل . يمكن استخدام هذه المعلومات من خلال وظائف الزناد العامة ، مثل ، tsvector_update_trigger()أو lo_manage()حتى لا تقوم بعمل غير ضروري.

استخدام العديد من الإحصائيات المتقدمة عند التقييم
في PG12 ، لم يتمكن المجدول من استخدام العديد من الإحصائيات المتقدمة للجدول نفسه في نفس الوقت. على سبيل المثال ، تخيل موقفًا يتم فيه إنشاء إحصائيتين متقدمتين لمجموعات مختلفة من الأعمدة ، والأعمدة من مجموعة ومن مجموعة أخرى تشارك في الاستعلام. الآن يمكن للمخطط الوصول إلى جميع المعلومات المتاحة.

البنية التحتية للتوازي والنسخ (انظر أيضًا هذا التصحيح. )
التزامن PostgreSQL لا يزال يعمل للاستعلامات للقراءة فقط. هناك صعوبات مع الكتاب ، أحدهم هو عمليات الحجب التي تؤدي في نفس الوقت مهمة واحدة (مدرجة في مجموعة موازية مشتركة). يُعتقد أن أقفال مثل هذه العمليات لا تتعارض - على سبيل المثال ، يمكن لعدة عمليات الاحتفاظ بقفل حصري على نفس الجدول. يتطلب هذا عناية خاصة من مطوري kernel ، ولكن بخلاف ذلك سيكون لديهم باستمرار جمود.
ولكن هناك استثناءان:

  • تأمين امتداد العلاقة ، والذي يتم التقاطه عند إضافة صفحات جديدة إلى نهاية ملف البيانات ، و
  • قفل الصفحة ، والذي يُستخدم عند نقل عناصر فهرس GIN من قائمة الانتظار إلى الشجرة الرئيسية.

(يمكنك قراءة المزيد في هذه المقالة. )
يجب أن تتعارض هذه الأقفال حتى بين عمليات نفس المجموعة الموازية - التي تنفذ هذا التصحيح. لكن هذه الأقفال لا يمكن أن تؤدي إلى جمود ، لذلك يتم استبعادها من الفحص.

بالنسبة للمستخدم ، بشكل عام ، لا يتغير شيء ، ولكن هذا التصحيح مهم لأنه ، أولاً ، يمهد الطريق لإدخال ونسخ متوازيين ، وثانيًا ، يزيل أحد اختناقات PostgreSQL في ظل ظروف تحميل عالية (والتي يمكن سماعها في التقرير HL ++ ).

سلامة


استبدلت نماذج SKH PRH استبدال استبدال
EDH (مفاتيح Diffie-Hellman سريعة الزوال) باستخدام بروتوكول SKIP البائد الآن.

initdb: تم تغيير الإعدادات الافتراضية للمصادقة
تم تغيير إعدادات الوصول الافتراضية للاتصالات المحلية والشبكات عند بدء initdb. الآن فيpg_hba.confالاتصالات المحلية بدلاً من طريقة المصادقةtrustستكونpeer(أو md5 إذا لم يكن النظير مدعومًا) ،md5واتصالات الشبكة. في البداية ، نوقشت تدابير أكثر ليبرالية: تحذير في الوثائق. ثم أكثر صرامة:scram-sha-256. نتيجة لذلك ، قررنا أن نقتصر علىpeerوmd5.

باستخدام clear_bzero
تصحيح هام. يعمل نظاما التشغيل bzero () و صريحة_ bzero () بكتابة وحدات بايت تحتوي على مناطق الذاكرة المشار إليها '\0'(انظر ، على سبيل المثال ، Linux). هذه التصحيحات ليست سوى البداية: هناك العديد من أقسام الذاكرة التي يمكن أن تبقى فيها كلمات المرور والمعلومات الحساسة الأخرى. قررنا البدء من أماكن مثل libpq ، حيث يمكن أن يظل الملف بأكمله الذي يحتوي على كلمات المرور في الذاكرة بعد قراءة .pgpass ، ومن التنظيف بعد إغلاق الاتصال. في be-secure-common.c يوجد الآن استبدال للكتابة السرية التي تم إدخالها في SSL ، والتي تظهر في سطر (مسار) الخطأ.

تمت إضافة معلمة "password_protocol" إلى libpq
يسمح هذا التصحيح لـ libpq بالتحكم في بروتوكول نقل كلمة المرور المستخدم أثناء الاتصال. بعد استلام هذه المعلمة ، سيرفض libpq المصادقة إذا كان البروتوكول أضعف من البروتوكول المحدد. بشكل افتراضي ، هذه المعلمة plaintext، أي جميع البروتوكولات مناسبة.

الوصول الإلزامي لـ TRUNCATE
يتيح هذا التصحيح امتدادات لتضمين التحكم في الوصول الإلزامي (MAC) لعملية TRUNCATE. سيتم التحقق من حقوق ذلك الآن بواسطة ملحق sepgsql . لا تدعم السياسة المرجعية لـ SELinux وتوزيعات Linux القائمة على Redhat تدقيق SELinux على db_table {truncate}. في هذه الحالة ، سيتم استخدام sepgsql مع 'deny_unknown' يساوي 1 ، وسيفشل TRUNCATE.

توفر GUC ssl_passphrase_command
رقعة بسيطة ولكنها مفيدة. لن تظهر قيمة المعلمة ssl_passphrase_command إلا بواسطة المستخدم الخارق. تحدد المعلمة أمرًا خارجيًا يتم استدعاؤه عندما تكون كلمة المرور مطلوبة لفك تشفير ملف SSL ، على سبيل المثال ، مفتاح خاص.

الموقع


قواعد ترتيب النسخ libc
بالنسبة لقواعد ترتيب وحدة العناية المركزة ، يتم تخزين أرقام الإصدارات في قاعدة البيانات. في كل مرة يتم استخدام القاعدة (الفرز ، مقارنة الأحرف) ، يتم التحقق من رقم الإصدار المحفوظ مع الإصدار الحالي في مكتبة ICU في نظام التشغيل ، وفي حالة وجود اختلافات ، يتم إصدار تحذير. يتيح لك هذا العثور على بعض الفهارس التي تم إنشاؤها وفقًا لقواعد الفرز المعدلة قد تكون غير صحيحة ويجب إعادة بنائها. من خلال إعادة بناء الفهارس بالأمرALTER COLLATION ... REFRESH VERSION، يتم تحديث إصدار قاعدة الفرز في قاعدة البيانات ولم تعد التحذيرات تصدر.

لكن ذلك كان فقط لوحدة العناية المركزة. يتم الآن تخزين رقم الإصدار لقواعد الفرز libc:

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

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

مما يجعل من الممكن إصدار تحذيرات عند تغيير مكتبة في نظام التشغيل. وثيق الصلة للغاية في ضوء الانتقال إلى glibc 2.28 ، حيث تغيرت العديد من قواعد الفرز ، ويجب إعادة بناء الفهارس المقابلة.

ولكن حتى تحولوا إلى 2.28 ، كل شيء هادئ:
ALTER COLLATION "ru_RU" REFRESH VERSION;

NOTICE:  version has not changed
ALTER COLLATION

بحث النص الكامل


بحث النص الكامل للغة اليونانية
لا يوجد تعليقات.

تعلمت dict_int كيفية التعامل مع القيم المطلقة.
أضاف قاموس قالب dict_int (ويعرف أيضًا باسم الملحق) القدرة على إزالة العلامة من رقم.


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)

أي هذه المرة تم الاعتراف بالقيمة المطلقة.

التقسيم


قبل
تشغيل الصفBEFOREعلى جدول مقسمفي الإصدار 12 ، لا يمكنك إنشاء مشغلات الصفعلى جدول مقسم. في أقسام منفصلة - من فضلك ، ولكن ليس على الطاولة بأكملها مرة واحدة. الآن ،BEFORE FOR EACH ROWسيتم توريث المشغل الذي تم إنشاؤه على جدول مقسم تلقائيًا وسيعمل لجميع الأقسام. ولكن بشرط أنه إذا تم تشغيلهUPDATE، فيمكن تغيير مفتاح القسم الموجود فيه فقط داخل القسم الحالي.

دعم الجداول المقسمة في النسخ المتماثل المنطقي
سابقًا ، تسبب تضمين جدول مقسم في منشور في حدوث خطأ:

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.

الآن يعمل.

خوارزمية JOIN مقطعية محسنة
بدءًا من الإصدار 11 ، يمكن للجدولة الانضمام إلى الجداول المقسمة قسمًا تلو الآخر ، ولكن فقط إذا كانت حدود الأقسام تتطابق تمامًا. الآن تم تحسين الخوارزمية: ستعمل إذا تم تضمين قسم جدول واحد بالكامل في قسم جدول آخر ، حتى إذا لم تتطابق أحجامها (على سبيل المثال ، إذا تم تقسيم جدول حسب اليوم والآخر حسب الشهر). تعمل الخوارزمية الجديدة على التقسيم حسب النطاقات والقوائم.

الانقسام الاقسام الكاملة يعمل الانقسام الاقسام
الان على الوصلات الخارجية الكاملة المسجلة بعبارة USING.

مفرش المائدة


في هذه المنطقة الجذابة والواعدة ، ولكن الصعبة ، لا توجد تطورات جذرية فيما يتعلق بـ PostgreSQL 12. لا توجد مخازن تخزين جاهزة مثل zheapأخرى مثل الكومة) ، ولكن العمل مستمر على واجهة برمجة التطبيقات.

مستوى أعلى من التجريد في تحديد حجم الجدول قام
روبرت هاس بإعادة كتابة الكود ، وتغيير بنيته لصالح الطبقات المجردة ، حتى لا يتم تكرار الكود في المستقبل. تشير هذه القطعة إلى estimate_rel_size- حجم طبقات (شوكات) الجدول.

يمكنك استخدام طرق الوصول إلى الجدول مع relcache.
يجلب هذا التصحيح إمكانات إدارة الذاكرة لطرق الوصول إلى الجدول إلى إمكانات طرق الفهرس.

تم تصميم tableam و TOAST TOAST
إلى حد كبير للتخزينheapلذلك ، عند إنشاء طرق جديدة للوصول إلى الجدول ، يمكنك الذهاب بطريقتين: مساعدة مطوري الطرق الجديدة على دمج إدراج سجلات TOAST وتحديثها وحذفها أو تفويض العمل باستخدام TOAST لوضع التعليمات البرمجية باستخدام تخزين PostgreSQL التقليدي - كومة الذاكرة المؤقتة. سلسلة من 5 تصحيحات تستخدم فتحات tuple لتنفيذ عمليات الإدراج / التحديث / الحذف ويمكن أن تساعد تلك التي تسير في كلا الاتجاهين.

المزامنة


معالجة أخطاء fsync في pg_receivewal و pg_recvlogical
تستمر المعركة ضد fsync () . يعتقد PostgreSQL أن المكالمة الناجحة fsync () تعني أن جميع البيانات الموجودة في الملف قد تم نقلها إلى القرص ، ولكن هذا لا يحدث دائمًا (يعتمد على نظام التشغيل) وقد يؤدي إلى فقدان البيانات. قررت PG13 أنه من الضروري التعامل مع المرافقpg_receivewalوpg_recvlogical. السلوك الافتراضي حاليًا هو ما يلي: ستقوم هذه الأدوات المساعدة بكتابة أخطاء fsync إلى السجلات ، واستعادة الاتصال والمتابعة كما لو لم يحدث شيء. ونتيجة لذلك ، تحتوي WAL على معلومات حول الملفات التي تم نسخها بنجاح ، والتي في الواقع لم يتم نقلها إلى القرص بشكل صحيح. لذا من الأفضل مقاطعة الأداة. كما تمت مناقشة مصير pg_dump و pg_basebackup و pg_rewind و pg_checksums ، ولكن حتى الآن اقتصروا على هذين الأمرين.

حماية ضد تعيين إشارات غير صحيحة لـ fsync ()
يتحقق هذا التصحيح إذا تم تعيين العلامات بشكل صحيح عند تلقي واصف الملف لـ fsync () - الدلائل مفتوحة للقراءة فقط ، وملفات للكتابة أو كليهما.

النسخ الاحتياطي والتكرار


توقف مؤقتًا أثناء الاسترداد قبل الوصول إلى نقطة الاسترداد
إذا انتهت WALs أثناء الاسترداد ، لكنهاrecovery_target_timeلم تصل إلى المستوىالمحدد، يكمل الخادم الاسترداد ويتحول إلى وضع التشغيل العادي. الآن لن يكون الأمر كذلك. ستتوقف عملية الاسترداد مؤقتًا ، كما هو مذكور في السجل ، وستتاح للمشرف الفرصة لإدراج شرائح WAL المفقودة ومتابعة الاسترداد.

معلمة ignore_invalid_pages
عندما تعثر عملية الاسترداد على نسخة متماثلة على ارتباط إلى صفحة غير صالحة في سجل WAL ، يحدثpanic-a. سيساعد إدراج المعلمة على التغلب عليها.ignore_invalid_pages. سيستمر التعافي مع احتمال فقدان السلامة والبيانات وغيرها من العواقب الأكثر خطورة. تم إعداد المعلمة لمطوري الخادم ويجب استخدامها في تلك الحالات عندما لا تزال بحاجة إلى محاولة إكمال الاسترداد وبدء النسخة المتماثلة.

تغيير primary_conninfo دون إعادة تشغيل
التصحيح سيرغي كورنيلوف، والذي يسمح لك بتغيير الإعدادات primary_conninfo، primary_slot_nameو wal_receiver_create_temp_slotبدون إعادة تشغيل الملقم. في الواقع ، من أجل ذلك ، تركوا الملف recovery.confفي الإصدار الثاني عشر. تقوم قوائم

النسخ الاحتياطي
Pg_basebackup الآن بإنشاء "بيان" - ملف JSON يحتوي على معلومات حول النسخ الاحتياطي الذي تم إنشاؤه (أسماء الملفات وأحجامها ، وملفات WAL الضرورية ، بالإضافة إلى المجموع الاختباري لكل شيء وكل شيء).
تتحقق الأداة المساعدة pg_validatebackup الجديدة من النسخ الاحتياطية للتوافق مع البيان ، وتتحقق أيضًا من توفر وصحة ملفات WAL اللازمة للاسترداد باستخدام الأداة pg_waldump (ينطبق هذا فقط على ملفات WAL داخل النسخة الاحتياطية نفسها ، وليس في الأرشيف).
سيسمح لك هذا باكتشاف المواقف التي تعرضت فيها ملفات النسخ الاحتياطي للتلف أو الاختفاء ، أو عندما أصبح الاسترداد مستحيلًا بسبب نقص ملفات السجل الضرورية.

تحديد فتحة النسخ المتماثل للبيانات غير المقروءة تعد فتحة النسخ المتماثل
آلية مناسبة ولكنها خطيرة: إذا لم يقرأ العميل البيانات من الفتحة في الوقت المحدد ، يمكن أن تشغل سجلات WAL غير المقروءة كل المساحة على الخادم. الآن باستخدام المعلمةmax_slot_wal_keep_sizeيمكنك تعيين حد أقصى من مساحة القرص التي يمكن أن تشغلها البيانات غير المقروءة. إذا تبين عند نقطة التفتيش التالية أنه تم تجاوز الحجم ، يتم تعطيل الفتحة ، ويتم تحرير المكان.

شبابيك


دعم مآخذ Unix على Windows Unix-
مآخذ المجال مدعومة على Windows 10 ، على الرغم من أنها معطلة بشكل افتراضي.

توثيق


هناك تطبيقان جديدان في الوثائق.
بعد مناقشة طويلة ، ظهر الملحق م . يوجد حاليا 101 مصطلح في المسرد.

كانت القدرة على إبراز لون الرسائل التشخيصية للأدوات المساعدة لوحدة التحكم باستخدام متغير PG_COLORسابقًا. تم توثيق هذا الآن في الملحق N. Color Support . كان القصد الأصلي من Peter Eisentrout في هذا التصحيح هو جعل الإخراج الملون قيد التشغيل افتراضيًا. وبالنسبة لأولئك الذين لم يرغبوا في ذلك ، تم اقتراح تعيين المتغير بشكل صريحNO_COLOR. ولكن كان هناك المزيد من المعارضين لتمييز الألوان للرسائل بين أولئك الذين يناقشون التصحيح. لذلك ، قرروا فقط لتوثيق الفرص المتاحة. وحصلنا على قسم جديد من المستوى الأول في التوثيق.



PG13, , PG14 . , . .

All Articles