首批通过分布式安全可靠测评,为关键业务系统打造
计算机系统时钟源介绍及其对OceanBase数据库的影响
更新时间:2026-06-16 09:21
在计算机系统中,时钟源(clocksource)是操作系统内核用来维持和更新系统时间的一种机制。计算机系统常见的时钟源有 tsc、arch_sys_counter、hpet、kvm-clock、apci_pm、pit 等几种。本文主要简单介绍这几种常见的时钟源,以及在 OceanBase 数据库服务器上如果操作系统内核的 clocksource 时钟源被错误地设置为 hpet 时可能会遇到的各种数据库异常问题总结。
详细说明
时钟源介绍
在计算机系统中,时钟源(clocksource)是操作系统内核用来维持和更新系统时间的一种机制。不同的硬件平台可能支持不同类型的时间源,它们在精度、稳定性和资源消耗等方面有所区别。
常见的时间源有以下几种。
tsc (Time Stamp Counter)
描述: TSC 是由 CPU 提供的计数器,它记录了自上次重启以来的处理器周期数。
优点:
高精度: TSC 是一个高精度计数器,在每个时钟周期递增。
低开销: 访问 TSC 的速度非常快,延迟低。
缺点:
同步问题: 在多核或多处理器系统中,不同核心上的 TSC 可能不完全同步。
动态频率调整: 如果 CPU 支持动态调整频率的技术(如 Intel SpeedStep 或 AMD Cool'n'Quiet),这可能导致 TSC 计数速率变化。
hpet (High Precision Event Timer)
描述: HPET 是一种由 Intel 和 Microsoft 共同设计的高精度定时器,旨在替代传统的 PIT 和 RTC。
优点:
高分辨率: HPET 通常提供至少 10 MHz 的频率,比传统定时器更精确。
多通道支持: HPET 支持多个比较器,可以独立配置中断。
缺点:
- 相对较高的读取延迟: 与 TSC 相比,HPET 的访问速度较慢。
arch_sys_counter
描述: ARM 架构下的一个全局系统计数器,属于 ARM Generic Timer 的一部分。
优点:
全局一致性: 适用于多核环境,提供一致的时间参考。
精度高: 由于其固定频率,可以提供精确的时间测量。
适用范围:
- 在现代 ARM 系统中使用,特别是那些需要高精度时间戳的应用场景。
kvm-clock
描述: 这是 KVM 虚拟化环境下的一种半虚拟化时钟源,旨在减少时间漂移问题。
优点:
- 提供更加准确和稳定的时间服务给运行在 KVM 上的虚拟机。
适用范围:
- 主要应用于虚拟化环境中,特别是在 Linux Guest 操作系统上作为默认的半虚拟化时钟源。
acpi_pm (Power Management Timer)
描述: 这是 ACPI 规范中定义的一个定时器,通常用作备用时间源。
优点:
- 稳定性好: 适合大多数系统,尤其是当其他更高精度的时间源不可用时。
缺点:
- 精度较低: 相比 TSC 或 HPET,它的分辨率较低,频率大约为 3.58 MHz。
pit (Programmable Interval Timer)
描述: 一种传统的硬件定时器,用于触发操作系统的时钟中断。
优点:
- 基本功能稳定可靠,适合基本的时间管理需求。
缺点:
- 精度有限: 通常在 100Hz 到 1000Hz 之间,对于现代应用来说可能不够精确。
如何查看时钟源
Linux 系统在 sysfs 文件系统中有两个系统时钟源相关的文件。
/sys/devices/system/clocksource/clocksource0/available_clocksource:保存了当前系统上可用的时间源(clocksource)列表。
*/sys/devices/system/clocksource/clocksource0/current_clocksource:保存了当前系统正在使用的时间源(clocksource)。
下面以不同硬件类型的服务器举例。
Intel x86 服务器上:
$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource tsc hpet acpi_pm $ cat /sys/devices/system/clocksource/clocksource0/current_clocksource tscHygon x86 服务器上:
$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource tsc hpet acpi_pm $ cat /sys/devices/system/clocksource/clocksource0/current_clocksource tscKunpeng-920 ARM 服务器上:
$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource arch_sys_counter $ cat /sys/devices/system/clocksource/clocksource0/current_clocksource arch_sys_counterHygon x86 KVM 虚拟机上:
$ systemd-detect-virt kvm $ cat /sys/devices/system/clocksource/clocksource0/available_clocksource kvm-clock acpi_pm $ cat /sys/devices/system/clocksource/clocksource0/current_clocksource kvm-clockKunpeng-920 ARM KVM 虚拟机上:
$ systemd-detect-virt kvm $ cat /sys/devices/system/clocksource/clocksource0/available_clocksource arch_sys_counter $ cat /sys/devices/system/clocksource/clocksource0/current_clocksource arch_sys_counter
如何更新时钟源
目前更新系统的时钟源分两种方法。
方法一: 即时更新当前使用的时钟源,重启机器后失效。
以 root 用户执行:
# echo tsc > /sys/devices/system/clocksource/clocksource0/current_clocksource
或者:
# echo hpet > /sys/devices/system/clocksource/clocksource0/current_clocksource
方法二: 持久化更新当前使用的时钟源,重启机器后才能生效。
这种方法需要去更改 GRUB 配置文件,如下。
以 root 用户执行:
# grubby --update-kernel=ALL --args="clocksource=tsc"
或者:
# grubby --update-kernel=ALL --args="clocksource=hpet"
OBServer 推荐使用的时钟源
目前通过 OAT 添加服务器并做装机模块化时,在 precheck 这一步会自动检查当前机器配置的时钟源,预期结果如下。
x86 物理机:tsc
ARM 物理机:arch_sys_counter
KVM虚拟机:kvm-clock 或 arch_sys_counter(ARM 虚拟机上)
相关代码如下。
-- precheck.sh
if is_arm; then
EXPECT_PHY_CLOCKSOURCE="arch_sys_counter"
else
EXPECT_PHY_CLOCKSOURCE="tsc"
fi
check_tsc_timer() {
local target_timer
if grep -q kvm-clock /sys/devices/system/clocksource/clocksource0/available_clocksource; then
target_timer=kvm-clock
else
target_timer=$EXPECT_PHY_CLOCKSOURCE
fi
curr_clocksource=$(cat /sys/devices/system/clocksource/clocksource0/current_clocksource)
if [[ "$curr_clocksource" = "$target_timer" ]]; then
echo_pass "check current_clocksource: $curr_clocksource"
else
echo_fail "check current_clocksource: $curr_clocksource ... EXPECT $target_timer"
echo_hint "modify current_clocksource to $target_timer. eg: append clocksource=$target_timer to GRUB_CMDLINE_LINUX in grub.cfg"
fi
}
如果不符合预期,OAT 任务的执行日志中会给出对应的报错信息。
[2022-12-30T11:14:07.770+0800] INFO - ### SUMMARY OF ISSUES IN PRE-CHECK ###
[2022-12-30T11:14:07.771+0800] INFO - check current_clocksource: hpet ... EXPECT tsc ... FAIL
hpet 时钟源对 OBServer 服务器的影响
在 Linux 操作系统上 tsc 是首选时钟源——因为它的开销低很多,而 hpet 作为后备时钟源。一个千万次事件计数的基准测试显示,tsc 花费约 0.6 秒,而 hpet 花费略微超过 12 秒,acpi_pm 电源管理计时器花费约 24 秒。
如果在 OBServer 数据库服务器上的时钟源被人为配置为 hpet,或者从 tsc 自动跳变了 hpet,会对 OBServer 数据库服务器带来严重的性能影响。目前已知的性能影响表现有如下几种。
性能压测时时钟源配置为 hpet 机器上的 CPU 异常繁忙,且内核态 CPU 使用率过高。

在压测时通过
perf top命令在该服务器上抓取热点函数,发现内核态read_hpet使用率最高,达到 52.15%。
时钟源配置为
hpet的服务器上 clog redo 日志回放和 SQL 执行都很慢,OBServer 进程 70% 的 CPU 都使用在get_timeof_day函数调用上,OBServer 集群合并卡住。OBServer 集群空载情况 CPU 使用率异常偏高,比如创建两个空租户后,在时钟源配置为
hpet的服务器上系统 CPU 利用率达到 60% 以上。
系统时钟源为什么会从tsc自动切换为hpet
Linux 内核会动态检测时钟源的稳定性和精度,即使用户通过 GRUB 指定 clocksource=tsc,如果内核认为 tsc 不符合其要求,仍然可能切换到其它时钟源(比如 hpet)。
可能的切换原因,如下。
如果系统检测发现
tsc的漂移超过内核设定的阈值,系统会标记tsc为不稳定并自动切换到hpet。对应的切换日志通过
dmesg -T命令可以查看出来:tsc: Marking TSC unstable due to clocksource watchdog或者tsc: Marking TSC unstable due to TSCs unsynchronized。

某些 OS 内核版本对
tsc的容错机制较低,检测逻辑可能导致误判。比如在 Hygon 7490 服务器上,如果操作系统内核中未包含针对 Hygon 7490 芯片的 4 号补丁,直接配置
clocksource=tsc会遇到无法生效的问题。根据海光服务器厂家反馈,目前只有如下的 OS 版本中包含了针对 Hygon 7490 芯片的4号补丁。OS版本 Anolis OS 8.9 (Kernel-5.10) BigCloud Enterprise Linux V21.10 U4(x86_64) CentOS 8.3 (64 bit) NingOS V3 1.0 openEuler 22.03 LTS SP3 openEuler 24.03 LTS Rocky Linux 9.3 凝思安全操作系统 V6.0.99 红旗 Asianux 服务器操作系统V8.8 (Kernel-5.10) 统信 UOS 服务器版 V20 (1070a) (Kernel-4.19) 统信 UOS 服务器版 V20 (1070e) (Kernel-4.19) 银河麒麟高级服务器操作系统 V10 SP3 (2403) 硬件层面的问题。
CPU 或某些硬件环境下,
tsc的计数受 CPU 频率调整(P-State)或深度节能模式(C-State)的影响。当 CPU 进入深度 C-State(如 C3、C6),
tsc可能暂停计数,导致系统认为其不可靠。CPU 是否启用或支持 Invariant TSC。
可以通过
cat /proc/cpuinfo | grep constant_tsc检查 CPU 是否支持 Invariant TSC,如果 CPU 不支持 constant_tsc,tsc在负载波动时可能不稳定,内核可能无法正确使用tsc。系统配置问题。
NTP 或 Chrony 等时间同步服务可能导致
tsc的计数被系统标记为漂移过大。
规避方式
如果 OAT 装机模块化任务的 precheck 日志中提示了 clocksource 相关的报错,请务必仔细检查并纠正对应的配置,不能直接跳过该报错信息。
如果系统可用时钟源(available_clocksource)中包含了
tsc,可以考虑将tsc设置为永久生效的时钟源。# cat /sys/devices/system/clocksource/clocksource0/available_clocksource tsc hpet acpi_pm # grubby --update-kernel=ALL --args="clocksource=tsc tsc=reliable"或者也可以采用如下的步骤来手工修改相关的 GRUB 配置文件。
执行
sudo vi /etc/default/grub,在原配置行GRUB_CMDLINE_LINUX后面的参数值中追加参数设置clocksource=tsc tsc=reliable。# 如果之前已经有clocksource等参数的,就直接替换掉 GRUB_CMDLINE_LINUX="原参数设置 clocksource=tsc tsc=reliable" # grub2-mkconfig -o /boot/grub2/grub.cfg修改后需重启机器生效,可以通过
cat /proc/cmdline和cat /sys/devices/system/clocksource/clocksource0/current_clocksource命令来确认是否已经真正生效了。$ cat /proc/cmdline $ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
适用版本
OceanBase 数据库所有版本。