MySQL性能調優(5)Innodb引擎的MVCC

MVCC

Multiversion concurrency control (多版本併發控制)
併發訪問(讀或寫)數據庫時,對正在事務內處理的數據做多版本的管理。以達到用來避免寫操作的堵塞,從而引發讀操作的併發問題。

這裏看一個案例

begin
// 這裏默認是加上X鎖的,在未做commit/rollback操作之前
update users set lastUpdate=now() where id =1; 
// 在其他的事務我們能不能進行對應數據的查詢 但是我這時查詢是能查到的當前時間這條記錄
select * from users where id = 1;

先來看看MVCC的處理機制

插入數據

同一個事務,事務行版本號相同

刪除數據
##### 修改數據 ##### 查詢數據 這也就是之前案例爲什麼能查詢數據的原因所在 ``` 記住圖上的規則 1. 查找數據行版本號早於當前事務版本數據行 // 行的系統版本號小於或等於事務的系統版本號,這裏就已經篩選出id等於1的兩條數據 2. 查找刪除版本號要麼爲null要麼大於當前事務版本號記錄 //爲null說明沒刪除,大於當前事務版本號說明是事務開啓過後 別的事務開啓做的數據,這個是爲了再次判斷當前事務更改數據 ```

那這些數據時怎麼來的呢

Undo Log

  • undo意爲取消,以撤銷操作爲目的,返回指定某個狀態的操作
  • UndoLog是爲了實現事務的原子性而出現的產物
  • Undo Log實現事務原子性:事務處理過程中如果出現了錯誤或者用戶執行了 ROLLBACK語句,MySQL可以利用Undo Log中的備份將數據恢復到事務開始之前的狀態。
  • UndoLog在MySQL innodb存儲引擎中用來實現多版本併發控制
  • Undo log實現多版本併發控制:事務未提交之前,Undo保存了未提交之前的版本數據,Undo 中的數據可作爲數據舊版本快照供其他併發事務進行快照讀
執行流程

這就是爲什麼加了X鎖的數據我們還能查詢的原因,他實際上是讀取undo log裏面的數據進行快照讀

當前讀與快照讀的區別

Innodb引擎的普通select都是快照讀。只有增刪改和加了鎖的纔是當前讀

Redo Log

  • Redo,顧名思義就是重做。以恢復操作爲目的,重現操作;
  • Redo log指事務中操作的任何數據,將最新的數據備份到一個地方 (Redo Log)
  • Redo log的持久:不是隨着事務的提交才寫入的,而是在事務的執行過程中,便開始寫入redo 中。具體的落盤策略可以進行配置
  • RedoLog是爲了實現事務的持久性而出現的產物
  • Redo Log實現事務持久性:防止在發生故障的時間點,尚有髒頁未寫入磁盤,在重啓MySQL服務的時候,根據redo log進行重做,從而達到事務的未入磁盤數據進行持久化這一特性。
執行流程
##### Redo Log補充說明 這裏可以看到redo log 默認大小是48M默認位置是在數據庫根路徑下面
指定Redo log 記錄在{datadir}/ib_logfile1&ib_logfile2 可通過innodb_log_group_home_dir 配置指定目錄存儲
一旦事務成功提交且數據持久化落盤之後,此時Redo log中的對應事務數據記錄就失去了意義,所以Redo log的寫入是日誌文件循環寫入的
指定Redo log日誌文件組中的數量 innodb_log_files_in_group 默認爲2
指定Redo log每一個日誌文件最大存儲量innodb_log_file_size 默認48M
指定Redo log在cache/buffer中的buffer池大小innodb_log_buffer_size 默認16M
Redo buffer 持久化Redo log的策略, innodb_flush_log_at_trx_commit:
取值 0 每秒提交 Redo buffer --> Redo log OS cache -->flush cache to disk[可能丟失一秒內的事務數據]
取值 1 默認值,每次事務提交執行Redo buffer --> Redo log OS cache -->flush cache to disk[最安全,性能最差的方式]
取值 2 每次事務提交執行Redo buffer --> Redo log OS cache 再每一秒執行 ->flush cache to disk操作

配置優化

改配置說明
如果是docker可以通過啓動選擇配置文件啓動
如果不想重啓的話可以利用 set global
set global 參數=? 
尋找配置文件位置和加載順序
mysql --help | grep -A 1 'Default options are read from the following files in the given order'

這是我docker中MySQL的配置文件位置和加載順序

MySQL服務器參數類型
全局參數
       set global autocommit = ON/OFF;
會話參數(<font color=red >會話參數不單獨設置則會採用全局參數</font>)
       set session autocommit = ON/OFF;
注意:
全局參數的設定對於已經存在的會話無法生效
會話參數的設定隨着會話的銷燬而失效
全局類的統一配置建議配置在默認配置文件中,否則重啓服務會導致配置失效
全局配置文件配置
最大連接數配置(如果連接數過大會有約束,就需要考慮改句柄數了)
max_connections 
系統句柄數配置
/etc/security/limits.conf
ulimit -a
MySQL句柄數配置
/usr/lib/systemd/system/mysqld.service
常用配置說明
port = 3306 #端口號
socket = /tmp/mysql.sock  #爲MySQL客戶程序與服務器之間的本地通信指定一個套接字文件
basedir = /usr/local/mysql #安裝 MySQL 的安裝路徑
datadir = /data/mysql #數據庫文件路徑
pid-file = /data/mysql/mysql.pid #記錄當前MySQL進程的pid
user = mysql  #表示MySQL的管理用戶
bind-address = 0.0.0.0 #MySQL服務器的IP地址。如果MySQL服務器所在的計算機有多個IP地址,這個選項將非常重要
max_connections=2000 #MySQL服務器同時處理的數據庫連接的最大數量
lower_case_table_names = 0 #表名區分大小寫
server-id = 1 #數據庫id號一般主從複製的時候會用到
tmp_table_size=16M #臨時表大小
transaction_isolation = REPEATABLE-READ #隔離級別
ready_only=1 #0是讀寫1是隻讀
其他參數配置
wait_timeout #服務器關閉非交互連接之前等待活動的秒數
innodb_open_files #限制Innodb能打開的表的個數
innodb_write_io_threads #innodb使用後臺線程處理innodb緩衝區數據頁上的寫 I/O(輸入輸出)請求數 
innodb_read_io_threads #innodb使用後臺線程處理innodb緩衝區數據頁上的讀 I/O(輸入輸出)請求數 
innodb_lock_wait_timeout #InnoDB事務在被回滾之前可以等待一個鎖定的超時秒數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章