I'm recently installed a new server with a newer MySQL release (from 8.0.13 to 8.0.16) and I have a different behavior while retrieving the next auto increment value of my table.
I was initially using
SHOW TABLE STATUS WHERE `Name` = 'user';
in my previous server it was working perfectly, I was able to retrieve the next auto increment value for the next record, but with the new server the same command is not working properly, the value displayed for auto_increment is not the next one
I have found a post mentioning that it might be due to the cache of the statistics table but on both servers I have
show variables like 'information_schema_stats_expiry';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| information_schema_stats_expiry | 86400 |
+---------------------------------+-------+
There is also a solution by disabling the cache of this table by using the command
SET PERSIST information_schema_stats_expiry = 0
but I have two questions:
first: where do I set this information_schema_stats_expiry ? I'm not able to launch this command on a SQL command line, neither in the mysql config file
second: If we disable the cache of this table, is there any issue with the overall database performance ?
I'm not sure why this changed when you upgraded from 8.0.13 to 8.0.16. The documentation says that this variable was added in 8.0.3.
This can be set as a session variable, so you could set it to 0 just in the session that needs to fetch the AUTO_INCREMENT value, and it should bypass the cache. But it won't affect other sessions, so should have minimal overall impact on performance.
SET information_schema_stats_expiry = 0;
SHOW TABLE STATUS WHERE `Name` = 'user';
Related
On azure I created a new MySQL Database instance. In this db I create a table using this script:
CREATE TABLE ROLES(
ID INTEGER PRIMARY KEY AUTO_INCREMENT,
ROLE_NAME VARCHAR(30) NOT NULL
);
Then I insert values using this script:
INSERT INTO `beezzy`.`roles` (`ROLE_NAME`) VALUES ('admin');
INSERT INTO `beezzy`.`roles` (`ROLE_NAME`) VALUES ('owner');
INSERT INTO `beezzy`.`roles` (`ROLE_NAME`) VALUES ('consultant');
after execution table contains such rows:
Why DB generates IDs like '11' and '21'?
I run the same script on my local machine and everything works fine. IDs was '1', '2', '3'
Please run the following query.
SELECT ##auto_increment_increment
If the value is more than 1 then set it to 1 by the following query:
SET ##auto_increment_increment=1;
Note: This change is visible for the current connection only.
EDIT:
In order to set it globally so that other connections can also see the change you need to set it for global and session too.
SET ##GLOBAL.auto_increment_increment = 1;
SET ##SESSION.auto_increment_increment = 1;
So other connections can see this change now.
More:
This value will be reset if you restart your MySQL server. In order to make this change permanent you need to write this variable under [mysqld] secion in your my.cnf [for linux] or my.ini [for windows] file.
[mysqld]
auto-increment-increment = 1
Your autoincrement is probably 10, however this is probably by design. Azure uses ClearDB which uses an autoincrement of 10 with a reason: namely replication.
When I use auto_increment keys (or sequences) in my database, they
increment by 10 with varying offsets. Why?
ClearDB uses circular replication to provide master-master MySQL
support. As such, certain things such as auto_increment keys (or
sequences) must be configured in order for one master not to use the
same key as the other, in all cases. We do this by configuring MySQL
to skip certain keys, and by enforcing MySQL to use a specific offset
for each key used. The reason why we use a value of 10 instead of 2 is
for future development.
You should not change the autoincrement value.
cleardb faq
I created a new MySql table and saw that the auto-increment field starts with a value of 3 and increments by 2. I do a SHOW VARIABLES LIKE 'auto_inc%'; and get this-
auto_increment_increment 2
auto_increment_offset 2
I did some research and found that I need to use-
SET ##auto_increment_increment=1; and
SET ##auto_increment_offset=1;
But my question is, will setting both these values to 1 affect how rows are inserted on other tables with auto-increment fields? Will the new rows inserted on those tables start with an auto-increment id of 1 now? Or will this only affect new tables going forward?
The effect of auto_increment_increment and auto_increment_offset is not per-table, it applies to all tables you insert into.
If you use SET in your own session, the variable will be changed in your session only. The behavior in other sessions will not change. Also if you disconnect and reconnect, your session settings are reset to the global settings.
To make the change global, you need to use SET GLOBAL. But the change will be undone the next time MySQL Server restarts.
To make the change global and persistent, either edit the my.cnf file so the variable is set every time MySQL Server starts, or else in MySQL 8.0 they added a feature so you can now use SET PERSIST so you can change global variables and it will retain the setting after a restart.
You can read more about this:
https://dev.mysql.com/doc/refman/8.0/en/using-system-variables.html
https://dev.mysql.com/doc/refman/8.0/en/set-variable.html
how do you create a table with an auto_increment_increment of 10 instead of the default of 1
I am using mySQL and mySQL workbench as well.
After creating the table either with the workbench gui or by statements, I have tried this in workbench and it works only when I add a new record from the workbench but not thru my web app. If I use the web app it starts to auto increment by one again...I just want to create the table and set its increment to 10 every time so first item is 10 then second is 20 then 30 and so on.
SELECT Auto_increment FROM information_schema.tables WHERE table_name='items';
SET ##auto_increment_increment=10;
Thanks.
You would need to set the auto_increment_increment=10 globally. The SET command you show only sets it for the current session.
Setting it globally makes it affect every table, not just your items table.
There's no support in MySQL for changing the increment size to a different value for each table.
You can change a global option in MySQL with SET GLOBAL. To make the change persist when the MySQL server is restarted, you must edit the options file. Read:
https://dev.mysql.com/doc/refman/5.6/en/using-system-variables.html
https://dev.mysql.com/doc/refman/5.6/en/option-files.html
I have integer fields in a table. The POSTs are sent by a complicated JavaScript. They send empty strings like "" but as you guessed MySQL doesn't allow empty strings in integer fields. Are there any options to allow empty strings? Like if it takes an empty string it will save it as NULL.
There are 2 ways to do this.
For Current Mysql Session (Temporary Solution)
First execute query to get current SQL mode of your mysql server.
mysql> SELECT ##sql_mode;
+----------------------------------------------------------------+
| ##sql_mode |
+----------------------------------------------------------------+
|STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+----------------------------------------------------------------+
1 row in set (0.00 sec)
If result contains STRICT_TRANS_TABLES, you have to remove that value to allow insert query to pass NULL value. Make sure your mysql User have privileges to apply this changes and restart Mysql Server after applying this.
SET GLOBAL sql_mode = '';
For Life Time of Mysql (Permanent Solution)
You have to update my.cnf file. Location of that file is : \etc\my.cnf or \etc\mysql\mysql.cnf
There will be some default parameters set under [mysqld] like
[mysqld]
innodb_file_per_table=1
default-storage-engine=MyISAM
performance-schema=0
max_allowed_packet=268435456
open_files_limit=10000
Just add one line under that
sql-mode=""
Make sure to restart Mysql Server after changing this file. Normally root user will be the owner of file so you have to login with root user on server.
For more details to understand what this SQL mode do.
STRICT_TRANS_TABLES
Enable strict SQL mode for transactional storage engines, and when possible for non-transactional storage engines. For details, see Strict SQL Mode.
Refer : http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_strict_trans_tables
NO_AUTO_CREATE_USER
Prevent the GRANT statement from automatically creating new user accounts if it would otherwise do so, unless authentication information is specified. The statement must specify a nonempty password using IDENTIFIED BY or an authentication plugin using IDENTIFIED WITH.
Refer: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_auto_create_user
NO_ENGINE_SUBSTITUTION
Control automatic substitution of the default storage engine when a statement such as CREATE TABLE or ALTER TABLE specifies a storage engine that is disabled or not compiled in.
Refer : http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_engine_substitution
Removing sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" from my.ini has solved the issue.
Edit: Removing the line above works but it is a bad idea. It allows to have things like 0000-00-00 or empty string dates. Better keep the line above and don't insert empty sting into an integer field, instead convert empty string into NULL and then insert that NULL into integer field.
Assuming that the column allows for NULL values, you must explicitly tell MySQL to use a value of NULL, rather than passing an empty string (which is cast to 0):
INSERT INTO table (column_name) VALUES (NULL);
For my automated acceptance tests, I want inserts to start with id=1.
I achieved this on one PC (XP 32bit, mysql 5.1.something) with (after deleting all rows from the table), "alter table tableName auto_increment = 0".
I'm now setting up a new PC (Windows 7 64bit, mysql 5.1.42), and this command seems to have no effect.
I can see in the information_schema.tables table that the auto_increment value is not changed back to 0 --- it just keeps going up. If I try to change the value in that table directly, I'm told that access is denied to 'root'#'localhost'. Does this perhaps give a hint to my problem?
Other stackoverflow people had suggested that "truncate from tableName" is a good alternative. I'm happy to report that this works. But does anyone know why the "alter table" command won't reset the auto_increment?
Thanks!
NOt sure why it worked on one server, and doesn't work on the other, but the MySQL manual states (quoting, emphasis mine) :
To change the value of the
AUTO_INCREMENT counter to be used
for new rows, do this:
ALTER TABLE t2 AUTO_INCREMENT = value;
You cannot reset the counter to a value less than or equal to any that
have already been used. For
MyISAM, if the value is less than or
equal to the maximum value currently
in the AUTO_INCREMENT column, the
value is reset to the current maximum
plus one. For InnoDB, if the value
is less than the current maximum value
in the column, no error occurs and the
current sequence value is not changed.
Maybe that's the cause of the problem : you are trying to put the auto_increment counter back to 0, but it's already higher than that value -- and as you cannot reset it to a value that's less than any value that's already been used, it doesn't work.