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.
Related
I'm trying to drop a table containing several hundred thousand column-based records. Normally when creating the database I use a column-based engine (infinidb) but in this case I forgot to include the ENGINE statement. So the database is pretty much unusable for my needs. Now I have a database full of tables that are taking forever to drop (it's been two hours and nothing has happened). I tried the ALTER TABLE table ENGINE=INFINIDB command but again, it's taking forever (see above re: two hours). EDIT: The first command I tried was DROP TABLE. It hung with every single table. Then I tried the ALTER command in case that was faster for some reason, but it wasn't.
Is there another way to get rid of this database? E.g. manually going into the /mysql/ directory and deleting the database? I guess I could just rename it and leave it, but I'd rather get rid of it entirely so it's not taking up space.
First of all you said Can't drop table. But in post you mentioned ALTER TABLE table ENGINE=INFINIDB.
But DROP != ALTER it is two different things.
So you can do following:
CREATE new table with same structure but engine you need.
copy(UPDATE) data from old table to the one you just created.
DROP old table.
RENAMErename new one to old name
It turned out that another process (a website) was using this database and had a couple of queries that got 'stuck' in the SQL server and caused the table to hang due to the database using the wrong engine, which I'm assuming was InnoDB since I didn't specify an engine when I initially used the "CREATE TABLE table1 AS SELECT * FROM table2" command. We finally managed to wipe the database and start over. Thanks for your help.
I have a mysql table y in database xxx which I attempted to change compression type before using
alter table y row_format=compressed key_block_size=8
the process stopped half way. I removed temp file '#sql-ib265.frm and #sql-ib265' in mysql lib directory and restarted the server. However
Now when I attempt the alter table y (with the same command above) again I get error.
ERROR 1050 (42S01) at line 1: Table 'xxx/#sql-ib265' already exists
I can't drop table 'xxx/#sql-ib265' because it can't be found.
what should I do?
Edit
Solution:
I ended up dropping the old database and recreate the database.
Try to restart mysql client with the --skip-auto-rehash option and try DROP TABLE again.
If above does not work, try this from MySQL Manual:
You have a corrupt innodb data dictionary..
https://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting-datadict.html
Problem with Temporary Table
If MySQL crashes in the middle of an ALTER TABLE operation, you may end up with an orphaned temporary table inside the InnoDB tablespace. Using the Table Monitor, you can see listed a table with a name that begins with #sql-. You can perform SQL statements on tables whose name contains the character “#” if you enclose the name within backticks. Thus, you can drop such an orphaned table like any other orphaned table using the method described earlier. To copy or rename a file in the Unix shell, you need to put the file name in double quotation marks if the file name contains “#”.
There are two ways to fix this problem.
As other answer suggests, official MySQL documentation suggests to drop a specially crafted table. But please note in versions >= 5.1 you need to prefix table name with #mysql50#.
Move (use RENAME TO) all good tables to a temporary database, drop&recreate the original one and then move the tables back. See a blog post for details.
in additional I'm loging in with root to do the recover job but failed. then i chown the .frm file to meet the owner of mysql service and succeed.
For anyone still facing this problem, I have just followed the following steps to solve it, which (to me at least) seem far less daunting than other solutions:
Use mysqldump to back up the database with all its data.
Drop and recreate the database.
Reload the database and all its schema from the file generated in (1).
Because the orphaned tables are hidden anyway, they don't get backed up, so you end up with a database without them. I had all my procedures/functions scripted out anyway, so was able to restore them easily - if you don't, make sure you use the --routines parameter to dump those too.
My dump file was around 1.5GB for the database in question (so it's not small), and the whole thing was completed in a few minutes.
I had the same error. I fixed it by switching the order in which I dropped the tables at the beginning of the file:
DROP TABLE IF EXISTS table_name;
This line is repeated for each table. Tables with foreign keys need to be deleted before the tables with the primary keys to which they point.
While Altering a table in mysql to Add a new Column I am getting Fatal Error Occurred.. I ve seen the relevant answers for this question where I found an Answer like :--
Make a new table with the same structure.
Add the column to the new table.
Insert the data from the old table into the new table.
Rename the old table to old.bak
Rename the new table to the old table.
If all went well, delete the old.bak.
But my original table contains some triggers , indexes, etc.
My question is
"Can I write my Alter Script in any diff. way to overcome this fatal Error" ?
My concern is related to MYSQL, but any other RDBMS related answers also fine...
This is MySQL specific: You can use a combination of [SHOW CREATE TABLE tabname][1] and [SHOW TRIGGERS WHERE Table = 'tabname'][2] to regenerate the table and triggers. You probably don't want the triggers firing when you are copying the rows. Also, if the table is of a significant size or you have a high enough rate of change, you probably want to prevent writes to it during the copy.
Sequence of steps:
Prevent writes to table (optional)
Create new table with SHOW CREATE TABLE output.
Apply schema changes.
Copy data from old table to new table.
Apply triggers from SHOW TRIGGERS output.
Swap old and new tables.
Hope this helps.
I have this table in MYSQL databse which has about 10 million records/rows. I want to insert a new column in the table. However a simple insert column query doesn't seem to work well for me.
This is what I have tried,
ALTER TABLE contacts ADD processed INT(11);
I waited for about 5 hours, but nothing happened. Is there any way to insert a new column in such a huge table?
Hope I am clear with my question. Any help would be appreciated.
If it's production:
You should use pt-online-schema-change of Percona Toolkit.
pt-online-schema-change emulates the way that MySQL alters tables internally, but it works on a copy of the table you wish to alter. This means that the original table is not locked, and clients may continue to read and change data in it.
pt-online-schema-change works by creating an empty copy of the table to alter, modifying it as desired, and then copying rows from the original table into the new table. When the copy is complete, it moves away the original table and replaces it with the new one. By default, it also drops the original table.
Or oak-online-alter-table which is part of openark kit
oak-online-alter-table allows for non blocking ALTER TABLE operations, table rebuilds and creating a table's ghost.
Altering tables will be slower, but it doesn't lock tables.
If it's not production and downtime is okay, try this approach:
CREATE TABLE contacts_tmp LIKE contacts;
ALTER TABLE contacts_tmp ADD COLUMN ADD processed INT UNSIGNED NOT NULL;
INSERT INTO contacts_tmp (contact_table_fields) SELECT * FROM contacts;
RENAME TABLE contacts_tmp TO contacts, contacts TO contacts_old;
DROP TABLE contacts_old;
im trying to delete a foreign key with the following syntax (5.0.45-community-nt):
alter table [table] drop foreign key [fk_name]
but I'm getting the following error:
The table '#sql-5f8_9c' is full – 99543 ms
any ideas?
thanks!
ALTER TABLE often requires creating a copy of the entire table, so you need enough space on your filesystem to store two copies of the data concurrently as it does this table restructure.
It may seem odd that it needs to make a copy of the table since you're just dropping a constraint. In more recent versions of MySQL, some ALTER TABLE operations have been optimized so they don't require a table restructure. But you're using a version of MySQL from July 2007!
See also:
The table is full
InnoDB 'The Table is Full' error