Pg+dSpam: zvyseni vykonu

Pavel Kankovsky peak na argo.troja.mff.cuni.cz
Středa Prosinec 14 13:51:22 CET 2011


On Wed, 14 Dec 2011, Jan Kasprzak wrote:

> 	Ano, premyslel jsem o tom co by se stalo, kdybych to cele obalil
> do jedne transakce - nemel by to byt slozity patch.
> 	 Stalo by se to, ze by velmi pravdepodobne velmi brzo
> a casto dochazelo k deadlockum v pripade, kdy dve instance dspamu budou
> aktualizovat hit county u tech stejnych tokenu, ale sahnou na ne
> v opacnem poradi.

Řekl bych, že je to celé o dost zajímavější, protože to vypadá, že
podpora pro masovou změnu v rámci jedné transakce tam už je. Dívám se na
zdroják driveru v GITu:

<http://dspam.git.sourceforge.net/git/gitweb.cgi?p=dspam/dspam;a=blob;f=src/pgsql_drv.c;h=6746d23246eaef59b7b9ad3f1db626cefc512272;hb=HEAD>

na funkci _ds_setall_spamrecords(). Ta dělá takovou zvláštní schizoidní
věc: Někde asi tak na čtvrté nebo páté stránce cyklí přes obsah argumentu
"diction", kde jsou zjevně tokeny, které má zpracovat a je-li potřeba
čítač změnit, tak vyrobí příslušný příkaz UPDATE, který přidá do bufferu
"update", kde k tomu na začátek přilepí "BEGIN" a na konec "COMMIT"
a nakonec to pošle do db, čili všechny updaty provede v jedné transakci.

Ale má to výjimku! Jestliže je to nový ten, který v db dosud není (a tudíž
ho nelze měnit), tak sestaví INSERT a ten provede samostatně hned uvnitř
smyčky (a pokud selže, tak to přidá do update).

Takže dávkové transakce tam už jsou a nějak se to s nimi musí umět
vypořádat (možná je tam někde něco, co zajistí, že je seznam vždy
setříděný stejným způsobem?), ale problém bych hledal v přidávání záznamů
pro nové tokeny.

Zdá se, že PostgreSQL nemá nic jako "MERGE" nebo "ON DUPLICATE KEY", co by
dovolilo v jednom kroku záznam buď vložit nebo aktualizovat. Ale možná by
šla použít tato finta

INSERT INTO table SELECT values... WHERE
	(SELECT COUNT(key) FROM table WHERE key = keyval) = 0

a tím podmíněně vytvořit nový záznam s nulovými hodnotami a za něj
přidat normální UPDATE.

Alternativně by možná šlo heuristicky zkusit nejdřív všechny INSERT-y
zkusit dávkově v jedné transakci a teprve v případě neúspěchu je provádět
individuálně. Hádám, že by pravděpodobnost výskytu situace, kdy se dva
procesy pokoušejí nově zaevidovat ten samý token, měla v čase velmi rychle
klesat.

-- 
Pavel Kankovsky aka Peak                          / Jeremiah 9:21        \
"For death is come up into our MS Windows(tm)..." \ 21st century edition /




Další informace o konferenci Linux