7.innodb的事務機制、鎖等簡述
1. innodb的核心特性
1.1 Innodb的事務的ACID特性:
● Atomic(原子性):所有語句作為一個單元全部成功執行或全部取消,不能出現中間狀態
● Consistent(一致性):如果資料庫在事務開始時處於一致狀態,則在執行該事務期間將保留一致狀態
●Isolated(隔離性):事務之間不相互影響
●Durable(永續性):事務成功完成後,所做的所有更改準確地記錄在資料庫中,所做的更改不會丟失
1.2 事務的宣告週期
begin:
sql 語句
commit或者rollback :提交或者回滾
1.3 自動提交機制(autocommit)
mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec)
注意:
線上修改引數
set autocommit=0; # 會話級別 ,及時生效
set global autocommit=0; #全域性級別 ,斷開視窗重連後生效,影響到所有新開的會話
(3)永久生效 vim /etc/my.cnf
autocommit=0;
1.4 事務的acid 特性如何保證?
1.4.1 一些概念名詞
髒頁:記憶體髒頁,記憶體中發生了修改,沒寫入到磁碟之前,我們把記憶體頁稱為髒頁
redolog : 重做日誌,一般會儲存在磁碟上(ib_logfile0,ib_logfile1) ,一般大小為50M
xx.ibd :這個是儲存資料和索引的檔案
buffer_poll: 緩衝區域
LSN: 日誌序列號 ,一般儲存磁碟資料頁,redo檔案,buffer pool,redo buffer ,作用:mysql 每次資料庫啟動,都會比較磁碟資料頁和redolog的LSN,必須要求兩者LSN一致資料才能正常啟動
WAL::日誌優先寫的方式實現持久化
CKPT:checkpoint,檢查點,就是將髒頁刷寫到磁碟的動作
TXID:事務號,innodb會為每一個事務生成一個事務號,伴隨著整個事務週期。
1.4.2 事務日誌redolog
作用:主要功能 保證“D", A C 也有一定的作用
●記錄了記憶體資料頁的變化
●提供快速的持久化功能(WAL)
●CSR過程中實現前滾的操作(保證磁碟資料頁和redo日誌LSN一致)
redo日誌位置: iblogfile0 ib_logfile1
情況一:
我們做了一個事務,begin;update;commit;
1.在begin時,會立即分配一個TXID=tx_01.
2.update時,會將需要修改的資料頁(dp_01,LSN),載入到data_buffer中,
3.DBWR執行緒,會進行dp_01資料頁修改更新,並更新LSN=102.
4.LogBWR日誌寫執行緒,會將dp_01資料頁的變化+LSN+TXID儲存到redobuffer中
5.執行commit時,LGWR日誌寫執行緒會將redobuffer資訊寫入redolog日誌檔案中,基於WAL原則在日誌完全寫入磁碟後,commit命令才執行成功,(會將此日誌打上commit標記)
6.假如此時宕機,記憶體髒頁沒有來的及寫入磁碟,記憶體資料全部丟失
7.mysql再次重啟時,必須要redlog和磁碟資料頁的LSN是一致的,但是,這時是不一致的
8.於是mysql此時無法正常啟動,那麼就是觸發CSR機制,在記憶體中追平LSN號,觸發CKPT,將記憶體資料頁更新到磁碟中,從而保證磁碟資料頁和redolog LSN一致,
這是mysql正常啟動
以上過程我們稱之基於redo的’前滾操作'
2. undo?
undo日誌使用者存放資料被修改前的值,簡單的說如果修改某表中的某個值的話,例如將tba表中的id=2這行資料的name='a' 修改成為name='a2',那麼undo日誌就會用來存放name='a'的記錄,如果這個修改出現異常,可以使用undo日誌來實現回滾操作,來保證事務的一致性。
關於undo的一系列引數:
▲innodb_max_undo_log_size :控制最大undo tablespace檔案的大小,當啟動了innodb_undo_log_truncate 時,undo tablespace 超過innodb_max_undo_log_size 閥值時才會去嘗試truncate該值預設大小為1G,truncate後的大小預設為10M
▲innodb_undo_tablespaces:設定undo獨立表空間個數,範圍為0-128, 預設為0,0表示表示不開啟獨立undo表空間 且 undo日誌儲存在ibdata檔案中。該引數只能在最開始初始化MySQL例項的時候指定,如果例項已建立,這個引數是不能變動的,如果在資料庫配置文 件 .cnf 中指定innodb_undo_tablespaces 的個數大於例項建立時的指定個數,則會啟動失敗,提示該引數設定有誤,如果設定了該引數為n(n>0),那麼就會在undo目錄下建立n個undo檔案(undo001,undo002 …… undo n),每個檔案預設大小為10M.
我們什麼時候需要設定這個引數呢?
當DB寫壓力較大時,可以設定獨立UNDO表空間,把UNDO LOG從ibdata檔案中分離開來,指定 innodb_undo_directory目錄存放,可以制定到高速磁碟上,加快UNDO LOG 的讀寫效能。
▲innodb_undo_log_truncate:InnoDB的purge執行緒,根據innodb_undo_log_truncate設定開啟或關閉、innodb_max_undo_log_size的引數值,以及truncate的頻率來進行空間回收和 undo file 的重新初始化,該引數生效的前提是,已設定獨立表空間且獨立表空間個數大於等於2個
3. undo空間管理
如果需要設定獨立表空間,需要在初始化資料庫例項的時候,指定獨立表空間的數量、UNDO內部由多個回滾段組成,即 Rollback segment,一共有128個,儲存在ibdata系統表空間中,分別從resg slot0 - resg slot127,每一個resg slot,也就是每一個回滾段,內部由1024個undo segment 組成。
回滾段(rollback segment)分配如下:
slot 0 ,預留給系統表空間;
slot 1- 32,預留給臨時表空間,每次資料庫重啟的時候,都會重建臨時表空間;
slot33-127,如果有獨立表空間,則預留給UNDO獨立表空間;如果沒有,則預留給系統表空間;
回滾段中除去32個提供給臨時表事務使用,剩下的 128-32=96個回滾段,可執行 96*1024 個併發事務操作,每個事務佔用一個 undo segment slot,注意,如果事務中有臨時表事務,還會在臨時表空間中的 undo segment slot 再佔用一個 undo segment slot,即佔用2個undo segment slot。如果錯誤日誌中有:Cannot find a free slot for an undo log。則說明併發的事務太多了,需要考慮下是否要分流業務。
回滾段(rollback segment )採用 輪詢排程的方式來分配使用,如果設定了獨立表空間,那麼就不會使用系統表空間回滾段中undo segment,而是使用獨立表空間的,同時,如果回顧段正在 Truncate操作,則不分配
4.redo?
當資料庫對資料做修改的時候,需要把資料頁從磁碟讀到buffer pool中,然後在buffer pool中進行修改,那麼這個時候buffer pool中的資料頁就與磁碟上的資料頁內容不一致,稱buffer pool的資料頁為dirty page 髒資料,如果這個時候發生非正常的DB服務重啟,那麼這些資料還在記憶體,並沒有同步到磁碟檔案中(注意,同步到磁碟檔案是個隨機IO),也就是會發生資料丟失,如果這個時候,能夠在有一個檔案,當buffer pool 中的data page變更結束後,把相應修改記錄記錄到這個檔案(注意,記錄日誌是順序IO),那麼當DB服務發生crash的情況,恢復DB的時候,也可以根據這個檔案的記錄內容,重新應用到磁碟檔案,資料保持一致。這個檔案就是redo log ,用於記錄 資料修改後的記錄,順序記錄.
4.1 redo 引數
▲innodb_log_files_in_group:redo log 檔案的個數,命名方式如:ib_logfile0,iblogfile1… iblogfilen。預設2個,最大100個。
▲innodb_log_file_size:檔案設定大小,預設值為 48M,最大值為512G,注意最大值指的是整個 redo log系列檔案之和,即(innodb_log_files_in_group * innodb_log_file_size )不能大於最大值512G。
▲innodb_log_group_home_dir:檔案存放路徑
▲innodb_log_buffer_size:Redo Log 快取區,預設8M,可設定1-8M。延遲事務日誌寫入磁碟,把redo log 放到該緩衝區,然後根據 innodb_flush_log_at_trx_commit引數的設定,再把日誌從buffer 中flush 到磁碟中
█innodb_flush_log_at_trx_commit:作用如下圖所示:
補充一下:這裡有一個fsync來重新整理I/O快取
==0 ###表示事務提交時,Innodb不會立即觸發將快取日誌寫到磁碟,而是每秒觸發一次快取日誌先回寫檔案系統快取中,然後立即呼叫作業系統fsync重新整理IO快取到磁碟檔案
==1 ### 表示當事務提交時,Innodb立即觸發將快取日誌寫到磁碟的檔案系統快取中,然後立即呼叫作業系統fsync重新整理io快取到磁碟檔案
==2 ### 表示當事務提交時,Innodb立即觸發將快取日誌寫到磁碟的檔案系統快取中,然後不會立即觸發重新整理快取,而是每秒觸發重新整理快取的。
4.2 redo空間管理
Redo log檔案以ib_logfile[number]命名,Redo log 以順序的方式寫入檔案檔案,寫滿時則回溯到第一個檔案,進行覆蓋寫。(但在做redo checkpoint時,也會更新第一個日誌檔案的頭部checkpoint標記,所以嚴格來講也不算順序寫)。
實際上redo log有兩部分組成:redo log buffer 跟redo log file。buffer pool中把資料修改情況記錄到redo log buffer,出現以下情況,再把redo log buffer刷下到redo log file:
Redo log buffer空間不足
事務提交(依賴innodb_flush_log_at_trx_commit引數設定)
後臺執行緒
做checkpoint
例項shutdown
binlog切換