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