sql >> Base de Datos >  >> RDS >> Mysql

Problema de interbloqueo de MySQL con InnoDB

Esto está provocando un interbloqueo porque UPDATE query está bloqueando todas las filas de la tabla y, según los índices utilizados (o la falta de ellos), dos sesiones diferentes potencialmente los bloquearán en un orden ligeramente diferente. Recuerda que UPDATE , DELETE y SELECT ... FOR UPDATE bloqueará todas las filas que encuentre, ya sea que esas filas coincidan con todos los WHERE condiciones o no. Por lo tanto, al usarlos, debe esforzarse para asegurarse de que encuentren la menor cantidad de filas posible, mediante el uso de índices (idealmente, la clave principal) y evitando condiciones vagas o de selección amplia.

Mi sugerencia para las colas de trabajo es bastante universal:bloquee lo menos posible, lo menos posible y siempre en un orden determinista. Entonces, generalmente:

  1. Usar lecturas sin bloqueo (SELECT regulares ) para encontrar trabajo que hacer buscando cosas que su trabajador sabe hacer y que actualmente no están reclamadas (lease_owner IS NULL AND lease_expiry IS NULL -- o similar).
  2. Elija un elemento de trabajo (o varios si se atreve, pero uno es mucho más simple y normalmente permite un rendimiento perfectamente aceptable).
  3. Actualice su elemento de trabajo (para reclamarlo, pero en cualquier caso también debe actualizarse):
    1. Abra una transacción.
    2. Bloquee su elemento de trabajo elegido con SELECT ... FOR UPDATE -- Si ya no está sin reclamar, cancela y elige otro.
    3. Actualice su elemento de trabajo elegido con su identificación de trabajador y un tiempo de vencimiento para su contrato de arrendamiento.
    4. Confirme su transacción inmediatamente.
  4. Comience a trabajar en sus elementos de trabajo alquilados.
  5. En algún otro proceso, otro encuestador busca trabajo abandonado y lo anula (mediante el mismo proceso de actualización anterior).

Puede obtener fácilmente un rendimiento muy alto con este diseño (miles de trabajos por segundo) y esencialmente sin conflictos ni problemas de pedidos. Las optimizaciones para elegir el trabajo que es menos probable que entre en conflicto con otros encuestadores son simples y efectivas (por ejemplo, módulo en ID de trabajo o similar, elegido para evitar la inanición de trabajos). La clave es recordar que el conflicto en la selección de trabajo está bien -- simplemente cancela e inténtalo de nuevo y todo avanza muy rápido.

Todas las escrituras de bloqueo para trabajos/elementos de la cola de trabajo deben realizarse solo en filas individuales y por clave principal solo .