Docs Menu
Docs Home
/ /

Creación de índices en colecciones pobladas

La creación de índices utiliza un proceso de creación optimizado que mantiene un bloqueo exclusivo en la colección al principio y al final de la creación. El resto del proceso de creación se basa en operaciones de lectura y escritura intercaladas. Para obtener una descripción detallada del proceso de creación de índices y el comportamiento del bloqueo, consulte Proceso de construcción de índices.

El índice se construye sobre un conjunto de réplicas o un clúster fragmentado, y se construye simultáneamente en todos los miembros del conjunto de réplicas que contienen datos. El principal requiere un número mínimo de miembros con derecho a voto (es decir, 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 con derecho a voto es cualquier miembro del conjunto de réplicas donde members[n].voteses mayor que.0 Consulte "Compilaciones 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 eran compatibles con la creación de índices tanto en primer plano como en segundo plano. La creación de índices en primer plano era rápida y producía estructuras de datos de índice más eficientes, pero requería bloquear todo acceso de lectura y escritura a la base de datos principal de la colección que se estaba indexando durante el tiempo que duraba la creación. Las creaciones de índices en segundo plano eran más lentas y tenían resultados menos eficientes, pero permitían el acceso de lectura y escritura a la base de datos y sus colecciones durante el proceso de construcción.

La creación de índices ahora obtiene un bloqueo exclusivo solo en la colección que se está indexando durante el inicio y el final del proceso de compilación para proteger los cambios en los metadatos. El resto del proceso de creación utiliza el comportamiento de suspensión de la creación de índices en segundo plano para maximizar el acceso de lectura y guardado a la colección durante la creación. La creación de índices sigue produciendo estructuras de datos de índice eficientes a pesar del comportamiento de bloqueo más permisivo.

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 forma similar, una aplicación puede guardar documentos correctamente en la colección inventory con valores duplicados de product_sku mientras la creación de índices está en curso. Si aún existen violaciones al final de la compilación, mongod termina la compilación y arroja un error.

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.

Para una colección particionada distribuida en varias particiones, una o más particiones pueden contener un fragmento con documentos duplicados. Por lo tanto, la operación de creación de índice puede tener éxito en algunas de las particiones (es decir, las que no tienen duplicados) pero no en otras (es decir, las que tienen duplicados). Para evitar dejar índices inconsistentes entre particiones, puedes emitir el db.collection.dropIndex() desde un mongos para descartar el índice de la colección.

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 durante periodos en los que la colección objetivo está bajo una carga de guardado intensa puede resultar en un rendimiento de guardado reducido y en tiempos de creación de índices más prolongados.

Considera designar un periodo de mantenimiento durante el cual las aplicaciones detengan o reduzcan las operaciones de guardado contra la colección. Inicia la creación de índices durante este periodo de mantenimiento para mitigar el posible impacto negativo del proceso de construcción.

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ámetromaxIndexBuildMemoryUsageMegabytes. Aumentar este parámetro solo es necesario en casos excepcionales, como al ejecutar varias compilaciones de índices simultáneas con un solo comandocreateIndexeso al indexar un conjunto de datos de más de 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 gradual toma, como máximo, un nodo del set de réplicas a la vez, comenzando con los nodos secundarios, y crean el índice en ese nodo como un autónomo. La creación de índices gradual requiere al menos una elección de set de réplicas. Solo debe usarse si los clientes cumplen con los requisitos mencionados en las páginas de índices graduales, ya que el 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 utilizan preocupaciones de escritura.

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

El quórum de confirmación especifica cuántos miembros votantes que contienen datos, o qué miembros votantes, incluido el principal, deben estar preparados para confirmar una creación de índice simultánea antes de que el principal ejecute la confirmación.

La preocupación de escritura es el nivel de reconocimiento de que la escritura se ha propagado a la cantidad especificada de instancias.

El quórum de confirmación especifica cuántos nodos deben estar listos para finalizar la compilación del índice antes de que el nodo principal la confirme. Por el contrario, cuando el nodo principal ha confirmado la compilación del índice, la preocupación de escritura especifica cuántos nodos deben finalizarla antes de que el comando regrese.

A partir de MongoDB 5.0, si el mongod primario realiza un shutdown correcto con "force" : true o recibe una señal SIGTERM durante la creación de índices y el commitQuorum está configurado en el valor por defecto votingMembers, el progreso de la creación de índices se guarda en el disco. El mongod recupera automáticamente la creación de índices cuando se reinicia y continúa desde el punto de control guardado. En versiones anteriores, si se interrumpía la creación de índices, debía reiniciarse desde el principio.

A partir de MongoDB 5.0, si un mongod secundario realiza un shutdown limpio con "force" : true o recibe una señal SIGTERM durante la creación de índices y el commitQuorum está configurado en el valor por defecto votingMembers, entonces el progreso de la creación de índices se guarda en el disco. El mongod recupera automáticamente la creación de índices cuando se reinicia y continúa desde el punto de control guardado. En versiones anteriores, si se interrumpía la creación de índices, debía reiniciarse desde el principio.

El mongod puede realizar el proceso de empresa emergente mientras se crea el índice que se está recuperando.

Si reinicia el mongod como una instancia autónoma (es decir, removiendo o comentando replication.replSetName, u omitiendo --replSetName), el mongod no puede reiniciar la creación de índices. La compilación permanece en un estado de pausa hasta que se reanuda manualmente dropped.

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 particionada tiene un índice inconsistente si la colección no tiene exactamente los mismos índices (incluidas las opciones de índice) en cada partición que contiene fragmentos de la colección. Aunque no deberían ocurrir índices inconsistentes durante las operaciones normales, pueden ocurrir índices inconsistentes, como por ejemplo:

  • Cuando un usuario está creando un índice con una restricción de clave unique y una partición contiene un fragmento con documentos duplicados. En tales casos, la operación de creación de índice puede tener éxito en las particiones sin duplicados, pero no en la partición con duplicados.

  • Cuando un usuario está compilando un índice en las particiones de forma continua (es decir, compilando manualmente el índice uno por uno en las particiones), pero no logra compilar el índice para una partición asociado o compila 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