上一篇,已經寫了查詢語句的執行過程,那麼更新語句難道還不一樣?
答案是肯定的。
一、更新準備
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)刷髒頁到磁盤,這個時間不定。