內存數據庫研發日誌之一.共享內存的詭異問題
草木瓜
20091211
一、序
數據庫在應用系統中非常複雜的,以Oracle數據庫爲例,其複雜度不亞於任何
操作系統。自已動手寫個內存數據庫,簡直就是天方夜譚。但這次我非要譚一
譚,開發一個內存數據庫。不僅包括後臺控制調用部分(考慮用C/C++實現),
而且還準備寫一個WebConsole(考慮用Java實現)。
話還沒說完,這個數據庫功能要簡單而且實用,性能要十分出色,這就是目標,
不是說要把Oracle之類打倒,那反而是癡人說夢,給你30年也搞不定。至於要
多少時間實現,只能說是慢慢來,因爲只是打算利用業餘時間。
這方面內容先前其實就有所準備,不過寫了一個非常不象樣的東西,比Oracle
第一個版本還要不象樣!想了下,這個版本,命名爲2.0,這個似乎有點象Oracle,
因爲它賣給用戶的第一個版本就是2.0。
二、共享內存
還是與Oracle一樣,使用共享內存存放數據庫數據。不過今天測試偶然發現了
一個問題,共享內存部分不能共享。問題就在於這個“部分”!
現象描述:
1. 啓動內存測試程序
[oracle@windows memdb2] ./testtablevar 123
[ERR] Memory::Open: No such file or directory
Size, Max, Hwm, HeadSize, Free, Reused, Used
------------------------------------------------------------
10000000, 2441, 1, 58644, 1, 0, 0
ID, Key, Hash, Start, Len, Pre, Next
------------------------------------------------------------
0, 0, 0, 0, 0, 0, 0
1, 0, 0, 1, 2441, 0, 0
C>
顯示如上內容,這裏其實已經創建了共享內存:
2. 查看Linux下共享內存信息
[oracle@windows memdb2] ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000123 524288 oracle 640 500000000 0
3. 重新運行程序
[oracle@windows memdb2]$ ./testtablevar 123
Size, Max, Hwm, HeadSize, Free, Reused, Used
------------------------------------------------------------
10000000, 2441, 1, 58644, 1, 0, 0
ID, Key, Hash, Start, Len, Pre, Next
------------------------------------------------------------
0, 0, 0, 0, 0, 0, 0
1, 0, 0, 0, 0, 0, 0
C>
注意,部分內存信息丟失。
There is currently no intrinsic way for a process to ensure exclusive
access to a shared memory segment. Asserting both IPC_CREAT and
IPC_EXCL in shmflg only ensures (on success) that a new shared memory
segment will be created, it doesn’t imply exclusive access to the seg-
ment.
奇怪吧~
4.在上面這個界面不退出,直接輸入命令r,p,q
C>r
C>p
ID, Key, Hash, Start, Len, Pre, Next
------------------------------------------------------------
0, 0, 0, 0, 0, 0, 0
1, 0, 0, 1, 2441, 0, 0
C>q
r作用是重新初始化內存(不調用任何內存Call,只是邏輯處理),p打印信息
5.再重新運行程序
[oracle@windows memdb2]$ ./testtablevar 123
Size, Max, Hwm, HeadSize, Free, Reused, Used
------------------------------------------------------------
10000000, 2441, 1, 58644, 1, 0, 0
ID, Key, Hash, Start, Len, Pre, Next
------------------------------------------------------------
0, 0, 0, 0, 0, 0, 0
1, 0, 0, 1, 2441, 0, 0
C>
一切正常,換一個程序查詢內存,還是沒問題!
6.問題原因
剛寫到這裏,突然知道問題所在了,就是內存地址的問題!每次打開共享
內存時一定要重新設置所有指針!
void TableVar::Open(void * _addr) {
this->m_pHead = (TTableVarHead *)_addr;
}
須改爲
void TableVar::Open(void * _addr) {
this->m_pHead = (TTableVarHead *)_addr;
this->m_pHead->data = (char *)_addr + this->m_pHead->headsize ;
this->m_pHead->chain = (TTableVarHeadChain *)( (char *)this->m_pHead + sizeof(TTableVarHead) );
}
所有的內存表類都所在這個問題!仔細回顧一下,上次不象樣的程序好象
也出過類似問題,及時寫好日誌是個非常好的辦法,害得我搞了半天!
三、後記
研發道路一定佈滿荊棘,但問題關鍵在於總結與記錄,去不斷豐富個人的
設計思想,擴展軟件知識面。最終獲得一定遠比一個不象樣的數據庫要多
得多。