15. 其餘存儲引擎php
15.1 設置存儲引擎html
15.2 MyISAM存儲引擎mysql
15.2.1 MyISAM啓動選項linux
15.2.3.1 靜態表特性windows
15.8.2.1 使用CONNECTION建立FEDERATED
15.8.2.2 建立FEDERATED表使用CREATE SERVER
存儲引擎是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. |
當你建立新表,你會指定存儲引擎,在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文件用來保存表和列的定義。表的索引和數據可能被存放在其餘一個或者多個文件中,根據存儲引擎決定。
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.能夠把數據文件目錄和索引文件目錄放在不一樣的目錄上,在create table的時候指定data directory和index directory。
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約束
具體看:http://dev.mysql.com/doc/refman/5.7/en/myisam-start.html
MyISAM表使用B樹索引。你初略的計算index文件的大小,(key_length+4)*0.67,覆蓋全部key。不壓縮的key評估的大小。
String索引空間能夠被壓縮。若是索引的第一個部分是string,也會使用前綴壓縮。索引壓縮會讓索引文件變小。
在MyISAM表你能夠前綴壓縮個數經過PACK_KEYS=1來指定,在建立表的時候。個數表明錢幾個字節。
靜態表也就是固定行長度的表。沒有可變長字段。每一個行使用固定長度字節。
靜態格式是最簡單,醉漢全的模式。也是最快的,由於能夠快速的定位到某一行。經過行號乘以行的長度。
若是電腦crash可是mysql還在運行。Myisamchk能夠簡單的發現那個是行的開始和結束,因此一般能夠所有回收上除非被部分寫入。
靜態表的一些特性:
1.char和varchar使用空白填充。Binary和varbinary使用0x00填充。
2.快速
3.cache簡單
4.crash重構很簡單,由於行位置是固定的。
5.不須要重組除非刪除了大量的行須要歸還空間給OS。
6.空間比動態表消耗的多。
動態表是表中包含了可變長的列,或者表使用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 numeric columns)
+ (length of strings)
+ (number of NULL columns + 7) / 8
可使用myisamchk –ed查看鏈接碎片的鏈接,這些鏈接能夠經過optimize table或者myisamchk –r移除。
標錯存儲米歐式是隻讀的,使用myisampack工具生成。亞水錶可使用myisampack解壓。
壓縮表有如下特性:
1.壓縮表空間佔用少。
2.每行獨立的被壓縮,行頭被壓縮成1到3個字節,根據表中的最大行來決定。每一個列壓縮也不一樣。壓縮類型:
a.後綴壓縮
b.前綴壓縮
c.數值列使用bit來代替0
d.若是int型,使用最小的長度來存儲值。好比bigint的列,若是值在-128到127 可使用smallint。
e.若是表只有不多的值,表類型就會被轉爲ENUM。
f.列可使用不少上面組合的壓縮類型。
3.能夠是靜態表或者動態表。
出現如下狀況MyISAM表就有可能被損壞:
1.mysqld在寫入時被kill
2.異常的電腦關閉。
3.硬件錯誤。
3.使用外部程序好比myisamchk來修改表,可是服務也同時在修改。
4.軟件bug,多是mysql的或者是MyISAM的
一般表損壞的症狀:
1.可能會在select數據的時候出現如下錯誤。
Incorrect key file for table: '...'. Try to repair it
2.查詢沒有完成,返回了一個未完成錯誤。
你能夠經過CHECK TABLE檢查MyISAM的表,而且聽過REPAIR TABLE修復損壞的MyISAM表。當服務沒有啓動能夠經過myisamchk來修復和檢查損壞表。
若是表損壞很頻繁,你能夠嘗試肯定爲何會出現。最重要的損壞是服務crash。你能夠經過error log的restarted mysqld信息來驗證,是否頻繁crash。若是不是crash那麼就有多是bug。
每一個MyISAM表包含索引文件,上面有個計數器用來檢查表是否被正確關閉。若是在check table或者myisamchk的時候有如下信息:
clients are using or haven't closed the table 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服務使用了這個表而且一個服務商在執行REPAIR TABLE或者CHECK TABLE,另一份服務在運行。CHECK TABLE是安全的,你能夠衝其餘服務上獲得警告。可是REPAIR TABLE應該避免由於當一個服務覆蓋了數據文件,另一個服務是不知道的。
通常不使用多個服務共享數據文件。
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或者MySQL Cluster。開發想要部署使用了MEMORY的應用程序,高可用或者頻繁更新數據要考慮MySQL Cluster是否是最好的選擇。一般使用MEMORY涉及到如下特性:
1.操做相關的短暫的,非重要數據的管理或者cache。當MySQL服務夯住或者重啓,MEMORY表的數據就會丟失。
2.內存存儲訪問快速,而且延遲低。數據能夠填充到內存不會致使操做系統swap到虛擬內存。
3.只讀或者讀多的數據訪問模式。
MySQL Cluster提供和MEMORY類似的功能提升性能,提供額外的特性MEMORY不支持的:
1.行級鎖而且多線程操做,client減低爭用。
2.可擴展性,甚至語句和寫入混合。
3.數據持久性的後臺操做
4.shared-nothing的結構,多host操做不會有單點錯誤。
5.自動數據分佈,應用程序不須要參與用戶sharding或者分區解決方案。
6.支持可變長字段,MEMORY不支持。
MEMORY性能受限於單線程執行結果和更新的時候表鎖。當實例負荷增長,語句混合了寫入會限制可擴展性。
儘管MEMORY表,可能沒有InnoDB速度快,對於繁忙的系統。特殊狀況下,更新的表級鎖可能會影響其餘線程對MEMORY表的操做。
根據查詢的不一樣,你能夠建立索引,好比默認的hash數據結構,或者b樹結構。
MEMORY存儲引擎都有個相關的磁盤文件,用來保存表定義。表名.frm。
MEMORY表有如下幾個特性:
1.MEMORY表使用小的block,表使用動態hash存儲,沒有一處或者額外的key空間。刪除行把空間放到一個鏈表。當你插入的時候會從新使用。MEMORY表在插入和刪除混合沒有什麼問題。
2.內存表固定長度。可變長度類型好比varchar也以固定長度保存。
3.內存表不能包含BLOB,TEXT裂隙
4.MEMORY支持AUTO_INCREMENT列
5.沒有零食內存表能夠被全部客戶端共享,可其餘臨時表同樣。
建立MEMORY表只要指定ENGINE=MEMORY。表被存放在內存,默認使用hash全部,hash索引可讓單個值更快的被查找,能夠建立零食表。當服務關閉,全部MEMORY中的數據就會丟失。表會一直存在,由於表定義文件是存放在磁盤的。
MEMORY表的由系統變量,max_heap_table_size決定,默認是16MB,強制不一樣的大小,能夠修改這個變量。這個值能夠在CREATE TABLE,ALTER TABLE,TRUNCATE TABLE上被定義。服務重啓也能夠設置MEMORY表的最大大小到max_heap_table_size。
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
MEMORY表內容存儲在內存中,這個是MEMORY表共享內部臨時表的目的。有2種表類型不一樣,MEMORY表的目的不是爲了存數據方便,可是內部臨時表倒是:
1.內部臨時表變的太大,服務自動會轉化爲磁盤表。
2.用戶建立的MEMORY表不會存到磁盤。
爲了MEMORY表,當服務啓動你可使用—init-file。你也可使用INSERT INTO … SELECT或者LOAD DATA INFILE到文件衝持久性表裏面導入數據。
當服務的MEMORY表在shutdown的時候就丟失。若是服務是master,slave不會在乎這些表是否是變空了,因此能夠從slave中看到之前的數據。爲了同步master和slave,當master使用memory表,先使用delete語句刪除全部記錄,這樣slave也會刪除全部記錄。Slave在master重啓和第一次使用表之間仍是會有過時數據。所以爲了不能夠在master上使用—init-file選項。
服務須要有足夠的內存來維護全部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。
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文件。損壞的記錄就會被丟失。
CSV存儲引擎不能定義索引。
分區也不支持。
使用CSV建立的表必需要有not null屬性。若是用了以前的MySQL建立的nullable列能夠繼續使用。
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或者延遲插入被使用。爲了歸檔更好的壓縮,你可使用OPTIMIZE TABLE或者REPAIR TABLE。Show table status能夠查看archive表的行數。
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段的過濾,若是傳輸全部bin log數據傳輸量太大。這個時候可使用假的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 Table Definitions 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;
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 NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> message CHAR(20)) ENGINE=MyISAM;
mysql> CREATE TABLE t2 (
-> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> message CHAR(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 NOT NULL AUTO_INCREMENT,
-> message CHAR(20), INDEX(a))
-> ENGINE=MERGE UNION=(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同樣,類型同樣,語言同樣,檢查index part是否能夠爲null。
若是MERGE不能被打開或者使用由於底層表的問題,CHECK TABLE檢查什麼表的問題。
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上並不慢。
1.直到MySQL 5.1.23 爲止均可以使用非臨時的MyISAM建立臨時MERGE表。
2.若是使用ALTER TABLE來修改MERGE到另一個存儲引擎,底層表消失,底層表的行被複制到alter table表上,使用了指定存儲引擎。
3.INSERT_METHOD表選項表示那個MyISAM表用於MERGE的insert into。若是底層表使用了自增字段,insert into MERGE表不會有反應
4.MERGE表不能維護惟一約束。
5.由於MERGE存儲引擎不能強制惟一性約束,REPLIACE就不可能和預期的同樣運行。主要有2個方面:
a.REPLACE只有在底層表的寫入上才能發現惟一性衝突。
b.若是REPLACE發現惟一性衝突,只能改變寫入的底層表。
6.MERGE表不支持分區。
7.你不能使用ANALYZE TABLE,REPAIR TABLE,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的時候,不能修改union list。
15.不能經過create select建立MERGE表。
16.在一些狀況下不一樣的PACK_KEYS表選項會致使一些想不到的問題。
FEDERATED存儲引擎可讓你訪問遠程數據不須要經過複製或者集羣技術。查詢本地FEDERATED表自動從遠程獲取數據。本地不保存數據。
爲了有FEDERATED存儲引擎,能夠在編譯的時候CMake –DWITH_FEDERATED_STORAGE_ENGINE選項。
FEDERATED存儲引擎默認不啓動,能夠經過-federated選項來啓動。存儲引擎源代碼在storage/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()一次獲取一行。
你可使用如下步驟建立FEDERATED表:
1.在遠程服務商建立表,若是表已經存在,使用show create table獲取語句。
2.在本地建立表定義,添加連接信息到遠程。
建立本地表關聯到遠程,有2個可用的選項。要不建立一個本地表而且制定鏈接字符串,或者使用已經存在的鏈接,經過create server建立的鏈接。
使用第一種方法建立,你必須指定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'
若是你建立一批FEDERATED表,你能夠先使用create server建立,如:
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 |
在使用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 duplicate key 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不支持用戶定義分區。
其餘的資源: http://forums.mysql.com/list.php?105.
EXAMPLE存儲引擎是爲了給開發存儲引擎的使用的例子,略。
具體看:http://dev.mysql.com/doc/refman/5.7/en/storage-engines-other.html
MySQL插件式存儲引擎體系結構,可讓數據庫根據不一樣的程序選擇不一樣的存儲引擎。MySQL服務體系結構隔離了應用程序和DBA對底層存儲的實現細節,提供一致的簡單的程序模型和API。所以儘管不一樣的存儲引擎能力不一樣,這些不一樣對應用程序不可見。
插件式存儲引擎結構提供了標準的服務管理和支持。存儲引擎本身是數據庫服務的組件實現了數據庫底層的數據保存。
有效的和模塊化的體系結構提供了大量的好處,能夠爲程序定製不一樣的存儲。好比數據長褲,事務處理和高可用。
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;
若是被卸載的存儲引擎已經有表存在,那麼這些表就不能被訪問了,可是依然存在在磁盤上。保證在卸載以前已經沒有表使用這個存儲過程了。