- 論壇徽章:
- 9
|
本帖最后由 wlmqgzm 于 2016-05-11 16:37 編輯
存儲(chǔ)層的整體數(shù)據(jù)規(guī)劃思路已經(jīng)全部完成:
整體流程在腦海中完整的過了一遍.
塊數(shù)據(jù)的整體設(shè)計(jì)思路已經(jīng)完成, 正在書寫當(dāng)中, 基本上確定, 存儲(chǔ)層的數(shù)據(jù)格式完整支持MVCC和數(shù)據(jù)庫SQL標(biāo)準(zhǔn)的全部四個(gè)隔離級別: 即read uncommited, read commit, repeatable read,serializable.
比最早的想法又進(jìn)了一步, 最早沒有打算實(shí)現(xiàn)這些, 隨著數(shù)據(jù)規(guī)劃, 發(fā)現(xiàn) 在數(shù)據(jù)層的定義中 只需要修改少量關(guān)鍵字節(jié), 就可以實(shí)現(xiàn)與innodb格式完全一致的功能.
因此, 初步計(jì)劃出2個(gè)版本;
2個(gè)版本在硬盤存儲(chǔ)格式上完全一致, 只是軟件功能上做了擴(kuò)展.
第一個(gè)版本1.00 按照KV數(shù)據(jù)庫的標(biāo)準(zhǔn)做, 實(shí)質(zhì)是實(shí)現(xiàn)read uncommited的SQL隔離級別版本. 先做這個(gè)版本.
第二個(gè)版本2.00 按照SQL數(shù)據(jù)庫的標(biāo)準(zhǔn)做, 再陸續(xù)增加read commit, repeatable read,serializable這三個(gè)SQL隔離級別版本,
其中repeatable read 在目前的數(shù)據(jù)規(guī)劃中, 與innodb類似, 實(shí)現(xiàn)了幻讀保護(hù), 即 repeatable read=serializable,
準(zhǔn)確的說, 將實(shí)現(xiàn)兩個(gè)SQL隔離級別. 在性能上, repeatable read將與read commit很接近, 主要的差別在于緩存中有效數(shù)據(jù)的多少,
我的規(guī)劃實(shí)現(xiàn)中 repeatable read 將利用空間保護(hù)(offset隔離), 實(shí)現(xiàn)幻讀保護(hù), 沒有像innodb一樣使用間隙鎖, 因此性能將更好一些.
今天心情比較高興,自己也很意外,基本上按照KV數(shù)據(jù)庫的標(biāo)準(zhǔn),實(shí)現(xiàn)了SQL數(shù)據(jù)庫的全部功能點(diǎn)的設(shè)計(jì),而且全部是高性能設(shè)計(jì),做完的話,會(huì)有比較好的性能
主要的技術(shù)難題的突破在MVCC的設(shè)計(jì),找到了一條覆蓋各類情況的模型.
設(shè)計(jì)壓縮塊/標(biāo)準(zhǔn)塊的結(jié)構(gòu):
// 1) 塊的位置號, 就是塊的唯一標(biāo)志, 位置號就是offset, 4字節(jié)整數(shù), 位置號==實(shí)際存儲(chǔ)的offset, 即該位置上讀到的4字節(jié)數(shù)據(jù)==該位置的offset
// 2) 塊的壓縮格式及壓縮率: 1字節(jié), 0=不壓縮, 1-9=lz4壓縮, 21-29=gzip壓縮, 31-39=bzip2, 先只做lz4, 其他備用
// 3) 塊內(nèi)部記錄數(shù):1字節(jié). 每個(gè)數(shù)據(jù)塊可存放1-240條記錄, 標(biāo)準(zhǔn)塊是一條記錄一個(gè)塊, 壓縮塊是1-240個(gè)記錄一個(gè)塊
這里保留了241-255的編號, 這些編號主要是為了未來(第2個(gè)版本)預(yù)留,
這些編號對應(yīng)的內(nèi)存結(jié)構(gòu), 在硬盤空間中沒有使用,
在內(nèi)存空間中使用, 將以特殊的方式, 提供高性能虛擬鎖
每個(gè)編號將在主鍵上以特殊方式(類似于MVCC)提供4M個(gè)鎖空間, 一共可以提供60M個(gè)鎖空間,即每個(gè)table可提供最大6000萬個(gè)鎖空間
將用于 存儲(chǔ)層的行鎖--更新鎖內(nèi)部使用, 這部分代碼還沒有做, 但是計(jì)劃在第2個(gè)版本中使用, 使用行鎖以后, 將提供完整MVCC和READ COMMIT等數(shù)據(jù)庫標(biāo)準(zhǔn)功能
第2個(gè)版本將實(shí)現(xiàn)完整的MVCC, 讀取是沒有任何鎖, 可提供高的性能. MVCC在第一個(gè)版本中做好預(yù)留, 但是不占數(shù)據(jù)內(nèi)存空間, 以便提供最好的性能
行鎖是寫鎖,即更新鎖, 正在考慮 不過都是第2個(gè)版本的事情, 這個(gè)版本只是做好預(yù)留, 按最簡單的方式實(shí)現(xiàn)
這個(gè)字節(jié)的關(guān)鍵設(shè)計(jì)在于它定位于內(nèi)存中8字節(jié)長整數(shù)offset的最高位,對于1-240的值將直接掩碼轉(zhuǎn)換為8bit全零的offset+1-240兩個(gè)參數(shù),對于241-255這個(gè)部分+3字節(jié)將轉(zhuǎn)化為一個(gè)最大60M的整數(shù),這個(gè)整數(shù)用atomic表示,依次循環(huán)使用這個(gè)參數(shù),最大可表示60M個(gè)正在更新中的數(shù)據(jù),實(shí)現(xiàn)最大6000萬個(gè)虛擬鎖,對于超過用戶自身offset中的數(shù)據(jù), 用戶級別的MVCC是不可見的, 因此,任何在此位置上的更新,將不會(huì)被任何用戶讀取.
說了半天,其實(shí)就是一句話, 在沒有增加新字節(jié)的情況下,實(shí)現(xiàn)了與MVCC以及事務(wù)處理的全兼容功能.所以,就是高效的實(shí)現(xiàn).
一種激進(jìn)的思路:所有的更新是MVCC的,這樣每個(gè)線程都可以提交請求更新數(shù)據(jù),但是最終的Commit是單寫線程的,這樣可以實(shí)現(xiàn)最大化的并發(fā),考慮中.......
// 3) 塊的大小, 1-5字節(jié)整數(shù), 壓縮編碼整數(shù), 表示未壓縮的長度
// 4) 塊的大小, 1-5字節(jié)整數(shù), 壓縮編碼整數(shù) 表示壓縮后實(shí)際的長度,如果不壓縮,同上一個(gè)值
// 5) 塊的內(nèi)容 0K--3.999G
// 6) 塊的校驗(yàn)碼: 8字節(jié), 塊內(nèi)容crc64校驗(yàn)
// 7) 塊的同步碼 8字節(jié)
// 塊的管理用掉 4+1+1+3+3+8+8=28字節(jié) , 對于4K字節(jié)的壓縮塊, 大約不到1%的開銷,
|
|