中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL——innodb日志管理

發布時間:2020-09-27 23:21:01 來源:網絡 閱讀:959 作者:一個笨小孩 欄目:MySQL數據庫

innodb日志管理機制:

1、innodb存儲引擎是支持事務ACID特性的,這個理論基本就是一個關系型數據庫相關的數據恢復原形設計,包括日志、回滾、redo、并發控制、buffer pool等管理方面,內容非常全面;

2、innodb的buffer pool主要用來存儲訪問過的數據頁面,他就是一塊連續的內存,通過一定的算法可以使這塊內存得到有效的管理,它是數據庫系統中擁有最大塊內存的系統模塊。

   innodb存儲引擎中數據的訪問是按照頁(也可以叫塊,默認為16KB)的方式從數據庫文件讀取到buffer pool中的,然后在內存中用同樣大小的內存空間來做一個映射;未來提高數據訪問效率,數據庫系統預先就分配了很多這樣的空間,用來與文件中的數據進行交換;buffer pool的大小可以在配置文件中配置,有參數innodb_buffer_pool_size的大小來決定,默認大小為128MB。在MySQL5.7.4以前,一旦MySQL啟動這個值便不能再做修改,如果要修改只能退出MySQL進程,然后修改對應的配置文件來設置新的buffer pool大小,重啟才能生效。

注意:在MySQL5.7.5之后,可以在MySQL進程運行的情況下,動態調整innodb_buffer_pool_size,需要強調的是,如果buffer pool的大小超過了1GB,應該通過調整innodb_buffer_pool_instances=N,把它分成若干個instance的做法,來提示MySQL處理請求的并發能力,因為buffer pool是通過鏈表的方式來管理頁面的,同時為了保護頁面,需要在存取的時候對鏈表加鎖,在多線程的情況下,并發去讀寫buffer pool里面緩存的頁面需要鎖的競爭和等待。所以修改為多個instance,每個instance各自管理自己的內存和鏈表,可以提升效率。

3、buffer pool實現原理:

   buffer pool可以有多個實例,可以通過配置文件中的參數innodb_buffer_pool_instance來設置,默認值為1,實現多個實例的buffer pool主要是為了提高數據頁訪問時的并發度。每個實例的空間大小都是相同的,也就是說系統會將整個配置的buffer pool大小按實例個數平分,然后每個實例各自進行初始化操作;


--注意:在運維過程中,看到狀態參數innodb_buffer_pool_bytes_data總是比innodb_buffer_pool_size小,就是因為控制頭信息占用了部分空間。實際的分配方式是,buffer pool頁面從整個實例池中從后向前分配,每次分配一個頁面,而控制結構使從前向后分配,每次分配一個buf_block_t結構的大小,知道相遇為止,這樣就將一個實例初始化好了。


第一、redo log日志文件管理:

   redo log是用來做數據庫crash recovery的,這是數據庫保障數據安全的重要功能之一。在數據庫操作中,它保存了對innodb表中數據的修改記錄,所以也叫日志文件。在innodb存儲引擎中,一般默認包括2個日志文件,新建數據庫之后會有名為ib_logfile0 和ib_logfile1的兩個文件,如果在啟動數據庫時,這兩個文件不存在,則innodb會根據配置參數或默認值,重新創建日志文件;


1.1、LSN 全名叫:log sequence number:

  在innodb內部的日志管理中,一個很重要的概念是LSN,全名叫log sequence number,它用來精確記錄日志位置信息,且是連續增長的。在innodb中,大小為8個字節值,它的增長量是根據一個MTR寫入的日志量來計算的,寫多少日志,LSN就增長多少。(LSN是一個完全邏輯的概念,每提交一個物理事務,LSN就加1)


1.2、在innodb中,通過日志組來管理日志文件,是一個邏輯定義,包含若干個日志文件,一個組中的日志文件大小相等,大小通過參數來設置,現在innodb只持有一個日志組。(在MySQL5.5以前日志組最大4G;MySQL5.6.3以后可以設置的更大到512G)


1.3、redo日志的寫入,都是字節連續的,雖然看上去是多個日志文件,但理解的時候,完全可以把它想象成一個文件。(日志組中的每個日志文件,都有自己的格式,內部也是按照大小相等的頁面切割,每個頁面大小是512字節)

---注意:如果每次寫入是磁盤塊大小的倍數,效率才是最高的,并且日志將邏輯事務對數據庫的分散隨機寫入轉化成了順序的512字節整數倍數據的寫入,這樣就大大提高了數據庫的效率。


1.4、redo日志文件的格式:

  每個日志文件,都有文件頭(普通頁面中,都會有12個字節用來存儲頁面頭信息,這些信息主要用于管理這個頁面本身的數據存儲方式;---注意只有2KB是日志頭,后面是一個個連續的,用來存儲MTR產生的日志頁面)


1.5、MTRinnodb物理事務:

   它是innodb存儲引擎中一個很重要的用來保證物理頁面寫入操作完整性及持久性的機制。之所以被稱為MTR,是因為它的意義相當于一個mini-transaction,用MTR來表示,這里吧它稱作“物理事務”,這樣叫是相對邏輯事務而言的。

物理事務既然被稱為事務,那它同樣有事務的開始和提交,物理事務的開始其實就是對物理事務結構體mtr_struct的初始化,物理事務的提交主要是將所有這個物理事務產生的日志寫入到innodb日志系統的日志緩沖區中,然后等待srv_master_thread線程定時將日志系統的日志緩沖區的日志數據刷到日志文件中;

---注意:日志緩沖區的存儲只是一個暫時的中間狀態,日志緩沖區的大小可以通過參數innodb_log_buffer_size來設置,一般都比較小,存儲不了多少日志。

--日志是在邏輯事務對數據庫做DML操作時,其所包含的物理事務MTR所記錄的,針對所有涉及的buffer pool頁面的修改記錄;


1.6、日志提高性能的關鍵原因:

①:因為日志是用來記錄buffer pool中page的修改記錄的,所以把page的寫入轉化為對日志的寫入,那此時page就不需要每次都刷盤,寫page頁面只需要在內存中寫入即可,性能會非常好;

②:通常,一個頁面是16KB,如果不寫入職,每次寫入的單位還是16KB,即使修改很少的數據,也是如此,這樣會導致無效IO非常嚴重。


1.7、redo日志大小設置的問題:

①:如果設置的非常大,固然性能可能會很好,但是如果數據庫出現異常停機,此時可能有很多日志都沒有刷盤,也就是log flushed up to 與 last          checkpointat 兩個值之間相差太多,恢復需要比較長的時間。(redo日志的恢復是順序的,都是根據頁面號的大小排序恢復的;)

②:日志容量大小的設置,最好與buffer pool的總大小匹配。如果日志容量太小,buffer pool太大,這就會導致buffer pool頻繁做檢查點,大的buffer      pool不能被好好利用,如果日志容量過大,而buffer pool很小,此時buffer page經常會被淘汰出去,增加IO頻次,同時如果數據庫意外宕機,buffer     pool太小,恢復起來也會比較慢;


1.8、redo日志記錄格式:

 

 innodb的日志是具有邏輯意義的物理日志,所以,日志記錄的格式就不完全是物理信息,而是有一定邏輯意義,基本的格式如下:
type(日志類型),space(表空間ID值),offset(前面space所指定的文件中的頁面號,以頁面大小為單位),data(表示這條日志記錄對應的數據,這個數據是不確定的,根據不同的type值而不同)
---type類型有很多,比較常用的有:
①:mlog_ibyte、mlog_2bytes、mlog_4bytes、mlog_8bytes:這四個類型,表示要在某個位置,寫入一個(兩個、四個、八個)字節的內容;
②:mlog_write_string:這種類型的日志,其實和mlog_ibyte是類似的,只是mlog_ibyte是要寫一個固定長度的數據,而mlog_write_string是要寫一段變長的數據。
③:mlog_undo_insert:這個類型的日志,是在將一條記錄設置為頁面中的最小記錄時產生的,因為只是打個標記,存儲的內容比較簡單;
④:mlog_init_file_page:這個類型的日志比較簡單,只有前面的基本頭信息,沒有data部分;
⑤:mlog_comp_page_create:這個類型只需要村一個類型及要創建的頁面的位置即可;
⑥:mlog_multi_rec_end:這個類型的記錄是非常特殊的,它只起一個標記的作用,其存儲的內容只有占一個字節的類型值。
⑦:mlog_comp_rec_clust_delete_mark:這個類型的日志是表示,需要將聚集索引中的某個記錄打上刪除標志;
⑧:mlog_comp_rec_update_in_place:這個類型的日志記錄更新后的記錄信息,包括所有被更新的列的信息。
⑨:mlog_comp_page_reorganize:這個類型的日志表示的是要重組指定的頁面,其記錄的內容也很簡單,只需要存儲要重組哪一個頁面即可;


1.9、日志刷盤時機:共有5種時機:

①:log buffer空間用完了,這就會將已經產生的log buffer中的日志刷到磁盤中,這是最普遍的一種方式;
②:master線程在后臺每秒鐘刷一次,將當前log buffer中的日志刷到磁盤中;
③:每次執行DML操作時,都會主動檢查日志空間是否足夠,如果使用空間的量已經超過了一個預設的經驗值,就會主動刷日志,以保證在后面真正執行時,不會再執行過程中被動的刷盤,但這里只會是寫文件(寫入OS緩沖中)不會刷盤
④:在做檢查點的時候,要保證所有要刷的頁面中LSN值最小的日志已經刷入到磁盤,不然,如果此時數據庫宕機,日志不存在,但數據頁面已經被修改,從而導致數據不一致,就違背了寫日志的原則;
⑤:提交邏輯事務時,會因為參數innodb_flush_log_at_trx_commit值的不同,產生不同的行為。如果設置0,則在事務提交時,根本不會去刷日志緩沖區,這種設置是最危險的;如果設置2,則在事務提交時會將日志寫入到文件中,但不會去刷盤,只要操作系統不掛,即使數據庫掛了,數據還是不會丟失,一般都是設置為2;



1.10、redo log刷盤機制:

當提交事務(邏輯)時,可以通過參數innodb_flush_log_at_trx_commit來控制redo log寫入的機制,參數值不同,產生的行為不同,主要參數值如下:

①:innodb_flush_log_at_trx_commit=0
  事務提交時,MySQL不會去處理日志緩存區的內容,也不會去處理日志文件的刷盤操作,由MySQL的后臺master線程每隔1s將緩存區的文件刷新到日志文件中;(主機正常,數據庫宕機后:一般只會丟失最近1s的事務)
②:innodb_flush_log_at_trx_commit=1
  事務提交時,會將日志緩沖區的日志寫入到文件中,同時會刷新到磁盤中,保證數據庫事務完全不會丟失。這種設置影響數據庫性能;(主機正常,數據庫宕機后:數據不會丟失)
③:innodb_flush_log_at_trx_commit=2
  事務提交時,會將日志緩存區日志寫入到文件中,但是不會刷新到磁盤中。由MySQL的后臺master線程每隔1s將系統緩存的日志文件刷新到磁盤中;(主機正常,數據庫宕機后:數據不會丟失)

  

---注意:如果數據庫所在主機宕機后:參數0 會丟失最近1s的事務;參數1 不會有任何數據丟失; 參數2 會丟失最近1s的事務;


第二、數據庫undo段管理:

在innodb中支持的回滾段總共有:128X1024=131072個,在每一個事務開始的時候,都會分配一個rseg,就是從長度為128的數組中,根據最近使用的情況,找到一個臨近位置的rseg;

在事務執行的過程中,會產生兩種回滾日志,一種是insert的undo記錄,一種是update的undo記錄;(因為innodb把undo分為兩類,一類就是新增,也就是insert,一類是修改,就是update,分類的依據就是事務提交后要不要做purge操作,因為insert是不需要purge的,只要事務提交了,那這個回滾記錄就可以丟掉了,而對于更新和刪除操作而言,如果事務提交了,還需要為MVCC服務,那就需要將這些日志放到history list中去,等待去做purge已經MVCC的多版本查詢等,所以分為兩類)


2.1、數據庫undo日志記錄格式:

 undo有4種類型:

①:trx_undo_insert_rec:記錄插入的undo日志類型,插入記錄用于回滾時,只需要通過其主鍵就可以實現回滾操作,所以在undo日志中,只記錄了表ID及主鍵信息;
②:trx_undo_upd_exist_rec:更新一條存在記錄的undo日志類型;
③:trx_undo_upd_del_rec:更新一條已經打了刪除標志記錄的undo日志類型;
④:trx_undo_del_mark_rec:刪除記錄時對記錄打刪除標志的undo日志類型;
---注意:與redo日志記錄存儲不同,undo日志的存儲,是不會垮頁面的;
---注意:使用參數innodb_force_recovery來決定要不要做回滾操作,如果設置3或3以上,那么在啟動innodb的時候就不回滾了,這樣可能導致數據庫邏輯上的不一致;


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

彭阳县| 阿图什市| 玛沁县| 随州市| 凤凰县| 渝北区| 孟津县| 平山县| 永平县| 松阳县| 泽普县| 苍南县| 岐山县| 汤原县| 县级市| 中牟县| 清镇市| 肃宁县| 辽阳市| 英山县| 定南县| 乾安县| 仙游县| 临泉县| 利辛县| 舒城县| 陵川县| 尤溪县| 新沂市| 黑龙江省| 扬州市| 敦煌市| 屏东市| 定结县| 赫章县| 疏附县| 濮阳市| 青铜峡市| 吉首市| 中超| 璧山县|