Remember that the Auto Increment fault

  

The fault is basically the same: on a black windy night, the hard-pressed programmer was awakened by a sudden alarm message, which was a problem with the database. Although the query operation is normal, the creation operation fails. After debugging, the reason is that the table is inserted with a row of problem data, and the value of the self-incrementing field is explicitly set to the maximum value of the integer, resulting in subsequent lack. The province inserted data cannot get a valid primary key value.

We might as well create a test table to illustrate the problem:

CREATE TABLE IF NOT EXISTS `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL , PRIMARY KEY (`id`)) ENGINE=InnoDB;

Then insert a row of problem data:

INSERT INTO test (id, name) VALUES (2147483647, 'x');

results Cannot execute normal insert statement:

INSERT INTO test (name) VALUES ('y');

The database will report an error:

#1062 – Duplicate entry ‘2147483647&rsquo For key ‘PRIMARY’

In other words, the InnoDB table type internally maintains a counter for the Auto Increment field to provide a necessary unique identifier for subsequent inserts. Whenever new data is inserted, the value of the counter is updated to MAX + 1. If you insert data uniquely identified as 2147483647, the counter will not update properly because it has reached the upper limit of the INT data type.

Since the reason for the problem has been clarified, the first feeling is to reset the counter of the Auto Increment field to a reasonable value. We can try to execute the following statement after deleting the problem data:
< Pre>ALTER TABLE test AUTO_INCREMENT = 123;

This method can undoubtedly achieve the goal, but there is a disadvantage: in MySQL, when ALTER a table, it is actually equivalent to re-create a table! If the original data is large, the process will be very slow.

Let's consider other methods. Since the problem lies in the implicit setting of the unique identifier, then we may wish to change the idea and explicitly set the unique identifier, for example, by "SELECT MAX … FOR UPDATE". The way the direct query gets a unique identifier and is explicitly set in the INSERT statement that is executed later.

However, this method is not transparent enough to modify the business code. A more transparent method is to use a trigger:

CREATE TABLE seq ( `id` int(11) NOT NULL AUTO_INCREMENT, `created ` timestamp NOT NULL, PRIMARY KEY (`id`)) Engine=InnoDB;DELIMITER |
 ;CREATE TRIGGER test_seq BEFORE INSERT ON testFOR EACH ROWBEGIN INSERT INTO seq (created) VALUES (NOW()); SET NEW.id = LAST_INSERT_ID();END;|
 ;

The problem seems to have been solved here, but after consulting @linux stray cat, the accident got a very simple answer: just delete the problem data, restart the service. In fact, there is a description in the document:

If you specify an AUTO_INCREMENT column for an InnoDB table, the table handle in the InnoDB data dictionary contains a special counter called the auto-increment counter that is used in assigning new values For the column. This counter is stored only in main memory, not on disk.


A server restart also cancels the effect of the AUTO_INCREMENT = N table option in CREATE TABLE and ALTER TABLE statements, which you can use with InnoDB tables to set the initial counter value or alter the current counter value.

The so-called: stepping through the iron shoes innocent, it takes no effort.

Copyright © Windows knowledge All Rights Reserved