Altering multiple MySQL database tables at the same time - mysql

I normally use phpMyAdmin for any database changes therefore rarely delve into making changes to schema via MySQL queries. I now however have multiple databases all exactly the same and it would be a huge time saver if I could alter all databases at the same time. I can use the following code for a single database
ALTER demo_database.demo_table ADD another_demo_column VARCHAR(255) AFTER demo_column_index
but I'm curious if I can use similar code like the following which obviously doesn't work or I wouldn't be asking the question.
ALTER demo_database.demo_table, demo_database_2.demo_table ADD another_demo_column VARCHAR(255) AFTER demo_column_index
I know I could obviously duplicate the same line of code over and over for each table but it would be good if there is a more elegant solution.
Any help is appreciated.

According to the MySQL documentation for ALTER you cannot combine the same alter statements across multiple tables.
You can however combine multiple alter statements to the same table.
If you had a lot to do then a stored procedure with prepared statements would be more elegant than copying and pasting.

Related

Adding the same (separate) index to all tables in a schema

I have a schema that is used to archive a data set on a daily basis. Some of the analysis needs to look back, so to optimise things I need to create a couple of indexes on each table. These would be seperate (I'm not trying to cross index or anything) just a simple non-unique index, but on each table in the schema.
The archive has already been building for over a year, so we have some 400 - 500 tables, making a manual ALTER query on each tablea bit too time consuming.
I could write a php script to do it, but wondered if there was a more elegant solution with a single query or transaction?
TIA
I have copied #Shadow's answer in the comments above here to show it as the answer:
Well, the alter table and add index sections will be string constants as you have to generate the alter table statements and then execute the alter table statements you generated in the first step. See an example here: stackoverflow.com/a/44527818/5389997

Can't drop table after creating table with wrong engine

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.

MySQL/Percona 5.6: INSERT INTO a table after a table is ALTERed

I have recently installed a new computer with Percona Server 5.6 instead of MySQL 5.6, and using InnoDB/XtraDB mostly, FWIW. The database I'm working on is merely a testing ground, but I have 1 issue: after I add a column to a table (or even remove one), I usually forget to INSERT or otherwise change another table's data, which keeps track of what column names are in which table; each table has ASCII name along with a number, and this number is the only difference between table names for simplicity. So, is there a way to auto-update the "relation" table so that the column name and table's number are added or changed, instead of using a cronjob ?
Now that I think, I could DROP that table and use information_schema instead ...
EDIT 0: Don't let the above realization stop you; it's just good to know if this is possible before going for a possible other way.
Yes, relying on the 'INFORMATION_SCHEMA.COLUMNS' may be best.
Unfortunately mysql does not support DDL TRIGGER events, as this would be what you are looking for.
triggers allow you to perform many SQL and procedural operations before insertion, update or deletion of rows in a specific table. However to the best of my knowledge - and I would be stoked if I were wrong - you cant set TRIGGER events on DDL statements like ALTER and DROP TABLE...
However still take the time to learn about triggers - they save a lot of time by eliminating the need for cronjobs and external updates for things like aggregate values.
https://dev.mysql.com/doc/refman/5.6/en/trigger-syntax.html

Transactional ALTER statements in MySQL

I'm doing an update to MySQL Database which includes MySQL scripts that make ALTER TABLE sentences, as well as DIU sentences (delete, insert, update).
The idea is to make a transactional update, so if a sentence fails, a rollback is made, but if I put ALTER TABLE sentences or others specified in http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html an implicit commit is made, so I can't make a complete rollback, because the indicated operations remains commited.
I tried to use mysqldump to make a backup which is used in case of error (mysql returns distinct to zero), but it is too slow and can fail too.
What can I do? I need this to ensure that future updates are safe and not too slow, because databases contains between 30-100 GB of data.
dump and reload might be your best options instead of alter table.
From mysql prompt or from the database script:
select * from mydb.myt INTO OUTFILE '/var/lib/mysql/mydb.myt.out';
drop table mydb.myt;
create tablemyt(your table ddl here)
load data infile '/var/lib/mysql/mydb.myt.out' INTO TABLE mydb.myt;
Check this out:
http://everythingmysql.ning.com/profiles/blogs/whats-faster-than-alter
I think it offers good guidance on "alternatives to alter".
Look at pt-online-schema change.
You can configure it to leave the 'old' table around after the online ALTER is completed. The old table will have an underscore prefix. If bad things happen, drop the tables you altered and renamed the OLD tables to the original tables. If everything is OK, then just drop the OLD tables.
http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html

Altering the data type of a column in a HUGE table. Performance issues

I want to run this on my table:
ALTER TABLE table_name MODIFY col_name VARCHAR(255)
But my table is huge, it has more than 65M (65 million) rows. Now when I execute, it takes nearly 50mins to execute this command. Any better way to alter table?
Well, you need
ALTER TABLE table_name CHANGE col_name new_name VARCHAR(255)
But, you are right, it takes a while to make the change. There really isn't any faster way to change the table in MySQL.
Is your concern downtime during the change? If so, here's a possible approach: Copy the table to a new one, then change the column name on the copy, then rename the copy.
You probably have figured out that routinely changing column names in tables in a production system is not a good idea.
another variant to use percona toolkit
https://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html
You can deal with schema change without downtime using Oak.
oak-online-alter-table copies schema of original table, applies your changes and then copies the data. The CRUD operations can still be invoked as oak puts some triggers on original table so no data is going to be lost during the operation.
Please refer to other question where author of oak gives detailed explanation about this mechanism and also suggests other tools.