2012-08-22 32 views
8

Tengo una tabla llamada tbl_jobs que almacena los metadatos de algunas tareas en segundo plano que se ejecutan en la aplicación. El esquema es como:Entrada duplicada para la clave 'PRIMARY' en mysql

CREATE TABLE `tbl_jobs` (
    `type` varchar(30) NOT NULL DEFAULT '', 
    `last_run_on` datetime NOT NULL, 
    `records_updated` text, 
    PRIMARY KEY (`type`,`last_run_on`), 
    UNIQUE KEY `index2` (`type`,`last_run_on`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$ 

Siempre que una tarea se ejecuta realiza una entrada en la tabla con el type que es un identificador único para diferentes puestos de trabajo, y la run timerecords updated en ese plazo.

Hay dos trabajos diferentes que se ejecutan al mismo tiempo con tipos: MAILER_UNLOCKED_REWARDS y MAILER_ALMOST_UNLOCKED.

Cuando estos trabajos intentan insertar sus entradas con la misma marca de tiempo, solo uno de ellos se inserta y el otro arroja una entrada duplicada para el error de clave.

Por ejemplo, los dos trabajos corrieron la siguiente:

INSERT INTO tbl_jobs 
      (type, 
      last_run_on, 
      records_updated) 
VALUES  ('MAILER_ALMOST_UNLOCKED', 
      '2012-08-22 19:10:00', 
      'f8a35230fb214989ac75bf11c085aa28:b591426df4f340ecbce5a63c2a5a0174') 

que se ejecutó correctamente, pero cuando la segunda tarea se ha ejecutado el comando de inserción

INSERT INTO tbl_jobs 
      (type, 
      last_run_on, 
      records_updated) 
VALUES  ('MAILER_UNLOCKED_REWARDS', 
      '2012-08-22 19:10:00', 
      '8a003e8934c07f040134c30959c40009:59bcc21b33a0466e8e5dc50443beb945') 

Se lanzó el error

Duplicate entry 'M-2012-08-22 19:10:00' for key 'PRIMARY' 

La clave principal es la combinación de type y last_run_on columnas

Si elimino la entrada para el primer trabajo, la inserción tiene éxito, es decir, está pidiendo que timestamp sean únicos.

Sin embargo, el conflicto por el mismo timestamp ocurre solo entre estos dos trabajos. Hay otros trabajos que se insertan para el mismo timestamp.

¿Alguna idea sobre cuál podría ser el problema?

+1

puede mostrar el 'show crear la tabla tbl_jobs' – jcho360

+0

Sólo un comentario, yo recomendaría el uso de una clave sustituta. Puede tener más de una entrada cada segundo. – Kermit

+1

Dado que una clave principal es necesariamente única, debe eliminar la línea 'UNIQUE KEY' de su script. – sp00m

Respuesta

4

¿Está utilizando todo el campo "tipo" en su índice? ¿O solo el primer personaje? Dado que la clave de MySQL se queja es

M-2012-08-22 19:10:00 

en lugar de Mailer _...

intente ejecutar:

SHOW INDEXES FROM tbl_jobs; 

Se debe dar algo como:

+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| tbl_jobs |   0 | PRIMARY |   1 | type  | A   |   0 |  NULL | NULL |  | BTREE  |   |    | 
| tbl_jobs |   0 | PRIMARY |   2 | last_run_on | A   |   0 |  NULL | NULL |  | BTREE  |   |    | 

..

y sospecho que se mostrará en su lugar "1" en la columna de la Sub_part del índice primario:

+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+ 
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | 
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 
| tbl_jobs |   0 | PRIMARY |   1 | type  | A   |   0 |  1 | NULL |  | BTREE  |   |    | 
| tbl_jobs |   0 | PRIMARY |   2 | last_run_on | A   |   0 |  NULL | NULL |  | BTREE  |   |    | 

...

Por cierto, la clave principal es siempre único, por lo que el segundo índice index2 declaro hay redundante.

+0

Estoy usando la clave de tipo completo. No puedo entender qué hace M- allí. – mickeymoon

+0

@mickeymoon, el error informado para PRIMARY no es coherente con los resultados. Hay algo mal en la definición, creo que MOSTRAR ÍNDICES ayudará (marque la columna "sub_parte"). – LSerni

+0

@Iserni: como señaló usted, el 'sub_part' es de hecho ** 1 ** para la columna' tipo'. pero, ¿qué implicaciones tiene? y cómo resolverlo? – mickeymoon

0

Lo primero: debe asegurarse de que la PRIMARY KEY se haya identificado AUTO_INCREMENT. Lo segundo: simplemente habilita el incremento automático por: ALTER TABLE [nombre de la tabla] AUTO_INCREMENTO = 1 Lo tercero: cuando ejecuta el comando Insertar, debe omitir esta tecla.

+0

La clave principal, en este caso, es alfanumérica, por lo que no se puede aplicar la configuración 'AUTO_INCREMENT'. – fusion3k

0

He visto este error si tengo un cierre del sistema o un problema de red. Realmente no tienes un duplicado en tu db. Ese es un error db MySQL. Todo lo que necesita hacer es: si realiza su inserción y no es true, simplemente modifique una de las columnas de su tabla que desea insertar en varchar a text o bigint y luego vuelva a hacer la inserción. Eso resuelve el problema.

If(!$insert) 
{  
$alter=Mysql_query("alter table  

`table_name` change `table_name` 

`table_name` bigint(255) not null");  

If($alter){ 

//you then redo your insertion.  

} 


} 
Cuestiones relacionadas