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

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

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

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

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

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

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

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

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

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



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