Referencia de DBA
Reglas de uso: los comandos siguientes son las formas estables y bien conocidas. El comportamiento difiere entre versiones y ediciones (¡licencias!) - cuando una línea diga "verifica contra tu versión", consulta la documentación del proveedor para la versión exacta antes de confiar en ella. Nunca ejecutes sentencias de diagnóstico que modifiquen datos en producción sin un registro de cambios.
1. Comparación rápida de motores
| Tema | Oracle | PostgreSQL | SQL Server | Db2 LUW | MySQL / MariaDB (InnoDB) |
|---|---|---|---|---|---|
| Modelo de concurrencia | MVCC (undo); los lectores nunca bloquean a los escritores | MVCC (versiones de filas en la tabla; VACUUM) | Bloqueo por defecto; MVCC si RCSI/snapshot está habilitado | Bloqueo; lecturas "currently committed" (CUR_COMMIT) | MVCC (undo) + bloqueos de gap/next-key en REPEATABLE READ (predeterminado) |
| DDL transaccional | No (commit implícito antes/después) | Sí (excepto, p. ej., CREATE INDEX CONCURRENTLY, CREATE DATABASE, VACUUM) | Sí para la mayoría de DDL | Sí para la mayoría de DDL (verifica por sentencia) | No (commit implícito; el DDL de MySQL 8 es atómico solo por sentencia) |
| Escalación de bloqueos | Nunca | Nunca | Sí (fila/página -> tabla, ~5000 bloqueos por objeto por sentencia) | Sí (LOCKLIST/MAXLOCKS) | No (pero hay bloqueos de gap) |
| Estadísticas de consultas | AWR/ASH (Diagnostics Pack), Statspack | pg_stat_statements | Query Store, DMVs | Funciones de tabla MON_GET_* | performance_schema, esquema sys, slow log |
| Timeout de bloqueo de sesión | 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; (bloqueos de metadatos) + innodb_lock_wait_timeout (bloqueos de filas) |
2. Diagnóstico de rendimiento
Método: (1) define el síntoma (una consulta, una ventana de tiempo, toda la instancia); (2) mira las esperas/modelo de tiempo antes de ajustar SQL; (3) obtén el plan real (no solo el estimado); (4) compara filas estimadas vs reales - las estimaciones incorrectas de cardinalidad suelen ser la causa raíz (estadísticas desactualizadas, sesgo, predicados correlacionados, parameter sniffing/bind peeking); (5) cambia una cosa, mide.
Oracle
- Plan estimado:
EXPLAIN PLAN FOR <stmt>;luegoSELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); - Plan real: ejecuta con
/*+ GATHER_PLAN_STATISTICS */luegoSELECT * 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_*) requieren el Diagnostics Pack (Enterprise Edition); SQL Monitor y SQL Tuning Advisor requieren el Tuning Pack. VerificaCONTROL_MANAGEMENT_PACK_ACCESS. Sin licencia: Statspack. - Esperas en vivo:
V$SESSION(event,wait_class,sql_id,blocking_session),V$SYSTEM_EVENT,V$SQL/V$SQLSTATS. - Esperas comunes:
db file sequential read(un solo bloque, acceso a índice),db file scattered read/direct path read(escaneos completos),log file sync(frecuencia de commits / I/O de redo),enq: TX - row lock contention(bloqueo de aplicación),enq: TM - contention(a menudo claves foráneas sin índice),latch: cache buffers chains(bloques calientes),gc *(interconexión RAC). - Estabilidad del plan: SQL Plan Management (baselines); los perfiles SQL necesitan el Tuning Pack.
PostgreSQL
EXPLAIN (ANALYZE, BUFFERS) <stmt>;- ANALYZE ejecuta la sentencia: envuelve DML enBEGIN; ... ROLLBACK;.pg_stat_statements(necesitashared_preload_libraries): SQL principales portotal_exec_time(los nombres de columna cambiaron en 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;- En vivo:
pg_stat_activity(state,wait_event_type,wait_event,xact_start,query); las sesionesidle in transactionmantienen bloqueos y bloquean VACUUM. - Módulo
auto_explainpara planes lentos en logs;track_io_timing = onpara tiempos de I/O. - Salud:
pg_stat_user_tables(seq_scan,n_dead_tup,last_autovacuum,last_autoanalyze); hinchazón; envoltura del ID de transacción:SELECT datname, age(datfrozenxid) FROM pg_database;. - Matar:
pg_cancel_backend(pid)(consulta) luegopg_terminate_backend(pid)(sesión).
SQL Server
- Plan real: SSMS "Include Actual Execution Plan" o
SET STATISTICS XML ON;;SET STATISTICS IO, TIME ON;para lecturas/CPU. - Query Store (2016+; ACTIVADO por defecto para nuevas bases de datos en 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+); regresiones -> forzado de planEXEC 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 comunes:
PAGEIOLATCH_*(lecturas de datos),LCK_M_*(bloqueo),WRITELOG(I/O de log / tasa de commits),CXPACKET/CXCONSUMER(paralelismo - verifica MAXDOP/cost threshold),SOS_SCHEDULER_YIELD(CPU),ASYNC_NETWORK_IO(cliente no consume resultados),RESOURCE_SEMAPHORE(asignaciones de memoria). - Parameter sniffing: compara planes por parámetro; opciones
OPTION (RECOMPILE),OPTIMIZE FOR, Query Store hints (2022) - elige por caso. - Extended Events; la sesión
system_healthmantiene gráficos de deadlock recientes.
Db2 LUW
- Explain: crea tablas de explain (
SYSPROC.SYSINSTALLOBJECTSoEXPLAIN.DDL),EXPLAIN PLAN FOR <stmt>, formatea condb2exfmt -d <DB> -1 -o plan.txt; vista rápidadb2expln. - Funciones de tabla de monitoreo:
MON_GET_PKG_CACHE_STMT(SQL principales:STMT_EXEC_TIME,NUM_EXECUTIONS,ROWS_READ),MON_GET_CONNECTION,MON_GET_ACTIVITY,MON_GET_TABLE,MON_GET_BUFFERPOOL. - Bloqueos:
SYSIBMADM.MON_LOCKWAITS,db2pd -db <DB> -wlocks,db2pd -db <DB> -locks. - Estadísticas:
RUNSTATS ON TABLE <SCHEMA>.<TABLE> WITH DISTRIBUTION AND DETAILED INDEXES ALL;-REORGCHKpara evaluar necesidades de reorg;db2advispara consejos de índices.
MySQL / MariaDB
EXPLAIN <stmt>; real: MySQL 8.0.18+EXPLAIN ANALYZE <stmt>; MariaDBANALYZE <stmt>(ambos ejecutan la sentencia).- SQL principales:
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, longitud del historial de la lista),information_schema.INNODB_TRX,sys.innodb_lock_waits; MySQL 8:performance_schema.data_locks/data_lock_waits; MariaDB:information_schema.INNODB_LOCKS/INNODB_LOCK_WAITSy el pluginMETADATA_LOCK_INFO; bloqueos de metadatos de MySQL:performance_schema.metadata_locks.
3. Bloqueo y concurrencia - trampas
| Motor | Trampa | Mitigación |
|---|---|---|
| Todos | Transacción larga + DDL: el DDL espera, y cada consulta posterior se encola detrás de él | Timeout de bloqueo corto en DDL, bucle de reintento, ejecutar cuando no haya transacciones largas; verificar antes (sesiones activas) |
| Oracle | Claves foráneas sin índice -> bloqueos TM en el hijo cuando se eliminan filas padre/se actualiza PK | Indexar columnas FK |
| Oracle | DDL falla ORA-00054 en objeto ocupado | DDL_LOCK_TIMEOUT; variantes online (CREATE INDEX ... ONLINE, ALTER TABLE ... MOVE ONLINE 12.2+, DBMS_REDEFINITION) - todas solo Enterprise Edition (no en SE2) |
| Oracle | Commit dentro de un bucle sobre un cursor abierto -> ORA-01555 snapshot too old | Fragmentar por rangos de clave/rowid (DBMS_PARALLEL_EXECUTE), dimensionar la retención de undo |
| PostgreSQL | La mayoría de ALTER TABLE toman ACCESS EXCLUSIVE; esperarlo bloquea a todos los lectores | SET lock_timeout; CREATE INDEX CONCURRENTLY; FK/CHECK NOT VALID luego VALIDATE CONSTRAINT |
| PostgreSQL | El cambio de tipo de columna reescribe la tabla (excepto casos seguros como aumentar la longitud de varchar) | Expandir/contraer con nueva columna + backfill |
| PostgreSQL | Sesiones idle in transaction | idle_in_transaction_session_timeout, arreglar la aplicación |
| SQL Server | Los lectores bloquean a los escritores bajo READ COMMITTED predeterminado | Evaluar READ_COMMITTED_SNAPSHOT ON (impacto en el almacén de versiones de tempdb; probar) |
| SQL Server | Escalación de bloqueo a tabla en DML grande | Lotes por debajo de ~5000 filas; ALTER TABLE ... SET (LOCK_ESCALATION = ...) con cuidado |
| SQL Server | NOLOCK usado como "solución" | Lecturas sucias, filas faltantes/duplicadas - rechazar en revisiones |
| Db2 | LOCKTIMEOUT = -1 (esperar para siempre) predeterminado | Establecer CURRENT LOCK TIMEOUT en sesiones de release |
| Db2 | ALTER TABLE ... DROP COLUMN, la mayoría de ALTER COLUMN SET DATA TYPE, SET NOT NULL/DROP NOT NULL ponen una tabla organizada por filas en estado reorg-pending (SQLSTATE 57007): hasta REORG TABLE solo se permiten escaneos, DROP/RENAME/TRUNCATE y la mayoría de otros ALTERs; un máximo de 31 unidades de trabajo de tales operaciones antes de que REORG sea obligatorio | Planificar REORG TABLE en la ventana; verificar REORG_PENDING / NUM_REORG_REC_ALTERS en SYSIBMADM.ADMINTABINFO |
| MySQL | Esperas de bloqueo de metadatos (MDL): DDL bloqueado por una transacción abierta y luego bloquea a todos | lock_wait_timeout bajo en la sesión de release; matar transacciones largas inactivas |
| MySQL | El DDL online retrocede silenciosamente a copia de tabla | Siempre especificar ALGORITHM=INSTANT (o INPLACE) con LOCK=NONE para que dé error; o gh-ost / pt-online-schema-change |
| MySQL | Bloqueos de gap/next-key en actualizaciones de rango bajo REPEATABLE READ | Indexar el predicado; considerar READ COMMITTED donde sea aceptable |
Deadlocks: siempre un problema de diseño (orden de acceso inconsistente, índices faltantes). Capturar: archivo de trace de Oracle / alert log (ORA-00060), log de PostgreSQL (log_lock_waits = on para esperas > deadlock_timeout), SQL Server system_health XE, monitor de eventos de Db2 para bloqueos, MySQL innodb_print_all_deadlocks.
4. HA / DR
| Motor | HA local | DR / réplicas | Operaciones y verificaciones clave |
|---|---|---|---|
| Oracle | RAC (almacenamiento compartido, activo-activo, licencia adicional) | Data Guard standby físico (aplicación de redo); Active Data Guard = abierto solo lectura con aplicación (licencia adicional) | Modos de protección: Maximum Performance (ASYNC, predeterminado), Maximum Availability (SYNC, retrocede), Maximum Protection (SYNC, primario se detiene si no hay standby). Broker dgmgrl: SHOW CONFIGURATION;, VALIDATE DATABASE <stby>;, SWITCHOVER TO <stby>;, FAILOVER TO <stby>;. Lag: V$DATAGUARD_STATS. Primario en FORCE LOGGING. Fast-Start Failover necesita un observer (idealmente en un tercer sitio). |
| PostgreSQL | Patroni (DCS: etcd/Consul/ZooKeeper) + HAProxy/VIP | Replicación de streaming (física, WAL); replicación lógica (publicaciones/suscripciones, PG10+) | pg_stat_replication (sent_lsn, write_lsn, flush_lsn, replay_lsn), pg_is_in_recovery(), pg_promote() (PG12+). Sincronía: synchronous_standby_names + synchronous_commit. Los slots de replicación retienen WAL si una réplica está caída -> disco lleno: monitorear, limitar con max_slot_wal_keep_size (PG13+). Patroni: patronictl -c <cfg> list / switchover / failover; endpoints REST de salud (/primary, /replica) para el balanceador de carga. La replicación lógica no replica ni DDL ni valores de secuencia (a partir de PG 18): aplicar cambios de esquema aditivos en el suscriptor primero y reiniciar secuencias antes de fallover a un suscriptor. |
| SQL Server | Failover Cluster Instance (almacenamiento compartido, WSFC) | Always On Availability Groups (WSFC, o Pacemaker en Linux); log shipping | Failover automático solo entre réplicas síncronas. Listener para clientes (MultiSubnetFailover=True). Logins, trabajos del Agente, servidores vinculados, credenciales NO se replican (AG contenida, SQL Server 2022 Enterprise, ayuda). AG completos necesitan Enterprise; Basic AG en Standard Edition (1 DB, 2 réplicas). Verificar sys.dm_hadr_database_replica_states. Failover planificado: ALTER AVAILABILITY GROUP [<AG>] FAILOVER; en el secundario síncrono objetivo. Los secundarios legibles tienen impacto en licencias. |
| Db2 LUW | pureScale (activo-activo) o HADR + automatización Pacemaker/TSA | HADR (hasta 3 standbys, HADR_TARGET_LIST) | HADR_SYNCMODE: SYNC, NEARSYNC, ASYNC, SUPERASYNC. Monitorear db2pd -db <DB> -hadr o MON_GET_HADR. Cambio de rol en standby: TAKEOVER HADR ON DATABASE <DB> (BY FORCE para failover). Lecturas en standby a través de DB2_HADR_ROS (limitaciones). |
| MySQL / MariaDB | InnoDB Cluster (Group Replication + MySQL Router); Galera (MariaDB) | Replicación asíncrona / semisíncrona, basada en GTID | SHOW REPLICA STATUS (MySQL 8.0.22+; MariaDB 10.5.1+ acepta REPLICA como sinónimo de SLAVE; versiones anteriores: SHOW SLAVE STATUS). Vigilar el lag de replicación y los GTID errantes; Galera necesita un quorum de componente primario (3 nodos o árbitro). |
Reglas de diseño: definir RPO/RTO por aplicación antes de elegir síncrono/asíncrono; prueba de DR al menos anualmente con resultados documentados (DORA requiere pruebas de continuidad de TIC para entidades financieras); los clientes deben reconectarse de forma transparente (cadenas de conexión con múltiples hosts/listener/SCAN, lógica de reintento); monitorear el lag y alertar; protección contra split-brain (quórum, fencing, observer/witness en un tercer sitio).
5. Backup, restauración, PITR
| Motor | Completo / incremental | PITR | Validar |
|---|---|---|---|
| Oracle (RMAN) | BACKUP DATABASE PLUS ARCHIVELOG; incremental nivel 0/1; CONFIGURE CONTROLFILE AUTOBACKUP ON; CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 14 DAYS; | Modo ARCHIVELOG requerido. RUN { SET UNTIL TIME "TO_DATE('2026-10-01 12:00','YYYY-MM-DD HH24:MI')"; RESTORE DATABASE; RECOVER DATABASE; } luego 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 es solo lógico (sin PITR) | Archivado de WAL (archive_mode, archive_command); restaurar 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; prueba de restauración real periódica |
| SQL Server | Modelo de recuperación FULL; BACKUP DATABASE [<db>] TO DISK = N'<path>' WITH CHECKSUM, COMPRESSION; diferencial; BACKUP LOG | Restaurar completo WITH NORECOVERY, diferencial WITH NORECOVERY, luego logs hasta el momento deseado WITH RECOVERY o STOPAT; RESTORE LOG [<db>] FROM DISK = N'<path>' WITH STOPAT = '2026-10-01 12:00'; | RESTORE VERIFYONLY FROM DISK = N'<path>' WITH CHECKSUM;; pruebas regulares de restauración |
| Db2 LUW | BACKUP DATABASE <db> TO <path> WITH 2 BUFFERS BUFFER 1024 PARALLELISM 4 COMPRESS EXCLUDE LOGS WITHOUT PROMPTING; incremental INCREMENTAL DELTA (necesita rastreadores de cambios) | Restaurar base + rollforward TO 2026-10-01-12.00.00.000000 (USING LOCAL TIME si es necesario) hasta AND STOP; db2ckbkp para verificar imagen | db2ckbkp -h <backup_file>; pruebas regulares de restauración y rollforward |
| MySQL / MariaDB | mysqldump lógico --single-transaction --routines --triggers --events --set-gtid-purged=OFF + --master-data=2 (MySQL) o --gtid (MariaDB); XtraBackup/MariaDB Backup físico --backup | Requiere logs binarios (activar en my.cnf: log_bin/log-bin, server_id). mysqlbinlog con --start-datetime/--stop-datetime o --start-position/--stop-position. XtraBackup/MariaDB Backup: --apply-log luego --copy-back o --move-back; PITR con logs binarios | mysqlcheck, CHECKSUM TABLE; pruebas periódicas de restauración |
Reglas generales de backup
- Cifrado: las copias de seguridad deben estar cifradas en reposo (RMAN
ENCRYPTION, pgBackRest--compress-type=zst --compress-level=6, SQL Server TDE/backup encryption, Db2ENCRYPT, XtraBackup/MariaDB Backup--encrypt). - Automatización: programación con verificación de éxito/fallo. Monitorear y alertar.
- Retención: cumplir con los requisitos legales (GDPR, SOX, etc.). Probar puntos de restauración.
- 3-2-1: al menos 3 copias, 2 medios diferentes, 1 fuera del sitio (nube u otro centro de datos).