调试 seekdb
默认 Bazel 构建使用 -O2 生产优化,同时保留调试信息。
构建可调试二进制
二进制文件位于 build/bin/src/observer/seekdb。分析 core dump 或提交调试信息时,应同时记录 seekdb -V,以便匹配二进制的 revision 和构建参数。优化构建可能内联函数或将变量显示为 optimized out;遇到这类情况时,日志或范围更小的单元测试通常更有效。
使用 GDB 或 LLDB
在 Linux 上查找进程并附加 GDB:
在 macOS 上使用 LLDB:
分析 core dump 时,必须使用生成该文件的同一二进制:
随后可以使用常规调试器命令设置断点、查看变量和获取 backtrace。
使用 RPM debuginfo
软件包将运行时二进制安装到 /usr/bin/seekdb。如果配置的软件源提供匹配的 debuginfo 包,可以直接安装;也可以在不安装的情况下提取:
rpm2cpio seekdb-debuginfo-<version>.<arch>.rpm | cpio -idmv
find usr/lib/debug -type f -name '*seekdb*.debug'
在 GDB 中加载实际找到的文件:
运行时二进制和 debuginfo 包的 revision、架构必须一致。不要依赖固定的包内路径,应使用提取后实际找到的文件。
使用日志调试
对于并发服务,日志通常比暂停进程更有效。使用 K() 添加结构化字段,然后重新构建受影响的目标:
使用配置的 base-dir 定位日志。systemd 安装可以同时检查服务输出和服务器日志:
如果在 /etc/seekdb/seekdb.cnf 中修改了 base-dir,应使用对应的日志目录。可以通过 trace ID 搜索一次请求的全部日志:
trace ID 会出现在日志行中,可以使用 rg 或 grep 搜索相关内容。日志字段、级别、轮转和限流请参考日志系统。
调试时调整日志配置
以下配置项都是动态生效的集群级参数:
ALTER SYSTEM SET syslog_level = 'DEBUG';
ALTER SYSTEM SET syslog_io_bandwidth_limit = '50MB';
ALTER SYSTEM SET diag_syslog_per_error_limit = 1000;
ALTER SYSTEM SET enable_async_syslog = false;
调试结束后应恢复原值。提高日志量或关闭异步日志可能影响性能并增加磁盘占用。
打印并解析调用栈
需要源码级调用栈时,可以在结构化日志中加入 lbt():
使用生成该日志的同一二进制解析地址,例如:
必须使用包含匹配调试信息的二进制,否则输出可能只有 ?? 栈帧。
SQL 执行跟踪
开启会话级 trace,执行待分析语句,再查看记录的操作:
不再需要时应关闭该设置。跟踪只适合定向诊断,可能带来额外开销。
Debug Sync
Debug Sync 可以让指定服务线程在已有的 DEBUG_SYNC 点暂停,而不停止整个进程。它适合在 GDB 会影响心跳或并发行为时进行调试。
在一个会话中启用并配置同步点,在另一个会话中发送信号:
ALTER SYSTEM SET debug_sync_timeout = '100000s';
SET ob_global_debug_sync = 'BEFORE_UNIT_MANAGER_LOAD wait_for signal_name execute 10000';
SET ob_global_debug_sync = 'now signal signal_name';
调试结束后清理同步点并关闭 Debug Sync:
SET ob_global_debug_sync = 'BEFORE_UNIT_MANAGER_LOAD clear';
ALTER SYSTEM SET debug_sync_timeout = 0;
同步点名称必须存在于实际执行的代码路径中。新增同步点需要在源码中加入 DEBUG_SYNC(...) 并重新构建受影响目标。