mysql共享表空间和独立表空间

MySQL  InnoDB 共享表空间和独立表空间




官网:https://dev.mysql.com/doc/refman/5.6/en/innodb-multiple-tablespaces.html
 



前言:学习mysql的时候总是习惯性的和oracle数据库进行比较。在学习mysql InnoDB的存储结构的时候也免不了跟oracle进行比较。Oracle的数据存储有表空间、段、区、块、数据文件;mysql InnoDB的存储管理也类似,但是mysql增加了一个共享表空间和独立表空间的概念;

image

一、概念

共享表空间: Innodb的所有数据保存在一个单独的表空间里面,而这个表空间可以由很多个文件组成,一个表可以跨多个文件存在,所以其大小限制不再是文件大小的限制,而是其自身的限制。从Innodb的官方文档中可以看到,其表空间的最大限制为64TB,也就是说,Innodb的单表限制基本上也在64TB左右了,当然这个大小是包括这个表的所有索引等其他相关数据。

独立表空间:

二、查看数据库的表空间

mysql> show variables like 'innodb_data%';

image

l 表空间有四个文件组成:ibdata1、ibdata2、ibdata3、ibdata4,每个文件的大小为10M,当每个文件都满了的时候,ibdata4会自动扩展;

l 当前的存储空间满的时候,可以在其他的磁盘添加数据文件,语法如下:语法如下所示:

pathtodatafile:sizespecification;pathtodatafile:sizespec;.;pathtodatafile:sizespec[:autoextend[:max:sizespecification]]

如果用 autoextend 选项描述最后一个数据文件,当 InnoDB 用尽所有表自由空间后将会自动扩充最后一个数据文件,每次增量为 8 MB。示例:

不管是共享表空间和独立表空间,都会存在innodb_data_file文件,因为这些文件不仅仅要存放数据,而且还要充当着类似于ORACLE的UNDO表空间等一些角色。

三、共享表空间优缺点

既然Innodb有共享表空间和独立表空间两种类型,那么这两种表空间存在肯定都有时候自己的应用的场景,存在即合理。以下是摘自mysql官方的一些介绍:

3.1 共享表空间的优点

表空间可以分成多个文件存放到各个磁盘,所以表也就可以分成多个文件存放在磁盘上,表的大小不受磁盘大小的限制(很多文档描述有点问题)。

数据和文件放在一起方便管理。

3.2 共享表空间的缺点

所有的数据和索引存放到一个文件,虽然可以把一个大文件分成多个小文件,但是多个表及索引在表空间中混合存储,当数据量非常大的时候,表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,对于经常删除操作的这类应用最不适合用共享表空间。

共享表空间分配后不能回缩:当出现临时建索引或是创建一个临时表的操作表空间扩大后,就是删除相关的表也没办法回缩那部分空间了(可以理解为oracle的表空间10G,但是才使用10M,但是操作系统显示mysql的表空间为10G),进行数据库的冷备很慢;

四、独立表空间的优缺点

4.1 独立表空间的优点

每个表都有自已独立的表空间,每个表的数据和索引都会存在自已的表空间中,可以实现单表在不同的数据库中移动。

空间可以回收(除drop table操作处,表空不能自已回收)

Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间。

对于使innodb-plugin的Innodb使用turncate table也会使空间收缩。

对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。

4.2 独立表空间的缺点

单表增加过大,当单表占用空间过大时,存储空间不足,只能从操作系统层面思考解决方法;

五、共享表空间和独立表空间之间的转换

5.1 查看当前数据库的表空间管理类型

脚本:show variables like "innodb_file_per_table";

mysql> show variables like "innodb_file_per_table";

image

ON代表独立表空间管理,OFF代表共享表空间管理;(查看单表的表空间管理方式,需要查看每个表是否有单独的数据文件)

5.2 修改数据库的表空间管理方式

修改innodb_file_per_table的参数值即可,但是修改不能影响之前已经使用过的共享表空间和独立表空间;

innodb_file_per_table=1 为使用独占表空间

innodb_file_per_table=0 为使用共享表空间

5.3共享表空间转化为独立表空间的方法(参数innodb_file_per_table=1需要设置)
单个表的转换操作,脚本:alter table table_name engine=innodb;

当有大量的表需要操作的时候,先把数据库导出,然后删除数据再进行导入操作,该操作可以用mysqldump进行操作(http://blog.itpub.net/12679300/viewspace-1259451/

总结:经过以上操作便完成数据库的存储空间的转换,了解技术是为了更好的利用技术,当数据量很小的时候建议使用共享表空间的管理方式。数据量很大的时候建议使用独立表空间的管理方式。



Advantages of File-Per-Table Mode

1 当truncate或者drop一个表时可以释放磁盘空间。如果不是独立表空间,truncate或drop一个表只是在ibdata文件内部释放,实际ibdata文件并不会缩小,释放出来的空间也只能让其他innodb引擎的表使用(有时这会造成磁盘空间容量监控的一个痛点,无法判断它到底有多满)

2 独立表空间下,truncate table操作会更快

3 独立表空间下,可以自定义表的存储位置,通过CREATE TABLE ... DATA DIRECTORY =absolute_path_to_directory命令实现(有时将部分热表放在不同的磁盘可有效地提升IO性能)

4 独立表空间下,可以回收表空间碎片(比如一个非常大的delete操作之后释放的空间),alter table xxx engine=innodb

5 可以移动单独的innodb表,而不是整个database

6 可以copy单独的innodb表从一个实例到另外一个实例(也就是transportable tablespace特色)

7 独立表空间模式下,可以使用Barracuda的文件格式,这个文件格式有压缩和动态行模式的特色。这个当表中有blob或者text字段的话,动态行模式(dynamic row format)可以发挥出更高效的存储。

8 独立表空间模式下,可以更好的改善故障恢复,比如更加节约时间或者增加崩溃后正常恢复的机率。

9 单独备份和恢复某张表的话会更快

10 可以使得从一个备份中单独分离出表,比如一个lvm的快照备份

11 可以在不访问MySQL的情况下方便地得知一个表的大小,即在文件系统的角度上查看。

12 在大部分的linux文件系统中,如果innodb_flush_method为O_DIRECT,通常是不允许针对同一个文件做并发写操作的。这时如果为独立表空间模式的话,应该会有较大的性能提升。

13 如果没有独立表空间模式,那么所有的东西都在共享表空间,而共享表空间是有64T的容量上限的(这点比较扯淡)

Potential Disadvantages of File-Per-Table Mode

1 独立表空间模式下,每个表或许会有很多没用到的磁盘空间,因为初始表空间大小是固定的吧,有些表根本没使用都这么多。如果没做好管理,可能会造成较大的空间浪费。

2 fsync操作必须运行在每一个单一的文件上,独立表空间模式下,多个表的写操作就无法合并为一个单一的IO,这样就添加许多额外的fsync操作

3 mysqld必须保证每个表都有一个open file,独立表空间模式下,这样就需要很多打开文件数,可能会影响性能

4 当drop一个表空间时,buffer pool会被扫描,如果buffer pool有几十G那么大,或许要花费几秒钟时间。这个扫描操作还会产生一个内部锁,可能会延迟其他操作,共享表空间模式下不会有这个问题。

5 如果许多表都增长迅速,那么可能会产生更多的分裂操作(应该指的是表空间大小的扩充),这个操作会损害drop table和table scan的性能。

6 innodb_autoextend_increment参数对独立表空间无效,这个参数指的是当系统表空间满了以后,它再次预先申请的磁盘空间大小,单位为M

 

Copying Tablespaces to Another Server(Transportable Tablespaces)

Transportable Tablespaces特性可以处理以下几个痛点

1 跑报表,单独拎出需要的几个表到新的实例上跑报表,可以保证报表产生巨大服务器开销不影响到现网服务

2 通过这个特性快速地建立一个新的slave

3 在当前库发生一个故障后备份一个该表的临时版本

4 一种比mysqldump更快的moving data的方式

5 可以将部分表移交到一个更合适的硬件环境下,比如小而操作频繁的放在SSD下,大而操作不频繁的放在HDD

Tablespace Copying Limitations and Usage Notes(Transportable Tablespaces)

1 必须是在独立表空间模式下

2 在迁移过程中,涉及到的表只读不可写

3 两边的page size必须保持一致(innodb_page_size)

4 DISCARD TABLESPACE操作不一致分区表,否则报错ERROR 1031 (HY000): Table storage engine for 'part' doesn'thave this option.

5 DISCARD TABLESPACE时,如果foreign_key_checks为1,那么不支持存在外键约束的表

6 ALTER TABLE ... IMPORT TABLESPACE操作不会去检查外键约束

7 ALTER TABLE ... IMPORT TABLESPACE并不需要.cfg的元数据文件来导入一个表空间。但是,这样的话就没有元数据检查了,同时会给出一个waring

Message: InnoDB: IO Read error: (2, No suchfile or directory) Error opening '.\
test\t.cfg', will attempt to import without schema verification
1 row in set (0.00 sec)

如果确认schema没有配错,那么不用.cfg文件可能更方便简洁,并且有利于元数据无法在.ibd文件里收集的故障恢复。

8 主从环境下,master和slave都必须设置为独立表空间模式

Example Procedure: Copying a Tablespace From One Server ToAnother (Transportable Tablespaces)

1 在源server上,创建一个测试表

mysql> use test;
mysql> CREATE TABLE t(c1 INT) engine=InnoDB;

2 在目标server上,同样创建出相同表结构的表

mysql> use test;
mysql> CREATE TABLE t(c1 INT) engine=InnoDB;

3 在目标server上,discard掉该表的表空间

mysql> ALTER TABLE t DISCARD TABLESPACE;

4 在源server上,运行FLUSH TABLES ... FOR EXPORT命令来静默这张表,并创建出.cfg元数据文件(.cfg文件创建在innodb的data目录)

mysql> use test;
mysql> FLUSH TABLES t FOR EXPORT;

5 复制源server上的.ibd和.cfg文件到目标server上

shell> scp /path/to/datadir/test/t.{ibd,cfg}destination-server:/path/to/datadir/test

6 在源server上,使用unlock tables命令来释放flush tables..for export命令上的锁

mysql> use test;
mysql> UNLOCK TABLES;

7 在目标server上,导入表空间

mysql> use test;
mysql> ALTER TABLE t IMPORT TABLESPACE;

Tablespace Copying Internals (Transportable Tablespaces)

ALTER TABLE ... DISCARD TABLESPACE做了下面这两件事

1 给table加X锁

2 分离出表空间

FLUSH TABLES ... FOR EXPORT做了以下几件事

1 给table加S锁

2 停止purge线程

3 脏页刷新到磁盘

4 表的元数据写到.cfg文件

Unlock tables做了以下几件事

1 删除.cfg文件

2 释放之前的共享锁,并重启purge线程

ALTER TABLE ... IMPORT TABLESPACE做了以下几件事

1 检查表空间内的每个页是否有损坏

2 更新每页上的space ID和LSNs

3 更新开头页的有效标志位和LSN

4 更新btree页

5 将页状态改为“脏页”,刷新到磁盘

Storing InnoDB Undo Logs in SeparateTablespaces

  5.6.3以前,innodb undo log存放在系统表空间,5.6.3以后可将undo log从系统表空间中分离出来。这样带来的好处是,可将undo放到SSD盘提升性能。这个特性主要由这几个参数实现

innodb_undo_tablespaces:undo logs创建的表空间文件数量,默认为0,表示存放在系统表空间,最大值为126

innodb_undo_directory:undo logs存放的路径,默认为.表示和其他日志文件一致

innodb_undo_logs:系统表空间中在一个事务里最大使用到的回滚段数量,默认为最大值128

分离步骤如下

1 决定undo logs的存放路径,修改innodb_undo_directory参数

2 决定一个非0的innodb_undo_logs值,可以通过压测决定到底取啥值,起始值设置小一些

3 决定一个非0的innodb_undo_tablespaces值

4 利用上述配置创建出新的mysql实例

5 压测IO负载情况

6 压测期间慢慢增大innodb_undo_logs,找到最合适的值

7 上生产环境下再测试观察

Changing the Number or Size of InnoDB LogFiles and Resizing the InnoDB Tablespace

Changing the Number or Size of InnoDB Log Files

1 SET GLOBAL innodb_fast_shutdown = 1;

2 正常关闭mysqld进程,确保正常关闭

3 备份旧的log files

4 删除旧的log files

5 修改my.cnf配置

6 重启mysqld,确保启动后log files的数量和新配置一致

5.6.8以后的版本,不再需要innodb_fast_shutdown,也不用删除旧的log files。

Increasing the Size of the InnoDB Tablespace

由innodb_data_file_path参数的autoextend参数控制就好,表空间会自动增长。默认每次增长为8M,系统表空间每次增长量可由参数innodb_autoextend_increment控制。如果要两个系统表空间文件,一个固定大小,一个自增,可以这么弄(建议一个就好,不要这么搞,有点乱,不好管理)

innodb_data_file_path =/ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend

Decreasing the Size of the InnoDB Tablespace

独立表空间回收磁盘空间,只要运行alter table xx engine=innodb就行,系统表空间回收步骤如下

1 使用mysqldump dump出所有的表

2 关闭mysql

3 删除整个data目录,包括ibdata文件和log file

4 启动mysql

5 导入dump文件



Mysql Innodb的两种表空间方式

要说表空间,Mysql的表空间管理远远说不上完善。换句话说,事实上Mysql根本没有真正意义上的表空间管理。Mysql的Innodb包含两种表空间文件模式,默认的共享表空间和每个表分离的独立表空间。只要在my.cnf里面增加innodb_file_per_table=1就可以从共享表空间切换到独立表空间。当然对于已经存在的表,则需要执行alter table MY_TABLE engine=innodb命令迁移数据。

共享表空间方式

由于是默认的方式,就暂且理解为Mysql官方推荐的方式。相对而言所有的数据都在一个(或几个)文件中,比较利于管理,而且在操作的时候只需要open这一个(或几个)文件即可,相对来说代价很低。

但问题是在数据达到以G为单位来计算的时候优劣逆转。一个大小惊人的文件很不利于管理,而且对于一个如此巨大的文件来说,读写它需要耗费的资源一样巨大。更加令人费解的是,MySQL竟然将索引和数据保存于同一个文件中,索引和数据之间尚存在资源争用,不利于性能的提升。你当然可以通过innodb_data_file_path的配置规划多个表空间文件,但MySQL的逻辑是“用满后增加”,仅仅是一个文件的拆分而已,不能从根本上分离数据和索引。

之前曾经遭遇到700G以上的表空间文件,而且更加让人郁闷的是对于如此大的文件还在以每天数G的数量增加。由于无法停机,即便是拷贝一下也要花费差不多一夜,只能眼睁睁看着它继续增大而毫无保守可行的办法。

独立表空间方式

相对而言对立表空间每个表都有独立的多个数据文件,而且做到了索引和数据的分离。多个小文件之间很方便的完成跨数据库甚至跨硬件的数据拷贝和迁移。相对来说灵活性很好。

这样做同样带来另一个方面的问题。当数据库中的表数量达到一定级别时,每次操作所涉及的文件过多,如果按照默认Centos的ulimit -n = 1024的话,仅仅只能保证同时打开256个表以内,这在习惯上“拆库拆表”的MySQL数据结构上很难达到要求。尚且这种数据文件的利用率不算很高,当大量“不高”的文件集中起来,浪费的空间也很惊人,更何况最后可能出现的状况不是“一堆K级别的小文件”而是“一堆G级别的大文件”,有点适得其反的意思。你自然可以联想到分区表,又是一个“仅仅做文件拆分而已”,多个分区文件缺一不可。

之前同样遇到过这个问题,MySQL连接大的状况下大量的timeout,但主机负载还算可以,查了一圈才知道是open files限制的问题,限制一修改,负载变得惊人,但连接数却又提升的不多。

总之,两种方法各有所长,部分互补,但都不是解决问题的终极方案。期待MySQL能够出现真正意义上表空间的概念,更加自由的规划数据文件。



对于innodb的数据存储文件,首先要解决两个概念性的问题: 共享表空间以及独占表空间。(innodb引擎与MYISAM引擎的区别很大。特别是它的数据存储方式等.)

1、共享表空间和独占表空间介绍

共享表空间以及独占表空间都是针对数据的存储方式而言的。

共享表空间:  每一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下。 默认的文件名为:ibdata1  初始化为10M。

独占表空间:  每一个表都将会生成以独立的文件方式来进行存储,每一个表都有一个.frm表描述文件,还有一个.ibd文件(这个文件包括了单独一个表的数据内容以及索引内容)。

2、共享表空间和独占表空间的区别

共享表空间:
优点:
1)可以放表空间分成多个文件存放到各个磁盘上(表空间文件大小不受表大小的限制,如一个表可以分布在不同的文件上)。

所以其大小限制不再是文件大小的限制,而是其自身的限制。从Innodb的官方文档中可以看到,其表空间的最大限制为64TB,也就是说,Innodb的单表限制基本上也在64TB左右了,当然这个大小是包括这个表的所有索引等其他相关数据。

2)表数据和表描述放在一起方便管理。 

缺点:
1)所有的数据和索引存放到一个文件中,将有一个很常大的文件,虽然可以把一个大文件分成多个小文件,但是多个表及索引在表空间中混合存储,这样对于一个表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,日志系统这类应用最不适合用共享表空间。

独立表空间(在配置文件(my.cnf)中设置innodb_file_per_table=1):

优点:
1)每个表都有自已独立的表空间。
2)每个表的数据和索引都会存在自已的表空间中。
3)可以实现单表在不同的数据库中移动。
4)空间可以回收。

对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理(表空不能自已回收),处理方式如下:
Drop table操作自动回收表空间

如果对于统计分析或是日志表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间
对于使innodb-plugin的Innodb使用turncate table也会使空间收缩
5)使用独占表空间的效率以及性能会更高一点。

缺点:
1)单表增加过大,如超过100个G:

当使用独享表空间来存放Innodb的表的时候,每个表的数据以一个单独的文件来存放,这个时候的单表限制,又变成文件系统的大小限制了。

3、共享表空间以及独占表空间之间的转化

修改独占空表空间配置,以下几个参数必须在一起加入

innodb_data_home_dir = "/usr/local/MySQL/var/"  数据库文件所存放的目录

innodb_log_group_home_dir = "/usr/local/mysql/var" 日志存放目录

innodb_data_file_path=ibdata1:10M:autoextend  设置配置一个可扩展大小的尺寸为10MB的单独文件(共享数据文件),名为ibdata1。没有给出文件的位置,所以默认的是在MySQL的数据目录内(如 /db/mysql/ibdata1)。

innodb_file_per_table=1  是否使用共享以及独占表空间(1 为使用独占表空间,0 为使用共享表空间)

innodb_file_per_table 通过这个参数来实现的转化,如果为OFF说明所使用的是共享表空间【默认情况下,所使用的表空间为共享表空间】

innodb_file_per_table值来进行修改即可,但是对于之前使用过的共享表空间则不会影响,除非手动的去进行修改

注意:

InnoDB不创建目录,所以在启动服务器之前请确认”所配置的路径目录”的确存在。

做数据的移植以及备份时,要注意数据文件的完整性.

  • innodb_file_per_table

    Command-Line Format --innodb-file-per-table
    System Variable Name innodb_file_per_table
    Variable Scope Global
    Dynamic Variable Yes
    Permitted Values (<= 5.6.5) Type boolean
    Default OFF
    Permitted Values (>= 5.6.6) Type boolean
    Default ON

    When innodb_file_per_table is enabled (the default), InnoDB stores the data and indexes for each newly created table in a separate .ibd file instead of the system tablespace. The storage for these tables is reclaimed when the tables are dropped or truncated. This setting enables InnoDBfeatures such as table compression. See Section 14.7.4, “InnoDB File-Per-Table Tablespaces” for more information.

    Enabling innodb_file_per_table also means that an ALTER TABLE operation moves an InnoDB table from the system tablespace to an individual .ibd file in cases where ALTER TABLE rebuilds the table (ALGORITHM=COPY).

    When innodb_file_per_table is disabled, InnoDB stores the data for tables and indexes in the ibdata files that make up the system tablespace. This setting reduces the performance overhead of file system operations for operations such as DROP TABLE or TRUNCATE TABLE. It is most appropriate for a server environment where entire storage devices are devoted to MySQL data. Because the system tablespace never shrinks, and is shared across all databases in an instance, avoid loading huge amounts of temporary data on a space-constrained system when innodb_file_per_table is disabled. Set up a separate instance in such cases, so that you can drop the entire instance to reclaim the space.

    innodb_file_per_table is enabled by default as of MySQL 5.6.6. Consider disabling it if backward compatibility with MySQL 5.5 or 5.1 is a concern. This will prevent ALTER TABLE from moving InnoDB tables from the system tablespace to individual .ibd files.

    innodb_file_per_table is dynamic and can be set ON or OFF using SET GLOBAL. You can also set this option in the MySQL configuration file (my.cnf or my.ini) but this requires shutting down and restarting the server.

    Dynamically changing the value requires the SUPER privilege and immediately affects the operation of all connections. 



 



File-Per-Table的优点:
1.当表删除或者truncate,空间可以被OS回收。
2.Truncate table在单个.ibd文件上执行更快。
3.可以为每个表指定一个特定存储。优化IO,空间管理。CREATE TABLE ... DATA DIRECTORY =absolute_path_to_directory 。
4.运行OPTIMEIZE TABLE,压缩或者重建创建表空间。运行OPTIMIZE TABLE InnoDB会创建一个新的ibd文件。当完成时,老的表空间会被新的代替。
5.可以移动单个表,不需要移动整个数据库
6.可以把表复制到另外一个实例
7.innodb_file_per_table启动后才能使用Barracuda文件格式。
8.可以更有效的存储带BLOB,TEXT使用动态行模式的表。
9.使用innodb_file_per_table可以提高recovery的成功率,减少损坏错误发生恢复的时间。
10.可以快速的备份,恢复单个表。
11.innodb_file_per_table 可以从备份中去除一个表
12.innodb_file_per_table在备份和复制表时,容易观察每个表的状态。
13.可以通过文件系统直接观察表的大小。
14.当innodb_flish_method设置为O_DIRECT,通常linux文件系统不允许并发的写入同一个文件。使用innodb_file_per_table就会有性能提升。
15.不启用innodb_file_per_table,数据都会放在系统表空间中,最大64TB,如果使用innodb_file_per_table每个表可以64TB。

File-Per-Table的缺点:
1.表空间中的空间只能被这个表使用
2.fsync操作必须在每个表上都运行一遍
3.mysqld必须保持一个打开的文件句柄,表太多会影响性能。
4.会消耗很多文件描述
5.innodb_file_per_tablezhiyou 5.6.6或更高版本才能用,有向下兼容问题。
6.如果很多表都增长,会出现文件碎片问题。导致drop表和表扫描性能下降。
7.当drop表的时候会扫描buffer pool,如果太大会比较耗时。
8.innodb_autoextend_increment指定当文件满了之后增长的空间。
 



PS:innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等.对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间.

1、什么是共享表空间和独占表空间

共享表空间以及独占表空间都是针对innodb表的数据存储而言的,ibdata1为innodb引擎的存储数据与索引的数据文件,ib_logfile0与ib_logfile1为innodb引擎使用的日志文件
共享表空间: mysql服务器中所有数据库的innodb表(数据,索引)全部放在一个文件中,默认这个共享表空间的文件路径在data目录下. 默认的文件名为:ibdata1 初始化为10M.
独占表空间: 每一个表都将会生成以独立的文件方式来进行存储,每一个表都有一个.frm表描述文件,还有一个.ibd文件. 其中这个文件包括了单独一个表的数据内容以及索引内容,默认情况下它的存储位置也是在表的位置之中.

2、两者之间的优缺点

  1. 共享表空间:

    优点:
    InnoDB在共享表空间模式下,是支持多文件的,用innodb_data_file_path选项可以配置:
    innodb_data_file_path = /disk1/ibdata1:2G;/disk2/ibdata2:2G:autoextend
    这样配置就把数据文件分散在了disk1和disk2两个路径下,第一个文件固定2G大小,第二个文件初始化2G,可以自增长.(数据文件大小不受表大小的限制,如一个表可以分布在不同的数据文件上).数据和文件放在一起方便管理.
    缺点:
    1.所有的数据和索引存放到一个文件中意味着将有一个很常大的文件,虽然可以把一个大文件分成多个小文件,但是服务器上的所有库中的innodb表及索引在表空间中混合存储,这样对于一个表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,日值系统这类应用最不适合用共享表空间.
    2.共享表空间不会收缩! ibdata1 只会一个劲的增长.对于一台服务器上面n个库而且存在删除库的的情况就郁闷了!

  2. 独立表空间:

    在配置文件(my.cnf)中设置: innodb_file_per_table

    优点:
    1. 每个表都有自已独立的表空间.
    2. 每个表的数据和索引都会存在自已的表空间中.
    3. 可以实现单表在不同的数据库中移动.
    4. 空间可以回收(除drop table操作处,表空不能自已回收)
    a) Drop table操作自动回收表空间,如果对于统计分析或是日值表,删除大量数据后可以通过:alter table TableName engine=innodb;回缩不用的空间.
    b) 对于使innodb-plugin的Innodb使用turncate table也会使空间收缩.
    c) 对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理.
    缺点:
    单表增加过大,如超过100个G.
    对于单表增长过大的问题,如果使用共享表空间可以把文件分开,但有同样有一个问题,如果访问的范围过大同样会访问多个文件,一样会比较慢.对于独立 表空间也有一个解决办法是:使用分区表,也可以把那个大的表空间移动到别的空间上然后做一个连接.其实从性能上出发,当一个表超过100个G有可能响应也 是较慢了,对于独立表空间还容易发现问题早做处理.

     相比较之下,使用独占表空间的效率以及性能会更高一点,推荐使用独立表空间的原因:

  1. 从性能上对比共享表空间和独立表空间:

    共享表空间在Insert操作上少有优势.其它都没独立表空间表现好.这里也有一个TIPS当启用独立表空间时,请合理调整一下:innodb_open_files .

  2. 从Linux系统处理上出发:

    文件系统fsync一大片更新数据,对系统io冲击较大.若分隔成多个小数据fsync,能够减少对读的影响. 同时从mysql代码,发现mysql保证两次fsync之间至少有20ms的sleep,这样的话,若将一次fsync变成多次小数据操作,应该能够减 少慢查询的比例.所以对于大量更新操作的系统不太适合用共享表空间



Innodb表空间

Innodb有两种管理表空间的方法

  独立表空间:每一张表都会生成独立的文件来进行存储,每一张表都有一个.frm表描述文件,和一个.ibd文件。其中ibd文件包括了单独一个表的数据内容和索引内容。

  共享表空间:某一个数据库的所有表的数据和索引文件都放在一个文件下,默认的文件是.ibdata1文件,初始值是10M,默认是存放在数据文件的根目录下(mysql/var)。

在性能和运维上独立表空间比共享的表空间有很多优势

 共享表空间

  优点:

    表空间可以分成多个文件存放到各个磁盘,所以表也就可以分成多个文件存放在磁盘上,表的大小不受磁盘大小的限制(很多文档描述有点问题)。

    数据和文件放在一起方便管理

   缺点:

    多个表及索引在表空间中混合存储,这样对于一个表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,日值系统这类应用最不适合用共享表空间。

    共享表空间分配后不能回缩

    进行数据库的冷备很慢,mysqldump是一个好的处理方式

独立空间

  优点:  

  1. 每个表都有自已独立的表空间。
  2. 每个表的数据和索引都会存在自已的表空间中。
  3. 可以实现单表在不同的数据库中移动。
  4. 空间可以回收

  缺点:

    单表增加过大,响应也是较慢,可以使用分区表

    单表增加过大,当单表占用空间过大时,存储空间不足,只能从操作系统层面思考解决方法

共享表空间和独立表空间之间的转换  

1.查看当前表空间情况:

1

show variables like '%per_table';

ON代表独立表空间管理,OFF代表共享表空间管理;

2.修改数据库的表空间管理方式

  修改配置文件 ,在/etc/my.cnf文件中设置

    innodb_file_per_table=1 为使用独占表空间

    innodb_file_per_table=0 为使用共享表空间

  重启mysql

3.共享表空间转化为独立表空间的方法

  (1)需要设置innodb_file_per_table=1

  (2)单个表 

      alter table table_name engine=innodb;

    很多表

      先把数据库导出,然后删除数据再进行导入操作,该操作可以用mysqldump进行操作

总结:

  经过以上操作便完成数据库的存储空间的转换

  当数据量很小的时候建议使用共享表空间的管理方式。数据量很大的时候建议使用独立表空间的管理方式 



innodb有两种表空间,共享表空间和独立表空间,表空间相关的两个参数有:

MySQL> show variables like 'innodb_data%';
+-----------------------+------------------------+
| Variable_name         | Value                  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
| innodb_data_home_dir  |                        |
+-----------------------+------------------------+

innodb_data_home_dir指明数据文件的父目录,默认的是服务器的数据目录。

innodb_data_file_path指明表空间组成的数据文件。

要重新配置表空间,需要先停止mysql服务器,删除变空间和日志文件,在使用新的配置重新启动服务器。

查看innodb表空间剩余大小

mysql> show table status like 'user'\G
*************************** 1. row ***************************
           Name: user
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 5
 Avg_row_length: 3276
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: 33
    Create_time: 2015-02-10 17:48:21
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options:
        Comment: 用户表
1 row in set (0.01 sec)

我这个在comment中没有显示,不知道是为什么??

在表空间满的时候,可以添加数据文件,在配置文件中添加

innodb_data_file_path=ibdata1:79M;ibdata2:12M:autoextend,添加这个后,无法启动mysql了,这个启动的条件是什么?

设置独立表空间

使用--innodb-file-per-table选项启动mysql,每个表有个。frm和.ibd文件,对于之后创建的表起作用。



增加mysql InnoDB的表空间

2013年9月12日 默北发表评论阅读评论 

上节说到了如何添加和调整innodb log文件,然而调整表空间没这么简单,需要将数据导出来然后再导入。对于共享的表空间,ibdata会变的非常大,即使删除大量的数据,ibdata空间回收效果不明显。

innodb_data_file_path
该变量设置innoDB数据文件的位置和大小。指定的文件必须大于10M,如果不受系统文件限制,可以设置大于4G。该变量是MySQL服务器容量规划和性能扩展能力的核心要素。通常设置是创建一个数据目录内容的基线大小,在10M到128M之间,第二个文件设置为10M并自动扩展。如innodb_data_file_path = ibdata1:128M;ibdata2:10M:autoextend。

innodb_file_per_table
有三种分配和管理表空间:
1. 原始分区的表空间也就是raw
2. 共享文件表空间
3. 每个表单独的表空间

使用innodb_file_per_table的好处有:
1. 如果使用软链接将大表分配到不同的分区上,易于管理数据文件
2. 易于监控解决IO资源使用的问题
3. 易于修复和恢复损坏的数据
3.1 相互独立的,不会影响其他innodb表
3.2 导出导入只针对单个表,而不是整个共享表空间
4. 解决单个文件大小的限制
5. 对于大量的delete操作,更易于回收磁盘空间
6. 碎片较少,易于整理optimize table
7. 易于安全审计
8. 易于备份

如果在innodb表已创建后设置innodb_file_per_table,那么数据将不会迁移到单独的表空间上,而是续集使用之前的共享表空间。
只有新创建的表才会分离到自己的表空间文件。

innodb_file_per_table是静态变量,更改后要重启mysql服务才能生效。

增加表空间
当没有使用innodb_file_per_table也没有启用自动扩展,那么随着数据的增长,表空间将满了。在这情况下,需要添加额外的表空间来扩展容量。方法如下:
1. 停止mysql服务
2. 备份配置文件,便于出现问题好回退
3. 编辑innodb_data_file_path值
根据你的环境更改ibdata1:$size;ibdataN:$size;…ibdataN:$size; 当前定义的表空间或默认表空间是不能改变的,否则启动失败,但是,可以额外的添加表空间,ibdataN序列根据当前的数量递增,$size自定义。
4. 启动mysql服务
6. 观察mysql错误日志是否有错

如需转载请注明出处:http://www.ttlsa.com/html/2961.html

发布了5 篇原创文章 · 获赞 6 · 访问量 797

猜你喜欢

转载自blog.csdn.net/lgf_201212/article/details/103947752
今日推荐