您的位置:首页 > 数据库

内存数据库研发日志之一.共享内存的诡异问题

2009-12-12 20:22 302 查看
内存数据库研发日志之一.共享内存的诡异问题

草木瓜

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) );
 
}

所有的内存表类都所在这个问题!仔细回顾一下,上次不象样的程序好象
也出过类似问题,及时写好日志是个非常好的办法,害得我搞了半天!

三、后记

研发道路一定布满荆棘,但问题关键在于总结与记录,去不断丰富个人的
设计思想,扩展软件知识面。最终获得一定远比一个不象样的数据库要多
得多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息