áľááá
, á°ááá
ááłáŽá˝á á°áááá°áá
áááľ
áá°á á˛á áĽáá°á°ááááá áĽáŤááłááą á¨áľá á á ááľ áá á á ááŤáł áľáŞáśá˝ ááľáĽ á áá¨á ááą ááľáĽ ááá áá˝áá. á ááą áľáŞáľ á áá ááááľ á¨ááá ááá¨áľ á áá áľ ááá á áá áĽáŤááłááą áĽáľá á¨áá á áľáŞáľ "áá" á¨áááľá áááľ ááááśá˝ á ááľ (xmin áĽá xmax). á áĽá áśá˝ ááľáĽ - ááááŤáąá áĽá á áá á¨áááá áá á áá°áá, ááá áá áአáĽá¨á¨áᨠá¨áááľ ááŁáŞ. áĽá áá ááŁáŞ á¨ááĽááľ ááĽáŠ ááá˘
(áĽáá°á°ááá°á áĽáááłá á¨á áá á¨á°ááłá°á ááᥠá ááŁáŞá ááľá á á
á ááááŤáľ á¨ááĽááą ááĽáŠ áá áá áá¨áá á áá˝ááᢠáá áá° á á¨áśááľ áľáá°ááľ áĽááá
á ááááŽá˝ á áááá áĽáááá¨áłááá˘)
á¨áľá á˛áá á xmin INSERT áľááá áá°á°á á á¨ááĽááľ ááĽá á°áááĽáŻá áĽá xmax áŁáś áá áááŤáá˘
á ááľ á¨áľá á˛á°á¨á á¨á áá áľáŞáľ xmax áĽá´áľ á°áá áŁá¨áááá á¨ááĽááľ ááĽá ááááľ áá°á¨áá áłáá˘
á ááľ á¨áľá á UPDATE áľááá á˛áá¨áᣠáááľ ááááá˝ á áľááá áá¨ááááᥠá°áá áĽá á áľááŁá˘ á¨á áá á¨á¨áľá áĽáľá xmax ááááá áŤá¨áááá á¨ááĽááľ áĽááľ áá áĽáŠá áŤááááᢠá¨ááŤá á°ááłáłá ááĽá¨ááá á á˛áľ áľáŞáľ á°ááĽáŻá; á¨áĽáą xmin áá á¨ááłáá áľáŞáľ xmax áá áá ááááłáá˘
ᨠxmin áĽá xmax ááľáŽá˝ á á¨áľá áĽáŞáľ áŤáľá ááľáĽ á°áŤáľá°ááᢠá¨áĽááá ááľáŽá˝ á á°á¨á᪠áŤáľáá ááá˝á áááᣠáááłááĄ-
- infomask á¨áá á áľáŞáľ áŁá áŞáŤáľ á¨ááááš á°á¨áłáłá á˘áľáľ áá. á áŁá áĽá áá¸á; áá áááášá ááľ á ááľ áĽáááá¨áłáá.
- ctid áá° ááŁáŠ á ááá á ááá áá, á°ááłáłá ááľáá á á˛áľ áľáŞáľ. áá á˛áąáŁ á áĽááá á¨á áá á¨ááĽá¨ááá áľáŞáľáŁ ctid á¨ááŤáááá°á áá á áľáŞáľ áŤáą ááᢠááĽáŠ á áš (x,y) á áá, x á¨áá˝ ááĽá áá, y á áľááľá ááľáĽ áŤáá á¨áá¨á á áá ááĽá áá.
- null bitmap - áŁáś áĽá´áľ (NULL) áŤáá¸áá á¨á ááľ á¨á°áá°á áľáŞáľ á ááśá˝ ááááľ áŤá°áááᢠNULL á¨áá°á áá á¨ááἠá áááľ áĽá´áśá˝ á ááą á áá°áááŁáľááá áŁá áŞá á á°áá á áááἠá áá áľá˘
á áá¤áąá ᣠáŤáľáá á áŁá áľáá áá - ááĽáŤááłááą á¨ááľáአáľáŞáľ á˘áŤááľ 23 áŁáᾠᣠáĽá áĽá áá á NULL á˘áľáá ááááŤáľá˘ á áá á¨áĄ "á áŁáĽ" á¨áá (áá á áĽááľ áááśá˝á á¨áŤá) á¨áá, á¨áá áŤáá á áá áá¨á á¨á áá áááľáľ áá˝áá.
á ááŁ
á¨ááľááŁáľ ááᎠá¨áá á°á á°á¨á ááĽá¨ááá áľáŤáá˝ áĽáá´áľ áĽáá°áá¨ááá á áááá áĽáááá¨áľá˘
ááá¨áŤáá˝áŁ áááľ áááśá˝ áĽá á á áá°áá áá áá¨á á áá áŤáá á á˛áľ á áá á¨áĽ áĽááá ááĄ-
=> CREATE TABLE t(
id serial,
s text
);
=> CREATE INDEX ON t(s);
ááĽááľ á¨áááá á áá á ááľ á¨áľá áĽááľááŁá˘
=> BEGIN;
=> INSERT INTO t(s) VALUES ('FOO');
á¨á áá á¨ááĽááľ ááĽáŤá˝á áĽáááĄ-
=> SELECT txid_current();
txid_current
--------------
3664
(1 row)
á¨áášá áááľ áĽááᢠá¨áá˝ áá°áť á áĽáŤ ááá_áá˝_ááĽáá˝ á°ááŁá áľá á áááá˝ áĽá á¨á¨áľá áľáŞáśá˝ áá¨á áĽááľáłáá ááá áľááááĄ
=> 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
á PostgreSQL ááľáĽ áŤáá ááá á¨ááá áá á áá á¨áŚá˝á áĽáá°ááŤááááľ áἠáá áᢠáá
áá áĽáááł á¨áá á á ááá áá - ááá ááłááá
á°ááŁáŠ "áĽáá°áá" áá¨áá áŤáłáŤá, ááá¨áłáľ á áľá¸á᪠á áá á áá¸áľ. áĽáąá áááá ᣠá¨áá¨ááá á¨á°áá°á ááá áĽáť áĽáá°ááá áĽá áĽáááłááááĄ-
=> 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)
áŤá°á¨ááá áĽáááĄ-
- ᨠt_ctid: (áá˝ ááĽáᣠá¨áá¨á á áá ááĽá) áá á ááľ á áááľ áĽáá˛áá áááľá¨á áá° á áá ááĽáŠ áᎠáłáááá˘
- á¨lp_flags á áá áááłá áááżáᢠáĽáá "á¨á°ááá°" áá - áá áááľ á ááá á áľááá á¨ááĽá¨ááááá áľáŞáľ áŤááááłá. ááá˝ áľáááá˝á á áá áĽáááá¨áłááá˘
- á¨ááá á¨áá¨á á˘áľáľ ááľáĽ áĽáľáŤáá áááľ áĽááśá˝ áĽáť á°ááá°áá. ᨠxmin_committed áĽá xmin_á¨á°á°á¨á á˘áľáľ á¨ááĽááľ ááĽá xmin ááá¸áá (á¨á°áá¨á ) áááá áŤááááłáᢠáááľ á°ááłáłá á˘áľáľ á¨ááĽááľ ááĽá xmaxá áŤááááłáá˘
áľááááłá? á ááľ á¨áľá á ááŤáľááĄá áľ áá á áá ááĽá 1 á á°áá á¨áĄ áá˝ áá ááłáŤá, áá° á¨ááááŞáŤá áĽá áĽá¸áá á¨á¨áľá áľáŞáľ áá ááá.
á ááĽá¨áááá áľáŞáľ ááľáĽ ᨠxmin ááľáŠ á áá áŁáá á¨ááĽááľ ááĽá á°áááˇáᢠááĽááą á ááá áá ááᣠáľááá áááąá ᨠxmin_committed áĽá xmin_aborted bits á áá°ááááá˘
á¨á¨áľá áľáŞáľ ctid ááľá á°ááłáłá á¨áľá áŤááááłá. áá áááľ á á˛áľ áľáŞáľ á¨áá áááľ ááá˘
áá á¨á¨áľá áľáŞáľ áľááá°á°á¨á áĽá áá áłá áľááá ᨠxmax ááľáŠ á áąá ááĽá 0 á°áááˇáᢠᨠxmax_aborted á˘áľ áľáá°ááá ááĽááśá˝ ááá ááĽá áľáŠá¨áľ á áá°áĄáá˘
á ááĽááľ ááĽáŽá˝ áá á¨áá¨á á˘áľ á áá¨á á°ááŁá˘ááľá áááťáťá á ááľ á°á¨á᪠áĽááá áĽááá°áľá˘ áĽá áĽáŤááá á¨á ááľ áá á áá áľáááŤáľáááá á°ááŁá áĽááá ááĄ-
=> 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;
á áá á á˝áŁ á á¨áľá áĽáŞáľ áŤáľá áá áá áĽá¨á°áŤáá° áĽááłá á¨á áá ááá˝ ááá˘
=> SELECT * FROM heap_page('t',0);
ctid | state | xmin | xmax | t_ctid
-------+--------+------+-------+--------
(0,1) | normal | 3664 | 0 (a) | (0,1)
(1 row)
á°ááłáłá ᣠáá á áŁá áľáá˝ áááá ᣠáá¨áá á¨á á¨á´áá áŤáą ááááľ ááťáá ᣠá¨áá¸áľ á ááśá˝ xmin áĽá xmaxá˘
=> SELECT xmin, xmax, * FROM t;
xmin | xmax | id | s
------+------+----+-----
3664 | 0 | 1 | FOO
(1 row)
ááľá°áŤá¨á
ááĽááą á á°áłáŤ áááł á¨á°á ááá, áááłáá ááľáłááľ áŤáľáááááłá - ááá á áááá áἠáá á. áá áá áááľá¨á XACT á¨ááŁá ááá á áĽá á áá áááá (áĽá ᨠ10 áľáŞáľ á ááľ CLOG (commit log) á°áĽá áá ፠áá á áĽá áá áľá á ááá á á°ááŤáŠ áŚáłáá˝ áá ááá áá˝áá).
XACT á¨áľáááľ áŤáłáá á°áá á¨áĽ á áá°áá; áĽááá á PGDATA/pg_xact áá፠ááľáĽ áŤá áááá˝ áá¸áᢠááĽáŤááłááą ááĽááľ áááľ á˘áľ á áá¸áᥠá¨á°ááá áĽá á¨á°á°á¨á - áá áĽáá° á á¨áľá áĽáŞáľ áŤáľáᢠáá áá¨á ááááťá¸áľ áĽáť á á ááŤáł áááá˝ á¨á°á¨ááá ááᥠáá°áá ááłá áááááá áľááľáĽ áá°áá ááłá áĽááááłááᢠáĽá á¨áĽááá áááá˝ áá ááľáŤáľ áá áĽáá° áááš áá á¨áá˝ á áá˝ áá¨ááááá˘
áľááá ᣠá XACT ááľáĽ ááĽááľ á˛áááᣠá¨á°ááŁá á˘áľ ááá ááĽááľ á°ááá áˇáᢠáĽá áá á ááááá áľ áá á¨áá¨á°á°á áá áĽáť áá (ááá áĽááłá áľá á áľá-áá¨áť áááἠáá áĽá¨á°ááááá áŁáááá)á˘
áá ááĽááľ á áá á¨á°ááá¨áľááá á¨á°áá á¨áĽ áá˝ á˛á°ááľáŁ áĽá áĽáŤááá˝á ááááľ áááá áłáá˘
- ᨠxmin ááĽááą á°á áá
áá? áŤááá, á¨á°áá á¨á á¨ááĽá¨áááá áľáŞáľ ááłá¨áľ á¨áá áľá.
áá áźá á¨áá¨áááá á ááłáá á¨á፠áá á°á¨ áľááľáł ááľáĽ á¨ááá áĽá ááŽáŤáŹá á°áĽá á¨áá áŤáá áá ááá á á áááá¨áľ ááᢠáĽáą á¨ááá áá áá°áśá˝ áááá áááá ᣠáĽá ááĽáŤááłááą á¨á áá (áá) ááĽááą ááĽá áá áááᢠ- á¨á°á ááá áłá˛áŤ áĽáá´áľ - á ááá¸á ááá á áá°á¨á? á¨á°á°á¨á á¨á¨áľá áĽáŞáľá ááłá¨áľ á¨áá áľáá˘
áá á áľááá XACT áá. ááá ááᣠááá áĽááłá á¨XACT á¨áá¨á¨áť ááá˝ á RAM ááľáĽ ááľ ááľáĽ á˘áááĄáᣠXACTá á á¨ááá ááá°á˝ á ááá ááľ ááᢠáľááá ᣠá¨ááĽááą áááł á áá´ á¨á°áá°áᣠáá° string version xmin_committed áĽá xmin_aborted bits ááťááᢠá¨ááá á˘áľáľ á ááą á¨á°ááᨠᨠxmin á¨ááĽááľ áááł áĽáá°áłáá ááá áŤá áĽá ááŁáŠ ááĽááľ XACTá ááľá¨áľ á¨áá áľáá˘
ááááľáá áĽááá á˘áľáľ á ááĽááą áĽáŤáą áŤáľááŁá á áá°áááá? ááľááŁáľ á˛áá áᣠááĽááą ááłáŤ áĽáá°áá áĽáľáŤáá á áŤáá áᢠáĽá á á°áá¸áá áľ ááᣠá á¨áľááš áážá˝ ááľáĽ á¨áľááš ááľááŽá˝ áĽáá°á°áá¨áŠ ááá˝ á áá°ááᢠáĽá áĽáá°áá áŤá áážá˝ ááአáá˝áá, áĽá áĽááąá ááľáłááľ áľááá á áá°áá. á á°á¨ááŞá, á ááłááľ áážá˝á á¨á áŁáá áá¸á፠áá° á˛áľá ááľááŁáľ ááťáá; á˘áľ áááá¨á áĽáá°áá ááá ἠááá áááľá á áĽá á ááááłáá˘
á¨áá áŁá ááłáą á¨á°áá¨á¨ á áá ááááá ááĽááľ (ááá ááŁáĽ á¨ááŤá¨ááá - SELECT) á ááľ áá¸á፠ááľáĽ á¨ááἠáážá˝á áááἠáááá áá˝ááá˘
áľááá áááĄá áĽááľá°áŤáááá˘
=> COMMIT;
á ááš áá ááá á¨á°ááá ááá á¨áá (áá á¨ááĽááą áááł á áľááľá á XACT ááľáĽ áĽáá°á°áááá áĽááááá)
=> SELECT * FROM heap_page('t',0);
ctid | state | xmin | xmax | t_ctid
-------+--------+------+-------+--------
(0,1) | normal | 3664 | 0 (a) | (0,1)
(1 row)
á áá ááááŞáŤ áášá á¨áá°áá°á ááĽáᾠᨠxmin ááĽááľ áááłá ááá°á áĽá áá° á¨áá¨á á˘áľáľ ááá á áá áľá˘
=> 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)
á°áá
á ááľ á¨áľá á˛á°á¨á á¨á áá á¨áá°á¨á ááĽááľ ááĽá á áá áŁáá áľáŞáľ xmax ááľá áá áááá áĽá xmax_aborted á˘áľ áá¸áłáá˘
á¨ááŁáŞ ááĽááľ áá á¨áááá°á ᨠxmax áľáĽáľáĽ áá áĽáá° á¨áľá áááá፠áĽáá°áá°áŤ áἠáá áᢠáá ááĽááľ áá á á¨áľá áááá ááá áá°á¨á á¨áááᣠááĽááą xmax áĽáľáŞá ááá áľá¨áľ ááá á á ááá°áłáᢠáľááááľ á áá á¨á áá áĽáááááŤáá. áá ááᣠá¨á¨áľá áááááŤáá˝ ááĽá áŤáá°áá°á áááá áĽáť áĽááľá°ááááᢠá RAM ááľáĽ áŚáł á áááľáąá áĽá á¨áľáááľ á áááá ááĽáŤá¸á á áááłáá. áĽáááľ áá, "á¨áĽá" ááĽááśá˝ ááá˝ ááłáśá˝ á áá¸á, áá á áá áá á°á¨ááŞ.
ááľááŠá áĽáá°áááá˘
=> BEGIN;
=> DELETE FROM t;
=> SELECT txid_current();
txid_current
--------------
3665
(1 row)
á¨ááĽááą ááĽáŠ á xmax ááľá áá áĽáá°á°áá áĽááŤááᣠááá áá á¨áá¨á á˘áľáľ á áá°ááá á¨áá˘
=> SELECT * FROM heap_page('t',0);
ctid | state | xmin | xmax | t_ctid
-------+--------+----------+------+--------
(0,1) | normal | 3664 (c) | 3665 | (0,1)
(1 row)
ááĽááľ
áááŚá˝á ááľáá¨áľ á¨ááá¸á áá á°ááłáłá áá, á XACT ááľáĽ áĽáť á¨á°áá¨á á á˘áľ áááĽááą á°ááá§á. áááá áľ áĽáá° ááá¸á ááŁá ááᢠááá áĽááłá áľááá ROLLBACK á°áĽá á¨áá ፠á˘ááá áááŚáš áá° áá á ááááąáᥠááĽááą á ááἠááá˝ ááľáĽ áááἠá¨áťáá ááá ááá áłáááἠáááŤáá˘
=> ROLLBACK;
=> SELECT * FROM heap_page('t',0);
ctid | state | xmin | xmax | t_ctid
-------+--------+----------+------+--------
(0,1) | normal | 3664 (c) | 3665 | (0,1)
(1 row)
ááš á˛á°á¨áľáŁ áááłá ââááŁáŤá áĽá ᨠxmax_aborted ááá á˘áľ áá° á¨áľá áľáŞáľ áááá áŤáᢠᨠxmax ááĽáŠ áŤáą á ááš áá áááŤáᣠáá ááá á áááá¨á°ááá˘
=> 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)
á ááá
ááťáťáŤá ááááŞáŤ á¨á¨áľáá á¨á ááá áľáŞáľ áĽáá°á°á¨á áĽá á¨á፠á á˛áľ áĽááłáľáᣠáá°áŤáá˘
=> BEGIN;
=> UPDATE t SET s = 'BAR';
=> SELECT txid_current();
txid_current
--------------
3666
(1 row)
áá áá á ááľ ááľáá áŤááŁá (á á˛áľ áľáŞáľ)áĄ-
=> SELECT * FROM t;
id | s
----+-----
1 | BAR
(1 row)
áá á ááš áá áááąáá áľáŞáśá˝ áĽááŤáá-
=> 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)
á¨á°á°á¨áá áĽáľá á áá áŁáá á¨ááĽááľ ááĽá á xmax ááľá áá ááááľ á°á°ááá áłáᢠá¨áá á á áá áá áá á á áŽáá áá á°á˝áá, ááááŤáąá áŤááá ááĽááľ áľáá°á°á¨á. áĽá xmax_aborted á˘áľ á°á ááá ááááŤáąá á¨á áá ááĽááľ áááł áĽáľáŤáá á ááłáááá˘
á¨ááľáአá¨ááááŞáŤ áľáŞáľ á áá ááá°ááá (t_ctid ááľá) áĽáá° á á˛áą áŤááááłáá˘
ááá°á á˘áá´ááľ á áá¨á á áá ááš áá ááłáŤá áĽá ááá°áá á¨áľá á á°áá á¨áĄ áá˝ áá ááá°ááá áľáŞáľ áá á áłá.
áá áĽáá° áľá¨áᣠá ááááŞáŤá á¨á¨áľá áľáŞáľ ááľáĽ áŤáá ᨠxmax áĽá´áľ á¨áľá ááááá á¨ááŤáłá ááá˘
á°á áᣠááĽááąá áĽáá áá á á˘
=> COMMIT;
áááŤáá˝
áĽáľáŤáá áľá¨áľ á¨á°áááááá áľá á á¨á´á áážá˝ áĽáť áá. á áá¨á á áááá˝ ááľáĽ áá áá¨á°áłá?
á áá¨á á áá ááá˝ ááľáĽ áŤáá áá¨á áĽáá°á¨á°áá°áá á¨áá¨á á áá á áááľ á áĽá á áááŤáŤáᢠáĽá á ááľ á áááľ á˘áá´ááľ áĽááłá á¨á°ááŤáŠ á áááľ áážá˝ á ááľá˘ áááłáᣠá˘-áá á¨ááłáłáł áá˝ áĽá âáá°á áâ áážá˝ á ááľá˘
ááá ááᣠááš áĽááá áá áá° á¨áľáá˝ áĽá á¨áľááš áĽáŤáłá¸á (áá áĽáá° á¨á á¨á´á áá˝) á áááá˝ á ááľá˘ á á°á¨ááŞá, á ááš áá¨á¨áť áá áá¨áľ áŤá ááἠá¨ááá áŚáł á á.
á áá¨á á áááá˝ ááľáĽ áŤá á¨áľáá˝ áĽáá° áá¨á á ááá ááááľ á áŁá á¨á°ááŤáŠ á ááááŽá˝ áááŤá¸á áá˝ááᢠáááłá áá˘-áá á¨á á á ááá˝ áá á¨á°áŤáŤááľ á¨áľáá˝ á¨áá¨á á áá ááá áĽá´áľ áĽá ááŁááť (ctid) áá° á°ááłá á¨á áá á¨áĽ á¨áľá ááááᢠá á á ááá áá¨á á ááá áá á áá á á°áᨠááááľ áááá áá˝áá.
á áŁá á áľáááá ááĽáĽ á á¨áľááá ááááľ á˘áá´ááśá˝ ááľáĽ ááá á¨á¨áľá áľáŞáśá˝ á¨áá. á°á á ᣠááá áĽáŤááłááą ááľáá á áľááá á á ááľ áľáŞáľ ááá¨áá áĽáá ááááľ áĽáá˝áááᢠá áá á áááá á áá¨á á áá á¨áľá áŤáľá ááľáĽ ᨠxmin áĽá xmax ááľáŽá˝ á¨ááᢠá¨áá¨á á ááá á¨ááᥠá áááá˝ áá° ááá á¨á¨áľáá˝ á¨á á¨á´á áľáŞáśá˝ áááŤá áĽáá ááááľ áĽáá˝ááá - áľááá ááĽááą á¨áľááá áľáŞáľ áĽáá°ááŤá¨á á á¨á´ááá á áááá¨áľ áĽáť ááá áá˝áá ᢠ(áĽáá° ááááá áá ááá áĽáááľ á áá°áá. á á ááłááľ áááłáá˝ á¨áłáááľ áŤááłá áá°áąá ááŤááťá˝ áá˝áá, ááá áá áá áá á áá á á áá áááá áĽáááá¨áłáá.)
á á°ááłáłá áá áŁá áá¨á á ááá áá˝ áá ááááąá áľáŞáśá˝ ᣠááááąá á¨á áá áĽá á¨áľáŽá á áááá˝á áĽáááááá˘
=> SELECT itemoffset, ctid FROM bt_page_items('t_s_idx',1);
itemoffset | ctid
------------+-------
1 | (0,2)
2 | (0,1)
(2 rows)
áááŁá ááĽááśá˝
á á°ááŁá, PostgreSQL á¨ááĽááľ ááĽáŽá˝á "áĽáá˛ááĽáĽ" á¨ááŤáľá˝á áááťá¸áľá áá ááá.
á ááľ ááĽááľ áááĽá áĽáť á¨ááŤáἠá¨ááᣠá á¨áľá áľáŞáśá˝ áłáááľ áá ááá á°á˝áĽá á ááá¨ááᢠáľááá , á¨á áááááą áá°áľ á ááááŞáŤ áááĽááą áááŁá xid áá°áŁá. ááĽáŠ á¨áá°áľ ááłáá፠áĽá á°á¨áłáłá ááĽá áŤáŤáľáłá.
áá áá ááĽá áááŁáľ á ááá áá°áśá˝ ááŤá¨á áááłá°áá á ááááá áĽá áľááá á áŁá ááŁá áá. áľá á á¨áś áľáá፠áááŁá ááĽáŽá˝á á¨ááá ááá áľ áá ááááŤáľ áá áĽáá°áááááá˘
á áá¨á á á˝á á°-ááśáá˝ ááľáĽ áááŁá ááĽáŽá˝ á ááá ááአáááľ ááľáĽ á áááĄáá˘
á á°ááŤáŠ áááŤáľ á á˛áľá°á ááľáĽ áá°á á˛á áĽá á áá á¨áá ááĽáŽá˝ áá áááŁá ááĽááśá˝ ááአáá˝áá ᣠáĽá áá á¨á°ááá° ááᢠááá áá áĽáá˛á ááááą ááĽá á áá¨á ááá˝ ááľáĽ ááá á áá˝áá, ááááŤáąá ááš á áááĽáá áá á˛á°á¨áľ áááá áľáááá˝ ááŤáŁ áá˝áá.
=> BEGIN;
=> SELECT txid_current_if_assigned();
txid_current_if_assigned
--------------------------
(1 row)
á ááľ ááĽááľ áááĽá áááἠá¨ááᨠáĽááá°áᣠáአá¨ááĽááľ ááĽá áá°á áá á˘
=> UPDATE accounts SET amount = amount - 1.00;
=> SELECT txid_current_if_assigned();
txid_current_if_assigned
--------------------------
3667
(1 row)
=> COMMIT;
á¨áá ááĽááśá˝
ááĽáŚá˝á áŤáľáááĄ
á SQL ááľáĽ ááááťá ááĽáŚá˝á áŤáľááᥠ(savepoint)ᣠáá á á¨á ááľá ááĽááľ áá á áá áłáŤááᥠáĽáá˛á°áá áŤáľá˝áááłáᢠááá áá áá á¨áá áŤáá áĽááá ááá፠áá á ááŁáŁáá ᣠááááŤáąá ááĽááą áááá áááŚáš á°ááłáłá áááł áľááá áĽá á á áŤá ááá ááἠá ááááľáá˘
áá áá á°ááŁá á°ááŁáŤá áááľá¨áᣠá¨áá ᣠááĽáĽ áá á¨áá°á¨á ááĽááľ á á°ááŤáŠ á°á¨áááᢠá¨á°á¨áḠááĽááśá˝ (áááľ ááĽááľ) ᣠá¨áááłá áááł á á°ááĽá áá°áłá°á áá˝ááá˘
á¨áá ááĽááśá˝ á¨áŤáłá¸á ááĽá á áá¸á (á¨ááá ááĽááľ ááĽá á¨á áŤá)ᢠá¨áá ááĽááśá˝ áááł á XACT ááľáĽ á á°ááá°á ááááľ á°áááá§á, ááá áá á¨áá¨á¨áťá áááł á ááá ááĽááľ áááł áá á¨á°áá°á¨á° áá: á¨á°á°á¨á, ááá á¨á°áá ááĽááśá˝ áĽáá˛á áá°á¨áá.
áľá ááĽááľ ááá°áť áá¨á á PGDATA/pg_subtrans áá፠ááľáĽ áŁá áááá˝ ááľáĽ á°á¨áá˝áˇáᢠáááá˝ áĽáá° XACT ááśá˝ á á°ááłáłá ááአá á°á°áŤá á¨ááłáá á¨á፠áá á°á¨ áľááľáł ááľáĽ áŁá ááľ á áŠá áá°ááłáá˘
á¨áá ááĽááśá˝á á¨áŤáľ áá ááĽááśá˝ áá á áŤááłáąá˘ á áŤáľ áá á¨áá°á¨á ááĽááśá˝ á ááá ááአá ááłá¸á á ááá áá á¨á°áአá áá°ááᣠááá áá á¨áá ááĽááśá˝ áá¸áᢠá áá°á á PostgreSQL ááľáĽ á¨áŤáľ áá ááĽááśá˝ á¨áá ᣠáĽá ááááŁáľá ᣠáá á: á áŁá á áŁá á áá á áá áŤáľáááá ᣠáĽá á ááá˝ á˛á˘á¤áá¤áľ ááľáĽ ááááłá¸á áĽááááľá áŤááłáłá ᣠá¨á፠ááá á°á áá°ááŤáá˘
á áá á¨áĄá áĽáá˝áłáŁ ááĽááľ áĽááááá á¨áľáá áĽááľááŁáĄ
=> 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)
á áá á¨ááľáá፠ááĽáĽ áĽááľááἠáĽá áá ááľáá á áľááŁá˘
=> SAVEPOINT sp;
=> INSERT INTO t(s) VALUES ('XYZ');
=> SELECT txid_current();
txid_current
--------------
3669
(1 row)
ᨠtxid_current() á°ááŁá á¨áááá°á áááá á¨ááĽááľ ááĽá áĽáá á¨áááá á¨ááĽááľ ááĽá áĽááłááá áἠáá áá˘
=> 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)
áá° áá ᣠááĽáĽ áĽááááľá áśáľá°ááá ááľáá áĽááľááŁá˘
=> 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)
á ááš áá á á°á°á¨áá á¨á°á°á¨á ááĽááľ á¨áłá¨ááá á¨áľá áá¨áľ áĽáááĽáááá˘
áááŚášá áĽááľá°áŤáááá.
=> 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)
á áá áĽáŤááłááą á¨áá ááĽááľ á¨áŤáą á¨áá á áá áĽááłáá á ááá áá¨áľ áá˝ááá˘
á¨áá ááĽááśá˝ á SQL ááľáĽ á ááá˝ áĽá á áá ááá áĽáá°ááá˝á áἠáá áᣠáááľáᣠá¨á ááá áłáá¨ááą á á˛áľ ááĽááľ áááá á áá˝ááᢠáá áá´ á¨ááłá ááĽáŚá˝á á˛á ááᣠáĽáá˛áá á¨PL/pgSQL áአáááłáá˝á á˛á áá áĽá á ááá˝ á ááŤáł áŤáá°áááą ááłáŽá˝ áá á á°ááá᪠áá áŤáá˘
=> BEGIN;
BEGIN
=> BEGIN;
WARNING: there is already a transaction in progress
BEGIN
=> COMMIT;
COMMIT
=> COMMIT;
WARNING: there is no transaction in progress
COMMIT
áľá á°áśá˝ áĽá á¨ááááá˝ áśáá˛
ááś áĽáá á áá°á¨áá áľ áá áľá á°áľ á¨á°áá ᨠáá áá¨á°áłá? áááłáᣠáĽáá°áá áĄ-
=> 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;
ERROR: current transaction is aborted, commands ignored until end of transaction block
áĽá áááŚášá áááá¸á á˘áááŠáᣠPostgreSQL áááá áŞáááľ áŤá°ááááĄ-
=> COMMIT;
ROLLBACK
ááááľáá ááĽááą á¨á°áłáŤ á áá ááá á áŤááťáá? áĽáááłá áá á¨áááŚášá á¨áá ááłá¨áť áááááľ á ááŤáľá˝á ááááľ áľá á°áľ ááá á áá˝áá - á¨ááĽááąá áĽááłá á áááťá ᣠáá áŚááŹá°áŠ ááŁáłáᢠáĽáá° ááłáá á˝áᣠá¨áľá á°áą á ááľ áŚááŹá°áŠ á ááľ ááľáá áááá á¨áťáá áľáĄ-
=> 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)
psql á¨á°áłáłáą áŚááŹá°áŽá˝ áľáááśá˝ áá° áá áĽáá°á°áááą áŤá á á ááá ááĽááą á¨á°áłáŤ á áá áĽáá˛ááĽá á¨ááŤáľá˝á áááł á áá ááŁá áááŁá.
=> 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;
á áá áááł psql á¨áĽáŤááłááą áľááá á ááľ áľáá á¨ááľáá፠ááĽáĽ áĽáá°ááŤáľááá á áááááľ á áľá¸á᪠á áá°áá, áĽá áŤáá°áłáŤ áá° áĽáą ááááľá ááááŤá. áá áááł á ááŁáŞááľ áĽá á áá á áááá, ááááŤáąá á¨ááľáá፠ááĽáŚá˝á áááá á (áá° áĽáááą áłááááą áĽááłá) á¨áá°á ááŞá áŤáŤáľáłá.
ááá: hab.com