OceanBase 是一个分布式关系型数据库,其以单进程多线程的方式运行。线程和资源的管理是保证数据库性能和稳定性的重要因素。
线程分类
OceanBase 数据库的线程可以大致分为以下几类:
SQL或transaction worker: 处理 SQL 和事务请求的线程。net io: 处理网络 IO 的线程。disk io: 处理磁盘 IO 的线程。compaction worker: 处理minor merge,major merge的线程。clog writer: 写 clog 的线程。election worker: 选举线程。misc timer:包括多个后台定时器线程,主要负责清理资源。
注意
在 OceanBase 数据库 V4.x 版本中,除 net io 和 disk io 以外,以上所有线程基本都拆分了租户。
除此之外还有一批 RootServer 专有的线程和少量特定用途的后台线程。
线程与租户的对应关系
上面列出的线程中,SQL 和事务的处理线程是分租户的,也即每个租户都有自己的一套 SQL 或 transaction worker。其它线程是多租户共享的。
线程是如何管理的
OBServer 尽量避免动态创建线程,基本上所有线程都是启动之后就创建好了,之后除非调整配置项,否则线程数基本不会再变化。
某个租户在特定 OBServer 上的 SQL 和 transaction worker 的线程数是由租户的 unit 规格决定的,其它的线程是由对应配置项指定的。
各个线程分配的资源原理
线程分配的资源包括:
- 内存:不同租户的内存是分开管理的,当前执行的 SQL 属于哪个租户,就使用那个租户的内存分配器。
- CPU:一个租户默认的活跃线程是
cpu * cpu_quota_concurrency, 但是在 OBServer 会根据需要动态增加线程,要控制租户 CPU 使用率,需要开启 cgroup。 - 网络和 IO:在 OceanBase 数据库 V4.x 版本之前,没有做控制;在 OceanBase 数据库 V4.x 版本,网络未做资源控制,但是 IO 可以通过 resource mananger 控制。
内存区域
sql work area: 这个是一个租户执行 SQL 过程中各个 operator 占用的内存。memory store: LSM tree 中的 memstore 的内存。kv cache:LSM tree 中 sstable 的 cache。system memory: 预留给net io,disk io,election,负载均衡等各种功能的内存。
资源共享与隔离
对内存来说:
sql work area,memory store,kv cache是租户独享的。system memory是多个租户共享的。
对线程来说:
sql worker是隔离的。net io、disk io、等是不隔离的。clog writer在 OceanBase 数据库 V4.x 之前版本是不隔离的,在 OceanBase 数据库 V4.x 版本是隔离的。 网络 IO/Disk IO 目前没有隔离。
SQL 引擎和事务引擎资源分配与隔离
SQL 引擎和事务引擎都是分租户的,不同租户之间完全隔离。
- 首先是内存,不同租户的 SQL 或事务内存是分开管理的,一个租户的内存耗光,不会影响到另一个租户。
- 其次是线程,不同租户的 SQL 或事务引擎的线程是完全独立的,一个租户的线程 hang 不会影响到另一个租户。
- 一个租户 SQL 线程的 CPU 占用, 是控制同时活跃的 SQL 线程实现的。
- SQL 引擎的 plan cache,事务引擎的锁也是完全独立的。
数据文件管理
OBServer 目前的数据文件只有两类:
- Redo Log 相关, 包含 redolog 和它的索引文件。
- Data 文件:保存各个分区的日志,包括各个分区的 checkpoint 点。
注意
- redolog 文件在 OceanBase 数据库 V4.x 版本下是分租户,在 OceanBase 数据库 V4.x 之前版本不区分租户。
- Data 文件不区分租户。