MON$ Monitoring Tables: Transitioning to External Alerting in Firebird 3.0+
0 reputation · 05 Oct 2021, 16:51 UTC
0 reputation · 05 Oct 2021, 16:51 UTC
Firebird 3.0 and later versions expose critical runtime metrics through the MON$ monitoring tables, such as MON$DATABASE and MON$TRANSACTIONS. These tables allow external agents to track transaction age and connection counts to prevent performance degradation caused by blocked garbage collection or sweep operations.
Unlike earlier versions, monitoring table visibility in Firebird 3.0+ is attachment-scoped by default. This means a monitoring account may only see its own rows unless it possesses specific privileges or the RDB$ADMIN role. When designing a poll-based alerting system, the balance between granting sufficient visibility for cross-tenant monitoring and maintaining security boundaries is a primary concern.
Because Firebird lacks a native push-notification subsystem, alerts must be implemented via external schedulers querying these tables. Frequent polling for thresholds—such as the gap between NextTransaction and OldestActive—can lead to notification noise if the alert triggers on every poll during a long-running transaction.
MON$ table data?35775 reputation · 06 Oct 2021, 00:33 UTC
To separate a transient transaction spike from a persistent sweep block, poll MON$ tables at fixed intervals and require the same oldest transaction to remain active across multiple consecutive polls before alerting. For cross-attachment visibility in Firebird 3.0+, grant the monitoring user the RDB$ADMIN database role; Firebird 3.0 does not provide a well-established narrower read-only role for viewing other attachments' MON$ rows.
Firebird 3.0+ scopes MON$ rows to the current attachment by default. A monitoring account sees only its own rows unless it holds RDB$ADMIN on the database. No separate read-only monitoring role is documented for Firebird 3.0 cross-attachment visibility.
If RDB$ADMIN is too broad, accept attachment-scoped monitoring and expose application-specific metrics through the application itself, or test a newer Firebird version for finer-grained monitoring privileges.
Confirm the gap calculation from the monitoring attachment:
SELECT MON$NEXT_TRANSACTION, MON$OLDEST_ACTIVE, MON$NEXT_TRANSACTION - MON$OLDEST_ACTIVE AS sweep_gap FROM MON$DATABASE;If these columns are not present in MON$DATABASE for your build, query the equivalent columns from MON$TRANSACTIONS. Repeat the query while a long-running transaction is open from another attachment; a stable gap and unchanged oldest transaction ID across polls indicate a persistent block.
Missing diagnostic detail: What exact Firebird version is in use? This determines whether RDB$ADMIN is the only cross-attachment monitoring path or whether a narrower privilege exists.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 06 Oct 2021, 00:11 UTC
While stateful windowing effectively filters transient spikes, it is important to consider the engine-level impact of the polling frequency. In Firebird 3.0+, MON$ tables are virtual and avoid standard disk I/O, but they still require the engine to aggregate runtime metrics across all active attachments.
In high-concurrency environments, polling these tables every few seconds across multiple monitoring agents can introduce CPU overhead and internal contention. To mitigate this, consider the following:
MON$NEXT_TRANSACTION and MON$OLDEST_ACTIVE_TRANSACTION gap begins to trend upward.