sql >> Database >  >> RDS >> Mysql

Waarom duurt het soms zo lang voordat een invoegquery is voltooid?

Ik heb hetzelfde fenomeen opgemerkt op mijn systemen. Query's die normaal gesproken een milliseconde duren, duren plotseling 1-2 seconden. Al mijn gevallen zijn eenvoudige, enkele tabel INSERT/UPDATE/REPLACE-statements --- niet op SELECT's. Geen belasting, vergrendeling of draadopbouw is duidelijk.

Ik had het vermoeden dat het te wijten was aan het opruimen van vuile pagina's, het wissen van wijzigingen op de schijf of een verborgen mutex, maar ik moet het nog verfijnen.

Ook uitgesloten

  • Serverbelasting -- geen correlatie met hoge belasting
  • Engine -- gebeurt met InnoDB/MyISAM/Memory
  • MySQL Query Cache -- gebeurt of het nu aan of uit staat
  • Logrotaties -- geen correlatie in gebeurtenissen

De enige andere observatie die ik op dit punt heb, is afgeleid van het feit dat ik dezelfde db op meerdere machines gebruik. Ik heb een zware leestoepassing, dus ik gebruik een omgeving met replicatie -- het grootste deel van de belasting is op de slaves. Ik heb gemerkt dat hoewel de master minimaal wordt belast, het fenomeen daar meer optreedt. Ook al zie ik geen vergrendelingsproblemen, misschien heeft Innodb/Mysql problemen met (thread) concurrency? Bedenk dat de updates op de slave single threaded zullen zijn.

MySQL-versie 5.1.48

Bijwerken

Ik denk dat ik een aanwijzing heb voor het probleem in mijn zaak. Op sommige van mijn servers merkte ik dit fenomeen meer op dan op andere. Toen ik zag wat er anders was tussen de verschillende servers en dingen aanpaste, werd ik geleid naar de MySQL innodb systeemvariabele innodb_flush_log_at_trx_commit .

Ik vond het document een beetje onhandig om te lezen, maar innodb_flush_log_at_trx_commit kan de waarden 1,2,0 aannemen:

  • Voor 1 wordt de logbuffer voor elke commit naar het logbestand gespoeld en voor elke commit wordt het logbestand naar de schijf gewist.
  • Voor 2 wordt de logbuffer voor elke commit naar het logbestand gewist en het logbestand wordt ongeveer elke 1-2 seconden naar de schijf gewist.
  • Voor 0 wordt de logbuffer elke seconde naar het logbestand gespoeld en wordt het logbestand elke seconde naar de schijf gewist.

In feite, in de volgorde (1,2,0), zoals gerapporteerd en gedocumenteerd, wordt verondersteld dat u betere prestaties in de handel krijgt voor een verhoogd risico.

Dat gezegd hebbende, ontdekte ik dat de servers met innodb_flush_log_at_trx_commit=0 slechter presteerden (d.w.z. met 10-100 keer meer "lange updates") dan de servers met innodb_flush_log_at_trx_commit=2 . Bovendien verbeterden de dingen onmiddellijk op de slechte gevallen toen ik het naar 2 schakelde (let op:je kunt het meteen wijzigen).

Dus mijn vraag is, waar is die van jou op ingesteld? Merk op dat ik deze parameter niet de schuld geef, maar eerder wil benadrukken dat de context verband houdt met dit probleem.



  1. Proactieve SQL Server Health Checks, Deel 5:Wachtstatistieken

  2. Opgeslagen procedure/functiedefinitie bekijken in MySQL

  3. SEC_TO_TIME() Voorbeelden – MySQL

  4. MySQL - Waarom worden COLLATION-regels genegeerd door de LIKE-operator voor het Duitse ß-teken