Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /

Creación de índices en colecciones pobladas

Las construcciones de índices utilizan un proceso de construcción optimizado que mantiene un bloqueo exclusivo en la colección al inicio y al final de la creación de índices. El resto del proceso de compilación da lugar a operaciones intercaladas de lectura y escritura. Para una descripción detallada del proceso de creación de índices y el comportamiento de bloqueo, consulte Proceso de creación de índices.

El índice se construye en un conjunto de réplicas o en un clúster fragmentado, y se construye simultáneamente en todos los miembros del conjunto de réplicas que contienen datos. El nodo primario requiere un número mínimo de miembros votantes que contienen datos (es decir, un quórum de confirmación), incluido él mismo, que deben completar la construcción antes de marcar el índice como listo para su uso. Un miembro "votante" es cualquier miembro del conjunto de réplicas donde members[n].votes es mayor que 0. Consulte creación de índices en entornos replicados para obtener más información.

Nota

Para obtener información sobre cómo crear índices en Atlas, consulta la página de gestión de índices en la documentación de Atlas.

Las versiones anteriores de MongoDB permitían crear índices tanto en primer plano como en segundo plano. La creación de índices en primer plano era rápida y generaba estructuras de datos más eficientes, pero requería bloquear todo el acceso de lectura y escritura a la base de datos principal de la colección que se estaba indexando durante el proceso. La creación de índices en segundo plano era más lenta y producía resultados menos eficientes, pero permitía el acceso de lectura y escritura a la base de datos y sus colecciones durante el proceso.

Ahora, la creación de índices obtiene un bloqueo exclusivo sobre la colección que se está indexando únicamente al inicio y al final del proceso. El resto del proceso utiliza el comportamiento de cesión de permisos propio de las creaciones de índices en segundo plano para maximizar el acceso de lectura y escritura a la colección durante la creación. A pesar de este comportamiento de bloqueo más permisivo, las creaciones de índices siguen generando estructuras de datos de índice eficientes.

El rendimiento de la creación de índices optimizada está al menos a la par con las creaciones de índices en segundo plano. Para las cargas de trabajo con pocas o ninguna actualizaciones recibidas durante el proceso de compilación, las creaciones de índices optimizadas pueden ser tan rápidas como una creación de índices en primer plano con esos mismos datos.

Utiliza db.currentOp() para supervisar el progreso de la creación de índices en curso.

MongoDB ignora la opción de creación de índices background si se especifica para createIndexes o sus asistentes de shell createIndex() y createIndexes().

Para los índices que aplican restricciones a la colección, como los índices únicos, el mongod verifica todos los documentos preexistentes y escritos simultáneamente en busca de violaciones de esas restricciones después de que se completa la creación de índices. Los documentos que violan las restricciones del índice pueden existir durante la creación de índices. Si algún documento viola las restricciones del índice al final de la compilación, el mongod termina la compilación y lanza un error.

Por ejemplo, considera una colección inventory que ya está poblada. Un administrador desea crear un índice único en el campo product_sku. Si algún documento de la colección tiene valores duplicados para product_sku, la creación de índices aún puede iniciarse con éxito. Si aún existen violaciones al final de la compilación, el mongod termina la compilación y arroja un error.

De manera similar, una aplicación puede escribir documentos con éxito en la colección inventory con valores duplicados de product_sku mientras se está construyendo el índice.

Para mitigar el riesgo de fallo en la creación de índices debido a violaciones de restricciones:

  • Valide que ningún documento de la colección viole las restricciones del índice.

  • Detén todos los guardados en la colección de aplicaciones que no puedan garantizar operaciones de guardado sin violaciones.

En una colección fragmentada distribuida en varios fragmentos, uno o más fragmentos pueden contener un bloque con documentos duplicados. Por lo tanto, la operación de creación de índice puede tener éxito en algunos fragmentos (los que no contienen duplicados), pero no en otros (los que sí los contienen). Para evitar índices inconsistentes entre los fragmentos, puede usar el db.collection.dropIndex() comando desde un para eliminar el índice de la colección.mongos

Para mitigar el riesgo de que esto ocurra, antes de crear el índice:

  • Valide que ningún documento de la colección viole las restricciones del índice.

  • Detén todos los guardados en la colección de aplicaciones que no puedan garantizar operaciones de guardado sin violaciones.

Tip

Por defecto, el servidor permite hasta tres creaciones de índices simultáneas. Para cambiar el número de creaciones de índices concurrentes permitidas, modifica el parámetro maxNumActiveUserIndexBuilds.

Si el número de creación de índices concurrentes alcanza el límite especificado por maxNumActiveUserIndexBuilds, el servidor bloquea la creación de índices adicionales hasta que el número de creación de índices concurrentes baje por debajo del límite.

La creación de índices cuando la colección de destino está sometida a una gran carga de escritura puede resultar en una reducción del rendimiento de escritura y en tiempos de creación de índices más prolongados.

Considere la posibilidad de establecer un período de mantenimiento durante el cual las aplicaciones detengan o reduzcan las operaciones de escritura en la colección. Inicie la creación del índice durante este período de mantenimiento.

createIndexes brinda soporte a la creación de uno o más índices en una colección. createIndexes utiliza una combinación de memoria y archivos temporales en disco para crear índices. El límite de memoria por defecto es de 200 megabytes por comando createIndexes, compartido equitativamente entre toda la creación de índices en ese comando. Por ejemplo, si se crean 10 índices con un comando createIndexes, MongoDB asigna a cada índice 20 megabytes para el proceso de creación de índices cuando se utiliza el límite de memoria por defecto de 200. Cuando se alcanza el límite de memoria, MongoDB crea archivos temporales en el subdirectorio _tmp dentro de --dbpath para completar la compilación.

Ajuste el límite de memoria con el parámetro maxIndexBuildMemoryUsageMegabytes. Aumentar este parámetro solo es necesario en casos raros, como cuando ejecutas muchas construcciones de índices simultáneas con un solo comando createIndexes o cuando indexas un conjunto de datos mayor que 500GB.

Cada createIndexes comando tiene un límite de maxIndexBuildMemoryUsageMegabytes. Al utilizar el valor maxNumActiveUserIndexBuilds por defecto de 3, el uso total de memoria para todas las creaciones de índices simultáneas puede alcanzar hasta 3 veces el valor de maxIndexBuildMemoryUsageMegabytes.

Si el host dispone de RAM libre limitada, puede que necesite incluir en el cronograma un periodo de mantenimiento para aumentar la RAM total del sistema para poder modificar el uso de RAM de mongod.

Nota

Requiere featureCompatibilityVersion 4.4+

Cada mongod en el set de réplicas o clúster debe tener featureCompatibilityVersion configurada al menos en 4.4 para iniciar la creación de índices simultáneamente en los miembros del set de réplicas.

La creación de índices en un Set de réplicas o en un clúster se realiza simultáneamente en todos los miembros del Set de réplicas que contienen datos. Para clústeres particionados, la creación de índices ocurre solo en las particiones que contienen datos para la colección que se está indexando. El primario requiere un número mínimo de miembros portadores de datos voting (es decir, quórum de confirmación), incluido él mismo, que deben completar la compilación antes de marcar el índice como listo para su uso.

El proceso de compilación se resume de la siguiente manera:

  1. El primario recibe el comando createIndexes e inmediatamente crea una entrada de oplog "startIndexBuild" asociada con la creación de índices.

  2. Los secundarios inician la creación de índices después de replicar la entrada de oplog "startIndexBuild".

  3. Cada nodo "vota" para confirmar la compilación una vez que termina de indexar los datos en la colección.

  4. Los miembros secundarios continúan procesando cualquier nueva operación de guardar en el índice mientras esperan que el primario confirme un quórum de votos.

  5. Cuando el Primario tiene un quórum de votos, verifica si hay alguna violación de las restricciones de clave, como errores de clave duplicada.

    • Si no hay violaciones de restricciones clave, el primario completa la creación de índices, marca el índice como listo para usar y crea una entrada de oplog asociada llamada "commitIndexBuild".

    • Si hay alguna violación de restricciones clave, la creación de índices falla. El Primario aborta la creación de índices y crea una entrada de oplog "abortIndexBuild" asociada.

  6. Los secundarios replican la entrada de oplog "commitIndexBuild" y completan la creación de índices.

    Si los secundarios replican en su lugar una entrada de oplog "abortIndexBuild", abortan la creación de índices y descartan la tarea de compilación.

Para clústeres particionados, la creación de índices ocurre solo en las particiones que contienen datos para la colección que se está indexando.

Para ver una descripción más detallada del proceso de creación de índices, ve Creación de Índices.

Por defecto, la creación de índices utiliza un quórum de confirmación de "votingMembers", o todos los miembros votantes que contienen datos. Para iniciar la creación de índices con un quórum de confirmación no predeterminado, especifica el parámetro commitQuorum para createIndexes o sus asistentes de shell db.collection.createIndex() y db.collection.createIndexes().

Para modificar el quórum de confirmación necesario para una creación de índices simultánea en curso, utilice el comando setIndexCommitQuorum.

Advertencia

Evita realizar procesos de creación de índices en modo continuo y replicado al mismo tiempo, ya que podría generar problemas inesperados, como compilaciones fallidas y bucles de fallos.

Nota

La creación de índices rotativos procesa como máximo un miembro del conjunto de réplicas a la vez, comenzando por los miembros secundarios, y crea el índice en ese miembro de forma independiente. Este método requiere al menos una elección de conjunto de réplicas. Utilice la creación de índices rotativos únicamente si cumple con los requisitos que se indican en las páginas correspondientes, ya que este procedimiento reduce la resiliencia del clúster.

Existen diferencias importantes entre quórums de confirmación y niveles de confirmación de escritura:

  • Las compilaciones de índices utilizan quórums de confirmación.

  • Las operaciones de escritura usan nivel de confirmación de escritura (write concern).

Cada nodo que lleva datos en un clúster es un miembro votante.

El quórum de confirmación especifica cuántos miembros votantes con datos, o qué miembros votantes, incluidos los primarios, deben estar preparados para comprometer una creación de índices simultánea antes de que el primario ejecute el compromiso.

El nivel de confirmación de escritura (write concern) es el nivel de confirmación que la operación de escritura ha alcanzado en el número especificado de instancias.

El quórum de confirmación especifica cuántos nodos deben estar listos para finalizar la creación de índices antes de que el primario confirme la creación de índices. Por el contrario, cuando el primario ha realizado la creación de índices, el nivel de confirmación de escritura (write concern) especifica cuántos nodos deben finalizar la creación de índices antes de que el comando devuelva una respuesta.

Si un nodo primario o secundario mongod realiza una limpieza shutdown con "force" : true o recibe una SIGTERM señal durante la compilación del índice y el commitQuorum está configurado en el valor votingMembers predeterminado, el progreso de la compilación del índice se guarda en el disco. El mongod nodo recupera automáticamente la compilación del índice al reiniciarse y continúa desde el punto de control guardado. En versiones anteriores, la compilación del índice debe reiniciarse desde el principio.

El mongod puede realizar el proceso de inicio mientras se recuperan las compilaciones de índices.

Si reinicia mongod como independiente (es decir,replication.replSetName eliminando o comentando u --replSetName omitiendo),mongod no puede reiniciar la compilación del índice. La compilación permanece en estado de pausa hasta que se dropped manualmente.

Si el mongod se apaga durante la creación de índices, se pierde la tarea de creación de índices y todo el progreso. El reinicio del mongod no reinicia la creación de índices. Debes volver a emitir la operación createIndex() para reiniciar la creación de índices.

A partir de MongoDB 5.0, si un nodo se revierte a un estado anterior durante la creación de índices, el progreso de la creación de índices se guarda en el disco. Si aún queda trabajo por hacer cuando concluye el rollback, el mongod recupera automáticamente la creación de índices y continúa desde el punto de control guardado.

MongoDB puede pausar una creación de índices en curso para realizar un rollback.

  • Si el rollback no revierte la creación de índices, MongoDB reinicia la creación de índices después de completar el rollback.

  • Si el rollback revierte la creación de índices, debes volver a crear el índice o los índices después de que se complete el rollback.

Una colección fragmentada tiene un índice inconsistente si no tiene exactamente los mismos índices (incluidas las opciones de índice) en cada fragmento que contiene partes de la colección. Si bien los índices inconsistentes no deberían ocurrir durante las operaciones normales, pueden ocurrir en los siguientes escenarios:

  • Al crear un índice con una restricción de clave unique, si una partición contiene un fragmento con documentos duplicados, la operación de creación del índice puede tener éxito en las particiones sin duplicados, pero no en la partición con duplicados.

  • Al crear un índice en todos los fragmentos de forma secuencial (es decir, construyendo manualmente el índice uno por uno en todos los fragmentos), o bien no logra construir el índice para un fragmento asociado, o bien construye incorrectamente un índice con una especificación diferente.

El servidor de configuración primario comprueba periódicamente las inconsistencias de índice en los particiones de las colecciones particionadas. Para configurar estas comprobaciones periódicas, consulta enableShardedIndexConsistencyCheck y shardedIndexConsistencyCheckIntervalMS.

El comando serverStatus devuelve el campo shardedIndexConsistency para informar sobre inconsistencias en los índices cuando se ejecuta en el servidor de configuración primario.

Para verificar si una colección fragmentada tiene índices inconsistentes, consulta Buscar índices inconsistentes entre particiones.

Para ver el estado de una operación de creación de índice, puedes utilizar el método db.currentOp() en mongosh. Para filtrar las operaciones actuales de creación de índices, consulta Operaciones de indexación activas para ver un ejemplo.

El campo msg incluye una medición del porcentaje de finalización de la etapa actual en el proceso de creación de índices.

Mientras se construye un índice, el progreso se escribe en el registro de MongoDB. Si se detiene y se reanuda la creación de índices, aparecerán mensajes de registro con campos como estos:

"msg":"Index build: wrote resumable state to disk",
"msg":"Found index from unfinished build",

Utiliza el comando dropIndexes o sus asistentes de shell dropIndex() o dropIndexes() para terminar una creación de índices en progreso. Consulta Detener la creación de índices en curso para obtener más información.

No utilices killOp para terminar una creación de índices en progreso en Sets de réplicas o clústeres particionados.

La siguiente tabla describe cada etapa del proceso de compilación de índices:

Etapa
Descripción

Bloqueo

El mongod obtiene un bloqueo exclusivo de X en la colección que se está indexando. Esto bloquea todas las operaciones de lectura y guardado en la colección, incluida la aplicación de cualquier operación de guardado replicada o comandos de metadatos que tengan como objetivo la colección. El mongod no libera este bloqueo.

Inicialización

El mongod crea tres estructuras de datos en este estado inicial:

  • La entrada inicial de metadatos del índice.

  • Una tabla temporal ("tabla de escrituras laterales") que almacena las claves generadas a partir de los guardados en la colección que se está indexando durante el proceso de construcción.

  • Una tabla temporal ("tabla de violación de restricciones") para todos los documentos que pueden causar un error de generación de claves. Los errores de generación de claves ocurren cuando un documento tiene claves no válidas para los campos indexados. Por ejemplo, un documento con valores de campo duplicados al construir un índice único o objetos GeoJSON malformados al construir un índice 2dsphere.

Bloqueo

El mongod degrada el bloqueo exclusivo de la colección X a un bloqueo de intención exclusiva IX. El mongod cede periódicamente este bloqueo para intercalar operaciones de lectura y escritura.

Escanear colección

Para cada documento de la colección, el mongod genera una clave para ese documento y la deposita en un clasificador externo.

Si el mongod encuentra un error al generar una clave durante el escaneo de colección, almacena esa clave en la tabla de violaciones de restricciones para su procesamiento posterior.

Si el mongod encuentra cualquier otro error al generar una clave, la creación falla con un error.

Una vez que el mongod completa el escaneo de colección, vacía las claves ordenadas en el índice.

Tabla de guardados del lado del proceso

El mongod vacía la tabla de escritura lateral utilizando la prioridad de primero en entrar, primero en salir.

Si el mongod encuentra un error de generación de clave al procesar una clave en la tabla de escrituras lateral, almacena esa clave en la tabla de violaciones de restricciones para su procesamiento posterior.

Si el mongod encuentra cualquier otro error al realizar el procesamiento de una clave, la compilación falla con un error.

Para cada documento guardado en la colección durante el proceso de creación, el mongod genera una clave para ese documento y lo almacena en la tabla de guardado lateral para su posterior procesamiento. El mongod utiliza un sistema de snapshot para establecer un límite en el número de claves para procesar.

Vota y espera el quórum de confirmación

El mongod que no forma parte de un set de réplicas se salta esta etapa.

El mongod envía un "voto" al primario para confirmar el índice. Específicamente, guarda el "voto" en una colección replicada interna en el primario.

Si el mongod es el primario, espera hasta tener un quórum de confirmación de votos (todos los miembros con datos que votan por defecto) antes de continuar con el proceso de creación de índices.

Si el mongod es secundario, espera hasta que replique una entrada de oplog "commitIndexBuild" o "abortIndexBuild":

  • Si el mongod replica una entrada de oplog "commitIndexBuild", finaliza el drenando de la tabla de escrituras secundarias y avanza a la siguiente etapa en el proceso de creación de índices.

  • Si el mongod replica una entrada de oplog "abortIndexBuild", aborta la creación de índices y descarta la tarea de construcción.

Mientras se espera el quórum de confirmación, el mongod añade cualquier clave adicional generada por operaciones de escritura a la colección que se está indexando en la tabla de escrituras laterales y vacía periódicamente la tabla.

Bloqueo

El mongod actualiza el bloqueo IX de intención exclusiva de la colección a un bloqueo S compartido. Esto bloquea todas las operaciones de guardado en la colección, incluida la aplicación de cualquier operación de guardado replicada o comandos de metadatos que tengan como objetivo la colección.

Finalizar el procesamiento de la tabla de guardados temporales laterales

El mongod continúa drenando los registros restantes en la tabla de escrituras secundarias. El mongod puede pausar la replicación durante esta etapa.

Si el mongod encuentra un error de generación de clave al procesar una clave en la tabla de escrituras lateral, almacena esa clave en la tabla de violaciones de restricciones para su procesamiento posterior.

Si el mongod encuentra cualquier otro error al realizar el procesamiento de una clave, la compilación falla con un error.

Bloqueo

El mongod actualiza el bloqueo S compartido en la colección a un bloqueo X exclusivo en la colección. Esto bloquea todas las operaciones de lectura y guardado en la colección, incluida la aplicación de cualquier operación de guardado replicada o comandos de metadatos que tengan como objetivo la colección. El mongod no libera este bloqueo.

Tabla de escritura con lado abatible

El mongod aplica cualquier operación restante en la tabla de escrituras lateral antes de eliminarla.

Si el mongod encuentra un error de generación de clave al procesar una clave en la tabla de escrituras lateral, almacena esa clave en la tabla de violaciones de restricciones para su procesamiento posterior.

Si el mongod encuentra cualquier otro error al realizar el procesamiento de una clave, la compilación falla con un error.

En este punto, el índice incluye todos los datos escritos en la colección.

Tabla de infracciones de restricciones de proceso

Si el mongod es el primario, vacía la tabla de violaciones de restricciones utilizando la prioridad de primero en entrar, primero en salir.

  • Si ninguna clave en la tabla de violaciones de restricciones produce un error de generación de claves o si la tabla está vacía, el mongod descarta la tabla y crea una entrada de oplog "commitIndexBuild". Los secundarios pueden completar la creación de índices asociada después de replicar la entrada del oplog.

  • Si alguna clave de la tabla de violación de restricciones sigue produciendo un error de generación de clave, el mongod aborta la creación y arroja un error. El mongod crea una entrada de oplog asociada "abortIndexBuild" para indicar que los secundarios deben abortar y descartar la tarea de creación de índices.

Si el mongod es un secundario, descarta la tabla de violación de restricciones. Dado que el primario debe vaciar con éxito la tabla de violaciones de restricciones antes de crear la entrada de oplog "commitOplogEntry", el secundario puede suponer con seguridad que no existen violaciones.

Marque el índice como listo

El mongod actualiza los metadatos del índice para indicar que el índice está listo para su uso.

Bloqueo

El mongod libera el bloqueo X en la colección.

Volver

Colecciones fragmentadas

En esta página