Tema: Re: Need nuomonės iš šono - DB
Autorius: 2x50
Data: 2011-12-09 16:46:34
As cia su jumis tuoj issiaiskinsiu kaip MySQL veikia :)

****************
  3. Zodziai deadlock ir performance yra antonimai, cia net nematau
> reikalo kazka bandyti spresti deadlocku pagalba, tai savizudybe.

NE. Tai klasikinė transakcinė problema.
http://dev.mysql.com/doc/refman/5.5/en/innodb-deadlocks.html
****************

is to paties linko
Deadlocks are a classic problem in transactional databases, but they are not 
dangerous unless they are so frequent that you cannot run certain 
transactions at all.
Noriu atkreipti demesi i ta sakinio dali nuo zodziu "unless they". Manau, 
kad

begin transaction
set transaction isolatio level serializable
select * from tbl where id = 5
delete from tbl where id = 5
end transaction

ir bus butent tas "unless they" atvejis. Kodel? Todel, kad (anot 
dokumentacijos) su set transaction isolatio level serializable select dalis 
kuria S locka, ne X. Isvada tokia

begin transaction
set transaction isolatio level serializable
select * from tbl where id = 5
delete from tbl where id = 5
end transaction

nera tas pats kaip

begin transaction
set transaction isolatio level serializable
select * from tbl where id = 5 FOR UPDATE
delete from tbl where id = 5
end transaction

ir pirmasis atvejis nera pakankamas tam, kad sustatyti transakcijas i eile. 
Kai kurios visvien prasides dar tada, kai anstesne dar nera pasibaigusi, bet 
ir dar neturi X locko (ivykde select bed dar nepradejo delete). Va cia yra 
potencialus kandidatai deadlockams. Kurie, savo ruoztu, nedaro nieko 
naudingo, o tik tusciai naudoja masinos resursus.

Nebent dokumentacijoj parasyta ne visai taip kaip veikia. Jei MySQL atveju 
FOR UPDATE ir SERIALIZABLE veikia vienodai, tada nebutu jokio skirtumo kaip 
naudoti - transakcijos stotu i eile pries prasidedamos (tiksliau, pries 
pradedamos vykdyti pirmaji select sakini).
Is kitos puses, naudojant FOR UPDATE, visiskai nera reikalo naudoti 
serialiniu transakciju (tokiam kontekste koks cia parasytas), nes FOR UPDATE 
yra dar grieztesnis mechanizmas, nei serialine transakcija.
is to paties linko
If you are using locking reads (SELECT ... FOR UPDATE or SELECT ... LOCK IN 
SHARE MODE), try using a lower isolation level such as READ COMMITTED.

Na niekas juk neraso tokiu ciklu
for i in 1..n loop
  if i mod 3 = 0 then
    do something;
  else
    do nothing
  end if;
end loop;
be svarios priezasties.

*********************************
Neginčiju. O pats kokią prasmę įžvelgi tokios FIFO eilės valgyme?:
SELECT * FROM `table` ORDER BY ID ASC LIMIT 1
DELETE FROM `table` WHERE `ID` = x

Matyt irgi jokios...
(tai tik visos programos/apdorojimo FRAGMENTAS, tik esmės iliustravimui;
koks dar vyksta apdorojimas ir galbūt daromi kokie select'ai yra
neaišku/nežinoma)
*********************************
Siaip bendra taisykle yra tokia - naudok serialines transakcijas tik tais 
atvejais, kai tai yra butina, jei tai nera butina, nenaudok, jos nieko gero 
neduoda. Todel ir siulau ju nenaudoti, ypac jei yra select ... for update. 
Kam tas galvos skausmas su deadlockais ir transakciju restartavimu - tai tik 
papildomas darbas, kurio galima isvengti, ir kuris reikalaus daugiau masinos 
resursu.

*********************************
STOP. Greitaveika didinama keičiant variklį, t.y. pereinant nuo MyISAM
(ir banalaus visos lentelės rakinimo) į InnoDB (transakcinę), kuri yra
gerokai tobulesnė. Ir greitaveika beveik neabejotinai padidėtų vien tik
dėl tokio banalaus pakeitimo. O kartu buvo pasiūlyti būdai
konkurentiškumui įvesti (įrašų trynimas), naudojant, beje, default
isolation level, kas apskritai neįmanoma MyISAM atveju.
*********************************

Nesigincysiu su tuo, kad InnoDB veiks greiciau nei MyISAM, nes nezinau, bet 
kaip rasiau ansciau, mano manymu, tai yra lavono gaivinimas. Padidinus 
konkurentiniu sesiju skaiciu, problema vel islys. O tada jau nebebus kur 
migruoti is InnoDB. Tai nera problemos sprendimas, tai yra sprendimo 
atideliojimas. Nors, kas zino galbut to ir visam sistemos gyvenimui uzteks 
:)

Is to paties linko
If nothing else helps, serialize your transactions with table-level locks.

Ka noriu akcentuoti
SELECT * FROM `table` ORDER BY ID ASC LIMIT 1 FOR UPDATE
yra lygiai tas pats, kas lockinti visa lenta, todel kad pati selecto 
konstrukcija yra tokia, kad vienu metu visos aktyvios transakcijos, kiek ju 
bebutu, bandys rakinti viena ir ta pati irasa. Su tokiu selectu nera 
imanomas variantas, kad 2 transakcijos paraleliai bandytu rakinti skirtingus 
irasus. Na, su FOR UPDATE problemu nebus zinoma, bet be FOR UPDATE ir su 
serialinem pasipils deadlockai. Be FOR UPDATE ir su bet kuriuo zemesniu 
isolation leveliu deadlockai nepasipils, bus tiesiog sukamos transakcijos, 
kurios nieko nepadaro.

Vienaip ar kitaip pats uzdavinys yra pagerinti greitaveika. Todel, mano 
manymu, norint is tikruju tai isspresti (ne atitolinti mirti), reikia 
spjauti (zinoma, jei tai imanoma) i ta 100% FIFO principa. Tegu jis buna ne 
visai FIFO, kazkoks "beveik FIFO", bet leidzia suktis nekonfliktuojancioms 
transakcijoms paraleliai apdorojant skirtingus irasus tuo paciu metu. Ar is 
tiesu yra labai didelis skirtumas tame, kad kazkoks irasas bus apdorotas x 
milisekundziu ar net, o dieve, 2 sekundem veliau, nei sekantis po jo buves 
eileje. Laiko prasme visvien transakcija butu ivykdoma anksciau tuo atveju, 
kai dideja norinciu pradeti transakciju eile. O kai baigsis masinos 
resursai, tai ta eile prades ilgeti su pagreiciu ir viena diena pamatysim 
mazdaug tokio turinio posta "vakar su 100 varototoju viskas prasisuko per 10 
min. siandien su 110 vartotoju sukasi jau 3 valandas, kame reikalas?"

Tai is tiesu yra klausimas temos autoriui, na ar is tiesu, NicMC, yra taip 
kad 100% FIFO butinas ir niekaip kitaip negalima? Ar galima galvoti taip, 
kad vienu metu yra apdorojami tarkim 10 ar 20 skirtingu irasu (is viso 
saraso) paraleliai ir jie bus grazinti ne grieztai pagal FIFO, o, tarkim, 
kazkiek atsitiktine tvarka.