Table Doesn't Exist MySQLIn Managed Services, we have many customers, and as each has a different kind of config and environment, working on their environment is always fun and interesting. In this blog post, I will showcase an issue we faced when dropping a table and how it was resolved.

There was a ticket to drop a table in a client’s production environment (MySQL 5.7). The table had a # symbol at the beginning of the table’s name. I thought it was easy that we can use quotes or backtick symbols to specify the table to drop. But it did not work as I expected and I came to know why the customer created the ticket to drop the table.

The following example recreates the problem. It shows the table, but you are unable to see the structure and cannot drop it.

When checking the .ibd and .frm files, those are present and nothing wrong with those physical files.

I thought the problem was due to the # symbol and wanted to try creating a new table with the # symbol and drop it. The result was a surprise that we were able to create the table and drop it. But again, it failed to drop the table which was given by the client.

Here we noticed one thing — we created the table in uppercase and when showing the table it showed in lowercase. This gives us a clue to check lower_case_table_names and it was set to 1 (by default 0 in Unix). So we wanted to try to create a table in one value and drop it when it is set to another.

Lower_case_table_names values and their behavior:

0Table and database names are stored on disk using the lettercase specified in the CREATE TABLE or CREATE DATABASE statement. Name comparisons are case-sensitive. You should not set this variable to 0 if you are running MySQL on a system that has case-insensitive file names (such as Windows or macOS). If you force this variable to 0 with –lower-case-table-names=0 on a case-insensitive file system and access MyISAM tablenames using different lettercases, index corruption may result.
1Table names are stored in lowercase on disk and name comparisons are not case-sensitive. MySQL converts all table names to lowercase on storage and lookup. This behavior also applies to database names and table aliases.
2Table and database names are stored on disk using the lettercase specified in the CREATE TABLE or CREATE DATABASE statement, but MySQL converts them to lowercase on lookup. Name comparisons are not case-sensitive. This works only on file systems that are not case-sensitive! InnoDB table names and view names are stored in lowercase, as for lower_case_table_names=1.

Scenario One: Create table when lower_case_table_names=0 and drop when lower_case_table_names=1

Set lower_case_table_names=0 and created tables and one database with uppercase.

To change the value of lower_case_table_names to 1, I just changed the value in config and restarted the MySQL service. When lower_case_table_names is 1,  you can see the first drop table of #Table1_test2 is successful and it shows, but the drop is failed for #table1_test2  and not showing in the table list. This is due to case-insensitive, as wherever we use uppercase it will lookup in lowercase only. This is the reason dropping the table of  #Table1_test2 dropped the table #table1_test2.

We are unable to use Test_database since it was created in uppercase. So whatever the tables are inside the database will not be accessible. In short,  when lower_case_table_names=1 uppercase letters are on tables and databases they will be treated as lowercase letters.

 

Scenario Two: Create table when lower_case_table_names=1 and drop when lower_case_table_names=0

When we tried to create databases and tables in uppercase, it created those in lowercase only. Creation of #table1_test2 failed with error already exists, since the first created statement of #Table1_test2 was converted into lowercase and created table #table1_test2. The same happened when creating the table Table1_test3 was successful,  it was created as table1_test3 and failed when creating again the table table1_test3.

To change the value of lower_case_table_names from 1 to 0, I just changed the value in config and restarted the MySQL service.  We were able to drop the tables and database when lowercase_table_name=0, since the database and table were not created with uppercase.

Scenario one was the one that we faced in our client environment. The client long ago created the table when lower_case_table_names=0 and they changed it after some time to lower_case_table_names=1.  So we got approval to set lower_case_table_names=0 and dropped the table and reverted it back to 1. Since this change was not dynamic, we needed a server restart.

Conclusion

I am not suggesting using 1 or 0 in lower_case_table_names, since this is based on the application requirement. But before changing the value from 0 to 1, please check if there are any tables or databases with uppercase. If any, those need to be converted into lowercase, as otherwise those uppercase tables and databases will not be accessible.  When changing the value from 1 to 0, we did not face a problem, since the tables and databases are not allowed to be created in uppercase and those are created in lowercase only due to case-insensitivity. In MySQL 8.0 you won’t be able to change lower_case_table_names value after database instance creation, as the value of this variable affects definitions of data-dictionary tables and can’t be changed after the server is initialized.

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Mark Gruenberg

Would this issue exist on mysql 8