C-Store是一个基于列存的OLAP数据库,他是由数据库业界大名鼎鼎的Mike Stonebraker带队完成的。在这个数据库实现中应用了压缩态运算、projection等诸多在当时看似很神奇的技术,后来该团队和产品被HP收购,并发展成为一个成功的商业版本——Vertica。
目前C-Store能找到的最后开源版本是0.2, 可以参考C-Store: A Column-Oriented DBMS。不过由于该代码发布于2006年,所用到的其他软件和OS版本(Fedora Core 3)很低,作者已经不保证能在当前的系统环境下编译使用。笔者为了分析该实现所用到的一些技术,对源码进行了编译安装工作,将其移植到CentOS 7。
下面是这个过程一些关键操作的记录,供大家参考。
用到的环境和其他软件
- CentOS 7: gcc和make使用系统自带的,磁盘剩余空间20GB以上。我是将OS安装在VirtualBox下,增加了辅助扩展。
- g++:如果系统安装不自带,手动安装
- Berkely DB 4.8.30:原来使用的是4.2,(备注:尝试6.1.29遇到了问题,版本跨度太大,怀疑接口有变。如果你成功了,请告诉WilliamLeoV@163.com方法, 谢谢!)
- LZO 2.09:原来使用的是1,尽管库使用2.0版本,但使用的头文件都是1.0版本的。
软件安装部署的过程
安装CentOS
这个无需多说,按照development集合安装,勾选开发库。额外可能需要安装bison(3.0.4), flex(2.6.0)。
安装Berkely DB
- 解压源码到适当的目录,在build_unix下
[cstore@bogon build_unix]$ ../dist/configure --enable-cxx
我没有遇到任何错误提示,如无特殊说明,下同。 - [cstore@bogon build_unix]$ make
- [cstore@bogon build_unix]$ sudo make install
软件会被安装在/usr/local/BerkeleyDB.4.8
安装LZO
- 与一般软件编译安装过程相同,解压、配置、编译、安装。
[cstore@bogon lzo-2.09]$ ./configure - [cstore@bogon lzo-2.09]$ make
- [cstore@bogon lzo-2.09]$ sudo make install
安装在/usr/local/lib
安装glog
- 与一般软件编译安装过程相同,解压、配置、编译、安装。
[cstore@bogon glog-0.3.4]$ ./configure - [cstore@bogon glog-0.3.4]$ make
- [cstore@bogon glog-0.3.4]$ sudo make install
安装在/usr/local/lib
准备好以后主角C-Store闪亮登场
编译安装C-Store
- 解压,修改Build目录下的makefile.init文件,将其中的Berkeley DB和LZO路径配置正确,并修正版本号
SLEEPYCAT_DIRECTORY := /usr/local/BerkeleyDB.4.8
LZO_LIB := /usr/local/lib
修改库版本号
LIBS := -ldb-4.8 -ldb_cxx-4.8 -lpthread -llzo2 -lglog # -lglog是新引入的第三方库用于日志输出,后续介绍 - 生成数据
[cstore@bogon src]$ make data
此时需要从internet上下载http://db.csail.mit.edu/data/data4.tar.gz自动下载需要15hr,实在难以接受。可以使用工具提前下载好,放在适当的目录,然后修改cstore-0.2/data/下的getData为
touch somethingToRemove
#ls -1 | grep -v getData | xargs rm
#wget http://db.csail.mit.edu/data/data4.tar.gz;
#wget http://db.csail.mit.edu/data/D6.data.ros.gz;
gunzip -c /media/sf_VM_Shared/CStore/D6.data.ros.gz > ./D6.data.ros;
tar -xzvf /media/sf_VM_Shared/CStore/data4.tar.gz;
#rm data4.tar.gz
这时候再执行make data就不需要下载了,同时会保留原始的数据文件压缩包,如果不需要了可以手动删除。至于第二行代码是否注掉,随意。
- 编译debug版本,其他选项可以参考makefile。
1. 修改Build/makefile.init
在CFLAGS后添加-DHAVE_CXX_STDHEADERS
添加LZO_INCLUDE := /usr/local/include/lzo,同时 IFLAGS后面添加 -I$(LZO_INCLUDE)。虽然lzo已经到了2.0版本,但接口原因只能用lzo1x.h。2. 对于src目录下的头文件的包含操作去掉.h,shell下快速替换sed -i "s/OLD_STRING/NEW_STRING/g" `grep "OLD_STRING" -rl *`
#include <iostream.h>
#include <fstream.h>
#include <hash_map.h>
#include <list.h>3. 有些类成员函数定义会报类似于error: extra qualification ‘CatalogInstance::’ on member ‘getColumns’ [-fpermissive]错误。去掉斜体的"类名::"即可。
AM/CatalogInstance.h:159:26 CatalogInstance::getColumns();
UnitTests/BAndOpTest.h:63:8 BAndOpTest::runTestCase1();
UnitTests/BAndOpTest.h:64:8 BAndOpTest::runTestCase2();
UnitTests/BOrOpTest.h:63:8 BOrOpTest::runTestCase1();
UnitTests/BOrOpTest.h:64:8 BOrOpTest::runTestCase2();
UnitTests/BNotOpTest.h:62:7 BNotOpTest::runTestCase1();
UnitTests/BNotOpTest.h:63:7 BNotOpTest::runTestCase2();
parser/ListProjections.h:74:11 ListProjections::addTupleAlias();4. 在common/DataSource.cpp的case Predicate::OP_EQUAL:下面使用{}限定局部变量范围
common/DatasourceFilters.cpp的case Predicate::OP_EQUAL:同理5. 在common/PosPair.h中添加#include <assert.h>
6. 在如下文件中添加#include <memory.h>
Wrappers/PosArrayBlock.h
Util/BDBFile.h7. 缺少stdlib.h的引用,会导致free,malloc,atoi,endl等找不到,以下文件中添加#include <stdlib.h>
Wrappers/Encoder/Encoder.h
common/Block.h //同时添加using namespace std;
Util/StopWatch.h //同时添加using namespace std;
Util/BDBFile.h //同时添加using namespace std;8. 将Util/BDBFile.cpp中的dbHandle->stat(&pStat, 0)添加1个参数dbHandle->stat(NULL, &pStat, 0);
9. UnitTests/HashMapTest.cpp中HashMapTest::run()修改
if ((int)map->get(&x) != c) 改为 if (*((int*)map->get(&x)) != c),其余相同
int a = (int)map->remove(k) 改为 void* a = map->remove(k)
好了,终于肯以正式编译程序了
[cstore@bogon src]$ make debug #如果使用make debu2则遇到错误时会立刻停下
正常情况下会编译成功,如果有问题请参考上面的步骤。生成的文件在 cstore/src/目录下
执行./cstoreqptest即可执行单元测试或输入SQL执行,不过多半你会遇到程序错误退出。
使用cgdb调试发现,在读取解析配置文件时如果遇到空行会出现该问题。是修改代码或配置文件,相信对想要分析cstore的人而言都是小菜一碟。
此次我们就介绍到这里。后续计划先简单介绍在cstore中使用glog库调试,然后再展开分析cstore 0.2的源码。