Estoy usando mysql (5.0.32-Debian_7etch6-log) y tengo una noche de ejecución de la carga masiva php (5.2.6) script (utilizando Zend_DB (1.5.1) a través de PDO) que hace lo siguiente:

  1. truncar un conjunto de 4 ‘importar’ tablas
  2. inserción masiva de datos en estos 4 ‘importar’ tablas (re-uso de identificadores que han sido previamente en las tablas, pero me trunca toda la tabla, por lo que no debería ser un problema, ¿verdad?)
  3. si todo va bien, cambiar el nombre de la ‘vivir’ tablas ‘temp’, la ‘importación’ tablas ‘vivir’ y luego el ‘temp’ (viejo ‘en vivo’) tablas para ‘importar’

Esto funcionó muy bien durante semanas. Ahora estoy de vez en cuando llegar esto, en algún lugar en el medio de toda la carga a granel proceso:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '911' for key 1

Cuenta que, esta no es la primera identificación que ha estado en la mesa antes de que el truncamiento ya. Cuando acabo de iniciar la secuencia de comandos manualmente de nuevo, funciona como un encanto.

Alguna idea? las sobras de los índices, algo que ver con el cambio de nombre, tal vez?

Además, al consultar la tabla para una entrada con el id al 911 después de eso, no es ni siquiera allí.

OriginalEl autor | 2008-10-21

6 Comentarios

  1. 2

    Errores como esto puede ocurrir cuando una tabla MyISAM se convierte en corrupto. Ejecutar el comando reparar en la tabla en cuestión es generalmente todo lo que se requiere para solucionarlo:

    > repair table mytablename;

    La mejor solución es no usar MyISAM para las mesas de los datos está en constante cambio – InnoDB es mucho más a prueba de balas, y como Pablo señala correctamente, puede utilizar transacciones en tablas InnoDB, pero no en MyISAM.

    Por cierto, me gustaría evitar el cambio de nombre de las tablas sobre la marcha – que es bastante torpe lo que hay que hacer sobre una base regular, y puede causar algunos resultados inesperados si alguna vez tienen otros usuarios en el sistema, mientras que el cambio de nombre que está pasando. ¿Por qué no hacer algo como esto:

    > truncate table temptable;
    > truncate table importtable;
    
    > #bulk insert new data
    > insert into importtable(col1,col2,col3) 
    > values(1,2,3),(4,5,6),(7,8,9);
    
    > #now archive the live data
    > insert into temptable(col1,col2,col3)
    > select col1,col2,col3 from livetable;
    
    > #finally copy the new data to live
    > truncate table livetable;
    > insert into livetable(col1,col2,col3)
    > select col1,col2,col3 from importtable;

    Por supuesto, si está insertando un número muy grande de filas, a continuación, se corre el riesgo de que todos sus datos en vivo no está disponible durante el tiempo que la inserción se lleva a completar, pero en general, este enfoque es mucho menos destructivas para los índices, desencadenadores o cualquier otra cosa que puede estar vinculado a las tablas en cuestión.

    OriginalEl autor

  2. 1

    Al parecer hubo algunos problemas de bloqueo o algo, yo era capaz de reproducir el comportamiento de disparo ‘SELECCIONAR’ declaraciones a los afectados y tablas relacionadas en una conexión en paralelo.

    ahora he utilizado DELETE FROM en lugar de TRUNCATE y cambiado el RENAME TABLE declaraciones (donde hice 3 cambia el nombre a la vez cada uno) a un grupo de solo ALTER TABLE xxx RENAME TO zzz declaraciones y no se puede reproducir el error más.

    así que esto podría ser resuelto. tal vez alguien más puede beneficiarse de mi día pasó con la investigación y un montón de prueba y error.

    OriginalEl autor

  3. 0

    Podría algún otro script ser la inserción en la base de datos, mientras que el script de importación se está ejecutando?

    OriginalEl autor Greg

  4. 0

    Ha intentado habilitar el registro de consultas para ver si realmente SON la inserción de un duplicado?

    Se puede reproducir en su entorno de prueba? No permitir el registro de consultas en la producción.

    Es posible que la tabla ha sido dañado si el problema es genuino; esto podría ser causado por un número de cosas, pero chunga de hardware o de falta de energía son algunas de las posibilidades.

    Comprobar el registro de mysql para ver si ha tenido problemas (o bloqueado) recientemente, o durante el período.

    De nuevo, todo lo que puedo sugerir es tratar de reproducir en su entorno de prueba. Crear muy grandes cargas de datos de prueba y en varias ocasiones la carga de ellos.

    OriginalEl autor MarkR

  5. 0

    Que están utilizando las transacciones? Puede eliminar una gran cantidad de este tipo de problemas con las transacciones, especialmente si es posible bloquear las tablas o conjunto de aislamiento de la transacción modo serializable. Yo no estoy muy familiarizado con aquellos en MySQL, pero creo que las transacciones sólo funcionan en tablas InnoDB (o que podrían ser obsoletos conocimiento).

    OriginalEl autor Paul Tomblin

  6. 0

    Está creando un nuevo registro con el campo ‘id’ se omite (o NULL),
    PERO antes de haber actualizado otro récord y se ha cambiado el ‘id’ a ‘911’.
    En otras palabras, usted no puede crear otro registro si su tabla AUTO_INCREMENT valor.

    OriginalEl autor Phpdevmd

Dejar respuesta

Please enter your comment!
Please enter your name here