среда, 11 марта 2009 г.

Причина ошибки Timeout expired при загрузке файла, база на SQL Server 2008

База данных внутреннего сервера DocsVision переводилась на новую машину. С Microsoft SQL Server 2005 32bit на Microsoft SQL Sever 2008 64 bit.
После перевода обнаружено следующее поведение. При добавлении файла любого размера в карточку возникает ошибка Timeout expired.

В журнале StorageServer фиксировалась следующая ошибка:

StorageServerRuntime Error: 0 : Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. Method name: StorageServer.FileWrite

Больше никаких ошибок в журналах DocsVision, и в системных журналах ОС не было. С производительностью сервера так же было все в порядке.

Детальное исследование нашим разработчиком показало, что вызов команды, которая выполняет загрузку бинарных данных в таблицу dvsys_binaries выполняется очень долго (несколько минут).

С помощью административных представлений (Dynamic Management Views) sys.dm_tran_active_transactions, sys.dm_exec_requests и sys.dm_exec_sql_text было обнаружено, что SQL Server дополнительно запускает следующий запрос:

SELECT StatMan([SC0], [LC0]) FROM ( SELECT TOP 100 PERCENT CONVERT([varbinary](200), SUBSTRING([Data], 1, 100)++ SUBSTRING([Data], CASE WHEN LEN([Data])<=200 THEN 101 ELSE LEN([Data])-99 END, 100) ) AS [SC0] ,DATALENGTH([Data]) AS [LC0] FROM [dbo].[dvsys_binaries] WITH (READUNCOMMITTED) ORDER BY [SC0] ) AS _MS_UPDSTATS_TBL

Эта команда получает первые и последние 100 байт из Data в колонку SC0, длину Data в колонку LC0 для каждой записи в dvsys_binaries, потом направляет полученные данные в функцию StatMan. Это крайне неэффективный запрос, он приводит к перечитыванию большого количества данных (в нашем случае это 11Гб). Осталось неясным, почему SQL Server 2008, при выполнении команды частичного обновления данных в BLOB-колонке для одной записи (указана по первичному ключу), запускает такой длительный запрос для анализа статистики.

Чтобы обойти проблему была выполнена команда:

EXEC sp_dboption 'MyBase', 'auto create statistics', 'false'

В результате отключено автоматическое создание статистики для нашей базы данных MyBase.

В процессе исследования проблемы были внесены следующие изменения:

1. Указан FILEGROWTH=100Mb – был 1 Мб. Столь малый показатель приводит к частым операциям по увеличению объема базы (дорогостоящая операция) и повышает общую фрагментированность данных.

2. Указан режим совместимости COMPATIBILITY_LEVEL = 100 – совместимость с форматом SQL Server 2008

Результат. Если после перевода базы на SQL Server 2008 появляется ошибка превышения таймаута при загрузке файла (создании карточки файла), то попробуйте отключить ведение статистики.

Комментариев нет:

Отправить комментарий