![]() | |
Причина ошибки Timeout expired при загрузке файла, база на SQL Server 2008Источник: dvprofessionals Михаил Захаров
База данных внутреннего сервера DocsVision переводилась на новую машину. С Microsoft SQL Server 2005 32bit на Microsoft SQL Sever 2008 64 bit. В журнале 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 появляется ошибка превышения таймаута при загрузке файла (создании карточки файла), то попробуйте отключить ведение статистики. |