Comment résoudre les problèmes liés à la commande UNLOAD dans Amazon Redshift ?

Dernière mise à jour : 07/10/2022

J'essaie de décharger des données de mon cluster Amazon Redshift vers Amazon Simple Storage Service (Amazon S3). Cependant, je reçois un message d'erreur. Comment résoudre ce problème ?

Brève description

Lorsque vous déchargez des données de votre cluster Amazon Redshift vers votre compartiment Amazon S3, vous pouvez rencontrer les erreurs suivantes :

L'erreur « DB user is not authorized to assume the AWS Identity and Access Management (IAM) Role » (L'utilisateur de la base de données n'est pas autorisé à endosser le rôle AWS Identity and Access Management (IAM))

error:  User arn:aws:redshift:us-west-2:<account-id>:dbuser:<cluster-identifier>/<dbuser username> is not authorized to assume IAM Role arn:aws:iam::<account-id>:role/<Role name>

L'erreur « 403 Access Denied » (403 Accès refusé)

[Amazon](500310) Invalid operation: S3ServiceException:Access Denied,Status 403,Error AccessDenied,

Remarque : utilisez la commande UNLOAD avec l'instruction SELECT lorsque vous déchargez des données vers votre compartiment S3. Déchargez les données textuelles dans un format délimité ou à largeur fixe (quel que soit le format de données utilisé lors du chargement). Vous pouvez également spécifier si un fichier gzip compressé doit être classé.

La destination de déchargement spécifiée sur S3 n'est pas vide

ERROR: Specified unload destination on S3 is not empty. Consider using a different bucket / prefix, manually removing the target files in S3, or using the ALLOWOVERWRITE option.

Cette erreur peut se produire lorsque vous essayez d'exécuter la même commande UNLOAD et que vous déchargez des fichiers dans le même dossier où se trouvent déjà les fichiers de données.

Par exemple, vous obtenez cette erreur si vous exécutez deux fois la commande suivante :

unload ('select * from test_unload')   
to 's3://testbucket/unload/test_unload_file1' 
iam_role 'arn:aws:iam::0123456789:role/redshift_role';

Solution

L'erreur « DB user is not authorized to assume the AWS Identity and Access Management (IAM) Role » (L'utilisateur de la base de données n'est pas autorisé à endosser le rôle AWS IAM)

Si l'utilisateur de la base de données n'est pas autorisé à endosser le rôle IAM, vérifiez les points suivants :

L'erreur « 403 Access Denied » (403 Accès refusé)

Si vous recevez une erreur « 403 Access Denied » (403 Accès refusé) de votre compartiment S3, vérifiez que les autorisations appropriées sont accordées pour vos opérations d'API S3 :

"Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",       
        "s3:List*",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::your_bucket",
        "arn:aws:s3:::your_bucket/*"
      ]
    }
  ]
}

Si vous utilisez le chiffrement côté serveur avec des clés de chiffrement gérées par S3, votre compartiment S3 chiffre chacun de ses objets avec une clé unique. Pour davantage de protection, la clé elle-même est également chiffrée à l'aide d'une clé racine qui est changée régulièrement.

Afin de chiffrer les données au repos déchargées, vérifiez que le paramètre s3:x-amz-server-side-encryption de votre politique de compartiment S3 est défini sur « true » (vrai) :

"Condition": {
   "Null": {
           "s3:x-amz-server-side-encryption": "true"
           }

Vérifiez que KMS_KEY_ID est chiffré afin de pouvoir utiliser la commande UNLOAD pour décharger les données chiffrées vers votre compartiment S3 :

unload ('select * from a') to 's3://mybucket/test/varchar/' iam_role 'arn:aws:iam::xxxxxx:role/RedshiftS3Access' ALLOWOVERWRITE CSV
KMS_KEY_ID '11111111111111111111111111'
encrypted;

Si votre compartiment S3 est chiffré avec une clé racine d'AWS Key Management Service (AWS KMS), ajoutez les autorisations suivantes à votre politique IAM :

"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]

La destination de déchargement spécifiée sur S3 n'est pas vide

L'erreur spécifiant que la destination de déchargement spécifiée sur S3 n'est pas vide se produit si vous essayez d'utiliser la commande UNLOAD pour décharger des fichiers dans un dossier où le même nom de fichier existe déjà.

Utilisez l'une des options suivantes afin de résoudre l'erreur :

  • Création d'un nouveau compartiment Amazon S3 ou utilisation d'un autre compartiment S3
  • Modification du préfixe de clé S3
  • Nettoyage des fichiers présents dans le compartiment Amazon S3 de destination
  • Utilisation de l'option ALLOWOVERWRITE avec la commande UNLOAD

Création d'un nouveau compartiment Amazon S3 ou utilisation d'un autre compartiment S3

1.    Créez un nouveau compartiment S3 ou identifiez un autre compartiment S3 existant.

2.    Mettez à jour la politique de compartiment de votre compartiment S3 pour votre compartiment existant ou nouvellement créé. L'exemple de politique suivant doit être ajouté en tant que politique d'autorisations :

{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "ExampleStatement01",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::0123456789:user/<UserName>"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::testbucket/*",
                "arn:aws:s3:::testbucket",
                "arn:aws:s3:::testbucket2/*",  --> Additional permission for new bucket
                "arn:aws:s3:::testbucket2"       
            ]
        }
    ]
}

3.    Utilisez le nouveau chemin de compartiment dans la commande UNLOAD. Dans l'exemple suivant, s3://testbucket2/unload/test_unload_file1 est le nouveau chemin de compartiment :

iam_role 'arn:aws:iam::0123456789:role/redshift_role';
unload ('select * from test_unload')   
to 's3://testbucket2/unload/test_unload_file1'

Modification du préfixe de clé S3

Modifiez le préfixe de clé de compartiment S3 dans le chemin S3 lorsque vous utilisez la commande UNLOAD. Dans l'exemple suivant, unload2 est le préfixe modifié :

iam_role 'arn:aws:iam::0123456789:role/redshift_role';
unload ('select * from test_unload')   
to 's3://testbucket/unload2/test_unload_file1'

Pour plus d'informations, veuillez consulter la section Organisation des objets à l'aide de préfixes.

Nettoyage des fichiers présents dans le compartiment Amazon S3 de destination

Utilisez l'option CLEANPATH afin de supprimer les fichiers existants situés dans le chemin Amazon S3 spécifié dans la clause TO avant de décharger les fichiers vers l'emplacement spécifié. Si vous incluez la clause PARTITION BY, les fichiers existants sont supprimés uniquement des dossiers de partition. Cela permet au compartiment Amazon S3 de recevoir de nouveaux fichiers générés par l'opération UNLOAD.

Important : les fichiers supprimés à l'aide de l'option CLEANPATH sont définitivement supprimés et ne peuvent pas être récupérés.

Afin d'utiliser l'option CLEANPATH, vous devez disposer de l'autorisation s3:DeleteObject sur le compartiment Amazon S3. L'exemple de politique suivant doit être ajouté en tant que politique d'autorisations :

{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "ExampleStatement01",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::0123456789:user/<UserName>"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:DeleteObject"  --> Additional Action added for delete object
            ],
            "Resource": [
                "arn:aws:s3:::testbucket/*",
                "arn:aws:s3:::testbucket"
            ]
        }
    ]
}

Remarque : vous ne pouvez pas spécifier l'option CLEANPATH si vous spécifiez l'option ALLOWOVERWRITE.

Utilisation de l'option ALLOWOVERWRITE avec la commande UNLOAD

La commande UNLOAD échoue si elle trouve des fichiers qu'elle risque de remplacer. Si l'option ALLOWOVERWRITE est spécifiée, la commande UNLOAD remplace les fichiers existants, y compris le fichier manifeste. Dans l'exemple suivant, les fichiers précédents sont remplacés et le compartiment est mis à jour avec les nouveaux enregistrements.

iam_role 'arn:aws:iam::0123456789:role/redshift_role' allowoverwrite;
unload ('select * from test_unload')   
to 's3://testbucket/unload/test_unload_file1'

Afin d'utiliser l'option ALLOWOVERWRITE, vous devez disposer de l'autorisation s3:PutObject sur le compartiment Amazon S3. L'exemple de politique suivant doit être ajouté en tant que politique d'autorisations :

{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "ExampleStatement01",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::0123456789:user/<UserName>"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:PutObject"  --> Additional Action added for overwriting objects
            ],
            "Resource": [
                "arn:aws:s3:::testbucket/*",
                "arn:aws:s3:::testbucket"
            ]
        }
    ]
}