MySQL判别InnoDB表是独立表空间还是共享表空间的方法详解

前言

InnoDB采用按表空间(tablespace)的方式进行存储数据, 默认配置情况下会有一个初始大小为10MB, 名字为ibdata1的文件, 该文件就是默认的表空间文件(tablespce file),用户可以通过参数innodb_data_file_path对其进行设置,可以有多个数据文件,如果没有设置innodb_file_per_table的话, 那些Innodb存储类型的表的数据都放在这个共享表空间中,而系统变量innodb_file_per_table=1的话,那么InnoDB存储引擎类型的表就会产生一个独立表空间,独立表空间的命名规则为:表名.idb. 这些单独的表空间文件仅存储该表的数据、索引和插入缓冲BITMAP等信息,其它信息还是存放在共享表空间中,那么如何判别数据库中哪些表是独立表空间,哪些表是共享表空间呢?

InnoDB逻辑存储结构

方法1:通过ibd文件判别

如果表的存储引擎是InnoDB,而且表空间(tablespace)是共享表空间的话,那么数据库对应目录下面是没有"表名.ibd"文件的。独立表空间的表的话,则有"表名.ibd"文件。只是这个方法很笨,对于生产环境,大量的表通过这种方式判别,确实不是一个好方法。

mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name  | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
1 row in set (0.01 sec)

mysql> use MyDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> create table Independent_tablespace(name varchar(64));
Query OK, 0 rows affected (0.03 sec)

mysql> exit

[root@DB-Server ~]# cd /data/mysql/MyDB/
[root@DB-Server MyDB]# ls -lrt Independent_tablespace*
-rw-rw---- 1 mysql mysql 8560 Aug 21 22:05 Independent_tablespace.frm
-rw-rw---- 1 mysql mysql 98304 Aug 21 22:05 Independent_tablespace.ibd
[root@DB-Server MyDB]# 

在配置文件my.cnf里面设置innodb_file_per_table=0,重启MySQL服务,创建表common_tablespace,你会在数据目录看到只有common_tablespace.frm文件。

mysql> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name  | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF |
+-----------------------+-------+
1 row in set (0.00 sec)

mysql> use MyDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> create table common_tablespace(name varchar(64));
Query OK, 0 rows affected (0.02 sec)

mysql> exit
Bye
[root@DB-Server MyDB]# ls -lrt common_tablespace*
-rw-rw---- 1 mysql mysql 8560 Aug 21 22:08 common_tablespace.frm
[root@DB-Server MyDB]# 

方法2:使用INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES来判别。

MySQL 5.6

MySQL 5.6 INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES 关于这个系统表提供了有关表格的格式和存储特性,包括行格式,压缩页面大小位级别的信息(如适用),INNODB的表空间信息。

The INNODB_SYS_TABLESPACES table provides metadata about InnoDB tablespaces, equivalent to the information in the SYS_TABLESPACES table in the InnoDB data dictionary.

花了点时间了解了一下INFORMATION_SCHEMA数据库下面的INNODB_SYS_TABLESPACES这个表,遂写了一个SQL来判断那些InnoDB引擎表是独立表空还是共享表空间

共享表空间:

SELECT TABLE_SCHEMA
 ,TABLE_NAME
 ,TABLE_TYPE
 ,N'共享表空间' AS TABLE_SPACE
 ,ENGINE
 ,VERSION
 ,TABLE_ROWS
 ,AVG_ROW_LENGTH
 ,CREATE_TIME
 ,UPDATE_TIME
FROM INFORMATION_SCHEMA.TABLES T
LEFT JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES I ON CONCAT(T.TABLE_SCHEMA, '/',T.TABLE_NAME)=I.NAME
WHERE I.NAME IS NULL AND T.TABLE_SCHEMA='MyDB' AND T.ENGINE='InnoDB';

不过这个脚本有个小小的bug,对于包含特殊字符的表名,有可能出现错误情况,这个是因为如果表名包含特殊字符,那么文件名或INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES中的NAME做了转义处理,如下所示

独立表空间

SELECT TABLE_SCHEMA
 ,TABLE_NAME
 ,TABLE_TYPE
 ,N'独立表空间' AS TABLE_SPACE
 ,ENGINE
 ,VERSION
 ,TABLE_ROWS
 ,AVG_ROW_LENGTH
 ,CREATE_TIME
 ,UPDATE_TIME
FROM INFORMATION_SCHEMA.TABLES T
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES I ON CONCAT(T.TABLE_SCHEMA, '/',T.TABLE_NAME)=I.NAME
WHERE T.TABLE_SCHEMA='MyDB' AND T.ENGINE='InnoDB';

方法3 :INFORMATION_SCHEMA.INNODB_SYS_TABLES判别

MySQL 5.7

如果是MySQL 5.7的话, 比MySQL 5.6有多了一种方法,MySQL 5.7 的INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES中多了SPACE_TYPE字段,不过其值全部为Single,而INFORMATION_SCHEMA.INNODB_SYS_TABLES中也多了字段SPACE_TYPE, 其值有Single与System 分别表示单独表空间和共享表空间。

#单独表空间

SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
WHERE SPACE_TYPE='Single';

SELECT TABLE_SCHEMA
 ,TABLE_NAME
 ,TABLE_TYPE
 ,N'独立表空间' AS TABLE_SPACE
 ,ENGINE
 ,VERSION
 ,TABLE_ROWS
 ,AVG_ROW_LENGTH
 ,CREATE_TIME
 ,UPDATE_TIME
FROM INFORMATION_SCHEMA.TABLES T
INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES I ON CONCAT(T.TABLE_SCHEMA, '/',T.TABLE_NAME)=I.NAME
WHERE T.TABLE_SCHEMA='YourDatabase' AND T.ENGINE='InnoDB';

#共享表空间

SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
WHERE SPACE_TYPE='System';

SELECT TABLE_SCHEMA
 ,TABLE_NAME
 ,TABLE_TYPE
 ,N'共享表空间' AS TABLE_SPACE
 ,ENGINE
 ,VERSION
 ,TABLE_ROWS
 ,AVG_ROW_LENGTH
 ,CREATE_TIME
 ,UPDATE_TIME
FROM INFORMATION_SCHEMA.TABLES T
LEFT JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES I ON CONCAT(T.TABLE_SCHEMA, '/',T.TABLE_NAME)=I.NAME
WHERE I.NAME IS NULL AND T.TABLE_SCHEMA='YourDatabase' AND T.ENGINE='InnoDB'

方法4: INFORMATION_SCHEMA.INNODB_TABLES判别

MySQL 8.0

如果是MySLQ 8.0的话,还多了一种方法, 那就是通过INFORMATION_SCHEMA.INNODB_TABLES来判断,这个新增的系统表可以通过SPACE_TYPE字段来区分共享表空间与独立表空间

SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE SPACE_TYPE='Single';

参考资料:

https://dev.mysql.com/doc/refman/8.0/en/innodb-tables-table.html

https://dev.mysql.com/doc/refman/5.6/en/innodb-i_s-tables.html

https://dev.mysql.com/doc/refman/5.6/en/innodb-sys-tablespaces-table.html#innodb-sys-tablespaces-table-flag-column

https://dev.mysql.com/doc/refman/5.6/en/innodb-sys-tablespaces-table.html

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • mysql Innodb表空间卸载、迁移、装载的使用方法

    条件:2台服务器:A和B,需要A服务器上的表迁移到B服务器.Innodb表:sysUser,记录数:351781.以下测试在MySQL 5.5.34中进行.开始处理:1:在B服务器上建立sysUser表,并且执行: 复制代码 代码如下: zjy@B : db_test 09:50:30>alter table sysUser discard tablespace; 2:把A服务器表的表空间(ibd)复制到B服务器的相应数据目录.3:修改复制过来的ibd文件权限: 复制代码 代码如下: chown

  • 浅析mysql 共享表空间与独享表空间以及他们之间的转化

    innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等.对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间.什么是共享表空间和独占表空间共享表空间以及独占表空间都是针对数据的存储方式而言的.共享表空间:  某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下. 默认的文件名为:ibdata1  初始化为10M.独占表空间:  每一个表都将会生成以独立的文件方式来进行存储,每一个表都有一个.frm

  • mysql 表空间及索引的查看方法

    1.查看索引 (1)单位是GB SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024*1024), 2), ' GB') AS 'Total Index Size' FROM information_schema.TABLES WHERE table_schema LIKE 'database'; +------------------+ | Total Index Size | +------------------+ | 1.70 GB | +--

  • MySQL 5.7临时表空间如何玩才能不掉坑里详解

    导读 MySQL 5.7的目标是成为发布以来最安全的MySQL服务器,其在SSL/TLS和全面安全开发方面有一些重要的改变. MySQL 5.7起支持独立临时表空间,但个别时候也可能会踩坑的. MySQL 5.7起,开始采用独立的临时表空间(和独立的undo表空间不是一回事哟),命名ibtmp1文件,初始化12M,且默认无上限. 选项 innodb_temp_data_file_path 可配置临时表空间相关参数. innodb_temp_data_file_path = ibtmp1:12M:

  • 关于JDBC与MySQL临时表空间的深入解析

    背景 临时表空间用来管理数据库排序操作以及用于存储临时表.中间排序结果等临时对象,相信大家在开发中经常会遇到相关的需求,下面本文将给大家详细JDBC与MySQL临时表空间的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间.为了限制临时表空间的大小,设置了: innodb_temp_data_fil

  • 深度解析MySQL 5.7之临时表空间

    临时表 临时表顾名思义,就是临时的,用完销毁掉的表. 数据既可以保存在临时的文件系统上,也可以保存在固定的磁盘文件系统上. 临时表有下面几种: 1.全局临时表 这种临时表从数据库实例启动后开始生效,在数据库实例销毁后失效.在MySQL里面这种临时表对应的是内存表,即memory引擎. 2.会话级别临时表 这种临时表在用户登录系统成功后生效,在用户退出时失效.在MySQL里的临时表指的就是以create temporary table 这样的关键词创建的表. 3.事务级别临时表 这种临时表在事务开

  • MySQL 清除表空间碎片的实例详解

    MySQL 清除表空间碎片的实例详解 碎片产生的原因 (1)表的存储会出现碎片化,每当删除了一行内容,该段空间就会变为空白.被留空,而在一段时间内的大量删除操作,会使这种留空的空间变得比存储列表内容所使用的空间更大: (2)当执行插入操作时,MySQL会尝试使用空白空间,但如果某个空白空间一直没有被大小合适的数据占用,仍然无法将其彻底占用,就形成了碎片: (3)当MySQL对数据进行扫描时,它扫描的对象实际是列表的容量需求上限,也就是数据被写入的区域中处于峰值位置的部分: 例如: 一个表有1万行

  • MySQL判别InnoDB表是独立表空间还是共享表空间的方法详解

    前言 InnoDB采用按表空间(tablespace)的方式进行存储数据, 默认配置情况下会有一个初始大小为10MB, 名字为ibdata1的文件, 该文件就是默认的表空间文件(tablespce file),用户可以通过参数innodb_data_file_path对其进行设置,可以有多个数据文件,如果没有设置innodb_file_per_table的话, 那些Innodb存储类型的表的数据都放在这个共享表空间中,而系统变量innodb_file_per_table=1的话,那么InnoDB

  • mysql表名忽略大小写配置方法详解

    linux下mysql默认是要区分表名大小写的.mysql是否区分大小写设置是由参数lower_case_table_names决定的,其中: 1)lower_case_table_names = 0  区分大小写(即对大小写不敏感),默认是这种设置.这样设置后,在mysql里创建的表名带不带大写字母都没有影响,都可以正常读出和被引用. 2)lower_case_table_names = 1  不区分大小写(即对大小写敏感).这样设置后,表名在硬盘上以小写保存,MySQL将所有表名转换为小写存

  • js表单元素checked、radio被选中的几种方法(详解)

    0.环境 <input type="checkbox"  value="lol"/>lol var lol = document.getElementsByTagName("input")[0]; 1.HTML DOM a.lol.checked = true; 属性的值可以不是lol,只要转为布尔值的时候为true就可以,取值时只有true.false两种 不会增加checked标记 b.lol.click(); 不会增加check

  • Django 多表关联 存储 使用方法详解 ManyToManyField save

    当models中使用ManyToManyField进行多表关联的时候,需要使用字段的add()方法来增加关联关系的一条记录,让两个实例关联起来才能顺利保存关联关系 #models.py 问题分类question_category和类别使用了多对多关系(先不管是否合理) #coding:utf-8 from django.db import models # Create your models here. class QuestionCategory(models.Model): categor

  • Navicat Premium 15无限试用注册表修改的方法详解

    最近看上了Navicat Premium 15对PostgreSQL的支持,老版本的会有找不到oid字段报错,网上栖息的一些和谐版本是通过暴力修改二进制文件中的密钥来完成的,把可执行文件的数字签名也给破坏了,若遇到别有用心的捆绑个后门也不是不可以,运行着没有底气,于是寻找突破14天试用的办法. 网上有12版本的删注册表方法,显得有些暴力,本文在这些方法的基础上缩小了删除的范围,避免伤及无辜. 首先把HKEY_CURRENT_USER\Software\Classes\CLSID和HKEY_CUR

  • Javaweb中Request获取表单数据的四种方法详解

    目录 表单代码 request.getParamter(String name);通过name获取值 request.getParamterValues(String name);通过name获取value值(一般用于复选框获取值) 代码片段 request.getParameterNames();直接获取表单所有对象的name值,返回值是枚举集合 request.getParameterMap();直接获取表单所有对象的name值以及数据 表单代码 <!DOCTYPE html> <h

  • Pandas实现两个表的连接功能的方法详解

    目录 准备数据 先导入模块 输出内容 连接 内连接 外连接 左连接 右连接 上次介绍了pandas的多条件筛选,这些都是一些数据处理的必要技能,也不贪多,咱们每次学习一点. 这次咱们说说pandas的两个表的连接技能merge,也就是根据一个表的条件去匹配另一个表的内容. 话不多说,直接正文. 准备数据 先导入模块 import pandas as pd df1 = pd.DataFrame({     '姓名': ['张三', '李四', '王五', '刘六', '齐四'],     '号码'

  • Python制作数据分析透视表的方法详解

    目录 1.pivot_table函数index属性 2.pivot_table函数values属性 3.pivot_table函数aggfunc属性 4.pivot_table函数columns属性 透视表是一种可以对数据动态排布并且分类汇总的表格格式,在常用的python的数据分析非标准库pandas中体现为pivot_table模块. pivot_table数据透视表可以灵活的定制数据分析需求进行汇总,当然在Excel办公操作中早就存在了数据透视表的工具.如今,数据透视表被应用在python

  • InnoDB的关键特性-插入缓存,两次写,自适应hash索引详解

    InnoDB存储引擎的关键特性包括插入缓冲.两次写(double write).自适应哈希索引(adaptive hash index).这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性. 插入缓冲 插入缓冲是InnoDB存储引擎关键特性中最令人激动的.不过,这个名字可能会让人认为插入缓冲是缓冲池中的一个部分.其实不然,InnoDB缓冲池中有Insert Buffer信息固然不错,但是Insert Buffer和数据页一样,也是物理页的一个组成部分. 主键是行唯一的标识符,在应用程序

  • MySQL数据库设计之利用Python操作Schema方法详解

    弓在箭要射出之前,低声对箭说道,"你的自由是我的".Schema如箭,弓似Python,选择Python,是Schema最大的自由.而自由应是一个能使自己变得更好的机会. Schema是什么? 不管我们做什么应用,只要和用户输入打交道,就有一个原则--永远不要相信用户的输入数据.意味着我们要对用户输入进行严格的验证,web开发时一般输入数据都以JSON形式发送到后端API,API要对输入数据做验证.一般我都是加很多判断,各种if,导致代码很丑陋,能不能有一种方式比较优雅的验证用户数据呢

随机推荐