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

全國咨詢/投訴熱線:400-618-4000

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

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

1.MySQL5.5.8之后版本默認Innodb存儲引擎

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

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

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

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

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



0 分享到:
和我們在線交談!