Azure Synapse: Не удается выполнить массовую загрузку, так как файл не удалось открыть. Код ошибки операционной системы 12(Код доступа неверен.)

#azure #azure-synapse #azure-data-lake-gen2

Вопрос:

Я использую Azure Synapse для запроса большого количества CSV-файлов с OPENROWSET помощью команды см. Здесь. Файлы расположены в озере данных поколения 2, подключенном к Azure Synapse через управляемую идентификацию.

Это работает нормально, когда я запрашиваю только несколько файлов одновременно, однако, когда я увеличиваю количество файлов, которые я пытаюсь запросить одновременно, я получаю следующую ошибку:

 Azure Synapse: Cannot bulk load because the file <file> could not be opened. Operating system error code 12(The access code is invalid.)
 

Вот <file> другой файл каждый раз, когда я выполняю запрос. Если я перейду к файлу в представлении связанных данных, я смогу загрузить и просмотреть файл. Также, если я укажу, чтобы выполнить запрос к файлу, упомянутому ранее в ошибке, он будет работать нормально.

Код, который я использую для запроса к озеру данных, приведен ниже:

 SELECT
            Parsed.*
            FROM OPENROWSET
            (
                bulk '2021/*/**.log',
                maxerrors = 2147483647,
                data_source = 'analytics',
                format = 'csv',
                fieldterminator ='0x0b',
                fieldquote = '0x0b'
            ) WITH (doc nvarchar(max)) AS Rows
            CROSS APPLY OPENJSON(Rows.doc)
            WITH
                (
                    col1 NVARCHAR(100),
                    col2 NVARCHAR(100),
                    ...,
                    coln NVARCHAR(MAX)
                ) AS Parsed
 

Здесь источником данных является analytics источник данных, указанный следующим образом:

     CREATE EXTERNAL DATA SOURCE analytics
        WITH
        (
            location = 'https://<url>.dfs.core.windows.net/analytics'
        )
 

Я попытался указать большое число для MAXERRORS параметра для BULK in OPENROWSET , так как я не возражаю, если при выполнении этого запроса будет пропущено только несколько файлов, однако это, похоже, работает только на уровне строк для ошибок, и эти ошибки находятся на уровне файлов.

Запрос выполняется здесь во встроенном бессерверном пуле.

Любые идеи о том, как обойти эту проблему, будут оценены по достоинству.

Ответ №1:

Ваш код выполняет сквозную аутентификацию в хранилище для любого пользователя AAD, подключенного к Synapse без сервера (что приведет к сбою, если вы используете логин SQL). Чтобы использовать MSI для подключения к хранилищу, вам потребуются учетные данные с областью действия базы данных, и вам нужно будет ссылаться на них во внешнем источнике данных, как в этом примере.

 
-- Optional: Create MASTER KEY if not exists in database:
-- CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Very Strong Password>
CREATE DATABASE SCOPED CREDENTIAL SynapseIdentity
WITH IDENTITY = 'Managed Identity';
GO
CREATE EXTERNAL DATA SOURCE mysample
WITH (    LOCATION   = 'https://<storage_account>.dfs.core.windows.net/<container>/<path>',
          CREDENTIAL = SynapseIdentity
)

 

Также ознакомьтесь с разделами этой статьи о брандмауэре в вашей учетной записи хранилища, если она заблокирована.

Ответ №2:

Просто добавляю быстрый ответ на этот вопрос. После внесения изменений, которые предложил Грег, я смог запросить немного больше данных, но все равно получил код ошибки 12.

Я поговорил со службой поддержки Azure, и они сообщили мне, что сообщение об ошибке на самом деле было 412 (но мне оно было недоступно); таким образом, это подразумевало, что файл используется/изменяется. Добавление следующего позволило синапсу Azure игнорировать это и запрашивать файл независимо от того,:

 ROWSET_OPTIONS = '{"READ_OPTIONS":["ALLOW_INCONSISTENT_READS"]}'
 

или для внешних таблиц:

 TABLE_OPTIONS = N'{"READ_OPTIONS":["ALLOW_INCONSISTENT_READS"]}'
 

Это сделало мой последний вопрос:

 SELECT
        Parsed.*
        FROM OPENROWSET
        (
            bulk '2021/*/**.log',
            maxerrors = 2147483647,
            data_source = 'analytics_master_key',
            format = 'csv',
            fieldterminator ='0x0b',
            fieldquote = '0x0b',
            ROWSET_OPTIONS = '{"READ_OPTIONS":["ALLOW_INCONSISTENT_READS"]}'
        ) WITH (doc nvarchar(max)) AS Rows
        CROSS APPLY OPENJSON(Rows.doc)
        WITH
            (
                col1 NVARCHAR(100),
                col2 NVARCHAR(100),
                ...,
                coln NVARCHAR(MAX)
            ) AS Parsed