oceanbase之RootServer(1)
1 概述
我们从Root Server开始分析。Root Server主要是提供命名服务,管理数据库系统的meta信息,管理ChunkServer,Root Server对集群的管理主要基于lease租约机制。Root Server使用HA主备机制来提高可用性。由HA检测master/slave节点的状态,如果master节点不可用,则虚拟IP会自动漂移到slave节点,slave节点接着提供服务。这块具体见《OceanBase介绍》。
2 Server框架
2.1 简单类框架
Oceanbase使用了tbnet网络框架,其服务基类ObBaseServer就是派生自tbnet::IServerAdapter类,继承这类需要实现handlePacket这两个操作接口。
关于tbnet框架的简单介绍,见《tbnet框架简介》。
这个鸟毛的类里面,start_service接口是public,但实际上代码里调用的地方只有一处,就是在start()函数里。如果是protected的就不会引起歧义了。
这个类里面的IPacketFactory、PacketStreamer和Transport都是tbnet网络框架定义的类,与底层网络和数据包相关。
几个相关函数:
1 虚函数initialize()给了实现类一个初始化机会;
2 函数start是服务启动程序;
3 发送response packet都是统一的,这个封装在函数send_response()中;
2.2 服务启动、停止
启动流程也就是start()函数,首先调用initialize()让继承类完成自己的初始化工作;后面就是tbnet相关的必要初始化事项,为packet streamer设置packet factory,并启动Transport;最后调用start_service()启动服务。
停止直接调用接口stop()即可,先将stopped_置为true,然后调用destroy(),给继承类一个做清理工作的机会,最后关闭Transport。
2.3 发送响应
函数send_response根据传入的参数构建一个ObPacket,然后设置packet数据,调用sereialize()方法序列化为byte stream,最后调用connection的postPacket()方法发送出去。
int ObBaseServer::send_response(const int32_t pcode, constint32_t version,
const ObDataBuffer& buffer,
tbnet::Connection* connection, const int32_t channel_id)
流程其实很简单,还是搞个流程图吧。
3 从main函数开始
3.1 BaseMain基类
没办法,只能从启动函数开始看,找线索。Root Server的main函数相当简单,在ob_rt_main.cpp中,创建了BaseMain对象,然后直接调用其start接口启动服务。最后调用destory接口在结束时释放资源。简单点就是:
BaseMain*pmain = ObRootMain::get_instance();
pmain->start(argc,argv, "root_server");
pmain->destroy();
这个是个虚类,没啥东西,就是一个简单的框架,先看看类声明:
1 两个public接口,就像前面main()里面调用的那样。也是virtual的,不过一般子类不会重写。
virtual int start(const int argc,char *argv[], const char* section_name);
virtual void destroy();
2 几个protected函数,干活的部分do_work()是纯虚的,子类必须实现。
virtual void do_signal(const int sig);
void add_signal_catched(const int sig);
virtual void print_usage(const char*prog_name);
virtual void print_version();
virtual const char*parse_cmd_line(const int argc, char *const argv[]);
virtual int do_work() = 0;
但是get_instance函数确定义在ObMainRoot类里,这有些tricky。类BaseMain在common模块中,但是get_instance却散落在子模块中。
比如Root Server,它就在ObMainRoot中;Chunk Server,它在ObChunkServerMain中,直接返回ObChunkServerMain对象。
在start()函数中,BaseMain做一些配置工作,最后调用do_work()。
3.2 ObMainRoot类
显然目标指向了ObMainRoot类,它在文件ob_root_main.h/cpp中。它重载了两个接口do_work和do_signal。还有一个成员ObRootWorker worker对象。
依然来个类图:
在do_work中,首先设置一些关注的signal,在设置了worker的一些属性后,直接调用worker.start()开启服务,可见它是个框,真正干活的是ObRootWorker类。基本函数逻辑如下:
add_signal_catched(START_REPORT_SIG);
add_signal_catched(START_MERGE_SIG);
add_signal_catched(DUMP_ROOT_TABLE_TO_LOG);
add_signal_catched(DUMP_AVAILABLE_SEVER_TO_LOG);
add_signal_catched(SWITCH_SCHEMA);
add_signal_catched(RELOAD_CONFIG);
add_signal_catched(DO_CHECK_POINT);
add_signal_catched(DROP_CURRENT_MERGE);
add_signal_catched(CREATE_NEW_TABLE);
worker.set_listen_port(port)
worker.set_dev_name(dev_name)
worker.set_config_file_name(config_file_name_)
worker.set_packet_factory(&packet_factory_)
worker.start()
另外这些所谓的signal并不是系统signal,而是OceanBase自定义的系统事件。