БД SQL Server становится недоступной в одночасье

9

Вчера моя база данных SQL Server была в порядке. Сегодня он практически непригоден для использования - он замедляется в пять-двадцать раз, в зависимости от того, когда я его ударил.

Некоторые данные были добавлены на сервер в процессе ночной загрузки, но ничего, кроме тома, который не должен сильно влиять на базу данных. Около 50000 простых текстовых записей (без XML или других фрипперов).

Сервер был исправлен этим утром, прежде чем мы перезагрузили его. Однако ни один из наших других серверов баз данных, которые также были исправлены, не ведет себя по-другому.

Казалось бы, Resource Monitor предполагает, что его дисковый ввод-вывод виноват. Он работает почти на 100% от емкости файла .mdf все время, даже если в базе данных ничего особенного не происходит. Доступ к Templog.ldf также работает довольно высоко.

Никто здесь не является опытным администратором баз данных (мы все разработчики с разным количеством навыков SQL), и мы все сбиты с толку тем, что произошло. Мы попытались запустить sp_updatestats и переместить некоторые большие индексы на разные диски, но безрезультатно.

Я думаю, что это как-то связано с патчем - кажется, слишком много совпадений. Коллега убежден, что из-за загрузки данных размер mdf увеличился до такой степени, что планы выполнения стали неэффективными.

Что на земле вызвало это? Как мы можем узнать, и что мы можем сделать, чтобы это исправить?

РЕДАКТИРОВАТЬ:

Использование не sp_WhoIsActiveпоказывает ничего необычного. Он регистрирует мое собственное использование sproc и некоторых команд от коллеги, который в настоящее время пытается переместить другой индекс. Это, вероятно, сдерживает БД прямо сейчас, но раньше она работала так же плохо.

Это стандартная версия SQL Server 2008 R2. SELECT @@VERSIONдает:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4033.0 (X64)
9 июля 2014 г. 16:04:25
Авторское право (c) Microsoft Corporation Standard Edition (64-разрядная версия) в Windows NT 6.1 (сборка 7601: пакет обновления 1) (гипервизор) )

Сервер имеет 72 ГБ оперативной памяти и три четырехъядерных процессора по 2 ГГц.

Исправление было применено только к Windows. Не было никаких изменений, кроме патча.

Выбранные настройки:

_id     name                        value   minimum     maximum     value_in_use    description                                 is_dynamic  is_advanced
1540    min memory per query (KB)   1024    512         2147483647  1024            minimum memory per query (kBytes)           1           1
1541    query wait (s)              -1      -1          2147483647  -1              maximum time to wait for query memory (s)   1           1
1543    min server memory (MB)      0       0           2147483647  16              Minimum size of server memory (MB)          1           1
1544    max server memory (MB)      65536   16          2147483647  65536           Maximum size of server memory (MB)          1           1

ОБНОВЛЕНИЕ: Перенос индексов и таблиц на разные разделы диска, кажется, улучшает ситуацию. Я до сих пор не понимаю, как мы могли так неожиданно достичь такого переломного момента.

Боб Твей
источник
Можете ли вы запустить sp_whoisactive в течение 5 минут и записать вывод в таблицу. Вы можете скачать его отсюда, и это покажет, как вы можете записать вывод в таблицу
Кин Шах
Что ж, если вы перезапустили сервер, это означает, что все ваши кэшированные данные были выгружены из пула буферов, и все ваши кэшированные планы выполнения также были сброшены. Это означает, что SQL Server придется увеличить оба этих параметра - каждый план выполнения придется перекомпилировать, и если статистика устарела, вы можете не получить наиболее эффективные планы. Это также означает, что данные должны будут считываться в память с диска, тогда как до перезапуска они, вероятно, гудели вместе с данными в памяти. Это должно быть недолгим.
Аарон Бертран
@AaronBertrand Так было уже восемь часов. Мы регулярно перезагружаем сервер для установки исправлений и никогда раньше не замечали ничего подобного.
Боб Tway
1
Не используйте пользовательский интерфейс для проверки настроек конфигурации. SELECT * FROM sys.configurations;- Вы хотите, value, value_in_useчтобы такие вещи, как max server memory (MB). Также SELECT @@VERSION;будет полезен номер сборки in , а также то, находится ли он в гипервизоре, и если что-то изменилось на хосте со вчерашнего дня (или со времени последнего перезапуска SQL Server).
Аарон Бертран
2
Какой тип подсистемы ввода-вывода вы используете? SAN, локальный диск и т. Д.? Есть ли вероятность того, что у вас случайно получилось плохо? Также хранятся ли ваши БД в том же месте, что и файлы ОС? И последний вопрос. Частью нашего процесса перед обновлением ОС было заранее сделать снимок виртуальной машины. К сожалению, ответственное лицо забыло совершить это. Очень быстро вся система становилась все медленнее и медленнее. Есть ли шанс, что это случилось с вами?
Кеннет Фишер

Ответы:

3

Может случиться, что небольшой объем данных достигает определенного предела в SQL Server, чтобы заставить другой план или что-то в этом роде. Это не исключено. Но тот факт, что ваш диск, кажется, находится под большой нагрузкой, приводит меня к другому выводу.

Есть 2 возможных базовых причины вашего замедления.

  1. Вы обновили свою систему и перезагрузили ее
  2. Вы загружаете кучу данных в нем

Давайте посмотрим на часть № 1

Возможно, ваша конфигурация SQL Server нарушена. Это может вызвать серьезные проблемы, связанные со скоростью вашего сервера и использованием диска.

Пожалуйста, проверьте сначала ваши основные настройки сервера. Эти основные параметры max server memory, affinity I/O mask, affinity maskи max degree of parallelism. Возможно, вам придется включить дополнительные параметры, используя show advanced options.

Вот полный сценарий:

-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'

Сравните результат с вашими документированными значениями на ваших этапах установки. Они все такие же?

У этого может быть много причин, почему ваш сервер ведет себя так странно. Я бы обычно поспорил, что ты max server memoryпросто неправ. Это приведет к тому, что ваш SQL Server будет постоянно менять страницы данных. Он не может держать все в своей памяти. Это означает, что ему нужно читать страницы с диска, обновлять его, мгновенно записывать обратно. Если другое обновление приходит и использует ту же страницу для обновления, оно не может быть прочитано из памяти. Вместо этого сервер должен снова прочитать его с диска. Просто поменяться ...

Другой проблемой может быть высокая аффинность к диску или процессам. Если вы использовали общий сервер (SQL Server + другие службы) с выделенным диском для SQL Server (что может быть редким, но может быть), это может быть вашей проблемой. Ваш сервер обычно имел, например, 3 процессора для процессов и один для ввода-вывода. Остальные 12 процессоров используются для других услуг. В этом случае ваша маска соответствия неверна и использует, например, автоматическую настройку. Это означает, что ваш сервер использует все 16 ядер для процессов и динамического ввода-вывода. Если у вас запущены огромные процессы, они могут создать огромную нагрузку на диск, который он может не обработать. Но на самом деле я не верю, что это ваш случай. Было бы быстрее (даже если немного), если это применимо, но ваш случай замедляется.

Другой проблемой может быть слишком высокая степень параллелизма. Это означает, что у вас слишком много потоков, работающих вхолостую в одной части запроса. Это также может привести к значительному замедлению, если параллелизм не будет работать, как ожидалось. Но это не будет описывать ваш высокий I / O в целом.

Теперь давайте посмотрим на часть № 2 тоже

Вы загружаете кучу строк в вашу систему. Даже если это обычная работа, она может повысить предел, в котором возрастают ваши планы запросов. Может даже случиться, что ваша вставка в сочетании с SQL Server вызывает такое поведение.

Вы упомянули, что вы уже пытались перенести свои индексы на другой диск, что, похоже, помогает. Это может случиться только с тем фактом, что вы распределяете нагрузку на два разных диска.

Возможно, что ваши показатели были сломаны, что ваши планы были сломаны или что ваша статистика просто устарела.

1. давайте проверим статистику последнего обновления. Вы можете сделать это вручную через интерфейс для каждого отдельного элемента статистики. Что было бы болью. Или вы можете попробовать этот код:

SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes

Это даст вам полную информацию по каждому индексу (и куче) и статистику за ними. Даже если вы запустите, sp_updatestatsэто не значит, что статистика была обновлена. Часть, когда обновление довольно сложное, даже если вы запускаете sp_updatestatsили даже если auto update statisticsоно включено, статистика не будет обновляться вовремя. Вот некоторые крайние точки, когда требуется / генерируется обновление:

  • Пустая таблица получает одну или несколько строк
  • Таблица с более чем 500 строками обновляет 20% + 500 дополнительных строк, и вставка произошла впоследствии
  • Когда 500 строк были изменены в таблице, которая содержит менее 500 строк

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

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

UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN

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

DBCC FREEPROCCACHE 

Если вы просто хотите очистить все кэши, вы можете запустить это вместо:

DBCC FREESYSTEMCACHE ('ALL')

Это очистит все кеши, а не только кеш плана. Я обычно предупреждаю, чтобы использовать это на производственном сервере в фазе производства. Но так как ваш сервер в настоящее время не работает, вы не можете причинить им слишком много вреда. Это может замедлиться на несколько секунд, может быть на 1-2 минуты, поскольку ему нужно восстановить все кэши, но после этого он должен работать с правильными планами.

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

SELECT * 
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)

Если фрагментация очень высока, вам может потребоваться ее реорганизация (фрагментация <20%) или полная перестройка (> 20%). Это может оказать большее давление на ваш диск и вызвать проблемы. С другой стороны, если индексы настолько плохи, это, вероятно, поможет в итоге больше, чем нанесет вред.

Помимо этих двух причин, все еще может быть третья проблема

Возможно, ваш сервер настроен, возможно, вы не изменили никакого кода за это время, просто добавили несколько строк. Вся статистика обновляется и все кеши перестраиваются. Все ваши индексы реорганизованы так, как вам нужно, но все равно - ничего не работает. Возможно, вы достигли предела доступной памяти в своих процессах. Может быть, вам нужно больше. Вы можете просто проверить, существует ли какой-либо процесс, который пытается получить больше памяти, чем у вас.

Вы можете проверить это с помощью этой команды:

SELECT * FROM sys.dm_exec_query_memory_grants

Он предоставит вам список всех сессий, которые занимают память. Может быть какой-то запрос, который все еще ожидает получения памяти. Эти запросы могут быть легко отфильтрованы. Все сеансы где granted_memory_kb IS NULL. Это сеансы, которые запрашивают память, но не получают ее. Другая вещь может быть предоставленной памятью, которая может быть слишком низкой. Вы можете сравнить столбцы requested_memory_kbс granted_memory_kb. Запрошенный показывает, сколько памяти необходимо для оптимальной работы процесса, в то время как предоставленный показывает память, которая включена для процесса. Если процессу требуется 2 ГБ для запуска, но только 2 МБ ... вы можете получить его самостоятельно. ;-)

Другой способ - проверить RESSOURCE_SEMAPHORE:

SELECT * FROM sys.dm_exec_query_resource_semaphore

Вы можете взглянуть на waiter_countи grantee_count. Если официант выше 0, у вас есть давление на вашу память, что может привести к обмену и может вызвать давление диска, замеченное вами в perfmon.

ионный
источник
0

Помимо возможных сбоев дисков, проверьте состояние вашей подсистемы RAID. Мы увидели нечто подобное, и оказалось, что батарея на контроллере RAID вышла из строя, поэтому кэш записи не был доступен - все записи должны были идти непосредственно на диск. Одно замечание - мы могли чувствовать паузу в системе, пока RDC входил в нее.

Уильям Дженс
источник