Saltar al contenido

Lección 12 de 25 · Lectura y práctica

Índices Concurrentes y su Mantenimiento

Concepto claveLos índices concurrentes en PostgreSQL son una funcionalidad avanzada que permite crear o eliminar índices sin bloquear las operaciones de escritura (INSERT, UPDATE, DELETE) en la tabla afectada. A diferencia de la.

Del concepto a la práctica

Taller de esta lección

CREATE INDEX CONCURRENTLY permite que la tabla siga aceptando escrituras durante la construcción, pero realiza más fases y no debe ejecutarse dentro de una transacción explícita. Si falla, puede quedar un índice inválido que ocupa recursos y no sirve para consultas hasta corregirlo. El mantenimiento incluye observar progreso, validar estado y retirar índices realmente innecesarios con cuidado.

Ejemplo resuelto

Para eventos(usuario_id, creado_en), se planifica en staging y luego se ejecuta:

sql
CREATE INDEX CONCURRENTLY eventos_usuario_fecha_idx
ON eventos (usuario_id, creado_en);

Se consulta el progreso y después se verifica indisvalid en los metadatos. Un índice inválido no se trata como terminado.

  1. Confirma espacio y ventana operativa.

  2. Ejecuta fuera de una transacción manual.

  3. Observa fases y duración.

  4. Valida estado y uso antes de documentarlo.

Error frecuente: lanzar muchos índices concurrentes simultáneamente. Corrección: secuéncialos para limitar I/O y bloqueos auxiliares.

Verifica en pg_index uniendo indexrelid con el nombre/oid esperado: indisvalid e indisready describen estados diferentes. CREATE INDEX CONCURRENTLY aún toma locks y espera transacciones/snapshots; no es una operación sin bloqueos. Un fallo puede dejar un índice inválido que participa en mantenimiento, y un unique inválido puede seguir imponiendo efectos. Inspecciona causa/estado y usa un runbook autorizado para retirar/recrear, nunca borres índices ajenos por este ejercicio.

Pruébalo

Simula una tabla pequeña, inicia la creación concurrente y registra si el índice termina válido.

Comprueba tu resultado

La evidencia debe incluir comando, estado final válido y ausencia de errores; no basta con que el comando haya sido aceptado.

Comparación de búsqueda por recorrido de filas y búsqueda mediante índice, seguida de medición del plan.
CursaloMapa de práctica
Medir antes de añadir un índice

Un índice puede ayudar a localizar las filas que necesita una consulta. Su utilidad depende del patrón de acceso y del coste de mantenerlo. Mide la consulta, revisa el plan y vuelve a medir después del cambio en lugar de suponer una mejora.

Ver la infografía en tamaño completo ↗

Concepto clave

Los índices concurrentes en PostgreSQL son una funcionalidad avanzada que permite crear o eliminar índices sin bloquear las operaciones de escritura (INSERT, UPDATE, DELETE) en la tabla afectada. A diferencia de la creación tradicional de índices, que requiere un bloqueo exclusivo, los índices concurrentes utilizan múltiples transacciones y un mecanismo de snapshot para construir el índice mientras la tabla sigue disponible para modificaciones.

Imagina que estás remodelando una biblioteca muy concurrida. En lugar de cerrar toda la biblioteca mientras reorganizas los catálogos (índices tradicionales), contratas a un equipo que trabaja en paralelo con los usuarios, actualizando los catálogos gradualmente sin interrumpir el préstamo de libros. Esto es similar a cómo PostgreSQL maneja los índices concurrentes: permite que las consultas de lectura y escritura continúen mientras se construye el índice en segundo plano, aunque con un costo adicional de recursos y tiempo.

Cómo funciona en la práctica

Cuando ejecutas un CREATE INDEX CONCURRENTLY, PostgreSQL realiza el proceso en varias fases para evitar bloqueos prolongados. Primero, inicia una transacción que toma un snapshot de la tabla y comienza a construir el índice. Luego, en una segunda transacción, sincroniza los cambios que ocurrieron durante la construcción inicial. Finalmente, valida que el índice sea consistente antes de hacerlo visible para las consultas.

Paso a paso: 1) PostgreSQL inicia la construcción del índice leyendo los datos de la tabla en el momento del snapshot. 2) Mientras tanto, las operaciones de escritura en la tabla se registran en un log de cambios. 3) Una vez completada la construcción inicial, PostgreSQL aplica los cambios del log al índice. 4) Se realiza una validación final para asegurar la consistencia. Si algo falla, el índice se marca como inválido y debe ser recreado.

Codigo en accion

Antes: Creación de un índice tradicional que bloquea la tabla.

-- Este comando bloqueará la tabla para escrituras hasta que termine
CREATE INDEX idx_user_email ON users(email);
-- Durante este tiempo, INSERT, UPDATE, DELETE en la tabla 'users' esperarán

Después: Creación de un índice concurrente que permite operaciones concurrentes.

-- Este comando permite operaciones de escritura durante la creación
CREATE INDEX CONCURRENTLY idx_user_email_concurrent ON users(email);
-- Las escrituras en 'users' pueden continuar, pero el índice tarda más en construirse

-- Verificar el estado del índice después de la creación
SELECT schemaname, tablename, indexname, indisvalid FROM pg_indexes 
WHERE indexname = 'idx_user_email_concurrent';
-- Si indisvalid es false, el índice falló y debe recrearse

Errores comunes

  • Usar CONCURRENTLY en transacciones explícitas: CREATE INDEX CONCURRENTLY no puede ejecutarse dentro de un bloque BEGIN/COMMIT. Esto causa error. Siempre ejecútalo fuera de transacciones.
  • Ignorar el estado del índice: No verificar si el índice quedó válido (indisvalid) después de la creación. Un índice inválido no se usará en consultas, degradando el rendimiento.
  • Crear múltiples índices concurrentes simultáneamente: Lanzar varios CREATE INDEX CONCURRENTLY al mismo tiempo puede saturar los recursos de I/O y CPU, ralentizando todo el sistema. Espacia estas operaciones.
  • Usar en tablas muy pequeñas: Para tablas con pocas filas, el overhead de la creación concurrente no justifica el beneficio. En estos casos, usa el método tradicional.
  • Olvidar el mantenimiento: Los índices concurrentes también requieren REINDEX CONCURRENTLY para reconstruirlos sin bloqueos. No uses REINDEX tradicional, ya que bloqueará la tabla.

Checklist de dominio

  1. Comprendo la diferencia entre CREATE INDEX y CREATE INDEX CONCURRENTLY en términos de bloqueo y tiempo de ejecución.
  2. Sé verificar el estado de un índice concurrente usando pg_indexes y la columna indisvalid.
  3. Puedo explicar cuándo es apropiado usar índices concurrentes (ej. en tablas de alta concurrencia) y cuándo no (tablas pequeñas o mantenimiento urgente).
  4. Conozco el comando REINDEX CONCURRENTLY para reconstruir índices sin interrumpir operaciones.
  5. Soy capaz de planificar la creación de índices concurrentes en horarios de baja carga para minimizar impacto.
  6. Entiendo que los índices concurrentes pueden fallar y cómo manejar esos fallos (recreación o monitoreo).
  7. Puedo identificar en un plan de ejecución si se está utilizando un índice creado concurrentemente.

Implementación y Monitoreo de un Índice Concurrente

En este ejercicio, implementarás y monitorearás un índice concurrente en una base de datos PostgreSQL de alta concurrencia. Sigue estos pasos:

  1. Conéctate a tu base de datos PostgreSQL (versión 12 o superior) que tenga una tabla con al menos 10,000 filas y alta actividad de escritura. Si no tienes una, crea una tabla de prueba con:
    CREATE TABLE ventas (id SERIAL PRIMARY KEY, producto VARCHAR(100), cantidad INT, fecha TIMESTAMP);
    INSERT INTO ventas (producto, cantidad, fecha) SELECT 'Producto' || n, (random()*100)::int, NOW() - (n || ' days')::INTERVAL FROM generate_series(1,10000) n;
  2. Crea un índice concurrente en la columna 'producto' de la tabla 'ventas'. Usa el comando apropiado y asegúrate de no ejecutarlo dentro de una transacción.
  3. Mientras se crea el índice, simula concurrencia ejecutando en otra sesión algunas operaciones de escritura, como:
    INSERT INTO ventas (producto, cantidad, fecha) VALUES ('NuevoProducto', 50, NOW());
    Observa que estas operaciones no deberían bloquearse.
  4. Verifica el estado del índice después de su creación. Consulta la vista pg_indexes para confirmar que el índice es válido (indisvalid = true).
  5. Si el índice es válido, ejecuta una consulta que lo utilice, por ejemplo:
    EXPLAIN ANALYZE SELECT * FROM ventas WHERE producto = 'Producto5000';
    Revisa el plan de ejecución para asegurarte de que se usa el índice.
  6. Documenta el tiempo que tomó la creación del índice y cualquier observación sobre el rendimiento durante el proceso.
Pistas
  • Asegúrate de usar la opción CONCURRENTLY en el comando CREATE INDEX.
  • Puedes monitorear el progreso del índice consultando la vista pg_stat_progress_create_index.
  • Si el índice falla, revisa los logs de PostgreSQL para errores y recrea el índice.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con PostgreSQL Avanzado: Optimización para Aplicaciones de Alta Concurrencia

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.