reserved state進入reserved state以後,sqlite可以修改資料庫中的內容,不過把修改以後的內容寫到pager的緩存里,大小由page cache指定。進入這個狀態以後,pager開始初始化日誌文件,用戶回滾和異常恢復。(其實就是把日誌中的文件內容拷貝到資料庫文件中去)這... ...

- reserved state
進入reserved state以後,sqlite可以修改資料庫中的內容,不過把修改以後的內容寫到pager的緩存里,大小由page cache指定。 進入這個狀態以後,pager開始初始化日誌文件,用戶回滾和異常恢復。(其實就是把日誌中的文件內容拷貝到資料庫文件中去) 這種機制使得資料庫在進行寫操作時可以同時進行讀操作。 不過由於只有一個reserved或exclusive鎖,所以只能有一個寫操作 - pending state
從reserved到exclusive要經歷一個pending state,即獲取pending鎖。 pending是一個gateway lock。- 不會有事務從unlock狀態到shared狀態,保證了不會有新的讀操作和寫操作
- 已經擁有shared鎖的事務可以正常運行。寫事務等待著這些事務的完成,釋放鎖。
- Exclusive state
當其他所有的資料庫鏈接都釋放了鎖之後,整個資料庫就只有一個寫操作的事務了。進入Exclusive狀態。- pager檢查日誌文件已經被寫到了磁碟中,調用fsync()系統調用(如果這個系統調用掛了,SQlite也沒辦法)
- 如果SYNCHRONOUS PRAGMA是預設的設置,會調用一次sync操作。
- 如果SYNCHRONOUS PRAGMA是FULL,會調用兩次sync操作
- 如果SYNCHRONOUS PRAGMA是NONE,不會調用sync操作
- pager把已經修改完的內容寫入資料庫文件
- 清理日誌文件,釋放鎖
- pager檢查日誌文件已經被寫到了磁碟中,調用fsync()系統調用(如果這個系統調用掛了,SQlite也沒辦法)
鎖實現的原理

SQLite鎖的實現是基於標準的文件鎖。SQlite在資料庫文件上有三個鎖,1個reserved byte,一個pending byte以及一個shared region。
- unlocked->shared
獲取pending byte的讀鎖。獲取成功以後,在shared region隨機獲得一個byte的讀鎖,並釋放pending byte的讀鎖。 - shared->reserved
獲取reserved byte的寫鎖即可。 - reserved->exclusive
首先獲取pending byte的寫鎖。
一旦成功,那麼由於pending byte已經被鎖定,因此不會有unlocked->shared。 接下來,會嘗試獲取整個shared region的寫鎖。 由於shared region有一些被active的事務持有讀鎖,因此資料庫會等待這些事務完成並釋放鎖。
恢復機制
使用reserved byte來決定是否需要恢復。
一般來說,日誌文件和reserved lock是同步的,即同時出現和消失。
如果SQLite發現了日誌文件,卻沒有發現reserved lock,那麼可以認為發生了crash或系統掉電。
當pager首次打開資料庫或從資料庫文件讀取到記憶體時,會做一個完整性檢查。如果發現不一致(有日誌文件卻沒有reserved lock),那麼資料庫進入恢復模式。此時的資料庫日誌文件叫做hot journal。
進入恢復模式以後,會直接從shared狀態進入pending狀態,如第一個圖的灰線所示。這樣子可以保證
1. 不會有新的資料庫連接
2. shared狀態的資料庫連接不會進入恢復模式(實際上不會發生,因為第一個資料庫連接會進入恢復模式,從而阻塞其他的資料庫連接進入shared狀態)
簡單的說,一個hot journal就是一個implicit exclusive鎖。如果寫操作crash了,那麼在其他資料庫連接成功恢複數據庫以前,資料庫不會有其他操作。crash以後第一個操作資料庫的pager會看到hot journal,併進行資料庫恢復。
關於文件鎖
File locks really are just flags within the operating system kernel, usually. (The details depend on the specific OS layer interface.) Hence, the lock will instantly vanish if the operating system crashes or if there is a power loss. It is usually also the case that the lock will vanish if the process that created the lock exits.