Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Lecturas secundarias de larga duración en clústeres particionados

A partir de MongoDB 8.2, las lecturas secundarias en clústeres particionados podrían finalizar automáticamente si existe riesgo de pérdida de documentos debido a migraciones por fragmentos.

Para respaldar este nuevo comportamiento, MongoDB 8.2 introduce los siguientes cambios:

  • Agregar terminateSecondaryReadsOnOrphanCleanupParámetrotrue (predeterminado:)

    Nota

    Si terminateSecondaryReadsOnOrphanCleanup se establece en false, el servidor no termina las lecturas y podría perder documentos en colecciones fragmentadas debido a migraciones de fragmentos. Este es el comportamiento por defecto en MongoDB 8.1 o anterior. Para aprender más, consulta Deshabilitar la terminación de lectura secundaria.

  • Aumenta orphanCleanupDelaySecs el valor por defecto de 900 segundos a 3600 segundos (1 hora)

De forma predeterminada, un clúster fragmentado realiza las siguientes operaciones cuando se confirma una migración de fragmentos:

  1. La partición de origen inicia un proceso de limpieza de huérfanos para borrar documentos que migraron a una partición diferente.

    1. El fragmento espera a que se completen todas las lecturas preexistentes en el fragmento principal.

    2. El fragmento espera orphanCleanupDelaySecs segundos adicionales (valor predeterminado: 1 hora).

    3. La partición borra documentos huérfanos.

  2. Los secundarios terminan las lecturas que comenzaron antes de que se completara la migración.

  3. Los secundarios replican eliminaciones de documentos huérfanos.

Diagrama que muestra el ciclo de vida de una lectura secundaria de larga duración que finaliza debido a una migración de fragmentos.

Finalizar las lecturas secundarias antes de eliminar documentos huérfanos garantiza que las lecturas secundarias de larga duración no omitan ningún documento eliminado durante el proceso de limpieza.

Puede supervisar las lecturas secundarias terminadas debido a la limpieza de huérfanos de las siguientes maneras:

  • Compruebe el estado del servidor de su nodo secundario con el siguiente mongosh comando:

    db.serverStatus().metrics.operation.killedDueToRangeDeletion

  • Revise sus registros mongod. Cada terminación genera una entrada de registro como la del siguiente ejemplo:

{
"t": {
"$date": "2025-06-11T12:11:43.361+02:00"
},
"s": "I",
"c": "SHARDING",
"id": 10016300,
"svc": "S",
"ctx": "conn93",
"msg": "Read has been terminated due to orphan range cleanup",
"attr": {
"type": "command",
...
"workingMillis": 0,
"durationMillis": 0,
"orphanCleanupDelaySecs": 3600
}
}

Si su aplicación realiza lecturas secundarias que superan las 1 horas en clústeres fragmentados que realizan migraciones de fragmentos, es posible que encuentre QueryPlanKilled errores (código 175 de error) debido a lecturas finalizadas.

El método recomendado para gestionar las lecturas secundarias de larga duración es implementar un mecanismo de reanudación en su aplicación.

También puedes gestionar lecturas secundarias de larga duración con las siguientes estrategias alternativas:

Un mecanismo de reanudación permite a tu aplicación crear una nueva operación de lectura que comience donde terminó la operación de lectura anterior.

Para implementar un mecanismo de reanudación efectivo, tu aplicación debe usar un ordenamiento coherente para los resultados de sus queries. Ten en cuenta los siguientes factores al seleccionar un orden de clasificación para tu mecanismo de reanudación:

  • La operación de clasificación debe utilizar un campo indexado para una ejecución eficiente de la consulta.

  • El campo de ordenación debe contener valores únicos.

    • Si los valores del campo de ordenación no son únicos, tu aplicación debe implementar lógica adicional para gestionar documentos que compartan el mismo valor de ordenación.

Considere una base de datos cities que contiene una colección zipcodes con la siguiente estructura:

{
"state": "NY",
"city": "NEW YORK",
"zipcode": "00501"
}

Para este ejemplo, supongamos que los valores del campo zipcode son únicos.

El siguiente código JavaScript realiza una operación de lectura secundaria para recuperar todos los documentos donde el state es NY e implementa un mecanismo de reanudación para gestionar errores QueryPlanKilled:

let readDoc;
let latestZip;
let cursor = db.getSiblingDB("cities").zipcodes.find({
state: "NY"
})
.sort({zipcode: 1})
.readPref("secondary");
while(cursor.hasNext()) {
try {
readDoc = cursor.next();
// process `readDoc` here
latestZip = readDoc.zipcode;
} catch (err) {
if (err.code === 175 &&
err.errmsg.includes("Read has been terminated due to orphan range cleanup")) {
console.log("Query terminated, resuming from zipcode:", latestZip);
cursor = db.getSiblingDB("cities").zipcodes.find({
state: "NY",
zipcode: {$gt: latestZip}
})
.sort({zipcode: 1})
.readPref("secondary");
} else {
throw err; // Rethrow non-termination errors
}
}
}

Al revisar la base de datos de ejemplo y la lógica de la aplicación, considere lo siguiente:

  • El código de ejemplo gestiona QueryPlanKilled errores con un mecanismo de reanudación que ordena por zipcode. Ordenar por el campo zipcode garantiza un orden coherente y un valor de orden único para cada documento. Esto permite que la aplicación reanude la operación de lectura exactamente donde se detuvo.

  • La cities.zipcodes colección implementa un {state: 1, zipcode: 1} índice compuesto para garantizar la eficiencia de las queries del mecanismo de reanudación. La implementación de este índice compuesto evita tanto escaneos de colección como ordenamientos en memoria, y admite operaciones de filtrado y ordenamiento. Para obtener más información sobre cómo crear índices efectivos, consulta La guía ESR (Igualdad, Ordenación, Rango).

  • El error QueryPlanKilled (código de error 175) puede ocurrir por razones distintas a la interrupción de lecturas secundarias. Para gestionar de manera precisa los errores QueryPlanKilled, debe analizar el campo errmsg. MongoDB devuelve el siguiente mensaje de error cuando finaliza una lectura secundaria:

{
code: 175,
name: QueryPlanKilled,
categories: [CursorInvalidatedError],
errmsg: "Read has been terminated due to orphan range cleanup"
}
  • Cuando la aplicación encuentra un error de QueryPlanKilled debido a la limpieza de rangos huérfanos, utiliza el código postal procesado exitosamente como punto de partida para la query reanudada. El operador $gt garantiza que la aplicación no procese documentos duplicados.

Prueba tus mecanismos de reanudación en un entorno de prueba y supervisa tu clúster de producción para comprender con qué frecuencia se terminan las lecturas secundarias. Si las terminaciones ocurren con frecuencia, puede que debas ajustar tus patrones de query o considerar enfoques alternativos de acceso a los datos. Para aprender cómo supervisar tu clúster para estos errores, consulta Supervisión.

El parámetro de servidor orphanCleanupDelaySecs controla el tiempo que MongoDB espera antes de borrar un fragmento migrado de la partición de origen.

Aumentar orphanCleanupDelaySecs permite que las operaciones de lectura secundarias se ejecuten durante un periodo de tiempo más largo. Puedes configurar el orphanCleanupDelaySecs tanto al inicio como en tiempo de ejecución.

El siguiente comando establece orphanCleanupDelaySecs en 2 horas:

db.adminCommand({
setParameter: 1,
orphanCleanupDelaySecs: 7200
})

Importante

Incrementar orphanCleanupDelaySecs significa que los documentos huérfanos permanecen en los nodos durante un periodo de tiempo más largo. Si aumentas este valor, ejecutar una query que utiliza un índice pero no incluye la clave de partición puede resultar en un rendimiento degradado, ya que la query debe filtrar más documentos huérfanos antes de devolver los resultados.

Nota

En MongoDB 8.1 o versiones anteriores, los clústeres fragmentados no finalizan automáticamente las lecturas secundarias de larga duración. Para que esto se ajuste a MongoDB 8.2 o versiones posteriores, deshabilite la finalización de lecturas secundarias.

El parámetro terminateSecondaryReadsOnOrphanCleanup del servidor controla si las lecturas secundarias de larga duración terminan automáticamente antes de la eliminación de documentos huérfanos.

Puede desactivar la terminación de lectura secundaria configurando terminateSecondaryReadsOnOrphanCleanup en false. Puede configurar este parámetro al iniciar o ejecutar.

El siguiente comando establece terminateSecondaryReadsOnOrphanCleanup en false:

db.adminCommand({
setParameter: 1,
terminateSecondaryReadsOnOrphanCleanup: false
})

Advertencia

Si esta funcionalidad está desactivada y las migraciones de fragmentos afectan a la colección objetivo, es posible que las lecturas secundarias no devuelvan todos los documentos.

Puedes evitar la finalización automática de lecturas secundarias de larga duración desactivando el balanceador y no realizando ninguna migración manual.

Para desactivar el balanceador en colecciones específicas, utiliza el campo enableBalancing del comando configureCollectionBalancing.

Para restringir las operaciones del balanceador a períodos específicos, consulte Programar la ventana de balanceo.

Advertencia

Desactivar el balanceador durante períodos prolongados puede provocar particiones desequilibradas, lo que reduce el rendimiento del clúster. Sólo desactive el balanceador si es necesario para tu caso de uso.

Volver

AutoMerger

En esta página