教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

Innodb和MySIAM在存儲(chǔ)方式上有什么區(qū)別?

更新時(shí)間:2018年11月16日15時(shí)07分 來(lái)源:傳智播客 瀏覽次數(shù):

1.MySQL5.5.8之后版本默認(rèn)Innodb存儲(chǔ)引擎

2.Innodb使用表空間進(jìn)行 數(shù)據(jù)存儲(chǔ)
    a.Innodb是支持事物的存儲(chǔ)引擎,也就是說(shuō)支持ACID特性的,適合處理更多的小事物,小事物也就是正常的提交,很少回滾;          
    b. Innodb和MySIAM在存儲(chǔ)方式上也有很大的區(qū)別,Innodb有自己的表空間的概念,表中的數(shù)據(jù)是存儲(chǔ)在表空間之中的,具體存儲(chǔ)在什么樣的表空間中呢?是由innodb_file_per_table這個(gè)參數(shù)決定的,如果這個(gè)參數(shù)為ON:獨(dú)立表空間,存儲(chǔ)的表名為(表名.ibd),如果參數(shù)為OFF:系統(tǒng)表空間(系統(tǒng)的共享表空間),存儲(chǔ)的表名為(ibdataX(X為數(shù)字)))      
       命令:show variables like 'innodb_file_per_table';           
       查看mysql數(shù)據(jù)庫(kù)的存放位置: show global variables like "%datadir%";
       接下來(lái)我們創(chuàng)建一個(gè)表來(lái)看一下
            create  table myinnodb(id int,c1 varchar(100)) engine='innodb';                   

            看一下文件系統(tǒng)是如何存儲(chǔ)的,進(jìn)入到數(shù)據(jù)庫(kù)存放的位置,ls -lh myinnodb*                   
            可以看到有myinnodb.frm和myinnodb.ibd兩個(gè)文件,frm文件時(shí)記錄表結(jié)構(gòu)的,ibd就是innodb表實(shí)際存儲(chǔ)的位置           
            接著把innodb_file_per_table參數(shù)設(shè)置為off,命令為set global innodb_file_per_table=off;                   
            show variables like 'innodb_file_per_table'; 用這個(gè)命令檢查是否關(guān)閉了                  
            再創(chuàng)建一個(gè)表:create  table myinnodb_g(id int,c1 varchar(100)) engine='innodb';                   
           查看存儲(chǔ)的位置,可以看到只有一個(gè)myinnodb_g.frm的文件,不存在ibd文件,也就是說(shuō)它的數(shù)據(jù)存儲(chǔ)在系統(tǒng)共享表的空間 存儲(chǔ)在ibdata1中
3.系統(tǒng)表空間和獨(dú)立表空間要如何選擇?
           首先看一下系統(tǒng)文件對(duì)表空間的管理方式      
           在mysql5.6之前的Innodb的innodb_file_per_table參數(shù)默認(rèn)值設(shè)置是off,也就是說(shuō)在mysql5.5版本的時(shí)候,所使用的innodb表的數(shù)據(jù)都存儲(chǔ)在系統(tǒng)共享表空間的,如果有人覺(jué)得使用這個(gè)是最合適的話呢,那么他可能遇到下面的情況,在系統(tǒng)繁忙中,他會(huì)發(fā)現(xiàn)系統(tǒng)表空間在不斷的增長(zhǎng),本來(lái)呢,這個(gè)也沒(méi)有什么問(wèn)題,只要沒(méi)有超過(guò)磁盤你的限制是可以接受的,但是一旦我們的磁盤空間出現(xiàn)不足,我們?yōu)榱酸尫糯疟P空間,不得不需要在系統(tǒng)中刪除大量的、無(wú)效的數(shù)據(jù)或者是一些長(zhǎng)期不會(huì)使用的數(shù)據(jù),比如像日志類的數(shù)據(jù),我們?cè)趧h除之后,系統(tǒng)表空間并不會(huì)減小,另外我們?cè)谶@種情況下想通過(guò)復(fù)制日志文件的方式對(duì)數(shù)據(jù)庫(kù)進(jìn)行備份,由于雖然刪除了數(shù)據(jù),表空間的大小也不會(huì)改變,這就意味著我們?cè)诿看蝿h除時(shí)都要浪費(fèi)很大的空間,不要以為我么不會(huì)遇到這種問(wèn)題,實(shí)際上我們目前是使用的innodb的熱備方式就是這樣處理的,因?yàn)檫@時(shí)候我們遇到了用到了使用系統(tǒng)表空間進(jìn)行數(shù)據(jù)的存儲(chǔ)的問(wèn)題;而想要收縮系統(tǒng)表空間的唯一方式,就是把整個(gè)數(shù)據(jù)庫(kù)所有Innodb表導(dǎo)出后,刪除Innodb表相關(guān)的文件后,重啟mysql服務(wù)器,進(jìn)行表空間的重建,然后再導(dǎo)入數(shù)據(jù),這個(gè)過(guò)程其實(shí)是很復(fù)雜的,并且十分耗時(shí),在業(yè)務(wù)繁忙的生成環(huán)境中呢,顯然是不可能做到的,使用系統(tǒng)表空間存儲(chǔ)文件很顯然的問(wèn)題就是無(wú)法簡(jiǎn)單的收縮文件大小,造成大量的課件浪費(fèi),會(huì)產(chǎn)生大量的磁盤碎片,從而降低系統(tǒng)的性能              如果我們使用獨(dú)立表空間的話上面的問(wèn)題就很好解決了,我們?nèi)绻麑?duì)一個(gè)大表的數(shù)據(jù)進(jìn)行清理之后,可以很方便的只對(duì)這一個(gè)表進(jìn)行optimize table操作,這樣的話也會(huì)對(duì)這個(gè)表進(jìn)行重建,但是對(duì)比對(duì)整個(gè)系統(tǒng)文件進(jìn)行重建的話要快的多,而且不需要重啟數(shù)據(jù)庫(kù)服務(wù)器,甚至不會(huì)影響正常訪問(wèn),從這點(diǎn)來(lái)看,顯然使用獨(dú)立表空間比使用系統(tǒng)表空間方便      再來(lái)看一下使用系統(tǒng)表空間和獨(dú)立表空間對(duì)IO產(chǎn)生的影響      對(duì)于系統(tǒng)表空間來(lái)說(shuō)呢,由于只有一個(gè)文件,如果同時(shí)對(duì)一個(gè)數(shù)據(jù)表空間進(jìn)行刷新時(shí),實(shí)際上在文件系統(tǒng)層面上來(lái)說(shuō),是按照順序進(jìn)行的,會(huì)產(chǎn)生IO瓶頸      對(duì)于獨(dú)立表空間來(lái)說(shuō)呢,由于每一個(gè)表都有自己的獨(dú)立表空間文件,自己在數(shù)據(jù)寫入時(shí),可以利用多個(gè)文件增加對(duì)IO處理的性能,所以對(duì)頻繁寫入來(lái)說(shuō)不太適合系統(tǒng)表空間統(tǒng)一存放數(shù)據(jù),而是要使用獨(dú)立表空間的方式      我強(qiáng)烈建議大量使用Innodb引擎時(shí)候,使用獨(dú)立表空間來(lái)進(jìn)行管理      在mysql5.6版本之后,獨(dú)立表空間也成為了默認(rèn)的配置     
          如果是5.6之前的版本想轉(zhuǎn)換位獨(dú)立表空間需要進(jìn)行如下的步驟:     
                 1.使用mysqldump導(dǎo)出所有數(shù)據(jù)庫(kù)表數(shù)據(jù)  (注意:數(shù)據(jù)庫(kù)使用的是存儲(chǔ)過(guò)程、觸發(fā)器、計(jì)劃事件等一定要記得一起導(dǎo)出)       
                 2.停止Mysql服務(wù),修改參數(shù)(在mysql的配置文件中加入innodb_file_per_table=on),并刪除相關(guān)的Innodb相關(guān)文件       
                 3.重啟Mysql服務(wù),重建Innodb系統(tǒng)表空間        
                 4.重新導(dǎo)入備份的數(shù)據(jù)
      

         我們系統(tǒng)表空間的數(shù)據(jù)遷移到獨(dú)立表空間后,現(xiàn)在的系統(tǒng)表空間還會(huì)有什么內(nèi)容呢?        
               雖然我們已經(jīng)把表的數(shù)據(jù)從系統(tǒng)表空間中遷移到了獨(dú)立表空間,但是在系統(tǒng)表空間中還是有一部分很重要的東西要存儲(chǔ)的        
               其中之就是Innodb數(shù)據(jù)字典,數(shù)據(jù)字典是數(shù)據(jù)庫(kù)結(jié)構(gòu)對(duì)象的元數(shù)據(jù)的信息,它存放一些與數(shù)據(jù)庫(kù)對(duì)象相關(guān)的一些信息,如表、列、索引、外鍵等,細(xì)心的同學(xué)已經(jīng)發(fā)現(xiàn)了,Mysql數(shù)據(jù)庫(kù)是使用frm文件來(lái)存儲(chǔ)表結(jié)構(gòu)的定義的,那么frm文件與系統(tǒng)表空間中存放的數(shù)據(jù)字典有什么區(qū)別呢?首先f(wàn)rm文件是mysql數(shù)據(jù)庫(kù)服務(wù)器層產(chǎn)生的文件,可以理解為mysql數(shù)據(jù)庫(kù)服務(wù)器層的數(shù)據(jù)字典,對(duì)于mysql所有的存儲(chǔ)引擎是一樣的;在mysql服務(wù)器層保存的多線程是與存儲(chǔ)引擎無(wú)關(guān)的Innodb內(nèi)存產(chǎn)生的數(shù)據(jù)字典,是innodb內(nèi)部產(chǎn)生的,并可以保證一些事物的安全性,另外,innodb存儲(chǔ)引擎沒(méi)有使用mysql數(shù)據(jù)庫(kù)上傳的類型,而是自己封裝了一些自定義,數(shù)據(jù)字典都是存儲(chǔ)了一些innodb相關(guān)的一些內(nèi)容,frm文件只是一個(gè)簡(jiǎn)單的二進(jìn)制文件,而innodb數(shù)據(jù)字典是通過(guò)計(jì)數(shù)來(lái)進(jìn)行數(shù)據(jù)管理的;         還有Undo 回滾段和innodb臨時(shí)表,這兩種數(shù)據(jù)呢,在mysql5.7的時(shí)候呢,都是從系統(tǒng)表空間中移出了,但是還是有很多的默認(rèn)存儲(chǔ)在系統(tǒng)表空間中,對(duì)于Undo 段在mysql5.6的時(shí)候就支持了

4.Innodb存儲(chǔ)引擎的特性
        1.Innodb是一種事物性存儲(chǔ)引擎            
             a.完全支持事物的ACID特性(原子性、一致性、隔離性和持久性)               
                   Innodb是如何實(shí)現(xiàn)ACID的特性?                 
                   能夠?qū)崿F(xiàn)原子性、一致性和持久性,Innodb使用了兩個(gè)特殊的日志類型,Redo Log(實(shí)現(xiàn)事物的持久性,由兩部分組成,重做日志緩沖區(qū)---->innodb_log_buffer_size)和Undo Log()            
             b.Innodb支持的是行級(jí)鎖                
                  行級(jí)鎖的特點(diǎn):                   
                        在進(jìn)行寫操作時(shí),需要鎖定的資源更少,支持的并發(fā)就會(huì)更多                     
                        innodb行級(jí)鎖是由存儲(chǔ)引擎層實(shí)現(xiàn)的                 
                  什么是鎖,鎖的作用是什么呢?                      
                        答:鎖是數(shù)據(jù)庫(kù)系統(tǒng)區(qū)別于文件系統(tǒng)的重要特性,鎖的主要作用是管理共享資源的并發(fā)訪問(wèn),并發(fā)訪問(wèn)是一個(gè)很讓人頭疼的問(wèn)題,對(duì)于任何的串行環(huán)境下工作良好的一個(gè)系統(tǒng),一旦出現(xiàn)并發(fā)就會(huì)出現(xiàn)各種各樣的問(wèn)題 ;鎖的另一個(gè)作用就是實(shí)現(xiàn)事物的隔離性                        
                  鎖的類型:   
                        共享鎖(也稱讀鎖):相互不會(huì)被堵塞的,多個(gè)線程可以在同一時(shí)間讀取同一資源,而不相互干擾                           
                        獨(dú)占鎖(也稱為寫鎖): 排他的,一個(gè)寫鎖可以堵塞其他的寫鎖和讀鎖,這是出于數(shù)據(jù)完成性的考慮,只有這樣在改填的時(shí)間里,只有一個(gè)線程執(zhí)行戲?qū)懭耄⒎乐蛊渌脩糇x取正在寫入的同一資源,也就是實(shí)現(xiàn)事物的隔離性                                                             
                        | Item      |  寫鎖      |  讀鎖    |       
                        | :-------- | --------: |    :--:     |
                        | 寫鎖       | 不兼容   |  不兼容 |        
                        | 讀鎖       |  不兼容  | 兼容   |                  
                        寫鎖和其他的鎖都是不兼容的,讀鎖和讀鎖之間是兼容的           
                        需要注意的是:對(duì)于Innodb來(lái)說(shuō),讀鎖和寫鎖都是行鎖,所謂的兼容性就是對(duì)同一行的記錄兼容性的情況                                        
                        什么是阻塞?           
                              阻塞是因?yàn)椴煌i之間的兼容性的關(guān)系,在有些時(shí)刻,一個(gè)事物中的鎖需要等待另一個(gè)事物中鎖的釋放它所占用的資源,形成的阻塞,阻塞是為了確保事物可以并發(fā),且可以正常的運(yùn)行,當(dāng)系統(tǒng)中出現(xiàn)了大量的阻塞,往往系統(tǒng)中就存在著問(wèn)題,也可能是一個(gè)被頻繁更新的表上出現(xiàn)了慢查詢                                                
        2.Innodb狀態(tài)檢查                
              show engine innodb status 包含了一些平均值的統(tǒng)計(jì)信息,平均值是指上次輸出結(jié)果生成的統(tǒng)計(jì)數(shù);兩次輸入的間隔時(shí)間不能少于30秒

作者:傳智播客人工智能+Python培訓(xùn)學(xué)院
首發(fā):http://python.itcast.cn/



0 分享到:
和我們?cè)诰€交談!