Buenas
Antes de entrar en temario, aclarar que en esta entrada sólo explicaré las tablas de monitoreo. Todo el tema de auditoria lo dejo para una futura entrada. Dicho ésto… ¡Al lío!
Poniéndonos en situación
Cómo decía, vamos a hablar de las tablas de monitoreo (tablas MON$) de Firebird. Estas tablas fueron introducidas por primera vez en la versión 2.1 de Firebird (ver release notes de la versión), siendo ampliadas y mejoradas posteriormente, hasta tener en la versión 2.5 (ver release notes de la versión), un completo sistema de auditoria y monitoreo. Estas tablas nos permitirán, mediante sencillas consultas SQL, ver una instancia del estado de nuestra base de datos en un punto de tiempo determinado.
Dado que estas tablas fueron introducidas en la versión 2.1 de Firebird, antes de intentar usarlas tendremos que asegurarnos que la base de datos ha sido creada en una versión mayor o igual a ésta (versión de ODS 11.1). Para saber la versión del ODS de la base de datos, os recomiendo la lectura de esta entrada anterior. En el caso de tener una base de datos creada con una versión anterior de Firebird, simplemente tendremos que hacer un backup y un restore con la versión deseada de Firebird (superior o igual a la 2.1) para tenerlas.
La información que podemos obtener de estas tablas es la siguiente:
- información general de la base de datos tales como nombre, tamaño de página, versión de ODS,….
- conexiones actuales a la base de datos y información del cliente conectado tales como dirección IP, nombre del programa o proceso mediante el que se conecta,….
- información sobre todas las transacciones
- información sobre todas las sentencias SQL
- estadísticas de uso, memoria consumida,…..
Alguna información que nos dan estas tablas podemos obtenerlas con la función RDB$GET_CONTEXT, así que tendremos dos formas de obtenerla. Para saber más acerca de la función RDB$GET_CONTEXT() os recomiendo la lectura de su documentación en firebirdsql.com.
Aislamiento de nuestra conexión
Dado que para acceder a las tablas MON$ tenemos que realizar consultas SQLs, necesitamos realizar una conexión a la base de datos. Esta conexión (y por lo tanto su transacción, sentencias SQLs, estadísticas,… asociadas) se verá reflejadas en las tablas de monitoreo junto a las demás conexiones. Para poder discriminarla de las demás, existen dos variables de sistema, CURRENT_CONNECTION y CURRENT_TRANSACTION. El valor de estas variables corresponderá a la columna ID de las tablas correspondientes y que veremos más adelante.
Seguridad
Las tablas de monitoreo sólo son accesibles en su totalidad a los usuarios que tengan asignado el rol RDB$ADMIN como el usuario SYSDBA, y al propietario de la base de datos. Los demás usuarios sólo verán la información relativa a su propia conexión (transacciones, sentencias y estadísticas de la misma).
Tipos de tabla de monitoreo
Podemos diferenciar dos tipos de tablas de monitoreo, las que nos proporcionan información general, y las que nos proporcionan información estadística. Prácticamente todas las tablas tienen el campo MON$STAT_ID el cual nos servirá para relacionar la información que estamos visualizando en una determinada tabla y sus respectivas estadísticas.
Metadata de tablas de valores
Desde la versión ODS 11.1:
MON$DATABASE (base de datos conectadas -> siempre será 1 registro)
- MON$DATABASE_NAME (ruta completa del nombre de la base de datos o su nombre de alias)
- MON$PAGE_SIZE (tamaño de página)
- MON$ODS_MAJOR (parte alta de la versión del ODS)
- MON$ODS_MINOR (parte baja de la versión del ODS)
- MON$OLDEST_TRANSACTION (número OIT - Oldest Interesting Transaction -)
- MON$OLDEST_ACTIVE (número OAT - Oldest Active Transaction -)
- MON$OLDEST_SNAPSHOT (número OST - Oldest Snapshot Transaction -)
- MON$NEXT_TRANSACTION (siguiente número de transacción)
- MON$PAGE_BUFFERS (número de páginas almacenadas en caché)
- MON$SQL_DIALECT (dialecto SQL de la base de datos)
- MON$SHUTDOWN_MODE (modo de apagado actual)
0: online
1: multi-user shutdown
2: single-user shutdown
3: full shutdown
- MON$SWEEP_INTERVAL (intervalo de sweep)
- MON$READ_ONLY (flag de sólo lectura)
- MON$FORCED_WRITES (flag de sincronización de escritura)
- MON$RESERVE_SPACE (flag de espacio de reserva)
- MON$CREATION_DATE (fecha/hora de creación)
- MON$PAGES (número de página guardadas en disco)
- MON$BACKUP_STATE (actual estado de físico de backup)
0: normal
1: stalled
2: merge
- MON$STAT_ID (ID de la estadística)
MON$ATTACHMENTS (agentes conectados)
- MON$ATTACHMENT_ID (ID del agente)
- MON$SERVER_PID (ID del proceso servidor)
- MON$STATE (estado del agente)
0: idle
1: active
- MON$ATTACHMENT_NAME (string de conexión)
- MON$USER (nombre del usuario conectado)
- MON$ROLE (rol del usuario conectado)
- MON$REMOTE_PROTOCOL (tipo de protocolo remoto)
- MON$REMOTE_ADDRESS (IP remota)
- MON$REMOTE_PID (ID del proceso cliente remoto)
- MON$REMOTE_PROCESS (path completo del proceso cliente remoto conectado)
- MON$CHARACTER_SET_ID (ID del character set)
- MON$TIMESTAMP (fecha y hora de la conexión)
- MON$GARBAGE_COLLECTION (flag del garbage collection)
- MON$STAT_ID (ID de la estadística)
MON$TRANSACTIONS (transacciones iniciadas)
- MON$TRANSACTION_ID (ID de la transacción)
- MON$ATTACHMENT_ID (ID del agente)
- MON$STATE (estado de la transacción)
0: idle
1: active
- MON$TIMESTAMP (fecha/hora del inicio de la transacción)
- MON$TOP_TRANSACTION (transacción más alta)
- MON$OLDEST_TRANSACTION (número local de OIT - Oldest Interesting Transaction -)
- MON$OLDEST_ACTIVE (número local de OAT - Oldest Active Transaction -)
- MON$ISOLATION_MODE (modo de aislamiento)
0: consistency
1: concurrency
2: read committed record version
3: read committed no record version
- MON$LOCK_TIMEOUT (timeout de bloqueo)
-1: infinite wait
0: no wait
N: timeout N
- MON$READ_ONLY (flag de sólo lectura)
- MON$AUTO_COMMIT (flag de auto-commit)
- MON$AUTO_UNDO (flag de auto-undo)
- MON$STAT_ID (ID de la estadística)
MON$STATEMENTS (sentencias SQL)
- MON$STATEMENT_ID (ID sentencia)
- MON$ATTACHMENT_ID (ID del agente)
- MON$TRANSACTION_ID (ID de la transacción)
- MON$STATE (estado de la sentencia)
0: idle
1: active
- MON$TIMESTAMP (fecha/hora del inicio de la sentencia)
- MON$SQL_TEXT (texto de la sentencia si procede)
- MON$STAT_ID (ID de la estadística)
MON$CALL_STACK (pila de llamadas de las peticiones PSQL activas)
- MON$CALL_ID (ID de la llamada)
- MON$STATEMENT_ID (ID de la sentencia DSQL)
- MON$CALLER_ID (ID de la petición del llamador)
- MON$OBJECT_NAME (nombre del objeto PSQL)
- MON$OBJECT_TYPE (tipo de objeto PSQL)
- MON$TIMESTAMP (fecha/hora de inicio de la petición)
- MON$SOURCE_LINE (número de línea del código del SQL)
- MON$SOURCE_COLUMN (número de columna del código del SQL)
- MON$STAT_ID (ID de la estadística)
Desde la versión ODS 11.2:
MON$CONTEXT_VARIABLES (variables de contexto conocidas)
- MON$ATTACHMENT_ID (ID del agente)
- MON$TRANSACTION_ID (ID de la transacción)
- MON$VARIABLE_NAME (nombre de la variable de contexto)
- MON$VARIABLE_VALUE (valor de la variable de contexto)
Metadata de tablas estadísticas
Desde la versión ODS 11.1:
MON$IO_STATS (estadísticas de E/S)
- MON$STAT_ID (ID de la estadística)
- MON$STAT_GROUP (grupo estadístico)
0: database
1: attachment
2: transaction
3: statement
4: call
- MON$PAGE_READS (número de páginas leídas)
- MON$PAGE_WRITES (número de páginas escritas)
- MON$PAGE_FETCHES (número de páginas servidas)
- MON$PAGE_MARKS (número de marcas de página)
MON$RECORD_STATS (estadísticas a nivel de registros)
- MON$STAT_ID (ID de la estadística)
- MON$STAT_GROUP (grupo estadístico)
0: database
1: attachment
2: transaction
3: statement
4: call
- MON$RECORD_SEQ_READS (número de registros leídos secuencialmente)
- MON$RECORD_IDX_READS (número de registros leídos mediante índices)
- MON$RECORD_INSERTS (número de registros añadidos)
- MON$RECORD_UPDATES (número de registros modificados)
- MON$RECORD_DELETES (número de registros borrados)
- MON$RECORD_BACKOUTS (número de registros descartados)
- MON$RECORD_PURGES (número de registros purgados)
- MON$RECORD_EXPUNGES (número de registros borrados)
Desde la versión ODS 11.2:
MON$MEMORY_USAGE (memoria usada)
- MON$STAT_ID (ID de la estadística)
- MON$STAT_GROUP (grupo estadístico)
0: database
1: attachment
2: transaction
3: statement
4: call
- MON$MEMORY_USED (uso de memoria en bytes)
- MON$MEMORY_ALLOCATED (bytes de memoria actualmente asignado a nivel de sistema operativo)
- MON$MAX_MEMORY_USED (máximo de memoria usada en bytes)
- MON$MAX_MEMORY_ALLOCATED (máximo de memoria asignada a nivel de sistema operativo en bytes)
Las descripciones de los campos de «state» y «mode» la encontraremos en la tabla de sistema RDB$TYPES.
Modificaciones de las tablas
Por lo general, la mayoría de estas tablas son de sólo lectura. No obstante, mediante sentencias de delete sobre las tablas MON$STATEMENTS y MON$ATTACHMENTS podremos cancelar sentencias que se demoran o terminar la sesión de algún cliente.
Ampliar información
Para más información, además de la lectura de las Release Notes mencionadas, en la carpeta doc de la instalación de Firebird, tenemos el documento README.monitoring_tables.txt, con una amplia explicación del contenido de las tablas.
Programa demo
Como ya es costumbre en mi, adjunto un programa para demostrar el uso de estas tablas de monitoreo. Aconsejo usarlo con una base de datos con varias conexiones concurrentes para ver realmente la potencia de los datos mostrados en el programa. Está realizado en XE7 y usando FireDAC como componentes de conexión a Firebird.
Hasta la próxima entrada,