了解 Firebird 监控表中的 MON$STAT_ID

Posted

技术标签:

【中文标题】了解 Firebird 监控表中的 MON$STAT_ID【英文标题】:Understanding MON$STAT_ID in the Firebird monitoring tables 【发布时间】:2014-10-03 01:20:39 【问题描述】:

我在几周前发布了有关 firebird 数据库以及如何监控它的信息。从那时起,我想出了一个漂亮的脚本来监视所有页面的读取/写入/获取/标记。我正在监视的列之一是 MON$STAT_IDMON$STAT_GROUP 字段。这对我来说是一个不错的数字;但是,我无法关联和理解它到底是什么。我认为打印出 MON$STAT_GROUP 会有所帮助,但它还没有以任何方式帮助我......

我还研究了RDB$ 命令,但发现的文档非常有限,以查看它们是否可以帮助我监控我的数据库。

所以我决定来这里首先询问我是否正在监视我的数据库,以便其他人可以查看来自页面读取/写入/获取/标记的数据,并对数据库是否正在执行做出明智的决定正如预期的那样。

其次,在我的脚本中添加RDB$ 命令是否会增加我将提供给数据库人员的数据价值?

最后,也许也是最重要的一点,是否有将MON$STAT_ID 字段与数据库中的实际表相关联,以了解何时发生了不应该发生的事情?我目前每分钟都在监视数据库,这可能很频繁,但我正在获取有效数据。现在唯一的问题是如何解释这些数据。有人可以就他们使用/过去使用过的方法给我一些建议吗?

(注意:运行 firebird 2.1)

【问题讨论】:

RDB$ 命令”是什么意思? RDB$ 是系统表的前缀和一组用于获取上下文信息的函数,但我不确定这些将如何应用在这里。 我已经添加了一个答案,但是由于您没有提供有关您在做什么或您需要什么的详细信息,因此实际上不可能回答您问题的某些部分(例如,您的第三段将需要您的实际代码,以便我们提供我们的见解) 【参考方案1】:

要按特定表显示统计信息,我使用此 SQL (FB 3)

select t.mon$table_name,trim(
case when r.mon$record_seq_reads>0 then 'Non index Reads: '||r.mon$record_seq_reads else '' end||
case when r.mon$record_idx_reads>0 then ' Index Reads: '||r.mon$record_idx_reads else '' end||
case when r.mon$record_inserts>0 then ' Inserts: '||r.mon$record_inserts else '' end||
case when r.mon$record_updates>0 then ' Updates: '||r.mon$record_updates else '' end||
case when r.mon$record_deletes>0 then ' Deletes: '||r.mon$record_deletes else '' end)
from MON$TABLE_STATS t
join mon$record_stats r on r.mon$stat_id=t.mon$record_stat_id
where t.mon$table_name not starting 'RDB$' and r.mon$stat_group=2
order by 1

【讨论】:

【参考方案2】:

MON$IO_STATS(以及MON$RECORD_STATSMON$MEMORY_USAGE)中的MON$STAT_ID列是监控表中记录的主键。几乎所有其他监控表都包含一个MON$STAT_ID 来指向这些统计信息:MON$ATTACHMENTSMON$CALL_STACKMON$DATABASEMON$STATEMENTSMON$TRANSACTIONS

换句话说:统计信息适用于数据库、附件、事务、语句或调用级别(PSQL 执行)。统计表包含一个名为MON$STAT_GROUP 的列来识别这些类型。 MON$STAT_GROUP 的值在RDB$TYPES 中有描述:

0:DATABASE 1:ATTACHMENT 2:TRANSACTION 3:STATEMENT 4:CALL

通常级别 0 的统计信息包含级别 1 的所有数据,级别 1 包含该附件的级别 2 的所有数据,级别 2 包含该事务的级别 3 的所有数据,级别 3 包含该语句的级别 4 的所有数据。

由于可能存在与下层无关的数据处理,或者特定的附件、事务或语句句柄已被删除,因此下层的数量不一定汇总为上层的总数。

无法将统计信息与特定表相关联(因为此信息与表无关,但 - 简化 - 来自执行可能涵盖多个表的语句)。

正如我还评论的那样,我不确定您所说的“RDB$ 命令”是什么意思。但我假设你在谈论RDB$GET_CONTEXT()RDB$SET_CONTEXT()。您可以使用RDB$GET_CONTEXT() 获取当前连接(SESSION_ID)和事务ID(TRANSACTION_ID)。这些值可用于监控表中的MON$ATTACHMENT_IDMON$TRANSACTION_ID。我认为SYSTEM 命名空间中的其他变量并不有趣,而USER_SESSIONUSER_TRANSACTION 中的变量都是用户定义的(最初这些命名空间是空的)。

在语句中使用CURRENT_CONNECTIONCURRENT_TRANSACTION 上下文变量要容易得多。如 Firebird 安装中的 doc\README.monitoring_tables.txt 所述:

系统变量 CURRENT_CONNECTION 和 CURRENT_TRANSACTION 可用于分别选择有关当前(对于调用者)连接和事务的数据。这些变量对应于相应监控表的 ID 列。

注意:我的回答是基于 Firebird 2.5。

【讨论】:

以上是关于了解 Firebird 监控表中的 MON$STAT_ID的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Firebird 2.1 中临时禁用表中的所有约束?

从 Firebird 数据库表中获取列名列表

FireBird 中Blob 字段最长是多长

Mon监控日志系统正式上线

Firebird 2.1 在某些数据库表中存储大量行是不是有效?

Firebird/Lazarus SQL 视图与选择 iif?