Referência de DBA
Regras de uso: os comandos abaixo são as formas estáveis e bem conhecidas. O comportamento difere entre versões e edições (licenciamento!) - quando uma linha disser "verifique em relação à sua versão", consulte a documentação do fornecedor para a release exata antes de confiar nela. Nunca execute instruções de diagnóstico que modifiquem dados em produção sem um registro de mudança.
1. Comparação rápida de engines
| Tópico | Oracle | PostgreSQL | SQL Server | Db2 LUW | MySQL / MariaDB (InnoDB) |
|---|---|---|---|---|---|
| Modelo de concorrência | MVCC (undo); leitores nunca bloqueiam escritores | MVCC (versões de linha na tabela; VACUUM) | Locking por padrão; MVCC se RCSI/snapshot habilitado | Locking; leituras "currently committed" (CUR_COMMIT) | MVCC (undo) + gap/next-key locks em REPEATABLE READ (padrão) |
| DDL transacional | Não (commit implícito antes/depois) | Sim (exceto, e.g., CREATE INDEX CONCURRENTLY, CREATE DATABASE, VACUUM) | Sim para a maioria das DDL | Sim para a maioria das DDL (verifique por instrução) | Não (commit implícito; DDL do MySQL 8 é atômica apenas por instrução) |
| Escalonamento de lock | Nunca | Nunca | Sim (linha/página -> tabela, ~5000 locks por objeto por instrução) | Sim (LOCKLIST/MAXLOCKS) | Não (mas gap locks) |
| Estatísticas de consulta | AWR/ASH (Diagnostics Pack), Statspack | pg_stat_statements | Query Store, DMVs | Funções de tabela MON_GET_* | performance_schema, sys schema, slow log |
| Timeout de lock de sessão | ALTER SESSION SET DDL_LOCK_TIMEOUT = 30; (DDL, segundos) | SET lock_timeout = '5s'; | SET LOCK_TIMEOUT 5000; (ms) | SET CURRENT LOCK TIMEOUT 30; (s) | SET SESSION lock_wait_timeout = 30; (metadata locks) + innodb_lock_wait_timeout (row locks) |
2. Diagnóstico de desempenho
Método: (1) defina o sintoma (uma consulta, uma janela de tempo, toda a instância); (2) veja as esperas/modelo de tempo antes de ajustar a SQL; (3) obtenha o plano real (não apenas o estimado); (4) compare linhas estimadas vs. reais - estimativas incorretas de cardinalidade são a causa raiz usual (estatísticas desatualizadas, skew, predicados correlacionados, parameter sniffing/bind peeking); (5) mude uma coisa, meça.
Oracle
- Plano estimado:
EXPLAIN PLAN FOR <stmt>;entãoSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); - Plano real: execute com
/*+ GATHER_PLAN_STATISTICS */entãoSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('<SQL_ID>', NULL, 'ALLSTATS LAST')); - AWR/ASH/ADDM (
@?/rdbms/admin/awrrpt.sql,ashrpt.sql,addmrpt.sql,V$ACTIVE_SESSION_HISTORY,DBA_HIST_*) exigem o Diagnostics Pack (Enterprise Edition); SQL Monitor e SQL Tuning Advisor exigem o Tuning Pack. VerifiqueCONTROL_MANAGEMENT_PACK_ACCESS. Sem licença: Statspack. - Esperas ao vivo:
V$SESSION(event,wait_class,sql_id,blocking_session),V$SYSTEM_EVENT,V$SQL/V$SQLSTATS. - Esperas comuns:
db file sequential read(single-block, acesso a índice),db file scattered read/direct path read(full scans),log file sync(frequência de commit / I/O de redo),enq: TX - row lock contention(locking de aplicação),enq: TM - contention(frequentemente chaves estrangeiras sem índice),latch: cache buffers chains(blocos quentes),gc *(RAC interconnect). - Estabilidade de plano: SQL Plan Management (baselines); perfis SQL precisam do Tuning Pack.
PostgreSQL
EXPLAIN (ANALYZE, BUFFERS) <stmt>;- ANALYZE executa a instrução: envolva DML emBEGIN; ... ROLLBACK;.pg_stat_statements(precisa deshared_preload_libraries): top SQL portotal_exec_time(nomes de colunas mudaram no PG13:total_exec_time,mean_exec_time).SELECT queryid, calls, round(total_exec_time) total_ms, round(mean_exec_time::numeric,1) mean_ms, rows, left(query,80) FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 20;- Ao vivo:
pg_stat_activity(state,wait_event_type,wait_event,xact_start,query); sessõesidle in transactionseguram locks e bloqueiam VACUUM. - Módulo
auto_explainpara planos lentos em logs;track_io_timing = onpara timings de I/O. - Saúde:
pg_stat_user_tables(seq_scan,n_dead_tup,last_autovacuum,last_autoanalyze); inchaço; wraparound de ID de transação:SELECT datname, age(datfrozenxid) FROM pg_database;. - Kill:
pg_cancel_backend(pid)(consulta) entãopg_terminate_backend(pid)(sessão).
SQL Server
- Plano real: SSMS "Include Actual Execution Plan" ou
SET STATISTICS XML ON;;SET STATISTICS IO, TIME ON;para leituras/CPU. - Query Store (2016+; ON por padrão para novos bancos em 2022):
sys.query_store_query,sys.query_store_query_text,sys.query_store_plan,sys.query_store_runtime_stats,sys.query_store_wait_stats(2017+); regressões -> forçar planoEXEC sp_query_store_force_plan @query_id = <q>, @plan_id = <p>;. - DMVs:
sys.dm_exec_requests(wait_type,blocking_session_id),sys.dm_os_wait_stats,sys.dm_exec_query_stats+CROSS APPLY sys.dm_exec_sql_text(sql_handle)+sys.dm_exec_query_plan(plan_handle). - Esperas comuns:
PAGEIOLATCH_*(leituras de dados),LCK_M_*(bloqueio),WRITELOG(I/O de log / taxa de commit),CXPACKET/CXCONSUMER(paralelismo - verifique MAXDOP/cost threshold),SOS_SCHEDULER_YIELD(CPU),ASYNC_NETWORK_IO(cliente não consumindo resultados),RESOURCE_SEMAPHORE(concessões de memória). - Parameter sniffing: compare planos por parâmetro; opções
OPTION (RECOMPILE),OPTIMIZE FOR, dicas do Query Store (2022) - escolha por caso. - Extended Events; a sessão
system_healthmantém gráficos de deadlock recentes.
Db2 LUW
- Explain: crie tabelas explain (
SYSPROC.SYSINSTALLOBJECTSouEXPLAIN.DDL),EXPLAIN PLAN FOR <stmt>, formate comdb2exfmt -d <DB> -1 -o plan.txt; visão rápidadb2expln. - Funções de tabela de monitoramento:
MON_GET_PKG_CACHE_STMT(top SQL:STMT_EXEC_TIME,NUM_EXECUTIONS,ROWS_READ),MON_GET_CONNECTION,MON_GET_ACTIVITY,MON_GET_TABLE,MON_GET_BUFFERPOOL. - Locks:
SYSIBMADM.MON_LOCKWAITS,db2pd -db <DB> -wlocks,db2pd -db <DB> -locks. - Estatísticas:
RUNSTATS ON TABLE <SCHEMA>.<TABLE> WITH DISTRIBUTION AND DETAILED INDEXES ALL;-REORGCHKpara avaliar necessidades de reorg;db2advispara conselhos de índice.
MySQL / MariaDB
EXPLAIN <stmt>; real: MySQL 8.0.18+EXPLAIN ANALYZE <stmt>; MariaDBANALYZE <stmt>(ambos executam a instrução).- Top SQL:
sys.statement_analysis,performance_schema.events_statements_summary_by_digest; slow query log (slow_query_log,long_query_time) +pt-query-digest. - InnoDB:
SHOW ENGINE INNODB STATUS\G(último deadlock, tamanho do history list),information_schema.INNODB_TRX,sys.innodb_lock_waits; MySQL 8:performance_schema.data_locks/data_lock_waits; MariaDB:information_schema.INNODB_LOCKS/INNODB_LOCK_WAITSe o pluginMETADATA_LOCK_INFO; metadata locks do MySQL:performance_schema.metadata_locks.
3. Locking e concorrência - armadilhas
| Engine | Armadilha | Mitigação |
|---|---|---|
| Todos | Transação longa + DDL: a DDL espera, e toda consulta posterior fica na fila atrás dela | Timeout de lock curto na DDL, loop de repetição, execute quando não houver transações longas; verifique antes (sessões ativas) |
| Oracle | Chaves estrangeiras sem índice -> TM locks no filho quando linhas pai são excluídas/PK atualizado | Indexar colunas FK |
| Oracle | DDL falha ORA-00054 em objeto ocupado | DDL_LOCK_TIMEOUT; variantes online (CREATE INDEX ... ONLINE, ALTER TABLE ... MOVE ONLINE 12.2+, DBMS_REDEFINITION) - todas Enterprise Edition apenas (não em SE2) |
| Oracle | Commit dentro de um loop sobre um cursor aberto -> ORA-01555 snapshot too old | Dividir por faixas de chave/rowid (DBMS_PARALLEL_EXECUTE), dimensionar undo retention |
| PostgreSQL | A maioria dos ALTER TABLE usa ACCESS EXCLUSIVE; esperar por ele bloqueia todos os leitores | SET lock_timeout; CREATE INDEX CONCURRENTLY; FK/CHECK NOT VALID então VALIDATE CONSTRAINT |
| PostgreSQL | Alteração de tipo de coluna reescreve a tabela (exceto casos seguros como aumentar o tamanho de varchar) | Expandir/contrair com nova coluna + backfill |
| PostgreSQL | Sessões idle in transaction | idle_in_transaction_session_timeout, corrija a aplicação |
| SQL Server | Leitores bloqueiam escritores sob READ COMMITTED padrão | Avalie READ_COMMITTED_SNAPSHOT ON (impacto no armazenamento de versão do tempdb; teste) |
| SQL Server | Escalonamento de lock para tabela em DML grande | Lotes abaixo de ~5000 linhas; ALTER TABLE ... SET (LOCK_ESCALATION = ...) com cuidado |
| SQL Server | NOLOCK usado como "correção" | Leituras sujas, linhas ausentes/duplicadas - rejeite em revisões |
| Db2 | LOCKTIMEOUT = -1 (esperar para sempre) padrão | Defina CURRENT LOCK TIMEOUT em sessões de release |
| Db2 | ALTER TABLE ... DROP COLUMN, a maioria dos ALTER COLUMN SET DATA TYPE, SET NOT NULL/DROP NOT NULL colocam uma tabela organizada por linha em estado reorg-pending (SQLSTATE 57007): até REORG TABLE apenas scans, DROP/RENAME/TRUNCATE e a maioria dos outros ALTERs são permitidos; no máximo 31 unidades de trabalho de tais operações antes que REORG se torne obrigatório | Planeje REORG TABLE na janela; verifique REORG_PENDING / NUM_REORG_REC_ALTERS em SYSIBMADM.ADMINTABINFO |
| MySQL | Esperas de metadata lock (MDL): DDL bloqueada por uma transação aberta então bloqueia todos | lock_wait_timeout baixo na sessão de release; mate transações longas ociosas |
| MySQL | DDL online silenciosamente cai para cópia de tabela | Sempre declare ALGORITHM=INSTANT (ou INPLACE) com LOCK=NONE para que gere erro; ou gh-ost / pt-online-schema-change |
| MySQL | Gap/next-key locks em atualizações de intervalo sob REPEATABLE READ | Indexe o predicado; considere READ COMMITTED onde aceitável |
Deadlocks: sempre um problema de design (ordem de acesso inconsistente, índices ausentes). Capture: Oracle arquivo de trace / alert log (ORA-00060), PostgreSQL log (log_lock_waits = on para esperas > deadlock_timeout), SQL Server system_health XE, Db2 event monitor para locking, MySQL innodb_print_all_deadlocks.
4. HA / DR
| Engine | HA local | DR / réplicas | Principais operações e verificações |
|---|---|---|---|
| Oracle | RAC (armazenamento compartilhado, ativo-ativo, licença extra) | Data Guard standby físico (redo apply); Active Data Guard = aberto somente leitura com apply (licença extra) | Modos de proteção: Maximum Performance (ASYNC, padrão), Maximum Availability (SYNC, recua), Maximum Protection (SYNC, primário para se não houver standby). Broker dgmgrl: SHOW CONFIGURATION;, VALIDATE DATABASE <stby>;, SWITCHOVER TO <stby>;, FAILOVER TO <stby>;. Lag: V$DATAGUARD_STATS. Primário em FORCE LOGGING. Fast-Start Failover precisa de um observer (idealmente em um terceiro site). |
| PostgreSQL | Patroni (DCS: etcd/Consul/ZooKeeper) + HAProxy/VIP | Replicação streaming (física, WAL); replicação lógica (publicações/assinaturas, PG10+) | pg_stat_replication (sent_lsn, write_lsn, flush_lsn, replay_lsn), pg_is_in_recovery(), pg_promote() (PG12+). Sync: synchronous_standby_names + synchronous_commit. Slots de replicação retêm WAL se uma réplica estiver inativa -> disco cheio: monitore, limite com max_slot_wal_keep_size (PG13+). Patroni: patronictl -c <cfg> list / switchover / failover; endpoints REST de saúde (/primary, /replica) para o balanceador de carga. Replicação lógica não replica nem DDL nem valores de sequência (a partir do PG 18): aplique mudanças de esquema aditivas no assinante primeiro e redefina sequências antes de fazer failover para um assinante. |
| SQL Server | Failover Cluster Instance (armazenamento compartilhado, WSFC) | Always On Availability Groups (WSFC, ou Pacemaker no Linux); log shipping | Failover automático apenas entre réplicas síncronas. Listener para clientes (MultiSubnetFailover=True). Logins, Agent jobs, linked servers, credenciais NÃO são replicados (contained AG, SQL Server 2022 Enterprise, ajuda). AGs completas precisam de Enterprise; Basic AG na Standard Edition (1 DB, 2 réplicas). Verifique sys.dm_hadr_database_replica_states. Failover planejado: ALTER AVAILABILITY GROUP [<AG>] FAILOVER; na réplica síncrona de destino. Secundárias legíveis têm impacto de licenciamento. |
| Db2 LUW | pureScale (ativo-ativo) ou HADR + automação Pacemaker/TSA | HADR (até 3 standbys, HADR_TARGET_LIST) | HADR_SYNCMODE: SYNC, NEARSYNC, ASYNC, SUPERASYNC. Monitore db2pd -db <DB> -hadr ou MON_GET_HADR. Troca de papel no standby: TAKEOVER HADR ON DATABASE <DB> (BY FORCE para failover). Leituras no standby via DB2_HADR_ROS (limitações). |
| MySQL / MariaDB | InnoDB Cluster (Group Replication + MySQL Router); Galera (MariaDB) | Replicação Async / semi-sync, baseada em GTID | SHOW REPLICA STATUS (MySQL 8.0.22+; MariaDB 10.5.1+ aceita REPLICA como sinônimo de SLAVE; versões antigas: SHOW SLAVE STATUS). Monitore lag de replicação e GTIDs errantes; Galera precisa de um quorum de componente primário (3 nós ou árbitro). |
Regras de design: defina RPO/RTO por aplicação antes de escolher sync/async; teste DR pelo menos anualmente com resultados documentados (DORA exige teste de continuidade de TIC para entidades financeiras); clientes devem se reconectar de forma transparente (strings de conexão com múltiplos hosts/listener/SCAN, lógica de repetição); monitore lag e alerte; proteção contra split-brain (quorum, fencing, observer/witness em um terceiro site).
5. Backup, restauração, PITR
| Engine | Completo / incremental | PITR | Validar |
|---|---|---|---|
| Oracle (RMAN) | BACKUP DATABASE PLUS ARCHIVELOG; incremental nível 0/1; CONFIGURE CONTROLFILE AUTOBACKUP ON; CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 14 DAYS; | Modo ARCHIVELOG obrigatório. RUN { SET UNTIL TIME "TO_DATE('2026-10-01 12:00','YYYY-MM-DD HH24:MI')"; RESTORE DATABASE; RECOVER DATABASE; } então ALTER DATABASE OPEN RESETLOGS; | RESTORE DATABASE VALIDATE;, CROSSCHECK BACKUP;, LIST BACKUP SUMMARY;, REPORT NEED BACKUP;, DELETE OBSOLETE; |
| PostgreSQL | pg_basebackup -D <dir> -Ft -z -X stream -P; pgBackRest --type=full / diff / incr backup; Barman. pg_dump é apenas lógico (sem PITR) | Arquivamento WAL (archive_mode, archive_command); restaure base + restore_command + recovery_target_time + recovery.signal (PG12+). pgBackRest: pgbackrest --stanza=<s> --type=time "--target=2026-10-01 12:00:00+02" restore | pgbackrest --stanza=<s> check, pgbackrest --stanza=<s> info; teste de restauração real periódico |
| SQL Server | Modelo de recuperação FULL; BACKUP DATABASE [<db>] TO DISK = N'<path>' WITH CHECKSUM, COMPRESSION; diferencial; BACKUP LOG | Restaure full WITH NORECOVERY, diferencial WITH NORECOVERY, então logs WITH NORECOVERY até a hora desejada usando STOPAT, então RESTORE DATABASE [<db>] WITH RECOVERY;. | RESTORE VERIFYONLY FROM DISK = N'<path>'; + teste de restauração regular |
| Db2 LUW | BACKUP DATABASE <DB> TO <path> (WITH 2 BUFFERS); incremental INCREMENTAL DELTA (nível delta); INCLUDE LOGS para PITR | Modo LOGARCHMETH1 deve estar ativo (TDP/TSM ou arquivamento de disco DISK:<path>). Restaure backup + ROLLFORWARD DATABASE <DB> TO 2026-10-01-12.00.00 USING LOCAL TIME AND STOP; | db2ckbkp, LIST HISTORY BACKUP ALL FOR <DB>;; pratique failover de HADR |
| MySQL / MariaDB | Ferramentas físicas: XtraBackup (Percona), mysqlbackup (MySQL Enterprise Backup, OE, pago); lógico: mysqldump --single-transaction --quick --all-databases (sem PITR); MariaDBBackup (fork do XtraBackup) | Binary logs (log_bin, expire_logs_days ou binlog_expire_logs_seconds); restaure backup físico completo, depois `mysqlbinlog ... --stop-datetime="2026-10-01 12:00:00" | mysql` |
Práticas recomendadas: automatize a verificação de backup; teste a restauração fora do ambiente de produção periodicamente (SLAs); criptografe backups em repouso; documente a sequência de restauração; para regulamentação financeira (DORA, SOX, PCI-DSS), pelo menos um teste de restauração completo e um exercício de DR por ano; tempos de backup e restauração devem estar dentro do RTO: meça e dimensione.
6. Segurança / GDPR
| Tópico | Ação |
|---|---|
| Criptografia em repouso (TDE) | Oracle TDE (Transparent Data Encryption) – licença Advanced Security; PostgreSQL pgcrypto/extensões ou criptografia no nível do sistema de arquivos; SQL Server TDE (padrão); Db2 ENCRYPT (native ou NCrypt); MySQL/MariaDB InnoDB tablespace encryption (MySQL 5.7+/MariaDB 10.1+); distribua e proteja chaves de forma separada (HSM ou cofre de chaves); $key must not be stored on the database host |
| Criptografia em trânsito | Force SSL/TLS: Oracle SQLNET.ENCRYPTION_SERVER=REQUIRED, WALLET / SSL_SERVER_DN_MATCH; PostgreSQL ssl = on, ssl_cert_file, ssl_key_file, ssl_ca_file; SQL Server Force Encryption (certificado); Db2 SSL_ENABLE=YES e SSL_SVR_STASH; MySQL require_secure_transport=ON, usuários REQUIRE SSL, REQUIRE X509; certifique-se de que clientes de aplicação também exijam TLS (rejeite conexões não criptografadas), |
| Mascaramento de dados | Oracle Data Redaction (Advanced Security); PostgreSQL extensões anon (pg_anon, postgresql_anonymizer); SQL Server Dynamic Data Masking; MySQL Enterprise Masking; para ambientes não produtivos, crie um processo de mascaramento repetível e estável, não apenas scripts manuais |
| Auditoria | Oracle Audit Vault (licença separada) ou UNIFIED_AUDIT_TRAIL (padrão); PostgreSQL pgaudit extensão; SQL Server SERVER AUDIT / DATABASE AUDIT SPECIFICATION; Db2 audit facilidade (audit buffer pool); MySQL Enterprise Audit (plugin audit_log no MySQL Enterprise) ou MariaDB Audit Plugin (Server Service+); audite acesso a dados sensíveis, mudanças de privilégio e tentativas de login com falha |
| PII Discovery | Oracle Data Masking & Subsetting (Enterprise Manager); PostgreSQL consultas de metadados combinadas com expressões regulares ou ferramentas de terceiros (eg, Priverion, Octai); SQL Server SQL Vulnerability Assessment (Azure Data Studio) / SSMS; ferramentas de database scanning para PII (email, CPF, cartão de crédito) baseadas em padrões |
| Right to Erasure / Deletion | GDPR Article 17: defina scripts de exclusão lógica (soft delete) ou exclusão em cascata (cascade delete) ORquestrados pela aplicação; não emita apagões brutos diretamente (bloqueios transacionais, dados órfãos); tenha uma retenção documentada (se legalmente necessária, anonimize em vez de excluir); meça o tempo de execução para o maior conjunto de dados |
Regras: conheça seus dados (classificação); aplique privilégio mínimo; evite contas de dorminhoco; use vaults de senha/variáveis de ambiente para cadeias de conexão (sem texto simples); documente o fluxo de dados (controlador vs. processador); tenha um processo de incidente de violação de dados (72 horas para notificação sob GDPR).
7. Migração Oracle -> PostgreSQL – armadilhas
A migração de Oracle para PostgreSQL é comum. Os assistentes gráficos (ora2pg, AWS DMS / SCT) funcionam para a maior parte dos objetos, mas algumas construções precisam ser refatoradas manualmente.
Diferenças de tipo
NUMBER(sem precisão) vs.NUMERIC(cuidado com escala 0 padrão no Oracle, sem padrão no PG). UseNUMERIC(38)ou análogo.DATEno Oracle = timestamp (ano-mês-dia hora:min:seg). PostgreSQL:DATE= apenas data,TIMESTAMP= data + hora. Migre híbridos de data/hora do Oracle (DATE) paraTIMESTAMP(0)no PG.VARCHAR2(4000)cabe normalmente.VARCHAR2(32767)no Oracle PL/SQL precisa deTEXTno PG (sem limite arbitrário).BINARY_FLOAT/BINARY_DOUBLE->REAL/DOUBLE PRECISION(lógica de valor especial NaN/Infinity é definida de forma diferente).ROWIDnão é um tipo de dados embutido no PG. Usectidpara posição física ou chave primária.- Tipos espaciais Oracle (SDO_GEOMETRY) -> PostGIS (geometry/geography).
Diferenças de sintaxe SQL
- Consultas de paginação:
OFFSET/FETCH FIRST(SQL:2008) funciona em ambos desde PG 8.4 e Oracle 12.1+. Mais antigo: Oracle usaROWNUM(aplica-se antes da ordenação, propenso a erros), PG usaLIMIT/OFFSET.ROWNUM,ROW_NUMBER()OVER (ORDER BY ...)funciona de forma confiável em ambos os casos. - Junção por vírgula implícita: Oracle permite junções por vírgula e mistura com ANSI. PG pede ANSI. Paliativo: parâmetro
transformOracleJoinno orafce não é uma correspondência de gramática completa. - Dual: Oracle requer
FROM dualpara expressões sem tabela. PG aceitaSELECT <expr>sem cláusulaFROM. Crie uma viewdualpara código compatível, mas trate-a com cautela. - Connect by (hierárquico): substitua por CTE recursiva (
WITH RECURSIVE). A maioria das ferramentas (ora2pg) faz isso, mas verifique. - MERGE: Oracle e PG suportam
MERGE(PG 15+ compatível; PG 15- usaINSERT ... ON CONFLICT/UPDATE ... FROM). - Flashback Query (
AS OF TIMESTAMP/AS OF SCN): sem substituto direto. Usepg_visibility, replicação lógica ou padrão de tabela de histórico.
Diferenças de PL/SQL vs. PL/pgSQL
- Blocos anônimos e funções: altere a sintaxe (palavras-chave
IS/BEGIN/END, chamada de funçãoSELECT function(...)ouPERFORM). - Pacotes: não existem (use esquemas, funções e variáveis de sessão (parâmetros personalizados
SET myapp.myvar) ). - Cursores:
SYS_REFCURSORcomoREFCURSORno PG,%ROWTYPEcomoRECORD,%TYPEé semelhante. AUTONOMOUS_TRANSACTION: pragma Oracle. PG: pode ser simulado por dblink (pg_background), mas evite sempre que possível (problemas de transação aninhada). Redesenhe a lógica.- Tipos de coleção: Oracle
VARRAY/NESTED TABLEcomoTABLE OFouARRAYno PG (esquema necessário). - Tratamento de exceções (diferentes nomes e causewords):
OTHERSda Oracle =WHEN OTHERSno PG;SQLERRM=SQLERRM(mas menos detalhes).NO_DATA_FOUND=NO_DATA_FOUND.TOO_MANY_ROWS=TOO_MANY_ROWS. Renomeie códigos de erro Oracle para os do PG.
Diferenças de otimização
- Estatísticas: Oracle
DBMS_STATS(padrão de amostragem) vs. PGANALYZE(vastos padrões). Cardinalidades são diferentes: reavalie planos após a migração. Execute uma coleta de estatísticas completa. - Hints: PG não tem hints (Oracle usa
/*+ ... */). Usepg_hint_planpara correspondência aproximada, mas o preferido é ajustar configurações (desabilitar determinados tipos de junção, random_page_cost, effective_cache_size) ou reescrever consultas. - Índices funcionais / baseados em expressão: ambos suportam, sintaxe ligeiramente diferente.
- Índices de bitmap: sem equivalente no PG (não existe). Reavalie com índices B-tree ou índices de extensão (pg_trgm, Bloom).
- Materialized Views: ambos suportam. Oracle
REFRESH COMPLETEvs.REFRESH MATERIALIZED VIEW CONCURRENTLY(PG 9.4+); PG requer um índice único exclusivo na MV paraCONCURRENTLY. - Parallel Query: PG suporta varreduras e junções paralelas (vem do paradigma de processo, Oracle de servidores paralelos). Configure
max_parallel_workers_per_gatheretc. e compare.
Operação e administração
- Sequências: no Oracle, o cache padrão é 20; no PG, o cache padrão é 1 (e as sequências podem ter lacunas devido a rollbacks). Defina
CACHEmaior para desempenho se gaps forem aceitáveis. - Synonym: não existe. Use views ou ajuste search_path.
- Triggers: sintaxe de corpo
FOR EACH ROWe tabelasOLD/NEWfuncionam de forma semelhante. No PG, triggers podem serBEFORE,AFTERouINSTEAD OF; sem triggers compostos (Oracle 12c+ tem). - Job scheduling: Oracle
DBMS_SCHEDULER/DBMS_JOB. PG:pg_cron(extensão) ou agendador de sistema (crontab, systemd). - Tablespaces: Oracle faz forte separação de armazenamento. PG gerencia tablespaces, mas não é tão utilizado (Gerenciamento de armazenamento a nível de banco de dados).
- Perfis e senhas: Oracle
PROFILE(complexidade de senha, recursos). PG: extensõespasswordcheck+pgaudit.ALTER SYSTEM SETe funções de criptografia.
8. Scripts de release – melhores práticas
Controle de versão
- Cada script de release (schema, dados, refatoração) é uma única confirmação, com ID de ticket, descrição e autor. Sem expresso manual em produção. Se a aplicação usa Flyway/Liquibase, siga sua numeração; caso contrário, use uma sequência nomeada (R__release_v1.2.3__description.sql).
- Teste cada script de release em staging/QA antes da produção.
- Inclusões: (1) o script em si; (2) um script de reversão (rollback.sql), embora reversões possam não ser possíveis para DDL destrutiva – tenha-o mesmo assim; (3) quaisquer etapas de migração de dados em lote.
- Certifique-se de que aplicativos que se conectam à produção esperam rollbacks para trás.
Diretrizes de script
- Idempotência:
CREATE TABLE IF NOT EXISTS ...,ALTER TABLE ... ADD COLUMN IF NOT EXISTS,CREATE OR REPLACE VIEWetc. Libere scripts que possam ser executados novamente com segurança (por exemplo, colunas adicionadas não duplicadas). - Transação: DML de migração de dados (UPDATE/INSERT) e DDL podem ser executados em uma transação no PostgreSQL (e geralmente em outros) – lide com todos os metadados e dados em um
BEGIN ... COMMIT;(exceto operações sem transação). Em engines que confirmam DDL implicitamente (Oracle, MySQL), agrupe DDL separadamente, então DML que dependa da DDL. - Tamanho do lote: se você estiver alterando milhões de linhas, divida em lotes (< 5000 linhas) para evitar escalonamento de lock / estouro de logs de transação. Inclua
WHERE id BETWEEN ... AND ...ou um loop procedural. - Gerenciamento de bloqueio: para DDL intensa, use declarações
ONLINEouCONCURRENTLYse disponíveis; caso contrário, programe fora do pico. UseSET lock_timeout/DDL_LOCK_TIMEOUTcom valor curto e loop de repetição. - Preparação antes: certifique-se de que não haja transações abertas de longa duração (sessões
idle in transaction, ou queries longas). Verifique a replicação de lag antes de DDL destrutiva (se lag > segundos, a réplica pode parar). - Implantação reversível: prefira adicionar colunas/configurações em vez de removê-las; uma vez que o aplicativo antigo seja aposentado, execute uma limpeza.
- Pós-release: atualize / recompile pacotes, procedimentos, visualizações, etc. (especialmente no Oracle:
UTL_RECOMP). Atualize estatísticas após grandes alterações de dados (ANALYZE / RUNSTATS / statspack).
Exemplo de estrutura de script (PostgreSQL)
-- migration: R20261001_update_customer_schema
-- description: add email_verified column and index
-- author: dba_team
-- ticket: PROJ-1234
BEGIN;
SET lock_timeout = '5s';
ALTER TABLE customer
ADD COLUMN IF NOT EXISTS email_verified BOOLEAN NOT NULL DEFAULT false;
-- Wait for autovacuum / no long transactions before this
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_customer_email_verified
ON customer (email_verified);
-- Update existing verified emails
UPDATE customer SET email_verified = true
WHERE email IS NOT NULL AND email_verified = false
AND email_verified IS DISTINCT FROM true;
COMMIT;
(nota: CREATE INDEX CONCURRENTLY não pode ser executado dentro de uma transação no PG; coloque-o ou fora do BEGIN/COMMIT ou use uma transação separada. O exemplo é estilizado; o DBA precisa saber da limitação.)
9. Checklist de revisão
Use esta lista ao revisar um release de banco de dados ou mudança de esquema:
- Controle de versão: cada script tem ID de ticket único e é confirmado.
- Idempotente:
IF NOT EXISTS/OR REPLACE/ etc., mesmo que o script seja executado novamente. - Reversão: script rollback presente (se possível).
- Bloqueio: DDL não será executada enquanto transações longas estiverem abertas; timeout definido.
- Tempo de implantação: agendado fora do horário de pico; verifique a capacidade de janela de manutenção.
- Backups: backup completo do banco de dados/objeto feito antes (verificar
RESTORE VALIDATE? Sim). - Migração de dados: loteada, verificações de consistência de dados após.
- Índices: on-line/concorrente se disponível; verifique índices ausentes após novas colunas/consultas.
- Estatísticas:
ANALYZE/RUNSTATSexecutado após grandes DML. - Replicação: verifique lag; certifique-se de que DDL não quebra replicação (especialmente migração lógica vs. física).
- Segurança: sem dados fixos; use parâmetros ou variáveis de ambiente; privilégios mínimos; nenhum
GRANT ALL. - Monitoramento: alertas configurados para locks, tempo de execução, erros.
- Revisão por pares: pelo menos outro DBA ou engenheiro de dados revisou, especialmente para produção.
- Teste: o script foi executado em um ambiente de staging espelhando dados e carga de produção?
- Compatibilidade com versões anteriores: alterações de esquema não quebram consultas do aplicativo em execução (por exemplo, não remova colunas usadas pelo aplicativo antigo).
- Lista de alterações: registre qualquer mudança de configuração (por exemplo, feito
ALTER SYSTEMou alterado parâmetro de inicialização).