MySQL表空间简介

本文主要介绍一下MySQL中的几种表空间概念及相关操作。

基础材料: CentOS7.5  MySQL 5.7.24

###############################################

system tablespace(系统表空间)

相关定义 : 一般用来存放mysql系统相关信息的一个特殊的共享表空间

存放路径 : 默认为MySQL初始化路径下的ibdata1文件

存放内容 : InnoDB data dictionary(InnoDB元数据信息)、doublewrite buffer(双写缓冲区)、change buffer(改变缓冲区)、undo logs以及用户创建的表也可以指定在系统表空间(但一般不这么做)

注:关于上述几项将另起一篇详细说明

控制参数: 

innodb_data_file_path   表空间大小及文件个数由该参数决定,该参数为全局参数,不可动态修改默认值为 ibdata1:12M:autoextend,默认的12M大小是根据innodb_page_size按最大值指定的,为了确保其空间可以容纳doublewrite buffer pages

innodb_page_size为16K时(MySQL默认值) 最小值为3M

innodb_page_size为32K时   最小值为6M

innodb_page_size为64K时   最小值为12M

指定多个文件该参数格式如下(my.cnf):

[mysqld]下添加

innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend[:max:maxfilesize]

注:autoextend(自动扩展)及max(最大文件大小)两个参数只能指定在最后一个ibdata上

autoextend默认每次自动扩展64M,指定其扩展大小参数为innodb_autoextend_increment=32M

innodb_data_home_dir   表空间存放位置控制参数,该参数为全局参数,不可动态修改,默认值为空,即所有表空间建立在数据库初始化目录下

指定自定义表空间位置如下:

innodb_data_home_dir = /path of mysql data file

注:=号两边需要有空格,Mysql不会主动创建目录,指定该位置时需提前创建目录,保证权限正确

如果指定该参数为空,也可以为innodb_data_file_path指定绝对路径

[mysqld]

innodb_data_home_dir =

innodb_data_file_path=/path/ibdata1:50M;ibdata2:/path/ibdata2:50M:autoextend[:max:maxfilesize]

相关问题: 

如果表空间所在文件系统满了怎么办?

一是扩展文件系统

二是在另外文件系统上新建系统表空间,步骤如下

1.停止mysql

2.修改my.cnf,innodb_data_file_path参数,将最后面文件的:autoextend[:max:maxfilesize]去掉,统计文件大小,将前面的50M修改为实际大小(统计大小进为1M的整数倍,例如统计大小不足200M,就写200M即可),写上新的文件系统的绝对路径,后面添加:autoextend[:max:maxfilesize],注意新建路径及相应权限

原:

[mysqld]            

innodb_data_home_dir =

innodb_data_file_path=/path of mysql data file/ibdata1:50M:autoextend[:max:maxfilesize]

新:                   

[mysqld]            

innodb_data_home_dir =

innodb_data_file_path=/path of old data file/ibdata1:200M;/path of new data file/ibdata2:50M:autoextend[:max:maxfilesize]

3.启动mysql

如何缩小系统表空间?

不能直接删除文件,将mysql数据导出,重做数据库,再将数据导入

指定裸设备存储系统表空间: 

步骤如下:

1.创建裸设备表空间

 [mysqld] 

 innodb_data_home_dir =

 innodb_data_file_path=/dev/sda1:10Gnewraw;/dev/sdb1:20Gnewraw

 注:10G为指定空间大小,后面的newraw为新建关键字                    

 2.重启mysql,此时系统会初始化裸设备表空间,期间不要有任何操作

 3.待初始化完成(系统启动完成),关闭停止数据库,修改配置文件为                

 [mysqld] 

 innodb_data_home_dir =

 innodb_data_file_path=/dev/sda1:10Graw;/dev/sdb1:20Graw

  4.启动数据库

#############################################################

File-Per-Table tablespace (单表表空间)(默认表空间形式)

相关定义 : 一般用来存放用户创建的表数据及索引的一个独立表空间,即一张表对应一个表空间文件

存放路径 : 默认为MySQL初始化路径下对应数据库名称文件夹下的 .frm(表结构文件),.ibd(数据+索引),.opt(数据库默认字符集及排序方式)

注:MyISAM引擎下由于其数据和索引是分开存放的,没有ibd文件,对应为.MYD(数据),.MYI(索引)

存放内容 : 用户表数据及索引

控制参数: 

innodb_file_per_table    是否开启单表表空间,该参数为全局参数,可动动态修改,默认为ON,如果设置为OFF,在没有显式指定表空间情况下,数据及索引默认存放到系统表空间ibdata下

相关问题:

使用单表表空间的优势?

1.使用单表表空间,在drop或者truncate时空间可以被收回至操作系统用做其他用途,如果使用系统表空间时,空间只能回收至表空间层级,只能用作mysql存储数据

2. 执行truncate速度更快

3. 在表级别指定不同表存放在不同的存储设备上,以提高性能

4. 可以执行optimize table重组表空间内部数据排列(同时也是主键索引的重新排列),回收多余空间,相当于oracle的降高水位操作,过程一般为建立临时表空间排列实际数据,完成后,删除旧表空间,以新表空间代替旧表空间

5. 进行单表空间在不同实例间移动,而不必处理整个数据库表空间。

6. 单表表空间使用 Barracuda 文件格式,支持行压缩 (compressed row formats)及动态行格式( dynamic row formats),动态行格式可以存储BLOB及TEXT更有效率(这两种大字段类型的列,不走页面管理(innodb_page_size))

 7.  统计表的占用空间,可以在操作系统层面直接查看文件大小

8. mysql表空间有最大值限制(innodb_page_size*4TB),默认16K对应最大值为64TB,使用单表表空间有助于分散容量,虽然一般情况下用不了这么多...

使用单表表空间的劣势?

1. 生产多个表空间可能存在空间碎片,需要对每个表空间执行optimize table,否则可能存在大量空间浪费   

2. fsync刷盘操作需要对所有被打开的表单独执行,占用更多的I/O

3. 对于每个打开的表都会产生句柄及文件描述符,数量较大的情况可能影响性能

4. drop单表表空间时,buffer pool会有大概几秒的时间产生一个扫描,并施加全局内部锁,导致其他操作延迟执行对于系统表空间的表不受影响

5. innodb_autoextend_increment参数对于单表表空间没有作用,单表表空间每次自动扩展大小为4MB

 如何在默认路径外创建File-Per-Table tablespace?

 使用关键字 DATA DIRECTORY = absolute_path_to_directory,注意目录权限问题

 例:

 mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/absolute_path_to_directory';

 此时会在默认路径下生成.frm文件以及.isl文件,.isl相当于一个软链接,指向/absolute_path_to_directory外部路径

单表表空间如何在其他instance中迁移?

步骤如下:

1.源实例执行,创建测试表

mysql > CREATE TABLE test(a INT) ENGINE=InnoDB;

mysql > insert into test value (1);

 2. 目的实例执行,创建测试表

mysql > CREATE TABLE test(a INT) ENGINE=InnoDB;

 3. 目的实例执行, detached并删除原表空间,此时mysql为该表加排它锁,该操作会记录binlog如果是主从结构需要关注一下,可以暂停binlog记录

mysql> ALTER TABLE test DISCARD TABLESPACE;

4. 加共享锁锁表防止导出过程中数据不一致,此时当前session对该表可读不可写,对其他表不可读不可写。其他session对该表可读不可写,对其他表正常读写。将buffer中的脏页刷入磁盘,其表空间所在目录下生成.cfg文件,该文件主要作用是导入时进行schema验证,可用cat查看其内容。此操作不会记录binlog

 mysql> FLUSH TABLES test FOR EXPORT;

5. 拷贝.cfg和.ibd文件到目的主机的对应表空间存放路径下,注意查看文件权限是否正确,否则导入时会提示找不倒表空间文件

shell> scp /path of database/directory/test.{ibd,cfg} destination-server:/path of database directory

6. 为源主机表释放锁,删除.cfg文件

mysql> UNLOCK TABLES;

7. 目标主机导入表空间,此过程会检查页面是否损坏,更新各页面LSN,并将脏页刷新至硬盘

mysql> ALTER TABLE test IMPORT TABLESPACE;

###################################################

General  tablespace(通用表空间)

相关定义 : 一般用来存放用户创建的表数据及索引的一个共享表空间,即多表数据存放在同一表空间内

存放路径 : 手工创建时指定的绝对路径,如果只指定了文件名则创建在数据库默认路径下

存放内容 : 用户创建表的数据及索引

控制参数 : 无直接控制参数

相关问题 :

如何创建通用表空间?

CREATE TABLESPACE tablespace_name ADD DATAFILE 'file_name'  [FILE_BLOCK_SIZE = value]  [ENGINE [=] engine_name]

例:mysql> CREATE TABLESPACE `test` ADD DATAFILE 'test.ibd' Engine=InnoDB;

       mysql> CREATE TABLESPACE `test` ADD DATAFILE '/outside tablespace directory/test.ibd' Engine=InnoDB;

说明:如果不指定文件的绝对路径时,表空间默认建立数据库目录下,如果指定绝对路径需要提前创建该路径并保证相应的读写权限,外部建立表空间时同样会在数据库所在目录下生成.isl的软连接文件。表空间文件名需要以ibd结尾。可选参数[FILE_BLOCK_SIZE = value],在启用压缩表时必须指定,[ENGINE [=] engine_name]在default_storage_engine全局参数未指定时(default_storage_engine=InnoDB是默认值)需要显式定义。

通用表空间优势?

通用表空间相比单表表空间占用内存少(产生文件句柄及描述符少)

支持Antelope and Barracuda文件格式以至于可以支持所有行格式row_format=(redundant,compact,dynamic,compressed)

通过alter table命令可将表在系统表空间,单表表空间及通用表空间中任意移动。

注:通用表空间不支持创建临时表

如何在通用表空间中创建表?

新建表:

mysql> CREATE TABLE test (c1 INT PRIMARY KEY) TABLESPACE test [ROW_FORMAT=COMPACT];

修改表:     

mysql> ALTER TABLE test TABLESPACE test;                

ROW_FORMAT是可选项,如果不指定默认为dynamic。如果指定为compressed,创建表空间时需要指定FILE_BLOCK_SIZE项,建表时也要加入参数KEY_BLOCK_SIZE项,且KEY_BLOCK_SIZE与FILE_BLOCK_SIZE为等值,以innodb_page_size为16为例,KEY_BLOCK_SIZE取值可以为(8,4,2,1),对应FILE_BLOCK_SIZE取值也应为(8,4,2,1)

 如何将表在3种表空间中移动? 

 ALTER TABLE tbl_name TABLESPACE = tablespace_name  (通用表空间名字)

 ALTER TABLE tbl_name TABLESPACE = innodb_system   (系统表空间关键字)

 ALTER TABLE tbl_name TABLESPACE = innodb_file_per_table (单表表空间关键字)

 如何确认表与表空间的归属关系?

 方法1:

 mysql> show create table test;

 输出如果明确列出表空间信息为通用表空间,如果没有列出表空间信息则为单表表空间

 方法2:

 mysql> select * from information_schema.INNODB_SYS_TABLES;

 输出项SPACE显示了表空间的ID,SPACE_TYPE显示了表空间的类型。

 mysql> select * from information_schema.INNODB_SYS_TABLESPACES;

 跟据输出的SPACE ID进行关联,找到具体的NAME

注:额外说一下 information_schema.INNODB_SYS_TABLESTATS里存储了表的统计行数,可以直接查找,当前版本count(*)时是否直接从该表取数,还是走全表扫描还需要确认一下,先写在这里留个记录

如何删除通用表空间?

需要先将其中的表drop掉之后,再drop表空间

########################################################################

REDO LOG (重做日志表空间)

相关定义 : 用来存放Innodb存储引擎的事务日志,用于在DB崩溃后进行数据恢复时保证数据完整性

存放路径 : 数据库默认路径下ib_logfile0,ib_logfile1,50M,循环使用

存放内容 : 数据被修改后的值,以物理页的形式存放在REDO LOG中

控制参数 :

innodb_log_file_size    定义每个redolog的大小,全局参数,不支持动态修改,默认值为50331648 bytes(48M)

innodb_log_files_in_group  定义有多少个redolog, 全局参数,不支持动态修改,默认值为2

注:innodb_log_file_size*innodb_log_files_in_group的总值不能大于512GB

例:编辑my.cnf文件

[mysqld]

innodb_log_file_size=200MB
innodb_log_files_in_group=4 

innodb_flush_log_at_trx_commit  定义redolog的刷盘方式,全局参数,支持动态修改,可选值为0、1、2

当innodb_flush_log_at_trx_commit=1时(默认值),在每个事务开始时,将log buffer(内存中)写入到log file buffer(物理文件系统缓存),同时调用fsync将log file buffer持久化到物理文件log file,由于每个事物都要产生持久化io,保证了数据安全性的同时(当数据库或者操作系统宕机时,最多丢失一个事务的数据),也造成了其效率在可选参数中是最低的

当innodb_flush_log_at_trx_commit=0时,在每个事务开始时,先写log buffer(内存中),每隔一秒(默认值,每隔N秒由参数innodb_flush_log_at_timeout=N决定)(或缓冲区满等其他条件会使其提前刷新),将log buffer(内存中)写入到log file buffer(物理文件系统缓存),同时调用fsync将log file buffer持久化到物理文件log file,由于每N秒才产生持久化io,效率会较高,同时如果数据库或者操作系统宕机会丢失N秒的数据

当innodb_flush_log_at_trx_commit=2时,在每个事务开始时,将log buffer(内存中)写入到log file buffer(物理文件系统缓存),  每隔一秒(默认值,每隔N秒由参数innodb_flush_log_at_timeout=N决定)(或缓冲区满等其他条件会使其提前刷新), 调用fsync将log file buffer持久化到物理文件log file,由于每N秒才产生持久化io,效率会较高。如果数据库宕机时不会丢失数据,因为此时数据已经保存在文件系统缓存中,如果操作系统宕机会丢失N秒的数据。

相关问题 :

redolog的作用?

redolog属于innodb存储引擎层(区别于binlog的server层),主要用于数据库崩溃后的自动恢复工作(参与恢复工作的还有undolog以及binlog(如果开启))

##############################################################

UNDO LOG (回滚日志表空间)

相关定义 : 用来存放Innodb存储引擎的事务日志,用于在DB崩溃后进行数据恢复时保证数据完整性

存放路径 : 数据库默认路径下ibdata1中,与系统表空间存放于同一文件中

存放内容 : 数据被修改前的值,以逻辑语句的形式存放在UNDO LOG中

控制参数 :

innodb_undo_directory

[mysqld]

innodb_undo_directory=/path of undo tablespace

指定undo表空间的存储路径,该参数只能在mysql初始化时指定

innodb_undo_tablespaces

[mysqld]

innodb_undo_tablespaces=3

指定UNDO表空间的数量,全局参数不支持动态修改,最大值95,默认值0,该参数只能在mysql初始化时指定

innodb_undo_log_truncate

[mysqld]

innodb_undo_log_truncate=ON

全局参数支持动态修改,默认值OFF,使用innodb_undo_log_truncate时,至少需要保证 innodb_undo_tablespaces参数为2,保证truncate其中之一时,另一个可以继续工作。

innodb_max_undo_log_size

[mysqld]

innodb_max_undo_log_size=2G

全局参数支持动态修改,默认值1G,配合innodb_undo_log_truncate参数使用,在undolog文件达到该限值时,会标记为截断,不会分配给其他事务,允许当前事务完成其操作后,回滚段不再被使用时,mysql将执行truncate,将文件大小恢复到初始化的大小(10MiB)

innodb_rollback_segments

[mysqld]

innodb_rollback_segments=128

全局参数支持动态修改,最大值128,默认值128,1个回滚段分配给系统表空间,32个回滚段分配给临时表空间,如果定义两个innodb_undo_tablespaces, innodb_rollback_segments值至少应为35个,一般保持默认值即可。

相关问题 :

undolog的作用?

主要用于事务回滚及数据库崩溃后的自动恢复工作,以及MVCC(多版本控制的实现)

########################################################

Temporary Tablespace (临时表空间)

相关定义 : 用于存储非压缩临时表的数据及相关对象

存放路径 : 数据库默认路径下 ibtmp1中

存放内容 : 临时表的数据及相关对象

控制参数 :

innodb_temp_data_file_path   

[mysqld]

innodb_temp_data_file_path=/path of data file

全局参数不支持动态修改,默认值ibtmp1:12M:autoextend,如果不指定路径将建立在数据库初始化路径下

相关问题:

临时表空间的一些说明?  

重启数据库后临时表空间会自动重建,重新分配表空间ID

不支持裸设备

元数据存储在 INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO 视图中

你可能感兴趣的:(Mysql,MYSQL)