Koma bwanji ngati mtundu wosasangalatsa wotere (katundu wanthawi yayitali wa OLAP patsamba la OLTP) ukadalipo? Bwanji kuyeretsa mwachangu kusintha tebulo kuzunguliridwa ndi mafunso ataliatali osaponda pachonga?
Kuyika pansi
Choyamba, tiyeni tione vuto limene tikufuna kuthetsa ndi mmene lingayambire.
Nthawi zambiri izi zimachitika patebulo laling'ono, koma zomwe zimachitika zosintha zambiri. Kawirikawiri izi kapena zosiyana mita/aggregates/magawo, pomwe UPDATE nthawi zambiri amachitidwa, kapena mzere wa buffer kukonza zochitika zomwe zikupitilira, zolembedwa zomwe zimangolowetsa /KUFUTA.
Tiyeni tiyese kupanganso chisankhocho ndi mavoti:
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;
Ndipo mofanana, mu mgwirizano wina, pempho lalitali, lalitali limayamba, kusonkhanitsa ziwerengero zovuta, koma osakhudza tebulo lathu:
SELECT pg_sleep(10000);
Tsopano timasintha mtengo wa imodzi mwazowerengera nthawi zambiri. Kwa chiyero cha kuyesa, tiyeni tichite izi
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
Chinachitika ndi chiyani? Chifukwa chiyani ngakhale kwa UPDATE yosavuta ya mbiri imodzi nthawi yokonzekera idachepetsedwa ndi nthawi 7 - kuchokera 0.524ms mpaka 3.808ms? Ndipo mlingo wathu ukukula pang'onopang'ono.
Zonse ndi zolakwika za MVCC.
Zonse ndi za
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
O, palibe choyeretsa! Kufanana Kuthamanga pempho kukusokoneza ife - pambuyo pake, tsiku lina angafune kutembenukira ku matembenuzidwe awa (bwanji ngati?), Ndipo ayenera kupezeka kwa iye. Ndipo chifukwa chake ngakhale VACUUM FULL sichidzatithandiza.
"Kugwetsa" tebulo
Koma tikudziwa motsimikiza kuti funsoli silifuna tebulo lathu. Chifukwa chake, tidzayesetsabe kubweza magwiridwe antchito ku malire oyenera pochotsa zonse zosafunikira patebulo - osachepera "pamanja", popeza VACUUM imasiya.
Kuti timveke bwino, tiyeni tiwone chitsanzo cha tebulo la buffer. Ndiko kuti, pali kutuluka kwakukulu kwa INSERT / DELETE, ndipo nthawi zina tebulo limakhala lopanda kanthu. Koma ngati ilibe kanthu, tiyenera sungani zomwe zili mkati mwake.
#0: Kuyang'ana momwe zinthu ziliri
Zikuwonekeratu kuti mutha kuyesa kuchitapo kanthu ndi tebulo ngakhale mutagwira ntchito iliyonse, koma izi sizomveka - kuwongolera kudzakhala kokulirapo kuposa zomwe zafunsidwa.
Tiyeni tipange njira - "ndi nthawi yoti tichitepo kanthu" ngati:
- VACUUM idakhazikitsidwa kalekale
Tikuyembekezera katundu wolemera, choncho zitheke Masekondi a 60 kuyambira [auto]VACUUM yomaliza. - Kukula kwa tebulo lakuthupi ndikwambiri kuposa cholinga
Tiyeni tifotokoze kuwirikiza kawiri kuchuluka kwa masamba (ma block 8KB) okhudzana ndi kukula kochepa - 1 blk pa mulu + 1 blk pa index iliyonse - patebulo lomwe lingakhale lopanda kanthu. Ngati tikuyembekeza kuti kuchuluka kwa deta kudzakhalabe mu buffer "nthawi zambiri", ndizomveka kusintha ndondomekoyi.
Pempho lotsimikizira
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: Padakali VACUUM
Sitingadziwe pasadakhale ngati funso lofananira likutisokoneza - ndendende ndi ma rekodi angati "achikale" chiyambireni. Chifukwa chake, tikaganiza zokonza tebulo, mulimonse, tiyenera kuchitapo kanthu VACUUM - mosiyana ndi VACUUM FULL, sichimasokoneza njira zofanana zomwe zimagwira ntchito ndi deta yowerengera.
Nthawi yomweyo, imatha kuyeretsa nthawi yomweyo zambiri zomwe tikufuna kuchotsa. Inde, ndipo mafunso otsatirawa patebuloli apita kwa ife ndi "hot cache", zomwe zidzachepetsa nthawi yawo - ndipo, chifukwa chake, nthawi yonse yoletsa ena ndi ntchito yathu yotumizira.
#2: Kodi alipo kunyumba?
Tiyeni tiwone ngati pali chilichonse patebulopo:
TABLE tbl LIMIT 1;
Ngati palibe mbiri imodzi yomwe yatsala, ndiye kuti tingapulumutse zambiri pakukonza mwa kungochita
Zimagwiranso ntchito ngati lamulo la DELETE lopanda malire patebulo lililonse, koma limathamanga kwambiri popeza silimasanthula matebulo. Komanso, nthawi yomweyo imamasula malo a disk, kotero palibe chifukwa chochitira VACUUM pambuyo pake.
Kaya mukufunika kukonzanso kauntala yotsatizana patebulo (RESTART IDENTITY) zili ndi inu kusankha.
#3: Aliyense - sinthanani!
Popeza timagwira ntchito m'malo opikisana kwambiri, tili pano tikuwona kuti palibe zolembedwa patebulo, wina atha kulemba kale kena kalikonse pamenepo. Sitiyenera kutaya chidziwitso ichi, ndiye chiyani? Ndiko kulondola, tiyenera kutsimikizira kuti palibe amene angalembe motsimikiza.
Kuti tichite izi tiyenera kuyatsa SERIALIZABLE-kudzipatula pazochita zathu (inde, apa tikuyamba kugulitsa) ndikutseka tebulo "mwamphamvu":
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
LOCK TABLE tbl IN ACCESS EXCLUSIVE MODE;
Mulingo wotsekereza uwu umatsimikiziridwa ndi ntchito zomwe tikufuna kuchita pamenepo.
#4: Kusagwirizana kwa chidwi
Timabwera kuno ndipo tikufuna "kutseka" chizindikiro - bwanji ngati wina anali wokangalika panthawiyo, mwachitsanzo, kuwerenga? "Tidzapachika" kuyembekezera kuti chipikachi chitulutsidwe, ndipo ena omwe akufuna kuwerenga adzathamangira mwa ife ...
Kuti izi zisachitike, "tidzadzipereka tokha" - ngati sitinathe kupeza loko mkati mwa nthawi inayake (yovomerezeka yaifupi), ndiye kuti tidzalandira kusiyana ndi maziko, koma sitingasokoneze kwambiri. ena.
Kuti muchite izi, ikani kusintha kwa gawo
SET statement_timeout = ...;LOCK TABLE ...;
Pofuna kuti tisagwirizane ndi kubwezeretsa mtengo "wakale" wa zosinthika pambuyo pake, timagwiritsa ntchito mawonekedwe KHALANI MALO, zomwe zimachepetsa kuchuluka kwa zoikamo pazochitika zamakono.
Tikukumbukira kuti statement_timeout imagwiranso ntchito pazopempha zonse zotsatila kuti ntchitoyo isapitirire kumitengo yosavomerezeka ngati pali zambiri patebulo.
#5: Koperani deta
Ngati tebulo liribe kanthu, deta iyenera kusungidwanso pogwiritsa ntchito tebulo losakhalitsa lothandizira:
CREATE TEMPORARY TABLE _tmp_swap ON COMMIT DROP AS TABLE tbl;
Siginecha ON COMMIT DROP zikutanthauza kuti panthawi yomwe ntchitoyo ikutha, tebulo losakhalitsa lidzasiya kukhalapo, ndipo palibe chifukwa chochichotsa pamanja pazolumikizana.
Popeza timaganiza kuti palibe zambiri "zamoyo" zambiri, ntchitoyi iyenera kuchitika mofulumira kwambiri.
Chabwino, ndizo zonse! Osayiwala mukamaliza kugulitsa
Kuyika pamodzi script yomaliza
Timagwiritsa ntchito "pseudo-python" iyi:
# собираем статистику с таблицы
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;
Kodi ndizotheka kusatengera deta kachiwiri?M'malo mwake, ndizotheka ngati oid ya tebulo palokha siyimangiriridwa kuzinthu zina zilizonse kuchokera ku mbali ya BL kapena FK kuchokera ku mbali ya DB:
CREATE TABLE _swap_%table(LIKE %table INCLUDING ALL);
INSERT INTO _swap_%table TABLE %table;
DROP TABLE %table;
ALTER TABLE _swap_%table RENAME TO %table;
Tiyeni tiyendetse script pa tebulo loyambira ndikuwona ma metrics:
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
Zonse zinayenda bwino! Gome lacheperachepera ka 50 ndipo UPDATEs zonse zikuthamanganso.
Source: www.habr.com