I have a table called tbl_jobs
that stores the meta data of some background jobs running in the application. The schema is like :
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$$
Whenever a job runs it makes an entry in the table with the type
which is a unique identifier for different jobs, run time
and the records updated
in that run.
There are two different jobs that run at same time with types : MAILER_UNLOCKED_REWARDS
and MAILER_ALMOST_UNLOCKED
.
When these jobs try to insert their entries with the same timestamp only one of them gets inserted and the other throws a Duplicate Entry for key error.
For instance the two jobs ran the following :
INSERT INTO tbl_jobs
(type,
last_run_on,
records_updated)
VALUES ('MAILER_ALMOST_UNLOCKED',
'2012-08-22 19:10:00',
'f8a35230fb214989ac75bf11c085aa28:b591426df4f340ecbce5a63c2a5a0174')
that ran successfully but when the second job ran the insert command
INSERT INTO tbl_jobs
(type,
last_run_on,
records_updated)
VALUES ('MAILER_UNLOCKED_REWARDS',
'2012-08-22 19:10:00',
'8a003e8934c07f040134c30959c40009:59bcc21b33a0466e8e5dc50443beb945')
It threw the error
Duplicate entry 'M-2012-08-22 19:10:00' for key 'PRIMARY'
The primary key is combination of type
and last_run_on
columns.
If I delete the entry for the first job the insertion succeeds, i.e it is asking for timestamp
alone to be unique.
However the conflict for the same timestamp
occurs only between these two jobs.There are other jobs that get inserted for the same timestamp
.
Any ideas on what could be the issue?
When creating a primary key or unique constraint after loading the data, you can get a “Duplicate entry for key 'PRIMARY'” error. If the data in the source database is valid and there are no any duplicates you should check which collation is used in your MySQL database.
Since both primary key and unique columns do not accept duplicate values, they can be used for uniquely identifying a record in the table. This means that, for each value in the primary or unique key column, only one record will be returned.
Primary key may not contain duplicate values. ... A primary key is a special relational database table column (or combination of columns) designated to uniquely identify all table records. It must contain a unique value for each row of data.
The Insert on Duplicate Key Update statement is the extension of the INSERT statement in MySQL. When we specify the ON DUPLICATE KEY UPDATE clause in a SQL statement and a row would cause duplicate error value in a UNIQUE or PRIMARY KEY index column, then updation of the existing row occurs.
Are you using the whole "type" field in your index? Or only the first character? Because the key MySQL is complaining about is
M-2012-08-22 19:10:00
instead of MAILER_...
Try running:
SHOW INDEXES FROM tbl_jobs;
It should give something like:
+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+
| 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 | | |
...
and I suspect it will show instead "1" in the Sub_part column of the PRIMARY index:
+----------+------------+----------+--------------+-------------+-----------+-------------+ ----------+--------+------+------------+---------+---------------+
| 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, the primary key is always unique, so the second index index2
you declare there is redundant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With