你的位置:首页 > 数据库

[数据库][MySQL Reference Manual]15. 其他存储引擎


15. 其他存储引擎

15. 其他存储引擎... 1

15.1 设置存储引擎... 3

15.2 MyISAM存储引擎... 4

15.2.1 MyISAM启动选项... 5

15.2.2 Key的空间要求... 5

15.2.3 MyISAM表存储格式... 5

15.2.3.1 静态表特性... 5

15.2.3.2 动态表特性... 6

15.2.3.3 压缩表特性... 6

15.2.4 MyISAM表问题... 7

15.2.4.1 MyISAM表损坏... 7

15.2.4.2 表没有被正确关闭... 7

15.3 MEMORY存储引擎... 8

15.3.1 性能特点... 9

15.3.2 MEMORY表的物理特性... 9

15.2.3 MEMORY的DDL操作... 9

15.2.4 索引... 9

15.2.5 用户创建和临时表... 10

15.2.6 导入数据... 10

15.2.7 MEMORY表和复制... 10

15.2.8 管理内存使用... 10

15.3 CSV存储引擎... 11

15.3.1 CSV表的检查和修复... 11

15.3.2 CSV的限制... 11

15.4 ARCHIVE存储引擎... 12

15.5 BLACKHOLE 存储引擎... 13

15.7 MERGE存储引擎... 14

15.7.1 MERGE表的优缺点... 16

15.7.2 MERGE表问题... 16

15.8 FEDERATED存储引擎... 17

15.8.1 FEDERATED存储引擎概述... 17

15.8.2 如何创建FEDERATED表... 18

15.8.2.1 使用CONNECTION创建FEDERATED.. 18

15.8.2.2 创建FEDERATED表使用CREATE SERVER. 19

15.8.3 FEDERATED存储引擎注意点... 20

15.8.4 FEDERATED存储引擎资源... 21

15.9 EXAMPLE存储引擎... 21

15.10 其他存储引擎... 21

15.11 MySQL存储引擎概述... 21

15.11.1 插件是存储引擎结构... 21

 

存储引擎是MySQL组件,用来控制不同表类型的SQL操作。InnoDB是默认而且是最常用的存储引擎,Oracle推荐使用,除非是特别的使用场景。

MySQL Server使用可插入的存储引擎结构可以让正在运行MySQL的存储引擎load,unload。

可以使用SHOW ENGINES语句来决定引擎是不是可以使用。Support字段说明引擎是不是被支持。

MySQL 5.6支持的存储引擎

InnoDB:MySQL 5.6默认的存储引擎。InnoDB是事务安全的存储引擎,有commit,rollback,crash-recovery功能来保护用户数据。InnoDB行级锁和Oracle样式的一致性无锁读,增加多用户并发和性能。InnoDB以聚集索引方式存储用户数据,对主键查询,可以减少IO。InnoDB也支持外键约束。

MyISAM:这些表footprint比较小,表级锁定限制了读写性能,一般用于只读或者读多写少的应用。

Memory:所有的数据都存放在RAM内,能够快速的访问数据。这个引擎就是以前的HEAP引擎。

CSV:这个表实际上是文本文件使用了逗号分隔值。CSV表一般用于导入导出,数据线存放在InnoDB,在需要导入导出的时候转为CSV表。

Archive:这个是紧密的非索引表,用来存储和获取大量数据。

Blackhole:这个引擎其实不保存数据,和linux的/dev/null一样。查询结果都是为空,这些表可以复制,DML语句会传到Slave,但是master不保存数据。

Merge:可以让DBA和开发逻辑的把一些MyISAM表当成一个对象。

Federated:连接到独立的MySQL服务,在这个逻辑数据库上为很多歌物理服务创建对象。

Example:这个是MySQL的例子,如何开始编写新的存储引擎。。

 

以下是不同存储引擎的基本特点:

 

Feature

MyISAM

Memory

InnoDB

Archive

NDB

Storage limits

256TB

RAM

64TB

None

384EB

Transactions

No

No

Yes

No

Yes

Locking granularity

Table

Table

Row

Row

Row

MVCC

No

No

Yes

No

No

Geospatial data type support

Yes

No

Yes

Yes

Yes

Geospatial indexing support

Yes

No

Yes[a]

No

No

B-tree indexes

Yes

Yes

Yes

No

No

T-tree indexes

No

No

No

No

Yes

Hash indexes

No

Yes

No[b]

No

Yes

Full-text search indexes

Yes

No

Yes[c]

No

No

Clustered indexes

No

No

Yes

No

No

Data caches

No

N/A

Yes

No

Yes

Index caches

Yes

N/A

Yes

No

Yes

Compressed data

Yes[d]

No

Yes[e]

Yes

No

Encrypted data[f]

Yes

Yes

Yes

Yes

Yes

Cluster database support

No

No

No

No

Yes

Replication support[g]

Yes

Yes

Yes

Yes

Yes

Foreign key support

No

No

Yes

No

No

Backup / point-in-time recovery[h]

Yes

Yes

Yes

Yes

Yes

Query cache support

Yes

Yes

Yes

Yes

Yes

Update statistics for data dictionary

Yes

Yes

Yes

Yes

Yes

[a] InnoDB support for geospatial indexing is available in MySQL 5.7.5 and higher.

[b] InnoDB utilizes hash indexes internally for its Adaptive Hash Index feature.

[c] InnoDB support for FULLTEXT indexes is available in MySQL 5.6.4 and higher.

[d] Compressed MyISAM tables are supported only when using the compressed row format. Tables using the compressed row format with MyISAM are read only.

[e] Compressed InnoDB tables require the InnoDB Barracuda file format.

[f] Implemented in the server (via encryption functions), rather than in the storage engine.

[g] Implemented in the server, rather than in the storage engine.

[h] Implemented in the server, rather than in the storage engine.

15.1 设置存储引擎

当你创建新表,你会指定存储引擎,在ENGINE选项上。

-- ENGINE=INNODB not needed unless you have set a different
-- default storage engine.
CREATE TABLE t1 (i INT) ENGINE = INNODB;
-- Simple table definitions can be switched from one to another.
CREATE TABLE t2 (i INT) ENGINE = CSV;
CREATE TABLE t3 (i INT) ENGINE = MEMORY;


当你忽略ENGINE选项,就是用默认存储引擎。目前默认存储引擎是InnoDB。你可以 指定默认存储引擎通过—default-storage-engine启动参数,或者配置文件中指定default-storage-engine。也可以在runtime设置使用set命令设置变量:

SET default_storage_engine=NDBCLUSTER;


临时表的存储引擎,通过create temporary table来创建,默认存储引擎通过default_tmp_storage_engine在启动前或者runtime设置。

可以使用alter table语句来转化表的存储引擎

ALTER TABLE t ENGINE = InnoDB;


如果指定的存储引擎没有被编译或者已经编译了但是没有激活,MySQL会使用默认存储引擎来代替。为了防止被魔火,可以启动NO_ENGINE_SUBSTITUTUIN SQL模式。如果指定的引擎不可用,会产生一个错误,而不是一个警告,表不会被创建。

对于新表,frm文件用来保存表和列的定义。表的索引和数据可能被存放在其他一个或者多个文件中,根据存储引擎决定。

15.2 MyISAM存储引擎

MyISAM的基本特性:

Storage limits

256TB

Transactions

No

Locking granularity

Table

MVCC

No

Geospatial data type support

Yes

Geospatial indexing support

Yes

B-tree indexes

Yes

T-tree indexes

No

Hash indexes

No

Full-text search indexes

Yes

Clustered indexes

No

Data caches

No

Index caches

Yes

Compressed data

Yes[a]

Encrypted data[b]

Yes

Cluster database support

No

Replication support[c]

Yes

Foreign key support

No

Backup / point-in-time recovery[d]

Yes

Query cache support

Yes

Update statistics for data dictionary

Yes

每个MyISAM表被存储在3个文件。文件以表名开头,并且有一个扩展名。Frm文件保存了表格式。Myd文件包村了数据文件,myi保存了索引文件。

可以通过mysqlcheck客户端,或者myisamchk工具,来检查和修复myisam表。也可以使用myisampack来压缩myisam表。

MyISAM主要由以下几个特点:

1.所有数据低字节先存。

2.所有数值类型高字节先存。

3.可以支持large files,最大63bit文件长度。

4.MyISAM最大行数2^32^2

5.每个MyISAM表64个索引,每个列最多16个索引

6.最大key为1000个字节。

7.当行被顺序插入,比如使用了auto_increment列,提高空间使用率。

8.支持一个表一个auto_increment列。

9.动态行大小,减少碎片。

10.MyISAM支持并发插入,如果表没有空闲的blocks你可以插入一个新行的同事,其他表读取表。

11.可以把数据文件目录和索引文件目录放在不同的目录上,在createtable的时候指定data directory和indexdirectory。

12.BLOB,TEXT可以被索引。

13.NULL值可以在所有列中

14.每个字符列可以有不同的字符集

15.每个MyISAM的索引文件有个标记表示表是否给关闭。

16.myisamchk标记呗检查过的表,如果使用了update-state选项。如果使用—fast选项不会被标记

17.myisamchk –analyze保存了部分可以的统计信息

18.myisampack可以压缩blob和varchar列

其他支持的特性:

1.支持varchar类型

2.varchar列可能固定或者动态行大小

3.varchar,char的长度最多为64KB。

4.任意长度的unique约束

15.2.1 MyISAM启动选项

具体看:http://dev.mysql.com/doc/refman/5.7/en/myisam-start.html

15.2.2 Key的空间要求

MyISAM表使用B树索引。你初略的计算index文件的大小,(key_length+4)*0.67,覆盖所有key。不压缩的key评估的大小。

String索引空间可以被压缩。如果索引的第一个部分是string,也会使用前缀压缩。索引压缩会让索引文件变小。

在MyISAM表你可以前缀压缩个数通过PACK_KEYS=1来指定,在创建表的时候。个数代表钱几个字节。

15.2.3 MyISAM表存储格式

15.2.3.1 静态表特性

静态表也就是固定行长度的表。没有可变长字段。每个行使用固定长度字节。

静态格式是最简单,醉汉全的模式。也是最快的,因为可以快速的定位到某一行。通过行号乘以行的长度。

如果电脑crash但是mysql还在运行。Myisamchk可以简单的发现那个是行的开始和结束,所以通常可以全部回收上除非被部分写入。

静态表的一些特性:

1.char和varchar使用空白填充。Binary和varbinary使用0x00填充。

2.快速

3.cache简单

4.crash重构很简单,因为行位置是固定的。

5.不需要重组除非删除了大量的行需要归还空间给OS。

6.空间比动态表消耗的多。

15.2.3.2 动态表特性

动态表是表中包含了可变长的列,或者表使用ROW_FORMATE_DYNAMIC创建。

动态格式比静态的有一点复杂,每个行的头都包含了行的长度。行也可以被碎片化。因为没有连续的空间存放。

你可以使用OPTIMIZE_TABLE或者myisamchk–r来整理表的碎片。如果是固定长度的列也包含了可变长的列。那么如果把变长列移动到其他地方那么固定长度的就不需要整理了。

动态格式有以下特性:

1.所有的字符创都是动态的,除非长度超过4

2.每个行前面都有一个bitmap,用来表示那些列时空字符串或者是0。但是不包含为null的值。如果字符串列的长度是0,或者数值型值是0,空间被删除只是在bitmap上面标记。

3.空间比静态的少。

4.每个行只用要求的空间。如果行变大,会分为很多碎片,比如,你更行了一行行变长了,但是变得碎片。

5.和静态表不同,crash之后要重组,因为行是碎片的,可能会丢失。

6.行长度计算公式如下:

3
+ (number of columns + 7) / 8
+ (number of char columns)
+ (packed size of numericcolumns)
+ (length of strings)
+ (number of NULL columns + 7) / 8


可以使用myisamchk –ed查看连接碎片的连接,这些连接可以通过optimizetable或者myisamchk –r移除。

15.2.3.3 压缩表特性

标错存储米欧式是只读的,使用myisampack工具生成。亚水表可以使用myisampack解压。

压缩表有以下特性:

1.压缩表空间占用少。

2.每行独立的被压缩,行头被压缩成1到3个字节,根据表中的最大行来决定。每个列压缩也不同。压缩类型:

       a.后缀压缩

       b.前缀压缩

       c.数值列使用bit来代替0

d.如果int型,使用最小的长度来存储值。比如bigint的列,如果值在-128到127 可以使用smallint。

e.如果表只有很少的值,表类型就会被转为ENUM。

f.列可以使用很多上面组合的压缩类型。

3.可以是静态表或者动态表。

15.2.4 MyISAM表问题

15.2.4.1 MyISAM表损坏

出现以下情况MyISAM表就有可能被损坏:

1.mysqld在写入时被kill

2.异常的电脑关闭。

3.硬件错误。

3.使用外部程序比如myisamchk来修改表,但是服务也同时在修改。

4.软件bug,可能是mysql的或者是MyISAM的

通常表损坏的症状:

1.可能会在select数据的时候出现以下错误。

Incorrect key file for table: '...'. Tryto repair it


2.查询没有完成,返回了一个未完成错误。

你可以通过CHECK TABLE检查MyISAM的表,并且听过REPAIR TABLE修复损坏的MyISAM表。当服务没有启动可以通过myisamchk来修复和检查损坏表。

如果表损坏很频繁,你可以尝试确定为什么会出现。最重要的损坏是服务crash。你可以通过error log的restarted mysqld信息来验证,是否频繁crash。如果不是crash那么就有可能是bug。

15.2.4.2 表没有被正确关闭

每个MyISAM表包含索引文件,上面有个计数器用来检查表是否被正确关闭。如果在checktable或者myisamchk的时候有以下信息:

clients are using or haven't closed thetable properly


这个信息表示表已经损坏,至少要检查该表。

计数器工作如下:

1.第一次表被MySQL更新,计数器自增1

2.在被更新的时候,计数器不变化。

3.当表的最后一个实例被关闭,计数器自减。

4.当你修复表或者检查表并且发现是没问题的,计数器会被重置为0.

5.为了避免问题,和其他操作交互的时候会检查表,如果计数器是0就不会被减。

也就是说,计数器只有在以下条件会变不正确:

1.MyISAM表被复制没有使用LOCK TABLES并且FLUSH TABLES.

2.MySQL在update和最后关闭之前crash。

3.表使用myisamchk –recover或者myisam –update-state和mysqld同时运行。

4.多个mysqld服务使用了这个表并且一个服务商在执行REPAIRTABLE或者CHECK TABLE,另外一份服务在运行。CHECKTABLE是安全的,你可以冲其他服务上得到警告。但是REPAIR TABLE应该避免因为当一个服务覆盖了数据文件,另外一个服务是不知道的。

一般不使用多个服务共享数据文件。

15.3 MEMORY存储引擎

MEMORY存储引擎创建特别目的的表,表内容是存放在内存中的。用户只能用来做临时的工作区或者只读cache。MEMORY存储引擎特性。

Storage limits

RAM

Transactions

No

Locking granularity

Table

MVCC

No

Geospatial data type support

No

Geospatial indexing support

No

B-tree indexes

Yes

T-tree indexes

No

Hash indexes

Yes

Full-text search indexes

No

Clustered indexes

No

Data caches

N/A

Index caches

N/A

Compressed data

No

Encrypted data[a]

Yes

Cluster database support

No

Replication support[b]

Yes

Foreign key support

No

Backup / point-in-time recovery[c]

Yes

Query cache support

Yes

Update statistics for data dictionary

Yes

[a] Implemented in the server (via encryption functions), rather than in the storage engine.

[b] Implemented in the server, rather than in the storage engine.

[c] Implemented in the server, rather than in the storage engine.

 

什么时候使用MEMORY或者MySQLCluster。开发想要部署使用了MEMORY的应用程序,高可用或者频繁更新数据要考虑MySQLCluster是不是最好的选择。通常使用MEMORY涉及到以下特性:

1.操作相关的短暂的,非重要数据的管理或者cache。当MySQL服务夯住或者重启,MEMORY表的数据就会丢失。

2.内存存储访问快速,并且延迟低。数据可以填充到内存不会导致操作系统swap到虚拟内存。

3.只读或者读多的数据访问模式。

MySQL Cluster提供和MEMORY相似的功能提高性能,提供额外的特性MEMORY不支持的:

1.行级锁并且多线程操作,client减低争用。

2.可扩展性,甚至语句和写入混合。

3.数据持久性的后台操作

4.shared-nothing的结构,多host操作不会有单点错误。

5.自动数据分布,应用程序不需要参与用户sharding或者分区解决方案。

6.支持可变长字段,MEMORY不支持。

15.3.1 性能特点

MEMORY性能受限于单线程执行结果和更新的时候表锁。当实例负荷增加,语句混合了写入会限制可扩展性。

尽管MEMORY表,可能没有InnoDB速度快,对于繁忙的系统。特殊情况下,更新的表级锁可能会影响其他线程对MEMORY表的操作。

根据查询的不同,你可以创建索引,比如默认的hash数据结构,或者b树结构。

15.3.2 MEMORY表的物理特性

MEMORY存储引擎都有个相关的磁盘文件,用来保存表定义。表名.frm。

MEMORY表有以下几个特性:

1.MEMORY表使用小的block,表使用动态hash存储,没有一处或者额外的key空间。删除行把空间放到一个链表。当你插入的时候会重新使用。MEMORY表在插入和删除混合没有什么问题。

2.内存表固定长度。可变长度类型比如varchar也以固定长度保存。

3.内存表不能包含BLOB,TEXT裂隙

4.MEMORY支持AUTO_INCREMENT列

5.没有零食内存表可以被所有客户端共享,可其他临时表一样。

15.2.3 MEMORY的DDL操作

创建MEMORY表只要指定ENGINE=MEMORY。表被存放在内存,默认使用hash所有,hash索引可以让单个值更快的被查找,可以创建零食表。当服务关闭,所有MEMORY中的数据就会丢失。表会一直存在,因为表定义文件是存放在磁盘的。

MEMORY表的由系统变量,max_heap_table_size决定,默认是16MB,强制不同的大小,可以修改这个变量。这个值可以在CREATETABLE,ALTER TABLE,TRUNCATE TABLE上被定义。服务重启也可以设置MEMORY表的最大大小到max_heap_table_size。

15.2.4 索引

MEMORY存储引擎支持hash和b树索引。你可以通过using子句来设置:

CREATE TABLE lookup
    (id INT, INDEX USING HASH (id))
    ENGINE = MEMORY;
CREATE TABLE lookup
    (id INT, INDEX USING BTREE (id))
    ENGINE = MEMORY;


MEMORY表最多可以有64个索引,每个索引16个列。最多key长度为3072个字节。

如果MEMORY表hash索引的列包含在很多索引中,yodate表影响字段的值会影响性能。性能影响和被几个索引引用有关。你可以使用b树索引来避免问题。

MEMORY表可以是非唯一的key。

索引列的值可以是null

15.2.5 用户创建和临时表

MEMORY表内容存储在内存中,这个是MEMORY表共享内部临时表的目的。有2种表类型不同,MEMORY表的目的不是为了存数据方便,但是内部临时表却是:

1.内部临时表变的太大,服务自动会转化为磁盘表。

2.用户创建的MEMORY表不会存到磁盘。

15.2.6 导入数据

为了MEMORY表,当服务启动你可以使用—init-file。你也可以使用INSERT INTO … SELECT或者LOADDATA INFILE到文件冲持久性表里面导入数据。

15.2.7 MEMORY表和复制

当服务的MEMORY表在shutdown的时候就丢失。如果服务是master,slave不会在意这些表是不是变空了,所以可以从slave中看到以前的数据。为了同步master和slave,当master使用memory表,先使用delete语句删除所有记录,这样slave也会删除所有记录。Slave在master重启和第一次使用表之间还是会有过期数据。因此为了避免可以在master上使用—init-file选项。

15.2.8 管理内存使用

服务需要有足够的内存来维护所有MEMORY表。

内存并不会因为删除个别的行而使用减少,内存只有在整个表删除的时候才会释放。删除行的内存会被新增的行重用。为了缩放所有的内存你可以执行delete或者truncate table来删除所有的行。或者直接drop table。为了释放删除行的内存,可以通过alter table engine=memory来重建表。

每行的内存使用公式如下:

SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)

+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) *2)

+ ALIGN(length_of_row+1, sizeof(char*))


ALIGN()表示向上取证,因为sizeof(char*) 在32位是4个字节,在64位是8个字节。

Max_heap_table_size表示最大的MEMORY表的大小。在创建表的时候。可以设置session的值,如,以下脚本创建了2个MEMEORY表,一个是1MB一个是2MB。

mysql> SET max_heap_table_size = 1024*1024;

Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;

Query OK, 0 rows affected (0.01 sec)

mysql> SET max_heap_table_size = 1024*1024*2;

Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;

Query OK, 0 rows affected (0.00 sec)


如果服务重启后,2个表都是从全局的max_heap_table_size里面获取最大值。

你也可以在创建MEMORY的表上设置max_rows。

15.4 CSV存储引擎

15.4.1 CSV表的检查和修复

CSV存储引擎支持CHECK,REPAIR语句来检查和修复损坏的CSV表。

当运行CHECK语句,CSV文件会检查字段的分隔符是否正确。发现一个不可用的行就会报错。检查表如下:

mysql> check table csvtest;

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

|Table        | Op    |Msg_type | Msg_text |

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

| test.csvtest | check |status   | OK       |

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

1 row in set (0.00 sec)


如果检查错误,表会被标记为crashed。一旦表被标记为损坏,当你check或者执行select 的时候会自动修复。相关的错误状态和形状带会在运行check的时候被显示:

mysql> check table csvtest;

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

|Table        | Op    |Msg_type |Msg_text                  |

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

| test.csvtest | check | warning  |Table is marked as crashed |

| test.csvtest | check |status   |OK                        |

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

2 rows in set (0.08 sec)


为了修复表可以运行REPAIR,这个副本尽量复制所有存在的数据,并且替换现在的CSV文件。损坏的记录就会被丢失。

15.4.2 CSV的限制

CSV存储引擎不能定义索引。

分区也不支持。

使用CSV创建的表必须要有notnull属性。如果用了之前的MySQL创建的nullable列可以继续使用。

15.5 ARCHIVE存储引擎

ARCHIVE存储引擎是特殊目的的,用来保存大量的非索引数据。

ARCHIVE特性如下:

Storage limits

None

Transactions

No

Locking granularity

Row

MVCC

No

Geospatial data type support

Yes

Geospatial indexing support

No

B-tree indexes

No

T-tree indexes

No

Hash indexes

No

Full-text search indexes

No

Clustered indexes

No

Data caches

No

Index caches

No

Compressed data

Yes

Encrypted data[a]

Yes

Cluster database support

No

Replication support[b]

Yes

Foreign key support

No

Backup / point-in-time recovery[c]

Yes

Query cache support

Yes

Update statistics for data dictionary

Yes

[a] Implemented in the server (via encryption functions), rather than in the storage engine.

[b] Implemented in the server, rather than in the storage engine.

[c] Implemented in the server, rather than in the storage engine.

ARCHIVE存储引擎包含MySQL binary发布中。如果是源代码安装,为了启动ARCHIVE存储引擎,可以使用CMake–DWITH_ARCHIVE_STORAGE_ENGINE选项。

可以在storage/archive查看ARCHIVE源代码。

当创建一个ARCHIVE表,服务创建一个表的定义在数据库目录。文件名为表名.frm。存储引擎创建其他文件,所有的都是以表名开头。数据文件的扩展名是ARZ,ARN文件会在优化操作的时候会出现。

ARCHIVE存储引擎,包括insert,select,但是没有delete,replace,update操作。使用order by排序,BLOB字段和其他所有基础类型但是不能排序spatial数据类型。

ARCHIVE存储引擎自持AUTO_INCREMENT类型属性。自增类型可以是唯一或者不唯一的索引。

试图在其他字段上创建创建索引都会报错。ARCHIVE存储引擎也支持对自增字段在创建表的时候设置初始化值。或者reset已经有的自增字段。

ARCHIVE不支持插入到自增字段小于当前字段最大值。如果尝试,就报键重复错误。

如果不需要BLOB字段在读取的时候会被忽略掉。

存储:行被压缩插入,ARCHIVE存储引擎使用zlib无损压缩方式。你可以使用OPTIMIZE TABLE来分析白哦并且打包到更小的格式。存储引擎也支持CHECK TABLE 。有一些被使用的类型:

1.INSERT语句只是把行存到压缩buffer中,buffer根据需要被刷新。Insert到buffer被锁保护。Select会强制buffer刷新。

2.bulk insert只有在完成后才可见,除非其他插入同时发生,可以部分可见。Select不会导致bulk insert刷新,除非正常的插入也同时发生。

获取:为了获取,行被解压。没有行cache。Select操作在压缩表上扫描:当select发生,查找有多上行会被读取。Select执行读一致性操作。大量在插入的时候有select语句会恶化,除非只有bulk或者延迟插入被使用。为了归档更好的压缩,你可以使用OPTIMIZETABLE或者REPAIR TABLE。Show tablestatus可以查看archive表的行数。

15.6 BLACKHOLE 存储引擎

BLACKHOLE存储引擎就是black hole,接受数据,但是不保存。获取总是为空。

mysql> CREATE TABLE test(i INT, c CHAR(10)) ENGINE = BLACKHOLE;

Query OK, 0 rows affected (0.03 sec)

 

mysql> INSERT INTO test VALUES(1,'record one'),(2,'record two');

Query OK, 2 rows affected (0.00 sec)

Records: 2  Duplicates: 0 Warnings: 0

 

mysql> SELECT * FROM test;

Empty set (0.00 sec)


如果要使用BLACKHOLE存储引擎,在编译源代码的时候,调用CMAKE–DWITH_BLACKHOLE_STORAGE_ENGINE。参数。

为了检查BLACKHOLE的源代码,可以在sql目录先查看发布的源代码。

当你创建BLACKHOLE表,服务创建一个表类型文件。表名.frm没有其他的文件。

BLACKHOLE存储引擎支持所有类型的索引。你可以在表定义的时候包含索引定义。

你可以使用show engine查看BLACKHOLE存储引擎是否可用。

插入到BLACKHOLE表,不保存任何数据,但是binlog会生成,SQL语句会被发送到slave上。

假设你的程序需要slave段的过滤,如果传输所有binlog数据传输量太大。这个时候可以使用假的master host,默认存储引擎是BLACKHOLE,描述如下:

Master写入bin log。假的mysqld进程就是slave,使用根据replicae-do-*,replicate-ignore-*规则写入一个新的过滤的binary log。被过滤的binary log提供给slave。

假进程并不提供任何数据存储,所以进程负荷几乎没有。

BLACKHOLE的INSERT触发器是一个例外,因为BLACKHOLE不保存任何数据,UPDATE和DELETE触发器没有被激活:FOR EACH ROW定义不会起作用因为没有数据。

其他可能使用BLACKHOLE的场景:

1.验证dump文件格式。

2.测量binary log 的负荷,通过使用BLACKHOLE不启动binary log的进行比较。

3.BLACKHOLE本质是no-op存储引擎,所以可以用来查找和存储引擎无关的性能问题。

BLACKHOLE存储引擎是事务的,提交事务被雪茹到binary log并且rollback并不会写入。

Blackhole存储引擎和自增字段

Blackhole是no-op引擎。任何表上的操作都没有响应。引擎并不会自动增加自增字段的值,也不会保留自增字段的状态。

考虑一下复制场景:

1.在master上,有一个blackhole表有一个自增字段并且是主键。

2.slave上有个一样表名的myisam表

3.插入操作执行没有显示的分配自增值。

在这个场景下复制就会报错,重复键错误。

基于语句的复制,自增值在context事件都是一样的。复制会因此报错。基于行的复制,每次插入的值都是一样的。也会报重复键错误。

列过滤

当使用基于行的binlog,slave少了最后一列是被支持的。具体可以看:

Section 17.4.1.10, “Replication with Differing TableDefinitions on Master and Slave”.

过滤工作在slave段,列在过滤之前就被复制到slave。至少有2种情况需要过滤:

1.数据机密,所以slave不能访问。

2.master有很多slave,在发送前过滤可以减少网络负荷。

Master列过滤可以使用BLACKHOLE存储引擎。和master表的过滤类似,使用BLACKHOLE引擎和—replicate-do-table或者—replicate-ignore-table。

Master的部署:

CREATE TABLE t1 (public_col_1, ..., public_col_N,

                secret_col_1, ..., secret_col_M) ENGINE=MyISAM;


信任slave部署:

CREATE TABLE t1 (public_col_1, ...,public_col_N) ENGINE=BLACKHOLE;


不信任slave部署:

CREATE TABLE t1 (public_col_1, ...,public_col_N) ENGINE=MyISAM;


15.7 MERGE存储引擎

MERGE存储引擎也就是MRG_MyISAM存储引擎,可以把一组一致的MyISAM表当成一个表。一致的意思是表结构和索引信息都一样。如果列顺序不同也不行。替代MERGE的方法是使用分区表,把单个表的不同分区存放在不同的文件上。分区可以让一些操作更加高效,不会受MyISAM存储引擎限制。

当你创建了MERGE表,MySQL创建2个文件在磁盘上。.frm和.mrg文件。

你可以使用select,delete,update,insert在MERGE表中。你必须有在MyISAM表上的select,delete,update权限。

使用DROP TABLE,只会删除MERGE设置,并不会影响底层表。

为了创建MERGE你必须指定,UNION操作说明那些MyISAM表被使用。你可以使用INSERT_METHOD选项来控制如何插入到MERGE表。使用FIRST或者LAST来决定插入到第一个表还是最后一个表。如果没有指定INSERT_METHOD或者指定了NO,插入MERGE不被允许操作,会报错。

创建MERGE的例子:

mysql> CREATE TABLE t1 (

   ->    a INT NOTNULL AUTO_INCREMENT PRIMARY KEY,

   ->    messageCHAR(20)) ENGINE=MyISAM;

mysql> CREATE TABLE t2 (

   ->    a INT NOTNULL AUTO_INCREMENT PRIMARY KEY,

   ->    messageCHAR(20)) ENGINE=MyISAM;

mysql> INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');

mysql> INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');

mysql> CREATE TABLE total (

   ->    a INT NOTNULL AUTO_INCREMENT,

   ->    messageCHAR(20), INDEX(a))

   ->    ENGINE=MERGEUNION=(t1,t2) INSERT_METHOD=LAST;


在底层MyISAM表上,指定了主键,但是没有再MERGE表上,因为MERGE不能强制底层表的唯一性。

创建之后,你可以使用查询MERGE表:

重新映射MERGE表的底层表:

1.删除重新创建。

2.使用alter table tbl_name union=(…)来修改。也可以使用alter table tbl_name union()来删除所有底层表。这样表就是空的,插入就会失败,因为没有底层表。

低沉表定义和索引必须和MERGE一直。当表被打开的时候进行一致性检查。如果任意表一致性检查失败,触发打开表的操作就会失败。也就是说当MERGE被访问的时候修改MERGE内表的定义就会导致访问失败。一致性检查会应用到所有表:

1.底层表和MERGE表必须列个数一样

2.底层表和MERGE表列顺序必须一样。

3.列类型必须一致。

4.类长度必须一致

5.列可以为null

6.底层表索引个数至少和MERGE一样多。底层表可以更多但是不能少于MERGE表。

每个索引必须满足一下条件:

1.索引类型必须一样。

2.index part必须一样。

3.对于每个索引,index part一样,类型一样,语言一样,检查indexpart是否可以为null。

如果MERGE不能被打开或者使用因为底层表的问题,CHECKTABLE检查什么表的问题。

15.7.1 MERGE表的优缺点

MERGE表优点:

1.简单管理日志表,比如你可以把不同的月份的数据放在不同的表上,使用myisampacl压缩。然后创建MERGE来使用它们。

2.获取更快的速度。你可以根据一些关键点拆分大的只读表,然后分开的多个表中,并且位于不同的磁盘。MERGE表结构可以比使用单个大表速度更快。

3.执行查询更加高效。如果你准确的知道你要获取什么,你可以在底层表执行查询,然后多其他表使用merge。在一组表上可以有很多个merge。

4.修复更加有效。修复小表比修复单个达标速度更快。

5.及时的把表映射到一个。MERGE表不需要维护所有因为索引属于个别的表。MERGE可以快速的创建或者重新映射。

6.如果有一组表,你先要创建一个大表,现在可以使用MERGE表来代替。

7.可以超过系统限制的文件大小,因为MERGE由多个表组成。

8.你可以创建一个别名,通过映射到MERGE表

MERGE缺点:

1.只能使用MyISAM作为底层表。

2.一些MyISAM表的 特性不可用。比如不能创建全文索引。

3.如果MERGE表不是临时的,所有低沉MyISAM表必须是非临时的。如果MERGE表是临时的,底层表可以是临时的也可以不是临时的。

4.MERGE表比MyISAM的文件描述多。如果10个客户端使用MERGE表映射了10个MyISAM表。服务使用(10*10)+10个文件描述。

5.索引读取很慢。当你读取索引,MERGE存储引擎需要在所有底层表上执行一个读来检查那个最匹配给定的index值。为了读取下一个值,MERGE存储引擎需要查询read buffer来查找下一个值。MERGE索引在eq_ref上很慢,但是在ref上并不慢。

15.7.2 MERGE表问题

1.直到MySQL 5.1.23 为止都可以使用非临时的MyISAM创建临时MERGE表。

2.如果使用ALTER TABLE来修改MERGE到另外一个存储引擎,底层表消失,底层表的行被复制到alter table表上,使用了指定存储引擎。

3.INSERT_METHOD表选项表示那个MyISAM表用于MERGE的insert into。如果底层表使用了自增字段,insertinto MERGE表不会有反应

4.MERGE表不能维护唯一约束。

5.因为MERGE存储引擎不能强制唯一性约束,REPLIACE就不可能和预期的一样运行。主要有2个方面:

       a.REPLACE只有在底层表的写入上才能发现唯一性冲突。

       b.如果REPLACE发现唯一性冲突,只能改变写入的底层表。

6.MERGE表不支持分区。

7.你不能使用ANALYZE TABLE,REPAIRTABLE,OPTIMIZE TABLE,ALTER TABLE,DROP TABLE,DELETE没有where子句的。

8.DROP table在MERGE 表上在windows上不起作用因为MERGE表被映射在底层表上。Windows不允许打开的文件被删除。所以你先要flush 所有merge表。

9.当文芳表的时候会检查MERGE和MyISAM表的定义。

10.MERGE表的索引顺序要和底层表一样。

11.如果发生错误比如Error 1017不能查看文件。通常表示底层表没有使用MyISAM存储引擎。

12.MERGE表最大的行数是2^64,就算映射的表在多也无法比这个行数多。

13.底层MyISAM表和MERGE表不同就会报错。

14.当LOCK tables的时候,不能修改unionlist。

15.不能通过create select创建MERGE表。

16.在一些情况下不同的PACK_KEYS表选项会导致一些想不到的问题。

15.8 FEDERATED存储引擎

FEDERATED存储引擎可以让你访问远程数据不需要通过复制或者集群技术。查询本地FEDERATED表自动从远程获取数据。本地不保存数据。

为了有FEDERATED存储引擎,可以在编译的时候CMake–DWITH_FEDERATED_STORAGE_ENGINE选项。

FEDERATED存储引擎默认不启动,可以通过-federated选项来启动。存储引擎源代码在storage/federated目录下。

15.8.1 FEDERATED存储引擎概述

当你创建表使用了标准的存储引擎(如,MyISAM,CSV,Innodb)表由表定义和相关数据组成。当你创建FEDERATED表,表定义是一样的,但是数据存储是在远程的。

FEDERATED表由以下2个要素组成:

1.远程服务的数据库表,包含了表定义,和相关数据。

2.本地服务的表,表定义和远程服务的要一样。表定义保存在frm文件,但是没有数据文件,只是有一个连接字符串指向远程表。

当在FEDERATED表执行查询和语句,草错可以正常执行,insert,update,delete都会被发送到远程去执行,或者从远程返回行。

FEDERATED结构如下:

当客户端执行SQL语句引用了FEDERATED表,客户端和服务间的信息流如下:

1.存储引擎查看,FEDERATED表相关的每个列,构建合适的SQL发送到远程表。

2.语句通过MySQL Client API发送到远程

3.远程服务处理语句并且本地服务获取语句处理的结果。

4.如果语句生成的结果,每个列都被转化为FEDERATED要的内部存储过程格式。并且结果发送到语句发生的最初地方。

本地服务和远程服务通过MySQL Client API交互使用mysql_real_query()发送语句,mysql_store_result()来获取结果,使用mysql_fetch_row()一次获取一行。

15.8.2 如何创建FEDERATED表

你可以使用以下步骤创建FEDERATED表:

1.在远程服务商创建表,如果表已经存在,使用show createtable获取语句。

2.在本地创建表定义,添加链接信息到远程。

创建本地表关联到远程,有2个可用的选项。要不创建一个本地表并且制定连接字符串,或者使用已经存在的连接,通过createserver创建的连接。

15.8.2.1 使用CONNECTION创建FEDERATED

使用第一种方法创建,你必须指定CONNECTION选项,例如:

CREATE TABLE federated_table (
    id     INT(20) NOT NULL AUTO_INCREMENT,
    name   VARCHAR(32) NOT NULL DEFAULT '',
    other  INT(20) NOT NULL DEFAULT '0',
    PRIMARY KEY  (id),
    INDEX name (name),
    INDEX other_key (other)
)
ENGINE=FEDERATED
DEFAULT CHARSET=latin1
CONNECTION='mysql://fed_user@remote_host:9306/federated/test_table';


CONNECTION字符串包含了连接到远程服务的信息包括存储数据的物理表。连接支付穿指定了服务名,登录凭据,端口,数据库/表名。格式如下:

scheme://user_name[:password]@host_name[:port_num]/db_name/tbl_name


schema:表示可以识别的协议,mysql是唯一支持的协议。

User_name:连接的用户名,用户名必须在remote上被创建,并且有正确的权限。

Password:可选用户名对应的密码

Host_name:远程服务的主机名或者ip地址

Port_num:可选,远程服务的端口

Db_name:数据库名

Tbl_name:远程的表名。

如:

CONNECTION='mysql://username:password@hostname:port/database/tablename'
CONNECTION='mysql://username@hostname/database/tablename'
CONNECTION='mysql://username:password@hostname/database/tablename'


15.8.2.2 创建FEDERATED表使用CREATESERVER

如果你创建一批FEDERATED表,你可以先使用createserver创建,如:

CREATE SERVER server_name
FOREIGN DATA WRAPPER wrapper_name
OPTIONS (option [, option] ...)


如:

CREATE SERVER fedlink
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'fed_user', HOST 'remote_host', PORT 9306, DATABASE 'federated');


创建FEDERATED表的使用,如下:

CREATE TABLE test_table (
    id     INT(20) NOT NULL AUTO_INCREMENT,
    name   VARCHAR(32) NOT NULL DEFAULT '',
    other  INT(20) NOT NULL DEFAULT '0',
    PRIMARY KEY  (id),
    INDEX name (name),
    INDEX other_key (other)
)
ENGINE=FEDERATED
DEFAULT CHARSET=latin1
CONNECTION='fedlink/test_table';


这个CONNECTION中包含了fedlink就是之前创建的server。

Description

CONNECTION string

CREATE SERVER option

mysql.servers column

Connection scheme

scheme

wrapper_name

Wrapper

Remote user

user_name

USER

Username

Remote password

password

PASSWORD

Password

Remote host

host_name

HOST

Host

Remote port

port_num

PORT

Port

Remote database

db_name

DATABASE

Db

15.8.3 FEDERATED存储引擎注意点

在使用FEDERATED的时候要注意:

1.FEDERATED表可能被复制到其他slave,但是你必须保证slave服务的可以使用用户密码访问远程服务,根据connection的定义。

后面是FEDERATED表支持的或不支持的特性:

1.远程服务必须是MySQL

2.远程表在访问前必须存在

3.很有可能一个FEDERATED表指向到另外一个FEDERATED表,但是注意不能创建出一个循环。

4.通常意义上FEDERATED表不支持索引,因为访问表数据是在远程被处理的,司机远程表是使用索引的。也就是说一个查询不能使用任何索引并且要表扫描,服务从远程获取所有记录并且过滤。不管使用了任何where,limit子句,这些子句都是在本地被使用的。

如果使用索引失败,或导致性能问题和网络负荷问题。另外会导致内存短缺。

5.注意当创建FEDERATED表因为和其他表一样的索引定义可能不被支持。比如在varchar,text,blob上创建前缀索引就会失败。

如:

CREATE TABLE `T1`(`A`VARCHAR(100),UNIQUE KEY(`A`(30))) ENGINE=FEDERATED
  CONNECTION='MYSQL://127.0.0.1:3306/TEST/T1';


6.内部实现, select,insert,update,但是没有实现handle

7.FEDERATED存储引擎支持,select,insert,update,delete,truncate table和索引。但是不支持alter table或者任何其他DDL语句除了drop table。

8.FEDERATED使用insert … on duplicatekey update语句,但是如果出现重复键错误,语句错误。

9.FEDERATED表在bulk insert的时候比其他表类型要慢,因为每个查询行都被分为独立的insert,insert到FEDERATED。

10.不支持事务。

11.FEDERATED执行bulk-insert处理多行被批量发送到远程表,性能得到提高并且远程的执行性能提高。如果远程是事务的,可以让远程引擎在错误发生的时候回滚:

       a.行的大小不能超过服务器间的包大小,如果超过,就会被分为多个包。并且回滚就会出错。
       b.bulk insert不支持insert… on duplicate key update。

12.FEDERATED无法知道远程表是不是被修改。因为文件必须和数据文件一样运行不能被其他服务写入。如果任何修改远程数据库本地表的一致性就可能会被破坏。

13.当使用CONNECTION连接的时候,不能在密码中使用@。但是在create server中可以使用。

14.insert_id和timestamp不能传播到data provider上。

15.任何drop table语句在FEDERATED表上只会删除本地表,不会删除远程表。

16.FEDERATED表不能使用query cache。

17.FEDERATED不支持用户定义分区。

15.8.4 FEDERATED存储引擎资源

其他的资源: http://forums.mysql.com/list.php?105.

15.9 EXAMPLE存储引擎

EXAMPLE存储引擎是为了给开发存储引擎的使用的例子,略。

15.10 其他存储引擎

具体看:http://dev.mysql.com/doc/refman/5.7/en/storage-engines-other.html

15.11 MySQL存储引擎概述

MySQL插件式存储引擎体系结构,可以让数据库根据不同的程序选择不同的存储引擎。MySQL服务体系结构隔离了应用程序和DBA对底层存储的实现细节,提供一致的简单的程序模型和API。因此尽管不同的存储引擎能力不同,这些不同对应用程序不可见。

插件式存储引擎结构提供了标准的服务管理和支持。存储引擎自己是数据库服务的组件实现了数据库底层的数据保存。

有效的和模块化的体系结构提供了大量的好处,可以为程序定制不同的存储。比如数据长裤,事务处理和高可用。

15.11.1 插件是存储引擎结构

MySQL服务使用插入是存储引擎结构体系可以让存储引擎加载和卸载。

加载存储引擎:

在存储引擎被使用前,存储引擎的共享library必须被加载到MySQL,使用INSTALL PLUGIN语句。比如:example存储引擎plugin称为example,shard library是ha_example。so.

mysql> INSTALL PLUGIN example SONAME'ha_example.so';


为了能够加载存储引擎,插件文件的路径必须在MySQL plugin目录,并且执行INSTALL PLUGIN用户要有对mysql.plugin表有插入权限。

Shared library目录可以查看plugin_dir。

卸载存储引擎

为了卸载存储引擎可以使用UNINSTALL PLUGIN语句:

mysql> UNINSTALL PLUGIN example;


如果被卸载的存储引擎已经有表存在,那么这些表就不能被访问了,但是依然存在在磁盘上。保证在卸载之前已经没有表使用这个存储过程了。