Tenemos una tabla MySQL que tiene un campo de incremento automático establecido como INT (11). Esta tabla prácticamente almacena una lista de trabajos que se ejecutan en una aplicación. En cualquier momento durante la vida útil de la aplicación, la tabla podría contener miles de entradas o estar completamente vacía (es decir, todo ha terminado).
El campo no tiene una clave externa para nada más.
El incremento automático parece reiniciarse aleatoriamente a cero, aunque en realidad nunca hemos podido atrapar el reinicio.
El problema se hace evidente porque vemos que el campo de incremento automático llega a, digamos, 600,000 registros más o menos, y luego, un tiempo después, el campo de incremento automático parece ejecutarse en los 1000 bajos.
Es casi como si el incremento automático se reiniciara si la tabla está vacía.
¿Es esto posible y, si es así, cómo lo apago o cambio la manera en que se restablece?
Si no es así, ¿alguien tiene una explicación de por qué podría estar haciendo esto?
¡Gracias!
fuente
Respuestas:
http://dev.mysql.com/doc/refman/4.1/en/innodb-auto-increment-handling.html
Debido a esto, cuando el servicio (o servidor) se reinicia, sucederá lo siguiente:
Entonces, en inglés simple, después de que se inicia el servicio MySQL, no tiene idea de cuál debería ser el valor de incremento automático para su tabla. Entonces, cuando inserta una fila por primera vez, encuentra el valor máximo del campo que usa el incremento automático, agrega 1 a este valor y usa el valor resultante. Si no hay filas, comenzará en 1.
Esto fue un problema para nosotros, ya que estábamos usando la tabla y la función de autoincremento de mysql para administrar perfectamente las identificaciones en un entorno de subprocesos múltiples donde los usuarios se redirigían a un sitio de pago de terceros. Así que teníamos que asegurarnos de que la identificación que el tercero nos envió y nos devolvió fuera única y que se mantuviera así (y, por supuesto, existe la posibilidad de que el usuario cancele la transacción después de haber sido redirigido).
Así que estábamos creando una fila, obteniendo el valor de incremento automático generado, eliminando la fila para mantener limpia la tabla y reenviando el valor al sitio de pago. Lo que terminamos haciendo para solucionar el problema de la forma en que InnoDB maneja los valores de AI fue lo siguiente:
Esto siempre mantiene el último Id. De transacción generado como una fila en la tabla, sin explotar innecesariamente la tabla.
Espero que ayude a cualquier otra persona que pueda encontrarse con esto.
Editar (2018-04-18) :
Como Finesse menciona a continuación, parece que el comportamiento de esto se ha modificado en MySQL 8.0+.
https://dev.mysql.com/worklog/task/?id=6204
La redacción de ese registro de trabajo es, en el mejor de los casos, defectuosa, sin embargo, parece que InnoDB en esas versiones más nuevas ahora admite valores de inclusión automática persistentes en todos los reinicios.
-Gremio
fuente
Hemos experimentado este problema y hemos descubierto que cuando la tabla de optimización se ejecutó en una tabla vacía, el valor de incremento automático también se restableció. Vea este informe de error de MySQL .
Como solución alternativa, puede hacer:
En lugar de
OPTIMIZE TABLE
.Parece que esto es lo que MySQL hace internamente (sin establecer el valor de incremento automático, obviamente)
fuente
Solo un disparo en la oscuridad: si la aplicación está utilizando a
TRUNCATE TABLE
para vaciar la tabla cuando termine de procesar, eso restablecerá el campo de incremento automático. Aquí hay una breve discusión sobre la cuestión. Aunque ese enlace menciona que InnoDB no restablece los aumentos automáticos en un trunc, eso se informó como un error y se solucionó hace unos años.Suponiendo que mi suposición es correcta, puede cambiar de truncar a eliminar para solucionar el problema.
fuente
Solo un restablecimiento explícito de ese valor, o una caída / recreación de ese campo u otra operación violenta similar debería restablecer un contador de aumento automático. (El TRUNCATE fue una muy buena teoría.) Parece imposible que de repente estés envolviendo un INT de 32 bits cuando el último valor que presencias es solo 600k. Definitivamente no debería reiniciarse solo porque la tabla se vacía. O tienes un error mysql o algo en tu código PHP. O el chico del cubículo de al lado te está engañando.
Puede depurar activando el registro binario , ya que contendrá declaraciones como esta en todo momento:
Entonces, al menos, puede ver cada detalle de lo que está sucediendo en esa tabla, incluso justo antes de que se reinicie el contador.
fuente
ALTER TABLE table_name ENGINE = MyISAM
Funciona para mi. Nuestra mesa siempre se mantiene muy pequeña, por lo que no necesita InnoDB.
fuente
InnoDB no almacena el valor de incremento automático en el disco, por lo que lo olvida cuando se cierra el servidor MySQL. Cuando el MySQL se inicia de nuevo, el motor InnoDB restaura el valor de incremento automático de esta manera:
SELECT (MAX(id) + 1) AS auto_increment FROM table
. Este es un error que se corrige en MySQL versión 8.0.Cambie el motor de la tabla para resolver el problema:
O actualice el servidor MySQL a la versión 8.0 cuando se lance.
fuente