本文主要介绍一下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 视图中