ํ์ง๋ง ์ด๋ฌํ ๋ถ์พํ ์ ํ(OLTP ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ์ฅ๊ธฐ OLAP ๋ก๋)์ด ์ฌ์ ํ ์กด์ฌํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์ด๋ป๊ฒ ํ๋ฐํ ๋ณํํ๋ ํ ์ด๋ธ์ ์ฒญ์ํ์ญ์์ค ๊ธด ์ง๋ฌธ์ ๋๋ฌ์ธ์ฌ ์๊ณ ๊ฐํด๋ฅผ ๋ฐ์ง ์์ต๋๊น?
๊ฐํด๋ฅผ ํผ์น๋ค
๋จผ์ , ์ฐ๋ฆฌ๊ฐ ํด๊ฒฐํ๋ ค๋ ๋ฌธ์ ๊ฐ ๋ฌด์์ธ์ง, ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ๋ฐ์ํ ์ ์๋์ง ๊ฒฐ์ ํด ๋ด ์๋ค.
๋ณดํต ์ด๋ฐ ์ํฉ์ด ๋ฐ์ํ๋๋ฐ ๋น๊ต์ ์์ ํ ์ด๋ธ์, ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด ๋ฐ์ํ๋ ๊ณณ ๋ง์ ๋ณํ. ๋ณดํต ์ด๋ ๊ฑฐ๋ ์๋๋ฉด ๋ฌ๋ผ์ ๋ฏธํฐ/์ง๊ณ/๋ฑ๊ธ, UPDATE๊ฐ ์์ฃผ ์คํ๋๋ ๊ฒฝ์ฐ ๋๋ ๋ฒํผ ํ ์ง์์ ์ผ๋ก ์งํ๋๋ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ธฐ๋ก์ด ์ง์์ ์ผ๋ก ์ฝ์ /์ญ์ ๋ฉ๋๋ค.
๋ฑ๊ธ์ ์ฌ์ฉํ์ฌ ์ต์ ์ ์ฌํํด ๋ณด๊ฒ ์ต๋๋ค.
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);
์ด์ ์ฐ๋ฆฌ๋ ์นด์ดํฐ ์ค ํ๋์ ๊ฐ์ ์ฌ๋ฌ ๋ฒ ์
๋ฐ์ดํธํฉ๋๋ค. ์คํ์ ์์์ฑ์ ์ํด ์ด๋ ๊ฒ ํฉ์๋ค.
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์ ์๋ชป์ ๋๋ค.
๋ชจ๋ ๊ฒ์ด ๋ค
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 ์ด ๋ง์ง๋ง [์๋]VACUUM ์ดํ. - ๋ฌผ๋ฆฌ์ ํ
์ด๋ธ ํฌ๊ธฐ๊ฐ ๋์๋ณด๋ค ํฝ๋๋ค.
์ต์ ํฌ๊ธฐ ๋๋น ํ์ด์ง ์(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;
๋จ์ผ ๋ ์ฝ๋๊ฐ ๋จ์ ์์ง ์์ ๊ฒฝ์ฐ ๊ฐ๋จํ ๋ค์์ ์ํํ์ฌ ์ฒ๋ฆฌ ์๊ฐ์ ๋ง์ด ์ ์ฝํ ์ ์์ต๋๋ค.
์ด๋ ๊ฐ ํ ์ด๋ธ์ ๋ํด ๋ฌด์กฐ๊ฑด์ ์ธ DELETE ๋ช ๋ น๊ณผ ๋์ผํ๊ฒ ์๋ํ์ง๋ง ์ค์ ๋ก ํ ์ด๋ธ์ ์ค์บํ์ง ์์ผ๋ฏ๋ก ํจ์ฌ ๋น ๋ฆ ๋๋ค. ๋ํ ์ฆ์ ๋์คํฌ ๊ณต๊ฐ์ ํ๋ณดํ๋ฏ๋ก ๋์ค์ VACUUM ์์ ์ ์ํํ ํ์๊ฐ ์์ต๋๋ค.
ํ ์ด๋ธ ์ํ์ค ์นด์ดํฐ(RESTART IDENTITY)๋ฅผ ์ฌ์ค์ ํด์ผ ํ๋์ง ์ฌ๋ถ๋ ์ฌ์ฉ์๊ฐ ๊ฒฐ์ ํฉ๋๋ค.
#3: ๋ชจ๋ - ์ฐจ๋ก๋๋ก ์งํํ์ธ์!
์ฐ๋ฆฌ๋ ๊ฒฝ์์ด ์น์ดํ ํ๊ฒฝ์์ ์ผํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์์ ํ ์ด๋ธ์ ํญ๋ชฉ์ด ์๋์ง ํ์ธํ๋ ๋์ ๋๊ตฐ๊ฐ ์ด๋ฏธ ๊ฑฐ๊ธฐ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ผ์ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด ์ ๋ณด๋ฅผ ์์ด๋ฒ๋ ค์๋ ์ ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ๊ทธ๋ ์ฃ , ๋๊ตฌ๋ ํ์คํ๊ฒ ๊ธฐ๋กํ ์ ์๋๋ก ํด์ผ ํฉ๋๋ค.
์ด๋ ๊ฒ ํ๋ ค๋ฉด ํ์ฑํํด์ผ ํฉ๋๋ค. ์ง๋ ฌํ ๊ฐ๋ฅ-ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌํ๊ณ (์, ์ฌ๊ธฐ์๋ ํธ๋์ญ์ ์ ์์ํฉ๋๋ค) ํ ์ด๋ธ์ "๋จ๋จํ" ์ ๊ธ๋๋ค.
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
LOCK TABLE tbl IN ACCESS EXCLUSIVE MODE;
์ด ์ฐจ๋จ ์์ค์ ์ํํ๋ ค๋ ์์ ์ ๋ฐ๋ผ ๊ฒฐ์ ๋ฉ๋๋ค.
#4: ์ดํด ์์ถฉ
์ฐ๋ฆฌ๋ ์ฌ๊ธฐ์ ์์ ํ์งํ์ "์ ๊ทธ๊ณ " ์ถ์ต๋๋ค. ์๋ฅผ ๋ค์ด ๊ทธ ์๊ฐ ๋๊ตฐ๊ฐ๊ฐ ํ์งํ์ ์ฝ๊ณ ์์๋ค๋ฉด ์ด๋จ๊น์? ์ฐ๋ฆฌ๋ ์ด ๋ธ๋ก์ด ํด์ ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ฉฐ โ์ค์งโํ ๊ฒ์ด๋ฉฐ, ์ฝ๊ณ ์ถ์ดํ๋ ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ฐ๋ฆฌ๋ฅผ ๋ง๋ ๊ฒ์ ๋๋ค...
์ด๋ฐ ์ผ์ด ๋ฐ์ํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ "์ฐ๋ฆฌ ์์ ์ ํฌ์"ํ ๊ฒ์ ๋๋ค. ํน์ (ํ์ฉ ๊ฐ๋ฅํ ์งง์) ์๊ฐ ๋ด์ ์ ๊ธ์ ์ป์ ์ ์๋ ๊ฒฝ์ฐ ๋ฒ ์ด์ค์์ ์์ธ๋ฅผ ๋ฐ๊ฒ ๋์ง๋ง ์ต์ํ ๋๋ฌด ๋ง์ด ๊ฐ์ญํ์ง๋ ์์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋.
์ด๋ ๊ฒ ํ๋ ค๋ฉด ์ธ์
๋ณ์๋ฅผ ์ค์ ํ์ญ์์ค.
SET statement_timeout = ...;LOCK TABLE ...;
๋์ค์ ๋ณ์์ "์ด์ " ๊ฐ์ ๋ณต์ํ๋ ์์ ์ ์ฒ๋ฆฌํ ํ์๊ฐ ์๋๋ก ๋ค์ ํ์์ ์ฌ์ฉํฉ๋๋ค. ๋ก์ปฌ๋ก ์ค์ , ์ด๋ ์ค์ ๋ฒ์๋ฅผ ํ์ฌ ํธ๋์ญ์ ์ผ๋ก ์ ํํฉ๋๋ค.
ํ ์ด๋ธ์ ๋ง์ ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ํธ๋์ญ์ ์ด ํ์ฉํ ์ ์๋ ๊ฐ์ผ๋ก ํ์ฅ๋์ง ์๋๋ก ๋ชจ๋ ํ์ ์์ฒญ์ statement_timeout์ด ์ ์ฉ๋๋ค๋ ์ ์ ๊ธฐ์ตํฉ๋๋ค.
#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;
๋ฐ์ดํฐ๋ฅผ ๋ ๋ฒ ๋ณต์ฌํ์ง ์๋ ๊ฒ์ด ๊ฐ๋ฅํ๊ฐ์?์์น์ ์ผ๋ก ํ ์ด๋ธ ์์ฒด์ oid๊ฐ BL ์ธก์ ๋ค๋ฅธ ํ๋์ด๋ DB ์ธก์ FK์ ์ฐ๊ฒฐ๋์ด ์์ง ์์ ๊ฒฝ์ฐ ๊ฐ๋ฅํฉ๋๋ค.
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๋ฐฐ๋ก ์ค์ด๋ค์๊ณ ๋ชจ๋ ์
๋ฐ์ดํธ๊ฐ ๋ค์ ๋น ๋ฅด๊ฒ ์คํ๋๊ณ ์์ต๋๋ค.
์ถ์ฒ : habr.com