前言
由于历史原因,Mysql数据库中存在大量非Innodb存储引擎的表,现需要把这些表的存储引擎批量修改成Innodb存储引擎。在此记录以解不时之需!
整体思路
通过拼接SQL语句把需要执行的所有语句输出到操作系统文件中,执行这个文件即可完成批量修改。
处理过程
本文主要在测试环境中模拟批量处理过程。
创建5张非Innodb存储引擎的表
mysql> create table test1.t1(id int) engine=myisam;
Query OK, 0 rows affected (0.01 sec)
mysql> create table test1.t2(id int) engine=myisam;
Query OK, 0 rows affected (0.01 sec)
mysql> create table test2.t3(id int) engine=myisam;
Query OK, 0 rows affected (0.01 sec)
mysql> create table test2.t4(id int) engine=myisam;
Query OK, 0 rows affected (0.01 sec)
mysql> create table test2.t5(id int) engine=myisam;
Query OK, 0 rows affected (0.00 sec)
查询非Innodb存储引擎的表
mysql> select TABLE_SCHEMA,TABLE_NAME from information_schema.tables where ENGINE!='innodb'and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
+--------------+------------+
| TABLE_SCHEMA | TABLE_NAME |
+--------------+------------+
| test1 | t1 |
| test1 | t2 |
| test2 | t3 |
| test2 | t4 |
| test2 | t5 |
+--------------+------------+
5 rows in set (0.00 sec)
拼接批量修改Innodb存储引擎的sql
真实环境中有大量非Innodb存储引擎的表,所以需要拼接sql批量执行。
SELECT CONCAT('ALTER TABLE ',table_schema,'.', table_name, ' ENGINE=InnoDB;') AS sql_statements
from information_schema.tables
where ENGINE!='innodb'
and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
执行结果如下:
mysql> SELECT CONCAT('ALTER TABLE ',table_schema,'.', table_name, ' ENGINE=InnoDB;') AS sql_statements
-> from information_schema.tables
-> where ENGINE!='innodb'
-> and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
+-------------------------------------+
| sql_statements |
+-------------------------------------+
| ALTER TABLE test1.t1 ENGINE=InnoDB; |
| ALTER TABLE test1.t2 ENGINE=InnoDB; |
| ALTER TABLE test2.t3 ENGINE=InnoDB; |
| ALTER TABLE test2.t4 ENGINE=InnoDB; |
| ALTER TABLE test2.t5 ENGINE=InnoDB; |
+-------------------------------------+
5 rows in set (0.00 sec)
执行结果输出到/tmp/result.sql文件
SELECT CONCAT('ALTER TABLE ',table_schema,'.', table_name, ' ENGINE=InnoDB;') AS sql_statements
INTO OUTFILE '/tmp/result.sql'
FIELDS TERMINATED BY ','
ENCLOSED BY ''
LINES TERMINATED BY '\n'
from information_schema.tables
where ENGINE!='innodb'
and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
执行结果如下:
mysql> SELECT CONCAT('ALTER TABLE ',table_schema,'.', table_name, ' ENGINE=InnoDB;') AS sql_statements
-> INTO OUTFILE '/tmp/result.sql'
-> FIELDS TERMINATED BY ','
-> ENCLOSED BY ''
-> LINES TERMINATED BY '\n'
-> from information_schema.tables
-> where ENGINE!='innodb'
-> and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
Query OK, 5 rows affected (0.00 sec)
查看/tmp/result.sql文件内容
[root@node2 ~]# cat /tmp/result.sql
ALTER TABLE test1.t1 ENGINE=InnoDB;
ALTER TABLE test1.t2 ENGINE=InnoDB;
ALTER TABLE test2.t3 ENGINE=InnoDB;
ALTER TABLE test2.t4 ENGINE=InnoDB;
ALTER TABLE test2.t5 ENGINE=InnoDB;
执行/tmp/result.sql
mysql> source /tmp/result.sql
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
再次查询非innodb存储引擎的表
mysql> select TABLE_SCHEMA,TABLE_NAME from information_schema.tables where ENGINE!='innodb'and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
Empty set (0.00 sec)
mysql>
数据库中已经不存在非innodb存储引擎的表了。
碰到的问题
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
mysql> SELECT CONCAT('ALTER TABLE ',table_schema,'.', table_name, ' ENGINE=InnoDB;') AS sql_statements
-> INTO OUTFILE '/tmp/result.sql'
-> FIELDS TERMINATED BY ','
-> ENCLOSED BY ''
-> LINES TERMINATED BY '\n'
-> from information_schema.tables
-> where ENGINE!='innodb'
-> and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
解决办法:
mysql> show variables like ‘secure_file_priv’;
±-----------------±----------------------+
| Variable_name | Value |
±-----------------±----------------------+
| secure_file_priv | /var/lib/mysql-files/ |
±-----------------±----------------------+
1 row in set (0.00 sec)
可以把文件输出到secure_file_priv参数指定的位置(本例是/var/lib/mysql-files/ 目录),如果文件要输出到任意位置,需要设置secure_file_priv参数。设置方法:
在/etc/my.cnf中加入secure_file_priv="",重启mysql数据库即可。
关于secure_file_priv参数的说明:
secure_file_priv是MySQL中用来限制文件上传和下载操作的参数。
当secure_file_priv为空时,表示可以在任意路径上传文件;
当secure_file_priv设置为特定路径时,表示只能在特定路径进行文件上传和下载;
当secure_file_priv为NULL时,表示不允许在任何路径上传文件。
官网上关于secure_file_priv参数的说明:

注意:修改secure_file_priv参数需要重启数据库,如果不能重启数据库,可以把文件输出到secure_file_priv参数指定的位置或者用下面这种方法输出到其他位置:
mysql> pager cat >/tmp/a.sql
PAGER set to 'cat >/tmp/a.sql'
mysql> SELECT CONCAT('ALTER TABLE ',table_schema,'.', table_name, ' ENGINE=InnoDB;') AS sql_statements
-> from information_schema.tables
-> where ENGINE!='innodb'
-> and TABLE_SCHEMA not in ('information_schema','mysql','performance_schema','sys');
5 rows in set (0.00 sec)
mysql>
mysql> \q
Bye
[root@node2 ~]# cat /tmp/a.sql
+--------------------------------------+
| sql_statements |
+--------------------------------------+
| ALTER TABLE test1.t6 ENGINE=InnoDB; |
| ALTER TABLE test1.t7 ENGINE=InnoDB; |
| ALTER TABLE test2.t8 ENGINE=InnoDB; |
| ALTER TABLE test2.t9 ENGINE=InnoDB; |
| ALTER TABLE test2.t10 ENGINE=InnoDB; |
+--------------------------------------+
总结
虽然很简单的功能,但是很实用。希望大家都能有所收获,谢谢!




