一條更新語句的執行過程

上一篇,已經寫了查詢語句的執行過程,那麼更新語句難道還不一樣?

答案是肯定的。

一、更新準備

update語句其實都會有一個隱藏的查詢更能,將需要修改的數據找到,然後才能更新。

其實這一階段跟查詢是一樣的。

二、更新

既然獲取到了數據,那麼要更新,這接下來的事都是與查詢sql多操作的了。

先知識擴展一下:

1.mysql中的日誌

這裏只介紹三種日誌:

1)binlog日誌

二進制日誌,也叫歸檔日誌。它是mysql中server層的日誌。

2)redo log

重做日誌,是innodb層面的日誌。它保證了事物的持久性。這裏涉及到了WAL技術,先寫日誌,在寫磁盤。

3)undo log

回滾日誌,用於事物回滾的。它保證了事物的原子性。

注:

一、undo log不是redo log的逆向日誌。

1)redo log是物理日誌,記錄的是一個頁的修改,它與更新數據無關。即redo log沒有能力去更新數據庫的一條數據。它的作用是如果意外重啓,將數據庫與其不一樣的數據頁加載到內存,根據redo log更新頁,這時候的頁與數據庫中的頁不一致,稱爲髒頁。最終數據落盤,稱刷髒頁。這個刷髒頁的過程與redo log一點關係也沒有。

2)undo log 是記錄的某個版本,是邏輯日誌,根據某行進行恢復。

二、redo log的寫入

redo log日誌是先寫入一個redo log buffer緩存中,然後間隔1s或者達到其內存一半時,write到怕page cache中,然後持久化到磁盤。這個過程中,也會存在未提交的事物被持久化到磁盤的情況。

2.mysql中的鎖

事物的四個特性:

原子性、一致性、隔離性、持久性。

上面我們已經知道了原理性、持久性是由日誌來實現的。那麼一致性和隔離性呢?

爲了保證原子性,引入了隔離性,那麼隔離性又怎麼處理呢?

答案是使用鎖。

mysql的默認隔離級別是可重複讀,那我們更新一條數據,如何使用鎖來實現隔離性呢?

討論是在有更新where條件有索引的基礎上進行:

1)更新條件是非唯一索引

這裏涉及到了回表,假如如下sql:

update user set age='30' where name='b'

其中name是非唯一索引。

2)當name是唯一索引

3)主鍵索引

知識點儲備到這裏,那麼update更新怎麼操作的,

1)獲取鎖,獲取不到就沒有修改的權限,就直接等待就行了。

2)寫日誌,將undo log、redo log、binlog寫入。

3)刷髒頁到磁盤,這個時間不定。

 

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