MySQL如何创建外部表
MySQL如何创建外部表
本文实验版本MySQL 8。
MySQL中所谓的外部表,就是将innodb表创建在变量datadir代表的数据目录之外。(跟Oracle外部表完全不是一个东西)
出于扩容,空间管理,IO优化等原因。
这里可以使用如下3种方式创建外部表:
DATA DIRECTORY方式
如果使用DATA DIRECTORY子句创建,前提是开启File-Per-Table表空间属性,即启动innodb_file_per_table变量(默认启用)。
以下是关闭File-Per_table表空间下,使用DATA DIRECTORY报错示例:
(root@localhost 10:50:10) [(none)](8)> set GLOBAL innodb_file_per_table=0; (root@localhost 10:50:30) [(none)](8)> CREATE TABLE zkm.t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/mysqldata1/'; ERROR 1031 (HY000): Table storage engine for 't1' doesn't have this option Warning (Code 1478): InnoDB: DATA DIRECTORY requires innodb_file_per_table. Error (Code 1031): Table storage engine for 't1' doesn't have this option
从 MySQL 8.0.21 开始,使用DATA DIRECTORY
子句在数据目录外创建的表和表分区仅限于InnoDB
。
由于实例崩溃恢复需要确定表空间文件位置目录,因此DATA DIRECTORY指定的数据目录外的位置则必须在提前定义好,无法随意指定,不然mysql它本身不知道都有哪些目录。
[root@dev-app80 ~]# mkdir /mysqldata_tmp [root@dev-app80 ~]# chown mysql:mysql /mysqldata_tmp (root@localhost 11:10:57) [(none)](8)> set GLOBAL innodb_file_per_table = 1; Query OK, 0 rows affected (0.00 sec) (root@localhost 11:20:53) [(none)](8)> CREATE TABLE zkm.t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/mysqldata_tmp/'; ERROR 3121 (HY000): The DATA DIRECTORY location must be in a known directory. Error (Code 3121): The DATA DIRECTORY location must be in a known directory. Error (Code 1031): Table storage engine for 't1' doesn't have this option
那么如何提前定义好DATA DIRECTORY指定的数据目录外的位置,比如上边的/mysqldata_tmp,这里通过innodb_directories来指定,不过该变量是只读的需要设置重启生效。
[root@dev-app80 ~]# vi /etc/my.cnf [mysqld]添加 innodb_directories="/mysqldata_tmp" 重启mysql服务。 (root@localhost 14:00:07) [(none)](9)> CREATE TABLE zkm.t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/mysqldata_tmp/'; Query OK, 0 rows affected (0.05 sec)
[root@dev-app80 ~]# ll /mysqldata_tmp/zkm/ total 112 -rw-r----- 1 mysql mysql 114688 Jun 30 14:03 t1.ibd
CREATE TABLE ... TABLESPACE方式
create table ... tablespace需要和data directory结合,可以不需要开启File-Per-Table表空间属性,即不需要启动innodb_file_per_table变量(虽然是默认启动),为此需要指定 "innodb_file_per_table" 为表空间名称。
(root@localhost 14:34:57) [(none)](9)> set GLOBAL innodb_file_per_table=0; Query OK, 0 rows affected (0.00 sec) (root@localhost 14:34:59) [(none)](9)> CREATE TABLE zkm.t2 (c1 INT PRIMARY KEY) TABLESPACE = NoExistsTbs DATA DIRECTORY = '/mysqldata_tmp/'; ERROR 3510 (HY000): Tablespace NoExistsTbs doesn't exist. (root@localhost 14:35:33) [(none)](9)> CREATE TABLE zkm.t2 (c1 INT PRIMARY KEY) TABLESPACE = innodb_file_per_table DATA DIRECTORY = '/mysqldata_tmp/'; Query OK, 0 rows affected (0.02 sec) [root@dev-app80 zkm]# ll /mysqldata_tmp/zkm/ total 224 -rw-r----- 1 mysql mysql 114688 Jun 30 14:30 t1.ibd -rw-r----- 1 mysql mysql 114688 Jun 30 14:33 t2.ibd
使用通用表空间创建外部表
同理通用表空间使用的非datadir新目录,需要出现在innodb_directories来指定,该变量是只读的需要设置重启生效。
我们设置一个新的目录/test_share_tbs,显示CREATE TABLESPACE并进行测试,默认的ENGINE = InnoDB,也可显示指定必须是ENGINE = InnoDB为子句(create tablespace test_share_tbs add datafile '/test_share_tbs/comm_tbs01.ibd' engine=innodb;)。
[root@dev-app80 zkm]# mkdir /test_share_tbs [root@dev-app80 zkm]# chown mysql:mysql /test_share_tbs/ [root@dev-app80 zkm]# vi /etc/my.cnf innodb_directories="/mysqldata_tmp;/test_share_tbs" 重启mysql服务。 (root@localhost 14:53:16) [(none)](8)> select @@innodb_directories,@@default_storage_engine; +--------------------------------+--------------------------+ | @@innodb_directories | @@default_storage_engine | +--------------------------------+--------------------------+ | /mysqldata_tmp;/test_share_tbs | InnoDB | +--------------------------------+--------------------------+ 1 row in set (0.00 sec) (root@localhost 15:01:18) [(none)](8)> create tablespace test_share_tbs add datafile '/test_share_tbs/comm_tbs01.ibd'; Query OK, 0 rows affected (0.18 sec) [root@dev-app80 zkm]# ll /test_share_tbs/ total 112 -rw-r----- 1 mysql mysql 114688 Jun 30 15:01 comm_tbs01.ibd
接下来将外部表创建的时候指定新的表空间test_share_tbs。防偷防爬。
(root@localhost 15:04:21) [(none)](8)> CREATE TABLE zkm.t3 (c1 INT PRIMARY KEY) TABLESPACE = test_share_tbs; Query OK, 0 rows affected (0.04 sec)
至此。