ok acum cateva zile am avut o mare problema cu serverul care tine trackerul http://**************
load FOARTE mare la un numar obisnuit de useri si peers. de fapt loadul a fost in crestere progresiva incepand cu o sapamana inainte.
mi-a fost destul de greu sa imi explic fenomenul. pana la urma m-am uitat la mysql stats si am vazut gramada de slow queries. am oprit serverul de mysql si am pus in my.cnf optiunea de a loga aceste slow queries.
spre surprinderea mea, 90% din slow queries aveau loc intr-un anume tabel "snatched". watch:
Cod:
(...)
# Query_time: 7 Lock_time: 5 Rows_sent: 1 Rows_examined: 18382
SELECT uploaded, downloaded FROM snatched WHERE torrent = 1096 AND userid = 1042;
# Query_time: 6 Lock_time: 3 Rows_sent: 0 Rows_examined: 0
UPDATE snatched SET uploaded = uploaded+0, downloaded = downloaded+0, port = 14821, connectable = 'yes', agent= 'BitTorrent/3.4.2', to_go = 0, last_action = '2006-10-01 11:24:53', seeder = 'yes' WHERE torrent = 532 AND userid = 16;
(...)
un log kilometric plin de slow queryuri in tabelul asta. am analizat tabelul si nu am vazut nimic ciudat, nimic care sa justifice queryurile extrem de incete (5-6 secunde pentru un query e enorm). nici marimea tabelului nu mi se pare foarte mare (18000 de linii).
Cod:
mysql> describe snatched;
+------------------+----------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+----------------------+------+-----+---------------------+----------------+
| id | int(11) | | PRI | NULL | auto_increment |
| torrentid | int(11) | YES | | 0 | |
| userid | int(11) | YES | | 0 | |
| torrent | int(10) unsigned | | | 0 | |
| torrent_name | varchar(255) | | | | |
| torrent_category | int(10) unsigned | | | 0 | |
| port | smallint(5) unsigned | | | 0 | |
| uploaded | bigint(20) unsigned | | | 0 | |
| downloaded | bigint(20) unsigned | | | 0 | |
| to_go | bigint(20) unsigned | | | 0 | |
| seeder | enum('yes','no') | | | no | |
| last_action | datetime | | | 0000-00-00 00:00:00 | |
| startdat | datetime | | | 0000-00-00 00:00:00 | |
| completedat | datetime | | | 0000-00-00 00:00:00 | |
| connectable | enum('yes','no') | | | yes | |
| agent | varchar(60) | | | | |
| finished | enum('yes','no') | | | no | |
+------------------+----------------------+------+-----+---------------------+----------------+
si cand dadeam manual un query in tabelul respectiv dura cateva secunde pana il executa.
este adevarat ca operatii in tabelul asta aveau loc destul de des. poate si cateva pe secunda. dar cred ca un server destul de decent (barton 2500+) poate duce fara probleme chestia asta.
singura explicatie pe care o vad e acel "Lock time" care apare in slow queries log. ma gandesc ca s-a intamplat urmatorul scenariu: 1 query are loc in tabelul respectiv, pune lock pe tabel. si pentru ca aveau loc multe queryuri, cele care urmau asteptau la rand in queue dupa acel Lock. fapt care conducea la un Lock time care crestea exponential pana la cateva secunde.
acum, eu nu sunt cine stie ce expert in mysql si va intreb pe voi: e obligatoriu ca o operatie intr-un tabel sa "incuie" acel tabel? nu se pot executa 2 selecturi in acelasi tabel in acelasi timp? e vreo setare ceva? e vreun parametru care trebuie dat la crearea tabelului?
mi se pare inadmisibil ca un server dupa cum am spus suficient de performant sa imi crape atunci cand au loc cateva queryuri pe secunda intr-un anume tabel.
apropo, cand am scapat de queryurile din tabelul "snatched" s-a stins brusc server loadul si totul merge perfect.