четверг, 4 июня 2009 г.

Причина ошибки Timeout Expiried при загрузке файла. Часть 2.

Начало данной темы было положено исследованиями http://dvprofessionals.blogspot.com/2009/03/timeout-expired-sql-server-2008.html. Хочу добавить, что отключение статистики полностью, может снизить производительность.

В последнее время было выявлено еще несколько подобных случаев, причем не только на SQL 2008, а и на SQL 2005.

Если вы встретились с данной ошибкой прежде всего нужно определить является ли сбор статистики причиной.

В момент загрузки файла выполните процедуру

SELECT
tr.[transaction_id]
,DATEDIFF(minute, tr.[transaction_begin_time], GETDATE()) [duration]
,req.[command]
,req.[blocking_session_id]
,txt.[text]
,sess.[host_name]
,sess.[program_name]
,sess.[login_name]
,sess.[login_time]
FROM sys.dm_tran_active_transactions tr
JOIN sys.dm_exec_requests req ON req.[transaction_id] = tr.[transaction_id] JOIN sys.dm_exec_sessions sess ON sess.[session_id] = req.[session_id] OUTER APPLY sys.dm_exec_sql_text(req.[sql_handle]) txt WHERE
req.[session_id] > 50
AND tr.[transaction_begin_time] < DATEADD(minute, -1, GETDATE()) ORDER BY [duration] DESC

которая возвращает длительные транзакции. Нужно вызывать до тех пор, пока не будет возвращен результат

Если в резуальтате запроса будет строка
SELECT StatMan([SC0], [SB0000]) FROM (SELECT TOP 100 PERCENT [SC0], step_direction([SC0]) over (order by NULL) AS [SB0000] FROM (SELECT CONVERT([varbinary](200), SUBSTRING ([Data], 1, 100)++substring([Data], case when LEN([Data])<=200 then 101

Следовательно сбор статистики включен.

В первую очередь нужно отключить сбор статистики на конкретной таблице:
EXEC sp_autostats 'dbo.dvsys_binaries', 'OFF'

Если отключение не помогло, то выполните запрос для удаления собранной статистической информации.

DECLARE @Cmd nvarchar(4000)
DECLARE @ObjectName sysname
DECLARE @StatName sysname

SET @ObjectName = '[dbo].[dvsys_binaries]'

DECLARE StatCursor CURSOR FAST_FORWARD FOR
SELECT name
FROM sys.stats
WHERE
object_id = OBJECT_ID(@ObjectName)
AND auto_created = 1

OPEN StatCursor
FETCH NEXT FROM StatCursor INTO @StatName

WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @Cmd = N'DROP STATISTICS ' + @ObjectName + N'.[' + @StatName + N']'
EXEC [dbo].[sp_executesql] @Cmd

FETCH NEXT FROM StatCursor INTO @StatName END

CLOSE StatCursor
DEALLOCATE StatCursor


И следующий запрос

DECLARE @Rtn int
DECLARE @Cmd nvarchar(4000)
DECLARE @ObjectName sysname
DECLARE @StatName sysname

SELECT
@ObjectName = 'dbo.dvsys_binaries'
,@Rtn = 0

DECLARE StatCursor CURSOR FAST_FORWARD FOR
SELECT name
FROM sys.stats
WHERE
object_id = OBJECT_ID(@ObjectName)
AND auto_created = 1

OPEN StatCursor
FETCH NEXT FROM StatCursor INTO @StatName

WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @Cmd = N'UPDATE STATISTICS ' + @ObjectName + N'(' + @StatName + N') WITH SAMPLE 0 ROWS, NORECOMPUTE'

PRINT 'Updating statistics ' + @StatName

EXEC @Rtn = [dbo].[sp_executesql] @Cmd

IF @Rtn <> 0 BREAK

FETCH NEXT FROM StatCursor INTO @StatName
END

CLOSE StatCursor
DEALLOCATE StatCursor

IF @Rtn <> 0
BEGIN
RAISERROR('Unable to update statistics, error: %d', 10, 1, @Rtn)
END

Обращаю внимание, что проблема еще полностью не изучена. Проверку всегда нужно проводить имея под рукой свежий бекап.

2 комментария:

  1. У меня симптомы именно такие, но все приведенные рекомендации (в том числе и из первой части) не помогли. Зато помогло отключение "auto update statistics" на базе данных в целом (что у нас было отключено и в 2005м SQL).
    p.s. sp_autostats включает/выключает авто-обновление (а не сбор) статистики по отдельной таблице.

    ОтветитьУдалить
  2. вдогонку - отключение автообновления статистики на производительность влияет, но незначительно - у нас обновление статистики запускается регулярно, по ночам, планом обслуживания. "ведущие собаководы" наоборот рекомендуют отключать автообновление, т.к. оно может запускаться в самое неожиданное, в том числе и рабочее время и сильно снижать производительность.

    ОтветитьУдалить