事務是指作為單個邏輯工作單元執行的一系列操作,這些操作要麼全做,要麼全不做,是乙個不可分割的工作單元。
事務開始之前和事務結束之後,資料庫的完整性限制未被破壞。
約束一致性:資料庫中建立表結構時所指定的外來鍵、check、唯一索引等約束。在 mysql 中不支援 check ,只支援另外兩種。
資料一致性:是乙個綜合性的規定,是由原子性、永續性、隔離性共同保證的結果。
一致性可以歸納為資料的完整性。資料的完整性是通過其他三個特性來保證的,包括原子性、隔離性、永續性,而這三個特性,又是通過 redo/undo 來保證的,正所謂:合久必分,分久必合,三足鼎力,三分歸晉,資料庫也是,為了保證資料的完整性,提出來三個特性,這三個特性又是由同乙個技術來實現的。
事務的所有操作,要麼全部完成,要麼全部不完成,不會結束在某個中間環節。
即要麼改了,要麼沒改,使用者感受不到乙個正在改的狀態
mysql 是通過 wal(write ahead log)技術來實現這種效果,如果事務提交了,那改了的資料就生效了,如果此時 buffer pool 的髒頁沒有刷盤,就需要使用 redo 日誌恢復出來的資料。而如果事務沒有提交,且 buffer pool 的髒頁被刷盤了,那這個本不應該存在的資料的消失就需要通過 undo 來實現,而undo 又是通過 redo 來保證的,所以最終原子性的保證還是靠 redo 的 wal 機制實現的。
每乙個寫事務,都會修改 buffer pool,從而產生相應的 redo 日誌,這些日誌資訊會被記錄到 ib_logfiles 檔案中。因為 redo 日誌是遵循 write ahead log 的方式寫的,所以事務是順序被記錄的。
在 mysql 中,任何 buffer pool 中的頁被刷到磁碟之前,都會先寫入到日誌檔案中,這樣做有兩方面的保證。
如果 buffer pool 中的這個頁沒有刷成功,此時資料庫掛了,那在資料庫再次啟動之後,可以通過 redo 日誌將其恢復出來,以保證髒頁寫下去的資料不會丟失,所以必須要保證 redo 先寫。
因為 buffer pool 的空間是有限的,要載入新頁時,需要從 lru (最近最少使用)鍊錶中淘汰一些頁,而這些頁必須要刷盤之後,才可以重新使用,那這時的刷盤,就需要保證對應的 lsn (log sequence number,日誌序列號)的日誌也要提前寫到 ib_logfiles 中,如果沒有寫的話,恰巧這個事務又沒有提交,資料庫掛了,在資料庫啟動之後,這個事務就沒法回滾了。所以如果不寫日誌的話,這些資料對應的回滾日誌可能就不存在,導致未提交的事務回滾不了,從而不能保證原子性,所以原子性就是通過 wal 來保證的。
事務完成之後,事務所做的修改進行持久化儲存,不會丟失。
永續性,就是指乙個事務一旦提交,它對資料庫中資料的改變就應該是永久性的,接下來的操作或故障不應該對其有任何影響,通過原子性,即便是遇到宕機,也可以從邏輯上將資料找回來後再次寫入物理儲存空間,這樣就從邏輯和物理兩個方面保證了資料不會丟失,即保證了資料庫的永續性。
乙個「提交」動作觸發的操作有:binlog 落地、傳送 binlog、儲存引擎提交、flush_logs, check_point、事務提交標記等。這些都是資料庫保證其資料完整性、永續性的手段。
通過原子性可以保證邏輯上的永續性,通過儲存引擎的資料刷盤可以保證物理上的永續性。這個過程與前面提到的 redo 日誌、事務狀態、資料庫恢復、引數 innodb_flush_log_at_trx_commit 有關,還與 binlog 有關。在資料庫恢復時,如果發現某事務的狀態為 prepare,則會在 binlog 中找到對應的事務並將其在資料庫中重新執行一遍,來保證資料庫的永續性。
當多個事務併發訪問資料庫中的同一資料時,所表現出來的相互關係。
即乙個事務內部的操作及使用的資料對其他的併發事務是隔離的,乙個事務的執行不能被其他事務干擾
innodb 支援的隔離性有 4 種,隔離性從低到高分別為:讀未提交、讀提交、可重複讀、可序列化。
讀未提交(ru,read uncommitted)。它能讀到乙個事務的中間過程,違背了 acid 特性,存在髒讀的問題,所以基本不會用到,可以忽略。
讀提交(rc,read committed)。它表示如果其他事務已經提交,這也是一種最普遍適用的級別。但由於一些歷史原因,可能 rc 在生產環境中用的並不多。
可重複讀(rr,repeatable read),是目前被使用得最多的一種級別。其特點是有 gap 鎖、目前還是預設的級別、在這種級別下會經常發生死鎖、低併發等問題。
可序列化,這種實現方式,其實已經並不是多版本了,又回到了單版本的狀態,因為它所有的實現都是通過鎖來實現的,所以實際上並不是多版本控制,它的特點也很明顯:讀鎖、單版本控制、併發低。
具體說到隔離性的實現方式,通常用 read view 表示乙個事務的可見性。 rc 級別的事務可見性比較高,它可以看到已提交的事務的所有修改。而 rr 級別的事務,則沒有這個功能,乙個讀事務中,不管其他事務對這些資料做了什麼修改,以及是否提交,只要自己不提交,查詢的資料結果就不會變。
隨著時間的推移,讀提交每一條讀操作語句都會獲取一次 read view,每次更新之後,都會獲取資料庫中最新的事務提交狀態,也就可以看到最新提交的事務了,即每條語句執行都會更新其可見性檢視。而反觀下面的可重複讀,這個可見性檢視,只有在自己當前事務提交之後,才去更新,所以與其他事務是沒有關係的。
在 rr 級別下,長時間未提交的事務會影響資料庫的 purge 操作,從而影響資料庫的效能,所以可以對這樣的事務新增乙個監控。
它們之間的相互關係,其中,4 個特性中有 3 個與 wal(write ahead log,顧名思義,在寫資料到磁碟之前先寫入log檔案中) 有關係,都需要通過 redo、undo 日誌來保證等。
Mysql學習筆記二
接著上面繼續學習,下面主要是以索引為主。建立索引 有四種型別的索引 主鍵 唯一索引 全文索引和普通索引 它是值惟一並且沒有值為null的域的索引。如 create table tablename filename columntype not null,filedname2.primary key ...
mysql學習筆記(二)
在具體應用中,需要實現在乙個查詢語句中顯示多張表的資料,這就是所謂的多表資料連線查詢,簡稱連線查詢。1.並 把具有相同字段數目和字段型別的表合併到一起。2.笛卡爾積 這個比較難懂,還是直接上圖 3.內連線 inner join 為了便於使用者操作,mysql專門提供了一種針對資料庫操作的運算 連線。...
Mysql學習筆記(二)
上次學習了mysql安裝,登入和退出等基本操作,以及建立,修改,刪除資料庫的基本指令重點注意mysql基本的語法規範。這篇博文主要介紹mysql幾種資料型別,以及資料表的基本內容。mysql主要有有下面幾種資料型別,包括整型,浮點型,字串型以及日期時間型。具體內容如下表所示 整型資料型別 儲存範圍 ...