热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在MySQL中选择合适的表空间以优化性能和管理效率

在MySQL中,合理选择表空间对于提升表的管理和访问性能至关重要。表空间作为MySQL中用于组织和管理数据的一种机制,能够显著影响数据库的运行效率和维护便利性。通过科学地配置和使用表空间,可以优化存储结构,提高查询速度,简化数据管理流程,从而全面提升系统的整体性能。

原标题:MySQL选择合适的表空间-爱可生

1339f229081ab875b9f7601866d00bfd.png

表空间的选择,可以说是对表的日常管理以及访问性能有非常紧密的联系。

表空间是用来管理 MySQL 关系表的一种形式,有自己的磁盘文件。

MySQL 表空间可分为共享表空间和单表空间;其中共享表空间又可分为系统表空间和通用表空间。

下面我来逐一看下每种表空间的相关特性。

一、系统表空间

在 MySQL 数据目录下有一个名为 ibdata1 的文件,可以保存一张或者多张表。

923275 12M -rw-r----- 1 mysql mysql 12M 3月 18 10:42 ibdata1

这个文件就是 MySQL 的系统表空间文件,默认为 1 个,可以有多个,只需要在配置文件 my.cnf 里面这样定义即可。

innodb_data_file_path=ibdata1:200M;ibdata2:200M:autoextend:max:800M

系统表空间不仅可以是文件系统组成的文件,也可以是非文件系统组成的磁盘块,比如裸设备,定义也很简单

innodb_data_file_path=/dev/nvme0n1p1:3Gnewraw;/dev/nvme0n1p2:2Gnewraw

系统表空间里都有些啥内容?

具体内容包括:double writer buffer、 change buffer、数据字典(MySQL 8.0 之前)、表数据、表索引。

那 MySQL 为什么现在主流版本默认都不是系统表空间?

究其原因,系统表空间有三个最大的缺点:

原因 1:无法做到自动收缩磁盘空间,造成很大的空间浪费。

即使它包含的表都被删掉,这部分空间也不会自动释放。

举个例子:

# 表 t1

mysql> create table t1(id int, r1 char(36)) tablespace innodb_system;

Query OK, 0 rows affected (0.03 sec)

# ibdata1 初始大小为 12M

mysql> \! ls -sihl ibdata1

923275 12M -rw-r----- 1 mysql mysql 12M 3月 18 15:32 ibdata1

# ... 插入一部分数据

# ...

mysql> select count(*) from t1;

+----------+

| count(*) |

+----------+

| 262144 |

+----------+

1 row in set (0.10 sec)

# ibdata1 增长到 76M

mysql> \! ls -sihl ibdata1

923275 76M -rw-r----- 1 mysql mysql 76M 3月 18 15:34 ibdata1

# 删除这张表

mysql> drop table t1;

Query OK, 0 rows affected (0.02 sec)

# 空间并没有释放

mysql> \! ls -sihl ibdata1

923275 76M -rw-r----- 1 mysql mysql 76M 3月 18 15:39 ibdata1

如何才能释放 ibdata1 呢?

这个比较麻烦,而且严重影响服务可用性,大致几个步骤:

1. 用 mysqldump 导出所有表数据;

2. 关闭 MySQL 服务;

3. 设置 ibdata1 为默认大小;

4. source 重新导入数据。

原因 2:扩容时,单表分离速度慢。

系统表空间在无限制增大导致磁盘满需要扩容时,无法快速的把表从系统表空间里分离出来,必须得经过停服务;改配置;扩容;重新导入数据;启服务等步骤方才可行。

原因 3:多张表的数据写入顺序写。

对多张表的写入数据依然是顺序写,这就致使 MySQL 发布了单表空间来解决这两个问题。

二、单表空间

单表空间不同于系统表空间,每个表空间和表是一一对应的关系,每张表都有自己的表空间。具体在磁盘上表现为后缀为 .ibd 的文件。

比如表 t1,对应的表空间文件为 t1.ibd

917107 96K -rw-r----- 1 mysql mysql 96K 3月 18 16:13 t1.ibd

单表空间如何应用到具体的表呢?

有两种方式:

方式 1:在配置文件中开启。

在配置文件中开启单表空间设置参数 innodb_filer_per_table,这样默认对当前库下所有表开启单表空间。

innodb_file_per_table=1

另外也可以直接建表时指定单表空间

mysql> create table t1 (id int, r1 char(36)) tablespace innodb_file_per_table;

Query OK, 0 rows affected (0.04 sec)

单表空间除了解决之前说的系统表空间的几个缺点外,还有其他的优点,详细如下:

1. truncate table 操作比其他的任何表空间都快;

2. 可以把不同的表按照使用场景指定在不同的磁盘目录;

比如日志表放在慢点的磁盘,把需要经常随机读的表放在 SSD 上等。

mysql> create table ytt_dedicated (id int) data directory = '/var/lib/mysql-files';

Query OK, 0 rows affected (0.04 sec)

3. 可以用 optimize table 来收缩或者重建经常增删改查的表。

一般过程是这样的:建立和原来表一样的表结构和数据文件,把真实数据复制到临时文件,再删掉原始表定义和数据文件,最后把临时文件的名字改为和原始表一样的。

举个例子,表 t1 之前的大小 324M

root@ytt-pc:/data/ytt/mysql/data/ytt# ls -sihl

总用量 325M

934068 4.0K -rw-r----- 1 mysql mysql 67 3月 6 23:01 db.opt

917593 12K -rw-r----- 1 mysql mysql 8.5K 3月 18 16:35 t1.frm

918181 325M -rw-r----- 1 mysql mysql 324M 3月 18 16:38 t1.ibd

进行表重建

mysql> optimize table t1;

+--------+----------+----------+-------------------------------------------------------------------+

| Table | Op | Msg_type | Msg_text |

+--------+----------+----------+-------------------------------------------------------------------+

| ytt.t1 | optimize | note | Table does not support optimize, doing recreate + analyze instead |

| ytt.t1 | optimize | status | OK |

+--------+----------+----------+-------------------------------------------------------------------+

2 rows in set (10.26 sec)

重建期间抓取到的结果:如愿以偿看到 # 开头的临时表定义和数据文件。

root@ytt-pc:/data/ytt/mysql/data/ytt# ls -sihl

总用量 409M

934068 4.0K -rw-r----- 1 mysql mysql 67 3月 6 23:01 db.opt

917100 12K -rw-r----- 1 mysql mysql 8.5K 3月 18 16:38 '#sql-1791_7.frm'

917107 85M -rw-r----- 1 mysql mysql 84M 3月 18 16:39 '#sql-ib51-975102565.ibd'

917593 12K -rw-r----- 1 mysql mysql 8.5K 3月 18 16:35 t1.frm

918181 325M -rw-r----- 1 mysql mysql 324M 3月 18 16:38 t1.ibd

重建完成,表 t1 实际占用空间 84M

root@ytt-pc:/data/ytt/mysql/data/ytt# ls -sihl

总用量 85M

934068 4.0K -rw-r----- 1 mysql mysql 67 3月 6 23:01 db.opt

917100 12K -rw-r----- 1 mysql mysql 8.5K 3月 18 16:38 t1.frm

917107 85M -rw-r----- 1 mysql mysql 84M 3月 18 16:39 t1.ibd

root@ytt-pc:/data/ytt/mysql/data/ytt#

4. 可以自由移植单表

并不需要移植整个数据库,可以把单独的表在各个实例之间灵活移植。

比如现在要把 ytt.t1 的数据移植到 ytt2.t1 里。

mysql> create database ytt2;

Query OK, 1 row affected (0.01 sec)

mysql> use ytt2

Database changed

mysql> create table t1 like ytt.t1;

Query OK, 0 rows affected (0.05 sec)

# 进行表数据移植。

mysql> alter table t1 discard tablespace;

Query OK, 0 rows affected (0.02 sec)

root@ytt-pc:/data/ytt/mysql/data/ytt# cp -rfp /tmp/t1.ibd ../ytt2/

mysql> alter table t1 import tablespace;

Query OK, 0 rows affected (0.38 sec)

# 确认下数据是否一致。

mysql> select (select count(*) from ytt.t1) 'ytt.t1',(select count(*) from ytt2.t1) 'ytt2.t1';

+---------+---------+

| ytt.t1 | ytt2.t1 |

+---------+---------+

| 2097152 | 2097152 |

+---------+---------+

1 row in set (1.69 sec)

5. 单表空间的表可以使用 MySQL 的新特性;

比如表压缩,大对象更优化的磁盘存储等。

6. 可以更好的管理和监控单个表的状态;

比如在 OS 层可以看到表的大小。

7. 可以解除 InnoDB 系统表空间的大小限制;

InnoDB 一个表空间最大支持 64TB 数据(针对 16KB 的页大小)。如果是系统表空间,整个实例都被这个限制,单表空间则是针对单个表有 64TB 大小限制。

当然了,单表空间也并不是没有缺点。比如:当多张表被大量的增删改后,表空间会有一定的膨胀;相比系统表空间,打开表需要的文件描述符增多,浪费更多的内存。

三、通用表空间

通用表空间先是出现在 MySQL Cluster 里,也就是 NDB 引擎。从 MySQL 5.7 引入到 InnoDB 引擎。通用表空间和系统表空间一样,也是共享表空间。每个表空间可以包含一张或者多张表,也就是说通用表空间和表之间是一对多的关系。

mysql> create tablespace ts1 add datafile '/var/lib/mysql-files/ts1.ibd' engine innodb;

Query OK, 0 rows affected (0.02 sec)

mysql> create table t1(id int,r1 datetime) tablespace ts1;

Query OK, 0 rows affected (0.02 sec)

mysql> create table t2(id int,r1 datetime) tablespace ts1;

Query OK, 0 rows affected (0.03 sec)

mysql> create table t3(id int,r1 datetime) tablespace ts1;

Query OK, 0 rows affected (0.03 sec)

通用表空间其实是介于系统表空间和单表空间之间的一种折中的方案。

和系统表空间类似,不会自动收缩磁盘空间;

和系统表空间类似,可以重命名表空间名字;

和单表空间类似,可以很方便把表空间文件定义在 MySQL 数据目录之外;

比单表空间占用更少的文件描述符,但是又不能像单表空间那样移植表空间。

幸运的是,可以在这三个表空间里随便切换。不过要注意切换时间点,毕竟切换涉及到数据的迁移,类似 copy 文件对系统的影响。

# 表 t1 随时切换各种表空间

mysql> alter table t1 tablespace innodb_file_per_table;

Query OK, 0 rows affected (14.15 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> alter table t1 tablespace innodb_system;

Query OK, 0 rows affected (16.95 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> alter table t1 tablespace ts1;

Query OK, 0 rows affected (13.98 sec)

Records: 0 Duplicates: 0 Warnings: 0

到本篇的末尾,再来看下三种表空间如何销毁:

系统表空间无法销毁,除非把里面的内容全部剥离出来;

单表空间如果表被删掉了,表空间也就自动销毁;或者是表被移植到其他表空间,单表空间也自动销毁。

通用表空间需要引用他的表全部删掉或者移植到其他表空间,才可以被成功删除。

# 删除表空间 ts2 失败

mysql> drop tablespace ts2;

ERROR 3120 (HY000): Tablespace `ts2` is not empty.

mysql> show errors;

+-------+------+--------------------------------+

| Level | Code | Message |

+-------+------+--------------------------------+

| Error | 3120 | Tablespace `ts2` is not empty. |

+-------+------+--------------------------------+

1 row in set (0.00 sec)

# 查看数据字典表来进一步查看表空间 ts2 被哪些表引用了

mysql> select regexp_replace(a.name,'/.+','') dbname,regexp_replace(a.name,'.+/','') tablename from innodb_tables a, innodb_tablespaces b where a.space = b.space and b.name= 'ts2';

+--------+-----------+

| dbname | tablename |

+--------+-----------+

| ytt | t4 |

+--------+-----------+

1 row in set (0.00 sec)

# 删除对应的表或者转到其他的表空间。

mysql> alter table t4 tablespace innodb_file_per_table;

Query OK, 0 rows affected (0.10 sec)

Records: 0 Duplicates: 0 Warnings: 0

# 删除表空间 ts2。

mysql> drop tablespace ts2;

Query OK, 0 rows affected (0.02 sec)

本篇主要介绍了 MySQL 三种表空间:单表空间、系统表空间、通用表空间。并把它们的优缺点以及相关注意事项简单进行了说明,希望大家在建表之初考虑好表空间的所属问题。



推荐阅读
  • Java 零基础入门:SQL Server 学习笔记(第21篇)
    Java 零基础入门:SQL Server 学习笔记(第21篇) ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • MySQL索引详解及其优化策略
    本文详细解析了MySQL索引的概念、数据结构及管理方法,并探讨了如何正确使用索引以提升查询性能。文章还深入讲解了联合索引与覆盖索引的应用场景,以及它们在优化数据库性能中的重要作用。此外,通过实例分析,进一步阐述了索引在高读写比系统中的必要性和优势。 ... [详细]
  • 在数据表中,我需要触发一个操作来刷新特定列的数据。例如,对于以下表格:| ID | Name | IsDeleted ||----|-------|-----------|| 1 | test | True || 2 | test2 | False |我希望在点击“更新”按钮时,能够仅刷新选定行的“IsDeleted”列。这将有助于确保数据的实时性和准确性。 ... [详细]
  • 本文深入探讨了数据库性能优化与管理策略,通过实例分析和理论研究,详细阐述了如何有效提升数据库系统的响应速度和处理能力。文章首先介绍了数据库性能优化的基本原则和常用技术,包括索引优化、查询优化和存储管理等。接着,结合实际应用场景,讨论了如何利用容器化技术(如Docker)来部署和管理数据库,以提高系统的可扩展性和稳定性。最后,文章还提供了具体的配置示例和最佳实践,帮助读者在实际工作中更好地应用这些策略。 ... [详细]
  • 在C#中开发MP3播放器时,我正在考虑如何高效存储元数据以便快速检索。选择合适的数据结构,如字典或数组,对于优化性能至关重要。字典能够提供快速的键值对查找,而数组则在连续存储和遍历方面表现优异。根据具体需求,合理选择数据结构将显著提升应用的响应速度和用户体验。 ... [详细]
  • 如何高效启动大数据应用之旅?
    在前一篇文章中,我探讨了大数据的定义及其与数据挖掘的区别。本文将重点介绍如何高效启动大数据应用项目,涵盖关键步骤和最佳实践,帮助读者快速踏上大数据之旅。 ... [详细]
  • 【漫画解析】数据已删,存储空间为何未减?揭秘背后真相
    在数据迁移过程中,即使删除了原有数据,存储空间却未必会相应减少。本文通过漫画形式解析了这一现象背后的真相。具体来说,使用 `mysqldump` 命令进行数据导出时,该工具作为 MySQL 的逻辑备份工具,通过连接数据库并查询所需数据,将其转换为 SQL 语句。然而,这种操作并不会立即释放存储空间,因为数据库系统可能保留了已删除数据的碎片信息。文章进一步探讨了如何优化存储管理,以确保数据删除后能够有效回收存储空间。 ... [详细]
  • 在过去,我曾使用过自建MySQL服务器中的MyISAM和InnoDB存储引擎(也曾尝试过Memory引擎)。今年初,我开始转向阿里云的关系型数据库服务,并深入研究了其高效的压缩存储引擎TokuDB。TokuDB在数据压缩和处理大规模数据集方面表现出色,显著提升了存储效率和查询性能。通过实际应用,我发现TokuDB不仅能够有效减少存储成本,还能显著提高数据处理速度,特别适用于高并发和大数据量的场景。 ... [详细]
  • 本文深入探讨了 MySQL 中 `ANALYZE TABLE` 和 `SHOW CREATE TABLE` 的语法规则及其应用。`ANALYZE TABLE` 语句用于分析并存储表的关键字分布情况,以优化查询性能。该操作在执行过程中会获取表的读锁,确保数据的一致性。而 `SHOW CREATE TABLE` 则用于显示创建表时的详细语句,包括表结构、索引和存储引擎等信息,有助于数据库管理和维护。通过这些命令,DBA 可以更好地理解和优化数据库性能。 ... [详细]
  • 在MySQL中实现时间比较功能的详细解析与应用
    在MySQL中实现时间比较功能的详细解析与应用。本文深入探讨了MySQL中时间比较的实现方法,重点介绍了`UNIX_TIMESTAMP`函数的应用。该函数可以接收一个日期时间参数,也可以不带参数使用,其返回值为Unix时间戳,便于进行时间的精确比较和计算。此外,文章还涵盖了其他相关的时间处理函数和技巧,帮助读者更好地理解和掌握MySQL中的时间操作。 ... [详细]
  • 揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节
    揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节 ... [详细]
  • Go 项目中数据库配置文件的优化与应用 ... [详细]
  • 本文详细探讨了MySQL并发参数的优化与调整方法,旨在帮助读者深入了解如何通过合理配置这些参数来提升数据库性能。文章不仅介绍了常见的并发参数及其作用,还提供了实际操作中的调整策略和最佳实践,适合希望提高数据库管理技能的技术人员阅读。 ... [详细]
  • MySQL 错误:检测到死锁,在尝试获取锁时;建议重启事务(Node.js 环境)
    在 Node.js 环境中,MySQL 数据库操作时遇到了“检测到死锁,在尝试获取锁时;建议重启事务”的错误。本文将探讨该错误的原因,并提供有效的解决策略,包括事务管理优化和锁机制的理解。 ... [详细]
author-avatar
ccccccc_fly_887
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有