使用PolyBase从Azure StorageV2的Parquet文件创建外部表遇报错求助
问题描述
目标是从Azure存储容器中的Parquet文件创建PolyBase外部表,环境信息如下:
- SQL Server 2019 (RTM-CU22-GDR) (KB5029378) - 15.0.4326.1 (X64)
- Azure存储类型:StorageV2(通用v2,LRS)
- Parquet文件由parquet-cpp-arrow version 4.0.0从SQL Server导出
- SAS令牌已通过PowerShell验证,上传下载、有效期、权限均无问题
执行创建外部表的代码后,查询时出现以下错误:
Msg 596, Level 21, State 1, Line 40
Cannot continue the execution because the session is in the kill state.
Msg 0, Level 20, State 0, Line 40
A severe error occurred on the current command.
The results, if any, should be discarded.
排查与解决思路
- 修正外部数据源类型:针对Azure Blob Storage,SQL Server 2019的PolyBase需使用
TYPE = BLOB_STORAGE而非HADOOP。HADOOP类型适配HDFS等分布式文件系统,错误的类型配置会直接导致会话崩溃。 - 核对凭据配置:
- 若使用SAS令牌,需将
IDENTITY设为SHARED ACCESS SIGNATURE,SECRET填入不带开头?的完整SAS令牌;若使用存储账户密钥,IDENTITY为存储账户名,SECRET为账户密钥,确保配置与实际认证方式一致。 - 确认SAS令牌包含
Read权限,且路径范围覆盖目标容器及文件。
- 若使用SAS令牌,需将
- 验证Parquet文件兼容性:
- 确认文件字段类型、顺序与外部表定义完全匹配,例如
CityID是否为INT类型,CityName是否对应Parquet字符串类型,类型不匹配会引发解析崩溃。 - 检查文件完整性,避免导出过程中出现的截断或损坏。
- 确认文件字段类型、顺序与外部表定义完全匹配,例如
- 检查PolyBase服务状态:
- 确保SQL Server PolyBase Engine和SQL Server PolyBase Data Movement Service已启动并正常运行。
- 执行
SELECT SERVERPROPERTY('IsPolyBaseInstalled')验证PolyBase功能是否启用,返回1表示已启用。
修正后的示例代码
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<MyMasterKey>'; GO -- SAS令牌凭据配置示例 CREATE DATABASE SCOPED CREDENTIAL ArchiveCredential WITH IDENTITY = 'SHARED ACCESS SIGNATURE', SECRET = '<MySASTokenWithoutLeadingQuestionMark>'; GO -- 存储账户密钥凭据配置示例(若使用账户密钥) -- CREATE DATABASE SCOPED CREDENTIAL ArchiveCredential -- WITH IDENTITY = '<MyStorageAccount>', -- SECRET = '<MyAccountKey>'; -- GO CREATE EXTERNAL DATA SOURCE ArchiveDataSource WITH ( LOCATION = 'wasbs://<MyContainer>@<MyStorageAccount>.blob.core.windows.net/', CREDENTIAL = ArchiveCredential, TYPE = BLOB_STORAGE -- 关键修正 ); GO CREATE EXTERNAL FILE FORMAT ArchiveFormat WITH ( FORMAT_TYPE = PARQUET, DATA_COMPRESSION = 'org.apache.hadoop.io.compress.SnappyCodec' -- 文件使用Snappy压缩时需指定,否则可省略 ); GO CREATE EXTERNAL TABLE CitiesArchive ( CityID INT NOT NULL, CityName VARCHAR(50) NOT NULL ) WITH ( LOCATION = 'parquet/CitiesArchive.parquet', -- 移除开头的/,避免路径解析问题 DATA_SOURCE = ArchiveDataSource, FILE_FORMAT = ArchiveFormat ); GO SELECT CityID, CityName FROM CitiesArchive; GO
内容的提问来源于stack exchange,提问作者Eric Russell
相关产品推荐
相关产品推荐

