Anticipa Problemas: Monitorización Inteligente de Tablespaces Oracle con AWR Warehouse

Mi nombre es Carla y me defino como una apasionada de conocer, compartir ideas, divertirme y aprender todo lo relacionado con Oracle.
Alegre y creativa, con un alto grado de autoexigencia, que busca, incluso sin querer, una forma diferente de ver un mismo problema o solución. Defensora del trabajo en equipo en todas las facetas de la vida y de disfrutar todo lo que haces, siempre con humildad.
Actualmente cuento con más de 15 años de experiencia como administradora de Oracle, habiendo ocupado previamente posiciones como desarrolladora en la rama de Inteligencia de Negocios. Fue en ese momento que me di cuenta de que no quería centrarme en el desarrollo, sino participar en todas las capas que involucraban los datos, desde el despliegue de la base de datos hasta su explotación final.
Siempre estoy dispuesta a ayudar y compartir conocimientos. Creo firmemente que con la tecnología hay que divertirse y no verla como una competencia. La persona con la que tienes que ser el mejor es contigo mismo.
Como DBAs, sabemos que uno de los dolores de cabeza más comunes son los tablespaces que se quedan sin espacio. Un tablespace lleno puede detener aplicaciones críticas, generar errores y, en el peor de los casos, causar una interrupción total del servicio. ¿No sería genial si pudieras predecir cuándo va a ocurrir esto y actuar antes de que sea un problema?
¡Hoy te presento una solución inteligente! He desarrollado un script que combina el poder de los datos históricos de Oracle AWR Warehouse con la sencillez de un script de shell para monitorizar el crecimiento de los tablespaces y alertarte proactivamente cuando necesiten más espacio.
El Desafío de los Tablespaces y Por Qué Necesitamos Ser Proactivos
Imagina esto: un lunes por la mañana, suena tu teléfono. "¡La aplicación está caída! ¡Error de tablespace lleno!". Es una pesadilla. Los tablespaces, que son las estructuras lógicas de almacenamiento en Oracle donde residen tus datos, crecen constantemente. Las transacciones, la inserción de nuevos datos, la creación de índices, todo consume espacio.
Si no monitorizas este crecimiento, te expones a:
Caídas de aplicaciones: Cuando un tablespace crítico se llena, las operaciones de escritura fallan.
Pérdida de datos (temporal)
Estrés y trabajo reactivo: En lugar de planificar, te ves apagando fuegos urgentes.
La Magia Detrás de Escena: AWR Warehouse de Oracle
Aquí es donde entra en juego el AWR Warehouse (Automatic Workload Repository Warehouse).
¿Qué es AWR?
Es una característica de Oracle que recopila automáticamente estadísticas de rendimiento y uso de tu base de datos en intervalos regulares (snapshots). Guarda datos sobre el uso de CPU, memoria, I/O, SQL más costosos... ¡y también el uso de tablespaces!
¿Qué es AWR Warehouse?
Piensa en ello como un "gran almacén" donde puedes guardar los datos AWR de múltiples bases de datos de tu entorno. En lugar de consultar directamente tu base de datos de producción (que podría tener un impacto en el rendimiento), puedes consultar este almacén centralizado.
¿Por qué es clave para nuestra solución?
Porque nos permite acceder al historial de crecimiento de los tablespaces sin afectar el rendimiento de tu base de datos de producción. Podemos ver cuánto creció un tablespace en el último mes, y esa es la métrica que usaremos para nuestra lógica predictiva.
Os presento mi "Oráculo de Tablespaces"
El script es un pequeño pero poderoso aliado que ejecuta la siguiente lógica:
Conexión Segura: Se conecta a una base de datos standby (para obtener la información actual de los tablespaces sin impactar la producción) y a tu AWR Warehouse.
Lista los Tablespaces: Obtiene todos los tablespaces que no sean del sistema o temporales.
Para cada tablespace, hace magia:
Obtiene el espacio actualmente utilizado y asignado (reservado) en MB.
Consulta el AWR Warehouse para determinar el crecimiento total en MB del último mes completo.
Calcula el espacio libre disponible.
¡La regla de oro! Compara: ¿Es el espacio libre disponible menor que el crecimiento del último mes?
Genera Alerta y Sugerencia: Si la respuesta es SÍ, se dispara una alerta. El script no solo te avisa, sino que te propone un comando
ALTER TABLESPACE RESIZEpara ampliarlo (atención que se trata de bigfile), sugiriendo un tamaño basado en su uso actual más el crecimiento del último mes.Envía el Informe: Consolida toda la información en un correo electrónico detallado.
La belleza de este enfoque es que no usamos un umbral fijo de porcentaje. En su lugar, usamos el patrón de crecimiento histórico del tablespace para predecir si se quedará sin espacio en el futuro cercano, basándose en su ritmo de consumo. Esto es ser verdaderamente proactivo.
Desglose del Script (monitor_tbs_growth.sh)
#!/bin/bash
#-----------------------------------------
# Configuración
#-----------------------------------------
ORACLE_SID_STANDBY="MY_PDB_STBY" # TNS de tu PDB Standby o base de datos de lectura
ORACLE_SID_AWR="MY_AWR_DB" # TNS de tu AWR Warehouse
USUARIO_STANDBY="system"
CLAVE_STANDBY="******" # ¡Ofuscada! Cambiar por tu contraseña real
USUARIO_AWR="system"
CLAVE_AWR="******" # ¡Ofuscada! Cambiar por tu contraseña real
MAIL_DESTINO="dba@mycompany.com" # Cambiar por tu dirección de correo
DEBUG=true # true para debug, false cuando esté implementado en producción
# --- AWR Warehouse Specifics ---
# !!! IMPORTANTE: DEBES CONFIGURAR ESTOS VALORES PARA TU ENTORNO !!!
# DB_TARGET_NAME TNS del target OEM .
# PDB_NAME_TO_MONITOR TNS de la Pluggable Database que quieres monitorizar.
DB_TARGET_NAME="my_cdb_prod" # Ejemplo: 'my_cdb_prod' o 'oracle_db_name'
PDB_NAME_TO_MONITOR="MY_APP_PDB" # Ejemplo: 'MY_APP_PDB'
# Variables entorno de BBDD
PATH=/home/nagios/.local/bin:/home/nagios/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
ORACLE_SID=cdboem # El SID del Listener/Instancia que atiende tu AWR Warehouse
ORAENV_ASK=NO
. oraenv -s
export TNS_ADMIN=/home/nagios/tns_admin # Ruta a tu tnsnames.ora
#-----------------------------------------
# Función para depuración
#-----------------------------------------
log_debug() {
# Redirige los mensajes de depuración a stderr para evitar contaminar stdout
$DEBUG && echo "[DEBUG] $(date +'%Y-%m-%d %H:%M:%S') $1" >&2
}
#-----------------------------------------
# Verifica conexión SQL
#-----------------------------------------
verifica_sqlplus() {
local conn_str=$1
local test_query="SELECT 'OK' FROM dual;"
log_debug "Intentando conectar a: $conn_str"
echo "$test_query" | sqlplus -s "$conn_str" | grep -q "OK" > /dev/null
if [ $? -ne 0 ]; then
echo "❌ ERROR: Fallo de conexión con $conn_str" >&2
exit 1
else
log_debug "Conexión exitosa a: $conn_str"
fi
}
#-----------------------------------------
# Obtener tablespaces excluyendo los sistema/temp
# Nota: Esto obtiene tablespaces de la standby
#-----------------------------------------
get_tablespaces() {
local conn_str="$1"
log_debug "Obteniendo listado de tablespaces de $conn_str"
sqlplus -s "$conn_str" <<EOF
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT DISTINCT tablespace_name
FROM dba_data_files
WHERE tablespace_name NOT IN ('SYSTEM','SYSAUX','UNDOTBS1','TEMP')
ORDER BY tablespace_name;
EOF
}
#-----------------------------------------
# Obtener crecimiento total del último mes completo desde el AWR Warehouse
# (Usando TRUNC(SYSDATE, 'MM') en SQL para fechas )
#-----------------------------------------
get_last_month_total_growth() {
local conn_awr="$1"
local tbs_name="$2"
local pdb_name_filter="$3"
local target_name_filter="$4"
log_debug "Calculando crecimiento TOTAL para '$tbs_name' en PDB '$pdb_name_filter' (Target: '$target_name_filter') para el último mes completo."
sqlplus -s "$conn_awr" <<EOF
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
WHENEVER SQLERROR EXIT FAILURE;
WITH
pdbs AS (
SELECT DISTINCT dbid, pdb_name, con_dbid
FROM DBA_HIST_PDB_INSTANCE
WHERE pdb_name = '$pdb_name_filter'
),
all_monthly_snapshots AS (
SELECT
s.end_interval_time,
(tsu.tablespace_usedsize * df.block_size) / 1024 / 1024 AS used_mb_raw,
df.tsname AS tablespace_name,
s.dbid,
p.pdb_name
FROM
dwa_hist_tbspc_space_usage tsu -- Usar dwa_hist_tbspc_space_usage si viene de DWA
JOIN dba_hist_snapshot s ON tsu.snap_id = s.snap_id AND tsu.dbid = s.dbid
JOIN dba_hist_datafile df ON tsu.dbid = df.dbid AND tsu.tablespace_id = df.ts#
JOIN dbsnmp.caw_dbid_mapping m ON s.dbid = m.new_dbid
JOIN pdbs p ON tsu.con_dbid = p.con_dbid
WHERE
s.END_INTERVAL_TIME >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -1) -- Inicio del último mes completo
AND s.END_INTERVAL_TIME < TRUNC(SYSDATE, 'MM') -- Fin del último mes completo (exclusivo)
AND df.tsname = '$tbs_name'
AND m.target_name = '$target_name_filter'
AND df.tsname NOT IN ('UNDO1', 'UNDO2', 'TEMP', 'PDB$SEED')
),
ranked_monthly_usage AS (
SELECT
used_mb_raw,
ROW_NUMBER() OVER (PARTITION BY tablespace_name, dbid, pdb_name ORDER BY end_interval_time ASC) AS rn_asc,
ROW_NUMBER() OVER (PARTITION BY tablespace_name, dbid, pdb_name ORDER BY end_interval_time DESC) AS rn_desc
FROM
all_monthly_snapshots
)
SELECT
NVL(
ROUND(
MAX(CASE WHEN rn_desc = 1 THEN used_mb_raw END) -
MAX(CASE WHEN rn_asc = 1 THEN used_mb_raw END)
, 2)
, 0)
FROM
ranked_monthly_usage;
EOF
}
#-----------------------------------------
# Obtener resumen de crecimiento anual por mes (para resumen histórico detallado)
# (Usando TRUNC(SYSDATE, 'MM') en SQL para fechas)
#-----------------------------------------
get_monthly_growth_summary() {
local conn_awr="$1"
local tbs_name="$2"
local pdb_name_filter="$3"
local target_name_filter="$4"
log_debug "Generando resumen mensual de crecimiento para '$tbs_name' en PDB '$pdb_name_filter' (Target: '$target_name_filter') para los últimos 12 meses."
sqlplus -s "$conn_awr" <<EOF
SET LINESIZE 300 PAGESIZE 100 FEEDBACK OFF
WHENEVER SQLERROR EXIT FAILURE;
WITH
pdbs AS (
SELECT DISTINCT dbid, pdb_name, con_dbid
FROM DBA_HIST_PDB_INSTANCE
WHERE pdb_name = '$pdb_name_filter'
),
monthly_last_snapshot AS (
SELECT
TRUNC(s.END_INTERVAL_TIME, 'MM') AS month_start_date,
df.tsname AS tablespace_name,
(tsu.tablespace_usedsize * df.block_size) / 1024 / 1024 AS tablespace_used_mb,
ROW_NUMBER() OVER (PARTITION BY TRUNC(s.END_INTERVAL_TIME, 'MM'), df.tsname, s.dbid, p.pdb_name ORDER BY s.END_INTERVAL_TIME DESC) AS rn
FROM
dwa_hist_tbspc_space_usage tsu -- Usar dwa_hist_tbspc_space_usage si viene de DWA
JOIN dba_hist_snapshot s ON tsu.snap_id = s.snap_id AND tsu.dbid = s.dbid
JOIN dba_hist_datafile df ON tsu.dbid = df.dbid AND tsu.tablespace_id = df.ts#
JOIN dbsnmp.caw_dbid_mapping m ON s.dbid = m.new_dbid
JOIN pdbs p ON tsu.con_dbid = p.con_dbid
WHERE
s.END_INTERVAL_TIME >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -12) -- Inicio de los últimos 12 meses completos
AND s.END_INTERVAL_TIME < TRUNC(SYSDATE, 'MM') -- Fin de los últimos 12 meses completos (exclusivo)
AND df.tsname = '$tbs_name'
AND m.target_name = '$target_name_filter'
AND df.tsname NOT IN ('UNDO1', 'UNDO2', 'TEMP', 'PDB$SEED')
),
calculated_growth AS (
SELECT
month_start_date,
tablespace_name,
tablespace_used_mb,
LAG(tablespace_used_mb) OVER (PARTITION BY tablespace_name ORDER BY month_start_date) AS previous_month_used_mb
FROM
monthly_last_snapshot
WHERE rn = 1
)
SELECT
TO_CHAR(month_start_date, 'YYYY-MM') AS mes,
NVL(ROUND(tablespace_used_mb - previous_month_used_mb, 2), 0) AS crecimiento_mb
FROM
calculated_growth
WHERE previous_month_used_mb IS NOT NULL
ORDER BY
month_start_date;
EOF
}
#-----------------------------------------
# Obtener el tamaño ACTUALMENTE UTILIZADO del tablespace en MB desde dba_segments.
# Se conecta a la BBDD de standby.
#-----------------------------------------
get_current_tbs_used_size_mb() {
local conn_str="$1" # Conexión a la BBDD que tiene los segmentos (ej. standby o prod)
local tbs_name="$2"
log_debug "Obteniendo tamaño ACTUALMENTE UTILIZADO para tablespace: $tbs_name de $conn_str"
sqlplus -s "$conn_str" <<EOF
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT ROUND(SUM(bytes)/1024/1024, 2)
FROM dba_segments
WHERE tablespace_name = '$tbs_name'
GROUP BY tablespace_name;
EOF
}
#-----------------------------------------
# Obtener el tamaño ACTUALMENTE ASIGNADO (ALLOCATED) del tablespace en MB
# desde dba_data_files. Esto representa el tamaño físico del datafile.
# Se conecta a la BBDD de standby .
#-----------------------------------------
get_current_tbs_allocated_size_mb_from_db() {
local conn_str="$1" # Conexión a la BBDD (ej. standby o prod)
local tbs_name="$2"
log_debug "Obteniendo tamaño ACTUALMENTE ASIGNADO para tablespace: $tbs_name de $conn_str"
sqlplus -s "$conn_str" <<EOF
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT ROUND(SUM(bytes)/1024/1024, 2)
FROM dba_data_files
WHERE tablespace_name = '$tbs_name'
GROUP BY tablespace_name;
EOF
}
#-----------------------------------------
# Proceso principal
#-----------------------------------------
main() {
local conn_stby="${USUARIO_STANDBY}/${CLAVE_STANDBY}@${ORACLE_SID_STANDBY}"
local conn_awr="${USUARIO_AWR}/${CLAVE_AWR}@${ORACLE_SID_AWR}"
verifica_sqlplus "$conn_stby"
verifica_sqlplus "$conn_awr"
log_debug "Obteniendo listado de tablespaces desde $ORACLE_SID_STANDBY..."
mapfile -t tablespaces < <(get_tablespaces "$conn_stby" | tr -d '\r')
if [ ${#tablespaces[@]} -eq 0 ]; then
log_debug "No se encontraron tablespaces para monitorear."
echo "OK: No se encontraron tablespaces para monitorear (excluyendo sistema/temp)."
exit 0
fi
local informe=""
local alter_commands_generated=""
local tablespaces_to_alert=()
for tbs_name in "${tablespaces[@]}"; do
if [[ -z "$tbs_name" ]]; then
continue
fi
log_debug "Analizando tablespace: $tbs_name"
current_tbs_used_size_mb=$(get_current_tbs_used_size_mb "$conn_stby" "$tbs_name" | tr -d '[:space:]\r')
current_tbs_allocated_size_mb=$(get_current_tbs_allocated_size_mb_from_db "$conn_stby" "$tbs_name" | tr -d '[:space:]\r')
# last_month_growth will now be obtained correctly from the SQL query itself
last_month_growth=$(get_last_month_total_growth "$conn_awr" "$tbs_name" "$PDB_NAME_TO_MONITOR" "$DB_TARGET_NAME" | tr -d '[:space:]\r')
log_debug "$tbs_name: Used=${current_tbs_used_size_mb}MB, Allocated=${current_tbs_allocated_size_mb}MB, Last_Month_Growth=${last_month_growth}MB"
if [[ "$current_tbs_used_size_mb" =~ ^[0-9]+([.][0-9]+)?$ ]] && \
[[ "$current_tbs_allocated_size_mb" =~ ^[0-9]+([.][0-9]+)?$ ]] && \
[[ "$last_month_growth" =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then
# Calculate free space
free_space_mb=$(echo "$current_tbs_allocated_size_mb - $current_tbs_used_size_mb" | bc)
log_debug "Free Space for $tbs_name: ${free_space_mb}MB"
# Check if free space is less than last month's growth
comp=$(echo "$free_space_mb < $last_month_growth" | bc)
if [[ $comp -eq 1 ]]; then
tablespaces_to_alert+=("$tbs_name")
informe+=$'\n'"--- Tablespace: ${tbs_name} ---"
informe+=$'\n'" > Tamaño Utilizado: ${current_tbs_used_size_mb} MB"
informe+=$'\n'" > Tamaño Asignado (Reservado): ${current_tbs_allocated_size_mb} MB"
informe+=$'\n'" > Espacio Libre Disponible: ${free_space_mb} MB"
informe+=$'\n'" > Crecimiento último mes: ${last_month_growth} MB"
informe+=$'\n'" > Alerta: El espacio libre (${free_space_mb} MB) es menor que el crecimiento del último mes (${last_month_growth} MB)."
informe+=$'\n'
informe+=$'\n'"------------------------------------------------------------"
informe+=$'\n'"Resumen de crecimiento mensual para $tbs_name (últimos 12 meses):"
# get_monthly_growth_summary now also uses SQL dates
informe+=$'\n'"$(get_monthly_growth_summary "$conn_awr" "$tbs_name" "$PDB_NAME_TO_MONITOR" "$DB_TARGET_NAME" | tr -d '\r')"
# Calculate the suggested resize command
target_size_calculated=$(echo "$current_tbs_used_size_mb + $last_month_growth" | bc)
new_size_mb=$(echo "scale=0; if ($current_tbs_allocated_size_mb > $target_size_calculated) $current_tbs_allocated_size_mb else $target_size_calculated" | bc)
new_size_mb=$(echo "$new_size_mb" | awk '{print int($1)}')
informe+=$'\n'
alter_cmd="ALTER TABLESPACE \"$tbs_name\" RESIZE ${new_size_mb}M;"
informe+=$'\n'"COMANDO SUGERIDO (ejecutar en PDB de producción):"
informe+=$'\n'"${alter_cmd}"
alter_commands_generated+=$'\n'"${alter_cmd}"
informe+=$'\n'
else
log_debug "Tablespace $tbs_name tiene suficiente espacio libre (${free_space_mb} MB) para el crecimiento del último mes (${last_month_growth} MB)."
fi
else
informe+=$'\n'"ADVERTENCIA: No se pudieron obtener todos los datos (USADO, ASIGNADO o CRECIMIENTO) para el tablespace $tbs_name."
log_debug "ADVERTENCIA: Datos incompletos para $tbs_name. Used: '$current_tbs_used_size_mb', Allocated: '$current_tbs_allocated_size_mb', Growth: '$last_month_growth'"
fi
done
if [ ${#tablespaces_to_alert[@]} -gt 0 ]; then
log_debug "Enviando informe por correo..."
(
echo -e "📈 Alerta de Espacio en Tablespaces - ¡Necesitan Ampliación Pronto! 📈\n"
echo -e "Los siguientes tablespaces tienen menos espacio libre disponible que su crecimiento del último mes:\n"
echo -e "$informe"
if [ -n "$alter_commands_generated" ]; then
echo -e "\n--- Resumen de Comandos ALTER TABLESPACE Generados (para ejecutar en PDB de producción) ---"
echo -e "$alter_commands_generated"
fi
) | mail -s "🚨 Alerta de espacio en Tablespaces - ${PDB_NAME_TO_MONITOR}" "$MAIL_DESTINO"
echo "CRITICAL: Informe de alerta de espacio en tablespaces enviado."
else
log_debug "No hay tablespaces que necesiten ampliación urgente."
echo "OK: No hay tablespaces con espacio libre menor que su crecimiento del último mes."
fi
}
main
Un Ejemplo de su Ejecución (Log Obfuscado)
Aquí puedes ver cómo se vería la salida del script en un entorno de depuración (DEBUG=true).
[xxxxxx@host-monitor-001 plugins]$ /usr/local/ncpa/plugins/monitor_tbs_growth.sh
[DEBUG] 2025-07-31 10:21:08 Intentando conectar a: system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:08 Conexión exitosa a: system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:08 Intentando conectar a: system/******@MY_AWR_DB
[DEBUG] 2025-07-31 10:21:08 Conexión exitosa a: system/******@MY_AWR_DB
[DEBUG] 2025-07-31 10:21:08 Obteniendo listado de tablespaces desde MY_PDB_STBY...
[DEBUG] 2025-07-31 10:21:08 Obteniendo listado de tablespaces de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:08 Analizando tablespace: AUDIT_DATA
[DEBUG] 2025-07-31 10:21:08 Obteniendo tamaño ACTUALMENTE UTILIZADO para tablespace: AUDIT_DATA de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:08 Obteniendo tamaño ACTUALMENTE ASIGNADO para tablespace: AUDIT_DATA de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:09 Calculando crecimiento TOTAL para 'AUDIT_DATA' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para el último mes completo.
[DEBUG] 2025-07-31 10:21:11 AUDIT_DATA: Used=80.38MB, Allocated=600MB, Last_Month_Growth=-8MB
[DEBUG] 2025-07-31 10:21:11 Free Space for AUDIT_DATA: 519.62MB
[DEBUG] 2025-07-31 10:21:11 Tablespace AUDIT_DATA tiene suficiente espacio libre (519.62 MB) para el crecimiento del último mes (-8 MB).
[DEBUG] 2025-07-31 10:21:11 Analizando tablespace: LOG_ARCHIVE
[DEBUG] 2025-07-31 10:21:11 Obteniendo tamaño ACTUALMENTE UTILIZADO para tablespace: LOG_ARCHIVE de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:11 Obteniendo tamaño ACTUALMENTE ASIGNADO para tablespace: LOG_ARCHIVE de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:11 Calculando crecimiento TOTAL para 'LOG_ARCHIVE' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para el último mes completo.
[DEBUG] 2025-07-31 10:21:14 LOG_ARCHIVE: Used=8.63MB, Allocated=1024MB, Last_Month_Growth=71.75MB
[DEBUG] 2025-07-31 10:21:14 Free Space for LOG_ARCHIVE: 1015.37MB
[DEBUG] 2025-07-31 10:21:14 Tablespace LOG_ARCHIVE tiene suficiente espacio libre (1015.37 MB) para el crecimiento del último mes (71.75 MB).
[DEBUG] 2025-07-31 10:21:14 Analizando tablespace: APP_CONFIG
[DEBUG] 2025-07-31 10:21:14 Obteniendo tamaño ACTUALMENTE UTILIZADO para tablespace: APP_CONFIG de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:14 Obteniendo tamaño ACTUALMENTE ASIGNADO para tablespace: APP_CONFIG de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:14 Calculando crecimiento TOTAL para 'APP_CONFIG' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para el último mes completo.
[DEBUG] 2025-07-31 10:21:16 APP_CONFIG: Used=75.81MB, Allocated=100MB, Last_Month_Growth=0MB
[DEBUG] 2025-07-31 10:21:16 Free Space for APP_CONFIG: 24.19MB
[DEBUG] 2025-07-31 10:21:16 Tablespace APP_CONFIG tiene suficiente espacio libre (24.19 MB) para el crecimiento del último mes (0 MB).
... (salida omitida para brevedad, pero seguiría para todos los tablespaces) ...
[DEBUG] 2025-07-31 10:21:36 Analizando tablespace: SALES_DATA_2025
[DEBUG] 2025-07-31 10:21:36 Obteniendo tamaño ACTUALMENTE UTILIZADO para tablespace: SALES_DATA_2025 de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:36 Obteniendo tamaño ACTUALMENTE ASIGNADO para tablespace: SALES_DATA_2025 de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:36 Calculando crecimiento TOTAL para 'SALES_DATA_2025' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para el último mes completo.
[DEBUG] 2025-07-31 10:21:39 SALES_DATA_2025: Used=120324.75MB, Allocated=126700MB, Last_Month_Growth=20241.5MB
[DEBUG] 2025-07-31 10:21:39 Free Space for SALES_DATA_2025: 6375.25MB
[DEBUG] 2025-07-31 10:21:39 Generando resumen mensual de crecimiento para 'SALES_DATA_2025' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para los últimos 12 meses.
... (más output de debug) ...
[DEBUG] 2025-07-31 10:21:47 Analizando tablespace: FILE_STORAGE
[DEBUG] 2025-07-31 10:21:47 Obteniendo tamaño ACTUALMENTE UTILIZADO para tablespace: FILE_STORAGE de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:47 Obteniendo tamaño ACTUALMENTE ASIGNADO para tablespace: FILE_STORAGE de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:21:47 Calculando crecimiento TOTAL para 'FILE_STORAGE' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para el último mes completo.
[DEBUG] 2025-07-31 10:21:47 FILE_STORAGE: Used=110707MB, Allocated=116736MB, Last_Month_Growth=20989MB
[DEBUG] 2025-07-31 10:21:47 Free Space for FILE_STORAGE: 6029MB
[DEBUG] 2025-07-31 10:21:47 Generando resumen mensual de crecimiento para 'FILE_STORAGE' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para los últimos 12 meses.
... (más output de debug) ...
[DEBUG] 2025-07-31 10:22:39 Analizando tablespace: TXN_DATA_2025
[DEBUG] 2025-07-31 10:22:39 Obteniendo tamaño ACTUALMENTE UTILIZADO para tablespace: TXN_DATA_2025 de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:22:39 Obteniendo tamaño ACTUALMENTE ASIGNADO para tablespace: TXN_DATA_2025 de system/******@MY_PDB_STBY
[DEBUG] 2025-07-31 10:22:39 Calculando crecimiento TOTAL para 'TXN_DATA_2025' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para el último mes completo.
[DEBUG] 2025-07-31 10:22:42 TXN_DATA_2025: Used=85135.88MB, Allocated=89700MB, Last_Month_Growth=13935.13MB
[DEBUG] 2025-07-31 10:22:42 Free Space for TXN_DATA_2025: 4564.12MB
[DEBUG] 2025-07-31 10:22:42 Generando resumen mensual de crecimiento para 'TXN_DATA_2025' en PDB 'MY_APP_PDB' (Target: 'my_cdb_prod') para los últimos 12 meses.
[DEBUG] 2025-07-31 10:22:50 Enviando informe por correo...
CRITICAL: Informe de alerta de espacio en tablespaces enviado.
En este log, vemos cómo el script analiza cada tablespace. Por ejemplo:
AUDIT_DATA: Tuvo un crecimiento negativo (-8MB), lo que significa que el espacio libre actual (519.62MB) es más que suficiente. ¡No hay alerta!SALES_DATA_2025: Mostró un crecimiento significativo de20241.5MBen el último mes, pero solo tiene6375.25MBde espacio libre. Esto dispara una alerta, ya que el espacio libre es menor que el crecimiento mensual. El script te enviaría un comandoALTER TABLESPACE "SALES_DATA_2025" RESIZE <nuevo_tamaño>M;sugerido.FILE_STORAGE: Un patrón similar al anterior, con6029MBde espacio libre y un crecimiento de20989MB. También generaría una alerta.TXN_DATA_2025: Otro tablespace que necesita atención, con4564.12MBlibres frente a un crecimiento de13935.13MB.
El Correo Electrónico de Alerta
Cuando se detecta un tablespace que necesita atención, el script genera un correo electrónico con un resumen detallado. Así es como se vería un correo de alerta , similar al que recibirías en tu bandeja de entrada:
Asunto: 🚨 Alerta de espacio en Tablespaces - [Nombre de tu PDB/Base de Datos]
Cuerpo del Correo:
📈 Alerta de Espacio en Tablespaces - ¡Necesitan Ampliación Pronto! 📈
Estimados administradores de bases de datos,
Se ha detectado que los siguientes tablespaces en la base de datos '[Nombre de tu PDB/Base de Datos]' tienen menos espacio libre disponible que su crecimiento registrado en el último mes. Esto indica una necesidad inminente de ampliación para evitar posibles interrupciones en el servicio.
--- Tablespace: SALES_DATA_2025 ---
> Tamaño Utilizado: 120324.75 MB
> Tamaño Asignado (Reservado): 126700 MB
> Espacio Libre Disponible: 6375.25 MB
> Crecimiento último mes: 20241.5 MB
> Alerta: El espacio libre (6375.25 MB) es menor que el crecimiento del último mes (20241.5 MB).
------------------------------------------------------------
Resumen de crecimiento mensual para SALES_DATA_2025 (últimos 12 meses):
MES CRECIMIENTO_MB
------- --------------
2025-02 14223.5
2025-03 15952.5
2025-04 17006.5
2025-05 18854.38
2025-06 20241.5
COMANDO SUGERIDO (ejecutar en PDB de producción):
ALTER TABLESPACE "SALES_DATA_2025" RESIZE 140566M;
--- Tablespace: FILE_STORAGE ---
> Tamaño Utilizado: 110707 MB
> Tamaño Asignado (Reservado): 116736 MB
> Espacio Libre Disponible: 6029 MB
> Crecimiento último mes: 20989 MB
> Alerta: El espacio libre (6029 MB) es menor que el crecimiento del último mes (20989 MB).
------------------------------------------------------------
Resumen de crecimiento mensual para FILE_STORAGE (últimos 12 meses):
MES CRECIMIENTO_MB
------- --------------
2024-09 0
2024-10 0
2024-11 0
2024-12 0
2025-01 0
2025-02 0
2025-03 384
2025-04 8512
2025-05 20802.88
2025-06 21053
COMANDO SUGERIDO (ejecutar en PDB de producción):
ALTER TABLESPACE "FILE_STORAGE" RESIZE 131696M;
--- Tablespace: TXN_DATA_2025 ---
> Tamaño Utilizado: 85135.88 MB
> Tamaño Asignado (Reservado): 89700 MB
> Espacio Libre Disponible: 4564.12 MB
> Crecimiento último mes: 13935.13 MB
> Alerta: El espacio libre (4564.12 MB) es menor que el crecimiento del último mes (13935.13 MB).
------------------------------------------------------------
Resumen de crecimiento mensual para TXN_DATA_2025 (últimos 12 meses):
MES CRECIMIENTO_MB
------- --------------
2025-02 10391.25
2025-03 11487.31
2025-04 12062.13
2025-05 13312.31
2025-06 13935.13
COMANDO SUGERIDO (ejecutar en PDB de producción):
ALTER TABLESPACE "TXN_DATA_2025" RESIZE 99071M;
--- Resumen de Comandos ALTER TABLESPACE Generados (para ejecutar en PDB de producción) ---
ALTER TABLESPACE "SALES_DATA_2025_OFS" RESIZE 140566M;
ALTER TABLESPACE "FILE_STORAGE_OFS" RESIZE 131696M;
ALTER TABLESPACE "TXN_DATA_2025_OFS" RESIZE 99071M;
Por favor, revisen estos tablespaces y consideren aplicar las acciones sugeridas lo antes posible.
Atentamente,
El equipo de Monitorización de Bases de Datos
[Tu Empresa/Organización]
¡Lleva la Gestión de DB al Siguiente Nivel!
Este script no solo te ayuda a evitar interrupciones, sino que te permite planificar tus ampliaciones de tablespaces con antelación, basándote en datos reales y no en suposiciones.




