Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
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 terminateSecondaryReadsOnOrphanCleanup parámetro (por defecto: true)

    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 Desactivar la finalización secundaria de lectura.

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

Por defecto, un clúster particionado realiza las siguientes operaciones cuando se confirma una migración de fragmento:

  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. La partición espera a que se completen cualquier lectura preexistente en el primario.

    2. La partición espera orphanCleanupDelaySecs segundos adicionales (por defecto: 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. Las secundarias replican las eliminaciones de documentos huérfanos.

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

Concluir las lecturas secundarias antes de borrar documentos huérfanos garantiza que las lecturas secundarias de larga duración no pierdan ningún documento borrado por 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 de mongod. Cada rescisión resulta en una entrada de registro como el 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 tu aplicación realiza lecturas secundarias que superan las 1 hora en clústeres fragmentados que realizan migraciones de fragmentos, podrías encontrar errores QueryPlanKilled (código de error 175) debido a lecturas terminadas.

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 ordenación debe utilizar un campo indexado para una ejecución eficiente de consultas.

  • 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"
}

En este ejemplo, asume 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 anteriores, los clústeres no terminan automáticamente las lecturas secundarias de larga duración. Para igualar este comportamiento en MongoDB 8.2 o versiones posteriores, desactiva la terminación de lectura secundaria.

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.

Se puede desactivar la terminación de lectura secundaria configurando terminateSecondaryReadsOnOrphanCleanup en false. Puede establecer este parámetro al inicio o en tiempo de ejecución.

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