内存数据库研发日志之一.共享内存的诡异问题
草木瓜
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) );
}
所有的内存表类都所在这个问题!仔细回顾一下,上次不象样的程序好象
也出过类似问题,及时写好日志是个非常好的办法,害得我搞了半天!
三、后记
研发道路一定布满荆棘,但问题关键在于总结与记录,去不断丰富个人的
设计思想,扩展软件知识面。最终获得一定远比一个不象样的数据库要多
得多。