MySQL 學習筆記四【事務和鎖】

============================================

MySQL學習筆記【第四部分】

============================================

一. 事務

1.概述

數據庫操作的最小工作單元,是作爲單個邏輯工作單元執行的一系列操作; 事務是一組不可再分割的操作集合(工作邏輯單元)

2.事務的ACID特性

- 原子性(Atomicity)

- 一致性(Consistency)

- 隔離性(Isolation)

- 持久性(Durability)

3.事務併發帶來的問題

  • 髒讀
  • 不可重複讀
  • 幻讀

4.事務隔離級別

- Read Uncommitted(未提交讀) —解決併發問題【事務未提交對其它事務也是可見的,髒讀】
- Read Committed(提交讀) —解決髒讀問題【一個事務開始之後,只能看到自己提交事務所做的修改,不可重複讀】
- Repeatable Read(可重複讀) —解決不可重複讀問題【在同一個事務中多次讀取同樣的數據結果一樣的,未定義解決幻讀問題】
- Serialiazable(串行化) —解決所有問題【最高的隔離級別,通過強制事務的串行執行】

5.InnoDB引擎對隔離級別的支持程度

在這裏插入圖片描述

二. 鎖

1.理解表鎖、行鎖

在這裏插入圖片描述

2.InnoDB鎖類型

  • 共享鎖(行鎖):Shared Locks
  • 排它鎖(行鎖):Exclusive Locks
  • 意向共享鎖(表鎖):Intension Shared Locks
  • 意向排它鎖(表鎖):Intension Exclusive Locks
  • 自增鎖:AUTO-INC Locks

行鎖算法:

  • 記錄鎖 Record Locks
  • 間隙鎖 Gap Locks
  • 臨鍵鎖 Next-key Locks

3.共享鎖、排它鎖

共享鎖:

共享鎖又稱爲讀鎖,簡稱S鎖,顧名思義,共享鎖就是多個事務對於同一數據可以共享一把鎖,都能訪問到數據,但是隻能讀不能修改。
加鎖釋鎖方式:

select * from users WHERE id=1 LOCK IN SHARE MODE;
 commit/rollback

排它鎖:

排它鎖又稱爲寫鎖,簡稱X鎖,排它鎖不能與其他鎖共存,如一個事務獲得了一個數據行的排它鎖,其他事務就不能在獲取該行的鎖(共享鎖,排它鎖),只有獲取了排它鎖的事務是可以對數據進行讀取和修改的(其它事務讀取數據可來自於快照)
加鎖釋鎖方式:

delete / update / insert 默認加上X鎖 
SELECT * FROM table_name WHERE ... FOR UPDATE 
commit/rollback

InnoDb-行鎖到底鎖了什麼

InnoDB的行鎖是通過給索引上的索引項加鎖來實現的。
只有通過索引條件進行數據檢索,InnoDB才使用行級鎖,否則,InnoDB 將使用表鎖(鎖住索引的所有記錄)
表鎖:lock tables xx read/write;

4.意向共享鎖(IS)、意向排它鎖(IX)

意向共享鎖:

表示事務準備給數據行加入共享鎖,即一個數據行加共享鎖前必須先取得該表的IS鎖, 意向共享鎖之間是可以相互兼容的。

意向排它鎖:

表示事務準備給數據行加入排他鎖,即一個數據行加排他鎖前必須先取得該表的IX鎖, 意向排它鎖之間是可以相互兼容的。

意義

當事務想去進行鎖表時,可以先判斷意向鎖是否存在,存在時則可快速返回該表不能 啓用表鎖

意向鎖(IS、IX)是InnoDB數據操作之前自動加的,不需要用戶干預

5.自增鎖AUTO-INC Locks

針對自增列自增長的一個特殊的表級別鎖

show variables like 'innodb_autoinc_lock_mode';

默認取值1,代表連續,事務未提交ID永久丟失

6.記錄鎖(Record)、間隙鎖(Gap)、臨鍵鎖(Next-Key)

Next-Key Locks

鎖住記錄+區間(左開右閉)
當sql執行按照索引進行數據的檢索時,查詢條件爲範圍查找(between and、<、>等)並有數 據命中則此時SQL語句加上的鎖爲Next-key locks,鎖住索引的記錄+區間(左開右閉)
在這裏插入圖片描述

Gap Locks

鎖住數據不存在的區間(左開右開)
當sql執行按照索引進行數據的檢索時,查詢條件的數據不存在,這時SQL語句加上的鎖即爲 Gap locks,鎖住索引不存在的區間(左開右開)
在這裏插入圖片描述
Record Locks
鎖住具體的索引項
當sql執行按照唯一性(Primary key、Unique key)索引進行數據的檢索時,查詢條件等值匹 配且查詢的數據是存在,這時SQL語句加上的鎖即爲記錄鎖Record locks,鎖住具體的索引項
在這裏插入圖片描述

7.解決髒讀、不可重複讀、幻讀

1 利用X鎖解決髒讀
在這裏插入圖片描述

2 利用S鎖解決不可重複讀
在這裏插入圖片描述
3 利用Next-Key解決幻讀
在這裏插入圖片描述

8.死鎖

死鎖介紹:

  • 多個併發事務(兩個以上)
  • 每個事務都持有鎖(或者是已經在等待鎖)
  • 每個事務都需要再繼續持有鎖
  • 事務之間產生加鎖的循環依賴,形成死鎖

死鎖的避免:

  • 類似的業務邏輯以固定的順序訪問表和行。
  • 大事務拆小。大事務更傾向於死鎖,如果業務允許,將大事務拆小。
  • 在同一個事務中,儘可能做到一次鎖定所需要的所有資源,減少死鎖概 率。
  • 降低隔離級別,如果業務允許,將隔離級別調低也是較好的選擇
  • 爲表添加合理的索引。可以看到如果不走索引將會爲表的每一行記錄添 加上鎖(或者說是表鎖)

9.MVCC

查看MySQL的設置的事務隔離級別

select global.@@tx_isolation;
select @@tx_isolation;

MVCC概述

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

MVCC邏輯流程-插入
在這裏插入圖片描述
MVCC邏輯流程-刪除
在這裏插入圖片描述
MVCC邏輯流程-修改
在這裏插入圖片描述
MVCC邏輯流程-查詢
在這裏插入圖片描述
Undo log
undo意爲取消,以撤銷操作爲目的,返回指定某個狀態的操作undolog指事務開始之前,在操作任何數據之前,首先將需操作的數據備份到一個地方(UndoLog)
UndoLog是爲了實現事務的原子性而出現的產物
UndoLog實現事務原子性
事務處理過程中如果出現了錯誤或者用戶執行了ROLLBACK語句,Mysql可以利用UndoLog中的備份將數據恢復到事務開始之前的狀態
UndoLog在Mysqlinnodb存儲引擎中用來實現多版本併發控制
Undolog實現多版本併發控制:
事務未提交之前,Undo保存了未提交之前的版本數據,Undo中的數據可作爲數據舊版本快照供其他併發事務進行快照讀
在這裏插入圖片描述

快照讀:

SQL讀取的數據是快照版本,也就是歷史版本,普通的SELECT就是快照讀
innodb快照讀,數據的讀取將由cache(原本數據)+undo(事務修改過的數據)兩部分組成

當前讀:

SQL讀取的數據是最新版本。通過鎖機制來保證讀取的數據無法通過其他事務進行修改UPDATE、DELETE、INSERT、SELECT…LOCKINSHAREMODE、SELECT…FORUPDATE都是當前讀。

Redo log
Redo,顧名思義就是重做。以恢復操作爲目的,重現操作;
Redolog指事務中操作的任何數據,將最新的數據備份到一個地方(RedoLog)Redolog的持久:
不是隨着事務的提交才寫入的,而是在事務的執行過程中,便開始寫入redo中。具體的落盤策略可以進行配置
RedoLog是爲了實現事務的持久性而出現的產物

Undolog實現多版本併發控制:
事務未提交之前,Undo保存了未提交之前的版本數據,Undo中的數據可作爲數據舊版本快照供其他併發事務進行快照讀

在這裏插入圖片描述

Redo log補充

  • 指定Redolog記錄在{datadir}/ib_logfile1&ib_logfile2可通過innodb_log_group_home_dir配置指定目錄存儲

  • 一旦事務成功提交且數據持久化落盤之後,此時Redolog中的對應事務數據記錄就失去了意義,所以Redolog的寫入是日誌文件循環寫入的

  • 指定Redolog日誌文件組中的數量innodb_log_files_in_group默認爲2

  • 指定Redolog每一個日誌文件最大存儲量innodb_log_file_size默認48M指定Redolog在cache/buffer中的buffer池大小innodb_log_buffer_size默認16M

  • Redobuffer持久化Redolog的策略,Innodb_flush_log_at_trx_commit:

  • 取值0每秒提交Redobuffer–>RedologOScache–>flushcachetodisk[可能丟失一秒內的事務數據]

  • 取值1默認值,每次事務提交執行Redobuffer–>RedologOScache–>flushcachetodisk [最安全,性能最差的方式]

  • 取值2每次事務提交執行Redobuffer–>RedologOScache再每一秒執行->flushcacheto disk操作

3.配置優化

MySQL服務器參數類型

基於參數的作用域:
全局參數setglobalautocommit=ON/OFF;
會話參數(會話參數不單獨設置則會採用全局參數):setsessionautocommit=ON/OFF;
注意:
全局參數的設定對於已經存在的會話無法生效
會話參數的設定隨着會話的銷燬而失效
全局類的統一配置建議配置在默認配置文件中,否則重啓服務會導致配置失效

mysql--help尋找配置文件的位置和加載順序
Defaultoptionsarereadfromthefollowingfilesinthegivenorder:
/etc/my.cnf/etc/mysql/my.cnf/usr/etc/my.cnf~/.my.cn
fmysql--help|grep-A1'Defaultoptionsarereadfromthefollowing filesinthegivenorder'

全局配置文件配置

最大連接數配置:max_connections
系統句柄配置:/etc/security/limits.confulimit-a
MySQL句柄數配置:/usr/lib/systemd/system/mysqld.service

常見全局配置文件配置

port=3306
socket=/tmp/mysql.sock
basedir=/usr/local/mysql
datadir=/data/mysql
pid-file=/data/mysql/mysql.pid
user=mysql
bind-address=0.0.0.0
max_connections=2000
lower_case_table_names=0#表名區分大小寫
server-id=1
tmp_table_size=16
Mtransaction_isolation=REPEATABLE-READ
ready_only=1
...

MySQL內存參數配置
每一個connection內存參數配置:

  • sort_buffer_sizeconnection排序緩衝區大小:建議256K(默認值)->2M之內當查詢語句中有需要文件排序功能時,馬上爲connection分配配置的內存大小
  • join_buffer_sizeconnection關聯查詢緩衝區大小:建議256K(默認值)->1M之內當查詢語句中有關聯查詢時,馬上分配配置大小的內存用這個關聯查詢,所以有可能在一個查詢語句中會分配很多個關聯查詢緩衝區
  • 上述配置4000連接佔用內存:4000*(0.256M+0.256M)=2G

Innodb_buffer_pool_size
innodbbuffer/cache的大小(默認128M)Innodb_buffer_pool

  • 數據緩存
  • 索引緩存
  • 緩衝數據
  • 內部結構
    大的緩衝池可以減小多次磁盤I/O訪問相同的表數據以提高性能
    參考計算公式:Innodb_buffer_pool_size=(總物理內存-系統運行所用-connection所用)*90%

MySQL其他參數配置

  • 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事務在被回滾之前可以等待一個鎖定的超時秒數

4.數據庫設計

在這裏插入圖片描述
在這裏插入圖片描述

注:希望讀者如果有時間的話可以去了解一下58同城的30條軍規

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章