Why does MODIFY AUTO_INCREMENT need to rebuild the table? - mysql

We have loaded several tables (hundreds of millions of rows each) but the following query requires the entire table to be rewritten (the type is exactly the same apart from the AUTO_INCREMENT):
ALTER TABLE sales MODIFY id BIGINT(20) NOT NULL AUTO_INCREMENT;
Is this just a huge oversight by MySQL or does it fundamentally change the format the data on disk?

Changing the AUTO_INCREMENT characteristic of a column cannot be done as an online DDL change. Even when I try to request it explicitly:
mysql> alter table sales modify column id bigint not null auto_increment,
ALGORITHM=INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported.
Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
This case of changing the column definition seems to count as a change to the column type (based on the error message).
https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html#innodb-online-ddl-summary-grid says:
Change column data type... Only supports ALGORITHM=COPY
In MySQL 5.7, changing the type of a column is still required to rebuild the table, except in one case: increasing VARCHAR length is allowed as an INPLACE change.
You aren't the only one to think that it should be allowed to change the AUTO_INCREMENT property without doing a table restructure: https://bugs.mysql.com/bug.php?id=72109

Related

Failing to rename a column involved in partition in MySQL

I have created a table with the following query.
CREATE table IF NOT EXISTS result(id varchar(255) not null, product varchar(255), prodcount int, searched_at datetime default CURRENT_TIMESTAMP, primary key (id, product, searched_at)) partition by hash(yearweek(searched_at))
Now I need to change the column name of searched_at to created_at. While using AlterTable command, I am getting the following error:
"Error: ER_BAD_FIELD_ERROR: Unknown column 'searched_at' in 'partition function'"
It seems that there is already a bug raised in MySQL: https://bugs.mysql.com/bug.php?id=85413
Does this issue have any workarounds?
Well, you probably have to start with ALTER TABLE table DROP PARTITIONING.
However, I would recommend stopping there, except for fixing the indexes.
PARITITION BY HASH() probably has no viable use case.
It sounds like you may be searching on a date range? If so, BY HASH will touch all the partitions because, for all it knows, the data is wrapped every year.
Pleas provide the important queries; I will help you redo the indexes.

custom AUTO INCREMENT value not working

I have the following sql code to create a table
CREATE TABLE db.object (
`objid` bigint(20) NOT NULL AUTO_INCREMENT,
`object_type` varchar(32) NOT NULL,
PRIMARY KEY (`objid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
However, the values in the objid are coming out as 1,2,3... (The insert statement is not adding the ids)
Shouldn't AUTO_INCREMENT=2 make the objid start from 2 instead of 1
With InnoDB tables, the AUTO_INCREMENT value will be reset to the maximum value (plus 1) when the table is opened. The auto increment value exists only in memory, it is not persisted on disk.
A table open would happen, for example, when the MySQL instance was shutdown and then restarted, and a reference is made to the table.
A table can also be closed at other times. For example, when open_table_cache is exceeded (that is, when a large number of other tables is opened), MySQL will close some of the open tables, to make room in the cache for newly opened tables.
I believe this behavior is documented somewhere in the MySQL Reference Manual.
I used your SQL, created the object table and entered two values for object_type and objid started at 2. Can't see anything wrong here...
It might. There are enough exceptions and gotchas with auto-inc on InnoDB tables that it bears urging a full review of the documentation.
That said, there is one scenario I can think of where MySQL ignores the initializer value. I'll quote the documentation:
InnoDB uses the in-memory auto-increment counter as long as the server runs. When the server is stopped and restarted, InnoDB reinitializes the counter for each table for the first INSERT to the table, as described [here]:
InnoDB executes the equivalent of the following statement on the first insert into a table containing an AUTO_INCREMENT column after a restart:
SELECT MAX(ai_col) FROM table_name FOR UPDATE;
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.
So if you create that table, then do a server restart (like as part of a deployment process), you'll get a nice value of 1 for the initial row. If you want to countermand this, you need to create the table, then insert a dummy row with the auto-inc value you want, then restart, then delete the dummy row.

mariadb alter table lock strategy

I am using MariaDB 10.1.9. Short version: What I really want to know for certain is if I can modify an indexed auto_increment field on an innodb table from int to bigint without locking the table?
Long version: Is there a detailed explanation of which ALTER TABLE operations require which lock level? The documentation just says "Depending on the required operation and the used storage engine, different lock strategies can be used for ALTER TABLE.". It doesn't provide a link to any details and each operation on the ALTER TABLE page does not specify it's required level.
From experimentation, I know ADD COLUMN does not require a lock. MODIFY COLUMN allows reads, but can it be manually set to allow writes? The MariaDB documentation says you can set the lock level, but if you don't set it restrictive enough, it will give an error - but it doesn't say what that error is. The current table column definition looks like
`Id` int(10) NOT NULL AUTO_INCREMENT
KEY `Id` (`Id`)
When I try
ALTER TABLE MyTable MODIFY MyField bigint AUTO_INCREMENT LOCK=NONE;
I just get a generic SQL syntax error. Even if I specify DEFAULT, I get an error, so I'm not sure how to use the LOCK - which I would expect the proper error to tell me when I have chosen an improper lock level.
The syntax...
alter_specification [, alter_specification] ...
... requires a comma
ALTER TABLE MyTable
MODIFY COLUMN MyField BIGINT AUTO_INCREMENT, -- comma here
LOCK=NONE;
I'm guessing the error was not all that "generic" -- it should have said something about the right syntax to use near 'LOCK... which is your hint not that the quoted term is the beginning of the error, but rather that that the parser/lexer expected something other than the quoted value to occur at that position (because it was looking for the comma).
If the column you are altering is the primary key, a lock seems inevitable -- because the entire table should need rebuilding, including all the indexes, since the primary key "rides free" in all indexes, as it is what's used after a non-covering index lookup to actually find the rows matched by the index.

#1034-137 while fixing the table when adding new column to table

I have one table in my database in Cpanel server in which there are 17 columns currently,out of them,one is auto incremented field(which is a primary key).
currently in that table I have 600k rows.
I want to add a new column to table,but I'm getting the following error
1034-137 while fixing the table
Alter command I am using for adding the column
ALter table 'tablename' add 'columnname' Varchar(200) NOT NULL
Please help me what should i do to add the columns to the existing table
Because the new column does not allow NULL values, you will need to specify a default value for the column. All the existing rows in the table will be populated with the default value for the new column when you alter the table.
For example, to set the default value to empty string, you can use this statement.
alter table 'tablename' add 'columnname' Varchar(200) NOT NULL DEFAULT ''
Here is some documentation on using DEFAULT.
You can also drop the DEFAULT constraint after altering the table, so that future inserts into the table will fail if there is an attempt to insert a NULL value into that column,
After researching the error it seems that the indexing on your table may be having issues. Which tables are indexed other than your primary key?
In phpmyadmin select your table, then on the toolbar open Operations.
Under "Table maintenance" on the right hand side click the check table link to find out if there are any errors.
You may need to do some reindexing to correct the error.

MySQL - How to create an auto increement field in the DB?

I am entering records in the MySQL DB. Now I want to have a "Serial_Number" field that increements automatically whenever a record is entered into the DB.
I don't want this "Serial_Number" field to be the primary key of the DB.
How can I create this field (with the attributes needed to be set).
I am using "SQL YOG" to access MySQL. If you are aware of the SQL YOG then tell me how to do that through SQL YOG.
The AUTO_INCREMENT column has to have a UNIQUE KEY constraint associated to it.
For instance, this will work just fine:
CREATE TABLE AutoNotId
(
Id INTEGER PRIMARY KEY,
Auto INTEGER AUTO_INCREMENT,
UNIQUE (Auto)
);
Edit:
The ALTER statement would look somewhat like this:
ALTER TABLE AutoNotId
MODIFY COLUMN Auto INTEGER AUTO_INCREMENT,
ADD UNIQUE (Auto);
I recommended, however the use of the long-hand syntax to specify the name of the UNIQUE constraint; But you can always refer to MySQL's Reference Manual for the exact specifications.
In MySQL tables can only have one auto increment field and they must be indexed.
There can be only one AUTO_INCREMENT column per table, it must be indexed, and it cannot have a DEFAULT value.
Is there a reason you don't want it to be the primary key?
If you want an incrementing value, you could fudge it by running updates after each insert:
SELECT MAX(serial) + 1 FROM myTable;
UPDATE myTable SET serial = <that number> WHERE id = ...
I don't think you can have an auto increment field:
CREATE TABLE `t` (`dd` int(11) NOT NULL)
ALTER TABLE `t` CHANGE `dd` `dd` INT( 11 ) NOT NULL AUTO_INCREMENT
MySQL said: Documentation
#1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key
You cannot do this in MySQL. From the doc:
There can be only one AUTO_INCREMENT
column per table, it must be indexed,
and it cannot have a DEFAULT value. An
AUTO_INCREMENT column works properly
only if it contains only positive
values. Inserting a negative number is
regarded as inserting a very large
positive number. This is done to avoid
precision problems when numbers “wrap”
over from positive to negative and
also to ensure that you do not
accidentally get an AUTO_INCREMENT
column that contains 0.
For MyISAM and BDB tables, you can
specify an AUTO_INCREMENT secondary
column in a multiple-column key. See
Section 3.6.9, “Using AUTO_INCREMENT”.
create table mytable (
ID INT IDENTITY(1,1) PRIMARY KEY,
SN INT IDENTITY(1,1)
)