MySQL与IO
???????? 數據庫作為存儲系統,所有業務訪問數據的操作都會轉化為底層數據庫系統的IO行為(緩存系統也可以當做是key-value的數據庫),本文主要介紹訪問mysql數據庫的IO流程以及IO相關的參數。
一 MySQL 的文件
首先簡單介紹一下MySQL的數據文件,MySQL 數據庫包含如下幾種文件類型:
數據文件 (datafile) 存放表中的具體數據的文件。 數據字典 記錄數據庫中所有innodb表的信息。
重做日志 (redolog) 記錄數據庫變更記錄的文件,用于系統異常crash(掉電)后的恢復操作,可以配置多個比如 ib_logfile0、 ib_logfile1,
回滾日志 (undolog) 也存在于mysql 的ibdata文件,用戶記錄事務的回滾操作。
歸檔日志 (binlog)?事務提交之后,記錄到歸檔日志中。
中繼日志 (relaylog) 從master 獲取到slave 的中轉日志文件,sql_thread 則會應用relay log?
 其他日志?slowlolg,?errorlog,?querylog
? ??對于以上文件的IO訪問順序可以分為順序訪問 比如binlog ,redolog ,relay log是順序讀寫,datafile,ibdata file是隨機讀寫,這些IO訪問的特點決定了在os 配置磁盤信息時候,如何考慮分區 ,比如順序寫可以的log 可以放到SAS 盤 ,隨機讀寫的數據文件可以放到ssd 或者fio 高性能的存儲。
2 寫操作 ? ? 為了保證數據寫入操作的安全性,數據庫系統設置了 undo,redo ?保護機制,避免因為os或者數據庫系統異常導致的數據丟失或者不一致的異常情況發生。 ? ? 以 insert into t values(1,1,'shuiyi');為例 ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖-2 寫操作的 IO 流程 我們假定數據在內存中,不考慮從磁盤中獲取數據的情形。大致的寫操作步驟: ?? 1 先寫undo log? ?? 2 在內存更新數據 ?? 3 記錄變更到redo log,prepare? ?? 4 寫入binlog ?? 5 redo log 第二階段,commit ? ?? 6 返回給client ? 如果有slave ?? 第4步之后 經過slave 服務線程 io_thread 寫到從庫的relay log ,再由sql thread 應用relay log 到從庫中。
關于性能 ???? 寫undo redo log ,binlog的過程中都是順序寫,都會很快的完成,隨機寫操作,inset_buffer 功能 ??? 對于非聚集類索引的插入和更新操作(5.5 版本及以上支持Update/Delete/Purge等操作的buffer功能),不是每一次都直接插入到索引頁中,而是先插入到內存中。具體做法是:如果該索引頁在緩沖池中,直接插入;否則,先將其放入插入緩沖區中,再以一定的頻率和索引頁合并,就可以將同一個索引頁中的多個插入合并到一個IO操作中,改隨機寫為順序寫,大大提高寫性能。 ? 關于數據安全,這是數據庫寫入的重點 ? ?? ???? 1,2,3? 過程失敗 就是事務失敗,因為此時還未寫入磁盤,對磁盤中的數據無影響,返回事務失敗給client,從庫也不會受到影響。 ???? 4,5 過程失敗的時候或者已經將寫成功返回給客戶,可以根據redo log 的記錄來進行恢復,如果出現部分寫失效 請參考《double write》 ???? mysql的寫redo log的第一個階段會把所有需要做的操作做完,記錄數據變更,第二階段的工作比較簡單 ,只做事務提交確認。如果寫入binlog 成功,而第二階段失敗,mysql 啟動時也會將事務進行重做,最終更 新到磁盤中。 ???? 5.5 +的 smei sync?可以更好的保障主從的事務一致性。?? 三 文件訪問方式 ? ? IO 訪問的方式分為兩種順序讀寫和隨機讀寫, 在mysql 的io過程中可以以此來將數據庫文件分類 ? ? ? 順序讀寫: ???? 重做日志? ib_logfile*,binlog file ? ? ? 隨機讀寫? ???? innodb 表數據文件,ibdata文件。 ? 根據系統的訪問類型,對硬件做如下分類 ? 讀多 SSD+RAID ? 寫多 FIO(flashcache) ? 容量密集 fio + flashcache ? 由于隨機io會嚴重降低系統的性能,在當前的硬件水平下,可以考慮選擇獎數據庫服務器配置ssd/fusionio。 ?? 四 影響IO的參數和策略 ? ? 影響mysql io 的參數有很多個,這里羅列幾個重要的參數。? ? ? innodb_buffer_pool_size ??? 該參數控制innodb 緩存大小,用于緩存應用訪問的數據,推薦配置為系統可用內存的80%。 ??? binlog_cache_size ??? 該參數控制二進制日志緩沖大小,當事務還沒有提交時,事務日志存放于cache,當遇到大事務cache不夠用的時,mysql會把uncommitted的部分寫入臨時文件,等到committed的時候才會寫入正式的持久化日志文件。 ??? innodb_max_dirty_pages_pct ??? 該參數可以直接控制Dirty Page在BP中所占的比率,當dirty page 達到了該參數的閾值,就會觸發MySQL 系統刷新數據到磁盤 ?? ??? innodb_flush_log_at_trx_commit ? ? 該參數確定日志文件何時write、flush。 為0,log buffer將每秒一次地寫入log file中,并且log file的flush(刷到磁盤)操作同時進行.該模式下,在事務提交的時候,不會主動觸發寫入磁盤的操作。 為1,每次事務提交時MySQL都會把log buffer的數據寫入log file,并且flush(刷到磁盤)中去. 為2,每次事務提交時MySQL都會把log buffer的數據寫入log file.但是flush(刷到磁盤)操作并不會同時進行。該模式下,MySQL會每秒執行一次 flush(刷到磁盤)操作。 注意: ? 由于進程調度策略問題,這個“每秒執行一次 flush(刷到磁盤)操作”并不是保證100%的“每秒”。 ??? sync_binlog ??? sync_binlog 的默認值是0,像操作系統刷其他文件的機制一樣,MySQL不會同步到磁盤中去而是依賴操作系統來刷新binary log。 當sync_binlog =N (N>0) ,MySQL 在每寫 N次 二進制日志binary log時,會使用fdatasync()函數將它的寫二進制日志binary log同步到磁盤中去。 ? ? innodb_flush_method ? ? 該參數控制日志或數據文件如何write、flush。可選的值為 fsync, o_dsync ,o_direct,littlesync,nosync ? fdatasync 模式:寫數據時,write這一步并不需要真正寫到磁盤才算完成(可能寫入到操作系統buffer中就會返回完成),真正完成是flush操作,buffer交給操作系統去flush,并且文件的元數據信息也都需要更新到磁盤。 ? O_DSYNC 模式:寫日志操作是在write這步完成,而數據文件的寫入是在flush這步通過fsync完成 ? O_DIRECT模式:數據文件的寫入操作是直接從mysql innodb buffer到磁盤的,并不用通過操作系統的緩沖,而真正的完成也是在flush這步,日志還是要經過OS緩沖 ? 注意:關于mysql 和io相關的參數,并不是一成不變的,需要根據自身業務系統和硬件系統做相應調整,系統上線之前,測試出一個最佳值。 五 小結 ? ? 數據庫的io是一個很復雜和細致的知識層面,涉及數據庫層和OS層面的IO寫入策略,也和硬件的配置有關,本文主要針對MySQL 層面做分析,可能分析的不夠全面,請各位朋友指點。、 想要Java視頻資料的請加?? 731661047? 六 參考文檔 http://www.percona.com/doc/percona-server/5.6/scalability/innodb_io.html http://www.orczhou.com/index.php/2009/08/innodb_flush_method-file-io/ 原文鏈接:http://blog.itpub.net/22664653/viewspace-1146808/
轉載于:https://www.cnblogs.com/maibaodexiaoer/p/8625983.html
總結
                            
                        - 上一篇: 第三年交强险是多少钱
 - 下一篇: js MD5加密处理