mongodb的MMAPV1存儲引擎鎖的最小粒度為Collection級別,包括讀鎖(S)、寫鎖(X),並且還提供了意向讀鎖(IS)、意向寫鎖(IX),意向鎖會加在比讀寫鎖更高的粒度上,比如在Collection上加了讀鎖,相應的會在db、global加意向讀鎖。
意向鎖並不是真正的鎖,只是表達了加鎖的意向,所以意向鎖之間是互相兼容的。X鎖和任何鎖都是互斥的,包括IX鎖,比如當前要更新Collection中的一個document,使得該Collection被加了X鎖,IX鎖會自動加載Collection所在db、global上,此時如果要在db級別做更新操作就需要在db上加X鎖,由於db上已經有了IX鎖,所以db級別的更新操作被阻塞。
意向鎖的意義在於讓更大級別的更新操作可以立即看到是否有小級別的更新操作在進行(如果沒有意向鎖,大更新操作要判斷是否有小更新操作在進行,就需要遍歷整個表),如果有,則大操作需要等待小操作釋放鎖(從而釋放意向鎖),如果沒有,則可以放心的進行大操作。
S X S + - X - -
IS IX S X IS + + + - IX + + - - S + - + - X - - - -
IS → IS → X → X → S → IS
如果是嚴格FIFO,則只有前兩個IS鎖可以被授權,但mongodb會授權隊列中所有的IS、S鎖,即便是此時新入隊的IS、S鎖,當IS、S鎖釋放后才會授權后面的X鎖。這點與mysql不同,經測試mysql是嚴格的FIFO。
mongodb並不支持事務,即mongodb無法保證多個操作的原子性,比如先find后update,但其通過鎖機制可以保證每一個操作的原子性,比如findAndUpdate。
參考:https://docs.mongodb.com/manual/faq/concurrency/
