??RocksDB內(nèi)部有WAL log文件偷线,此外栋烤,LSM tree還包含了一些SST files酿愧。每經(jīng)過一次compaction游岳,產(chǎn)出的新文件都會添加到SST files中政敢,而輸入的SST file會被刪除。然而胚迫,compaction輸入的SST file并不是立即就從SST file集合中刪除喷户,因為有可能在這些SST file上正進行著get or iterator操作。只有當冗余的SST file上沒有任何操作的時候访锻,才會執(zhí)行真正的刪除文件操作褪尝。接下來,我們會詳細介紹怎么跟進SST file上的讀寫等操作信息期犬。
??LSM tree的文件信息保存在一個命名為version的數(shù)據(jù)結(jié)構(gòu)中河哑。當compaction or memtable flush結(jié)束后,SST file就會更新龟虎,此時璃谨,RocksDB就會為最新的LSM tree創(chuàng)建一個新的version來記錄SST file信息。在某一個時刻鲤妥,只會有一個“current” version數(shù)據(jù)結(jié)構(gòu)來記錄最新LSM tree的文件信息佳吞。get or iterator操作會使用這個version記錄的文件來執(zhí)行完get or iterator的過程。在get or iterator執(zhí)行過程中涉及到的所有SST file都必須保留棉安。如果一個version上沒有任何get or iterator操作底扳,那么這個version就會被drop掉,所有沒有任何version記錄的SST files也都會被刪除掉垂券。
??剛開始時version記錄了三個文件:
v1={f1, f2, f3} (current)
files on disk: f1, f2, f3
??這時一個iterator操作使用了v1
v1={f1, f2, f3} (current, used by iterator1)
files on disk: f1, f2, f3
??此時花盐,發(fā)生了memtable flush,創(chuàng)建了一個新的version和 file 4
v2={f1, f2, f3, f4} (current)
v1={f1, f2, f3} (used by iterator1)
files on disk: f1, f2, f3, f4
??執(zhí)行了compaction操作,將f2 菇爪、f3算芯、f4 compaction為 f5,產(chǎn)生最新的version3
v3={f1, f5} (current)
v2={f1, f2, f3, f4}
v1={f1, f2, f3} (used by iterator1)
files on disk: f1, f2, f3, f4, f5
??我們可以看到凳宙,v2既不是最新的version熙揍,也沒有任何讀操作使用,所以v2以及f4將被刪除氏涩。f1届囚、f2、f3在v1中是尖,v1仍然被iterator1使用意系,所以無法刪除。
v3={f1, f5} (current)
v1={f1, f2, f3} (used by iterator1)
files on disk: f1, f2, f3, f5
??加入此時饺汹,iterator1結(jié)束了蛔添,則最新狀態(tài)為
v3={f1, f5} (current)
v1={f1, f2, f3}
files on disk: f1, f2, f3, f5
??此時,v1既不是最新的version,也沒有被任何操作引用迎瞧,所以即將被刪除夸溶,f2和f3也隨之刪除
v3={f1, f5} (current)
files on disk: f1, f5
??這些邏輯是通過引用計數(shù)來實現(xiàn)的。每個SST file和version都有一個引用計數(shù)凶硅。當創(chuàng)建一個version時缝裁,會遞增所有引用的SST file的引用計數(shù)。當一個version沒有被使用時足绅,它所包含的所有SST file的引用計數(shù)丟會遞減1捷绑。如果一個文件的引用計數(shù)為0,那么就可以被刪除了编检。
??類似胎食,每個version也都有一個引用計數(shù)扰才。當創(chuàng)建一個version時允懂,那這個version就是最新的version,引用計數(shù)遞增1衩匣。如果一個version不再是最新的version時蕾总,其引用計數(shù)會遞減1。在一個version上執(zhí)行的任何操作都會將其引用計數(shù)遞增1琅捏,這些操作計數(shù)后會將其引用計數(shù)遞減1生百。當一個version的引用計數(shù)為0時,那么這個version就要被刪除掉柄延。如果一個version上有操作在執(zhí)行或者是最新的version蚀浆,那么他的引用計數(shù)就永遠不會是0,也無法被刪除搜吧。
??有時候市俊,reader操作戶直接引用一個version,比如執(zhí)行compaction操作時的輸入version滤奈。更多情況下摆昧,reader是通過一個命名為super version的數(shù)據(jù)結(jié)構(gòu)來引用version,這個super version會記錄memtables和version的引用計數(shù)蜒程,super version其實就是a whole view of the DB绅你。在使用super version來操作version的引用計數(shù)時,reader只需要對一個引用計數(shù)執(zhí)行遞增和遞減操作就可以了昭躺。
??RocksDB的所有version信息記錄在VersionSet中忌锯,這個數(shù)據(jù)結(jié)構(gòu)也同時記錄了哪個version是當前version。由于每個column family都有一個單獨的LSM樹领炫,所以每個column family都有一個version list(其中一個是當前version)偶垮。不過,每個DB中僅且只有一個VersionSet來記錄所有column family的version s信息。