mysql insert on duplicate key related deadlock - mysql

In logs I have deadlocks that are related to this query:
INSERT INTO `driver_state` (id, state)
VALUES('83799','waiting')
ON DUPLICATE KEY UPDATE
state = IF(state = 'active', state, VALUES(state));
Exact error:
ER_LOCK_DEADLOCK: Deadlock found when trying to get lock; try restarting transaction
I have tried to reason and understand how this query could even possibly cause a deadlock, but haven't gotten very far.
Table structure
CREATE TABLE IF NOT EXISTS `driver_state` (
`id` int(11) NOT NULL,
`state` enum('inactive','waiting_orders','has_order','busy') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
In this case we use MEMORY table, but with InnoDB it has same locking issues.
Table gets lots of these insert on duplicate key queries and select queries (All select queries are very fast and optimized). Transactions are not used anywhere nor manual locking etc.
Could you please propose any ideas what could possibly cause this?

Why is there an IF statement in your ON DUPLICATE KEY UPDATE?
I think your problem is there. It looks like you are saying if there is a duplicate key, set the value of state depending on what the value of state is.
What is wrong with ON DUPLICATE KEY UPDATE state='waiting'?
I would try this to see if the deadlock goes away to confirm that it is caused by the IF.
I would also explain here in greater detail what you are trying to do.

Related

MySQL - 'Failed to read auto-increment value from storage engine' with no records

I'm trying to insert a row into my database like I always made.
The query I'm using is the following :
INSERT INTO catbeni (Nome) VALUES ('Televisore')
As you can see, I'm using the simplest way to insert a row into the database. Now, I display my table with an HTML table, and I allow people to remove rows directly from the HTML page. By clicking a button, they execute the following query to remove the row :
DELETE FROM table WHERE id=any_id
The problem is that when I delete each records, so that I've got no record in my table, I get this error trying to insert a new one into my database :
Failed to read auto-increment value from storage engine
I already inserted rows in an empty table, but I've never had this error. Looking for a solution online I found a few questions on Stack Overflow, but none of the solutions worked for me. The solution I found most of the time is executing a query on my table to reset the AUTO_INCREMENT property of my PRIMARY KEY.
This is the query, caught from this question :
ALTER TABLE `table_name` AUTO_INCREMENT = 1
The only solution that worked for me, is accessing phpMyAdmin and inserting manually a row with any id, but I naturally can't solve my problem following this way.
This is the CREATE TABLE statement used to create my table :
CREATE TABLE `catbeni` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Nome` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
I hope I'm clear!

MySQL foreign key clause on create statement causing lost connection error

I am running MySQL 5.5.43-0+deb8u1 and trying to create the following table:
CREATE TABLE IF NOT EXISTS `car_favorites` (
`id` INTEGER UNSIGNED auto_increment ,
`user_id` INTEGER UNSIGNED NOT NULL,
`car_id` INTEGER UNSIGNED NOT NULL,
`created_at` DATETIME NOT NULL,
`updated_at` DATETIME NOT NULL,
`deleted_at` DATETIME,
UNIQUE `user_id_car_id` (`user_id`, `car_id`),
PRIMARY KEY (`id`),
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
The referenced tables users and cars already exist. When I try to run this query I get the following error:
ERROR 2013 (HY000): Lost connection to MySQL server during query
Afterwards, the table is listed when do something like SHOW TABLES, but if I try to execute a query against the table (i.e. DESCRIBE car_favorites) the service reports that the table doesn't exist, and restarting the service makes the table disappear.
However, when I remove this part of the query:
FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
The table is created with no problems. Strangely, if I run this query:
SHOW ENGINE INNODB STATUS;
immediately after running the failing create query, there are no foreign key errors shown or listed. Turning up MySQL logging and examining the error log shows this rather vague error:
13:21:41 UTC - mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
Followed by a stack trace and some other info, but nothing specific.
I have no idea why this foreign key clause is causing this crash. Any insight or point in the right direction would be greatly appreciated.
Through the process of writing this question, I found the answer. Fairly obvious if you actually take a breath and read the create query.
Since I declared the column car_id with NOT NULL, then the ON DELETE SET NULL part of the foreign key declaration doesn't make any sense. Changing that clause to ON DELETE CASCADE solved the problem.
Why MySQL chokes hard and can't give me a more specific error, I have no idea.

MySQL INSERT with a Composite Key

Edit: I am a muppet. So after careful trawling of the rows I was trying to insert, there was a bug in my code which meant empty strings were being inserted. Because this happened more than once, MySQL quite rightly threw an error because I was trying to insert the same data again. Sorry for any time wasted! Mods, feel free to delete this.
My table structure is as follows:
CREATE TABLE IF NOT EXISTS `foo` (
`user` varchar(80) NOT NULL,
`group` varchar(20) NOT NULL,
`completed` int(1) NOT NULL,
PRIMARY KEY (`user`,`group`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Now when I try to do a MySQL Insert, it throws errors saying that I have duplicates (which with the key set up, won't work). What I don't get is why I am seeing those errors. I know that I am not inserting a duplicate of those composite values (although some values will appear many times in the group column.
An example of my insert: INSERT INTO food(user, group, completed) VALUES ('user1', 'groupA', '0'),('user2', 'groupB', '0'),('user3', 'groupA', '0');
So the composite of user and group are definitely unique. So why does it fail complaining that I am trying to insert a non unique key?
The error I get is: #1062 - Duplicate entry 'groupA' for key 1. It seems to be fine if I am trying to insert one or two rows at a time, but I am currently trying to insert 140 rows in one go.
Thanks!
You can't use "group" as a column name because it's a reserved word.
I altered the column name and your query works just fine, as it should.
Since you've completely "obfuscated" your actual SQL, it's entirely possible that you edited out a typo that's responsible for your error.
Your key is not composite. I fit was composite error would be like this
ERROR 1062 (23000): Duplicate entry 'user1-groupA' for key 'PRIMARY'
Notice, it displays values of all columns that make index.
I think You have another index just on column group.

MySQL duplicate entry error even though there is no duplicate entry

I am using MySQL 5.1.56, MyISAM. My table looks like this:
CREATE TABLE IF NOT EXISTS `my_table` (
`number` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`money` int(11) NOT NULL,
PRIMARY KEY (`number`,`name`)
) ENGINE=MyISAM;
It contains these two rows:
INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(1, 'S. Name', 150), (2, 'Another Name', 284);
Now I am trying to insert another row:
INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(2, 'S. Name', 240);
And MySQL just won't insert it while telling me this:
#1062 - Duplicate entry '2-S. Name' for key 'PRIMARY'
I really don't understand it. The primary key is on the first two columns (both of them), so the row I am trying to insert HAS a unique primary key, doesn't it?
I tried to repair the table, I tried to optimize the table, all to no avail. Also please note that I cannot change from MyISAM to InnoDB.
Am I missing something or is this a bug of MySQL or MyISAM? Thanks.
To summarize and point out where I think is the problem (even though there shouldn't be):
Table has primary key on two columns. I am trying to insert a row with a new combination of values in these two columns, but value in column one is already in some row and value in column two is already in another row. But they are not anywhere combined, so I believe this is supposed to work and I am very confused to see that it doesn't.
Your code and schema are OK. You probably trying on previous version of table.
http://sqlfiddle.com/#!2/9dc64/1/0
Your table even has no UNIQUE, so that error is impossible on that table.
Backup data from that table, drop it and re-create.
Maybe you tried to run that CREATE TABLE IF NOT EXIST. It was not created, you have old version, but there was no error because of IF NOT EXIST.
You may run SQL like this to see current table structure:
DESCRIBE my_table;
Edit - added later:
Try to run this:
DROP TABLE `my_table`; --make backup - it deletes table
CREATE TABLE `my_table` (
`number` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`money` int(11) NOT NULL,
PRIMARY KEY (`number`,`name`),
UNIQUE (`number`, `name`) --added unique on 2 rows
) ENGINE=MyISAM;
I know this wasn't the problem in this case, but I had a similar issue of "Duplicate Entry" when creating a composite primary key:
ALTER TABLE table ADD PRIMARY KEY(fieldA,fieldB);
The error was something like:
#1062 Duplicate entry 'valueA-valueB' for key 'PRIMARY'
So I searched:
select * from table where fieldA='valueA' and fieldB='valueB'
And the output showed just 1 row, no duplicate!
After some time I found out that if you have NULL values in these field you receive these errors. In the end the error message was kind of misleading me.
I had a similar issue, but in my case it turned out that I used case insensitive collation - utf8_general_ci.
Thus, when I tried to insert two strings which were different in a case-sensitive comparison, but the same in the case-insensitive one, MySQL fired the error and I couldn't understand what a problem, because I used a case-sensitive search.
The solution is to change the collation of a table, e.g. I used utf8_bin which is case-sensitive (or utf8_general_cs should be appropriate one too).
In case this helps anyone besides the OP, I had a similar problem using InnoDB.
For me, what was really going on was a foreign key constraint failure. I was referencing a foreign key that did not exist.
In other words, the error was completely off. The primary key was fine, and inserting the foreign key first fixed the problem. No idea why MySQL got this wrong suddenly.
Less common cases, but keep in mind that according to DOC https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html
When running an online ALTER TABLE operation, the thread that runs the ALTER TABLE operation will apply an “online log” of DML operations that were run concurrently on the same table from other connection threads. When the DML operations are applied, it is possible to encounter a duplicate key entry error (ERROR 1062 (23000): Duplicate entry), even if the duplicate entry is only temporary and would be reverted by a later entry in the “online log”. This is similar to the idea of a foreign key constraint check in InnoDB in which constraints must hold during a transaction.
In my case the error was caused by the outdated schema, one column was originally varchar(50) but the dump I was trying to import was created from a modified version of the schema that has varchar(70) for that column (and some of the entries of that field where using more than 50 chars).
During the import some keys were truncated and the truncated version was not unique anymore. Took a while to figure that out, I was like "but this supposedly duplicated key doesn't even exist!".
Try with auto increment:
CREATE TABLE IF NOT EXISTS `my_table` (
`number` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`money` int(11) NOT NULL,
PRIMARY KEY (`number`,`name`)
) ENGINE=MyISAM;
Your code is work well on this demo:
http://sqlfiddle.com/#!8/87e10/1/0
I think you are doing second query (insert...) twice. Try
select * from my_table
before insert new row and you will get that your data already exist or not.
i have just tried, and if you have data and table recreation wouldnt work, just alter table to InnoDB and try again, it would fix the problem
In case anyone else finds this thread with my problem -- I was using an "integer" column type in MySQL. The row I was attempting to insert had a primary key with a value larger than allowed by integer. Switching to "bigint" fixed the problem.
As per your code your "number" and "Name" are primarykey and you are inserting S.NAME in both row so it will make a conflict. we are using primarykey for accessing complete data. here you cant access the data using the primarykey 'name'.
im a beginner and i think it might be the error.
In my case the error was very misleading. The problem was that PHPMyAdmin uses "ALTER TABLE" when you click on the "make unique" button instead of "ALTER IGNORE TABLE", so I had to do it manually, like in:
ALTER TABLE mytbl ADD UNIQUE (columnName);
This problem is often created when adding a column or using an existing column as a primary key. It is not created due to a primary key existing that was never actually created or due to damage to the table.
What the error actually denotes is that a pending key value is blank.
The solution is to populate the column with unique values and then try to create the primary key again. There can be no blank, null or duplicate values, or this misleading error will appear.
For me a noop on table has been enough (was already InnoDB):
ALTER TABLE $tbl ENGINE=InnoDB;
tl;dr: my view showed my table was empty but the view excluded existing rows.
I had the same problem but mine was because I was inserting the same test rows I had used before. When I checked to see if my table was empty, I used a view that excluded different tenants so the search came back empty. When I checked the actual table, the previous records were still there.
Once I had deleted the existing records, the insert worked. Only half a day of frustration lost to this one...
Had this error, when adding a composite primary key that is ADD PRIMARY KEY (column1, column2, ...) The value of all the columns in that row must not be duplicated.
For Example:
You do ADD PRIMARY KEY (name, country, number)
name
country
number
collin
Uk
5
collin
Uk
5
This will throw an error #1062 - Duplicate entry 'collin-UK-5' for key 'PRIMARY' because the columns combined have duplicate
So if you see this format of error just check and ensure that the columns you want to add a composite primary key to combined don't have duplicates.
Another reason you may be getting this error is because the same restriction exists in another related table, and they Keyname on the related table has the exact same name. I've had this happen once and it was quite difficult to identify.
i.e. if you have a trigger that inserts data to a different table (the "related" table) with the same restriction and same Keyname, MySQL will not include the name of the table throwing the error, only the Keyname.
As looking on your error #1062 - Duplicate entry '2-S. Name' for key 'PRIMARY' it is saying that you use primary key in your number field that's why it is showing duplicate Error on Number Field.
So Remove this primary Key then it inset duplicate also.

What could cause duplicate ids on a auto increment primary key field (mysql)?

RESOLVED
From the developer: the problem was that a previous version of the code was still writing to the table which used manual ids instead of the auto increment. Note to self: always check for other possible locations where the table is written to.
We are getting duplicate keys in a table. They are not inserted at the same time (6 hours apart).
Table structure:
CREATE TABLE `table_1` (
`sales_id` int(10) unsigned NOT NULL auto_increment,
`sales_revisions_id` int(10) unsigned NOT NULL default '0',
`sales_name` varchar(50) default NULL,
`recycle_id` int(10) unsigned default NULL,
PRIMARY KEY (`sales_id`),
KEY `sales_revisions_id` (`sales_revisions_id`),
KEY `sales_id` (`sales_id`),
KEY `recycle_id` (`recycle_id`)
) ENGINE= MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=26759 ;
The insert:
insert into `table_1` ( `sales_name` ) VALUES ( "Blah Blah" )
We are running MySQL 5.0.20 with PHP5 and using mysql_insert_id() to retrieve the insert id immediately after the insert query.
I have had a few duplicate key error suddenly appear in MySql databases in the past even though the primary key is defined and auto_increment. Each and every time it has been because the table has become corrupted.
If it is corrupt performing a check tables should expose the problem. You can do this by running:
CHECK TABLE tbl_name
If it comes back as corrupt in anyway (Will usually say the size is bigger than it actually should be) then just run the following to repair it:
REPAIR TABLE tbl_name
Does the sales_id field have a primary (or unique) key? If not, then something else is probably making inserts or updates that is re-using existing numbers. And by "something else" I don't just mean code; it could be a human with access to the database doing it accidentally.
As the other said; with your example it's not possible.
It's unrelated to your question, but you don't have to make a separate KEY for the primary key column -- it's just adding an extra not-unique index to the table when you already have the unique (primary) key.
We are getting duplicate keys in a table.
Do you mean you are getting errors as you try to insert, or do you mean you have some values stored in the column more than once?
Auto-increment only kicks in when you omit the column from your INSERT, or try to insert NULL or zero. Otherwise, you can specify a value in an INSERT statement, over-riding the auto-increment mechanism. For example:
INSERT INTO table_1 (sales_id) VALUES (26759);
If the value you specify already exists in the table, you'll get an error.
Please post the results of this query:
SELECT `sales_id`, COUNT(*) AS `num`
FROM `table_1`
GROUP BY `sales_id`
HAVING `num` > 1
ORDER BY `num` DESC
If you have a unique key on other fields, that could be the problem.
If you have reached the highest value for your auto_increment column MySQL will keep trying to re-insert it. For example, if sales_id was a tinyint column, you would get duplicate key errors after you reached id 127.