DynamoDB Scan无执行反馈求助:云端运行仅输出初始日志
为修复数据问题,我们通过扫描DynamoDB表执行重加密操作,代码如下:
var tableName = dynamoDbMapperProvider.getTableName(DynamoSnapshot.class, address); log("Starting re-encryption for table " + tableName); int migratedSnapshotsCount = 0; for (var snapshot : dynamoDBMapper.scan(DynamoSnapshot.class, snapshotScanExpression)) { if (snapshot.getEncryptedKey() != null) { try { encryptionService.decrypt( EnvelopeMessage.of(snapshot.getBinaryData(), snapshot.getEncryptedKey(), snapshot.getCmkId()) ); // decryption okay so just set Cmk to configured value as a side-effect... log("Updating CmkId for " + snapshot.getRootId()); dynamoDBMapper.save(snapshot.withCmkId(cmkId)); } catch (EncryptDecryptException ex) { if (ex.isKmsError()) { // ... reencrypt and log... migratedSnapshotsCount++; } } } } log( "Re-encrypt encrypted key process completed for table " + tableName + ", " + migratedSnapshotsCount + " Snapshots migrated and re-encrypted." );
该程序运行在云端无法本地调试,预期至少输出两条日志,但仅得到循环前的第一条日志,后续无任何日志与异常输出,可能的原因如下:
DynamoDB扫描操作阻塞或无限挂起
DynamoDB的scan操作默认分页处理数据,若表数据量极大、网络波动、KMS服务限流,或者SDK内部重试机制陷入循环,会导致扫描请求长时间卡住,循环根本无法进入。另外,若snapshotScanExpression配置了不合理的参数(比如错误的过滤条件、无限扫描范围),也会让SDK一直等待数据,程序停在循环启动前的阶段。循环体无符合条件的执行分支
代码中通过if (snapshot.getEncryptedKey() != null)过滤条目,如果表中所有DynamoSnapshot对象的encryptedKey均为null,循环内部的代码完全不会执行。这种情况下程序会正常走完循环,输出最后一条日志,但如果结合日志配置问题,最后一条日志可能被过滤,导致看起来后续无输出。云端日志配置异常
若云端环境的日志级别配置过高(比如仅输出INFO级,但循环内日志为DEBUG级),后续日志会被过滤,无法输出到日志系统。另外,如果日志输出目的地配置错误,或者日志框架采用异步输出但程序崩溃前未完成日志刷写,也会导致后续日志丢失。循环内发生未捕获异常导致程序静默崩溃
代码仅捕获了EncryptDecryptException,但循环内可能出现其他未捕获的运行时异常:比如snapshot.getRootId()返回null时拼接日志字符串会抛出NullPointerException,或者dynamoDBMapper.save()抛出其他未处理的异常。若云端环境未正确采集异常日志,程序会直接终止,既不会继续执行,也不会输出异常信息。DynamoDB权限配置问题
若程序所在IAM角色对目标表的权限不足(比如仅有扫描权限但无数据读取权限),scan方法会返回空结果集,循环不会执行。这种情况下程序会正常输出最后一条日志,但如果日志配置异常导致最后一条日志无法显示,就会出现仅看到初始日志的现象。
内容的提问来源于stack exchange,提问作者J. Wong

