詳解 Mysql 事務和Mysql 日誌
事務特性
1、原子性(Atomicity):事務開始後所有操作,要麼全部做完,要麼全部不做,不可能停滯在中間環節。
2、一致性(Consistency):事務開始前和結束後,資料庫的完整性約束沒有被破壞 。比如A向B轉賬,不可能A扣了錢,B卻沒收到。
3、隔離性(Isolation):同一時間,只允許一個事務請求同一資料,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。
4、永續性(Durability):事務完成後,事務對資料庫的所有更新將被儲存到資料庫,不能回滾。
事務併發問題
1、髒讀:事務A讀取了事務B更新的資料,然後B回滾操作,那麼A讀取到的資料是髒資料
2、不可重複讀:事務 A 多次讀取同一資料,事務 B 在事務A多次讀取的過程中,對資料作了更新並提交,導致事務A多次讀取同一資料時,結果 不一致。
3、幻讀:系統管理員A將資料庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。
小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表
事務隔離
mysql預設是“可重複讀”,序列化後
事務隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
讀未提交(read-uncommitted) | 是 | 是 | 是 |
不可重複讀(read-committed) | 否 | 是 | 是 |
可重複讀(repeatable-read) | 否 | 否 | 是 |
序列化(serializable) | 否 | 否 | 否 |
#查全域性事務隔離級別 SELECT @@global.tx_isolation; #查當前會話事務隔離級別 SELECT @@session.tx_isolation; #查當前事務隔離級別 SELECT @@tx_isolation; #設定全域性隔離級別 set global transaction isolation level read committed; #設定當前會話隔離級別 set session transaction isolation level read committed;
序列化是最高的隔離級別,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每個讀的資料行上加上共享鎖,在這個級別,可能導致大量的超時現象和鎖競爭。
共享鎖(Share):共享鎖的代號是S
mysql日誌檔案系統組成
1、MySQL日誌檔案系統的組成
a、錯誤日誌:記錄啟動、執行或停止mysqld時出現的問題。
b、通用日誌:記錄建立的客戶端連線和執行的語句。
c、更新日誌:記錄更改資料的語句。該日誌在MySQL 5.1中已不再使用。
d、二進位制日誌:記錄所有更改資料的語句。還用於複製。
e、慢查詢日誌:記錄所有執行時間超過long_query_time秒的所有查詢或不使用索引的查詢。
f、Innodb日誌:innodb redo log
二進位制日誌(binlog):
包含了所有更新了資料或者已經潛在更新了資料(比如沒有匹配任何行的一個DELETE)
包含關於每個更新資料庫(DML)的語句的執行時間資訊
不包含沒有修改任何資料的語句,如果需要啟用該選項,需要開啟通用日誌功能
主要目的是儘可能的將資料庫恢復到資料庫故障點,因為二進位制日誌包含備份後進行的所有更新
用於在主複製伺服器上記錄所有將傳送給從伺服器的語句
啟用該選項資料庫效能降低1%,但保障資料庫完整性,對於重要資料庫值得以效能換完整。有些類似於oracle開啟歸檔模式。
show variables like '%version%'; show variables like '%log_bin%'; //是否啟用 binlog show variables like '%binlog%'; //binlog 相關引數 show variables like '%datadir%'; //資料檔案目錄,預設日誌存在該目錄 #編輯my.cnf來設定binary log日誌位置(注,配置二進位制日誌路徑及檔名後,系統變數log_bin被自動置為on) log_bin=/var/lib/mysql/binarylog/binlog #如果在my.cnf裡面只設置log_bin,但是不指定file_name,然後重啟資料庫。你會發現二進位制日誌檔名稱為${hostname}-bin 這樣的格式 #切換日誌 show master status; flush logs; show master status;
每次重啟MySQL服務也會生成一個新的二進位制日誌檔案,相當於二進位制日誌切換。切換二進位制日誌時,你會看到這些number會不斷遞增。另外,除了這些二進位制日誌檔案外,你會看到還生成了一個DB-Server-bin.index的檔案,這個檔案中儲存所有二進位制日誌檔案的清單又稱為二進位制檔案的索引
二進位制日誌的刪除可以通過命令手工刪除,也可以設定自動清理。
show binary logs; mysql> purge binary logs to 'DB-Server-bin.000002'; purge binary logs to xxx; 表示刪除某個日誌之前的所有二進位制日誌檔案。這個命令會修改index中相關資料 purge binary logs before '2017-03-10 10:10:00'; 清除某個時間點以前的二進位制日誌檔案。 purge master logs before date_sub( now( ),interval 7 day);清除7天前的二進位制日誌檔案 reset master;清除所有的二進位制日誌檔案(當前不存在主從複製關係) show variables like 'expire_logs_days';我們也可以設定expire_logs_days引數,設定自動清理,其預設值為0,表示不啟用過期自動刪除功能,如果啟用了自動清理功能,表示超出此天數的二進位制日誌檔案將被自動刪除,自動刪除工作通常發生在MySQL啟動時或FLUSH日誌時。 set expire_logs_days=7;
二進位制日誌相關引數
1、系統變數log_bin_trust_function_creators,預設為OFF,這個引數開啟會限制儲存過程、Function、觸發器的建立。
2:系統變數sql_log_bin 用於控制會話級別二進位制日誌功能的開啟或關閉,預設為ON,表示啟用二進位制日誌功能。
3、系統變數binlog_cache_size 表示為每個客戶端分配binlog_cache_size大小的快取,預設值32768。二進位制日誌快取使用的前提條件是伺服器端使用了支援事務的引擎以及開啟了bin log功能,它是MySQL用來提高binlog的效率而設計的一個用於短時間內臨時快取binlog資料的記憶體區域。一般來說,如果我們的資料庫中沒有什麼大事務,寫入也不是特別頻繁,2MB~4MB是一個合適的選擇。但是如果我們的資料庫大事務較多或多事務語句,寫入量比較大,可適當調高binlog_cache_size。同時,我們可以通過binlog_cache_use 以及 binlog_cache_disk_use來分析設定的binlog_cache_size是否足夠,是否有大量的binlog_cache由於記憶體大小不夠而使用臨時檔案(binlog_cache_disk_use)來快取了。
可以通過檢視Binlog_cache_disk_use 與 Binlog_cache_use來判斷binlog_cache_size是否需要調整。
4、系統變數max_binlog_cache_size 二進位制日誌能夠使用的最大cache記憶體大小。當執行多語句事務時,max_binlog_cache_size 如果不夠大,系統可能會報出“Multi-statement transaction required more than ‘max_binlog_cache_size' bytes of storage”的錯誤。
5、 系統變數max_binlog_stmt_cache_size
max_binlog_cache_size針對事務語句,max_binlog_stmt_cache_size針對非事務語句,當我們發現Binlog_cache_disk_use或者Binlog_stmt_cache_disk_use比較大時就需要考慮增大cache的大小
6、系統變數max_binlog_size, 表示二進位制日誌的最大值,一般設定為512M或1GB,但不能超過1GB。該設定並不能嚴格控制二進位制日誌的大小,尤其是二進位制日誌比較靠近為不而又遇到一根比較大事務時, 為了保證事務的完整性,不可能做切換日誌的動作,只能將該事務的所有SQL都記錄進當前日誌,直到事務結束。
7、系統變數binlog_checksum 用作複製的主從校檢。 NONE表示不生成checksum,CRC-32表示使用這個演算法做校檢。
8、系統變數sync_binlog,這個引數對於Mysql系統來說是至關重要的,它不僅影響到二進位制日誌檔案對MySQL所帶來的效能損耗,而且還影響到MySQL中資料的完整性。
sync_binlog=0,當事務提交後,Mysql僅僅是將binlog_cache中的資料寫入binlog檔案,但不執行fsync之類的磁碟同步指令通知檔案系統將快取重新整理到磁碟,而是讓Filesystem自行決定什麼時候來做同步。MySQL中預設的設定是 sync_binlog=0,即不作任何強制性的磁碟重新整理指令,這個設定效能是最好的,但風險也是最大的。一旦系統崩潰(Crash),在檔案系統快取中的所有二進位制日誌資訊都會丟失。從而帶來資料不完整問題。
sync_binlog=n,在進行n次事務提交以後,Mysql將執行一次fsync之類的磁碟同步指令,同時檔案系統將Binlog檔案快取重新整理到磁碟。
可以適當的調整sync_binlog, 在犧牲一定的一致性下,獲取更高的併發和效能。
9、系統變數binlog_format 指定二進位制日誌的型別。分別有STATEMENT、ROW、MIXED三種值。MySQL 5.7.6之前預設為STATEMENT模式。MySQL 5.7.7之後預設為ROW模式。這個引數主要影響主從複製。
基於SQL語句的複製(statement-based replication,SBR),
基於行的複製(row-based replication,RBR),
混合模式複製(mixed-based replication,MBR)。
檢視二進位制日誌內容
方法1:使用show binlog events方式可以獲取當前以及指定binlog的日誌,不適宜提取大量日誌。
SHOW BINLOG EVENTS[IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
SHOW BINLOG EVENTS IN 'mysql-bin.000005' \G
方法2: 使用mysqlbinlog命令列檢視日誌內容(適宜批量提取日誌)。
system mysqlbinlog /var/lib/mysql/DB-Server-bin.000013; mysqlbinlog /var/lib/mysql/DB-Server-bin.000013 > test.sql;
二進位制日誌的型別
基於段的日誌格式
binlog_format=STATEMENT
記錄了操作的sql語句。
優點:
日誌記錄量相對較小,節約磁碟及網路I/O,只對以一條記錄修改或插入ROW格式所產生日量小於段產生的日誌量。
缺點:
必須記錄上下文資訊,保證語句在從伺服器上的執行結果和在主伺服器上相同。
特定函式如UUID,USER()這樣非確定性的函式無法複製。
可能造成mysql複製的主備伺服器資料不一致,從而中斷複製鏈路。
顯示binlog 格式
show variables like 'binlog_format';
set session binlog_format=statement;
基於行的日誌格式
將my.ini 二進位制格式修改為binlog_format=ROW
row 的優點:row格式可以避免MYSQL複製中出現主從不一致的問題,官方推薦這種格式。同一個sql語句修改了10000條資料的情況下。基於段的日誌只會記錄這個SQL語句。基於行的日誌會有10000條記錄,分別記錄每一行資料的修改。
1.是mysql主從複製更加安全。
2.對每一行資料修改比基於段的複製高效。如果誤操作修改了資料庫中的資料,同時沒有備份可以恢復時,我們就可以通過分析二進位制日誌,對日誌中記錄的資料修改操作做反向處理的方式來達到恢復資料的目的。
row 的缺點:記錄日誌量較大
binlog_row_image=[full,minimal,noblob]
full : 記錄列的所有修改;minimal :只記錄修改的列。noblob :如果是text型別或clob欄位,不記錄 這些日誌。
使用 mysqlbinlog -vv ../data/mysql-bin.000005 檢視明細日誌。
set session binlog_row_image=minimal
混合日誌格式:
binlog_format=MIXED
特點:根據sql語句由系統決定在記錄段和基於行的日誌格式中進行選擇。資料量大小由所執行的SQL決定。
如何選擇二進位制格式
建議binlog_formart =mixed or binlog_format=row; binlog_row_image=minimal;
複製方式:
1.基於SQL語句的複製(SBR)
優點:生成日誌量少,節約網路傳輸的ID.並不要求對主從資料庫的表定義完全相同。
相比於基於行的複製方式更為靈活。
缺點:對於非確定事件,無法保證主從複製資料的一致性。對於儲存過程,觸發器
2.基於行的複製(RBR)
優點:可以應用於任何SQL的複製包括非確定性函式,儲存過程等。可以減少資料庫鎖的使用。
缺點:要求主從資料庫的表結構相同,否則就會中斷複製。
3.複製工作方式
1.主伺服器將變更寫入二進位制日誌。
2.從讀取主的二進位制日誌變更並寫入到relay_log中。
基於日誌點的複製,基於GTID的複製。
3.在從上重放relay_log中的日誌。
基於SQL段的日誌是在從庫上重新執行記錄的SQL。
基於行的日誌則是在從庫上直接應用對資料行的修改。
以上就是詳解 Mysql 事務和Mysql 日誌的詳細內容,更多關於Mysql 事務和Mysql 日誌的資料請關注我們其它相關文章!