各个工具类属于 Tianmu 引擎的核心组件,这些组件可以说是 Tianmu 的基石,由于工具类的范围广,在源码解读系列中会挑选主要的一些跟大家做分享,包括:日志系统、异常处理、堆栈跟踪、线程池、内存管理、数据压缩/解压缩等。本篇内容主要分享前面四点。

源码结构
众所周知大型项目会有巨量的代码,为了方便管理和维护,一般开发人员会根据功能模块对源代码划分为不同的目录,所以在分析大型项目时首先要知道项目中每个目录的作用是干什么的,然后再根据自己的需求去对应的目录解读对应的代码。
1. StoneDB 源码目录结构
2. Tianmu 引擎的源码目录结构

Tianmu 引擎的日志系统
Tianmu 引擎的日志类型分为了三类,系统日志、调试日志、和查询引擎执行的结果日志。其中系统的异常信息、异常情况的堆栈信息 和一些计时信息都记录在系统日志里面。 系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误。
下图为 Tianmu 引擎的日志系统结构关系图:

1. 日志系统
系统日志把日志分为了以下 7 个级别 :

使用枚举类型表示各个级别
enumLogCtl_Level { DISABLED = 0, FATAL = 1, ERROR = 2, WARN = 3, INFO = 4, DEBUG = 5, TRACE = 6 };并支持将MySQL日志级别映射到Tianmu日志级别,可以通过 设置参数 tianmu_global_debug_level 来控制日志的输出级别:

日志的级别越高输出的信息就越多,当然详细的日志信息会影响系统的运行性能,需要视情况而定。
Tianmu 的系统日志会统一落地到 MySQL 安装目录下/log/tianmu.log文件
日志系统核心类:
class utils:: LogCtl
2. 调试日志
调试日志落地到mysql安装目录下/log/trace.log文件。
由 tianmu_control_trace 该配置项控制,为1打开记录日志的开关,为0则关闭
调用接口对象:
system::Channel rccontrol
3. 查询引擎执行的结果日志
查询引擎执行的结果日志落地到 StoneDB 安装目录下/log/ query.log文件。
由 tianmu_ini_controlquerylog 该配置项控制,为1打开记录日志的开关,为0则关闭
调用接口对象:
system::Channel rcquerylog

堆栈跟踪
保存堆栈的相关信息(堆栈的函数调用和堆栈的符号信息等),方便后续调试和问题排查,目前 Tianmu 系统基于异常处理模块加上了堆栈信息的记录,如果有异常情况出现,就会把现场的堆栈信息记录下来。堆栈的调用信息会以 WARN 级别的日志信息记录在 Tianmu 的系统日志里面,日志所在的目录:StoneDB 安装目录下/log/tianmu.log文件中。
其中为了获得堆栈信息,Tianmu 这里使用了 glibc中提供的 backtrace() 和 backtrace_symbols() 两个函数来输出和解析程序的 call stack,并使用 g++ 中的 abi::__cxa_demangle 来 demangle (将C++ ABI标识符(C++ ABI identifier)转换成C++源程序标识符(original C++ source identifier)的过程称为demangle。更简单的说,识别C++编译以后的函数名的过程,就叫demangle。)
调用函数接口:
GetStackTrace();

异常处理
Tianmu支持的异常处理类型如下图:

异常处理的流程图如下:

出现异常后Tianmu 系统会把异常信息,和出现异常逻辑的堆栈调用信息以WARN级别的日志信息记录在Tianmu的系统日志里面,日志所在的目录:StoneDB安装目录下/log/tianmu.log文件中。
异常处理模块核心基类:
class common:: Exception

线程池
Tianmu 的线程是基于 C++ 新特性实现的
线程池核心类:
class utils::thread_pool
其具有以下优点:
1.线程池类型
目前Tianmu引擎基于此线程池类定义了以下四类线程池
延迟插入线程池
主要功能是将 insert buffer 中的数据加载到数据库
utils::thread_pool delay_insert_thread_pool;
加载导入线程池
主要功能是把插入和导入的数据落地到磁盘
utils::thread_pool load_thread_pool;
查询处理线程池
为查询过程中提供并行处理的能力
utils::thread_pool query_thread_pool;
delete & update 执行线程池
为 delete 和update 执行接口提供并行执行的功能
utils::thread_pool delete_or_update_thread_pool
各类线程池和其中加入的线程执行体如下图所示:

2.线程池初始化流程
线程池初始化的过程是在 StoneDB 系统启动的过程中进行的初始化,主要是为各类线程池初始化实例对象,设置各类线程池的类型,和线程池的大小。
下图为线程初始化过程 StoneDB 系统调用的流程:

以上是本文全部内容。
如果您对我们的源码感兴趣,欢迎到我们的 GitHub 代码仓库阅读查看,觉得不错记得点个 Star 哦~
StoneDB 代码仓库: https://github.com/stoneatom/stonedb
StoneDB 社区官网: https://stonedb.io/
