MYSQL中InnoDB是什么?
一種表驅(qū)動(dòng),除了innodb還有其它的,例如isam,myisam等.
innodb的特色在于支持并發(fā)與表間引用 MySQL支持多種存儲(chǔ)引擎,用戶可以方便的選用不同的存儲(chǔ)引擎來支持自己的應(yīng)用,每種不同的存儲(chǔ)引擎都有其自己的特性
Innodb是其中的一種存儲(chǔ)引擎,它的特性是支持事務(wù),并且采用多版本并發(fā)控制的方式來提高并發(fā)度主要是事務(wù)表,當(dāng)一個(gè)事務(wù)全部完成,才會(huì)執(zhí)行update.如果一段代碼沒有完成(及一個(gè)事務(wù)操作沒有完成)它是不會(huì)update的,例如:銀行轉(zhuǎn)帳,一筆業(yè)務(wù)沒有完成的時(shí)候,突然的斷電,或是,網(wǎng)絡(luò),系統(tǒng)的原因使你無法完成此交易的話,這個(gè)事務(wù)是要回滾的此交易之前的狀態(tài)的,沒有完成交易,你銀行的money是不會(huì)減少的!缺點(diǎn)是,innoDB的表執(zhí)行起來速度較慢,但是安全!bbs的表要求的是速度,用的都是myisam的表!不知這樣通俗的說,你是否理解?
----------------------------------------------------------------------
翻譯一段MySQL關(guān)于Innodb的物理行結(jié)構(gòu)的官方文檔:
Records in InnoDB ROW_FORMAT=COMPACT tables have the following characteristics:
InnoDB ROW_FORMAT=COMPACT 的表,其中的記錄有如下特點(diǎn):
Each index record contains a five-byte header that may be precededby a variable-length header. The header is used to link togetherconsecutive records, and also in row-level locking.
每個(gè)索引記錄包含一個(gè)五字節(jié)的頭,在它之前還有一個(gè)變長(zhǎng)的頭。這個(gè)頭是用來連接連續(xù)的記錄,也用于行級(jí)鎖。
The record header contains a bit vector for indicating NULL columns.The bit vector occupies (n_nullable+7)/8 bytes. Columns that are NULLwill not occupy other space than the bit in this vector.
記錄頭包含一個(gè)位向量,用來指明空列。位向量占用了(可空的列數(shù)+7)/8字節(jié)。值為空的列不會(huì)再占用此位向量以外的空間。
For each non-NULL variable-length field, the record header containsthe length of the column in one or two bytes. Two bytes will only beneeded if part of the column is stored externally or the maximum lengthexceeds 255 bytes and the actual length exceeds 127 bytes.
對(duì)于每個(gè)非空的變長(zhǎng)字段,記錄頭使用一或兩個(gè)字節(jié)包含了列的長(zhǎng)度。只有如下情況才會(huì)用到兩個(gè)字節(jié):字段的值保存在外部;或者字段的最大長(zhǎng)度走過了255,并且實(shí)際的字段值超過了127字節(jié)。
The record header is followed by the data contents of the columns. Columns that are NULL are omitted.
記錄頭的后面是字段的內(nèi)容,其中空字段被忽略。
Records in the clustered index contain fields for all user-definedcolumns. In addition, there is a six-byte field for the transaction IDand a seven-byte field for the roll pointer.
clustered索引的記錄包含了所有用戶定義的列。此外,還有一個(gè)六字節(jié)的區(qū)域保存事務(wù)ID,一個(gè)七字節(jié)的的區(qū)域保存roll pointer(回滾指針?)
If no primary key was defined for a table, each clustered index record also contains a six-byte row ID field.
如果沒有定義主鍵,每個(gè)clusterd索引也會(huì)包含一個(gè)六字節(jié)的row ID區(qū)域。
Each secondary index record contains also all the fields defined for the clustered index key.
每個(gè)副索引(非clustered索引)也包含所有clustered索引鍵列。
Internally, InnoDB stores fixed-length, fixed-width charactercolumns such as CHAR(10) in a fixed-length format. InnoDB truncatestrailing spaces from VARCHAR columns.
內(nèi)部地,InnoDB用定長(zhǎng)的格式存儲(chǔ)定長(zhǎng)的字符列,如CHAR(10)。InnoDB會(huì)去掉VARCHAR列兩側(cè)的空格。
Internally, InnoDB attempts to store UTF-8 CHAR(n) columns in nbytes by trimming trailing spaces. In ROW_FORMAT=REDUNDANT, such columnsoccupy 3*n bytes. The motivation behind reserving the minimum space nis that it in many cases enables an update of the column to be done inplace without causing fragmentation of the index page.
內(nèi)部地,InooDB嘗試把UTF-8 CHAR(n)列兩側(cè)的空格去掉,使此列只占用n字節(jié)。在ROW_FORMAT=REDUNDANT時(shí),這樣的列要占用3*n字節(jié)。這是為了update該列時(shí)在索引頁(yè)不產(chǎn)生碎片。
---------------------------------------------------------------------
InnoDB性能調(diào)節(jié)提示
·如果Unix的top工具或者Windows任務(wù)管理器顯示,你的數(shù)據(jù)庫(kù)的工作負(fù)荷的CPU使用率小于70%,則你的工作負(fù)荷可能是磁盤綁定的,可能你正生成太多的事務(wù)和提交,或者緩沖池太小。使得緩沖池更大一些會(huì)有幫助的,但不要設(shè)置緩沖池等于或超過物理內(nèi)存的80%.
· 把數(shù)個(gè)修改放在一個(gè)事務(wù)里。如果事務(wù)對(duì)數(shù)據(jù)庫(kù)修改,InnoDB在該事務(wù)提交時(shí)必須刷新日志到磁盤。因?yàn)榇疟P旋轉(zhuǎn)的速度至多167轉(zhuǎn)/秒,如果磁盤沒有騙操作系統(tǒng)的話,這就限制提交的數(shù)目為同樣的每秒167次。
· 如果你可以接受損失一些最近的已提交事務(wù),你可以設(shè)置參數(shù) innodb_flush_log_at_trx_commit 為 0。無論如何InnoDB試著每秒刷新一次日志,盡管刷新不被許可。
· 使用大的日志文件,甚至讓它與緩沖池一樣大。當(dāng)InnoDB寫滿日志文件時(shí),它不得不在一個(gè)檢查點(diǎn)把緩沖池已修改的內(nèi)容寫進(jìn)磁盤。小日志文件導(dǎo)致許多不必要的吸盤寫操作。大日志文件的缺點(diǎn)時(shí)恢復(fù)時(shí)間更長(zhǎng)。
· 也讓日志緩沖相當(dāng)大(與8MB相似的數(shù)量)。
· 如果你存儲(chǔ)變長(zhǎng)字符串,或者列可能包含很多NULL值,則使用VARCHAR列類型而不是CHAR類型。一個(gè)CHAR(N)列總是占據(jù)N個(gè)字節(jié)來存儲(chǔ),即使字符串更短或字符串的值是NULL。越小的表越好地適合緩沖池并且減少磁盤I/O。
當(dāng)使用row_format=compact (MySQL 5.1中默認(rèn)的InnoDB記錄格式)和可變長(zhǎng)度字符集,比如GB2312或sjis,CHAR(N)將占據(jù)可變數(shù)量的空間,至少為N 字節(jié)。
·在一些版本的GNU/Linux和Unix上,用Unix的fsync()(InnoDB默認(rèn)使用的)把文件刷新到磁盤,并且其他相似的方法是驚人的慢。如果你不滿意數(shù)據(jù)庫(kù)的寫性能,你可以試著設(shè)置參數(shù) innodb_flush_method 值為 O_DSYNC,雖然 O_DSYNC在多數(shù)系統(tǒng)上看起來更慢。
· 當(dāng)在Solaris 10上,為x86_64架構(gòu)(AMDOpteron)使用InnoDB存儲(chǔ)引擎,重要的是使用forcedirectio選項(xiàng)來安裝任何為存儲(chǔ)與InnoDB相關(guān)的文件而使用的數(shù)據(jù)系統(tǒng)。(默認(rèn)在Solaris 10/x86_64上不使用這個(gè)文件系統(tǒng)安裝選項(xiàng) )。使用forcedirectio失敗會(huì)導(dǎo)致InnoDB在這個(gè)平臺(tái)上的速度和性能嚴(yán)重下降。
·當(dāng)導(dǎo)入數(shù)據(jù)到InnoDB中之時(shí),請(qǐng)確信MySQL沒有允許autocommit模式,因?yàn)樵试Sautocommit模式會(huì)需要每次插入都要刷新日志到磁盤。要在導(dǎo)入操作規(guī)程中禁止autocommit模式,用SET AUTOCOMMIT和COMMIT語(yǔ)句來包住導(dǎo)入語(yǔ)句:
SET AUTOCOMMIT=0;
/* SQL import statements ... */
COMMIT;
· 如果你使用mysqldump 選項(xiàng)--opt,即使不用SET AUTOCOMMIT和COMMIT語(yǔ)句來包裹,你也使得快速的轉(zhuǎn)儲(chǔ)文件被導(dǎo)入到InnoDB表中。
· 小心大宗插入的大回滾:InnoDB在插入中使用插入緩沖來節(jié)約磁盤I/O,但是在相應(yīng)的回滾中沒有使用這樣的機(jī)制。一個(gè)磁盤綁定的回滾可以用相應(yīng)插入花費(fèi)時(shí)間的30倍來執(zhí)行。殺掉數(shù)據(jù)庫(kù)進(jìn)程沒有是幫助的,因?yàn)榛貪L在服務(wù)器啟動(dòng)時(shí)會(huì)再次啟動(dòng)。除掉一個(gè)失控的回滾的唯一方法是增大緩沖池使得回滾變成CPU綁定且跑得快,或者使用專用步驟,請(qǐng)參閱15.2.8.1節(jié),“強(qiáng)制恢復(fù)”。
· 也要小心其它大的磁盤綁定操作。用 DROP TABLE 或 CREATE TABLE 來清空一個(gè)表,而不是用 DELETE FROM tbl_name。
· 如果你需要插入許多行,則使用多行插入語(yǔ)法來減少客戶端和服務(wù)器之間的通訊開支:
INSERT INTO yourtable VALUES (1,2), (5,5), ...;
這個(gè)提示對(duì)到任何表類型的插入都是合法的,不僅僅是對(duì)InnoDB類型。
· 如果你在第二個(gè)鍵上有UNIQUE約束,你可以在導(dǎo)入會(huì)話中暫時(shí)關(guān)閉唯一性檢查以加速表的導(dǎo)入:
SET UNIQUE_CHECKS=0;
對(duì)于大表,這節(jié)約了大量磁盤I/O,因?yàn)镮nnoDB可以使用它的插入緩沖來在一批內(nèi)寫第二個(gè)索引記錄。
· 如果你對(duì)你的表有FOREIGN KEY約束,你可以在導(dǎo)入會(huì)話過程中通過關(guān)閉外鍵檢查來提速表的導(dǎo)入:
SET FOREIGN_KEY_CHECKS=0;
對(duì)于大表,這可以節(jié)約大量的磁盤I/O。
· 如果你經(jīng)常有對(duì)不經(jīng)常更新的表的重發(fā)查詢,請(qǐng)使用查詢緩存:
[mysqld]
query_cache_type = ON
query_cache_size = 10M