I've spent a bit of time trying to reproduce the error on the partition scheme, but cannot get the exact error with the orphaned table
120927 16:57:04 [ERROR] Cannot find or open table reportingdb/v3_zone_date_cpm7k#P#pcurrent_2012926 from
the internal data dictionary of InnoDB though the .frm file for the
table exists.
By moving the .ibd file for the partition out of the data directory (which it seems somehow has happened), I get an expected error:
[ERROR] MySQL is trying to open a table handle but the .ibd file for
table foo/v3_zone_date_cpm7k#P#pcurrent_2012822 does not exist.
From a chat discussion I know you have an outdated backup file. Barring actually being able to force drop the partition 'pcurrent_2012926' (some data loss), the steps to restore this backup are as follows (a month worth of data loss unfortunately):
- Take a backup of your main server (just in case!)
- Restore the backup on a different server
- Take a mysqldump of the table:
mysqldump -uuser -p reportingdb v3_zone_date_cpm7k > v3_zone_date_cpm7k.sql
- copy v3_zone_date_cpm7k.sql to the main server
- On the main server, attempt to do this:
DROP TABLE reportingdb.v3_zone_date_cpm7k
- If that works, import your dumpfile:
mysql -uuser -p reportingdb < v3_zone_date_cpm7k.sql
which should restore that table (with a month-old table)
- If the
DROP TABLE
does not work, try moving the v3_zone_date_cpm7k.frm
and other files to a different location and restarting the server. Then import the dump file
The last step is in regards to the error message telling you you have an orphaned table:
This means that there is an orphaned .frm file without a corresponding table inside InnoDB. You can drop the orphaned .frm file by deleting it manually. [src]
I really hope this is not necessary and you can restore the partition by another means. This is a last resort method.
I finally reproduced your initial error. Though it will do little to restore the partition, it might be helpful to understand to keep this from happening in the future (potential issue in how backup/restore process is handled, or how the partitions are created):
[ERROR] Cannot find or open table v3_zone_date_cpm7k#P#p00 from
the internal data dictionary of InnoDB though the .frm file for the
table exists.
Here is the nature of table creation with CREATE TEMPORARY TABLE
You can use the TEMPORARY keyword when creating a table. A TEMPORARY table is visible only to the current connection, and is dropped automatically when the connection is closed. This means that two different connections can use the same temporary table name without conflicting with each other or with an existing non-TEMPORARY table of the same name. (The existing table is hidden until the temporary table is dropped.) To create temporary tables, you must have the CREATE TEMPORARY TABLES privilege.
My guess would be you must have done the following sequence of events:
- You ran
CREATE TEMPORARY TABLE
- Terminated DB Connection (which makes the temporary table drop immediately)
- You had to run
CREATE TEMPORARY TABLE
again because he table did not exist
I have seen this problem victimize many developers, especially when it comes to MySQL Replication. For example, if you run STOP SLAVE;
, the SQL Thread will close. Any tables create with CREATE TEMPORARY TABLE
will be dropped. When you run START SLAVE;
, MySQL Replication breaks instantly because the table needed for INSERTs, UPDATEs, or DELETEs no longer exist. I have had to perform mysqlbinlog dumps on relay logs to locate the original CREATE TEMPORARY TABLE
statements, run them as CREATE TABLE
in order for the table to remain accessible to other DB Connections, including the SQL Thread when START SLAVE;
is reissued.
As for your Questions
- Is there a way to tell MySQL that the creation of the temporary table and the
SELECT
query are just executed if the table does not exist?
- Maybe with an if-condition?
- Or can I check to some information schema if a temp-table exists?
You cannot check the information_schema for temp table existence. In the OS, there is no manifested .frm
in datadir
. You could find it in the folder defined in tmpdir
.
Here is an example: I will create a temporary table called test.junk
and try to locate the whereabouts of the table. (Note: I am using MySQL for Windows)
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.12-log MySQL Community Server (GPL)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test
Database changed
mysql> create temporary table junk (a int) engine=MyISAM;
Query OK, 0 rows affected (0.02 sec)
mysql> show create table junk\G
*************************** 1. row ***************************
Table: junk
Create Table: CREATE TEMPORARY TABLE `junk` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.01 sec)
mysql> select count(1) from information_schema.tables
-> where table_schema='test' and table_name='junk';
+----------+
| count(1) |
+----------+
| 0 |
+----------+
1 row in set (0.08 sec)
mysql> show variables like 'datadir';
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| datadir | C:\MySQL_5.5.12\data\ |
+---------------+-----------------------+
1 row in set (0.00 sec)
mysql> show variables like 'tmpdir';
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| tmpdir | C:\Users\redwards\AppData\Local\Temp |
+---------------+--------------------------------------+
1 row in set (0.00 sec)
mysql>
The table is not visible in INFORMATION_SCHEMA.TABLES. Let's locate the table in the OS
C:\MySQL_5.5.12\data\test>cd
C:\MySQL_5.5.12\data\test
C:\MySQL_5.5.12\data\test>dir junk.*
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\MySQL_5.5.12\data\test
File Not Found
C:\MySQL_5.5.12\data\test>dir C:\Users\redwards\AppData\Local\Temp\*.frm
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\Users\redwards\AppData\Local\Temp
10/19/2012 11:04 AM 8,554 #sql7ac_3_0.frm
1 File(s) 8,554 bytes
0 Dir(s) 190,200,049,664 bytes free
C:\MySQL_5.5.12\data\test>dir C:\Users\redwards\AppData\Local\Temp\*.MY*
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\Users\redwards\AppData\Local\Temp
10/19/2012 11:04 AM 0 #sql7ac_3_0.MYD
10/19/2012 11:04 AM 1,024 #sql7ac_3_0.MYI
2 File(s) 1,024 bytes
0 Dir(s) 190,200,049,664 bytes free
C:\MySQL_5.5.12\data\test>
There is the temp table, in the tmpdir folder. When I closed the mysql client and run dir C:\Users\redwards\AppData\Local\Temp\*.frm
, the table vanished.
RECOMMENDATION
You can do one of two things
- Create the temp table, load it with data, keep the same DB Connection around, and then access the data with the same ProcessID.
- Do
CREATE TEMPORARY TABLE IF NOT EXISTS
(This is really a band-aid to improper design but may circumvent the problem).
UPDATE 2012-12-18 13:06 EDT
Further Observation #1
If you stayed with the same DB Connection and still have this problem, here something else not previously mentioned: You gave the temp table an index. That should be a UNIQUE INDEX or PRIMARY KEY.
Further Observation #2
You could shift the operation from a CREATE TABLE ... SELECT
to CREATE TABLE ... INSERT IGNORE
Further Observation #3
If you want to use temp tables, please specify MyISAM. InnoDB has a tendency to leave pigeon holes in the data dictionary with ibdata1 in the event of a crash or upon DB Connection termination.
With these three(3) observations in mind, here is my recommended change
CREATE TEMPORARY TABLE IF NOT EXISTS cache
(id int(11) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM;
INSERT IGNORE INTO cache SELECT id FROM table WHERE xyz;
CREATE TEMPORARY TABLE IF NOT EXISTS cache
(id int(11) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM;
INSERT IGNORE INTO cache SELECT id FROM table WHERE xyz;
Give it a Try !!!
Best Answer
I find this troubling for two reasons
REASON #1
This could be a bug that never got squashed out of MySQL 5.5.17
Nov 08, 2011
: http://bugs.mysql.com/bug.php?id=63144 (Status is Needs Triage on MySQL 5.5.17)Mar 21, 2011
: http://bugs.mysql.com/bug.php?id=60563 (MySQL 5.5.10)Jun 23, 2006
: http://bugs.mysql.com/bug.php?id=20662REASON #2
You are trying to acquire a metadata lock on an InnoDB table in an RDS environment? Ouch !!!
Possible Workaround
Instead of trusting the metadata locking in RDS, ask the information_schema if the table exists already. Suppose the table is
mydb.backupfiles
. Run this query:If the answer comes back 0, run
CREATE TABLE backupfiles ...
. Otherwise, don't run it.Possible Solution
Upgrade to the Latest MySQL (5.6.12) or the Latest MySQL5.5 (5.5.31). Hopefully, this issue was solved in a more recent version
Give it a Try !!!
UPDATE 2013-07-11 15:16 EDT
Here is a rewrite of your bash code to check if the table already exists