Para modificar as regras de autenticação do banco de dados, utilize o utilitário gs_guc. O exemplo abaixo demonstra como recarregar a configuração para permitir conexões de replicação:
gs_guc reload -Z datanode -N all -I all -h 'host replication all 0.0.0.0/0 sha256'
2. Troca Manual de Nós (Primário/Secundário)
Para realizar o switchover manual do cluster, primeiro verifique o status e o ID do nó, e em seguida execute o comando de troca:
# Verificar status do cluster
cm_ctl query -Cvidp
# Executar a troca (switchover)
cm_ctl switchover -n [node_id] -D [data_dir]
3. Detecção de Transações de Longa Duração
Consulte a view pg_stat_activity para identificar transações abertas por mais de um minuto, excluindo a conexão atual:
SELECT
pid,
sessionid,
usename,
datname,
now() - xact_start AS duracao_transacao,
query,
state
FROM pg_catalog.pg_stat_activity
WHERE now() - xact_start > INTERVAL '1 minute'
AND pid <> pg_backend_pid()
ORDER BY duracao_transacao DESC;
4. Monitoramento de Consultas Lentas (Long Queries)
Para encontrar consultas em execução há mais de um minuto, utilize a seguinte query:
SELECT
pid,
sessionid,
usename,
application_name,
client_addr,
now() - query_start AS tempo_execucao,
query,
state
FROM pg_catalog.pg_stat_activity
WHERE now() - query_start > INTERVAL '1 minute'
AND pid <> pg_backend_pid()
ORDER BY tempo_execucao DESC;
5. Distribuição de Conexões Ativas por IP
Agrupe as conexões ativas (não ociosas) para visualizar a origem dos acessos:
SELECT
usename,
client_addr,
COUNT(*) AS total_conexoes
FROM pg_catalog.pg_stat_activity
WHERE state <> 'idle'
AND pid <> pg_backend_pid()
GROUP BY usename, client_addr
ORDER BY total_conexoes DESC;
6. Análise de Bloqueios e Espera
6.1 Detecção de Lock Wait
Identifique sessões bloqueadas juntando a atividade atual com o status de espera:
SELECT
act.pid,
act.datname,
act.usename,
act.query,
w.wait_event,
w.wait_status,
w.lockmode
FROM pg_catalog.pg_stat_activity act
JOIN pg_thread_wait_status w ON act.sessionid = w.sessionid
WHERE act.state = 'active'
AND act.pid <> pg_backend_pid()
AND act.client_addr IS NOT NULL
ORDER BY act.query_start DESC;
6.2 Detalhamento de Bloqueios
Para visualizar quem está bloqueando quem, utilize uma CTE para cruzar locks concedidos e pendentes:
WITH lock_info AS (
SELECT usename, granted, locktag, query_start, query
FROM pg_locks l
JOIN pg_stat_activity a ON l.pid = a.pid
WHERE locktag IN (SELECT locktag FROM pg_locks WHERE granted = 'f')
)
SELECT
t_lock.usename AS usuario_bloqueador,
t_lock.query AS query_bloqueadora,
w_lock.usename AS usuario_bloqueado,
w_lock.query AS query_bloqueada,
EXTRACT(EPOCH FROM now() - w_lock.query_start) AS tempo_espera_seg
FROM lock_info t_lock
JOIN lock_info w_lock ON t_lock.locktag = w_lock.locktag
WHERE t_lock.granted = 't' AND w_lock.granted = 'f';
7. Verificação de Slots de Replicação Inativos
Slots de replicação inativos podem causar acúmulo de WAL. Verifique-os filtrando por status:
SELECT * FROM pg_replication_slots
WHERE active = 'f'
AND slot_name NOT IN ('gs_roach_incr', 'gs_roach_full', 'dn_6002', 'dn_6003');
8. Consultas Lentas em Período Específico
Utilize a tabela de histórico de desempenho para auditar queries lentas em uma janela de tempo:
SELECT
*,
finish_time - start_time AS tempo_total
FROM dbe_perf.statement_history
WHERE start_time BETWEEN '2023-01-01 08:00:00' AND '2023-01-01 10:00:00'
ORDER BY tempo_total DESC;
9. Monitoramento de Latência de Replicação
Calcule o atraso (lag) entre o WAL atual e a posição dos slots de replicação:
SELECT
rs.slot_name,
rs.active,
pg_size_pretty(pg_xlog_location_diff(pg_current_wal_lsn(), rs.restart_lsn)) AS latencia_wal
FROM pg_catalog.pg_replication_slots rs;
10. Verificação de Função do Nó
Verifique se o nó está em modo de recuperação (Standby) ou operando como Primário:
SELECT
pg_is_in_recovery(),
pg_last_xlog_receive_location(),
pg_last_xlog_replay_location();
11. Análise de Armazenamento (Tabelas e Índices)
11.1 Tamanho das Tabelas
SELECT
CURRENT_CATALOG AS banco_dados,
nsp.nspname AS esquema,
rel.relname AS tabela,
pg_size_pretty(pg_total_relation_size(rel.oid)) AS tamanho_total
FROM pg_namespace nsp
JOIN pg_class rel ON nsp.oid = rel.relnamespace
WHERE nsp.nspname NOT IN ('pg_catalog', 'information_schema', 'snapshot')
AND rel.relkind = 'r'
ORDER BY pg_total_relation_size(rel.oid) DESC
LIMIT 50;
11.2 Índices com Maior Tamanho
SELECT
schemaname,
relname AS tabela,
indexrelname AS indice,
pg_size_pretty(pg_table_size(indexrelid)) AS tamanho_indice
FROM pg_stat_user_indexes
WHERE schemaname NOT IN ('pg_catalog', 'information_schema', 'snapshot')
ORDER BY pg_table_size(indexrelid) DESC
LIMIT 50;
11.3 Taxa de Bloat (Tuplas Mortas)
SELECT
schemaname,
relname,
n_live_tup AS tuplas_vivas,
n_dead_tup AS tuplas_mortas,
ROUND((n_dead_tup::numeric / NULLIF((n_dead_tup + n_live_tup), 0) * 100), 2) AS percentual_bloat
FROM pg_stat_user_tables
WHERE (n_live_tup + n_dead_tup) > 10000
ORDER BY percentual_bloat DESC
LIMIT 50;
12. Consumo de Memória por Sessão
12.1 Memória por Estado da Sessão
SELECT
a.state,
SUM(m.totalsize)::bigint AS memoria_total_bytes
FROM gs_session_memory_detail m
JOIN pg_stat_activity a ON substring_inner(m.sessid, position('.' in m.sessid) + 1) = a.sessionid::text
WHERE a.pid != pg_backend_pid()
GROUP BY a.state
ORDER BY memoria_total_bytes DESC;
13. SQL Lento em Tempo Real
Monitoramento de sessões ativas com tempo de execução elevado:
SELECT
datname,
usename,
pid,
query_start,
EXTRACT(EPOCH FROM (now() - query_start)) AS tempo_execucao_seg,
state,
query
FROM pg_stat_activity
WHERE state NOT IN ('idle')
AND query_start IS NOT NULL
ORDER BY tempo_execucao_seg DESC;
14. Mapeamento de Thread do Sistema para Query
Script shell para identificar qual query está consumindo CPU em uma thread específica:
#!/bin/bash
source ~/.bashrc
# Encontra threads 'worker' do processo gaussdb
TIDS=$(ps -ef | grep gaussdb | grep -v grep | awk '{print $2}' | xargs top -n 1 -bHp | grep ' worker' | awk '{print $1}' | tr "\n" "," | sed 's/,$//')
gsql -p 26000 postgres -c "SELECT pid, lwtid, state, query FROM pg_stat_activity a, dbe_perf.thread_wait_status s WHERE a.pid = s.tid AND lwtid IN ($TIDS);"
15. Análise de Atraso de Replicação
15.1 Atraso nos Slots
SELECT
slot_name,
active,
pg_xlog_location_diff(
CASE WHEN pg_is_in_recovery() THEN restart_lsn ELSE pg_current_xlog_location() END,
restart_lsn
) AS lsn_delay_bytes
FROM pg_replication_slots;
15.2 Atraso Primário vs Secundário
No servidor primário:
SELECT client_addr, sync_state,
pg_xlog_location_diff(pg_current_xlog_location(), receiver_replay_location)
FROM pg_stat_replication;
No servidor secundário:
SELECT
now() AS momento_atual,
pg_last_xact_replay_timestamp() AS ultimo_replay,
EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) AS atraso_segundos;
16. Depuração de Processos Travados (Hang)
Para analisar uma query que está travada, obtenha o ID da thread do sistema (lwtid) e use ferramentas do SO:
-- Passo 1: Obter ID da Thread (lwtid)
SELECT pid, lwtid, state, query
FROM pg_stat_activity a, dbe_perf.thread_wait_status s
WHERE a.pid = s.tid AND query LIKE '%trecho_da_query%';
-- Passo 2: No SO, verificar stack trace
pstack [lwtid_obtido]
17. Histórico de Auditoria de Login
Consulta ao log de auditoria para verificar origens de conexão em um período:
SELECT
time,
username,
substring(client_conninfo::varchar from position('@' in client_conninfo::varchar) + 1 for 15) as ip_origem
FROM pg_query_audit('2024-01-01 08:00:00', '2024-01-01 10:00:00')
WHERE username NOT IN ('rdsAdmin', 'rdsMetric')
ORDER BY time ASC;
18. Histórico de Sessões e Performance
Analise sessões históricas e tempo de execução de queries passadas:
SELECT
sample_time,
sessionid,
d.datname,
r.rolname,
query
FROM dbe_perf.local_active_session a
LEFT JOIN pg_database d ON a.databaseid = d.oid
LEFT JOIN pg_roles r ON a.userid = r.oid
WHERE sample_time BETWEEN '2024-01-01 08:00:00' AND '2024-01-01 10:00:00'
ORDER BY sample_time;