VACUUM เดชเดฐเดพเดœเดฏเดชเตเดชเต†เดŸเตเดฎเตเดชเต‹เตพ, เดžเด™เตเด™เตพ เดฎเต‡เดถ เดธเตเดตเดฎเต‡เดงเดฏเดพ เดตเตƒเดคเตเดคเดฟเดฏเดพเด•เตเด•เตเดจเตเดจเต

VACUUM PostgreSQL-เดฒเต† เด’เดฐเต เดŸเต‡เดฌเดฟเดณเดฟเตฝ เดจเดฟเดจเตเดจเต เดŽเดจเตเดคเต เดฎเดพเดคเตเดฐเด‚ "เด•เตเดฒเต€เตป เด…เดชเตเดชเต" เดšเต†เดฏเตเดฏเดพเตป เด•เดดเดฟเดฏเตเด‚ เด†เดฐเตเด‚ เด•เดพเดฃเตเดจเตเดจเดฟเดฒเตเดฒ - เด…เดคเดพเดฏเดคเต, เดˆ เดฑเต†เด•เตเด•เต‹เตผเดกเตเด•เตพ เดฎเดพเดฑเตเดฑเตเดจเตเดจเดคเดฟเดจเต เดฎเตเดฎเตเดชเต เด†เดฐเด‚เดญเดฟเดšเตเดš เด’เดฐเต เดธเดœเต€เดต เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดชเต‹เดฒเตเด‚ เด‡เดฒเตเดฒ.

เดŽเดจเตเดจเดพเตฝ เด…เดคเตเดคเดฐเดฎเตŠเดฐเต เด…เดธเตเด–เด•เดฐเดฎเดพเดฏ เดคเดฐเด‚ (เด’เดฐเต OLTP เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเดฟเตฝ เดฆเต€เตผเด˜เด•เดพเดฒ OLAP เดฒเต‹เดกเต) เด‡เดชเตเดชเต‹เดดเตเด‚ เดจเดฟเดฒเดตเดฟเดฒเตเดฃเตเดŸเต†เด™เตเด•เดฟเตฝ? เดŽเด™เตเด™เดจเต† เดธเดœเต€เดตเดฎเดพเดฏเดฟ เดฎเดพเดฑเตเดจเตเดจ เดชเดŸเตเดŸเดฟเด• เดตเตƒเดคเตเดคเดฟเดฏเดพเด•เตเด•เตเด• เดจเต€เดฃเตเดŸ เดšเต‹เดฆเตเดฏเด™เตเด™เดณเดพเตฝ เดšเตเดฑเตเดฑเดชเตเดชเต†เดŸเตเดŸเต เด’เดฐเต เดฑเดพเด•เตเด•เดฟเตฝ เด•เดพเดฒเตเด•เตเดคเตเดคเตเดจเตเดจเดฟเดฒเตเดฒเต‡?

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.524ms เดฎเตเดคเตฝ 3.808ms เดตเดฐเต†? เดžเด™เตเด™เดณเตเดŸเต† เดฑเต‡เดฑเตเดฑเดฟเด‚เด—เต เด•เต‚เดŸเตเดคเตฝ เดธเดพเดตเดงเดพเดจเดคเตเดคเดฟเตฝ เดตเดณเดฐเตเดจเตเดจเต.

เดŽเดฒเตเดฒเดพเด‚ MVCC เดฏเตเดŸเต† เด•เตเดดเดชเตเดชเดฎเดพเดฃเต.

เดŽเดฒเตเดฒเดพ เด•เดพเดฐเตเดฏเด™เตเด™เดณเตเด‚ MVCC เดธเด‚เดตเดฟเดงเดพเดจเด‚, เด‡เดคเต เดŽเตปเดŸเตเดฐเดฟเดฏเตเดŸเต† เดŽเดฒเตเดฒเดพ เดฎเตเตป เดชเดคเดฟเดชเตเดชเตเด•เดณเตเด‚ เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เดพเตป เด…เดจเตเดตเต‡เดทเดฃเดคเตเดคเดฟเดจเต เด•เดพเดฐเดฃเดฎเดพเด•เตเดจเตเดจเต. เด…เดคเดฟเดจเดพเตฝ โ€œเดกเต†เดกเตโ€ เดชเดคเดฟเดชเตเดชเตเด•เดณเดฟเตฝ เดจเดฟเดจเตเดจเต เดจเดฎเตเดฎเตเดŸเต† เดŸเต‡เดฌเดฟเตพ เดตเตƒเดคเตเดคเดฟเดฏเดพเด•เตเด•เดพเด‚:

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 เด‰เดชเต‡เด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเต.

เด‡เดคเต เด•เต‚เดŸเตเดคเตฝ เดตเตเดฏเด•เตเดคเดฎเดพเด•เตเด•เตเดจเตเดจเดคเดฟเดจเต, เด’เดฐเต เดฌเดซเตผ เดŸเต‡เดฌเดฟเดณเดฟเดจเตเดฑเต† เด‰เดฆเดพเดนเดฐเดฃเด‚ เดจเต‹เด•เตเด•เดพเด‚. เด…เดคเดพเดฏเดคเต, INSERT / DELETE เดจเตเดฑเต† เด’เดฐเต เดตเดฒเดฟเดฏ เด’เดดเตเด•เตเด•เต เด‰เดฃเตเดŸเต, เดšเดฟเดฒเดชเตเดชเต‹เตพ เดชเดŸเตเดŸเดฟเด• เดชเต‚เตผเดฃเตเดฃเดฎเดพเดฏเตเด‚ เดถเต‚เดจเตเดฏเดฎเดพเดฃเต. เดชเด•เตเดทเต‡, เด…เดคเต เดถเต‚เดจเตเดฏเดฎเดฒเตเดฒเต†เด™เตเด•เดฟเตฝ, เดžเด™เตเด™เตพ เด…เดคเต เดšเต†เดฏเตเดฏเดฃเด‚ เด…เดคเดฟเดจเตเดฑเต† เดจเดฟเดฒเดตเดฟเดฒเต† เด‰เดณเตเดณเดŸเด•เตเด•เด™เตเด™เตพ เดธเด‚เดฐเด•เตเดทเดฟเด•เตเด•เตเด•.

#0: เดธเดพเดนเดšเดฐเตเดฏเด‚ เดตเดฟเดฒเดฏเดฟเดฐเตเดคเตเดคเตเดจเตเดจเต

เด“เดฐเต‹ เด“เดชเตเดชเดฑเต‡เดทเดจเตเด‚ เดถเต‡เดทเดตเตเด‚ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดŸเต‡เดฌเดฟเตพ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดŽเดจเตเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เดšเต†เดฏเตเดฏเดพเตป เดถเตเดฐเดฎเดฟเด•เตเด•เดพเดฎเต†เดจเตเดจเต เดตเตเดฏเด•เตเดคเดฎเดพเดฃเต, เดŽเดจเตเดจเดพเตฝ เด‡เดคเต เดตเดณเดฐเต†เดฏเดงเดฟเด•เด‚ เด…เตผเดคเตเดฅเดฎเดพเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒ - เดฎเต†เดฏเดฟเดจเตเดฑเดจเตปเดธเต เด“เดตเตผเดนเต†เดกเต เดŸเดพเตผเด—เต†เดฑเตเดฑเต เด…เดจเตเดตเต‡เดทเดฃเด™เตเด™เดณเตเดŸเต† เดคเตเดฐเต‚เดชเตเดŸเตเดŸเดฟเดจเต†เด•เตเด•เดพเตพ เดตเดฒเตเดคเดพเดฏเดฟเดฐเดฟเด•เตเด•เตเด‚.

เดจเดฎเตเด•เตเด•เต เดฎเดพเดจเดฆเดฃเตเดกเด‚ เดฐเต‚เดชเดชเตเดชเต†เดŸเตเดคเตเดคเดพเด‚ - โ€œเด‡เดคเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เต‡เดฃเตเดŸ เดธเดฎเดฏเดฎเดพเดฃเตโ€ เดŽเด™เตเด•เดฟเตฝ:

  • เดตเดณเดฐเต†เด•เตเด•เดพเดฒเด‚ เดฎเตเดฎเตเดชเดพเดฃเต เดตเดพเด•เตเดตเด‚ เดธเดฎเดพเดฐเด‚เดญเดฟเดšเตเดšเดคเต
    เด•เดจเดคเตเดค เดญเดพเดฐเด‚ เดžเด™เตเด™เตพ เดชเตเดฐเดคเต€เด•เตเดทเดฟเด•เตเด•เตเดจเตเดจเต, เด…เดคเดฟเดจเดพเตฝ เด…เดคเต เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเด• 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 - VACUUM FULL เดชเต‹เดฒเต†เดฏเดฒเตเดฒ, เดฑเต€เดกเต-เดฑเตˆเดฑเตเดฑเต เดกเดพเดฑเตเดฑเดฏเตเดฎเดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจ เดธเดฎเดพเดจเตเดคเดฐ เดชเตเดฐเด•เตเดฐเดฟเดฏเด•เดณเดฟเตฝ เด‡เดคเต เด‡เดŸเดชเต†เดŸเตเดจเตเดจเดฟเดฒเตเดฒ.

เด…เดคเต‡ เดธเดฎเดฏเด‚, เดžเด™เตเด™เตพ เดจเต€เด•เตเด•เด‚ เดšเต†เดฏเตเดฏเดพเตป เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจ เดฎเดฟเด•เตเด•เดตเดฏเตเด‚ เด‰เดŸเดจเดŸเดฟ เดตเตƒเดคเตเดคเดฟเดฏเดพเด•เตเด•เดพเตป เด‡เดคเดฟเดจเต เด•เดดเดฟเดฏเตเด‚. เด…เดคเต†, เดˆ เดชเดŸเตเดŸเดฟเด•เดฏเดฟเดฒเต† เดคเตเดŸเตผเดจเตเดจเตเดณเตเดณ เดšเต‹เดฆเตเดฏเด™เตเด™เตพ เดžเด™เตเด™เดณเดฟเดฒเต‡เด•เตเด•เต เดชเต‹เด•เตเด‚ "เดนเต‹เดŸเตเดŸเต เด•เดพเดทเต†" เดตเดดเดฟ, เด…เดคเต เด…เดตเดฐเตเดŸเต† เดฆเตˆเตผเด˜เตเดฏเด‚ เด•เตเดฑเดฏเตเด•เตเด•เตเด‚ - เด…เดคเดฟเดจเดพเตฝ, เดžเด™เตเด™เดณเตเดŸเต† เดธเต‡เดตเดจ เด‡เดŸเดชเดพเดŸเต เดตเดดเดฟ เดฎเดฑเตเดฑเตเดณเตเดณเดตเดฐเต† เดฌเตเดฒเต‹เด•เตเด•เต เดšเต†เดฏเตเดฏเตเดจเตเดจ เด†เด•เต† เดธเดฎเดฏเด‚.

#2: เดตเต€เดŸเตเดŸเดฟเตฝ เด†เดฐเต†เด™เตเด•เดฟเดฒเตเด‚ เด‰เดฃเตเดŸเต‹?

เดชเดŸเตเดŸเดฟเด•เดฏเดฟเตฝ เดŽเดจเตเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เด‰เดฃเตเดŸเต‹ เดŽเดจเตเดจเต เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เดพเด‚:

TABLE tbl LIMIT 1;

เด’เดฐเต เดฑเต†เด•เตเด•เต‹เตผเดกเต เดชเต‹เดฒเตเด‚ เด…เดตเดถเต‡เดทเดฟเด•เตเด•เตเดจเตเดจเดฟเดฒเตเดฒเต†เด™เตเด•เดฟเตฝ, เดฒเดณเดฟเดคเดฎเดพเดฏเดฟ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดฒเต‚เดŸเต† เดจเดฎเตเด•เตเด•เต เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เดฟเตฝ เดงเดพเดฐเดพเดณเด‚ เดฒเดพเดญเดฟเด•เตเด•เดพเด‚ เดšเตเดฐเตเด•เตเด•เตเด•:

เด‡เดคเต เด“เดฐเต‹ เดŸเต‡เดฌเดฟเดณเดฟเดจเตเด‚ เด’เดฐเต เดจเดฟเดฐเตเดชเดพเดงเดฟเด•เดฎเดพเดฏ DELETE เด•เดฎเดพเตปเดกเต เดชเต‹เดฒเต† เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต, เดŽเดจเตเดจเดพเตฝ เด‡เดคเต เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ เดŸเต‡เดฌเดฟเดณเตเด•เตพ เดธเตเด•เดพเตป เดšเต†เดฏเตเดฏเดพเดคเตเดคเดคเดฟเดจเดพเตฝ เดตเดณเดฐเต† เดตเต‡เด—เดคเดฏเตเดณเตเดณเดคเดพเดฃเต. เดฎเดพเดคเตเดฐเดฎเดฒเตเดฒ, เด‡เดคเต เด‰เดŸเตป เดคเดจเตเดจเต† เดกเดฟเดธเตเด•เต เดธเตเดชเต‡เดธเต เดธเตเดตเดคเดจเตเดคเตเดฐเดฎเดพเด•เตเด•เตเดจเตเดจเต, เด…เดคเดฟเดจเดพเตฝ เดชเดฟเดจเตเดจเต€เดŸเต เด’เดฐเต VACUUM เดชเตเดฐเดตเตผเดคเตเดคเดจเด‚ เดจเดŸเดคเตเดคเต‡เดฃเตเดŸ เด†เดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ.

เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดŸเต‡เดฌเดฟเตพ เดธเต€เด•เตเดตเตปเดธเต เด•เตŒเดฃเตเดŸเตผ (RESTART IDENTITY) เดชเตเดจเดƒเดธเดœเตเดœเดฎเดพเด•เตเด•เดฃเดฎเต‹ เดŽเดจเตเดจเต เดคเต€เดฐเตเดฎเดพเดจเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเต เดจเดฟเด™เตเด™เดณเดพเดฃเต.

#3: เดŽเดฒเตเดฒเดพเดตเดฐเตเด‚ - เดฎเดพเดฑเดฟเดฎเดพเดฑเดฟ เดŽเดŸเตเด•เตเด•เตเด•!

เดžเด™เตเด™เตพ เดตเดณเดฐเต† เดฎเดคเตเดธเดฐเดพเดงเดฟเดทเตเด เดฟเดคเดฎเดพเดฏ เด…เดจเตเดคเดฐเต€เด•เตเดทเดคเตเดคเดฟเตฝ เดœเต‹เดฒเดฟ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเดพเตฝ, เดชเดŸเตเดŸเดฟเด•เดฏเดฟเตฝ เดŽเตปเดŸเตเดฐเดฟเด•เดณเตŠเดจเตเดจเตเดฎเดฟเดฒเตเดฒเต†เดจเตเดจเต เดžเด™เตเด™เตพ เด‡เดตเดฟเดŸเต† เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เด†เดฐเต†เด™เตเด•เดฟเดฒเตเด‚ เด‡เดคเดฟเดจเด•เด‚ เด…เดตเดฟเดŸเต† เดŽเดจเตเดคเต†เด™เตเด•เดฟเดฒเตเด‚ เดŽเดดเตเดคเดฟเดฏเดฟเดŸเตเดŸเตเดฃเตเดŸเดพเด•เตเด‚. เดˆ เดตเดฟเดตเดฐเด™เตเด™เตพ เดจเดฎเตเด•เตเด•เต เดจเดทเตโ€ŒเดŸเดชเตเดชเต†เดŸเตเดคเตเดคเดฐเตเดคเต, เด…เดชเตเดชเต‹เตพ เดŽเดจเตเดคเดพเดฃเต? เดถเดฐเดฟเดฏเดพเดฃเต, เด†เตผเด•เตเด•เตเด‚ เด…เดคเต เด‰เดฑเดชเตเดชเดฟเดšเตเดšเต เดŽเดดเตเดคเดพเตป เด•เดดเดฟเดฏเดฟเดฒเตเดฒเต†เดจเตเดจเต เด‰เดฑเดชเตเดชเดพเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต.

เด‡เดคเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต, เดžเด™เตเด™เตพ เดชเตเดฐเดตเตผเดคเตเดคเดจเด•เตเดทเดฎเดฎเดพเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต เดธเต€เดฐเดฟเดฏเดฒเตˆเดธเต เดšเต†เดฏเตเดฏเดพเดตเตเดจเตเดจเดคเต-เดžเด™เตเด™เดณเตเดŸเต† เด‡เดŸเดชเดพเดŸเดฟเดจเตเดณเตเดณ เดเดธเตŠเดฒเต‡เดทเตป (เด…เดคเต†, เด‡เดตเดฟเดŸเต† เดžเด™เตเด™เตพ เด’เดฐเต เด‡เดŸเดชเดพเดŸเต เด†เดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเต) เด•เต‚เดŸเดพเดคเต† เดชเดŸเตเดŸเดฟเด• "เด•เดŸเตเดŸเดฟเดฏเดพเดฏเดฟ" เดฒเต‹เด•เตเด•เต เดšเต†เดฏเตเดฏเตเด•:

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;

เดกเดพเดฑเตเดฑ เดฐเดฃเตเดŸเดพเดฎเดคเตเด‚ เดชเด•เตผเดคเตเดคเดพเดคเดฟเดฐเดฟเด•เตเด•เดพเตป เด•เดดเดฟเดฏเตเดฎเต‹?เดคเดคเตเดตเดคเตเดคเดฟเตฝ, BL เดตเดถเดคเตเดคเต เดจเดฟเดจเตเดจเตเดณเตเดณ เดฎเดฑเตเดฑเต‡เดคเต†เด™เตเด•เดฟเดฒเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดจเด™เตเด™เดณเตเดฎเดพเดฏเดฟ เด…เดฒเตเดฒเต†เด™เตเด•เดฟเตฝ DB เดตเดถเดคเตเดคเต เดจเดฟเดจเตเดจเตเดณเตเดณ FK-เดฏเตเดฎเดพเดฏเดฟ เดŸเต‡เดฌเดฟเดณเดฟเดจเตเดฑเต† oid เดคเดจเตเดจเต† เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดšเตเดšเดฟเดŸเตเดŸเดฟเดฒเตเดฒเต†เด™เตเด•เดฟเตฝ เด…เดคเต เดธเดพเดงเตเดฏเดฎเดพเดฃเต:

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

เด’เดฐเต เด…เดญเดฟเดชเตเดฐเดพเดฏเด‚ เดšเต‡เตผเด•เตเด•เตเด•