sql >> Database teknologi >  >> RDS >> Mysql

MySQL-deadlocking-problem med InnoDB

Dette forårsager et dødvande, fordi UPDATE forespørgslen låser alle rækker i tabellen, og afhængigt af de anvendte indekser (eller mangel på samme), vil to forskellige sessioner potentielt låse dem i lidt forskellig rækkefølge. Husk at UPDATE , DELETE , og SELECT ... FOR UPDATE vil låse alle rækker, de støder på, uanset om disse rækker matcher alle WHERE forhold eller ej. Så når du bruger dem, bør du prøve hårdt for at være sikker på, at de støder på så få rækker som muligt, ved at bruge indekser (ideelt set den primære nøgle) og undgå vage eller bredt udvalgte forhold.

Mit forslag til arbejdskøer er stort set universelt:Lås så lidt som muligt så sjældent som muligt og altid i en deterministisk rækkefølge. Så generelt:

  1. Brug ikke-låsende læsninger (almindelig SELECT). ) for at finde arbejde at lave ved at lede efter ting, som din medarbejder ved, hvordan man gør, og som i øjeblikket ikke er gjort krav på (lease_owner IS NULL AND lease_expiry IS NULL -- eller lignende).
  2. Vælg et arbejdsemne (eller et par stykker, hvis du tør, men en er langt enklere og giver normalt mulighed for helt acceptabel ydeevne).
  3. Opdater dit arbejdselement (for at gøre krav på det, men under alle omstændigheder skal det også opdateres):
    1. Åbn en transaktion.
    2. Lås dit valgte arbejdsemne med SELECT ... FOR UPDATE -- Hvis den ikke længere er uopkrævet, skal du afbryde og vælge en anden.
    3. Opdater dit valgte arbejdselement med dit arbejder-id og en udløbstid for din lejekontrakt på det.
    4. Bekræft din transaktion med det samme.
  4. Begynd arbejdet med dine lejede arbejdsgenstande.
  5. I en anden proces leder en anden poller efter forladt arbejde og gør krav på det (via den samme opdateringsproces ovenfor).

Du kan nemt få meget høj gennemstrømning med dette design (tusindvis af jobs i sekundet), og i det væsentlige uden uenighed og uden bestillingsproblemer. Optimeringer for at vælge arbejde, der er mindre tilbøjelige til at komme i konflikt med andre meningsmålere, er enkle og effektive (f.eks. modul på job-id eller lignende, valgt for at undgå udsultning af job). Nøglen er at huske, at konflikt om jobvalg er okay -- bare afbryd og prøv igen, og alt går meget hurtigt.

Alle låseskrivninger for emner/jobs i arbejdskø bør kun udføres på enkelte rækker og kun med primærnøgle .




  1. PHP - byg associativt array på flere niveauer fra database (sortér byer efter stat fra db)

  2. MySQL Trigger - opdater tabel med værdi valgt fra en anden tabel

  3. Sådan indsætter du et nyt auto-increment ID

  4. MySQL-producerende kolonner med loop i en select-sætning