我的 Firebird 数据库出现了奇怪的减速问题。在日常使用数据库期间,客户端会遇到明显的减速,而系统仍有许多可用资源。有关环境的一些信息:
- 以 SuperServer 模式运行的 64 位 Firebird 2.5.2 服务器
- 数据库在 64 位 Windows 2008 R2 服务器操作系统上运行
- 服务器操作系统在具有 4 个 CPU 核心和 16 GB RAM 的 VMware 4.1 VM 中运行
- 数据库大小约为 37 GB,数据库的并发连接数约为 150。
在观察减速情况时:
- 机器的 CPU 使用率在 40-60% 之间,没有更高的峰值,并且负载在所有 4 个核心之间很好地分布
- 服务器的内存使用量约为 4-6 GB,其余内存用作操作系统缓存
- 磁盘队列长度几乎不会超过 0.3,延迟约为 2-5 毫秒
- 服务器上几乎没有网络活动。
不过,速度减慢似乎与服务器的总体负载有关。在夜间,当没有用户连接到数据库/没有后台作业运行时,用于参考的测试查询在 4-5 秒内执行,而在白天,当所有用户都连接到数据库时,执行相同的参考查询需要 60 多秒才能完成。不过应该补充的是,速度减慢是一般性的,在服务器负载下,没有特定的查询速度变慢,特定的 Firebird 数据库中的一切都变慢了。该服务器还有其他数据库,每天执行的事务数量非常少,这些其他数据库没有显示出速度减慢的迹象。我甚至创建了一个正在经历速度减慢的实时数据库的副本,并对原始数据库和重复数据库执行了相同的查询 - 原始数据库执行查询的速度很慢,而重复数据库执行速度很快。我知道原始数据库和重复数据库之间的唯一区别是连接用户数/并发事务数。
由于我在可用的操作系统资源中没有找到所有这些问题的明显原因,因此我尝试从 Firebird 获取统计数据。
观察结果:
- 根据 mon$statements,在高峰时段,数据库有 30-40 个事务并行运行(其中 mon$state == 1,根据档案,这意味着事务正在运行或正在等待锁定)
- fb_lock_print 显示有关数据库的以下信息:
锁定头块
Version: 145, Active owner: 0, Length: 2097152, Used: 1335440 Flags: 0x0001 Enqs: 9993237, Converts: 93191, Rejects: 1417230, Blocks: 2 Deadlock scans: 0, Deadlocks: 0, Scan interval: 10 Acquires: 19972846, Acquire blocks: 0, Spin count: 0 Mutex wait: 0.0% Hash slots: 1009, Hash lengths (min/avg/max): 0/ 2/ 7 Remove node: 0, Insert queue: 0, Insert prior: 0 Owners (38): forward: 20824, backward: 872088 Free owners (126): forward: 973360, backward: 728016 Free locks (370): forward: 852200, backward: 195936 Free requests (12425): forward: 614608, backward: 1230536 Lock Ordering: Enabled
这里我注意到“rejects”字段占“enqs”字段的~14%,但不幸的是我不知道这些值的确切含义。我猜大约有 14% 的锁定请求由于某种原因被拒绝,但我可能完全错了。
所以问题是:
- 在这种情况下,应该如何解释 fb_lock_print 的输出?这些数字在某种意义上是“错误的”吗?它们可以通过一些参数调整来改进吗?
- 应采取哪些额外措施来查明导致速度变慢的原因?
答案1
我使用的是 32 位版本的 Firebird(版本 2.5.2),一个月以来,当 nbackup 工具开始锁定数据库时,对数据库的访问速度开始变慢。使用 nbackup 解锁数据库后,查询再次快速正常运行。我们使用 nbackup -L / nbackup -N 通过 fastcopy 复制数据库文件。