MYSQL table existence oddity - mysql

The series of events that lead to this oddity are as follows:
mysql> DROP TABLE `mytest`;
ERROR 1051 (42S02): Unknown table 'mytest'
mysql> CREATE TABLE `mytest` (id INT NOT NULL PRIMARY KEY,_modified DATETIME, KEY(_modified));
ERROR 1050 (42S01): Table '`mydb`.`mytest`' already exists
mysql> show tables like '%mytest%';
Empty set (0.01 sec)
I initially thought this might be a file permission issue in the data directory, but I have checked and the files that should be present to represent this table do not exist.
This is mysql version 5.1, myisam tables.
I should probably also mention that this occurs during an automated nightly restore of a large database, which is pulled from backup location as a gzipped tar archive, extracted into the mysql data directory and then myisamchk is run against all MYI files in the new directory.
After 2 hours of investigation I am still lost as to what could be causing this - any assistance would be appreciated.

try this
CREATE TABLE `mytest` IF NOT EXISTS ELSE TRUNCATE `mytest`
Use TRUNCATE to empty the table and reset cardinality instead of deleting the table and recreating it.

try this :
mysql> DROP TABLE '`mydb`.`mytest`'

Seems like broken indexes or definition files.
Try to stop mysql, go to the mysql's data directory, delete the files for the particular table, and restart mysql. Be careful not to delete other files.
If it's InnoDB type, than some command to repair broken tables could help.
IIRC it's CHECK TABLE ... and REPAIR TABLE.

Related

How to move InnoDB table to another drive?

I have MySQL running on SSDs, SSDs that I'm about to run out of space on. My webhost overcharges for SSDs and the majority of the data in MySQL is "archived" data (i.e. data that isn't actively used). I have larger HDDs that can hold this data. As such, I want to be able to move specific InnoDB tables from the SSDs to the HDDs.
One solution I've thought about and researched is moving the individual .ibd files (I have innodb_file_per_table enabled) for the specific tables in question to the HDDs and then symlink. However, researching this, it looks like that is a bad idea for InnoDB.
I've also seen that since 5.6, MySQL supports the DATA DIRECTORY command:
To create a new InnoDB file-per-table tablespace in a specific
location outside the MySQL data directory, use the DATA DIRECTORY =
absolute_path_to_directory clause of the CREATE TABLE statement.
Plan the location in advance, because you cannot use the DATA
DIRECTORY clause with the ALTER TABLE statement. The directory you
specify could be on another storage device with particular performance
or capacity characteristics, such as a fast SSD or a high-capacity
HDD.
The problem is, it looks like this is only supported for new tables. I want to do it for existing tables. Any tips on how? I'm running Percona MySQL, if it helps.
Thanks!
UPDATE: Here is what I tried, but I'm getting a syntax error:
CREATE TABLE abc_2 LIKE abc ENGINE=InnoDB DATA DIRECTORY='/xxx/mysql/archive/'
Apparently CREATE ... LIKE ... DATA DIRECTORY ... is a combination that is not supported.
Do SHOW CREATE TABLE to get the current definition. Edit it to add DATA DIRECTORY and INDEX_DIRECTORY. Then use the edited text to create the new table.
Then INSERT INTO new_tbl SELECT * FROM real_tbl; and shuffle the names: RENAME TABLE real_tbl TO old_tbl, new_tbl TO real_tbl;.
Verify the results and finally DROP old_tbl;
I have dealt with this problem myself, and eventually found a more elegant solution than 'create new - copy - switch': detaching, moving and re-importing the underlying tablespace files. This is much more efficient on large and/or heavily indexed tables as MySQL does not have to redo work it has already done.
In short, it comes down to the following steps:
FLUSH TABLES `table_name` FOR EXPORT;
While keeping the connection open, move the tablespace files in a shell:
$ mv /var/lib/mysql/database_name/table_name.{ibd,cfg} ~
Now back in MySQL release the lock, drop the table, re-create it with the correct DATA DIRECTORY and discard its tablespace:
UNLOCK TABLES;
SHOW CREATE TABLE `table_name`;
DROP TABLE `table_name`;
CREATE TABLE `table_name` /* ... */ DATA DIRECTORY='/path/to/desired/location';
ALTER TABLE `table_name` DISCARD TABLESPACE;
Now copy the moved tablespace files to the desired location:
$ cp -a ~/table_name.{ibd,cfg} /path/to/desired/location
And import them:
ALTER TABLE `table_name` IMPORT TABLESPACE;
More background and motivation for why 'create new - copy - switch' is inefficient can be found in a blogpost I wrote on this topic: https://www.moxio.com/blog/28/moving-individual-mysql-tables-on-disk.

MySQL can't select from existing table because it doesn't exist?

I have no idea what is going on. I have a table called project_share_invite. A few hours ago (in our production environment) I could no longer issue SELECTs against this table. MySQL claims the table does not exist, though it shows on show tables. The only noteworthy event that has happened on the machine today is a routine package upgrade (via apt).
mysql> use analytics;
Database changed
mysql> show tables like 'project_share_invite';
+--------------------------------------------+
| Tables_in_analytics (project_share_invite) |
+--------------------------------------------+
| project_share_invite |
+--------------------------------------------+
1 row in set (0.00 sec)
mysql> select count(*) from project_share_invite;
ERROR 1146 (42S02): Table 'analytics.project_share_invite' doesn't exist
Ideas? This doesn't make any sense to me.
Update: The files for the table are still present on disk (project_share_invite.frm and project_share_invite.idb respectively) and have content in them.
A quick restart of MySQL has not fixed this.
Update: Same results when using root account instead of specific user account.
Update: I am unable to recreate the tables either.
CREATE TABLE `analytics`.`project_share_invite` ( ... )
ERROR 1146 (42S02): Table 'analytics.project_share_invite' doesn't exist
Update: Should have checked the error logs first:
InnoDB: Load table 'analytics/project_share_invite' failed, the table has missing foreign key indexes.
Though I've no idea how it's got in this state.
Looks like you hit a known bug in MySQL where a foreign key constraint exists, but the associated index was dropped. See: http://bugs.mysql.com/bug.php?id=68148
Depending on the version of MySQL (Seems like you need 5.6 or >) you can fix this problem by turning off foreign key checking and then recreating the missing index(es).
SET FOREIGN_KEY_CHECKS=0;
You should check the structure using SHOW CREATE TABLE table name
Then use CREATE INDEX to recreate the missing indexes.
This error is usually caused by moving files around at the filesystem level.
Keep in mind that SHOW TABLES just reads the .frm file, but once you query the table, MySQL invokes the storage engine. InnoDB has its own internal way of managing metadata, in a "data dictionary" which is always stored in ibdata1.
So if you moved the datadir but forgot the ibdata1 file (or copied an ibdata1 from another instance), then the InnoDB data dictionary wouldn't know about the table, even though SHOW TABLES does.
Another possibility is that you copied data files around, and now they don't have the write ownership or file permissions. So for example the .frm file is readable but the .ibd is not. They should be owned and writeable by mysql:mysql.
If your apt upgrade changed file locations or file permissions, that could cause it too. I would advise using ls -l to verify the permissions on the files.

MySql 1050: MySQLSyntaxErrorException: Table 'my_db/#sql-ib520' already exists

I've tried to execute the following ALTER TABLE statement:
ALTER TABLE `my_table` ADD COLUMN `new_column` LONGTEXT NULL DEFAULT NULL AFTER `old_column`;
During the execution of the script I've got
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
It appears that this left database in inconsistent state, since no new field was added, and when I try to execute the script again, I'm getting this strange error.
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'my_db/#sql-ib520' already exists
I do not have #sql-ib520 table in my database, so to my understanding it must be some temp table created by the MySQL.
Does anyone encountered this error before, and how could I solve it?
Thanx
Edit
I've tried the script suggested by Alex, but I had not worked:
drop table `#mysql50##sql-ib520`;
ERROR 1051 (42S02): Unknown table 'my_db.#mysql50##sql-ib520'
Update
I'm using Amazon RDS with MySQL 5.6.12
I'm using an AWS RDS instance as well, and did a ton of reading on this problem. While I didn't find a great solution, here's how I fixed it by only replacing one table instead of the entire database.
If you run this command:
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
you can see the full list of database tables, including the orphaned table, which isn't normally visible. The two problem tables for me were:
ID NAME
407 my_database/#sql-ib379
379 my_database/users
because I was attempting to ALTER my users table when the DB crashed. Now, as mentioned above, I couldn't run any further ALTER TABLE commands because it was trying to create the same temporary table for any subsequent queries. I tried everything to DROP the orphaned table, but with the 'my_database/' part, it didn't seem possible. I also didn't want to drop and recreate my entire database, and I noticed that the orphaned table is referencing an internal ID of the users table (#sql-ib379), so I figured I would just swap it out. Here's a little MySQL script that did the trick for me:
-- temporarily disable foreign key checks
SET foreign_key_checks = 0;
-- replace this line with query to create a structural copy of the users table
-- named users_copy, including foreign keys if you use them
-- copy everything from original table into new table
INSERT INTO `users_copy` SELECT * FROM `users`;
Make sure everything looks ok, and then run:
-- rename the existing table
RENAME TABLE `users` TO `users_backup`;
-- in case the copy process took some time, and there were additional rows added
-- to the original table, grab them and put them into the copy table
INSERT INTO `users_copy` SELECT * FROM `users_backup` WHERE `users_backup`.id > (SELECT MAX(id) FROM `users_copy`);
-- finally, rename the copy table to the original table name
RENAME TABLE `users_copy` TO `users`;
- re-enable foreign key checks
SET foreign_key_checks = 1;
If you are not using foreign keys, you should be good to go now. I would recommend keeping the backup table around for a bit just in case, but once you remove that backup table, it should remove the orphaned table as well. If you are using foreign keys however, it is very important that you update any references to the original table name (in this case, users)! Depending on how you have your foreign keys setup, other tables that were dependent on users will now reference users_backup, which could cause problems with lost data.
Hope this helps.
After all, since I'm using AWS RDS instance, the script recommended by Alex did not work.
MySQL documentation also recommends this script, you can find more info here about orphaned intermediate tables.
For AWS RDS I've found only one post with no solution provided by Amazon staff. You might want to follow this post in case some solution is provided.
So, at the moment, my only solution was to dump the existing database and create a new one.

MySQL Create Table Error - Table Doesn't Exist

I am new to MySQL, and I am having a problem where if I try to create a Table in my newly created Database "recommend", I get the following error:
ERROR 1146 (42S02): Table 'recommend.Users' doesn't exist
I checked related posts here and on the internet but nothing helped.
If I use the MySQL command line I still get the same error.
SELECT DATABASE() FROM DUAL;
+------------+
| DATABASE() |
+------------+
| recommend |
+------------+
1 row in set (0.00 sec)
but then when i run this command :
mysql> use recommend
Database changed
mysql> CREATE TABLE Users (UserName VARCHAR(20),password VARCHAR(20),PRIMARY KEY(UserName));
ERROR 1146 (42S02): Table 'recommend.Users' doesn't exist
I also tried using Navicat and still get the same error :(
I had the same problem. I actually read this thread before I got lucky with a simple solution. I attempted to drop my table and it worked, in your case your table is User:
DROP TABLE Users;
The table does not exist, so naturally MySQL complains:
Error Code: 1051. Unknown table 'Users'
But then I ran my CREATE TABLE statement again and it worked. Hopefully others can validate this works every time? A lot easier than going to an error log, especially if you are not the greatest DBA/System Admin/Hacker.
This looks like a data dictionary problem. You can get more information by checking the error log. (See the MySQL docs here).
Possibly, you have an orphaned table. If so, the solution is to create a table of the same name in a different database, then copy the .frm file to the current database. Then you can DROP the table, and a subsequent CREATE should then succeed. More details on troubleshooting this sort of problem can be found here
The Problem was...
You have a DB with "InnoDB ENGINE".......
My Solution was...
You must have a "MyISAM ENGINE",
how to change?... find on your environment may be with
# find / -name my.cnf
on LINUX, simply add the following line to
vim /etc/mysql/my.cnf
Add:
default-storage-engine= MyISAM
Then restart mysql:
service mysql restart

Drop screwed up table in Mysql db

I've managed to corrupt (or something) the 'sessions' table in a mysql db i have (which is called "e_learning_resource_prelive"). This wouldn't be a problem normally as i could just go back to a backup dump of the db. However, the corrupted table seems to be stopping me deleting the database:
> mysqladmin -u root drop e_learning_resource_prelive
Dropping the database is potentially a very bad thing to do.
Any data stored in the database will be destroyed.
Do you really want to drop the 'e_learning_resource_prelive' database [y/N] y
mysqladmin: DROP DATABASE e_learning_resource_prelive failed;
error: 'Unknown table 'sessions''
When i go into the db the sessions table shows up in show_tables (it's the only one there, the mysqladmin drop deleted the rest) but i can't drop it:
mysql> show tables;
+---------------------------------------+
| Tables_in_e_learning_resource_prelive |
+---------------------------------------+
| sessions |
+---------------------------------------+
1 row in set (0.00 sec)
mysql> drop table sessions;
ERROR 1051 (42S02): Unknown table 'sessions'
Can anyone tell me how i can delete this table, or the whole db? I need to delete the db and then rebuild it from my backup dump.
Figured it out, seems kind of obvious now. The dbs all just have a folder which can be deleted like anything else.
sudo rm -r /var/lib/mysql/e_learning_resource_prelive
Thanks anyone who looked, anyway :)
max
session is a reserved keyword (http://developer.mimer.com/validator/sql-reserved-words.tml), I think that is why your database is corrupt.
I had the same issue using a reserved keyword (references in my case), and I also had the problem that renaming, dropping or truncating the table was giving an sql error.
To fix this problem, use backtick-characters in the alter table query.
ALTER TABLE `session` RENAME TO newname
This way the query won't fail, and your data are still there (thank god!). I hope someone finds this useful!
Use the GUI interface. There is probably some not-very-printable character in the sessions name.
Or maybe the underlying file on the filesystem was deleted? If so, try creating an empty file named sessions there.