Portál AbcLinuxu, 12. května 2025 16:39

Dotaz: MySQL - vysoké i/o zatížení s InnoDB?

23.9.2009 08:58 Leinad
MySQL - vysoké i/o zatížení s InnoDB?
Přečteno: 890×
Odpovědět | Admin

Mám na netu jednu PHP webovou aplikaci, která má dlouhodobě problémy s rychlostí pravděpodobně kvůli ne ideálně udělané databázi a SQL dotazů na ni. Často jede rychle, často se ale taky stává, že se na půl minuty zasekne.

Z logů slow_query. Velké množství dotazů, které překročil čas 5 vteřin vykonování (často i přes 30s) byl mezi jinými jednoduchý update. Konkrétně dotazy typu
UPDATE statistika SET doba_online = doba_online + '7' WHERE jmeno = 'Leinad'
Tabulka "statistika" má kromě pár dalších sloupců sloupce "jmeno", který je VARCHAR a index a "doba_online", který je TIME. Tato tabulka slouží pro logování, jaký čas daný uživatel strávil na webu, takže dotaz se provádí každým kliknutím uživatele. TAbulka je InnoDB a má cca 300 řádků.

Zkusil jsem přehodit tabulku na engine MyISAM a už se tyto dotazy v logách slow_query neobjevují. Mám podezření, že InnoDB má vyšší režii na disk. Jedu na virtuálním serveru a když jsem se chvíli koukal na "top", tak jsem viděl často vyskočit hodnotu %wa až na 100%.

 

Je možné, že InnoDB má až tak moc velkou režii proti MyISAM? Četl jsem, že má vyšší (kvůli transakcím), ale nedovedl jsem si nikdy představit, že by to takhle mohlo zlikvidovat výkon... Nemáte nějaký tip, co s tím?
(Rada dát všechny tabulky na MyISAM znemožní použití transakcí u dotazů, kde se to hodí. Rada dát část tabulek do MyISAM a zbytek nechat na InnoDB by asi pomohla zvýšit rychlost, ovšem zbývající dotazy typu UPDATE a INSERT budou stále dělat problémy, jen jich bude méně...)

MySQL verze "5.0.32-Debian_7etch3-log".

 

Pozn.: Očekávám kritiku návrhu tabulky, kdy není ideální použití pro index tabulky typu VARCHAR. Vím to, ale nemyslím si, že má cenu se pouštět do opravy, když to můj problém stejně nevyřeší.

Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

23.9.2009 10:15 x22
Rozbalit Rozbalit vše Re: MySQL - vysoké i/o zatížení s InnoDB?
Odpovědět | | Sbalit | Link | Blokovat | Admin
Vela % I/O-wait (WA v tope) je pri databazi a web aplikacii celkom normalne.

Co by tam robilo I/O 5s v takomto dotaze na 300 riadkovej tabulke? Ten dotaz IO nerobi asi vobec, lebo cela tabulka bude v cache, ked sa tak casto pouziva. CPU tiez nema co robit 5s, takze to bude asi nejake zamykanie.

Ked sa podobny dotaz robi casto, tak tych updatov v jednej tabulke moze byt dost naraz. Ak su pripadne v dlhsich transakciach, tak to moze vadit.

23.9.2009 11:58 Leinad
Rozbalit Rozbalit vše Re: MySQL - vysoké i/o zatížení s InnoDB?

Nevyužívá se cache databáze při dotazech typu SELECT, nikoliv UPDATE?
 

Zamykání by tam být u tohoto dotazu nemělo. Ta "statistika" je hlavně UPDATEována přihlášeným člověkem, málokdy jiným uživatelem. Tj. nemělo by tam být žádné čekání na zámek. V logu slow_query se psalo navíc u těch dotazů "Lock_time: 0", jen parametr  "Query_time:" je vysoký...

23.9.2009 18:04 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: MySQL - vysoké i/o zatížení s InnoDB?
Odpovědět | | Sbalit | Link | Blokovat | Admin
Samotný dotaz je dost neškodný, spíš by to chtělo vědět, v jakém kontextu se vykonává. Podle popisu problému se čeká na disk. InnoDB narozdíl od MyISAM synchronizuje commity transakcí na disk, aby po pádu serveru byla DB konzistentní. Doporučuju se podívat na několik věcí:
  1. Pokud se vykonává několik SQL zápisů (insert, update, delete) najednou, obalit je do begin...commit, aby se to zapsalo jen jednou a ne po každém příkazu
  2. Pokud máte hodně paralelních zápisů najednou tak si holt musíte počkat, až se všechny vyřídí, nebo koupit diskový pole, lepší řadič, nebo použít jinou technologii (myisam nebo memory table pokud Vám nejde o integritu po pádu)
  3. Případně lze použít nežurnálovací filesystem pro oddíl s databází (nebo přímo prázdné místo na disku), jelikož integritu dat řeší InnoDB sama o sobě
  4. Pokud jste ve VM, platí výše zmíněná rada tuplem: pokuste se pro oddíl s databází virtuálního stroje přidělit oddíl na disku hostitele, a ne soubor přes loopback (nedejbože na žurnálovacím FS)
  5. Některé SQL aplikace jsou navyklé kvůli MyISAM použít LOCK TABLES, pokud se tam něco takového vyskytuje, tak by stálo za to to přepsat do transakcí
Co se týče indexů, tak to je asi v tuto chvíli méně tíživý problém. VARCHAR by vadit nemusel, ale zrovna tak můžete indexovat např. jen podle prvních 20 znaků toho pole... pro nějakou lepší radu by to chtělo vidět schema a typické dotazy (SELECTy).

In Ada the typical infinite loop would normally be terminated by detonation.
23.9.2009 18:05 pht | skóre: 48 | blog: pht
Rozbalit Rozbalit vše Re: MySQL - vysoké i/o zatížení s InnoDB?
PS. ještě bych dodal k těm žurnálovacím FS, že ext3 je v tomto případě nejhorší možná volba (např. proti XFS), protože fsync() na soubor s databází sesynchronizuje zápisy do všech souborů v systému, ne pouze do jednoho :(
In Ada the typical infinite loop would normally be terminated by detonation.
23.9.2009 22:03 Leinad
Rozbalit Rozbalit vše Re: MySQL - vysoké i/o zatížení s InnoDB?
Odpovědět | | Sbalit | Link | Blokovat | Admin

Tak problém zdá se vyřešen. Zvýšení innodb_buffer_pool_size. Byl nastaven standardně na 8MB. Databázi jsem měl (hlavně asi díky fórám a logováním) velkou 30MB, takže velké tabulky s fórem zdá se vyhazovaly tabulky jako "statistika", do které se každým klikem uživatele zapisovalo. A přepnutí na MyISAM fungovalo zdá se proto, že má možná vlastní jiný parametr cache (ehm, jen domněnka).

 

Díky tedy za rady a omlouvám se, že jsem si dostatečně neprohledal web předem. Resp. googlil jsem před podáním dotazu tady na fóru a našel jsem, že cache ovlivňuje rychlost DB, ale našel jsem jen články o cache využívanou při dotazech typu SELECT, narazil jsem na rady ohledně indexů, atd., ale to že tam je ještě další cache pro celé tabulky jsem zjistil bohužel až teď. No, tak snad tato diskuse pomůže v budoucnu někomu dalšímu, kdo se s tímto problémem setká.

Jinak, ten článek, co mi pomohl, byl na adrese <a href="http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/">http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/</a>

 

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.