ááá¯á·áá±á¬áº ááá¯ááá¯á·áá±á¬áááŸá áºááŒáá¯á·ááœááºá¡áá»áá¯ážá¡á á¬áž (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
áá¬ááŒá áºáá¬áá²? ááŸááºáááºážáá áºáá¯á á¡ááá¯ážááŸááºážáá¯á¶áž UPDATE ááẠá¡áááºááŒá±á¬áá·áºáááºáž á á®áááºáá»áááºááᯠá ááŒááẠáá»áŸá±á¬á·áá»áá²á·áááºá - 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 á áá¹áááºá· áá±á¬ááºáá¯á¶áž [auto]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 ááŸáá·áºááá°áá²á áááºážááẠread-write data ááŒáá·áºá¡áá¯ááºáá¯ááºáá±á¬ parallel process áá»á¬ážááá¯á¡ááŸá±á¬áá·áºá¡ááŸááºáááŸááá«á
áá áºáá»áááºáááºážááŸá¬áááºá áááºážááẠáá»áœááºá¯ááºááá¯á·áááºááŸá¬ážááá¯áá±á¬á¡áá¬á¡áá»á¬ážá á¯ááᯠáá»ááºáá»ááºážáááºááŸá¬ážááá¯ááºáááºá áá¯ááºáááºá á€ááá¬ážááŸá áá±á¬ááºáááºááœá²áá±ážááœááºážáá»á¬ážááẠáá»áœááºá¯ááºááá¯á·áᶠáá±á¬ááºááœá¬ážáá«áááá·áºáááºá "hot cache" ááŒáá·áºáááºážááá¯á·áááŒá¬áá»áááºááᯠáá»áŸá±á¬á·áá»áá±ážááá·áº - ááá¯á·ááŒá±á¬áá·áº áá»áœááºá¯ááºááá¯á·ááááºáá±á¬ááºááŸá¯áá±ážááœá±ááŒáá·áº á¡ááŒá¬ážáá°áá»á¬ážááᯠááááºááá¯á·ááá·áº á á¯á á¯áá±á«ááºážá¡áá»áááºá
#2: á¡áááºááŸá¬ áá áºáá±á¬ááºáá±á¬ááºááŸááá¬ážá
ááá¬ážáá²ááŸá¬ áá áºáá¯áá¯ááŸááááŸá á á áºáá±ážááŒáá·áºáá¡á±á¬ááºá
TABLE tbl LIMIT 1;
ááŸááºáááºážáá
áºáá¯áá»áŸááá»ááºáá«áá ááá¯ážááŸááºážá
áœá¬áá¯ááºáá±á¬ááºááŒááºážááŒáá·áº áá¯ááºáá±á¬ááºááŒááºážá¡ááœáẠáá»á¬ážá
áœá¬ áááºáá¬á
á±ááá¯ááºáááºá
áááºážááẠááá¬ážáá áºáá¯á á®á¡ááœáẠááŒáœááºážáá»ááºáááŸá DELETE ááœááºáááºážáá áºáá¯áá²á·ááá¯á· áá¯ááºáá±á¬ááºáááºá ááá¯á·áá±á¬áº áááºážááẠááá¬ážáá»á¬ážááᯠá¡ááŸááºááááºá áááºááºááááºáá±á¬ááŒá±á¬áá·áº ááá¯ááá¯ááŒááºáááºáááºá ááá¯á·á¡ááŒááºá áááºážááẠdisk space ááá¯áá»ááºáá»ááºážááœááºá á±ááŒá®áž VACUUM áá¯ááºáá±á¬ááºáá»ááºááá¯áá¯ááºáá±á¬ááºáááºáááá¯á¡ááºáá«á
ááá¬áž ááááºážááááºážáá±á¬ááºáᬠ(RESTART IDENTITY) ááᯠááŒááºáááºáááºááŸááºááẠááá¯á¡ááºáááºááŒá áºá á± áááºáá¯á¶ážááŒááºáááºáᬠááŸááááºá
#3- áá°ááá¯ááºáž- á¡ááŸáá·áºáá»á
áá»áœááºá¯ááºááá¯á·ááẠááŒáá¯ááºááá¯ááºááŸá¯ ááŒááºážáááºáá±á¬ áááºáááºážáá»ááºááœáẠá¡áá¯ááºáá¯ááºáá±á¬ááŒá±á¬áá·áºá áá»áœááºá¯ááºááá¯á· á€áá±áá¬ááœáẠááá¬ážááœáẠááá·áºááœááºážááŸá¯áá»á¬áž áááŸáááŒá±á¬ááºáž á á áºáá±ážáá±á ááºá áá áºá á¯á¶áá áºáŠážááẠááá¯áá±áá¬ááœáẠáá áºáá¯áᯠáá±ážáá¬ážááŒá®ážáá¬áž ááŒá áºááá¯ááºáááºá á€á¡áá»ááºá¡áááºááᯠáá»áœááºá¯ááºááá¯á· ááá¯á¶ážááŸá¯á¶ážááá·áºáá«á á¡áááºááŒá±á¬áá·áºáááºážá ááŸááºáá«áááºá áááºáá°áá០á¡á²áá«ááᯠáá±áá±áá»á¬áá»á¬ ááá±ážááá¯ááºáá°ážááá¯áᬠáá±áá»á¬á¡á±á¬áẠáá¯ááºááá¯á·ááá¯áááºá
áá«ááá¯áá¯ááºááá¯á· áá»áœááºáá±á¬áºááá¯á· enable áá¯ááºááá¯á· ááá¯áá«áááºá Serializable áá«á-áá»áœááºá¯ááºááá¯á·áááœá±áá±ážááœá±áá°á¡ááœáẠáá®ážááŒá¬ážááœá²áá¬ážááŒááºáž (áá¯ááºáá²á·á á€ááœáẠáá»áœááºá¯ááºááá¯á·ááẠááœá±áá±ážááœá±áá°áá áºáᯠá áááºáááº) ááŸáá·áº á á¬ážááœá²ááᯠâáááºážáááºážáá»ááºáá»ááºâ áá±á¬á·áááºáá«-
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
LOCK TABLE tbl IN ACCESS EXCLUSIVE MODE;
á€ááááºááá¯á·ááŒááºážá¡ááá·áºááẠáááºážá¡áá±á«áº áá»áœááºá¯ááºááá¯á·áá¯ááºáá±á¬ááºááá¯áá±á¬ áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááŒáá·áº áá¯á¶ážááŒááºáááºá
#4- á¡áá»áá¯ážá á®ážááœá¬ážáááááá¹á
áá»áœááºáá±á¬áºááá¯á· áá®ááá¯áá¬ááŒá®áž ááá¯ááºážáá¯ááºááᯠâáá±á¬á·áááºâ áá»ááºááẠ- á¥ááᬠáá áºá á¯á¶áá áºáá±á¬ááºá á¡á²áá«ááᯠáááºááŒá®áž á¡á²áá®á¡ááá¯ááºá¡ááá·áºááŸá¬ áááºááŒáœáá±áááºááá¯ááẠáááºááá¯áá¯ááºááá²á áá®ááá±á¬á·áá±ážááœááºáá¬áá±á¬á·ááá·áºá¡áá»áááºááᯠá á±á¬áá·áºáá»áŸá±á¬áºáá±ááŸá¬ááŒá áºááŒá®áž áááºáá»ááºáá²á·áá°ááœá±áááºáž áááºáá¬ááŸá¬áá«...
ááá¯ááá¯á·áááŒá áºááœá¬ážá á±áááºá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠâááááááá¯ááºááá¯ááá¯ááºá áá±ážáá«â ááẠ- á¡áááºá áá»áœááºá¯ááºááá¯á·ááẠá¡áá»áááºá¡ááá¯ááºážá¡áá¬áá áºáá¯á¡ááœááºáž áá±á¬á·ááá¯áááá°ááá¯ááºáá²á·áá«áá ááá¯á·áá±á¬áẠá¡ááŒá±áá¶ááŸááŒáœááºážáá»ááºáá áºáá¯ááᯠáá»áœááºá¯ááºááá¯á·áááŸááááá·áºáááºá ááá¯á·áá±á¬áº á¡áááºážáá¯á¶ážá¡á¬ážááŒáá·áº áá»áœááºá¯ááºááá¯á·ááẠá¡ááœááºá¡áááºážáááºáá±á¬ááºá áœááºáááºáááºááá¯ááºáá«á á¡ááŒá¬ážáá°áá»á¬ážá
áá«ááá¯áá¯ááºááá¯á·á session variable ááᯠáááºááŸááºáá«á
SET statement_timeout = ...;LOCK TABLE ...;
áá±á¬ááºááá¯ááºážááœáẠvariable á "á¡áá±á¬ááºáž" áááºááá¯ážááᯠááŒááºáááºááááºážááááºážááẠáááá¯á¡ááºá á±áááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠáá±á¬ááºááᯠá¡áá¯á¶ážááŒá¯áá«áááºá Local áááºááŸááºáá«ááááºáááºá áááºáááºááᯠáááºááŸá ááœá±áá±ážááœá±áá°á¡ááœáẠááá·áºáááºáá±ážáááºá
statement_timeout ááẠáá±á¬ááºáááºááœá²áá±á¬ááºážááá¯ááŸá¯áá»á¬ážá¡á¬ážáá¯á¶ážááœáẠáááºáá±á¬ááºááŸá¯ááŸááááºááᯠááŸááºáá¬ážáá¬ážááŒá®áž ááá¬ážááœááºáá±áá¬áá»á¬ážá áœá¬ááŸááá«á áááºáá¶ááá¯ááºáá±á¬áááºááá¯ážáá»á¬ážá¡áá ááœá±áá±ážááœá±áá°ááᯠáááá·áºáá¯ááºááá¯ááºá á±áááºá
#5- áá±áá¬ááᯠáá°ážáá°áá«á
ááá¬ážááẠáá¯á¶ážáá¯á¶ážáá»á¬ážáá»á¬áž ááá¬ááá¯ááºáá«áá á¡ááẠáá¬áá®ááá¬ážááᯠá¡áá¯á¶ážááŒá¯á áá±áá¬ááᯠááŒááºáááºááááºážáááºážááááºááŒá áºáá«áááºá
CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE tbl;
áááºááŸáẠCOMMIT DROP ááœáẠááá¯ááá¯áááºááŸá¬ ááá¯á¡áá»áááºááœáẠááœá±ááœáŸá²ááŒááºážááŒá®ážáá¯á¶ážáá«á áá¬áá®ááá¬ážááẠáááºááŸááá±áááºááŒá áºááŒá®áž áááºážááᯠáá»áááºáááºááŸá¯á¡ááŒá±á¡áá±ááœáẠááá¯ááºááá¯ááºáá»ááºáá áºááẠáááá¯á¡ááºáá«á
"ááá¯ááºááá¯ááº" áá±áᬠá¡áá»á¬ážá¡ááŒá¬ážáááŸááᯠáá»áœááºá¯ááºááá¯á·áá°ááá±á¬ááŒá±á¬áá·áºá á€áá¯ááºáá±á¬ááºáá»ááºááẠáá»ááºááŒááºá áœá¬áá¯ááºáá±á¬ááºááá·áºáááºá
á¡ááºáž áá«áá²! ááœá±ááœáŸá²ááŒá®ážáááºááŸáá·áº ááá±á·áá«ááŸáá·áº
áá±á¬ááºáá¯á¶áž áá¬ááºááœáŸááºážááᯠááœá²áááºáá¬ážáááºá
áá»áœááºá¯ááºááá¯á·ááẠဠ"pseudo-python" ááá¯á¡áá¯á¶ážááŒá¯áááº-
# ÑПбОÑаеЌ ÑÑаÑОÑÑÐžÐºÑ Ñ ÑаблОÑÑ
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;
á¡áááºážá¡ááŒá áºááá¬ážáá±á«áºááœáẠscript ááá¯ááœáá·áºááŒá®áž áááºááá áºáá»á¬ážááᯠá á áºáá±ážááŒáá·áºááŒáá«á áá¯á·á
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 áá»á¯á¶á·ááœá¬ážááŒá®áž á¡ááºááááºáá»á¬ážá¡á¬ážáá¯á¶ážááẠáá»áŸááºááŒááºá
áœá¬ ááŒááºáááºáááºáá±áá«áááºá
source: www.habr.com