亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

MySQL常用存儲(chǔ)引擎之Innodb

Soarkey / 528人閱讀

摘要:所以我們?nèi)绻褂孟到y(tǒng)表空間進(jìn)行表數(shù)據(jù)的存儲(chǔ),所面臨的問題是無法很容易的收縮系統(tǒng)文件,造成大量的空間浪費(fèi),并且會(huì)產(chǎn)生大量的磁盤碎片,從而降低了系統(tǒng)性能。

1. mysql 5.5及之后版本默認(rèn)存儲(chǔ)引擎

??為不了解存儲(chǔ)引擎的數(shù)據(jù)庫使用者,提供了很大的便利,因?yàn)閕nnodb適應(yīng)大部分應(yīng)用場(chǎng)景。

??和myisam不同的是,innodb是一種事務(wù)型存儲(chǔ)引擎。也就是說,innodb是支持事務(wù)的acid特性的。innodb的設(shè)計(jì),更適合大量的小事務(wù),而小事務(wù)大部分情況下, 都可以正常提交,很少會(huì)被回滾。

2. innodb使用表空間進(jìn)行數(shù)據(jù)存儲(chǔ) 2.1 關(guān)于innodb_file_per_table參數(shù)

??innodb和mysiam存儲(chǔ)數(shù)據(jù)方式不同,innodb有自己的表空間的概念。表中的數(shù)據(jù)是存儲(chǔ)在表空間之中的,具體存儲(chǔ)在什么樣的表空間中了,則由 innodb_file_per_table 這個(gè)參數(shù)來決定。

ON: 為每個(gè)innodb表建立一個(gè)空間,tablename.ibd(.ibd后綴)

OFF:則會(huì)把數(shù)據(jù)存儲(chǔ)到系統(tǒng)的共享表空間,ibdatax(x代表一個(gè)數(shù)字,從1開始)

3. 系統(tǒng)表空間和獨(dú)立表空間要如何選擇 3.1 比較 3.1.1 系統(tǒng)表空間無法簡(jiǎn)單的收縮文件大小

??在mysql5.6之前的innodb參數(shù)-innodb_file_per_table = OFF (默認(rèn)),也就是數(shù)據(jù)默認(rèn)會(huì)存儲(chǔ)到系統(tǒng)表空間中。

??默認(rèn)的設(shè)置會(huì)遇到下面的問題:在一個(gè)繁忙的系統(tǒng)中,系統(tǒng)表空間不斷的增長(zhǎng)。沒超過我們磁盤限制是可以接受的,但是一旦我們磁盤空間出現(xiàn)不足,我們?yōu)榱酸尫糯疟P空間,不得不在系統(tǒng)中刪除大量無效的數(shù)據(jù)(如:長(zhǎng)期不使用的日志類數(shù)據(jù)等)。我們?cè)趧h除數(shù)據(jù)后,系統(tǒng)表空間并不會(huì)縮小。這種情況下,我們想通過復(fù)制文件的方式,對(duì)數(shù)據(jù)庫進(jìn)行備份。由于雖然刪除了數(shù)據(jù),但表空間大小并不會(huì)改變,這就意味著,我們每次刪除時(shí),都要浪費(fèi)很大的空間。

??你不要以為我們不會(huì)遇到備份的問題,實(shí)際上,目前我們最常用的熱備方式,就是這樣處理的。這時(shí)我們就會(huì)遇到使用系統(tǒng)表空間進(jìn)行存儲(chǔ)的一些問題了。

??想要收縮系統(tǒng)表空間的唯一方法就是把系統(tǒng)表空間的表導(dǎo)出后,刪除innodb的文件后,在重啟mysql服務(wù)器,進(jìn)行表空間的重建,然后在導(dǎo)入數(shù)據(jù)。這個(gè)過程其實(shí)是很復(fù)雜的,并且十分耗時(shí),這在業(yè)務(wù)繁忙的生產(chǎn)環(huán)境中了,顯然是不可能做到的。

??所以我們?nèi)绻褂孟到y(tǒng)表空間進(jìn)行表數(shù)據(jù)的存儲(chǔ),所面臨的問題是無法很容易的收縮系統(tǒng)文件,造成大量的空間浪費(fèi),并且會(huì)產(chǎn)生大量的磁盤碎片,從而降低了系統(tǒng)性能。

3.1.2 獨(dú)立表空間可以通過optimize table命令收縮系統(tǒng)文件

??如果我們使用獨(dú)立表空間, 對(duì)一個(gè)大表的數(shù)據(jù)進(jìn)行清理之后,可以方便的對(duì)這個(gè)表進(jìn)行收縮,使用optimize table命令 ,會(huì)對(duì)表進(jìn)行重建。但是對(duì)比整個(gè)系統(tǒng)進(jìn)行重建要快的多,而且不需要重啟數(shù)據(jù)庫服務(wù)器,甚至不會(huì)影響這個(gè)表的正常訪問。所以從這點(diǎn)來看,使用獨(dú)立的表空間顯然要比使用系統(tǒng)表空間要好得多。

3.1.3 系統(tǒng)表空間會(huì)產(chǎn)生io瓶勁

??對(duì)于系統(tǒng)個(gè)表空來說,由于只有一個(gè)文件。如果同時(shí)對(duì)多個(gè)表進(jìn)行數(shù)據(jù)刷新時(shí),實(shí)際上在文件系統(tǒng)層面上來說是順序進(jìn)行的,所以會(huì)產(chǎn)生一定的io瓶勁。

3.1.4 獨(dú)立表空間可以同時(shí)向多個(gè)文件刷新數(shù)據(jù)

??對(duì)于獨(dú)立表空間來說,由于每個(gè)表都有自己的表空間文件。在進(jìn)行數(shù)據(jù)寫入時(shí),可以利用多個(gè)文件增加io處理的性能。所以對(duì)于平凡寫入操作的系統(tǒng)來說,不太適合使用系統(tǒng)表空間統(tǒng)一存放數(shù)據(jù),而是要使用獨(dú)立表空間的方式。

3.2 建議

??對(duì)使用innodb存儲(chǔ)引擎的表使用獨(dú)立表空間進(jìn)行管理,在mysql5.6后,使用innodb存儲(chǔ)引擎的默認(rèn)表配置就是獨(dú)立存儲(chǔ)空間。

3.3 表轉(zhuǎn)移的步驟
把原來存在于系統(tǒng)表空間中的表轉(zhuǎn)移到獨(dú)立表空間中的方法
3.3.1 使用mysqldump導(dǎo)出所有數(shù)據(jù)庫表數(shù)據(jù)

??如果數(shù)據(jù)庫中使用存儲(chǔ)過程,觸發(fā)器,計(jì)劃事件等,一定要記得一起導(dǎo)出。

3.3.2 停止mysql服務(wù)器,修改參數(shù),并刪除innodb相關(guān)文件

??停止mysql服務(wù),如果是主從架構(gòu)的話,我們可以先從-從服務(wù)器上進(jìn)行這些操作。停止mysql服務(wù)器之后,我們需要修改my.cnf文件,并加入innodb_file_per_table這個(gè)參數(shù),然后手動(dòng)刪除原來innodb系統(tǒng)中的相關(guān)數(shù)據(jù)文件,這時(shí)后系統(tǒng)表空間就不含有任何數(shù)據(jù)了。

3.3.3 重啟mysql服務(wù),重建innodb系統(tǒng)表空間

??實(shí)際上,由于我們之前已經(jīng)備份了所有數(shù)據(jù)表,所以這里可以重建一個(gè)data目錄,并使用mysql install db腳本來重建數(shù)據(jù)庫目錄

3.3.4 重新導(dǎo)入數(shù)據(jù)

??重新導(dǎo)入之前備份的數(shù)據(jù),就可以完成數(shù)據(jù)的恢復(fù),并且把原來存在于系統(tǒng)表空間的數(shù)據(jù)遷移到獨(dú)立表空間中了。

??我們也可不按照上面操作,在修改完系統(tǒng)參數(shù)后,重啟服務(wù)后將需要修改的所有innodb表都執(zhí)行一遍:alter table table_name engine=innodb;.這樣也可以把系統(tǒng)表空間的表遷移到獨(dú)立表空間中,但是卻無法對(duì)系統(tǒng)表空間所占用的空間進(jìn)行回收,所以還是按照上面正規(guī)步驟吧。

3.3.5 轉(zhuǎn)移后系統(tǒng)表空間存儲(chǔ)的內(nèi)容
我們把系統(tǒng)表空間數(shù)據(jù)遷移到獨(dú)立表空間后,那么現(xiàn)在系統(tǒng)表空間還有什么內(nèi)容了?

??答案是雖然我們已經(jīng)把系統(tǒng)表數(shù)據(jù)遷移了出來,但是對(duì)于系統(tǒng)表空間來說,還是有一些很重要的東西要存儲(chǔ)的。這其中之一就是 innodb數(shù)據(jù)字典信息

??數(shù)據(jù)字典是數(shù)據(jù)對(duì)象結(jié)構(gòu)的元數(shù)據(jù)信息,存放與數(shù)據(jù)庫對(duì)象相關(guān)的信息。如:表,列,索引,內(nèi)鍵等內(nèi)容

mysql是使用 .frm文件存儲(chǔ)表結(jié)構(gòu)定義的,那么.frm文件和系統(tǒng)空間中的數(shù)據(jù)字典又有什么區(qū)別了?

??首先,.frm文件是mysql服務(wù)器層產(chǎn)生的文件,可以理解為mysql數(shù)據(jù)庫服務(wù)器層的數(shù)據(jù)字典,這對(duì)mysql所有存儲(chǔ)引擎都是一樣的。mysql數(shù)據(jù)層所保留的東西是與存儲(chǔ)引擎無關(guān)的,而innodb內(nèi)部的數(shù)據(jù)字典是存儲(chǔ)引擎內(nèi)部產(chǎn)生的,并可以保證事務(wù)的一些安全性。另外,innodb存儲(chǔ)引擎沒有直接使用mysql數(shù)據(jù)上的一些類型,而是自己封裝了定義,因此其數(shù)據(jù)字典存儲(chǔ)的都是引擎相關(guān)的內(nèi)容。最后,.frm文件只是簡(jiǎn)單的二進(jìn)制文件,而innodb數(shù)據(jù)字典是通過b樹來進(jìn)行數(shù)據(jù)管理的

除了innodb數(shù)據(jù)字典外,系統(tǒng)表空間還存在undo回滾段和innodb臨時(shí)表

這兩種在mysql5.7都是可以從系統(tǒng)表移除的 了,但還會(huì)有很多人默認(rèn)的把他們存儲(chǔ)在系統(tǒng)表空間中。這里要聲明的是,undo回滾段的存儲(chǔ)在mysql5.6就已經(jīng)支持了。

4. innodb存儲(chǔ)引擎的特性 4.1 innodb是一種事物性存儲(chǔ)引擎

??完全支持事物的acid特性

redo log 和 undo log

redo log實(shí)現(xiàn)事物的持久性,其有兩部分組成

innodb_log_buffer_size:配置redo log緩沖區(qū)的大小,以字節(jié)為單位,程序每隔秒就會(huì)把緩存區(qū)數(shù)據(jù)刷新到磁盤里,所以這個(gè)緩存區(qū)不用配置太大。

innodb_log_files_in_group:決定了數(shù)據(jù)庫目錄下的ib_**的文件數(shù)量

undo log 幫助對(duì)未提交事物進(jìn)行回滾和實(shí)現(xiàn)多版本并發(fā)控制

聯(lián)系

redo log存儲(chǔ)的是已提交的事物,undo log存儲(chǔ)的是未提交的事物。

對(duì)innodb的表進(jìn)行修改時(shí),不僅會(huì)產(chǎn)生redo log 還會(huì)產(chǎn)生 undo log

用戶事物失敗或使用回滾語句,就需要利用undo log中的信息了。

redo log順序?qū)懭?,在?shù)據(jù)庫允許時(shí),不需要對(duì)redo log進(jìn)行讀取操作。undo log 需要進(jìn)行隨機(jī)讀寫的,mysql5.6中的undo log可以獨(dú)立于系統(tǒng)的空間而存在。如果條件允許,我們就可以把undo log存儲(chǔ)到固態(tài)存儲(chǔ)設(shè)備上,這樣可以獲得更好的性能。

4.2 innodb支持行級(jí)鎖

??同myisam支持的表級(jí)鎖是不一樣的,行級(jí)鎖的特點(diǎn)是在進(jìn)行寫操作時(shí),我們所需要鎖定的資源更少,這樣可以支持的并發(fā)就更多。需要注意的是,innodb的行級(jí)鎖是由存儲(chǔ)引擎層實(shí)現(xiàn)的,mysql服務(wù)器完全不了解存儲(chǔ)引擎中鎖的實(shí)現(xiàn)方式。

??說到鎖可能大家還不太了解,數(shù)據(jù)庫中鎖的作用是什么了?因?yàn)殒i對(duì)我們數(shù)據(jù)庫的性能有非常大的影響,所以這里介紹下什么是鎖。

??可能很多開發(fā)人員會(huì)問,經(jīng)常聽到dba說的各種各樣的鎖,比如說行級(jí)鎖,表級(jí)鎖,共享鎖,獨(dú)斷鎖等等。這些鎖的作用是啥了?

4.2.1 什么是鎖?

??鎖是數(shù)據(jù)庫系統(tǒng)區(qū)別于文件系統(tǒng)的重要特性鎖的主要作用是管理共享資源的并發(fā)訪問。并發(fā)訪問是一個(gè)很讓人頭疼的事情啊,對(duì)于任何一個(gè)在竄行環(huán)境下工作良好的系統(tǒng),一旦涉及到并發(fā)的情況就有可能出現(xiàn)各種各樣的問題。
??比如說郵件系統(tǒng),在一個(gè)郵箱中,所有的郵件都是竄行的疊在一起的,彼此首尾相連。這種結(jié)構(gòu)對(duì)于讀取和投遞郵件都是有很大的好處的。當(dāng)有新的郵件到來時(shí),只要插入文件末尾就可以了。當(dāng)有兩個(gè)用戶,同時(shí)對(duì)郵箱進(jìn)行郵件投遞,那會(huì)出現(xiàn)什么樣的情況了?很有可能郵箱的數(shù)據(jù)會(huì)被破壞,兩封性的內(nèi)容會(huì)交叉在一起。當(dāng)然了,這可能和我們平常生活的感受有很大的不同。那是因?yàn)楝F(xiàn)在的郵箱系統(tǒng)都是利用了鎖進(jìn)行了控制。鎖保證了一個(gè)用戶向郵箱投遞郵件時(shí),另一個(gè)用戶會(huì)阻塞,無法向相同的文件末尾寫入文件。
??那么鎖的另一個(gè)作用就是實(shí)現(xiàn)事務(wù)的隔離性。前面提到過,我們通過redo log 和 undo log 實(shí)現(xiàn)了事務(wù)的原子性,一致性和持久性,而隔離性就需要鎖來實(shí)現(xiàn)。對(duì)于未提交的事務(wù)鎖定的數(shù)據(jù)是無法被其他事務(wù)查詢到的。

4.2.2 鎖的常見分類
了解了什么是鎖,及鎖的作用后,我們來看看鎖的常見分類。

共享鎖(也稱讀鎖):可以看出讀鎖是共享的,不會(huì)被阻塞的, 多個(gè)線程可以在同一時(shí)間讀取同一資源,而不相互干擾。
獨(dú)占鎖(也稱寫鎖):寫鎖是獨(dú)占的,是排它的,會(huì)阻塞其他的寫鎖和讀鎖。這是對(duì)數(shù)據(jù)完整性的考慮,只有這樣才能保證在給定的時(shí)間里,只有一個(gè)線程可以執(zhí)行寫入,并防止其他用戶正在讀取寫入的資源,也就是我們前面說的事務(wù)的隔離性。
??對(duì)于innodb來說,讀鎖和寫鎖都是行鎖。兼容性指的是對(duì)同一行記錄可見兼容的情況

??按照上面介紹,對(duì)于同一資源的請(qǐng)求應(yīng)該是互斥的,但是實(shí)際體驗(yàn)并不和以上相同。(鎖比上面提到的復(fù)雜多了)

初始化數(shù)據(jù)庫中數(shù)據(jù)

測(cè)試,兩個(gè)連接啟動(dòng)一個(gè)事務(wù)。一個(gè)連接給表的第一行記錄加個(gè)獨(dú)占鎖,不提交事務(wù)

另一個(gè)連接獲取加了獨(dú)占鎖的數(shù)據(jù),仍然可以獲取到

這和我們介紹的兼容性情況完全不同,這是為什么了?

??這就是innodb在實(shí)現(xiàn)鎖上的獨(dú)到之處,這里innodb用到了我們上面提到的undo log中的記錄,所以我們?cè)诘诙€(gè)連接中查看的數(shù)據(jù)實(shí)際上是存儲(chǔ)在undo log中的版本。也就是說,并不是我們?cè)诘谝粋€(gè)連接中進(jìn)行更新的。

4.2.3 鎖的粒度

??鎖的粒度就是鎖的策略,指被加鎖資源的最小單位。比如在行上加鎖,那么最小單位就是行,這鎖就稱為行級(jí)鎖。如果說的最小單位是列,那就稱為鎖的列級(jí)鎖。同理,如果鎖的最小單位是表的話,那么鎖的最小單位就是表級(jí)鎖。

表級(jí)鎖:mysql中最基本的表策略,開銷最小的策略,并發(fā)性低。表鎖會(huì)在加鎖時(shí)鎖定整張表,一個(gè)用戶在對(duì)表進(jìn)行寫操作前,需要先獲得寫鎖。這會(huì)阻塞其他用戶的讀寫操作,只有沒有寫鎖時(shí),其他用戶才可以獲取讀鎖,讀鎖之前說了是相互間不會(huì)阻塞的。表級(jí)鎖通常是在mysql服務(wù)器層實(shí)現(xiàn)的,所以雖然innodb實(shí)現(xiàn)了行級(jí)鎖,但是在一些時(shí)候,mysql數(shù)據(jù)服務(wù)層還是會(huì)對(duì)innodb表加上表級(jí)鎖。

實(shí)驗(yàn)使用兩個(gè)連接,一個(gè)連接加表級(jí)獨(dú)占鎖

第二個(gè)連接從表獲取數(shù)據(jù)

第一個(gè)連接執(zhí)行解鎖操作,第二個(gè)連接就會(huì)被執(zhí)行

行級(jí)鎖:可以最大程度的支持并發(fā)處理,同時(shí)鎖的開銷比表級(jí)鎖要大。目前innodb和其他的存儲(chǔ)引擎中實(shí)現(xiàn)了行級(jí)鎖,行級(jí)鎖只在存儲(chǔ)引擎中進(jìn)行實(shí)現(xiàn),而mysql服務(wù)層并沒有實(shí)現(xiàn)。

4.2.4 阻塞和死鎖

什么是阻塞:阻塞是不同鎖之間兼容性的關(guān)系。在有些時(shí)刻,一個(gè)事務(wù)中的鎖需要等待另一事務(wù)中的鎖釋放它所占用的資源,這就形成了阻塞。阻塞是為了確保事務(wù)可以并發(fā)且正常的運(yùn)行, 但是,當(dāng)一個(gè)系統(tǒng)中如果出現(xiàn)了大量的阻塞,往往就意味著系統(tǒng)中存在著問題。也許是在一個(gè)被頻繁更新的表上出現(xiàn)了慢查詢或是由于其他的管理操作,如表備份等。對(duì)一個(gè)頻繁訪問的資源加上了排他鎖,過多的阻塞不是個(gè)好的現(xiàn)象,使數(shù)據(jù)庫中的連接大量的堆積,占用大量的系統(tǒng)資源,使得系統(tǒng)的總體性能下降。

什么是死鎖:死鎖是指兩個(gè)或兩個(gè)以上的事務(wù),在執(zhí)行過程中相互占用了對(duì)方等待的資源 ,而產(chǎn)生的一種異常。處在阻塞中的事務(wù)占有被阻塞事務(wù)的多個(gè)資源,而死鎖是產(chǎn)生事務(wù)的多個(gè)事務(wù)之間相互占用對(duì)方等待的資源,這就是阻塞和死鎖最大的不同之處。另外一點(diǎn)不同是,死鎖數(shù)據(jù)庫系統(tǒng)會(huì)自動(dòng)發(fā)現(xiàn),并且在多個(gè)資源占用的事務(wù)中,選擇一個(gè)資源占用最少的事務(wù)來進(jìn)行回滾操作。這樣就可以使其他事務(wù)正常的運(yùn)行了,所以說死鎖是可以由系統(tǒng)自動(dòng)處理的。如果只是有少量的死鎖,并不會(huì)對(duì)系統(tǒng)造成什么影響。只要在應(yīng)用程序中,發(fā)現(xiàn)死鎖,并進(jìn)行重新處理就可以了。但是,如果一個(gè)系統(tǒng)中頻繁的出現(xiàn)大量的死鎖,這時(shí)就需要留意了。通常情況下,死鎖可以通過在多個(gè)事務(wù)中按相同的順序訪問所需要的資源來解決,也可通過增加相關(guān)的索引來解決。

innodb狀態(tài)檢查

show engine innodb status 這命令的用法百度

5. innodb適用場(chǎng)景

??innodb適合于大多數(shù)OLTP應(yīng)用。無論是否需要事務(wù)支持,只要是不使用innodb所不支持的特殊的功能的話,我們都應(yīng)該在新的系統(tǒng)中使用innodb存儲(chǔ)引擎。其中所說的特殊功能可能就包括之前介紹myisam功能中對(duì)于空間應(yīng)用和全文索引這些應(yīng)用。由于在mysql5.7之前,只支持myisam存儲(chǔ)引擎,所以如果我們要使用mysql來存儲(chǔ)這類應(yīng)用數(shù)據(jù)的話,可能就只能選擇myisam存儲(chǔ)引擎了??墒沁@種情況在mysql5.7之后有了改變,innodb支持全文索引和空間函數(shù)了。 所以對(duì)于這類應(yīng)用,我們也可以完全使用innodb存儲(chǔ)引擎來進(jìn)行存儲(chǔ)了。innodb和myisam是mysql最常用的兩種存儲(chǔ)引擎,還有一些引擎會(huì)使用到,請(qǐng)聽下回分解。

相關(guān)文章

InnoDB 引擎獨(dú)立表空間 innodb_file_per_table
MySQL Server參數(shù)優(yōu)化 - innodb_file_per_table(獨(dú)立表空間)
show engine innodb status解讀
死鎖和阻塞的關(guān)系

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/28959.html

相關(guān)文章

  • 可能是全網(wǎng)最好的MySQL重要知識(shí)點(diǎn)/面試題總結(jié)

    摘要:并發(fā)雖然是必須的,但可能會(huì)導(dǎo)致以下的問題。事務(wù)隔離級(jí)別有哪些的默認(rèn)隔離級(jí)別是標(biāo)準(zhǔn)定義了四個(gè)隔離級(jí)別讀取未提交最低的隔離級(jí)別,允許讀取尚未提交的數(shù)據(jù)變更,可能會(huì)導(dǎo)致臟讀幻讀或不可重復(fù)讀??纱谢罡叩母綦x級(jí)別,完全服從的隔離級(jí)別。 標(biāo)題有點(diǎn)標(biāo)題黨的意思,看了文章之后希望大家不會(huì)有這個(gè)想法,絕對(duì)干貨?。。∵@篇花文章是我花了幾天時(shí)間對(duì)之前總結(jié)的MySQL知識(shí)點(diǎn)做了完善后的產(chǎn)物,這篇文章可以用...

    chaos_G 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<