Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

AWS DMS: por qué evitar el filtrado por columnas

By Dhiraj BhamareApr 7, 20258 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

AWS Database Migration Service (DMS) es una herramienta muy utilizada para migrar y replicar bases de datos, compatible con entornos homogéneos y heterogéneos. Cuando se usa AWS Database Migration Service (DMS) para migrar datos desde fuentes como Amazon RDS MySQL y Amazon RDS PostgreSQL, los filtros de origen permiten acotar de forma efectiva la cantidad y el tipo de registros que se transfieren a la base de datos de destino. Sin embargo, conviene tener presentes ciertas limitaciones de estos filtros para que la migración fluya sin sobresaltos.

Visión general de AWS DMS

AWS DMS permite migrar datos replicando de forma continua los cambios desde la base de datos de origen hacia la de destino, con un tiempo de inactividad mínimo. Entre sus funciones clave se encuentran:

  • Full Load, CDC y replicación continua: admite tanto la migración inicial como la sincronización continua.
  • Mapeo de esquemas y tablas: permite incluir y transformar objetos con flexibilidad.
  • Capacidades de filtrado: ofrece filtrado a nivel de fila y de columna para controlar qué datos se replican.
  • Compatibilidad con varios motores de bases de datos: funciona con MySQL, PostgreSQL, SQL Server, Oracle y otros.

A pesar de estas capacidades, el filtrado por columnas en AWS DMS no siempre se comporta como se espera, sobre todo al procesar actualizaciones durante el CDC.

¿Qué es el filtrado por columnas en AWS DMS?

El filtrado por columnas en AWS DMS te permite incluir o excluir filas de la replicación según condiciones aplicadas a columnas específicas. Por ejemplo, puedes configurar una tarea de DMS para que replique únicamente las filas en las que una columna como ‘status’ sea igual a ‘active’, o donde una columna ‘timestamp’ sea posterior a una fecha determinada. Resulta especialmente útil cuando solo te interesa migrar un subconjunto de datos o aplicar lógica de negocio durante la migración.

Este es un ejemplo de regla de filtro por columnas en DMS:

{
  "rules": [\
    {\
      "rule-type": "selection",\
      "rule-id": "1",\
      "rule-name": "FilterActiveUsers",\
      "object-locator": {\
        "schema-name": "public",\
        "table-name": "users"\
      },\
      "rule-action": "include",\
      "filters": [\
        {\
          "filter-type": "source",\
          "column-name": "status",\
          "filter-conditions": [\
            {\
              "filter-operator": "eq",\
              "value": "active"\
            }\
          ]\
        }\
      ]\
    }\
  ]

Caso de uso: filtrado por columnas durante la migración de datos

Para evaluar cómo maneja DMS el filtrado por columnas, hicimos una prueba de concepto (POC) migrando datos desde una instancia RDS MySQL 8.0 a otra instancia RDS MySQL 8.0 con AWS Database Migration Service (DMS). El requisito era simple: replicar filas desde la tabla de origen a la tabla de destino solo cuando una columna específica, llamada "name", cumpliera cierta condición (es decir, cuando name = "b"). Para lograrlo, recurrimos a la función de filtrado por columnas de origen de DMS, que permite incluir o excluir filas según valores específicos.

Configuración

  • Origen: RDS MySQL 8.0.36
  • Destino: RDS MySQL 8.0.36
  • Versión de DMS: Engine 3.5.4
  • Modo de migración: Full Load con CDC

Se creó una tabla de muestra en la base de datos de origen:

CREATE TABLE `Sample` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);

Se configuró una tarea de migración de DMS con un filtro a nivel de columna para replicar únicamente las filas en las que name = ‘b’.

Regla de mapeo de DMS:

{
"rules": [\
{\
"rule-type": "selection",\
"rule-id": "098947021",\
"rule-name": "098947021",\
"object-locator": {\
"schema-name": "Test",\
"table-name": "Sample"\
},\
"rule-action": "include",\
"filters": [\
{\
"filter-type": "source",\
"column-name": "name",\
"filter-conditions": [\
{\
"filter-operator": "eq",\
"value": "b"\
}\
]\
}\
]\
}\
]
}

regla de selección con filtro de origen

Observaciones y hallazgos:

Cuando se insertó una fila con name = ‘b’, se replicó correctamente. Del mismo modo, una inserción con name = ‘a’ se ignoró como correspondía. Sin embargo, las actualizaciones presentan inconsistencias:

  • La actualización de name=’a’ a name=’b’ se ignoró, aun cuando el CDC capturó el evento.

Si la validación de DMS está habilitada, este comportamiento provoca registros desalineados entre las bases de datos de origen y destino, ya que la validación marcará las discrepancias.

Esto pone aún más en evidencia que AWS DMS aplica los filtros con base en el estado previo a la actualización, lo que puede derivar en problemas de integridad de datos cuando se utiliza el filtrado por columnas.

Causa raíz: cómo aplica los filtros AWS DMS

AWS DMS evalúa los filtros de columna a partir del estado de la fila antes de que ocurra la actualización. Es decir:

  • Eventos de inserción: el filtro se aplica a los valores de la fila insertada.
  • Eventos de actualización: el filtro se evalúa antes de aplicar la actualización.
  • Eventos de eliminación: el filtro verifica el estado de la fila previo a la eliminación.

Como las actualizaciones se filtran según el estado original de la fila, una actualización que cambia name = ‘a’ a name = ‘b’ se ignora. La fila no cumplía la condición del filtro antes de la actualización, por lo que nunca se replica.

Este comportamiento puede generar inconsistencias en los datos. Si una aplicación depende del filtrado de filas tras una actualización, los datos esperados podrían no llegar a replicarse nunca.

Solución alternativa: filtrar en la base de datos de destino

Como AWS DMS no ofrece la opción de aplicar filtros después de procesar una actualización, hace falta una solución alternativa:

Paso 1: eliminar los filtros de columna de la tarea de DMS

Modifica la tarea de DMS para que replique todos los datos sin filtrado.

Paso 2: implementar el filtrado en la base de datos de destino

En lugar de replicar directamente a la tabla Sample en la base de datos de destino, puedes replicar a una tabla de staging y luego usar un trigger o un stored procedure para mover las filas válidas a la tabla Sample.

Crea una tabla de staging (sample_staging) en la base de datos RDS MySQL de destino. Esta tabla almacenará temporalmente los datos replicados antes de moverlos a la tabla Sample.

Por ejemplo, en MySQL:

CREATE TABLE sample_staging (
id INT PRIMARY KEY,
name VARCHAR(255)
);

Paso 3: crear un stored procedure

Crea un stored procedure que mueva las filas válidas (por ejemplo, aquellas en las que name = ‘b’) desde la tabla de staging (sample_staging) a la tabla de destino (Sample). Este procedimiento se encargará tanto de las inserciones como de las actualizaciones.

CREATE PROCEDURE MoveValidRowsToSample()
BEGIN
-- Insert or update valid rows in the Sample table
INSERT INTO Sample (id, name)
SELECT id, name
FROM sample_staging
WHERE name = 'b'
ON DUPLICATE KEY UPDATE
name = VALUES(name);
--Delete valid rows from the staging table
DELETE FROM sample_staging
WHERE name = 'b';
END

Paso 4: crear un trigger

Crea un trigger sobre la tabla de staging (sample_staging) para que invoque automáticamente al stored procedure cada vez que se inserte o actualice una fila.

CREATE TRIGGER after_insert_sample_staging
AFTER INSERT ON sample_staging
FOR EACH ROW
BEGIN
CALL MoveValidRowsToSample();
END

CREATE TRIGGER after_update_sample_staging
AFTER UPDATE ON sample_staging
FOR EACH ROW
BEGIN
CALL MoveValidRowsToSample();
END

Cómo funciona

  • Base de datos de origen: contiene los datos originales.
  • AWS DMS: replica los datos desde el origen hacia la tabla sample_staging en la base de datos RDS MySQL de destino.
  • Tabla de staging (sample_staging): almacena temporalmente todos los datos replicados.
  • Trigger: invoca automáticamente a un stored procedure cada vez que se insertan o actualizan datos en la tabla sample_staging.
  • Stored procedure: mueve las filas válidas (donde name = ‘b’) desde sample_staging a la tabla Sample.
  • Tabla de destino (Sample): contiene únicamente las filas válidas una vez que el trigger y el stored procedure han procesado los datos.

En PostgreSQL se puede implementar una función similar usando triggers BEFORE INSERT OR UPDATE.

Pruebas en RDS PostgreSQL

Para confirmar que este comportamiento no era exclusivo de MySQL, hicimos la misma prueba en RDS PostgreSQL. Los resultados fueron idénticos:

  • Las actualizaciones que hacían que una fila cumpliera la condición del filtro no se replicaban a la tabla de destino.
  • Esto confirma que el problema no depende de la base de datos, sino que es una limitación de cómo DMS gestiona los filtros de columna durante el CDC.

Otras limitaciones de los filtros de origen de DMS

  • Columnas con idiomas de derecha a izquierda (RTL): al usar filtros de origen de DMS, se podría suponer que la herramienta maneja todo tipo de datos, sin importar el idioma o el alfabeto. No es así. Los filtros de origen de DMS no procesan columnas que contengan idiomas RTL como el hebreo. Si las condiciones del filtro involucran este tipo de columnas, los filtros pueden no funcionar como se espera, lo que deriva en una replicación de datos incompleta o incorrecta.

Ejemplo: si tienes una columna con texto en hebreo (por ejemplo, customer_name en hebreo) y aplicas una condición como customer_name = "דוד", DMS podría no evaluar la condición correctamente.

  • Columnas LOB (Large Object): no se pueden aplicar filtros a columnas LOB, como BLOBs, CLOBs o TEXT en MySQL, ni BYTEA o TEXT en PostgreSQL. Intentar filtrar con base en estas columnas no surte efecto.

Ejemplo: si la tabla de un documento tiene una columna content de tipo TEXT, un filtro como content LIKE ‘%AWS%’ no funcionará.

Recomendaciones para un filtrado efectivo

  • Indexar las columnas filtradas: para mejorar el rendimiento de la tarea de DMS, crea índices sobre las columnas filtradas junto con la clave primaria. Así se logra un filtrado eficiente y se reduce la carga sobre la base de datos de origen.
  • Usa el filtrado del lado del destino cuando sea necesario: si el comportamiento del filtrado por columnas no se ajusta a tus necesidades, considera aplicar los filtros directamente en la base de datos de destino.
  • Evita filtrar en columnas LOB y RTL: como DMS no admite el filtrado en columnas LOB ni en texto RTL, conviene planificar enfoques alternativos para este tipo de datos.

Aprendizajes clave:

  • DMS evalúa los filtros sobre el estado previo a la actualización: los filtros de columna solo verifican los valores existentes de la fila antes de aplicar la actualización.
  • Las actualizaciones pueden ignorarse: si una actualización hace que una fila cumpla la condición del filtro, no se replicará a menos que la fila ya cumpliera dicha condición previamente.
  • La solución alternativa requiere filtrado del lado del destino: para asegurar una replicación correcta, evita usar filtros de columna en AWS DMS y aplica la lógica de filtrado en la base de datos de destino.

Este comportamiento puede causar pérdidas de datos inesperadas en esquemas de replicación que dependen del filtrado por columnas. Si necesitas filtrar según valores posteriores a la actualización, AWS DMS por sí solo no alcanza: hay que implementar lógica adicional en la base de datos de destino para garantizar una replicación precisa.

AWS DMS evalúa los filtros de columna sobre el estado previo a la actualización de una fila durante el CDC. Como resultado, las actualizaciones que modifican una fila para que cumpla la condición del filtro no se replican, lo que puede provocar inconsistencias inesperadas en los datos. Esta limitación puede afectar las estrategias de replicación y la consistencia de los datos.

Si tu migración depende del filtrado posterior a la actualización, AWS DMS por sí solo no alcanza, y se necesita lógica adicional del lado de la base de datos. Futuras actualizaciones de AWS DMS o una documentación más clara podrían ayudar a despejar este comportamiento.

Esperamos que este artículo te haya aportado información valiosa. Si quieres saber más o te interesan nuestros servicios, no dudes en escribirnos. Puedes contactarnos aquí.