OceanBase系统日志管理
日志分类
Oceanbase数据库日志可以分为系统日志(syslog )和事务日志(clog)。
- 系统日志(syslog):OceanBase数据库进程运行过程中打印的日志,用于监控报警和诊断,是可观测性领域的内容。
- 事务日志(commit log):OceanBase数据库先于数据持久化的WAL,用于保证事务性,是数据一致性领域的内容。
注:本文仅讨论OceanBase的系统日志(syslog),不涉及事务日志(clog)。
⭐️ OceanBase系统日志分为以下五种类型,默认打印INFO级别以上的日志。
- 启动和运行日志 :
observer.log
和observer.log.wf
。 - 选举日志 :
election.log
和election.log.wf
。 - RS日志 :
rootservice.log
和rootservice.log.wf
。 - 全链路追踪日志 :
trace.log
。 - 告警日志 :
alert.log
。
除trace.log、alert.log日志之外,每类日志文件自动生成一个带有.wf
后缀的WARNING日志文件,只打印WARN 级别以上的日志。通过集群配置项enable_syslog_wf
控制是否生成WARNING日志文件。
OceanBase数据库的单个系统日志文件大小不超过256MB ,当日志文件大小达到256 MB时,系统会进行日志轮转。原日志文件追加时间为后缀(格式为yyyyMMddHHmmss
),时间为本日志文件中最后一条日志的生成时间,并生成新的日志文件。发生日志轮转时,.wf
日志文件即使没到256MB也会一起轮转。
也就是说xxx.log.wf
文件和xxx.log
文件总是一一对应的,.wf
文件一般情况下远小于256 MB。
bash
log
├── election.log
├── election.log.wf
├── observer.log
├── observer.log.20220427154619
├── observer.log.wf
├── observer.log.wf.20220427154619
├── rootservice.log
├── rootservice.log.20220427165438
├── rootservice.log.wf
├── rootservice.log.wf.20220427165438
└── log
├── alert.log
└── alert.log.20220304102928236
程序日志分为不同的模块,且有父模块和子模块两个层级。
- OceanBase数据库的父模块包括CLIENT、CLOG、COMMON、ELECT、LIB、PROXY、RPC、RS、SERVER、SHARE、SQL、STORAGE、TLOG等。
- 如果父模块下含有子模块,则表示为
父模块.子模块
。例如:SQL.PARSER
表示SQL模块下的PARSER子模块;SQL.*
表示SQL模块下的所有子模块。
日志格式
系统日志内容看起来像下面这样:
bash
[2022-04-29 16:39:55.186527] WARN [COMMON] get_file_id_range (ob_log_file_group.cpp:127) [103594] [0] [Y0-0000000000000000-0-0] [lt=17] [dc=0] max file does not exist(max_file_id=4, b_exist=false)
⭐️ 一条日志由头部(header)及消息体(message )组成:
-
header
部分:time
:该条日志打印的时间。对应上面的[2022-04-29 16:39:55.186527]
。log_level
:该条日志的级别,目前支持以下级别(由高到低):ERROR
、USER_ERR
、WARN
、INFO
、TRACE
、DEBUG
。module
:当前打印日志的模块名,由父模块和子模块组成,OceanBase数据库支持按模块指定日志级别。对应上面的[COMMON]
。function
:当前打印日志的函数名。对应上面的get_file_id_range
。file_name:line_number
:当前打印日志的代码源文件名以及行号。对应上面的(ob_log_file_group.cpp:127)
。thread_id
:当前打印日志的线程ID。对应上面的[103594]
。coroutine_id
:当前打印日志的协程ID。对应上面的[0]
。trace_id
:用于跟踪一个任务的trace_id
,任务级唯一,该trace_id
通过RPC在各个OBServer间传递,从而可以根据trace_id
来获取一个任务的所有日志数据。对应GV$OB_SQL_AUDIT
视图中的TRACE_ID
字段。对应上面的[Y0-0000000000000000-0-0]
。log_used_time
:指上一条日志的处理时间 (异步日志场景包含日志写入文件时间)。对应上面的[lt=17]
。dropped_msg_count
:dc=xx
,其中xx
表示当前日志距离上一条日志期间丢弃的日志个数, 没有丢弃时为0。对应上面的[dc=0]
。
-
message
部分:消息体一般由消息描述信息(info)与参数(parameter)组成。info
:具体的日志内容。对应上面的max file does not exist
。parameter
:以name=value
的list形式组成的KV列表。value部分如果是简单类型直接展示,如果是复杂类型则展示为类似于JSON格式的文本(为提高可读性,去掉了JSON格式KEY上的"
)。对应上面的(max_file_id=4, b_exist=false)
。
日志级别
⭐️ OceanBase的系统日志划分了七个日志级别,日志级别从高到低依次为:
- ERROR:严重错误。用于记录系统的故障信息,且必须进行故障排除,否则系统不可用。
- WARN:警告。系统能继续提供服务,但行为可能不符合预期,或可能将有严重错误发生,需进行故障排除。
- INFO:提示。用于记录系统运行的当前状态,该信息为正常信息。
- EDIAG:Error Diagnosis,协助故障排查的诊断信息,通常为OceanBase数据库程序的Bug。
- WDIAG:Warning Diagnosis,协助故障排查的诊断信息,预期内的错误,OceanBase数据库能进行容错。
- TRACE:SQL语句级调试信息,日志数与SQL复杂度相关,与访问数据量无关。
- DEBUG:调试信息。用于调试时更详细地了解系统运行状态,包括当前调用的函数名、参数、变量、函数调用返回值等。
日志的默认打印级别为WDIAG级别。查看系统日志级别:
sql
SHOW PARAMETERS LIKE '%syslog_level%';
SELECT * FROM GV$OB_PARAMETERS WHERE NAME='syslog_level';
⭐️ 日志级别可以在系统、会话、语句三个级别进行设置:
- 系统级别 :作用范围为整个集群所有OBServer。仅支持在系统租户下配置。通过系统配置项
syslog_level
设置系统级别的日志级别。
sql
ALTER SYSTEM SET syslog_level='WDIAG';
--设置SQL模块的日志级别为debug,设置COMMON模块的日志级别为error
ALTER SYSTEM SET syslog_level='sql.*:debug, common.*:error';
- Session级别 :作用范围为当前租户在集群内所在的OBServer。通过系统变量
ob_log_level
设置Session级别的日志级别。- 设置Session级别的变量仅对当前Session有效,对其他Session无效。
- 设置Global级别的变量对当前Session无效,需要重新登录建立新的Session才会生效。
sql
--检查系统变量
SHOW VARIABLES LIKE '%ob_log_level%';
--设置会话级别的日志级别
SET ob_log_level='INFO';
SET @@ob_log_level='sql.*:debug, common.*:info';
SET @@SESSION.ob_log_level='sql.*:debug, common.*:info';
--设置Global级别的日志级别
SET GLOBAL ob_log_level='INFO';
SET @@GLOBAL.ob_log_level='sql.*:debug, common.*:info';
📖 系统变量
ob_log_level
的默认值为disabled,表示禁用Session级别的日志。
- 语句级别 :作用范围为当前执行语句所在的OBServer。只在SQL语句执行期间生效。通过Hint设置语句级别的日志级别。
sql
--通过Hint设置语句级别的日志级别
SELECT /*+log_level('sql.*:debug, common.*:info')*/ * FROM t;
注 :如果使用MySQL的C客户端执行带Hint的SQL语句,需要使用
-c
选项登录,否则MySQL客户端会将Hint作为注释从用户SQL语句中去除,导致系统无法收到用户Hint。
日志配置参数
⭐️ 系统日志相关的集群配置项如下:
enable_syslog_recycle
:用于设置是否开启回收系统日志。默认为false。enable_syslog_wf
:用于设置是否把WARN以上级别的系统日志打印到一个单独的日志文件(日志文件的后缀为wf
)中。默认为true。enable_async_syslog
:用于设置是否为observer.log、election.log和rootservice.log启用系统日志异步写。默认为true。max_syslog_file_count
:用于设置在回收日志文件之前可以容纳的最大日志文件数量。默认为0,表示不会删除任何日志文件。syslog_io_bandwidth_limit
:用于设置系统日志所能占用的磁盘IO带宽上限,超过带宽上限容量的系统日志将被丢弃。取值为0表示关闭系统日志。默认为30MB。syslog_level
:用于设置系统日志级别。默认为WDIAG。syslog_disk_size
:用于设置系统日志的磁盘空间上限。当系统日志的总大小将要达到该上限时,最旧的日志文件将会被删除,包括已压缩的日志文件。默认为0M。syslog_compress_func
:用于设置系统日志的压缩算法。默认为none,表示不压缩。syslog_file_uncompressed_count
:用于设置系统日志不压缩的文件数量。只有在syslog_compress_func
取值不为none时才生效,且每一种系统日志文件单独计算数量。默认为0。alert_log_level
:用于单独设置告警日志的级别。默认为INFO。
📖 配置项syslog_compress_func
与配置项syslog_file_uncompressed_count
、syslog_disk_size
、max_syslog_file_count
之间的关系:
-
syslog_compress_func =none
:syslog_file_uncompressed_count
的取值无效;syslog_disk_size
和max_syslog_file_count
共同控制日志文件上限,同时满足数量和大小限制。
-
syslog_compress_func !=none
:max_syslog_file_count
的取值无效;- 日志个数超过
syslog_file_uncompressed_count
取值的部分进行压缩,整体接近syslog_disk_size
取值时开始删除最旧的日志。
📖 OceanBase V4中,max_syslog_file_count
与syslog_disk_size
的关系如下:
max_syslog_file_count=0
且syslog_disk_size=0
:不回收日志,直到磁盘写满。max_syslog_file_count=0
且syslog_disk_size>0
:当日志总大小接近syslog_disk_size
时,开始删除最旧的日志文件。max_syslog_file_count>0
且syslog_disk_size=0
:当某种日志文件的数量超过max_syslog_file_count
时,开始删除最旧的日志文件max_syslog_file_count>0
且syslog_disk_size>0
:当某种日志文件的数量超过max_syslog_file_count
时,或者当日志总大小接近syslog_disk_size
时,开始删除最旧的压缩文件。
日志监控项
通过GV$SYSSTAT
视图可以方便的查看系统日志相关的监控项。
sql
select CON_ID,CLASS,STAT_ID,NAME,VALUE,VALUE_TYPE from oceanbase.GV$SYSSTAT
where class=128 and stat_id > 160000 and stat_id < 170000 and con_id=1;
系统日志分析查看
查找特定SQL请求的日志
- 确认SQL审计已开启。
sql
SHOW PARAMETERS LIKE 'enable_sql_audit';
- 执行SQL报错后,登录系统租户,通过
GV$OB_SQL_AUDIT
视图查询该SQL的执行信息。
sql
select * from gv$ob_sql_audit where query_sql like '%select xx,yy from tt%' limit 1\G
通过以上查询结果,我们可以获取到该 SQL 请求执行的SVR_IP
及TRACE_ID
。
- 登录目标节点,并通过
TRACE_ID
检索日志文件。
bash
grep 'YB4206019C9E-0005F55950FFAF04-0-0' observer.log
grep 'YB4206019C9E-0005F55950FFAF04-0-0' observer.log.*
- 结合日志上下文、OS指标、OS事件等多角度指标,对本节点进行分析。通过TRACE_ID对应的RPC调用,串联起其他OceanBase节点、ODP节点、应用节点,对全链路进行分析。
基于Trace查找上一次SQL请求日志
OceanBase数据库日志打印时均会带trace_id
,通过在日志文件(observer.log、election.log和rootservice.log)中搜索对应的trace_id,可以获取上一次SQL请求的完整日志。
- 开启Trace功能。
sql
--方法一:通过设置Session变量 ob_enable_show_trace 来开启Trace功能。这种方式对本Session的后续所有语句生效。
SET ob_enable_show_trace=ON;
--方法二:通过设置Hint中的 trace_log 字段来开启Trace功能。这种方式只对带Hint的当前语句生效。
SELECT /*+trace_log=on*/c1 FROM t1 LIMIT 2;
- 使用SHOW TRACE查看上一次SQL语句的详细执行跟踪信息。
sql
obclient [test]> SHOW TRACE;
+-------------------------------------------+----------------------------+------------+
| Operation | StartTime | ElapseTime |
+-------------------------------------------+----------------------------+------------+
| com_query_process | 2023-03-22 14:30:27.552259 | 0.405 ms |
| └── mpquery_single_stmt | 2023-03-22 14:30:27.552266 | 0.386 ms |
| ├── sql_compile | 2023-03-22 14:30:27.552283 | 0.083 ms |
| │ └── pc_get_plan | 2023-03-22 14:30:27.552286 | 0.025 ms |
| └── sql_execute | 2023-03-22 14:30:27.552379 | 0.242 ms |
| ├── open | 2023-03-22 14:30:27.552380 | 0.024 ms |
| ├── response_result | 2023-03-22 14:30:27.552417 | 0.140 ms |
| │ ├── get_das_id | 2023-03-22 14:30:27.552421 | 0.000 ms |
| │ └── do_local_das_task | 2023-03-22 14:30:27.552435 | 0.049 ms |
| └── close | 2023-03-22 14:30:27.552570 | 0.039 ms |
| ├── close_das_task | 2023-03-22 14:30:27.552571 | 0.012 ms |
| └── end_transaction | 2023-03-22 14:30:27.552596 | 0.003 ms |
+-------------------------------------------+----------------------------+------------+
12 rows in set (0.006 sec)
📖 Operation类型请参见:https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013146
- 通过trace_id在日志文件查询上一次SQL请求的完整日志。
通过last_trace_id()
获取trace_id。
sql
SELECT last_trace_id() FROM DUAL;
登录对应OB节点,进入到日志文件所在目录,执行grep $trace_id observer.log
命令,获取trace_id所对应的日志。
bash
cd /home/admin/oceanbase/log
grep YB42AC1E87CC-0005F6BFDB3E2199-0-0 observer.log
grep YB42AC1E87CC-0005F6BFDB3E2199-0-0 observer.log.20250903*
grep YB42AC1E87CC-0005F6BFDB3E2199-0-0 rootservice.log.20250903*
Alert日志
🐘 OceanBase V4.2.3引入了alert告警日志。
Alert日志是警告日志,包含了OBServer运行过程中重要的INFO、WARN、ERROR日志,旨在记录集群中的关键事件,为监控集群状态、排查并解决常见问题提供方便。
Alert日志位于系统日志同一级目录的log/alert
子目录下,日志文件名为alert.log
。
单个Alert日志文件大小不超过256MB ,当日志文件大小达到256 MB时,系统会进行日志轮转。原日志文件追加时间为后缀(格式为yyyyMMddHHmmss
),例如:alert.log.20220304102928236。
Alert日志格式
日志文件以CSV格式存储,每个日志字段间以|
隔开,日志信息文本以""
包裹。
bash
2023-12-21 13:46:57.650115|INFO|LOG|OB_LOG_SERVICE_START_SUCCESS|0|1001|51152|OBServer|Y5B690B7C0505-00060C87BB2B5971-0-0|start|ob_log_service.h:224|"OBServer log service start success, cost 638519 us."
Alert日志包含以下12个字段:
- 日志打印时间
- Alert日志级别:例如INFO、WARN、ERROR。
- 日志所属的模块:例如LOG、STORAGE、SQL、TRANS。
- 事件标识符:唯一标识了集群运行过程中发生的重要事件,例如
OB_LOG_SERVICE_START_SUCCESS
。 - 错误码:INFO级别日志的错误码为 0。
- 租户ID
- 线程号
- 线程名
- TRACE ID:当前SQL语句的标识符,用于追踪一条SQL的执行过程。例如
Y5B690B7C0505-00060C87BB2B5971-0-0
。 - 函数名:日志所处函数的函数名。
- 代码位置:日志所处的代码位置,例如
ob_log_service.h:224
。 - 详细信息:日志事件描述、错误原因、解决方案。
Alert日志查询
Alert日志以CSV格式存储,支持系统租户以外表的形式查看日志。
sql
SELECT * FROM sys_external_tbs.__all_external_alert_log_info;
相比Alert日志文件,外表中增加了IP和PORT字段,表示Alert所属节点的IP地址和端口号。
如果alert.log文件达到了256MB,会有新的Alert日志文件生成,此时需要手动刷新外表的文件列表:
sql
ALTER EXTERNAL TABLE sys_external_tbs.__all_external_alert_log_info refresh;
刷新后再进行查询,即可查到所有日志内容。
Alert日志可以用于以下问题的排查:
- 通过alert.log文件中的WARN日志和ERROR日志可以查看事件的描述信息,还可以获取错误原因和解决方式。
- 通过alert.log文件中的INFO日志,可以查看某个流程的进度。
References
【1】https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001499554
【2】https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001500076
【3】https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002012816
【4】https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003381447
【5】https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013146