PostgreSQL-3 рдореЗрдВ MVCCред рдкрдВрдХреНрддрд┐ рд╕рдВрд╕реНрдХрд░рдг

рдЦреИрд░, рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдЕрд▓рдЧрд╛рд╡ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рд╣реИ рдФрд░ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╡рд┐рд╖рдпрд╛рдВрддрд░ рдХрд┐рдпрд╛ рд╣реИред рдФрд░ рд╣рдо рдЕрдВрдд рдореЗрдВ рд╕рдмрд╕реЗ рдЖрдХрд░реНрд╖рдХ рдЪреАрдЬрд╝ рддрдХ рдкрд╣реБрдБрдЪ рдЧрдП рд╣реИрдВ, рд╡рд╣ рд╣реИ, рдкрдВрдХреНрддрд┐ рд╕рдВрд╕реНрдХрд░рдг (рдЯреНрдпреВрдкрд▓реНрд╕)ред

рдЯрдкрд▓ рд╢реАрд░реНрд╖рдХ


рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреЗ рдХрдИ рд╕рдВрд╕реНрдХрд░рдг рдПрдХ рд╕рд╛рде рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреВрд╕рд░реЗ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЗрд╕рдХреЗ рдкреНрд░рднрд╛рд╡реА "рд╕рдордп" ( xmin ) рдФрд░ "рд╕рдордп" ( xmax ) рдХреА рд╕рдорд╛рдкреНрддрд┐ рдХреЗ рд╕рд╛рде рд▓реЗрдмрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЙрджреНрдзрд░рдг рдЪрд┐рд╣реНрдиреЛрдВ рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡реЗрддрди рд╡реГрджреНрдзрд┐ рдХрд╛рдЙрдВрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдордп рдХреЗ рдмрдЬрд╛рдп рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдпрд╣ рдХрд╛рдЙрдВрдЯрд░ рд▓реЗрдирджреЗрди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ ред

(рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ: рд▓реЗрди-рджреЗрди рдЖрдИрдбреА рд╣рдореЗрд╢рд╛ рдХрд╛рдЙрдВрдЯрд░ рдХреА рдПрдХ рд╕реАрдорд┐рдд рдмрд┐рдЯ рдЧрд╣рд░рд╛рдИ рдХреЗ рдХрд╛рд░рдг рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рддрдм рдкрд╛рдПрдВрдЧреЗ рдЬрдм рд╣рдорд╛рд░реА рдЪрд░реНрдЪрд╛ рдардВрдб рддрдХ рдкрд╣реБрдВрдЪ рдЬрд╛рдПрдЧреАред)

рдЬрдм рдПрдХ рдкрдВрдХреНрддрд┐ рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИ, рддреЛ xmin рдХрд╛ рдореВрд▓реНрдп INSERT рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд▓реЗрдирджреЗрди рдХреА рдЖрдИрдбреА рдХреЗ рдмрд░рд╛рдмрд░ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ xmax рдореЗрдВ рднрд░рд╛ рдирд╣реАрдВ рдЬрд╛рддрд╛ рд╣реИред

рдЬрдм рдХреЛрдИ рдкрдВрдХреНрддрд┐ рд╣рдЯрд╛ рджреА рдЬрд╛рддреА рд╣реИ, рддреЛ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдХреЗ xmax рдорд╛рди рдХреЛ рдЙрд╕ рд╕реМрджреЗ рдХреА рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рд▓реЗрдмрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ DELETE рдХрд░рддрд╛ рд╣реИред

рдПрдХ рдЕрджреНрдпрддрди рдЖрджреЗрд╢ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдмрд╛рдж рдХреЗ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ: DELETE рдФрд░ INSERTред рдкрдВрдХреНрддрд┐ рдХреЗ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, xmax рдХреЛ рдЙрд╕ рд▓реЗрдирджреЗрди рдХреА рдЖрдИрдбреА рдХреЗ рдмрд░рд╛рдмрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ UPDATE рдХреЛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдлрд┐рд░ рдЙрд╕реА рдкрдВрдХреНрддрд┐ рдХрд╛ рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ xmin рдХрд╛ рдорд╛рди рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ xmax рдХреЗ рд╕рдорд╛рди рд╣реЛрддрд╛ рд╣реИред

xmin рдФрд░ xmax рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╣реЗрдбрд░ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЯрдкрд▓ рд╣реЗрдбрд░ рдореЗрдВ рдЕрдиреНрдп рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬреИрд╕реЗ:

  • infomask - рдХрдИ рдмрд┐рдЯреНрд╕ рдЬреЛ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдЯрдкрд▓ рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЙрдирдореЗрдВ рд╕реЗ рдХрд╛рдлреА рдХреБрдЫ рд╣реИрдВ, рдФрд░ рд╣рдо рд╕рдордп рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗред
  • ctid - рдПрдХ рд╣реА рдкрдВрдХреНрддрд┐ рдХреЗ рдЕрдЧрд▓реЗ, рдЕрдзрд┐рдХ рд╣рд╛рд▓ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджрд░реНрднред рдирд╡реАрдирддрдо, рдЕрдк-рдЯреВ-рдбреЗрдЯ, рдкрдВрдХреНрддрд┐ рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ ctid рдЬреЛ рдмрд╣реБрдд рд╣реА рд╕рдВрд╕реНрдХрд░рдг рд╣реИред рд╕рдВрдЦреНрдпрд╛ (x,y) рдлреЙрд░реНрдо рдореЗрдВ рд╣реИ, рдЬрд╣рд╛рдВ x рдкреГрд╖реНрда рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдФрд░ y рд╕рд░рдгреА рдореЗрдВ рдкреЙрдЗрдВрдЯрд░ рдХреА рдХреНрд░рдо рд╕рдВрдЦреНрдпрд╛ рд╣реИред
  • NULLs рдмрд┐рдЯрдореИрдк, рдЬреЛ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдЙрди рд╕реНрддрдВрднреЛрдВ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдирдореЗрдВ NULL рд╣реЛрддрд╛ рд╣реИред NULL рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рдирд┐рдпрдорд┐рдд рдореВрд▓реНрдп рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рдирддреАрдЬрддрди, рд╣реЗрдбрд░ рдмрд╣реБрдд рдмрдбрд╝рд╛ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ рдЯреНрдпреВрдкрд▓ рдкрд░ 23 рдмрд╛рдЗрдЯреНрд╕ рдХрдо рд╕реЗ рдХрдо, рд▓реЗрдХрд┐рди рдЖрдорддреМрд░ рдкрд░ рдирд▓ рдмрд┐рдЯрдореИрдк рдХреЗ рдХрд╛рд░рдг рдмрдбрд╝рд╛ рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ "рд╕рдВрдХреАрд░реНрдг" рд╣реИ (рдЕрд░реНрдерд╛рдд, рдЗрд╕рдореЗрдВ рдХреБрдЫ рдХреЙрд▓рдо рд╣реИрдВ), рдУрд╡рд░рд╣реЗрдб рдмрд╛рдЗрдЯреНрд╕ рдЕрдзрд┐рдХ рд╕реНрдерд╛рди рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧреА рдЬрд╛рдирдХрд╛рд░реА рд╣реИред

рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ


рдЖрдЗрдП рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рджреЗрдЦреЗрдВ рдХрд┐ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдкрд░ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдкрд░ рд╕рдВрдЪрд╛рд▓рди рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рдо рдПрдХ рд╕рдореНрдорд┐рд▓рд┐рдд рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рджреЛ рд╕реНрддрдВрднреЛрдВ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рдПрдХ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдирдИ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдПрдВрдЧреЗ:

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

рдкреЗрдЬ рдХреА рд╕рд╛рдордЧреНрд░реА рдкрд░ рдирдЬрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВред "Pageinspect" рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реЗ heap_page_items рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрдВ рд╕рдВрдХреЗрдд рдФрд░ рдкрдВрдХреНрддрд┐ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддрд╛ рд╣реИ:

 => 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 рдЬреИрд╕рд╛ t_ctid : (рдкреГрд╖реНрда рд╕рдВрдЦреНрдпрд╛, рд╕реВрдЪрдХ рд╕рдВрдЦреНрдпрд╛)ред
  • lp_flags рдкреЙрдЗрдВрдЯрд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреАред рдпрд╣ рдпрд╣рд╛рдВ "рд╕рд╛рдорд╛рдиреНрдп" рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╕реВрдЪрдХ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдкрдВрдХреНрддрд┐ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддрд╛ рд╣реИред рд╣рдо рдмрд╛рдж рдореЗрдВ рдЕрдиреНрдп рдореВрд▓реНрдпреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗред
  • рд╕рднреА рд╕реВрдЪрдирд╛ рдмрд┐рдЯреНрд╕ рдореЗрдВ рд╕реЗ, рд╣рдордиреЗ рдЕрдм рддрдХ рдХреЗрд╡рд▓ рджреЛ рдЬреЛрдбрд╝реЗ рдЪреБрдиреЗ рд╣реИрдВред xmin_committed рдФрд░ xmin_aborted рдмрд┐рдЯреНрд╕ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВ рдХрд┐ ID xmin рд╕рд╛рде рд▓реЗрди-рджреЗрди рдкреНрд░рддрд┐рдмрджреНрдз рд╣реИ (рд╡рд╛рдкрд╕ рд▓реБрдврд╝рдХрд╛)ред рд╕рдорд╛рди рдмрд┐рдЯреНрд╕ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдЖрдИрдбреА xmax рд╕рд╛рде рд▓реЗрдирджреЗрди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред

рд╣рдо рдХреНрдпрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╣реИрдВ? рдЬрдм рдПрдХ рдкрдВрдХреНрддрд┐ рдбрд╛рд▓реА рдЬрд╛рддреА рд╣реИ, рддреЛ рддрд╛рд▓рд┐рдХрд╛ рдкреГрд╖реНрда рдореЗрдВ рдПрдХ рд╕рдВрдХреЗрддрдХ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдирдВрдмрд░ 1 рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкрдВрдХреНрддрд┐ рдХреЗ рдкрд╣рд▓реЗ рдФрд░ рдПрдХрдорд╛рддреНрд░ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИред

рдЯрдкрд▓ рдореЗрдВ xmin рдлрд╝реАрд▓реНрдб рдХреЛ рд╡рд░реНрддрдорд╛рди рд▓реЗрдирджреЗрди рдХреА рдЖрдИрдбреА рд╕реЗ рднрд░рд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рд▓реЗрди-рджреЗрди рдЕрднреА рднреА рд╕рдХреНрд░рд┐рдп рд╣реИ, xmin_committed рдФрд░ xmin_aborted рдмрд┐рдЯреНрд╕ рджреЛрдиреЛрдВ xmin_committed рд╣реИрдВред

рдкрдВрдХреНрддрд┐ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ 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 (рдХрдорд┐рдЯ рд▓реЙрдЧ) рдХрд╣рд╛ рдЬрд╛рддрд╛ рдерд╛, рдФрд░ рдЖрдкрдХреЛ рдЕрднреА рднреА рдЗрд╕ рдирд╛рдо рдХреЗ рдЖрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред)

XACT рд╕рд┐рд╕реНрдЯрдо рдХреИрдЯрд▓реЙрдЧ рдХреА рддрд╛рд▓рд┐рдХрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди PGDATA / pg_xact рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдлрд╝рд╛рдЗрд▓реЗрдВред рдкреНрд░рддреНрдпреЗрдХ рд▓реЗрдирджреЗрди рдХреЗ рд▓рд┐рдП рдЗрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рджреЛ рдмрд┐рдЯреНрд╕ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ - "рдкреНрд░рддрд┐рдмрджреНрдз" рдФрд░ "рдирд┐рд░рд╕реНрдд" - рдареАрдХ рдЙрд╕реА рддрд░рд╣ рдЬреИрд╕реЗ рдЯреБрдкреЗрд▓ рд╣реИрдбрд░ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдХреЗрд╡рд▓ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рдХрдИ рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рдлреИрд▓реА рд╣реБрдИ рд╣реИ; рдЬрдм рд╣рдо рдардВрдб рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗ рддреЛ рд╣рдо рдЗрд╕ рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯ рдЖрдПрдВрдЧреЗред PostgreSQL рдЗрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдкреЗрдЬ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЕрдиреНрдп рд╕рднреА рдХреЗ рд╕рд╛рдеред

рдЗрд╕рд▓рд┐рдП, рдЬрдм рдХреЛрдИ рд▓реЗрдирджреЗрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ XACT рдореЗрдВ рдЗрд╕ рд▓реЗрдирджреЗрди рдХреЗ рд▓рд┐рдП "рдкреНрд░рддрд┐рдмрджреНрдз" рдмрд┐рдЯ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╕рдм рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рд▓реЗрдирджреЗрди рдкреНрд░рддрд┐рдмрджреНрдз рд╣реЛрддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рдо рдЕрднреА рддрдХ рд░рд╛рдЗрдЯ-рдлреЙрд░рд╡рд░реНрдб рд▓реЙрдЧ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ)ред

рдЬрдм рдХреБрдЫ рдЕрдиреНрдп рд▓реЗрди-рджреЗрди рддрд╛рд▓рд┐рдХрд╛ рдкреГрд╖реНрда рдкрд░ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдо рдЕрднреА рджреЗрдЦ рд░рд╣реЗ рдереЗ, рддреЛ рдкреВрд░реНрд╡ рдХреЛ рдХреБрдЫ рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рджреЗрдиреЗ рд╣реЛрдВрдЧреЗред

  1. рдХреНрдпрд╛ рд▓реЗрдирджреЗрди xmin рдкреВрд░рд╛ рд╣реБрдЖ рдерд╛? рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдмрдирд╛рдИ рдЧрдИ рдЯрдкрд▓ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрдиреА рдЪрд╛рд╣рд┐рдПред
    рдпрд╣ рдПрдХ рдЕрдиреНрдп рд╕рдВрд░рдЪрдирд╛ рдХреЛ рджреЗрдЦрдХрд░ рдЬрд╛рдВрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЗрдВрд╕реНрдЯрд╛ рдХреА рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ рдФрд░ рдЬрд┐рд╕реЗ ProcArray рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рдВрд░рдЪрдирд╛ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рд╡рд░реНрддрдорд╛рди (рд╕рдХреНрд░рд┐рдп) рд▓реЗрдирджреЗрди рдХреА рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рд╕рднреА рд╕рдХреНрд░рд┐рдп рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд░рдЦрддреА рд╣реИред
  2. рдпрджрд┐ рд▓реЗрдирджреЗрди рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рдерд╛, рддреЛ рдХреНрдпрд╛ рдпрд╣ рдкреНрд░рддрд┐рдмрджреНрдз рдерд╛ рдпрд╛ рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ рдерд╛? рдпрджрд┐ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЯрдкрд▓ рдХреЛ рднреА рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред
    рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ XACT рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд▓реЗрдХрд┐рди рд╣рд░ рдмрд╛рд░ XACT рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ рдорд╣рдВрдЧрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдБрдХрд┐ XACT рдХреЗ рдЕрдВрддрд┐рдо рдкреГрд╖реНрда рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА рдореЗрдВ рдмрдлрд╝рд░реНрд╕ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдПрдХ рдмрд╛рд░ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд▓реЗрди-рджреЗрди рдХреА рд╕реНрдерд┐рддрд┐ xmin_committed рдФрд░ xmin_aborted рдмрд┐рдЯреНрд╕ рдХреЛ рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдмрд┐рдЯ рд╕реЗрдЯ рд╣реИ, рддреЛ рд▓реЗрдирджреЗрди рдХреА рд╕реНрдерд┐рддрд┐ рдЬреНрдЮрд╛рдд рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдиреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдЕрдЧрд▓реЗ рд▓реЗрдирджреЗрди рдХреЛ XACT рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред

рд▓реЗрди-рджреЗрди рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд▓реЗрдирджреЗрди рдЗрди рдмрд┐рдЯреНрд╕ рдХреЛ рд╕реЗрдЯ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ? рдЬрдм рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреА рдЬрд╛ рд░рд╣реА рд╣реИ, рддреЛ рд▓реЗрди-рджреЗрди рдЕрднреА рддрдХ рдЗрд╕ рдмрд╛рдд рд╕реЗ рдЕрдирдЬрд╛рди рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рдкреНрд░рддрд┐рдмрджреНрдз рд╕рдордп рдореЗрдВ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреМрди рд╕реА рдкрдВрдХреНрддрд┐рдпрд╛рдБ рдФрд░ рдХреМрди рд╕реЗ рдкреГрд╖реНрда рдмрджрд▓реЗ рдЧрдП рд╣реИрдВред рдРрд╕реЗ рдХрдИ рдкреГрд╖реНрда рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЙрди рдкрд░ рдирдЬрд╝рд░ рд░рдЦрдирд╛ рдЕрд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреБрдЫ рдкреЗрдЬ рдмрдлрд░ рдХреИрд╢ рд╕реЗ рдбрд┐рд╕реНрдХ рд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ; рдмрд┐рдЯреНрд╕ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдлрд┐рд░ рд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрджреНрдз рдХреА рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдордВрджреА рдХрд╛ рдорддрд▓рдм рд╣реЛрдЧрд╛ред

рд▓рд╛рдЧрдд рдмрдЪрдд рдХрд╛ рдЙрд▓реНрдЯрд╛ рдкрдХреНрд╖ рдпрд╣ рд╣реИ рдХрд┐ рдЕрдкрдбреЗрдЯ рдХреЗ рдмрд╛рдж, рдХреЛрдИ рднреА рд▓реЗрдирджреЗрди (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рд╡рд╛рд▓рд╛) рднреА рдмрдлрд░ рдХреИрд╢ рдореЗрдВ рдбреЗрдЯрд╛ рдкреЗрдЬ рдмрджрд▓рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП, рд╣рдо рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рддреЗ рд╣реИрдВред

 => 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 рд▓реЗрдирджреЗрди рдкреВрд░рд╛ рд╣реЛрдиреЗ рддрдХ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдмрд╛рдж рдореЗрдВ рддрд╛рд▓реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдХреЗрд╡рд▓ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкрдВрдХреНрддрд┐ рддрд╛рд▓реЗ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИред рд╡реЗ рдореЗрдореЛрд░реА рдкрд░ рдХрдмреНрдЬрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рджрд░реНрд╢рди рдЙрд╕ рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рд▓реЗрди-рджреЗрди рдореЗрдВ рдЕрдиреНрдп рдХрдорд┐рдпрд╛рдВ рд╣реИрдВ, рдЬрд┐рди рдкрд░ рдмрд╛рдж рдореЗрдВ рднреА рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред

рдЪрд▓реЛ рдПрдХ рдкрдВрдХреНрддрд┐ рд╣рдЯрд╛ рджреЗрдВред

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

рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд▓реЗрдирджреЗрди рдЖрдИрдбреА xmax рдлрд╝реАрд▓реНрдб рдХреЛ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реВрдЪрдирд╛ рдмрд┐рдЯреНрд╕ 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; => 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 рдмрд┐рдЯ рд░реАрд╕реЗрдЯ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╡рд░реНрддрдорд╛рди рд▓реЗрдирджреЗрди рдХреА рд╕реНрдерд┐рддрд┐ рдЕрднреА рддрдХ рдЕрдЬреНрдЮрд╛рдд рд╣реИред

рдкрдВрдХреНрддрд┐ рдХрд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЕрдм рджреВрд╕рд░реЗ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реИ, рдПрдХ рдирдП рдХреЗ рд░реВрдк рдореЗрдВред

рдЗрдВрдбреЗрдХреНрд╕ рдкреЗрдЬ рдореЗрдВ рдЕрдм рджреВрд╕рд░реА рдкреЙрдЗрдВрдЯрд░ рдФрд░ рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рд╣реИ, рдЬреЛ рдЯреЗрдмрд▓ рдкреЗрдЬ рдореЗрдВ рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддреА рд╣реИред

рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрд╕реА рддрд░рд╣, рдкрд╣рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ xmax рдХрд╛ рдорд╛рди рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкрдВрдХреНрддрд┐ рд▓реЙрдХ рд╣реИред

рдЕрдВрдд рдореЗрдВ, рд╣рдо рд▓реЗрди-рджреЗрди рдХрд░рддреЗ рд╣реИрдВред

 => COMMIT; 

рдЗрдВрдбреЗрдХреНрд╕


рд╣рдо рдЕрдм рддрдХ рдХреЗрд╡рд▓ рддрд╛рд▓рд┐рдХрд╛ рдкреГрд╖реНрдареЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рдереЗред рд▓реЗрдХрд┐рди рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рдЕрдВрджрд░ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ?

рд╕реВрдЪрдХрд╛рдВрдХ рдкреГрд╖реНрдареЛрдВ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реВрдЪрдХрд╛рдВрдХ рдкреНрд░рдХрд╛рд░ рдкрд░ рдЕрддреНрдпрдзрд┐рдХ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреГрд╖реНрда рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдмреА-рдЯреНрд░реА рдореЗрдВ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдкреГрд╖реНрда рдФрд░ "рд╕рд╛рдорд╛рдиреНрдп" рдкреГрд╖реНрда рд╣реЛрддреЗ рд╣реИрдВред

рдлрд┐рд░ рднреА, рдПрдХ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдкреГрд╖реНрда рдореЗрдВ рдЖрдорддреМрд░ рдкрд░ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдФрд░ рд╕реНрд╡рдпрдВ рдХреЛ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреА рдУрд░ рд╕рдВрдХреЗрдд рд╣реЛрддрд╛ рд╣реИ (рдЬреИрд╕реЗ рддрд╛рд▓рд┐рдХрд╛ рдкреГрд╖реНрда)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдкреГрд╖реНрда рдХреЗ рдЕрдВрдд рдореЗрдВ рдХреБрдЫ рд╕реНрдерд╛рди рд╡рд┐рд╢реЗрд╖ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рд╕реВрдЪрдХрд╛рдВрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрд░рдЪрдирд╛рдПрдВ рднреА рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдПрдХ рдмреА-рдЯреНрд░реА рдореЗрдВ, рдкрддреНрддрд╛ рдкрдиреНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдЕрдиреБрдХреНрд░рдордг рдХреБрдВрдЬреА рдФрд░ рдПрдХ рд╕рдВрджрд░реНрдн ( ctid ) рдХрд╛ 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; 

Subtransactions


Savepoints


SQL рдореЗрдВ, savepoint рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдЬреЛ рдмрд┐рдирд╛ рдЗрд╕рдХреЗ рдкреВрд░реНрдг рдЧрд░реНрднрдкрд╛рдд рдХреЗ рд▓реЗрдирджреЗрди рдХреЗ рдХреБрдЫ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдЙрдкрд░реЛрдХреНрдд рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рдЕрд╕рдВрдЧрдд рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд▓реЗрди-рджреЗрди рдХреА рд╕реНрдерд┐рддрд┐ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реИ рдФрд░ рдХреЛрдИ рднреА рдбреЗрдЯрд╛ рд╢рд╛рд░реАрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕реЗрд╡рдкреЙрдЗрдВрдЯ рдХреЗ рд╕рд╛рде рд▓реЗрди-рджреЗрди рдХреЛ рдХрдИ рдЕрд▓рдЧ - рдЕрд▓рдЧ рдЙрдк - рдпреЛрдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рдирдХреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

Subtrabsactions рдХреА рдЕрдкрдиреА рдЖрдИрдбреА (рдореБрдЦреНрдп рд▓реЗрдирджреЗрди рдХреА рдЖрдИрдбреА рд╕реЗ рдЕрдзрд┐рдХ) рд╣реЛрддреА рд╣реИред рд╕рдмрдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рдХреА рд╕реНрдерд┐рддрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ XACT рдХреЛ рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдореБрдЦреНрдп рд▓реЗрдирджреЗрди рдХреА рд╕реНрдерд┐рддрд┐ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ: рдпрджрд┐ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рднреА рд╕рдмрдЯреНрд░реЗрдХреНрдЯ рд╡рд╛рдкрд╕ рднреА рд░реЛрд▓рдЖрдЙрдЯ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред

рдШрдЯрд╛рд╡ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА PGDATA / pg_subtrans рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред рдЗрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреА рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА рдореЗрдВ рдмрдлрд╝рд░реНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рдиреНрд╣реЗрдВ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рд╕рдВрд░рдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреИрд╕реЗ XACT рдмрдлрд╝рд░реНрд╕ред

рд╕реНрд╡рд╛рдпрддреНрдд рд▓реЗрдирджреЗрди рдХреЗ рд╕рд╛рде рдШрдЯрд╛рд╡ рдХреЛ рднреНрд░рдорд┐рдд рди рдХрд░реЗрдВред рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рд╕реНрд╡рд╛рдпрддреНрдд рд▓реЗрдирджреЗрди рдПрдХ рджреВрд╕рд░реЗ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рд╕рдмрдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВред рдирд┐рдпрдорд┐рдд PostgreSQL рдореЗрдВ рдХреЛрдИ рд╕реНрд╡рд╛рдпрддреНрдд рд▓реЗрдирджреЗрди рдирд╣реАрдВ рд╣реИрдВ, рдЬреЛ рдХрд┐, рд╢рд╛рдпрдж, рдмреЗрд╣рддрд░ рдХреЗ рд▓рд┐рдП: рдЙрдиреНрд╣реЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрддреНрдпрдВрдд рджреБрд░реНрд▓рдн рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдЕрдиреНрдп DBMS рдореЗрдВ рдЙрдирдХреА рдЙрдкрд▓рдмреНрдзрддрд╛ рджреБрд░реНрд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдЖрдордВрддреНрд░рд┐рдд рдХрд░рддреА рд╣реИ, рдЬреЛ рд╣рд░ рдХреЛрдИ рдЧреНрд░рд╕реНрдд рд╣реИред

рдЖрдЗрдП рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ, рдПрдХ рд▓реЗрдирджреЗрди рд╢реБрд░реВ рдХрд░реЗрдВ рдФрд░ рдПрдХ рдкрдВрдХреНрддрд┐ рдбрд╛рд▓реЗрдВ:

 => 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 рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рджреВрд╕рд░реА рдкрдВрдХреНрддрд┐ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВред

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

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ txid_current рдлрд╝рдВрдХреНрд╢рди рдореБрдЦреНрдп рд▓реЗрди-рджреЗрди рдХреА рдЖрдИрдбреА рдХреЛ 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 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) 

рдЕрдм рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджреЗрдЦрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрд╛рд╡ рдХреА рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рд╣реИред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдПрд╕рдХреНрдпреВрдПрд▓, рд╕рдмрдЯреНрд░реЗрди рдХреЗ рд╕реНрдкрд╖реНрдЯ рдЙрдкрдпреЛрдЧ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рдЖрдк рд╡рд░реНрддрдорд╛рди рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдирдпрд╛ рд▓реЗрдирджреЗрди рд╢реБрд░реВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдпрд╣ рддрдХрдиреАрдХ рддрдм рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИ рдЬрдм рдкреАрдПрд▓рд╕реА / рдкреАрдЬреАрдХреНрдпреВрдПрд▓ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдХреБрдЫ рдЕрдиреНрдп, рдЕрдзрд┐рдХ рд╡рд┐рджреЗрд╢реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдмрдЪрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

 => 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 рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХрдорд╛рдВрдб рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдмрдЪрдд рдмрд┐рдВрджреБ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдлрд▓рддрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЗрд╕реЗ рд░реЛрд▓рдмреИрдХ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдореЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕реЗрд╡рдкреЙрдЗрдВрдЯ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╕реЗ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрдирдХреЗ рд▓рд┐рдП рд░реЛрд▓рдмреИрдХ рдХреЗ рдмрд┐рдирд╛) рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдУрд╡рд░рд╣реЗрдб рдкрд░ рдЬреЛрд░ рджреЗрддрд╛ рд╣реИред

рдкрд░ рдкрдврд╝реЗрдВ ред

Source: https://habr.com/ru/post/hi477648/


All Articles