Добрый день, коллеги.
В сегодняшней статье мы бы хотели рассмотреть достаточно востребованную и популярную тему, как настройка планов обслуживания MS SQL Server. В результате проведения аудитов мы достаточно часто (более чем в 60 % случаев) обнаруживаем некорректности в настройке СУБД MS SQL Server, используемой для работы с продуктами фирмы «1С». Практика показывает, что эта СУБД является наиболее распространенной, поэтому в данной статье рассмотрим основные нюансы работы именно с ней.
Итак, с чего начинается настройка плана обслуживания? Конечно же с бэкапа! Первое правило DBA гласит: «Ничего не начинай делать без бэкапа». Ну и мы не будем. Давайте рассмотрим два основных варианта создания бэкапов, а точнее две модели резервного копирования, или модели восстановления (https://msdn.microsoft.com/ru-ru/library/ms189275(v=sql.120).aspx)
Восстановление по модели simple
Ваша база данных находится в SIMPLE режиме восстановления. Что это означает? Это означает, что бэкапы бывают только полные, журналы транзакций бэкапировать не нужно, производительность в этом смысле максимальная, но восстановиться можно только на точку бэкапа. Восстановление базы «на указанный момент времени» невозможно.

В целом, использование модели SIMPLE для реальных рабочих баз оправданно только в случаях исключительно высокой нагрузки и незначительности события потери данных с момента последнего бэкапа.
Кроме того, затрону сразу вопрос работы с журналом транзакций. Так как нам журнал тразакций в этом режиме восстановления не очень‑то и помощник, нет необходимости в его резервном копировании — вся информация из журнала уже ушла в бэкап. Обычно журналы в такой модели восстановления почти не растут, но иногда полезно его усекать. Например, после массового изменения данных эта операция может быть крайне полезна с точки зрения места, занимаемого журналом транзакций. Если диск с журналом переполнится — проблемы функционирования базы данных вам обеспечены.
Усечение данных может быть проведено, как стандартным мастером настройки плана обслуживания, так и с помощью несложно скрипта на T‑SQL:
DBCC SHRINKFILE (DatabaseName, 1);
GO
Этот скрипт уменьшит размер лог‑файла базы данных до начального размера (по умолчанию, чаще всего это будет 1 Мб). Однако, не стоит выполнять эту операцию постоянно. В идеале, ваши файлы не должны изменяться в размере в ходе планомерной работы, но об этом мы поговорим как‑нибудь в другой раз.
Восстановление по модели full
Давайте рассмотрим основные принципы настройки резервного копирования и управления размером журнала лога транзакций с точки зрения самого массового варианта — полной модели восстановления БД.
Полная модель восстановления отличается от простой тем, что в течение всей работы базы данных мы можем (а еще точнее — ДОЛЖНЫ!) делать бэкапы лога транзакций, тем самым обеспечивая возможность восстановления БД между точками основных бэкапов или откаты на конкретные промежутки времени функционирования базы, а также обеспечивая освобождение места в файле журнала (усечение). Если этого не делать, он будет расти постоянно до тех пор, пока однажды не заполнит все доступное ему место (либо на диске, либо до ограничения, заданного в СУБД). Последствия кажутся очевидными, и не самыми приятными.
С точки зрения наличия полных бэкапов — безусловно, минимальная граница — это как правило те же одни сутки. Разностные бэкапы базы данных — это возможность сохранить только изменения, произошедшие с момента последнего бэкапа. Это позволяет достаточно быстро и оперативно проводить резервное копирование базы данных, при этом использовать достаточно быстрое восстановление БД до нужного состояния.
Резервные копии журнала транзакций могут выполняться с нужной вам периодичностью в течение дня, подробнее чем разностное копирование БД. Мы рекомендуем, обычно, выбирать степень подробности копий около ¼ от времени создания разностных копий БД.
Как уже было сказано выше, при выполнении резервной копии журнала транзакций базы данных в полной модели он усечется автоматически (только не путайте усечение со сжатием!).
Пересчет статистики и работа с индексами
Достаточно ошибочной является сложившаяся практика работы с индексами и статистикой у наших клиентов. Очень часто мы сталкиваемся вообще с полным отсутствием этих процедур в планах обслуживания баз данных. Часто они выполняются в неправильном порядке. Часто просто неоптимально (например, одновременно!).
Правильная последовательность действий выглядит так:
- Определяем степень фрагментированности индекса
-
Если индекс маленький или мало фрагментирован, запускаем процедуру реорганизации индекса и пересчета статистики.
-
В противном случае запускам процедуру перестроения индекса. Процедура перестроения индекса фактически приведет к обновлению статистики, поэтому пересчитывать статистику после полного перестроения индекса не нужно.
- Пересчитываем всю остальную статистику, где это требуется.
Если рассмотреть мини‑скрипт для пересчета статистики и перестроения индексов (не претендуем на супер полноту и универсальность), то выглядеть он будет примерно так (с перебором индексов через курсор):
DECLARE @SQL NVARCHAR(MAX)
DECLARE @MIN_IND_SIZE integer = 128
DECLARE @MIN_FRAGMENTATION_LEVEL integer = 10
DECLARE @CRITICAL_FRAGMENTATION_LEVEL integer = 30
DECLARE currentIndex CURSOR LOCAL READ_ONLY FORWARD_ONLY FOR
SELECT ‘ALTER INDEX [‘ + ind.name + N’] ON [‘ +
SCHEMA_NAME(obj.[schema_id]) + ‘].[‘ + obj.name + ‘] ‘ +
CASE WHEN stat.avg_fragmentation_in_percent > @CRITICAL_FRAGMENTATION_LEVEL
THEN ‘REBUILD WITH (SORT_IN_TEMPDB = ON, ONLINE = ON)’
ELSE ‘REORGANIZE’
END + ‘;’
FROM (
SELECT stat.[object_id], stat.index_id,
avg_fragmentation_in_percent = MAX(stat.avg_fragmentation_in_percent)
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, ‘DETAILED’) stat
WHERE stat.page_count > @MIN_IND_SIZE AND stat.index_id > 0
AND stat.avg_fragmentation_in_percent > @MIN_FRAGMENTATION_LEVEL
GROUP BY stat.[object_id], stat.index_id
) stat
JOIN sys.indexes ind WITH(NOLOCK) ON stat.[object_id] = ind.[object_id]
AND stat.index_id = ind.index_id
JOIN sys.objects obj WITH(NOLOCK) ON obj.[object_id] = stat.[object_id]
OPEN currentIndex
FETCH NEXT FROM currentIndex INTO @SQL
WHILE @@FETCH_STATUS = 0 BEGIN
print @sql
EXEC sys.sp_executesql @SQL
FETCH NEXT FROM cur INTO @SQL
END
CLOSE currentIndex
DEALLOCATE currentIndex
Обратите внимание на использование tempdb, а также на сохранение индекса доступным во время перестроения — в зависимости от редакции вашей СУБД последняя функция может быть недоступна.
Уведомления
Кроме всех технических аспектов, очень правильно настраивать такие планы обслуживания, которые при некорректном выполнении все‑таки уведомят вас о произошедшей беде. И это будет самый короткий абзац в моей статье. 
Если вам все показалось слишком сложным, или вы не уверены в том, что можете сделать подобные настройки самостоятельно — не стесняйтесь, обращайтесь к нам— мы поможем!
MAPATNK2
02.07.18
✎
10:08
Добрый день, посдкажите пожалуйста, месяц назад перестал выполняться план обслуживания, после долгих поисков выяснилось, что перестроение индекса в 1 из баз не выполняется, (выполняется вечно не завершаясь).
В чем может быть проблема? Т.к. задание не завершается в логах ничего нет и в журнале тоже. Все базы перестаривают индекс, именно рабочая не хочет. Sql 2016
MAPATNK2
02.07.18
✎
10:09
База Упп весит не более 3 ГБ
MAPATNK2
02.07.18
✎
10:13
Работало больше года, вдруг перестало. Может можно как-то проверить почему не работает перестроение, скрипт, отчет. Может есть у кого готовый скрипт для перестроения индекса. Сам боюсь по материалам открытых источников писать, не системный администратор, опыта с SQL ещё мало, вдруг что повредится.
Галахад
02.07.18
✎
10:21
Хм. 3 ГБ, может просто забить? При таком размере разница, наверное незаметна.
Сияющий в темноте
02.07.18
✎
10:23
А потом вырастет,и огребут проблем
никогда не следует оставлять проблемы на завтра
вопрос-а нигде времени исполнения не указывается?
MAPATNK2
02.07.18
✎
10:26
(4) нет, т.к. если добавить в план обслуживание перестроение индекса, то план вообще перестает выполнятся. Я вывел перестроение индекса в отдельный подплан, попробовал запустить вручную, перестроение выполняется, если в нем не указана база УПП, при добавлении базы УПП в задание, оно так же перестает выполнятся.
MAPATNK2
02.07.18
✎
10:31
В задание возможно посмотреть скрипт, хотел скопировать и вставить в T-SQL. Но формирование скрипта продолжается бесконечно.
Сияющий в темноте
02.07.18
✎
10:35
Если он не формирует скрипт,то он ждет от кого-то завершения обращения к базе,возможно,где то подвисло внесение изменений в таблицы.
Как бы,напрашивается,закрыть все соединения этой базе и повторить попытку.Причем,вполне вероятно,что висит какой-то из предыдущих скриптов.
1sanekmaloi1
02.07.18
✎
10:48
ТИИ сделай.
ptiz
02.07.18
✎
10:56
ADirks
02.07.18
✎
10:58
Вот тут есть всё что надо: https://ola.hallengren.com
MAPATNK2
02.07.18
✎
11:23
(9) Не пашет скрипт
MAPATNK2
02.07.18
✎
11:23
(10) А есть где попонятней объяснено. Опыта работы нет с SQL
MAPATNK2
02.07.18
✎
11:38
Есть какой нибудь готовый проверенный скрипт? SQL 2016
MAPATNK2
02.07.18
✎
11:40
(7) Он никогда не формировался, даже на 2008 даже на 2014 на разных базах, на разных ОС.
Галахад
02.07.18
✎
11:43
(13) Возьми из своего плана обслуживания.
Нажми на кнопку «просмотр t-sql» и выполни его в консоли. Возможно там увидишь ошибку.
MAPATNK2
02.07.18
✎
12:30
(15) Он не формируется. Уже писал выше.
ADirks
02.07.18
✎
12:40
(14) Готовый и проверенный — это как раз у Олы.
1. Скачиваешь https://ola.hallengren.com/scripts/MaintenanceSolution.sql
2. Запускаешь этот скрипт в MSSMS, с активной базой, в которой хочешь создать таблички и SPшки. Часто это всё сваливают в msdb, но я создаю отдельную базу для всяких логов, и называю её Monitor
3. Для проверки запускаешь
exec [Monitor].[dbo].[IndexOptimize]
@Databases = », —здесь список баз, ч/з запятую
@MaxDOP = 2,
@FragmentationLow = NULL,
@FragmentationMedium = ‘INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE’,
@FragmentationHigh = ‘INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE’,
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@UpdateStatistics = ‘ALL’,
@OnlyModifiedStatistics = ‘Y’,
@LogToTable = ‘Y’
4. Если всё хорошо, запихиваешь это в job
5. Периодически, ради интереса, посмтриваешь в табличку CommandLog — что оно там наребилдило и апдейтнуло.
ADirks
02.07.18
✎
12:44
Почитать можно например http://catalog.mista.ru/public/256292/
Там тоже есть подобный скрипт, можно его взять, попробовать
MAPATNK2
02.07.18
✎
12:56
(17) Спасибо, но совсем не понятно что это и как этим пользоваться. Скачал, запустил, что дальше делать с этим?
MAPATNK2
02.07.18
✎
12:56
(17) Где выполнять эти команды
ADirks
02.07.18
✎
13:14
(20) в Microsoft SQL Server Management Studio
MAPATNK2
02.07.18
✎
13:20
(21) Скачал, запустил, скрипт отработал, он в мастер запихал что нужно, потом я выполнил процедуру
exec [master].[dbo].[IndexOptimize]
@Databases = ‘[UPP]’, —здесь список баз, ч/з запятую
@MaxDOP = 2,
@FragmentationLow = NULL,
@FragmentationMedium = ‘INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE’,
@FragmentationHigh = ‘INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE’,
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@UpdateStatistics = ‘ALL’,
@OnlyModifiedStatistics = ‘Y’,
@LogToTable = ‘Y’
в ответ получил
Date and time: 2018-07-02 15:18:52
Server: WIN-9PMOB5DBGIK
Version: 12.0.2000.8
Edition: Enterprise Edition (64-bit)
Platform: Windows
Procedure: [master].[dbo].[IndexOptimize]
Parameters: @Databases = ‘[UPP]’, много всего
Version: 2018-06-27 20:44:12
Source: https://ola.hallengren.com
Date and time: 2018-07-02 15:18:52
Database: [UPP]
Status: ONLINE
Standby: No
Updateability: READ_WRITE
User access: MULTI_USER
Is accessible: Yes
Recovery model: SIMPLE
Date and time: 2018-07-02 15:19:41
MAPATNK2
02.07.18
✎
13:20
[dbo].[CommandLog] пустая
MAPATNK2
02.07.18
✎
13:29
(21) Вопрос, эти функции без моего ведома, т.е. как регламентыне задания выполняться не будут? Это просто готовые функции, которые можно вызвать в любое время?
ADirks
02.07.18
✎
13:47
если в Messages повылазило куча сообщений типа
Date and time: 2018-07-02 17:40:33
Command: UPDATE STATISTICS [SK].[dbo].[_1SCONST] [PK__1SCONST]
Outcome: Succeeded
Duration: 00:00:00
Date and time: 2018-07-02 17:40:33
значит, скрипт отработал. Почему пусто в логах — не знаю
Да, это функции, для использования их в job’ах. Ну и так просто можно, руками.
Джоб там тоже создался, но без расписания. Правда, он зачем-то через sqlcmd команду запускает, так что я его выкинул, и свой сделал.
ADirks
02.07.18
✎
13:50
(22) А вот в master не надо бы ничего запихивать. Она не для этого.
В msdb ещё куда ни шло. Но, повторяюсь, лучше отдельную базу создать, не системную.
ADirks
02.07.18
✎
13:57
(22)+ Кстати, если лог пустой, то значит ничего не перестраивалось, т.к. нет необходимости. Собственно, в этом и фишка подобных скриптов, что они не всё подряд обмолачивают, а только те индексы/статистики, которые перешли определенный порог фрагментации / неактуальности.
MAPATNK2
02.07.18
✎
14:22
(27) Понял, спасибо большое.
MAPATNK2
02.07.18
✎
14:22
Очень помогли
После обновления платформы 8.3.20.1674, обратил внимание что не выполняется реиндексация баз данных относящихся к 1С, в логах значится ошибка — «Невозможно реорганизовать индекс «_Acc48_1» в таблице «_Acc48″, поскольку отключена блокировка на уровне страницы.»
Как оказалось что начиная с версии платформы 8.3.22 необходимо выполнять дефрагментацию индексов по следующему алгоритму:
- До дефрагментации индекса необходимо включить страничные блокировки. Пример команды: ALTER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON);
- Выполнить дефрагментацию.
- Обратно выключить страничные блокировки. Пример команды: ALTER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = OFF, ALLOW_ROW_LOCKS = ON);
Исходя из этого пришлось написать скрипт выполняющий умную реорганизацию индексов базы данных с принудительным включением блокировки индекса на уровне страницы и её отключение, если блокировка была изначально выключена.
Скрипт работает по следующему принципу:
- В базе данных определяются таблицы для которых необходимо включить страничные блокировки и таблицы для которых страничные блокировки уже включены.
- Выполняется включение страничных блокировок для определенных таблиц.
- Выполняется реорганизация индексов базы данных.
- Выполняется выключение страничных блокировок для тех таблиц, для которых оно было включено.
Скачать “1s_reorgonize_index_mssql.sql” 1s_reorgonize_index_mssql.sql – Загружено 20 раз – 2 KB
ПОНРАВИЛАСЬ ИЛИ ОКАЗАЛАСЬ ПОЛЕЗНОЙ СТАТЬЯ, ПОБЛАГОДАРИ АВТОРА
Не работает реорганизация индексов, если есть отключенные.
Модератор: Дмитрий Юхтимовский
Не работает реорганизация индексов, если есть отключенные.
Добрый день!
С помощью клиента IndexesClient82.dt создаю предлагаемые новые индексы и отключаю редко используемые.
Но при наличии отключенных индексов перестает работать реорганизация индексов:
[img]
http://screencast.com/t/dc1SUbgOHH
[/img]
Генерируется ошибка:
Сбой выполнения запроса «ALTER INDEX [_Accum19257_ByDims19274_RTRN] ON [dbo…» со следующей ошибкой: «Невозможно выполнить указанную операцию с отключенным индексом «_Accum19257_ByDims19274_RTRN» для таблица «dbo._AccumRg19257″.». Возможные причины сбоя: проблемы с этим запросом, свойство «ResultSet» установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Можно ли сделать чтобы задача «Реорганизация индекса» пропускала отключенные индексы?
- simol
- Сообщений: 101
- Зарегистрирован: 18 фев 2013, 11:17
Re: Не работает реорганизация индексов, если есть отключенны
Гилёв Вячеслав » 10 дек 2013, 22:39
simol писал(а):Добрый день!
С помощью клиента IndexesClient82.dt создаю предлагаемые новые индексы и отключаю редко используемые.
Но при наличии отключенных индексов перестает работать реорганизация индексов:
[img]http://screencast.com/t/dc1SUbgOHH
[/img]
Генерируется ошибка:Сбой выполнения запроса «ALTER INDEX [_Accum19257_ByDims19274_RTRN] ON [dbo…» со следующей ошибкой: «Невозможно выполнить указанную операцию с отключенным индексом «_Accum19257_ByDims19274_RTRN» для таблица «dbo._AccumRg19257″.». Возможные причины сбоя: проблемы с этим запросом, свойство «ResultSet» установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Можно ли сделать чтобы задача «Реорганизация индекса» пропускала отключенные индексы?
Для этого надо в регламенте указать список тех таблиц, которые надо обслуживать , а не всю базу целиком.
- Гилёв Вячеслав
- Сообщений: 2726
- Зарегистрирован: 11 фев 2013, 15:40
- Откуда: Россия, Москва
Re: Не работает реорганизация индексов, если есть отключенны
simol » 10 дек 2013, 22:44
Гилёв Вячеслав писал(а):Для этого надо в регламенте указать список тех таблиц, которые надо обслуживать , а не всю базу целиком.
Это не удобно, могут появляться новые индексы или другие отключиться. То есть в конструкторе нельзя прописать игнорирование отключенных индексов и нужно делать свой скрипт?
- simol
- Сообщений: 101
- Зарегистрирован: 18 фев 2013, 11:17
Re: Не работает реорганизация индексов, если есть отключенны
Гилёв Вячеслав » 10 дек 2013, 22:49
simol писал(а):
Гилёв Вячеслав писал(а):Для этого надо в регламенте указать список тех таблиц, которые надо обслуживать , а не всю базу целиком.
Это не удобно, могут появляться новые индексы или другие отключиться. То есть в конструкторе нельзя прописать игнорирование отключенных индексов и нужно делать свой скрипт?
Наверное платные средства с подобным функционалом есть, но это лучше спрашивать тех кто такими инструментами пользуются.
- Гилёв Вячеслав
- Сообщений: 2726
- Зарегистрирован: 11 фев 2013, 15:40
- Откуда: Россия, Москва
Re: Не работает реорганизация индексов, если есть отключенны
simol » 23 янв 2014, 11:25
Гилёв Вячеслав писал(а):расскажите что получилось
Допроведем с вами аудит и продолжу по этому вопросу.
- simol
- Сообщений: 101
- Зарегистрирован: 18 фев 2013, 11:17
Re: Не работает реорганизация индексов, если есть отключенны
simol » 03 фев 2014, 17:18
Аудит завершился, спасибо!
Теперь продолжаю исследование.
Сначала хотел сделать алгоритм:
Исполняйте инструкцию ALTER INDEX … REORGANIZE, чтобы выполнить дефрагментацию индекса, при соблюдении следующих пороговых значений: значение avg_page_space_used_in_percent в диапазоне от 60 до 75 или значение avg_fragmentation_in_percent в диапазоне от 10 до 15. Исполняйте инструкцию ALTER INDEX … REBUILD, чтобы выполнить дефрагментацию индекса, при соблюдении следующих пороговых значений: значение avg_page_space_used_in_percent меньше 60 или значение avg_fragmentation_in_percent больше 15.
Столкнулся с тем, что есть таблица, записи в которой на столько большие, что при дефрагментации 0 получается avg_page_space_used_in_percen = 68% и эта таблица каждую итерацию требует REORGANIZE.
Потом решил сделать основываясь на алгоритме как для кластеризованных так и для некластеризованных:
> 5 % и <= 30 % REORGANIZE. > 30% ALTER INDEX REBUILD WITH (ONLINE = ON)
Затем заинтересовался вопросом обновления статистики и хотел добавить обновление статики по индексам, по которым перестроил индекс. Затем встал вопрос с очисткой процедурного кеша.
В результате лазя по просторам интернета нашел такой ресурс http://ola.hallengren.com/
Осознаваясь на который настроил регламенты:
1) каждый час по правилу >5%<=30% REORGANIZE, >30% REBUILD
2) каждые 6 часов обновление статистики, которая изменялась и очистка процедурного кеша
3) каждое воскресенье тестирование баз
- simol
- Сообщений: 101
- Зарегистрирован: 18 фев 2013, 11:17
Вернуться в MS SQL Server для целей 1С:Предприятие
Кто сейчас на форуме
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1
0
— 26.05.2016 — 12:58
Добрый день !
База SQL
В ежеденевном плане обслуживания в задаче «Перестроение индекса» вчера появилась ошибка
Сбой выполнения запроса «ALTER INDEX [_InfoRg5466_ByDataKey_RR] ON [dbo].[_…» со следующей ошибкой: «Возможно, повреждена схема. Запустите DBCC CHECKCATALOG.
При выполнении текущей команды возникла серьезная ошибка.. При наличии результатов они должны быть аннулированы.». Возможные причины сбоя: проблемы с этим запросом, свойство «ResultSet» установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Запускаю DBCC CHECKCATALOG
Сообщение 3852, уровень 16, состояние 1, строка 1
Строка (object_id=328648514) в sys.objects (type=U ) не имеет совпадающей строки (object_id=328648514,index_id=0) в sys.indexes.
Подскажите как решить проблему
1
— 26.05.2016 — 13:32
http://www.skalnyy.com/tag/ms-sql/
ЗЫ бэкап сделай
2
— 26.05.2016 — 13:35
и конкретно про (0)
http://www.sql.ru/forum/960965/alter…irovat-tablicu
http://infostart.ru/public/72532/

