Pasar un lago de datos de Hive a Apache Iceberg solía costar semanas de ingeniería: un clúster para reescribir los datos, conversiones de tipos y un plan de vuelta atrás. Desde el 4 de noviembre de 2026, Amazon S3 Tables lo hace como una operación gestionada por API, sin cómputo que aprovisionar y sin parar las escrituras en la tabla original salvo unos minutos en el corte. Solo se paga por los datos copiados; la conversión de Hive a Iceberg no tiene coste propio.
Qué cambia y para quién
La migración funciona con tablas Hive externas registradas en el AWS Glue Data Catalog y guardadas como Parquet en buckets de S3 de uso general. S3 Tables crea una tabla Iceberg nueva en un table bucket, convierte los tipos de Hive a Iceberg, recomprime los datos y junta los ficheros pequeños. La tabla de origen no se toca y sigue disponible para lecturas y escrituras durante todo el proceso.
El flujo tiene tres pasos:
- Start crea la tabla destino (de solo lectura) y copia los datos. Antes de copiar nada, genera informes de compatibilidad de la tabla y de cada objeto.
- Sync copia solo lo que ha cambiado desde la última copia, incluso dentro de una partición. Se puede repetir tantas veces como haga falta y también sirve para reanudar una migración fallida.
- Complete pasa la tabla a lectura y escritura y activa el mantenimiento automático. Es irreversible.
Está disponible en diez regiones, entre ellas Fráncfort, Irlanda y Estocolmo.
Cómo lanzarla
Desde la consola: en el table bucket destino, Create table y Migrate existing table. Por CLI, con los comandos de la documentación:
# Empieza y pausa tras generar los informes de compatibilidad
aws s3tables start-table-migration \
--role-arn arn:aws:iam::111122223333:role/S3TablesMigrationRole \
--destination-table '{"tableBucketARN":"arn:aws:s3tables:eu-west-1:111122223333:bucket/lake","namespace":"sales","name":"orders"}' \
--source-type glueTable \
--source '{"glueTable":{"catalogId":"111122223333","databaseName":"sales","tableName":"orders"}}' \
--migration-output '{"bucket":"arn:aws:s3:::lake-reports","prefixes":{"tableCompatibilityReport":"migration","objectCompatibilityReport":"migration","objectMigrationReport":"migration"}}' \
--review-migration-plan
# Revisa el estado y los informes; después, aprueba la copia
aws s3tables get-table-migration --migration-id <migration-id>
aws s3tables update-table-migration --migration-id <migration-id> --requested-state queued
# Copia los cambios antes del corte y completa (no se puede deshacer)
aws s3tables sync-table-migration \
--role-arn arn:aws:iam::111122223333:role/S3TablesMigrationRole \
--table-arn arn:aws:s3tables:eu-west-1:111122223333:bucket/lake/table/<table-id> \
--migration-output '{"bucket":"arn:aws:s3:::lake-reports","prefixes":{"tableCompatibilityReport":"migration","objectCompatibilityReport":"migration","objectMigrationReport":"migration"}}'
aws s3tables complete-table-migration \
--table-arn arn:aws:s3tables:eu-west-1:111122223333:bucket/lake/table/<table-id>El rol necesita leer los metadatos de Glue y los objetos de origen, escribir en la tabla destino y en el bucket de informes, y una relación de confianza con migration.s3tables.amazonaws.com. Si usas SSE-KMS en el destino, la clave también tiene que permitir a maintenance.s3tables.amazonaws.com.
Mi recomendación es usar siempre --review-migration-plan la primera vez: la migración se queda en pendingReview hasta que la apruebas y puedes leer los informes antes de pagar por copiar un solo byte.
La política de migración no se puede cambiar
Dos ajustes deciden qué pasa con los datos que no encajan, y se fijan en el start para siempre: unmatchedSourceFieldsPolicy (columnas del origen que no están en el esquema destino: fail o drop) e incompatibleValuesPolicy (valores que no se pueden convertir: fail o setNull). Ambos fallan por defecto. Con setNull, un fichero que guarde quantity como bigint en una columna int se migra con esa columna a null en ese objeto: es cómodo, pero es pérdida de datos silenciosa si nadie lee el informe de objetos.
Trampas y casos límite
- Formatos. Solo Parquet (sin comprimir, Snappy, gzip, Zstandard, Brotli o LZ4). Nada de ORC, Avro, JSON ni LZO.
- Tablas excluidas. Ni tablas Hive transaccionales (ACID), ni las registradas en Lake Formation, ni las que ya están en un formato abierto, ni las que saltan cabeceras.
- Misma cuenta y región para origen, destino e informes. Sin catálogos federados.
- Sobrescrituras. Un sync falla un objeto que se haya sobrescrito desde la copia anterior, aunque el contenido sea idéntico y el bucket tenga versionado. Si tu ETL reescribe particiones enteras, cuenta con ello.
- Particiones fuera de la ruta de la tabla o con proyección de particiones de Athena: hay que moverlas o registrarlas antes (
MSCK REPAIR TABLE). - Lo que no se copia: parámetros de la tabla en Glue, ajustes de SerDe, estadísticas y comentarios de columnas.
- Objetos archivados en Glacier o en los niveles de archivo de Intelligent-Tiering: hay que restaurarlos primero.
Frente a lo que había
Hasta ahora, la vía de referencia de AWS era una guidance con CloudFormation que levanta un clúster de Amazon EMR, ejecuta un Create Table As Select con Spark orquestado por Step Functions y apaga el clúster al acabar. Funciona, pero es infraestructura que mantener, una copia completa con CTAS y un clúster que pagar mientras dura. La migración gestionada cambia ese clúster por una API con informes previos y syncs repetibles, a cambio de las restricciones de arriba. Si tus tablas son Parquet en Glue, en la misma cuenta y sin Lake Formation, ya no hay motivo para montar el pipeline a mano; si no, la vía con EMR sigue siendo la que vale.
Fuentes
- Amazon S3 Tables now offer managed migration of Apache Hive tables to Apache Iceberg — AWS News Blog
- Running a table migration — AWS Documentation
- How to migrate a table to S3 Tables — AWS Documentation
- Setting up table migration — AWS Documentation
- Guidance for Migrating Tabular Data from Amazon S3 to S3 Tables — AWS Solutions