2012-08-22 14 views
8

Ho una tabella denominata tbl_jobs che memorizza i metadati di alcuni processi in background in esecuzione nell'applicazione. Lo schema è simile:Duplica voce per chiave "PRIMARY" in 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$$ 

Ogni volta che un lavoro viene eseguito lo rende una voce nella tabella con la type che è un identificatore univoco per diversi lavori, run time e la records updated in quel periodo.

Esistono due diversi lavori che vengono eseguiti contemporaneamente con i tipi: MAILER_UNLOCKED_REWARDS e MAILER_ALMOST_UNLOCKED.

Quando questi lavori cercano di inserire le voci con lo stesso timestamp, solo uno di essi viene inserito e l'altro genera un errore Duplicato per la chiave.

Per esempio i due lavori eseguito il seguente:

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

che correva con successo ma quando il secondo lavoro ha eseguito il comando di inserimento

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

Si gettò l'errore

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

La chiave primaria è la combinazione di type e last_run_on colonne.

Se elimino la voce per il primo lavoro, l'inserimento ha esito positivo, cioè è necessario che timestamp sia univoco.

Tuttavia il conflitto per lo stesso timestamp si verifica solo tra questi due processi. Esistono altri lavori che vengono inseriti per lo stesso timestamp.

Qualche idea su quale potrebbe essere il problema?

+1

è possibile mostrare lo show create table tbl_jobs' – jcho360

+0

Solo un commento ', mi consiglia di utilizzare una chiave surrogata. Potresti avere più di una voce che si verifica ogni secondo. – Kermit

+1

Poiché una chiave primaria è necessariamente univoca, è necessario rimuovere la riga 'UNIQUE KEY' del proprio script. – sp00m

risposta

4

Stai utilizzando l'intero campo "tipo" nel tuo indice? O solo il primo personaggio? Poiché la chiave di MySQL si lamenta è

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

invece di MAILER _...

prova ad eseguire:

SHOW INDEXES FROM tbl_jobs; 

Dovrebbe dare qualcosa di simile:

+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+ 
| 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  |   |    | 

..

e ho il sospetto che mostrerà invece "1" nella colonna Sub_part dell'indice PRIMARIA:

+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+ 
| 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  |   |    | 

...

BTW, la chiave primaria è sempre unico, in modo che il secondo indice index2 si dichiara c'è ridondante.

+0

Sto usando l'intero tipo di chiave. Non riesco a capire cosa sta facendo M-. – mickeymoon

+0

@mickeymoon, l'errore segnalato per PRIMARY è incoerente con i risultati. C'è qualcosa di sbagliato nella definizione, credo che SHOW INDEXES aiuterà (controlla la colonna "sub_part"). – LSerni

+0

@Iserni: come sottolineato da te il 'sub_part' è in effetti ** 1 ** per la colonna' type'. ma quali implicazioni ha? e come fare per risolverlo? – mickeymoon

0

La prima cosa: devi assicurarti che PRIMARY KEY sia stato impostato AUTO_INCREMENT. La seconda cosa: abilita semplicemente l'incremento automatico di: ALTER TABLE [nome tabella] AUTO_INCREMENT = 1 La terza cosa: quando esegui il comando di inserimento devi saltare questa chiave.

+0

La chiave primaria - in questo caso - è alfanumerica, quindi l'impostazione "AUTO_INCREMENT' non può essere applicata. – fusion3k

0

Ho visto questo errore se ho un arresto del sistema o un problema di rete. Davvero non hai un duplicato nel tuo db. Questo è un errore di db MySQL. Tutto quello che devi fare è: se fai il tuo inserimento e non è true, basta modificare una delle colonne del tuo tavolo che vuoi inserire in uno da varchar a text o bigint e quindi ripetere l'inserimento. Questo risolve il 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.  

} 


} 
Problemi correlati