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.