MySQL 5.7 General Tablespace学习(r11笔记第34天)
MySQL里面的文件蛮有意思,之前大体有两个参数来做基本的控制。一个是innodb_data_file_path就是一个共享表空间,数据都往这一个文件里放,也就是ibdata1,这个文件其实角色是有重复的,undo,数据都会放在一起。ibdata1会持续增长,无法收缩。另外一个参数是innodb_file_per_table,这样一来,就成了独立表空间,通俗一些就是每一个表都有独立的文件.frm和.ibd,而且实际中使用独立表空间还是比较普遍的,对于delete的操作影响MySQL和Oracle就大大不同。
后来到了MySQL 5.7.5,新增了在线阶段undo log的功能,让undo从原本的ibdata1剥离出来,而对于通用的独立表空间的应用场景,MySQL也提供了另外一种管理方式,就是General tablespace。其实这个特性在Oracle中已经非常普遍,换个角度来理解就很容易了,它没有库的概念,可以在多个库里建属于同一表空间的表。
为了支持这个特性,主要做了两部分改动:Innodb层的支持及Server层对MDL子模块的改动。这部分我们后面又时间再说。
创建一个表空间的语句很简单,语法如下:
CREATE TABLESPACE tablespace_name
ADD DATAFILE 'file_name'
[FILE_BLOCK_SIZE = value]
[ENGINE [=] engine_name]
大体的格式就是create tablespace xxx add datafile 'xxxx' engine=innodb; 这样的方式,存储单位默认是16k。
create tablespace general_ts1 add datafile 'general_ts1_01.dbf' engine=innodb;
ERROR 3121 (HY000): Incorrect File Name 'general_ts1_01.dbf'.
这里需要说明的一点是,文件路径可以是绝对的,也可以是相对的。但是文件名就得是.ibd的格式。
create tablespace general_ts1 add datafile 'general_ts1_01.ibd' engine=innodb;
Query OK, 0 rows affected (0.06 sec)
当然我们可以使用create table xxx 指定tablespace的方式,或者是alter table 指定tablespace的方式。
下面这种方式在GTID下是不支持的,值得说明一下。
create table test_ts tablespace general_ts1 as select * from test ;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
我们换一个姿势,创建一个表指定表空间。
create table test_ts (id int,name varchar(30)) tablespace general_ts1;
Query OK, 0 rows affected (0.04 sec)
查看表的建表语句就可以看得很清楚了。
> show create table test_ts;
| test_ts | CREATE TABLE `test_ts` (
`id` int(11) DEFAULT NULL,
`name` varchar(30) DEFAULT NULL
) /*!50100 TABLESPACE `general_ts1` */ ENGINE=InnoDB DEFAULT CHARSET=utf8 |
我们来对比测试一下,重新指定一个表users,大概有80多万的数据量。
> select count(*)from users;
+----------+
| count(*) |
+----------+
| 817975 |
+----------+
可以看到在修改前的表usres是存在两个独立的文件。
-rw-r----- 1 mysql mysql 8606 Dec 4 22:48 users.frm
-rw-r----- 1 mysql mysql 41943040 Dec 4 22:48 users.ibd
使用alter语句来修改,整个过程很快
> alter table users tablespace general_ts1;
Query OK, 0 rows affected (1.87 sec)
Records: 0 Duplicates: 0 Warnings: 0
这个时候目录下只存在一个定义文件了,数据都放到新建的表空间了。
-rw-r----- 1 mysql mysql 8606 Jan 4 22:46 users.frm
我们简单解析一下这个定义文件,看看内容和原来有什么差别,可以看到有了新的表空间的标识。
# strings users.frm
PRIMARY
InnoDB
general_ts1
)
user_id
user_name
user_id
user_name
原本空白的数据文件马上就有了数据。
-rw-r----- 1 mysql mysql 41943040 Jan 4 22:46 general_ts1_01.ibd
如果我们修改表空间为独立表空间的方式,也是可以的。
> ALTER TABLE users TABLESPACE=innodb_file_per_table;
Query OK, 0 rows affected (2.17 sec)
Records: 0 Duplicates: 0 Warnings: 0
有一个差别就是建表DDL和原来的格式就不大一样了。
> show create table users;
| users | CREATE TABLE `users` (
`user_id` int(11) unsigned NOT NULL,
`user_name` varchar(64) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) /*!50100 TABLESPACE `innodb_file_per_table` */ ENGINE=InnoDB DEFAULT CHARSET=utf8 |
修改完成后.ibd文件会重新生成。
如果要查看表空间的信息,在使用general tablespace的情况下查看数据字典就会有一些差别。比如数据库test下存在一个表users,在视图INNODB_SYS_TABLESPACES中是只能看到表空间的基础定义信息,general_ts1而找不到users的字样。
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- Android selector的实例详解
- Android底部弹窗的实现示例代码
- Android编程实现自定义渐变颜色效果详解
- ES11屡试不爽的新特性,你用上了几个?
- Android设计模式之策略模式详解
- Android实现类似iOS风格的对话框实例代码
- Android 给图片加上水印的示例代码(支持logo+文字)
- Android studio 下JNI编程实例并生成so库的实现代码
- Android实现简单时钟View的方法
- Android编程之创建自己的内容提供器实现方法
- Android自定义View圆形和拖动圆、跟随手指拖动效果
- Android开发之OkHttpUtils的具体使用方法
- Xshell5连接虚拟机中的Linux的方法以及失败原因解决
- Android 多线程的实现方法总结
- Android编程之SQLite数据库操作方法详解