MVCC-3. Awọn ẹya okun

Nitorinaa, a ti gbero awọn ọran ti o jọmọ idabobo, o si ṣe a padasehin nipa siseto data ni ipele kekere. Ati nikẹhin a wa si apakan ti o nifẹ julọ - awọn ẹya okun.

Akọsori

Gẹgẹbi a ti sọ tẹlẹ, ila kọọkan le wa nigbakanna ni awọn ẹya pupọ ninu aaye data. Ẹya kan gbọdọ jẹ iyatọ bakan lati omiiran, Fun idi eyi, ẹya kọọkan ni awọn ami meji ti o pinnu “akoko” iṣẹ ti ẹya yii (xmin ati xmax). Ni awọn agbasọ - nitori pe kii ṣe akoko bii iru eyi ti o lo, ṣugbọn counter npo pataki kan. Ati pe counter yii jẹ nọmba idunadura naa.

(Gẹgẹbi o ti ṣe deede, otitọ jẹ idiju diẹ sii: nọmba idunadura ko le pọ si ni gbogbo igba nitori agbara iwọn kekere ti counter. Ṣugbọn a yoo wo awọn alaye wọnyi ni awọn alaye nigba ti a ba de didi.)

Nigbati a ba ṣẹda ila kan, xmin ti ṣeto si nọmba idunadura ti o fun ni aṣẹ INSERT, ati pe xmax ti wa ni ofifo.

Nigbati ọna kan ba ti paarẹ, iye xmax ti ẹya ti isiyi jẹ samisi pẹlu nọmba idunadura ti o ṣe PA.

Nigbati ọna kan ba jẹ atunṣe nipasẹ aṣẹ imudojuiwọn, awọn iṣẹ meji ni a ṣe ni otitọ: PA ati FI sii. Ẹya lọwọlọwọ ti kana ṣeto xmax dogba si nọmba idunadura ti o ṣe imudojuiwọn naa. Ẹya tuntun ti okun kanna ni a ṣẹda lẹhinna; iye xmin rẹ ṣe deede pẹlu iye xmax ti ẹya ti tẹlẹ.

Awọn aaye xmin ati xmax wa ninu akọsori ẹya kana. Ni afikun si awọn aaye wọnyi, akọsori ni awọn miiran ni, fun apẹẹrẹ:

  • infomask jẹ lẹsẹsẹ awọn die-die ti o ṣalaye awọn ohun-ini ti ẹya yii. Nibẹ ni o wa oyimbo kan pupo ti wọn; A óò gbé àwọn kókó pàtàkì yẹ̀ wò díẹ̀díẹ̀.
  • ctid jẹ ọna asopọ si atẹle, ẹya tuntun ti ila kanna. Fun tuntun julọ, ẹya lọwọlọwọ ti ila kan, ctid tọka si ẹya yii funrararẹ. Nọmba naa ni fọọmu (x,y), nibiti x jẹ nọmba oju-iwe, y jẹ nọmba atọka ninu titobi.
  • asan bitmap - Ṣe samisi awọn ọwọn wọnyẹn ti ẹya ti a fun ti o ni iye asan (NULL). NULL kii ṣe ọkan ninu awọn iye iru data deede, nitorinaa ẹda naa gbọdọ wa ni ipamọ lọtọ.

Bi abajade, akọsori naa tobi pupọ - o kere ju awọn baiti 23 fun ẹya kọọkan ti laini, ati nigbagbogbo diẹ sii nitori NULL bitmap. Ti tabili ba jẹ "dín" (iyẹn ni, ni awọn ọwọn diẹ ninu), oke le gba diẹ sii ju alaye to wulo lọ.

Fi sii

Jẹ ki a ṣe akiyesi diẹ sii bi awọn iṣẹ ṣiṣe okun-kekere ṣe ṣe, bẹrẹ pẹlu fifi sii.

Fun awọn idanwo, jẹ ki a ṣẹda tabili tuntun pẹlu awọn ọwọn meji ati atọka lori ọkan ninu wọn:

=> CREATE TABLE t(
  id serial,
  s text
);
=> CREATE INDEX ON t(s);

Jẹ ki a fi ọna kan sii lẹhin ti o bẹrẹ idunadura kan.

=> BEGIN;
=> INSERT INTO t(s) VALUES ('FOO');

Eyi ni nọmba idunadura wa lọwọlọwọ:

=> SELECT txid_current();
 txid_current 
--------------
         3664
(1 row)

Jẹ ki a wo awọn akoonu inu oju-iwe naa. Iṣẹ heap_page_items ti ifaagun oju oju-iwe gba ọ laaye lati gba alaye nipa awọn itọka ati awọn ẹya ila:

=> SELECT * FROM heap_page_items(get_raw_page('t',0)) gx
-[ RECORD 1 ]-------------------
lp          | 1
lp_off      | 8160
lp_flags    | 1
lp_len      | 32
t_xmin      | 3664
t_xmax      | 0
t_field3    | 0
t_ctid      | (0,1)
t_infomask2 | 2
t_infomask  | 2050
t_hoff      | 24
t_bits      | 
t_oid       | 
t_data      | x0100000009464f4f

Ṣe akiyesi pe ọrọ okiti ni PostgreSQL tọka si awọn tabili. Eyi jẹ lilo ajeji miiran ti ọrọ naa - a mọ òkiti kan data be, eyi ti ko ni nkankan ni wọpọ pẹlu tabili. Nibi a ti lo ọrọ naa ni itumọ ti "ohun gbogbo ni a dapọ," ni idakeji si awọn atọka ti a ti paṣẹ.

Iṣẹ naa fihan data "bi o ṣe jẹ", ni ọna kika ti o ṣoro lati ni oye. Lati ro ero rẹ, a yoo fi apakan kan ti alaye naa silẹ ki a si pinnu rẹ:

=> SELECT '(0,'||lp||')' AS ctid,
       CASE lp_flags
         WHEN 0 THEN 'unused'
         WHEN 1 THEN 'normal'
         WHEN 2 THEN 'redirect to '||lp_off
         WHEN 3 THEN 'dead'
       END AS state,
       t_xmin as xmin,
       t_xmax as xmax,
       (t_infomask & 256) > 0  AS xmin_commited,
       (t_infomask & 512) > 0  AS xmin_aborted,
       (t_infomask & 1024) > 0 AS xmax_commited,
       (t_infomask & 2048) > 0 AS xmax_aborted,
       t_ctid
FROM heap_page_items(get_raw_page('t',0)) gx
-[ RECORD 1 ]-+-------
ctid          | (0,1)
state         | normal
xmin          | 3664
xmax          | 0
xmin_commited | f
xmin_aborted  | f
xmax_commited | f
xmax_aborted  | t
t_ctid        | (0,1)

Eyi ni ohun ti a ṣe:

  • Fi odo kan kun nọmba atọka lati jẹ ki o dabi kanna bi t_ctid: (nọmba oju-iwe, nọmba atọka).
  • Ti ṣe ipinnu ipo ti itọka lp_flags. Nibi o jẹ "deede" - eyi tumọ si pe itọka gangan n tọka si ẹya ti okun naa. A yoo wo awọn itumọ miiran nigbamii.
  • Ninu gbogbo awọn die-die alaye, awọn orisii meji nikan ni a ti damọ titi di isisiyi. Awọn xmin_committed ati xmin_aborted bits tọkasi boya nọmba idunadura xmin ti ṣe (aborted). Meji iru die-die tọka si idunadura nọmba xmax.

Kini a ri? Nigbati o ba fi ọna kan sii, nọmba atọka 1 yoo han ni oju-iwe tabili, ti o tọka si akọkọ ati ẹya nikan ti ila naa.

Ninu ẹya okun, aaye xmin ti kun pẹlu nọmba idunadura lọwọlọwọ. Iṣowo naa ṣi ṣiṣẹ, nitorina mejeeji xmin_committed ati xmin_aborted bit ko ṣeto.

Awọn kana version ctid aaye ntokasi si kanna kana. Eyi tumọ si pe ẹya tuntun ko si tẹlẹ.

Aaye xmax ti kun pẹlu nọmba idalẹnu 0 nitori ẹya ti ila yii ko ti paarẹ ati pe o wa lọwọlọwọ. Awọn iṣowo kii yoo san ifojusi si nọmba yii nitori xmax_aborted bit ti ṣeto.

Jẹ ki a gbe igbesẹ kan diẹ si ilọsiwaju kika nipa fifi awọn alaye diẹ kun si awọn nọmba idunadura. Ati pe jẹ ki a ṣẹda iṣẹ kan, nitori a yoo nilo ibeere diẹ sii ju ẹẹkan lọ:

=> CREATE FUNCTION heap_page(relname text, pageno integer)
RETURNS TABLE(ctid tid, state text, xmin text, xmax text, t_ctid tid)
AS $$
SELECT (pageno,lp)::text::tid AS ctid,
       CASE lp_flags
         WHEN 0 THEN 'unused'
         WHEN 1 THEN 'normal'
         WHEN 2 THEN 'redirect to '||lp_off
         WHEN 3 THEN 'dead'
       END AS state,
       t_xmin || CASE
         WHEN (t_infomask & 256) > 0 THEN ' (c)'
         WHEN (t_infomask & 512) > 0 THEN ' (a)'
         ELSE ''
       END AS xmin,
       t_xmax || CASE
         WHEN (t_infomask & 1024) > 0 THEN ' (c)'
         WHEN (t_infomask & 2048) > 0 THEN ' (a)'
         ELSE ''
       END AS xmax,
       t_ctid
FROM heap_page_items(get_raw_page(relname,pageno))
ORDER BY lp;
$$ LANGUAGE SQL;

Ni fọọmu yii, o ṣe alaye diẹ sii ohun ti n ṣẹlẹ ninu akọsori ti ẹya ila:

=> SELECT * FROM heap_page('t',0);
 ctid  | state  | xmin | xmax  | t_ctid 
-------+--------+------+-------+--------
 (0,1) | normal | 3664 | 0 (a) | (0,1)
(1 row)

Iru, ṣugbọn alaye ti o kere pupọ, alaye le gba lati tabili funrararẹ, ni lilo awọn ọwọn pseudo xmin ati xmax:

=> SELECT xmin, xmax, * FROM t;
 xmin | xmax | id |  s  
------+------+----+-----
 3664 |    0 |  1 | FOO
(1 row)

Imuduro

Ti idunadura kan ba pari ni aṣeyọri, o nilo lati ranti ipo rẹ - ṣe akiyesi pe o ti ṣe. Lati ṣe eyi, eto kan ti a pe ni XACT ni a lo (ati ṣaaju ẹya 10 ti a pe ni CLOG (igi adehun) ati pe orukọ yii tun le rii ni awọn aaye oriṣiriṣi).

XACT kii ṣe tabili katalogi eto; iwọnyi ni awọn faili inu PGDATA/pg_xact liana. Won ni meji die-die fun kọọkan idunadura: ifaramo ati aborted - o kan bi ninu awọn kana version akọsori. Alaye yii ti pin si ọpọlọpọ awọn faili nikan fun irọrun; a yoo pada si ọran yii nigbati a ba gbero didi. Ati pe iṣẹ pẹlu awọn faili wọnyi jẹ oju-iwe nipasẹ oju-iwe, bii pẹlu gbogbo awọn miiran.

Nitorinaa, nigbati idunadura kan ba ṣe ni XACT, a ti ṣeto bit ifaramo fun idunadura yii. Ati pe eyi ni gbogbo ohun ti o ṣẹlẹ lakoko ṣiṣe (botilẹjẹpe a ko sọrọ nipa iwe igbasilẹ iṣaaju sibẹsibẹ).

Nigbati iṣowo miiran ba wọle si oju-iwe tabili ti a kan wo, yoo ni lati dahun awọn ibeere pupọ.

  1. Njẹ iṣowo xmin ti pari? Ti kii ba ṣe bẹ, lẹhinna ẹya ti o ṣẹda ti okun ko yẹ ki o han.
    Ayẹwo yii ni a ṣe nipasẹ wiwo ọna miiran, eyiti o wa ni iranti ti a pin ti apẹẹrẹ ati pe a pe ni ProcArray. O ni atokọ ti gbogbo awọn ilana ti nṣiṣe lọwọ, ati fun ọkọọkan nọmba ti iṣowo lọwọlọwọ (lọwọ) jẹ itọkasi.
  2. Ti o ba ti pari, lẹhinna bawo ni - nipa ṣiṣe tabi fagile? Ti o ba fagilee, lẹhinna ẹya ila ko yẹ ki o han boya.
    Eyi jẹ deede ohun ti XACT jẹ fun. Ṣugbọn, botilẹjẹpe awọn oju-iwe ti o kẹhin ti XACT ti wa ni ipamọ ni awọn buffers ni Ramu, o tun jẹ gbowolori lati ṣayẹwo XACT ni gbogbo igba. Nitoribẹẹ, ni kete ti a ti pinnu ipo idunadura, o ti kọ si xmin_committed ati xmin_aborted bits ti ẹya okun. Ti ọkan ninu awọn die-die wọnyi ba ṣeto, lẹhinna ipo iṣowo xmin ni a ka pe a mọ ati pe idunadura atẹle kii yoo ni lati wọle si XACT.

Kini idi ti awọn iwọn wọnyi ko ṣeto nipasẹ idunadura funrararẹ n ṣe ifibọ naa? Nigbati ifibọ ba waye, idunadura naa ko iti mọ boya yoo ṣaṣeyọri. Ati ni akoko ṣiṣe, ko han gbangba awọn ila wo ninu awọn oju-iwe ti o yipada. O le jẹ ọpọlọpọ awọn oju-iwe bẹẹ, ati pe fifi wọn sori wọn jẹ alailere. Ni afikun, diẹ ninu awọn oju-iwe le jẹ jade lati kaṣe ifipamọ si disk; kika wọn lẹẹkansi lati yi awọn die-die pada yoo fa fifalẹ iṣẹ naa ni pataki.

Isalẹ ti awọn ifowopamọ ni pe lẹhin awọn ayipada, eyikeyi iṣowo (paapaa ọkan ti n ṣe kika ti o rọrun - SELECT) le bẹrẹ lati yi awọn oju-iwe data pada ninu kaṣe ifipamọ.

Nitorinaa, jẹ ki a ṣatunṣe iyipada naa.

=> COMMIT;

Ko si ohun ti o yipada ni oju-iwe (ṣugbọn a mọ pe ipo iṣowo ti wa ni igbasilẹ tẹlẹ ni XACT):

=> SELECT * FROM heap_page('t',0);
 ctid  | state  | xmin | xmax  | t_ctid 
-------+--------+------+-------+--------
 (0,1) | normal | 3664 | 0 (a) | (0,1)
(1 row)

Bayi idunadura ti o wọle si oju-iwe ni akọkọ yoo ni lati pinnu ipo iṣowo xmin ki o kọ si awọn die-die alaye:

=> SELECT * FROM t;
 id |  s  
----+-----
  1 | FOO
(1 row)

=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   | xmax  | t_ctid 
-------+--------+----------+-------+--------
 (0,1) | normal | 3664 (c) | 0 (a) | (0,1)
(1 row)

Paarẹ

Nigbati ọna kan ba ti paarẹ, nọmba ti idunadura piparẹ lọwọlọwọ ni a kọ si aaye xmax ti ẹya ti isiyi, ati pe xmax_aborted bit ti yọ kuro.

Ṣe akiyesi pe iye ṣeto ti xmax ti o baamu si idunadura ti nṣiṣe lọwọ n ṣiṣẹ bi titiipa ila kan. Ti idunadura miiran ba fẹ lati ṣe imudojuiwọn tabi paarẹ ila yii, yoo fi agbara mu lati duro fun idunadura xmax lati pari. A yoo sọrọ diẹ sii nipa ìdènà nigbamii. Fun bayi, a kan ṣe akiyesi pe nọmba awọn titiipa ila jẹ ailopin. Wọn ko gba aaye ni Ramu ati iṣẹ ṣiṣe eto ko jiya lati nọmba wọn. Otitọ, awọn iṣowo "gun" ni awọn alailanfani miiran, ṣugbọn diẹ sii lori eyi nigbamii.

Jẹ ká pa ila.

=> BEGIN;
=> DELETE FROM t;
=> SELECT txid_current();
 txid_current 
--------------
         3665
(1 row)

A rii pe nọmba idunadura naa ni a kọ sinu aaye xmax, ṣugbọn awọn ipin alaye ko ṣeto:

=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   | xmax | t_ctid 
-------+--------+----------+------+--------
 (0,1) | normal | 3664 (c) | 3665 | (0,1)
(1 row)

Fagilee

Aborting awọn ayipada ṣiṣẹ bakannaa lati ṣe, nikan ni XACT aborted bit ti ṣeto fun idunadura naa. Undoing jẹ bi sare bi ifaramo. Botilẹjẹpe aṣẹ naa ni a pe ni ROLLBACK, awọn ayipada ko yi pada: ohun gbogbo ti idunadura naa ṣakoso lati yipada ni awọn oju-iwe data ko yipada.

=> ROLLBACK;
=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   | xmax | t_ctid 
-------+--------+----------+------+--------
 (0,1) | normal | 3664 (c) | 3665 | (0,1)
(1 row)

Nigbati oju-iwe naa ba wọle, ipo naa yoo ṣayẹwo ati pe xmax_aborted hint bit yoo ṣeto si ẹya ila. Nọmba xmax funrararẹ wa lori oju-iwe, ṣugbọn ko si ẹnikan ti yoo wo.

=> SELECT * FROM t;
 id |  s  
----+-----
  1 | FOO
(1 row)

=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   |   xmax   | t_ctid 
-------+--------+----------+----------+--------
 (0,1) | normal | 3664 (c) | 3665 (a) | (0,1)
(1 row)

Imudojuiwọn

Imudojuiwọn naa n ṣiṣẹ bi ẹnipe o kọkọ paarẹ ẹya ti isiyi ti kana ati lẹhinna fi sii tuntun kan.

=> BEGIN;
=> UPDATE t SET s = 'BAR';
=> SELECT txid_current();
 txid_current 
--------------
         3666
(1 row)

Ibeere naa ṣe agbejade laini kan (ẹya tuntun):

=> SELECT * FROM t;
 id |  s  
----+-----
  1 | BAR
(1 row)

Ṣugbọn lori oju-iwe a rii awọn ẹya mejeeji:

=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   | xmax  | t_ctid 
-------+--------+----------+-------+--------
 (0,1) | normal | 3664 (c) | 3666  | (0,2)
 (0,2) | normal | 3666     | 0 (a) | (0,2)
(2 rows)

Ẹya ti paarẹ jẹ samisi pẹlu nọmba idunadura lọwọlọwọ ni aaye xmax. Pẹlupẹlu, iye yii ti kọ lori atijọ, niwon a ti fagile idunadura iṣaaju. Ati pe xmax_aborted bit ti parẹ nitori ipo iṣowo lọwọlọwọ ko tii mọ.

Ẹya akọkọ ti ila ni bayi tọka si keji ( aaye t_ctid) bi tuntun.

Atọka keji yoo han ni oju-iwe atọka ati ila keji tọka ẹya keji ni oju-iwe tabili.

Gẹgẹ bi pẹlu piparẹ, iye xmax ni ẹya akọkọ ti ila naa jẹ itọkasi pe ila naa ti wa ni titiipa.

O dara, jẹ ki a pari idunadura naa.

=> COMMIT;

Atọka

Nitorinaa a ti sọrọ nikan nipa awọn oju-iwe tabili. Ohun ti o ṣẹlẹ inu awọn atọka?

Alaye ti o wa ninu awọn oju-iwe atọka yatọ pupọ da lori iru atọka kan pato. Ati paapaa iru atọka kan ni awọn oriṣiriṣi awọn oju-iwe. Fun apẹẹrẹ, igi B ni oju-iwe metadata ati awọn oju-iwe “deede”.

Sibẹsibẹ, oju-iwe naa nigbagbogbo ni ọpọlọpọ awọn itọka si awọn ori ila ati awọn ori ila funrara wọn (gẹgẹbi oju-iwe tabili). Ni afikun, ni opin oju-iwe naa aaye wa fun data pataki.

Awọn ori ila ni awọn atọka tun le ni awọn ẹya ti o yatọ pupọ ti o da lori iru atọka naa. Fun apẹẹrẹ, fun igi B, awọn ori ila ti o ni ibatan si awọn oju-iwe ewe ni iye bọtini itọka ati itọkasi (ctid) si laini tabili ti o baamu. Ni gbogbogbo, atọka le jẹ tito ni ọna ti o yatọ patapata.

Ojuami pataki julọ ni pe ko si awọn ẹya ila ni awọn atọka ti eyikeyi iru. O dara, tabi a le ro pe laini kọọkan jẹ aṣoju nipasẹ ẹya kan pato. Ni awọn ọrọ miiran, ko si awọn aaye xmin ati xmax ninu akọsori ila atọka. A le ro pe awọn ọna asopọ lati atọka itọsọna si gbogbo awọn ẹya tabili ti awọn ori ila - nitorinaa o le rii iru ẹya ti idunadura naa yoo rii nikan nipa wiwo tabili. (Gẹgẹbi nigbagbogbo, eyi kii ṣe gbogbo otitọ. Ni awọn igba miiran, maapu hihan le mu ilana naa pọ si, ṣugbọn a yoo wo eyi ni alaye diẹ sii nigbamii.)

Ni akoko kanna, ni oju-iwe atọka a wa awọn itọka si awọn ẹya mejeeji, mejeeji ti lọwọlọwọ ati ti atijọ:

=> SELECT itemoffset, ctid FROM bt_page_items('t_s_idx',1);
 itemoffset | ctid  
------------+-------
          1 | (0,2)
          2 | (0,1)
(2 rows)

Foju lẹkọ

Ni iṣe, PostgreSQL nlo awọn iṣapeye ti o gba laaye lati “fipamọ” awọn nọmba idunadura.

Ti idunadura kan ba ka data nikan, ko ni ipa lori hihan ti awọn ẹya kana. Nitorinaa, ilana iṣẹ ni akọkọ fun xid foju kan si idunadura naa. Nọmba naa ni ID ilana ati nọmba ọkọọkan kan.

Ipinfunni nọmba yii ko nilo amuṣiṣẹpọ laarin gbogbo awọn ilana ati nitorinaa o yara pupọ. A yoo mọ idi miiran fun lilo awọn nọmba foju nigba ti a ba sọrọ nipa didi.

Awọn nọmba foju ko ṣe akiyesi ni eyikeyi ọna ni awọn aworan aworan data.

Ni awọn aaye oriṣiriṣi ni akoko, awọn iṣowo foju le dara daradara ninu eto pẹlu awọn nọmba ti o ti lo tẹlẹ, ati pe eyi jẹ deede. Ṣugbọn iru nọmba bẹẹ ko le kọ sinu awọn oju-iwe data, nitori nigbamii ti oju-iwe naa ba wọle o le padanu gbogbo itumọ.

=> BEGIN;
=> SELECT txid_current_if_assigned();
 txid_current_if_assigned 
--------------------------
                         
(1 row)

Ti idunadura kan ba bẹrẹ lati yi data pada, o fun ni gidi, nọmba idunadura alailẹgbẹ.

=> UPDATE accounts SET amount = amount - 1.00;
=> SELECT txid_current_if_assigned();
 txid_current_if_assigned 
--------------------------
                     3667
(1 row)

=> COMMIT;

Itẹle lẹkọ

Fi awọn ojuami pamọ

Ti ṣe alaye ni SQL fi ojuami (savepoint), eyiti o gba ọ laaye lati fagilee apakan ti idunadura kan laisi idilọwọ rẹ patapata. Ṣugbọn eyi ko baamu si aworan atọka ti o wa loke, nitori pe idunadura naa ni ipo kanna fun gbogbo awọn ayipada rẹ, ati ni ti ara ko si data ti yiyi pada.

Lati ṣe iṣẹ ṣiṣe yii, idunadura kan pẹlu aaye ipamọ kan ti pin si ọpọlọpọ lọtọ iteeye lẹkọ (subtransaction), awọn ipo ti eyi ti o le wa ni isakoso lọtọ.

Awọn iṣowo itẹ-ẹiyẹ ni nọmba tiwọn (ti o ga ju nọmba ti idunadura akọkọ lọ). Ipo ti awọn iṣowo itẹ-ẹiyẹ ti wa ni igbasilẹ ni ọna deede ni XACT, ṣugbọn ipo ikẹhin da lori ipo ti iṣowo akọkọ: ti o ba ti fagilee, lẹhinna gbogbo awọn iṣowo itẹ-ẹiyẹ tun fagile.

Alaye nipa itẹ-ẹiyẹ idunadura ti wa ni ipamọ sinu awọn faili ni ilana PGDATA/pg_subtrans. Awọn faili wọle nipasẹ awọn ifipamọ ni iranti pinpin apẹẹrẹ, ti a ṣeto ni ọna kanna bi awọn buffers XACT.

Maṣe dapo awọn iṣowo itẹ-ẹiyẹ pẹlu awọn iṣowo adase. Awọn iṣowo adaṣe ko dale lori ara wọn ni eyikeyi ọna, ṣugbọn awọn iṣowo itẹ-ẹiyẹ ṣe. Ko si awọn iṣowo adase ni deede PostgreSQL, ati, boya, fun awọn ti o dara julọ: wọn nilo pupọ, ṣọwọn pupọ, ati wiwa wọn ni awọn DBMS miiran nfa ilokulo, lati eyiti gbogbo eniyan lẹhinna jiya.

Jẹ ki a ko tabili naa kuro, bẹrẹ idunadura kan ki o fi ori ila naa sii:

=> TRUNCATE TABLE t;
=> BEGIN;
=> INSERT INTO t(s) VALUES ('FOO');
=> SELECT txid_current();
 txid_current 
--------------
         3669
(1 row)

=> SELECT xmin, xmax, * FROM t;
 xmin | xmax | id |  s  
------+------+----+-----
 3669 |    0 |  2 | FOO
(1 row)

=> SELECT * FROM heap_page('t',0);
 ctid  | state  | xmin | xmax  | t_ctid 
-------+--------+------+-------+--------
 (0,1) | normal | 3669 | 0 (a) | (0,1)
(1 row)

Bayi jẹ ki a fi aaye ipamọ kan sii ki o fi laini miiran sii.

=> SAVEPOINT sp;
=> INSERT INTO t(s) VALUES ('XYZ');
=> SELECT txid_current();
 txid_current 
--------------
         3669
(1 row)

Ṣe akiyesi pe iṣẹ txid_current () da nọmba idunadura akọkọ pada, kii ṣe nọmba idunadura itẹ-ẹiyẹ.

=> SELECT xmin, xmax, * FROM t;
 xmin | xmax | id |  s  
------+------+----+-----
 3669 |    0 |  2 | FOO
 3670 |    0 |  3 | XYZ
(2 rows)

=> SELECT * FROM heap_page('t',0);
 ctid  | state  | xmin | xmax  | t_ctid 
-------+--------+------+-------+--------
 (0,1) | normal | 3669 | 0 (a) | (0,1)
 (0,2) | normal | 3670 | 0 (a) | (0,2)
(2 rows)

Jẹ ki a yi lọ pada si aaye fifipamọ ki o fi laini kẹta sii.

=> ROLLBACK TO sp;
=> INSERT INTO t(s) VALUES ('BAR');
=> SELECT xmin, xmax, * FROM t;
 xmin | xmax | id |  s  
------+------+----+-----
 3669 |    0 |  2 | FOO
 3671 |    0 |  4 | BAR
(2 rows)

=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   | xmax  | t_ctid 
-------+--------+----------+-------+--------
 (0,1) | normal | 3669     | 0 (a) | (0,1)
 (0,2) | normal | 3670 (a) | 0 (a) | (0,2)
 (0,3) | normal | 3671     | 0 (a) | (0,3)
(3 rows)

Ninu oju-iwe ti a tẹsiwaju lati rii ila ti a ṣafikun nipasẹ idunadura itẹ-ẹiyẹ ti paarẹ.

A ṣatunṣe awọn ayipada.

=> COMMIT;
=> SELECT xmin, xmax, * FROM t;
 xmin | xmax | id |  s  
------+------+----+-----
 3669 |    0 |  2 | FOO
 3671 |    0 |  4 | BAR
(2 rows)

=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   | xmax  | t_ctid 
-------+--------+----------+-------+--------
 (0,1) | normal | 3669 (c) | 0 (a) | (0,1)
 (0,2) | normal | 3670 (a) | 0 (a) | (0,2)
 (0,3) | normal | 3671 (c) | 0 (a) | (0,3)
(3 rows)

Bayi o le rii kedere pe iṣowo itẹ-ẹiyẹ kọọkan ni ipo tirẹ.

Ṣe akiyesi pe awọn iṣowo itẹ-ẹiyẹ ko le ṣee lo ni gbangba ni SQL, iyẹn ni, o ko le bẹrẹ idunadura tuntun laisi ipari ti lọwọlọwọ. Ilana yii ti muu ṣiṣẹ ni aitọ nigba lilo awọn aaye ipamọ, bakannaa nigba mimu awọn imukuro PL/pgSQL mu ati ni nọmba awọn miiran, awọn ọran nla diẹ sii.

=> BEGIN;
BEGIN
=> BEGIN;
WARNING:  there is already a transaction in progress
BEGIN
=> COMMIT;
COMMIT
=> COMMIT;
WARNING:  there is no transaction in progress
COMMIT

Awọn aṣiṣe ati atomity ti awọn iṣẹ

Kini yoo ṣẹlẹ ti aṣiṣe ba waye lakoko ṣiṣe iṣẹ kan? Fun apẹẹrẹ, bii eyi:

=> BEGIN;
=> SELECT * FROM t;
 id |  s  
----+-----
  2 | FOO
  4 | BAR
(2 rows)

=> UPDATE t SET s = repeat('X', 1/(id-4));
ERROR:  division by zero

Aṣiṣe kan ti ṣẹlẹ. Bayi idunadura naa ni a gba pe o ti parẹ ati pe ko gba awọn iṣẹ laaye ninu rẹ:

=> SELECT * FROM t;
ERROR:  current transaction is aborted, commands ignored until end of transaction block

Ati paapaa ti o ba gbiyanju lati ṣe awọn ayipada, PostgreSQL yoo jabo iṣẹyun kan:

=> COMMIT;
ROLLBACK

Kilode ti idunadura kan ko le tẹsiwaju lẹhin ikuna? Otitọ ni pe aṣiṣe le dide ni iru ọna ti a yoo ni iraye si apakan ti awọn ayipada - atomity ti kii ṣe idunadura paapaa, ṣugbọn oniṣẹ yoo jẹ irufin. Gẹgẹbi apẹẹrẹ wa, nibiti oniṣẹ ṣakoso lati ṣe imudojuiwọn laini kan ṣaaju aṣiṣe:

=> SELECT * FROM heap_page('t',0);
 ctid  | state  |   xmin   | xmax  | t_ctid 
-------+--------+----------+-------+--------
 (0,1) | normal | 3669 (c) | 3672  | (0,4)
 (0,2) | normal | 3670 (a) | 0 (a) | (0,2)
 (0,3) | normal | 3671 (c) | 0 (a) | (0,3)
 (0,4) | normal | 3672     | 0 (a) | (0,4)
(4 rows)

O gbọdọ sọ pe psql ni ipo ti o tun jẹ ki iṣowo naa tẹsiwaju lẹhin ikuna bi ẹnipe awọn iṣe ti oniṣẹ aṣiṣe ti yiyi pada.

=> set ON_ERROR_ROLLBACK on
=> BEGIN;
=> SELECT * FROM t;
 id |  s  
----+-----
  2 | FOO
  4 | BAR
(2 rows)

=> UPDATE t SET s = repeat('X', 1/(id-4));
ERROR:  division by zero

=> SELECT * FROM t;
 id |  s  
----+-----
  2 | FOO
  4 | BAR
(2 rows)

=> COMMIT;

Ko ṣoro lati gboju le won pe ni ipo yii, psql nitootọ fi aaye ifipamọ aitọ han ṣaaju aṣẹ kọọkan, ati pe ninu ọran ikuna bẹrẹ yiyi pada si rẹ. Ipo yii kii ṣe lilo nipasẹ aiyipada, nitori eto awọn aaye ipamọ (paapaa laisi yiyi pada si wọn) kan pẹlu oke pataki.

Itesiwaju.

orisun: www.habr.com

Fi ọrọìwòye kun