Olá pessoal!
Espero que estejam bem!
Garantir a alta disponibilidade dos nossos bancos de dados Oracle é crucial para manter o desempenho ideal e cumprir os Acordos de Nível de Serviço (SLAs). O Oracle Enterprise Manager (OEM) oferece uma maneira bastante completa de monitorar e gerenciar o uptime dos banco de dados monitorados. Dito isso, recebi uma ligação de um cliente que perguntou:
- Existe alguma maneira de calcular o tempo de atividade do banco de dados nos últimos 30 dias usando uma abordagem simples e rápida?
Bem, a resposta é: sim!
O OEM tem as informações sobre uptime/disponibilidade na sua interface gráfica, onde você pode navegar até os alvos e verificar. Não sou um grande especialista em OEM, mas eu diria que talvez você possa criar algum relatório (ou talvez já exista) sobre disponibilidade.
OK, mas nós somos DBAs, gostamos de trabalhar usando SSH e SQL*Plus, não é? Então, a questão é:
- Existe alguma maneira de calcular o tempo de uptime do banco de dados nos últimos 30 dias usando instruções SQL?
Novamente, a resposta é: sim! Com certeza!
Se você estiver usando o Oracle Enterprise Manager, pode executar uma instrução SELECT diretamente nas views do OEM para calcular manualmente o uptime dos bancos de dados.
Esse blog post irá ajudá-lo a calcular o tempo de uptime do banco de dados e a porcentagem de SLA usando consulta SQL nas views do OEM.
Abaixo, vamos fazer um drill drown pela consulta SQL usada para calcular o uptime dos bancos de dados, tanto para bancos de dados single instance, quanto para bancos de dados RAC (Real Application Clusters) nos últimos 30 dias.
Below, we’ll walkthrough the SQL query used to calculate database uptime for both individual databases and RAC (Real Application Clusters) databases over the last 30 days.
Você precisa se conectar ao BD que é o repositório do OEM.
A consulta completa é essa:
COLUMN target_name FORMAT a11
COLUMN uptime_hours FORMAT 9999
SET LINESIZE 200
SET PAGESIZE 500
WITH availability AS (
SELECT
target_name,
target_type,
CASE
WHEN INSTR(target_name, '_') > 0 THEN SUBSTR(target_name, 1, INSTR(target_name, '_') - 1)
ELSE target_name
END AS cluster_name,
availability_status,
start_timestamp,
NVL(end_timestamp, SYSTIMESTAMP) AS end_timestamp
FROM
SYSMAN.MGMT$AVAILABILITY_HISTORY
WHERE
target_type = 'oracle_database'
AND start_timestamp >= TRUNC(SYSDATE) - 30
),
downtime AS (
SELECT
cluster_name,
SUM(CASE WHEN availability_status != 'Target Up' THEN (end_timestamp - start_timestamp) * 24 ELSE 0 END) AS downtime_hours
FROM
availability
GROUP BY
cluster_name
),
adjusted_uptime AS (
SELECT
cluster_name,
ROUND(720 - SUM(downtime_hours), 0) AS uptime_hours
FROM
downtime
GROUP BY
cluster_name
)
SELECT
cluster_name AS target_name,
uptime_hours,
ROUND((uptime_hours / 720) * 100, 2) AS sla_percentage
FROM
adjusted_uptime
ORDER BY
cluster_name;
Vamos fazer o breakdown da query. A query consiste em três partes:
- Extraindo e Normalizando Intervalos
- Calculando o Downtime
- Calculando o Uptime e o Percentual de SLA
Vamos começar com:
- Extraindo e Normalizando Intervalos
Essa parte da query extrai dados relevantes da view MGMT$AVAILABILITY_HISTORY e normaliza o nome do cluster para BD’s RAC:
WITH availability AS (
SELECT
target_name,
target_type,
CASE
WHEN INSTR(target_name, '_') > 0 THEN SUBSTR(target_name, 1, INSTR(target_name, '_') - 1)
ELSE target_name
END AS cluster_name,
availability_status,
start_timestamp,
NVL(end_timestamp, SYSTIMESTAMP) AS end_timestamp
FROM
SYSMAN.MGMT$AVAILABILITY_HISTORY
WHERE
target_type = 'oracle_database'
AND start_timestamp >= TRUNC(SYSDATE) - 30
)
Explicação::
- target_name: O nome do banco de dados ou instância;
- target_type: O tipo do alvo, que é ‘oracle_database’;
- cluster_name: Nome normalizado para clusters RAC, extraindo a parte do target_name antes do primeiro underscore. Para bancos de dados single instance, usa-se o próprio target_name;
- availability_status: O status do banco de dados (por exemplo, ‘Target Up’, ‘Target Down’);
- start_timestamp: A hora de início do intervalo de status;
- end_timestamp: A hora de término do intervalo de status, padronizando para o timestamp atual se estiver nulo.
Vamos agora para:
2. Calculando Downtime:
Essa parte agrega as horas de downtime para cada cluster:
downtime AS (
SELECT
cluster_name,
SUM(CASE WHEN availability_status != 'Target Up' THEN (end_timestamp - start_timestamp) * 24 ELSE 0 END) AS downtime_hours
FROM
availability
GROUP BY
cluster_name
)
Explicação:
- downtime_hours: Total de horas que o banco de dados esteve down (Eu estou assumindo que o BD esteve down se availability_status for diferente de ‘Target Up’).
Essa parte da query vai também vai somar as horas de downtime para cada cluster.
Vamos agora para:
3. Calculando o Uptime e o Percentual de SLA:
Essa parte calcula o uptime ajustado e o percentual de SLA com base no total de horas possíveis em um mês, 30 dias (720 horas):
adjusted_uptime AS (
SELECT
cluster_name,
ROUND(720 - SUM(downtime_hours), 0) AS uptime_hours
FROM
downtime
GROUP BY
cluster_name
)
SELECT
cluster_name AS target_name,
uptime_hours,
ROUND((uptime_hours / 720) * 100, 2) AS sla_percentage
FROM
adjusted_uptime
ORDER BY
cluster_name;
Explicação::
- uptime_hours: Total possível de horas (720) subtraído pelas horas de downtime;
- sla_percentage: O percentual de SLA calculado como (uptime_hours / 720) * 100.
Seguindo esta abordagem, você pode calcular com precisão o uptime dos bancos de dados e o percentual de SLA para seus bancos de dados Oracle usando views do OEM. Este método é particularmente útil para gerar relatórios de uptime e garantir que seus bancos de dados atendam aos padrões de disponibilidade necessários.
Abaixo temos um exemplo de saída. Os nomes dos bancos de dados foram substituídos por razões de segurança:
TARGET_NAME UPTIME_HOURS SLA_PERCENTAGE ----------- ------------ -------------- DB01 701 97.36 DB02 681 94.58 DB03 708 98.33 DB04 711 98.75 DB05 705 97.92 DB06 692 96.11 DB07 711 98.75 DB08 701 97.36 DB09 705 97.92 DB10 703 97.64 DB11 689 95.69 DB12 701 97.36 DB13 713 99.03 DB14 714 99.17 DB15 714 99.17 DB16 714 99.17 DB17 714 99.17 DB18 714 99.17 DB19 714 99.17 DB20 714 99.17 DB21 708 98.33 DB22 547 75.97
Espero que seja útil!
Um abraço,
Vinicius
Related posts
Disclaimer
Minhas postagens refletem minhas próprias opiniões e não representam necessariamente as opiniões do meu empregador, a Accenture.