рдЬрдм VACUUM рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕рд╛рдлрд╝ рдХрд░рддреЗ рд╣реИрдВ

рд╡реИрдХреНрдпреВрдо PostgreSQL рдореЗрдВ рдХрд┐рд╕реА рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдХреЗрд╡рд▓ "рд╕рд╛рдл" рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХреЛрдИ рдирд╣реАрдВ рджреЗрдЦ рд╕рдХрддрд╛ - рдпрд╛рдиреА, рдРрд╕рд╛ рдПрдХ рднреА рд╕рдХреНрд░рд┐рдп рдЕрдиреБрд░реЛрдз рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЗрди рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХреЛ рдмрджрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╢реБрд░реВ рд╣реБрдЖ рд╣реЛред

рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдРрд╕рд╛ рдЕрдкреНрд░рд┐рдп рдкреНрд░рдХрд╛рд░ (рдУрдПрд▓рдЯреАрдкреА рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░ рджреАрд░реНрдШрдХрд╛рд▓рд┐рдХ рдУрдПрд▓рдПрдкреА рд▓реЛрдб) рдЕрднреА рднреА рдореМрдЬреВрдж рд╣реИ? рдХреИрд╕реЗ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдмрджрд▓рддреА рд╣реБрдИ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ рд▓рдВрдмреЗ рдкреНрд░рд╢реНрдиреЛрдВ рд╕реЗ рдШрд┐рд░реЗ рд╣реБрдП рд╣реИрдВ рдФрд░ рд░реЗрдХ рдкрд░ рдХрджрдо рдирд╣реАрдВ рд░рдЦ рд░рд╣реЗ рд╣реИрдВ?

рдЬрдм VACUUM рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕рд╛рдлрд╝ рдХрд░рддреЗ рд╣реИрдВ

рд░реЗрдХ рдХреЛ рдЦреЛрд▓рдирд╛

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдЬрд┐рд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡рд╣ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреИрд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛ рд╕рдХрддреА рд╣реИред

рдЖрдорддреМрд░ рдкрд░ рдпрд╣реА рд╕реНрдерд┐рддрд┐ рд╣реЛрддреА рд╣реИ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЫреЛрдЯреА рдореЗрдЬ рдкрд░, рд▓реЗрдХрд┐рди рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдШрдЯрд┐рдд рд╣реЛрддрд╛ рд╣реИ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдмрджрд▓рд╛рд╡. рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рдпрд╛ рдЕрд▓рдЧ рдореАрдЯрд░/рд╕рдореБрдЪреНрдЪрдп/рд░реЗрдЯрд┐рдВрдЧ, рдЬрд┐рд╕ рдкрд░ рдЕрджреНрдпрддрди рдЕрдХреНрд╕рд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╛ рдмрдлрд╝рд░-рдХрддрд╛рд░ рдШрдЯрдирд╛рдУрдВ рдХреА рдХреБрдЫ рдирд┐рд░рдВрддрд░ рдЪрд▓ рд░рд╣реА рдзрд╛рд░рд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬрд┐рд╕рдХреЗ рд░рд┐рдХреЙрд░реНрдб рд▓рдЧрд╛рддрд╛рд░ рд╕рдореНрдорд┐рд▓рд┐рдд/рд╣рдЯрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдЖрдЗрдП рд░реЗрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд▓реНрдк рдХреЛ рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

CREATE TABLE tbl(k text PRIMARY KEY, v integer);
CREATE INDEX ON tbl(v DESC); -- ╨┐╨╛ ╤Н╤В╨╛╨╝╤Г ╨╕╨╜╨┤╨╡╨║╤Б╤Г ╨▒╤Г╨┤╨╡╨╝ ╤Б╤В╤А╨╛╨╕╤В╤М ╤А╨╡╨╣╤В╨╕╨╜╨│

INSERT INTO
  tbl
SELECT
  chr(ascii('a'::text) + i) k
, 0 v
FROM
  generate_series(0, 25) i;

рдФрд░ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ, рдПрдХ рдЕрдиреНрдп рдХрдиреЗрдХреНрд╢рди рдореЗрдВ, рдПрдХ рд▓рдВрдмрд╛, рд▓рдВрдмрд╛ рдЕрдиреБрд░реЛрдз рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдХреБрдЫ рдЬрдЯрд┐рд▓ рдЖрдБрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рдирд╛, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реА рддрд╛рд▓рд┐рдХрд╛ рдкрд░ рдХреЛрдИ рдкреНрд░рднрд╛рд╡ рдирд╣реАрдВ рдкрдбрд╝ рд░рд╣рд╛ рд╣реИ:

SELECT pg_sleep(10000);

рдЕрдм рд╣рдо рдХрд┐рд╕реА рдПрдХ рдХрд╛рдЙрдВрдЯрд░ рдХрд╛ рдорд╛рди рдХрдИ-рдХрдИ рдмрд╛рд░ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдкреНрд░рдпреЛрдЧ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ dblink рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд▓реЗрдирджреЗрди рдореЗрдВрд╣рдХреАрдХрдд рдореЗрдВ рдпрд╣ рдХреИрд╕реЗ рд╣реЛрдЧрд╛:

DO $$
DECLARE
  i integer;
  tsb timestamp;
  tse timestamp;
  d double precision;
BEGIN
  PERFORM dblink_connect('dbname=' || current_database() || ' port=' || current_setting('port'));
  FOR i IN 1..10000 LOOP
    tsb = clock_timestamp();
    PERFORM dblink($e$UPDATE tbl SET v = v + 1 WHERE k = 'a';$e$);
    tse = clock_timestamp();
    IF i % 1000 = 0 THEN
      d = (extract('epoch' from tse) - extract('epoch' from tsb)) * 1000;
      RAISE NOTICE 'i = %, exectime = %', lpad(i::text, 5), lpad(d::text, 5);
    END IF;
  END LOOP;
  PERFORM dblink_disconnect();
END;
$$ LANGUAGE plpgsql;

NOTICE:  i =  1000, exectime = 0.524
NOTICE:  i =  2000, exectime = 0.739
NOTICE:  i =  3000, exectime = 1.188
NOTICE:  i =  4000, exectime = 2.508
NOTICE:  i =  5000, exectime = 1.791
NOTICE:  i =  6000, exectime = 2.658
NOTICE:  i =  7000, exectime = 2.318
NOTICE:  i =  8000, exectime = 2.572
NOTICE:  i =  9000, exectime = 2.929
NOTICE:  i = 10000, exectime = 3.808

рдХреНрдпрд╛ рд╣реБрдЖ? рдПрдХрд▓ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЕрджреНрдпрддрди рдХреЗ рд▓рд┐рдП рднреА рдХреНрдпреЛрдВ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп 7 рдЧреБрдирд╛ рдХрдо рд╣реЛ рдЧрдпрд╛ - 0.524 рдПрдордПрд╕ рд╕реЗ 3.808 рдПрдордПрд╕ рддрдХ? рдФрд░ рд╣рдорд╛рд░реА рд░реЗрдЯрд┐рдВрдЧ рдФрд░ рдЕрдзрд┐рдХ рдзреАрд░реЗ-рдзреАрд░реЗ рдмрдврд╝ рд░рд╣реА рд╣реИред

рдпрд╣ рд╕рдм рдПрдорд╡реАрд╕реАрд╕реА рдХреА рдЧрд▓рддреА рд╣реИред

рдпрд╣ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ рдПрдорд╡реАрд╕реАрд╕реА рддрдВрддреНрд░, рдЬреЛ рдХреНрд╡реЗрд░реА рдХреЛ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд╕рднреА рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рддреЛ рдЖрдЗрдП рдЕрдкрдиреА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ "рдореГрдд" рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рд╕реЗ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ:

VACUUM VERBOSE tbl;

INFO:  vacuuming "public.tbl"
INFO:  "tbl": found 0 removable, 10026 nonremovable row versions in 45 out of 45 pages
DETAIL:  10000 dead row versions cannot be removed yet, oldest xmin: 597439602

рдУрд╣, рд╕рд╛рдл рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ! рд╕рдорд╛рдирд╛рдВрддрд░ рдЪрд▓ рд░рд╣рд╛ рдЕрдиреБрд░реЛрдз рд╣рдорд╛рд░реЗ рд╕рд╛рде рд╣рд╕реНрддрдХреНрд╖реЗрдк рдХрд░ рд░рд╣рд╛ рд╣реИ - рдЖрдЦрд╝рд┐рд░рдХрд╛рд░, рд╡рд╣ рдХрд┐рд╕реА рджрд┐рди рдЗрди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреА рдУрд░ рд░реБрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣реЗрдЧрд╛ (рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐?), рдФрд░ рд╡реЗ рдЙрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЗрд╕рд▓рд┐рдП VACUUM FULL рднреА рд╣рдорд╛рд░реА рдорджрдж рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред

рдореЗрдЬ рдХреЛ "рдврд╣рдирд╛"ред

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

рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдмрдлрд╝рд░ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдорд╛рдорд▓реЗ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВред рдпрд╛рдиреА, INSERT/DELETE рдХрд╛ рдПрдХ рдмрдбрд╝рд╛ рдкреНрд░рд╡рд╛рд╣ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдХрднреА-рдХрднреА рддрд╛рд▓рд┐рдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЦрд╛рд▓реА рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдпрд╣ рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдЕрд╡рд╢реНрдп рд╣реА рдЦрд╛рд▓реА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЗрд╕рдХреА рд╡рд░реНрддрдорд╛рди рд╕рд╛рдордЧреНрд░реА рд╕рд╣реЗрдЬреЗрдВ.

#0: рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЖрдХрд▓рди рдХрд░рдирд╛

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рдСрдкрд░реЗрд╢рди рдХреЗ рдмрд╛рдж рднреА рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдХреЛрдИ рдЦрд╛рд╕ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ - рд░рдЦрд░рдЦрд╛рд╡ рдУрд╡рд░рд╣реЗрдб рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд▓рдХреНрд╖реНрдп рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдереНрд░реВрдкреБрдЯ рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛрдЧрд╛ред

рдЖрдЗрдП рдорд╛рдирджрдВрдб рдмрдирд╛рдПрдВ - "рдпрд╣ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ" рдпрджрд┐:

  • VACUUM рдХреЛ рдХрд╛рдлреА рд╕рдордп рдкрд╣рд▓реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛
    рд╣рдо рднрд╛рд░реА рдмреЛрдЭ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд░рд╣рдиреЗ рджреЗрдВ 60 рд╕реЗрдХрдВрдб рдкрд┐рдЫрд▓реЗ [рдСрдЯреЛ]рд╡реИрдХреНрдпреВрдо рдХреЗ рдмрд╛рдж рд╕реЗред
  • рднреМрддрд┐рдХ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЖрдХрд╛рд░ рд▓рдХреНрд╖реНрдп рд╕реЗ рдмрдбрд╝рд╛ рд╣реИ
    рдЖрдЗрдП рдЗрд╕реЗ рдиреНрдпреВрдирддрдо рдЖрдХрд╛рд░ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдкреГрд╖реНрдареЛрдВ рдХреА рджреЛрдЧреБрдиреА рд╕рдВрдЦреНрдпрд╛ (8KB рдмреНрд▓реЙрдХ) рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ - рдвреЗрд░ рдХреЗ рд▓рд┐рдП 1 blk + рдкреНрд░рддреНрдпреЗрдХ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЗ рд▓рд┐рдП 1 blk - рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЦрд╛рд▓реА рдЯреЗрдмрд▓ рдХреЗ рд▓рд┐рдПред рдпрджрд┐ рд╣рдо рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдбреЗрдЯрд╛ рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рд╣рдореЗрд╢рд╛ "рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ" рдмрдлрд░ рдореЗрдВ рд░рд╣реЗрдЧреА, рддреЛ рдЗрд╕ рдлреЙрд░реНрдореВрд▓реЗ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рдирд╛ рдЙрдЪрд┐рдд рд╣реИред

рд╕рддреНрдпрд╛рдкрди рдЕрдиреБрд░реЛрдз

SELECT
  relpages
, ((
    SELECT
      count(*)
    FROM
      pg_index
    WHERE
      indrelid = cl.oid
  ) + 1) << 13 size_norm -- ╤В╤Г╤В ╨┐╤А╨░╨▓╨╕╨╗╤М╨╜╨╡╨╡ ╨┤╨╡╨╗╨░╤В╤М * current_setting('block_size')::bigint, ╨╜╨╛ ╨║╤В╨╛ ╨╝╨╡╨╜╤П╨╡╤В ╤А╨░╨╖╨╝╨╡╤А ╨▒╨╗╨╛╨║╨░?..
, pg_total_relation_size(oid) size
, coalesce(extract('epoch' from (now() - greatest(
    pg_stat_get_last_vacuum_time(oid)
  , pg_stat_get_last_autovacuum_time(oid)
  ))), 1 << 30) vaclag
FROM
  pg_class cl
WHERE
  oid = $1::regclass -- tbl
LIMIT 1;

relpages | size_norm | size    | vaclag
-------------------------------------------
       0 |     24576 | 1105920 | 3392.484835

#1: рдЕрднреА рднреА рд╢реВрдиреНрдп

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

рд╕рд╛рде рд╣реА, рд╣рдо рдЬреЛ рд╣рдЯрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЙрд╕рдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛ рдпрд╣ рддреБрд░рдВрдд рд╕рд╛рдлрд╝ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рдВ, рдФрд░ рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдкрд░ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрдПрдВрдЧреЗ "рд╣реЙрдЯ рдХреИрд╢" рджреНрд╡рд╛рд░рд╛, рдЬрд┐рд╕рд╕реЗ рдЙрдирдХреА рдЕрд╡рдзрд┐ рдХрдо рд╣реЛ рдЬрд╛рдПрдЧреА - рдФрд░, рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд┐рд╕рд┐рдВрдЧ рд▓реЗрдирджреЗрди рджреНрд╡рд╛рд░рд╛ рджреВрд╕рд░реЛрдВ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рдиреЗ рдХрд╛ рдХреБрд▓ рд╕рдордпред

#2: рдХреНрдпрд╛ рдШрд░ рдкрд░ рдХреЛрдИ рд╣реИ?

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХреБрдЫ рд╣реИ рдпрд╛ рдирд╣реАрдВ:

TABLE tbl LIMIT 1;

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

рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд▓рд┐рдП рдмрд┐рдирд╛ рд╢рд░реНрдд DELETE рдХрдорд╛рдВрдб рдХреЗ рд╕рдорд╛рди рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рддреЗрдЬрд╝ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рд╕реНрдХреИрди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рддреБрд░рдВрдд рдбрд┐рд╕реНрдХ рд╕реНрдерд╛рди рдЦрд╛рд▓реА рдХрд░ рджреЗрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдмрд╛рдж рдореЗрдВ VACUUM рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

рдЖрдкрдХреЛ рддрд╛рд▓рд┐рдХрд╛ рдЕрдиреБрдХреНрд░рдо рдХрд╛рдЙрдВрдЯрд░ (рд░реАрд╕реНрдЯрд╛рд░реНрдЯ рдЖрдЗрдбреЗрдВрдЯрд┐рдЯреА) рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ, рдпрд╣ рдЖрдкрдХреЛ рддрдп рдХрд░рдирд╛ рд╣реИред

#3: рд╣рд░ рдХреЛрдИ - рдмрд╛рд░реА-рдмрд╛рд░реА рд╕реЗ!

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

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ serializable-рд╣рдорд╛рд░реЗ рд▓реЗрдирджреЗрди рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧрд╛рд╡ (рд╣рд╛рдВ, рдпрд╣рд╛рдВ рд╣рдо рд▓реЗрдирджреЗрди рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ) рдФрд░ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ "рдХрд╕рдХрд░" рд▓реЙрдХ рдХрд░реЗрдВ:

BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
LOCK TABLE tbl IN ACCESS EXCLUSIVE MODE;

рдЕрд╡рд░реЛрдзрди рдХрд╛ рдпрд╣ рд╕реНрддрд░ рдЙрди рдкрд░рд┐рдЪрд╛рд▓рдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рд╣рдо рдЙрд╕ рдкрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

#4: рд╣рд┐рддреЛрдВ рдХрд╛ рдЯрдХрд░рд╛рд╡

рд╣рдо рдпрд╣рд╛рдВ рдЖрддреЗ рд╣реИрдВ рдФрд░ рд╕рдВрдХреЗрдд рдХреЛ "рд▓реЙрдХ" рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ - рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдХреЛрдИ рдЙрд╕ рд╕рдордп рд╕рдХреНрд░рд┐рдп рдерд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕рд╕реЗ рдкрдврд╝ рд░рд╣рд╛ рдерд╛? рд╣рдо рдЗрд╕ рдмреНрд▓реЙрдХ рдХреЗ рд░рд┐рд▓реАрдЬрд╝ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдореЗрдВ "рд▓рдЯрдХреЗ" рд░рд╣реЗрдВрдЧреЗ, рдФрд░ рдЬреЛ рдЕрдиреНрдп рд▓реЛрдЧ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд╡реЗ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрдПрдВрдЧреЗ...

рдРрд╕рд╛ рд╣реЛрдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо "рдЦреБрдж рдХрд╛ рдмрд▓рд┐рджрд╛рди" рджреЗрдВрдЧреЗ - рдпрджрд┐ рд╣рдо рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд (рд╕реНрд╡реАрдХрд╛рд░реНрдп рд░реВрдк рд╕реЗ рдХрдо) рд╕рдордп рдХреЗ рднреАрддрд░ рддрд╛рд▓рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рдереЗ, рддреЛ рд╣рдореЗрдВ рдЖрдзрд╛рд░ рд╕реЗ рдПрдХ рдЕрдкрд╡рд╛рдж рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо рд╣рдо рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣рд╕реНрддрдХреНрд╖реЗрдк рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ рдЕрдиреНрдпред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рддреНрд░ рдЪрд░ рд╕реЗрдЯ рдХрд░реЗрдВ рд▓реЙрдХ_рдЯрд╛рдЗрдордЖрдЙрдЯ (рд╕рдВрд╕реНрдХрд░рдг 9.3+ рдХреЗ рд▓рд┐рдП) рдпрд╛/рдФрд░ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ_рдЯрд╛рдЗрдордЖрдЙрдЯ. рдпрд╛рдж рд░рдЦрдиреЗ рд╡рд╛рд▓реА рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ_рдЯрд╛рдЗрдордЖрдЙрдЯ рдорд╛рди рдХреЗрд╡рд▓ рдЕрдЧрд▓реЗ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд╕реЗ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рдпрд╛рдирд┐ рдЪрд┐рдкрдХрд╛рдиреЗ рдореЗрдВ рдРрд╕реЗ - рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:

SET statement_timeout = ...;LOCK TABLE ...;

рдмрд╛рдж рдореЗрдВ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЗ "рдкреБрд░рд╛рдиреЗ" рдорд╛рди рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рд╕реЗ рди рдЬреВрдЭрдирд╛ рдкрдбрд╝реЗ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдлреЙрд░реНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рд╕реНрдерд╛рдиреАрдп рд╕реЗрдЯ рдХрд░реЗрдВ, рдЬреЛ рд╕реЗрдЯрд┐рдВрдЧ рдХреЗ рджрд╛рдпрд░реЗ рдХреЛ рд╡рд░реНрддрдорд╛рди рд▓реЗрдирджреЗрди рддрдХ рд╕реАрдорд┐рдд рдХрд░рддрд╛ рд╣реИред

рд╣рдореЗрдВ рдпрд╛рдж рд╣реИ рдХрд┐ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ_рдЯрд╛рдЗрдордЖрдЙрдЯ рдмрд╛рдж рдХреЗ рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ рддрд╛рдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдбреЗрдЯрд╛ рд╣реЛрдиреЗ рдкрд░ рд▓реЗрдирджреЗрди рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рдореВрд▓реНрдпреЛрдВ рддрдХ рди рдмрдврд╝ рд╕рдХреЗред

#5: рдбреЗрдЯрд╛ рдХреЙрдкреА рдХрд░реЗрдВ

рдпрджрд┐ рддрд╛рд▓рд┐рдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕рд╣рд╛рдпрдХ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╕рд╣реЗрдЬрдирд╛ рд╣реЛрдЧрд╛:

CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE tbl;

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

рдЪреВрдБрдХрд┐ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдмрд╣реБрдд рдЕрдзрд┐рдХ "рд▓рд╛рдЗрд╡" рдбреЗрдЯрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдСрдкрд░реЗрд╢рди рдмрд╣реБрдд рдЬрд▓реНрджреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЦреИрд░ рд╡рд╣ рд╕рдм рд╣реИ! рд▓реЗрди-рджреЗрди рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рди рднреВрд▓реЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЪрд▓рд╛рдПрдБ рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рддрд╛рд▓рд┐рдХрд╛ рдЖрдБрдХрдбрд╝реЛрдВ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдПред

рдЕрдВрддрд┐рдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛

рд╣рдо рдЗрд╕ "рдЫрджреНрдо-рдЕрдЬрдЧрд░" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

# ╤Б╨╛╨▒╨╕╤А╨░╨╡╨╝ ╤Б╤В╨░╤В╨╕╤Б╤В╨╕╨║╤Г ╤Б ╤В╨░╨▒╨╗╨╕╤Ж╤Л
stat <-
  SELECT
    relpages
  , ((
      SELECT
        count(*)
      FROM
        pg_index
      WHERE
        indrelid = cl.oid
    ) + 1) << 13 size_norm
  , pg_total_relation_size(oid) size
  , coalesce(extract('epoch' from (now() - greatest(
      pg_stat_get_last_vacuum_time(oid)
    , pg_stat_get_last_autovacuum_time(oid)
    ))), 1 << 30) vaclag
  FROM
    pg_class cl
  WHERE
    oid = $1::regclass -- table_name
  LIMIT 1;

# ╤В╨░╨▒╨╗╨╕╤Ж╨░ ╨▒╨╛╨╗╤М╤И╨╡ ╤Ж╨╡╨╗╨╡╨▓╨╛╨│╨╛ ╤А╨░╨╖╨╝╨╡╤А╨░ ╨╕ VACUUM ╨▒╤Л╨╗ ╨┤╨░╨▓╨╜╨╛
if stat.size > 2 * stat.size_norm and stat.vaclag is None or stat.vaclag > 60:
  -> VACUUM %table;
  try:
    -> BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    # ╨┐╤Л╤В╨░╨╡╨╝╤Б╤П ╨╖╨░╤Е╨▓╨░╤В╨╕╤В╤М ╨╝╨╛╨╜╨╛╨┐╨╛╨╗╤М╨╜╤Г╤О ╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨║╤Г ╤Б ╨┐╤А╨╡╨┤╨╡╨╗╤М╨╜╤Л╨╝ ╨▓╤А╨╡╨╝╨╡╨╜╨╡╨╝ ╨╛╨╢╨╕╨┤╨░╨╜╨╕╤П 1s
    -> SET LOCAL statement_timeout = '1s'; SET LOCAL lock_timeout = '1s';
    -> LOCK TABLE %table IN ACCESS EXCLUSIVE MODE;
    # ╨╜╨░╨┤╨╛ ╤Г╨▒╨╡╨┤╨╕╤В╤М╤Б╤П ╨▓ ╨┐╤Г╤Б╤В╨╛╤В╨╡ ╤В╨░╨▒╨╗╨╕╤Ж╤Л ╨▓╨╜╤Г╤В╤А╨╕ ╤В╤А╨░╨╜╨╖╨░╨║╤Ж╨╕╨╕ ╤Б ╨▒╨╗╨╛╨║╨╕╤А╨╛╨▓╨║╨╛╨╣
    row <- TABLE %table LIMIT 1;
    # ╨╡╤Б╨╗╨╕ ╨▓ ╤В╨░╨▒╨╗╨╕╤Ж╨╡ ╨╜╨╡╤В ╨╜╨╕ ╨╛╨┤╨╜╨╛╨╣ "╨╢╨╕╨▓╨╛╨╣" ╨╖╨░╨┐╨╕╤Б╨╕ - ╨╛╤З╨╕╤Й╨░╨╡╨╝ ╨╡╨╡ ╨┐╨╛╨╗╨╜╨╛╤Б╤В╤М╤О, ╨▓ ╨┐╤А╨╛╤В╨╕╨▓╨╜╨╛╨╝ ╤Б╨╗╤Г╤З╨░╨╡ - "╨┐╨╡╤А╨╡╨▓╤Б╤В╨░╨▓╨╗╤П╨╡╨╝" ╨▓╤Б╨╡ ╨╖╨░╨┐╨╕╤Б╨╕ ╤З╨╡╤А╨╡╨╖ ╨▓╤А╨╡╨╝╨╡╨╜╨╜╤Г╤О ╤В╨░╨▒╨╗╨╕╤Ж╤Г
    if row is None:
      -> TRUNCATE TABLE %table RESTART IDENTITY;
    else:
      # ╤Б╨╛╨╖╨┤╨░╨╡╨╝ ╨▓╤А╨╡╨╝╨╡╨╜╨╜╤Г╤О ╤В╨░╨▒╨╗╨╕╤Ж╤Г ╤Б ╨┤╨░╨╜╨╜╤Л╨╝╨╕ ╤В╨░╨▒╨╗╨╕╤Ж╤Л-╨╛╤А╨╕╨│╨╕╨╜╨░╨╗╨░
      -> CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE %table;
      # ╨╛╤З╨╕╤Й╨░╨╡╨╝ ╨╛╤А╨╕╨│╨╕╨╜╨░╨╗ ╨▒╨╡╨╖ ╤Б╨▒╤А╨╛╤Б╨░ ╨┐╨╛╤Б╨╗╨╡╨┤╨╛╨▓╨░╤В╨╡╨╗╤М╨╜╨╛╤Б╤В╨╕
      -> TRUNCATE TABLE %table;
      # ╨▓╤Б╤В╨░╨▓╨╗╤П╨╡╨╝ ╨▓╤Б╨╡ ╤Б╨╛╤Е╤А╨░╨╜╨╡╨╜╨╜╤Л╨╡ ╨▓╨╛ ╨▓╤А╨╡╨╝╨╡╨╜╨╜╨╛╨╣ ╤В╨░╨▒╨╗╨╕╤Ж╨╡ ╨┤╨░╨╜╨╜╤Л╨╡ ╨╛╨▒╤А╨░╤В╨╜╨╛
      -> INSERT INTO %table TABLE _tmp_swap;
    -> COMMIT;
  except Exception as e:
    # ╨╡╤Б╨╗╨╕ ╨╝╤Л ╨┐╨╛╨╗╤Г╤З╨╕╨╗╨╕ ╨╛╤И╨╕╨▒╨║╤Г, ╨╜╨╛ ╤Б╨╛╨╡╨┤╨╕╨╜╨╡╨╜╨╕╨╡ ╨▓╤Б╨╡ ╨╡╤Й╨╡ "╨╢╨╕╨▓╨╛" - ╤Б╨╗╨╛╨▓╨╕╨╗╨╕ ╤В╨░╨╣╨╝╨░╤Г╤В
    if not isinstance(e, InterfaceError):
      -> ROLLBACK;

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

CREATE TABLE _swap_%table(LIKE %table INCLUDING ALL);
INSERT INTO _swap_%table TABLE %table;
DROP TABLE %table;
ALTER TABLE _swap_%table RENAME TO %table;

рдЖрдЗрдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд╕реНрд░реЛрдд рддрд╛рд▓рд┐рдХрд╛ рдкрд░ рдЪрд▓рд╛рдПрдБ рдФрд░ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:

VACUUM tbl;
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  SET LOCAL statement_timeout = '1s'; SET LOCAL lock_timeout = '1s';
  LOCK TABLE tbl IN ACCESS EXCLUSIVE MODE;
  CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE tbl;
  TRUNCATE TABLE tbl;
  INSERT INTO tbl TABLE _tmp_swap;
COMMIT;

relpages | size_norm | size   | vaclag
-------------------------------------------
       0 |     24576 |  49152 | 32.705771

рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛ рдЧрдпрд╛! рддрд╛рд▓рд┐рдХрд╛ 50 рдЧреБрдирд╛ рд╕рд┐рдХреБрдбрд╝ рдЧрдИ рд╣реИ рдФрд░ рд╕рднреА рдЕрджреНрдпрддрди рдлрд┐рд░ рд╕реЗ рддреЗрдЬреА рд╕реЗ рдЪрд▓ рд░рд╣реЗ рд╣реИрдВред

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ