Приветствую вас заклинатели железа, направляю вам преинтереснейшую ситуёвину для разбора и помощи вашему слуге.
Проблема: После обновления платформы 8.3.20.1674->8.3.22.1603 сломалось автоматическое резервное копирование баз данных, созданное менеджером в SSMS 2012. При попытке реиндексации баз данных коих у нас не одна, ssms ругается на "Невозможно реорганизовать индекс "_Acc48_1" в таблице "_Acc48", поскольку отключена блокировка на уровне страницы." И так на 30к+ индексов. Во всех базах где произошло какое-то обновление/регламентное задание/бог его знает что ещё. В кратце, для реиндексации нужно чтобы все таблицы баз были с включенным параметром "allow_page_locks" или как описан в клиенте он "Блокировка страниц в памяти".
Что пробовал?: · Гуглил. Не помогло.
· Доставать dt сувать обратно, индексы логично достаются и суются вместе с базой. Не помогло.
· Поднимал бэкап до обновления платформы в тест базу, смотрел что в индексах с нашим параметром. Там везде "ON". У нас после обновы в 30к "OFF".
· В небольших базах было по 1-2 индекса с флагом офф, проставлял там руками параметр в истину, запускал план бэкапа, реиндексация и сам бэкап проходили на ура. Сделал вывод, что выставив как-то параметр в 30к индексах я таки получу автобэкапирование, но не пойму причины возникновения отключения параметра. Можно утолкать кусок скрипта перед реиндексацией который будет ставить параметр в "ON". Костыль....
· Пробовал делать тестирование и исправление ошибок через конфигуратор. Не помогло.
Люди добрые: Кто сталкивался с подобным? Подскажите как решали.
Кто сможет написать запрос который в автомате проставит флаг во всех индексах всех таблиц базы, буду очень признателен.
Конструкция
ALT ER INDEX ALL ON <Table name>
SET (ALLOW_PAGE_LOCKS = ON)
GO
не помогает, так как во втором параметре нужна таблица, как туда указать все таблицы, не знаю, не могу, не умею.
Кто сможет написать запрос который в автомате проставит флаг во всех индексах всех таблиц базы, буду очень признателен.
Накидал на коленке, никаких гарантий, юзать на свой страх и риск
USE [enter_database_name_here]
GO
DECLARE @object_schema VARCHAR(256);
DECLARE @object_name VARCHAR(256);
DECLARE @index_name VARCHAR(256);
DECLARE db_cursor CURSOR FOR
SEL ECT OBJECT_SCHEMA_NAME(object_id) AS object_schema,
OBJECT_NAME(object_id) AS object_name,
name AS index_name
FR OM sys.indexes
WH ERE allow_page_locks = 0 AND OBJECT_SCHEMA_NAME(object_id) != 'sys';
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @object_schema, @object_name, @index_name;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ('ALT ER INDEX ' + @index_name + ' ON ' + @object_schema + '.'+ @object_name + ' SET (ALLOW_PAGE_LOCKS = ON)');
FETCH NEXT FR OM db_cursor INTO @object_schema, @object_name, @index_name;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;
(2) До обновления платформы все индексы были ON, лишь после обновления они чем-то выставились в OFF. Раз это мешает реорганизации, полагаю это не оптимизация, а ошибка всё-таки.
добавьте эти таблицы в исключения при реорганизации индекса.
Там тупо все таблицы нужно добавить в исключения, и это я не преувеличиваю, какой тогда смысл в реорганизации?
(5) Хм... Мало того, что такое решение (OFF) не разрешит реорганизацию индексов, а только перестроение.
Это еще может привести вместо блокировки на уровне страницы к блокировки на уровне всей таблицы.
Короче, я с вами согласен - я бы все включил обратно.
Есть слабая надежда, что просто алгоритм обновления зачем-то (для ускорения? Есть подозрение, что тогда надо бы проверить еще ALLOW_ROW_LOCK, ежели и тут OFF, все понятно - ускорялись, блокируя потаблично) отключил ALLOW_PAGE_Locks и просто забыл включить обратно.
(9)Переживаю, что включение мне не даст решения проблемы, уже вторую последнюю платформу поставили, а результат тот же, после каких-то манипуляций, в индексах всех флаги постраничной блокировки уходят в офф.
Откатит на более раннюю платформу не вариант, говорят в бухне есть что-то из-за чего на платформе 20, не бельме... А вот на 22 на ура...
Пока не уточнял, что там такое интересное, что прям необходимо бухне в 22 версии...
(12) Ну, что касается интересов бухгалтерии, сильно сомневаюсь, что им нужна 22.
Просто сделайте как в 8, только проверьте, возможно надо будет еще включить ALLOW_ROW_LOCKS.
Т.е. добавить еще одну строку:
USE имя базы
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
Даже интересно стало. Попробую накатить 8.3.22.1603.
А вообще, как резервное копирование связано с реиндексацией? Я в танке.
ЗЫ: такого релиза нет! Видимо откатили, есть только 8.3.22.1672. Честно сказать, кто сейчас ставит 8.3.22 платформу... только тестовые кролики. Вероятно, это была платформа для тестирования.
Огромное всем спасибо за проявленный интерес к проблеме и ответы с решениями, причины пока не нашли, тестим, выясняем какое регламентное меняет наш параметр. Запрос (8), помог исключительно, если не найдём корень проблемы сунем эту вещь с условием перед реорганизацией, в плане бэкапов
(25) При первой реструктуризации после обновления платформы, 1С запросом получает список индексов
sel ect a.name, b.name fr om sys.indexes a join sys.tables b on a.object_id = b.object_id join sys.schemas s ON b.schema_id = s.schema_id and s.name = 'dbo' where a.[allow_page_locks] = 1 and a.index_id <> 0
и затем принудительно изменят параметр для каждого.
Можно посмотреть профайлером, при обновлении конфигурации.
Неправильный синтаксис около "INDEX". Если имелась в виду часть табличного указания, то для этого теперь необходимо использовать ключевое слово A WITH и круглые скобки. Правильный синтаксис см. в электронной документации по SQL Server.
Та же проблема на 8.3.22.1603. Решал скриптом с условием - если ошибка реорганизации, то ALLOW_PAGE_LOCKS = ON и снова реорганизовать. Но, например, в Документообороте, данное решение помогало на 3 дня. Приходилось по новой скрипт запускать. Вчера установил 8.3.22.1704. Естественно, существующие ошибки не ушли. Сегодня пройдусь скриптом. Посмотрим, вылезут ли ошибки реорганизации на новой платформе.
Добрый вечер!
Тоже словили эту "ошибку" на планах обслуживания. Не реорганизуется индекс: "...При попытке реиндексации баз данных "Невозможно реорганизовать индекс "_Acc48_1" в таблице "_Acc48", поскольку отключена блокировка на уровне страницы....".
Посмотрел, куча индексов с отключенным параметром блокировки в базах (ALLOW_PAGE_LOCKS). Это косяк платформы или чего? До перехода на 8.3.22.1704 все было в порядке. Может кто-то подсказать, что делать-то?? Будет ли работать не реорганизация, а перестроение индекса?
(34) "На днях убедился что при любой реструктуризации базы, в индексах флажок ставится в off" - что с этим делать? Не подскажете?
(36) На днях убедился что при любой реструктуризации базы, в индексах флажок ставится в off" - что с этим делать? Не подскажете?
Как уже ранее написали, воспользуйся скриптом с (8), затем даунгрейд до 8.3.19.1723(она минимальна для работы без выбросов из 19 серии), потом измени что-то в базе чтобы запустилась реструктуризация или запусти обновление базы через строку запуска /обновитьбазуданных или что там, нагугли. И затем скриптом нужно будет пробежаться проверить, есть ли индексы с off или нету. Просто они в off уходят когда обнова проходит только. Без обновы базы не добиться изменения индексов. Если 8.3.19.1723 решит проблему, то заходи сюда, пиши
(36) очевидно же, что баг в новых версиях платформы. Поменять ручонками через (8) и откатить платформу на постарее, Ну или бежать впереди паровоза и быть бесплатным бетта-тестером товарищей с Селезнёвки.
(37) Причем здесь впереди паровоза. Поменять на постарее и получить вылеты как у половины РФ. Сначала обновлениями типовых вынудили менять релиз платформы, а теперь такая фича...
(39)версий платформ ниже 8.3.22 в которых нет вылетов, много. Загляни в users, там 14.11 вышла куча платформ и 8.3.19/20/21/22
Попробуй себе в 8.3.19.1723 ткнуть, она точно будет работать и точно выкидывать не будет, но я не знаю решает ли она проблему с индексами. На моём нынешнем месте рабочем, пока нет доступа к sql чтобы мне этот момент затестить. Если будешь тестить отпишись пожалуйста о результате.
(39) притом, что из вас делают бесплатных беттатестеров.
Все типовые торчат еще в хрен знает каком далёком режиме совместимости, на 15 то и то, только в этом году переход был (в котором конкретно РБ изменили, и он, самый тяжелый для перехода больших баз, ибо реструктуризация невъ..ная).
А все остальные плюшки платформы, типовые конфы не используют от слова совсем. Смысла ставить последние релизы нет.
ЗЫ: А падение платформы, без её замены, можно вылечить фаерволом, тупо забанив ip и порты, куда 1с-ина щемится.
Но, то что они в последних платформах отключают блокировку страниц, грозит рассогласованностью данных в дальнейшем, тут надо на партнёрке вопросы задавать - какого хрена ?
(46) нет, вам придётся выкинуть реорганизацию индекса с плана обслуживания, 1с-ина теперь решила таким способом бороться с блокировками - сняв блокировку индекса на уровне страниц
Всем привет! Кто как в итоге решил вопрос с реорганизацией? Я так понимаю 3 варианта: откатиться с 22 платформы, вставить скрипт в план обслуживания перед реорганизацией и отказаться от реорганизации?
DECLARE @Database NVARCHAR(255)
DECLARE DatabaseCursor CURSOR READ_ONLY FOR
SEL ECT name FR OM master.sys.databases
WH ERE name NOT IN ('master','msdb','tempdb','model','distribution') -- исключаемые базы данных
AND name IN ('acount_01_usn') -- используется для выбора конкретных баз данных (раскомментируйте эту строку)
AND state = 0 -- база данных онлайн
AND is_in_standby = 0 -- база данных не читается только для log shipping
ORDER BY 1
OPEN DatabaseCursor
FETCH NEXT FROM DatabaseCursor INTO @Database
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'sp_MSforeachtable ''ALT ER INDEX ALL ON ' + @Database + '.? SET (ALLOW_PAGE_LOCKS = ON)'''
EXEC('sp_MSforeachtable ''ALT ER INDEX ALL ON ' + @Database + '.? SET (ALLOW_PAGE_LOCKS = ON)''')
FETCH NEXT FR OM DatabaseCursor INTO @Database
END
CLOSE DatabaseCursor
DEALLOCATE DatabaseCursor
Важно! Начиная с версии платформы 8.3.22 необходимо выполнять дефрагментацию индексов по следующему алгоритму:
До дефрагментации индекса необходимо включить страничные блокировки. Пример команды: ALT ER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON);
Выполнить дефрагментацию.
Обратно выключить страничные блокировки. Пример команды: ALT ER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = OFF, ALLOW_ROW_LOCKS = ON);
Короче сделал сам. Я пользуюсь скриптом Tavalik для работы с индексами в ежедневном плане обслуживания.
Внес изменения, чтобы не вылетала реорганизация индекса с описанной в этом топике ошибкой.
Реорганизация индекса таблицы производится теперь только при установленном для нее ALLOW_PAGE_LOCKS. Если параметр ALLOW_PAGE_LOCKS не установлен, то реорганизация индекса таблицы не производится. Дожидаемся, пока уровень дефрагментации этого индекса достигнет 30% и проводим перестроение индекса.
ИМХО, это решение - "меньшее из зол", т.к. устанавливать параметр ALLOW_PAGE_LOCKS на все индексы таблиц противоречит внесенным 1С изменениям, может повлиять на блокировки и стабильность работы всей 1С.
А проводить ежедневное тотальное перестроение индекса потребует повышенных временных затрат и увеличение нагрузки.
-------------------------------------------
-- Выполняет реорганизацию либо дефрагменатцию индексов указанной базы данных
-- Алгоритм пработы:
-- 1. Собираются информация обо всех фрагментированных индексах (степерь фрагментации более 5%)
-- 2. Если фрагментация менее или равна 30% тогда выполняется дефрагментация, иначе реиндексация индекса
-- Автор: Онянов Виталий (Tavalik.ru)
-- Версия от 20.05.2017
-------------------------------------------
-- НАСТРАИВАЕМЫЕ ПАРАМЕТРЫ
-- База данных для анализа
USE <имя базы>
-------------------------------------------
-- СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ
DECLARE @object_id int; -- ID объекта
DECLARE @index_id int; -- ID индекса
DECLARE @partition_number bigint; -- количество секций если индекс секционирован
DECLARE @schemaname nvarchar(130); -- имя схемы в которой находится таблица
DECLARE @objectname nvarchar(130); -- имя таблицы
DECLARE @indexname nvarchar(130); -- имя индекса
DECLARE @partitionnum bigint; -- номер секции
DECLARE @fragmentation_in_percent float; -- процент фрагментации индекса
DECLARE @command nvarchar(4000); -- инструкция T-SQL для дефрагментации либо ренидексации
DECLARE @allow_page_locks bit; -- состояние параметра allow_page_locks в индексе таблицы
-------------------------------------------
-- ТЕЛО СКРИПТА
-- Отключаем вывод количества возвращаемых строк, это несколько ускорит обработку
SET NOCOUNT ON;
-- Удалим временные таблицы, если вдруг они есть
IF OBJECT_ID('tempdb.dbo.#work_to_do') IS NOT NULL DR OP TABLE #work_to_do
-- Отбор таблиц и индексов с помощью системного представления sys.dm_db_index_physical_stats
-- Отбор только тех объектов которые:
-- являются индексами (index_id > 0)
-- фрагментация которых более 5%
-- количество страниц в индексе более 128
SEL ECT
sys.dm_db_index_physical_stats.object_id,
sys.dm_db_index_physical_stats.index_id,
sys.dm_db_index_physical_stats.partition_number,
sys.dm_db_index_physical_stats.avg_fragmentation_in_percent as fragmentation_in_percent,
sys.indexes.allow_page_locks
INTO #work_to_do
FR OM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED'), sys.indexes
WHERE sys.dm_db_index_physical_stats.index_id > 0
AND sys.dm_db_index_physical_stats.avg_fragmentation_in_percent > 5.0
AND sys.dm_db_index_physical_stats.page_count > 128;
-- Объявление Открытие курсора курсора для чтения секций
DECLARE partitions CURSOR FOR SEL ECT * FR OM #work_to_do;
OPEN partitions;
-- Цикл по секциям
FETCH NEXT FR OM partitions INTO @object_id, @index_id, @partition_number, @fragmentation_in_percent, @allow_page_locks;
WHILE @@FETCH_STATUS = 0
BEGIN
-- Собираем имена объектов по ID
SEL ECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
FR OM sys.objects AS o
JOIN sys.schemas as s ON s.schema_id = o.schema_id
WH ERE o.object_id = @object_id;
SEL ECT @indexname = QUOTENAME(name)
FR OM sys.indexes
WH ERE object_id = @object_id AND index_id = @index_id;
SELECT @partition_number = count (*)
FR OM sys.partitions
WH ERE object_id = @object_id AND index_id = @index_id;
-- Если фрагментация менее или равна 30% тогда дефрагментация, иначе реиндексация
IF @fragmentation_in_percent < 30.0 and @allow_page_locks = 'true'
SET @command = N'ALT ER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
IF @fragmentation_in_percent >= 30.0
SET @command = N'ALT ER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
IF @partition_number > 1 and @command is not null
SET @command = @command + N' PARTITION=' + CAST(@partition_number AS nvarchar(10));
-- Выполняем команду
IF @command is not null
PRINT N'Executed: ' + @command;
EXEC (@command);
SET @command = null;
PRINT N'Index: object_id=' + STR(@object_id) + ', index_id=' + STR(@index_id) + ', fragmentation_in_percent=' + STR(@fragmentation_in_percent);
-- Следующий элемент цикла
FETCH NEXT FR OM partitions INTO @object_id, @index_id, @partition_number, @fragmentation_in_percent, @allow_page_locks;
END;
-- Закрытие курсора
CLOSE partitions;
DEALLOCATE partitions;
-- Удаление временной таблицы
DR OP TABLE #work_to_do;
GO
А проводить ежедневное тотальное перестроение индекса потребует повышенных временных затрат и увеличение нагрузки.
В общем-то и ежедневная реорганизация - тоже переливание из пустого в порожнее, по большому счёту. Обновления статистики, как правило, вполне достаточно
В ветке 8.3.22 изменились настройки индексов в Microsoft SQL Server.
Гранулярность блокировки индекса теперь может быть установлена только на уровне строк.
https://dl03.1c.ru/content/Platform/8_3_22_1709/1cv8upd_8_3_22_1709.htm#e3b9347f-72e1-11ec-aa69-0050569f678a Цитата:
Система «1С:Предприятие» устанавливает гранулярность блокировок на уровне строк, если используется Microsoft SQL Server версии 2008 и последующие версии. Исключается возможность эскалации блокировок. Возможно увеличение потребления оперативной память Microsoft SQL Server.
Рекомендации учёта изменений в регламентных операциях доступны в статье "Регламентные операции на уровне СУБД для MS SQL Server" ( https://its.1c.ru/db/metod8dev#content:5837:hdoc ) в разделе "Дефрагментация индексов".
Цитата:
1. До дефрагментации индекса необходимо включить страничные блокировки. Пример команды:
ALT ER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON);
2. Выполнить дефрагментацию.
3. Обратно выключить страничные блокировки. Пример команды:
ALT ER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = OFF, ALLOW_ROW_LOCKS = ON);
USE [ИмяБазы]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
после реорганизации
USE [ИмяБазы]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = OFF)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
(63)встаю на базу, создаю запрос, останавливается с ошибкой.
USE [ИмяБазы]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
Неправильный синтаксис около "INDEX". Если имелась в виду часть табличного указания, то для этого теперь необходимо использовать ключевое слово A WITH и круглые скобки. Правильный синтаксис см. в электронной документации по SQL Server.
Сообщение 156, уровень 15, состояние 1, строка 1
Неправильный синтаксис около ключевого слова "SET".
После обновления платформы с версии 8.3.20.1674 до версии 8.3.20.2184, план обслуживания sql баз 1с - реорганизация индексов стала выдавать ошибку.
Задание состоит из 2 частей:
Реорганизация индекса
Обновление статистики
Ошибки при выполнении задачи Реорганизация индексов.
Номер ошибки: -1073548784
Сведения об:
Сбой выполнения запроса "ALT ER INDEX [_AccumRg4879_1] ON [dbo].[_AccumRg487..." со следующей ошибкой: "Не удалось найти объект "dbo._AccumRg4879", так как он не существует, или отсутствуют разрешения.". Возможные причины сбоя: проблемы с этим запросом, свойство "ResultSet" установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Сбой выполнения запроса "ALT ER INDEX [_AccRg465_1] ON [dbo].[_AccRg465] REO..." со следующей ошибкой: "Невозможно реорганизовать индекс "_AccRg465_1" в таблице "_AccRg465", поскольку отключена блокировка на уровне страницы.". Возможные причины сбоя: проблемы с этим запросом, свойство "ResultSet" установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Сбой выполнения запроса "ALT ER INDEX [_AccumRgT7681_1] ON [dbo].[_AccumRgT7..." со следующей ошибкой: "Невозможно реорганизовать индекс "_AccumRgT7681_1" в таблице "_AccumRgT7681", поскольку отключена блокировка на уровне страницы.". Возможные причины сбоя: проблемы с этим запросом, свойство "ResultSet" установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Везде где обновлялась платформа. Такая проблема.
Подскажите пожалуйста как решается эта проблема или как теперь нужно настраивать план обслуживания 1с баз.
После обновления платформы с версии 8.3.20.1674 до версии 8.3.20.2184, план обслуживания sql баз 1с - реорганизация индексов стала выдавать ошибку.
Задание состоит из 2 частей:
Реорганизация индекса
Обновление статистики
Ошибки при выполнении задачи Реорганизация индексов.
Номер ошибки: -1073548784
Сведения об:
Сбой выполнения запроса "ALT ER INDEX [_AccumRg4879_1] ON [dbo].[_AccumRg487..." со следующей ошибкой: "Не удалось найти объект "dbo._AccumRg4879", так как он не существует, или отсутствуют разрешения.". Возможные причины сбоя: проблемы с этим запросом, свойство "ResultSet" установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Сбой выполнения запроса "ALT ER INDEX [_AccRg465_1] ON [dbo].[_AccRg465] REO..." со следующей ошибкой: "Невозможно реорганизовать индекс "_AccRg465_1" в таблице "_AccRg465", поскольку отключена блокировка на уровне страницы.". Возможные причины сбоя: проблемы с этим запросом, свойство "ResultSet" установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Сбой выполнения запроса "ALT ER INDEX [_AccumRgT7681_1] ON [dbo].[_AccumRgT7..." со следующей ошибкой: "Невозможно реорганизовать индекс "_AccumRgT7681_1" в таблице "_AccumRgT7681", поскольку отключена блокировка на уровне страницы.". Возможные причины сбоя: проблемы с этим запросом, свойство "ResultSet" установлено неправильно, параметры установлены неправильно или соединение было установлено неправильно.
Везде где обновлялась платформа. Такая проблема.
Подскажите пожалуйста как решается эта проблема или как теперь нужно настраивать план обслуживания 1с баз.
(63)встаю на базу, создаю запрос, останавливается с ошибкой.
USE [ИмяБазы]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
Неправильный синтаксис около "INDEX". Если имелась в виду часть табличного указания, то для этого теперь необходимо использовать ключевое слово A WITH и круглые скобки. Правильный синтаксис см. в электронной документации по SQL Server.
Сообщение 156, уровень 15, состояние 1, строка 1
Неправильный синтаксис около ключевого слова "SET".
В итоге, есть объяснение логики изменения схемы работы с индексами?
Система «1С:Предприятие» устанавливает гранулярность блокировок на уровне строк, если используется Microsoft SQL Server версии 2008 и последующие версии. Исключается возможность эскалации блокировок. Возможно увеличение потребления оперативной память Microsoft SQL Server.
(72)Эскалация блокировок ведет к меньшему расходу памяти на эти блокировки, но увеличивает количество блокированных записей, в том числе и тех, в блокировании которых нет необходимости. То есть точность наложения блокировок снижается. Блокируется больше - больше тормозов.
пожалуйста разверните мне, я новичок в этом.
первый этап это отключение блокировок? но при этом могут появиться жалобы на тормоза в базе и просто больше памяти будет задействовано.
но я так и не понял второй этап, возвращение блокировок! он обязательный?
USE [ИмяБазы]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
после реорганизации
USE [ИмяБазы]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = OFF)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
(77) на другой аналогичной базе убрал реорганизацию совсем и участил обновление статистик, также все работает в пределах нормы. Может 1с-ники и правы когда блокировки страниц убрали
(82) "Дефрагментация и перестроение индексов" из этой программы не работает (MS SQL2016). Работает только 2-й вариант скрипта от Ola Hallengren ( http://qmbsql.ru/ ).
Всем привет.
Я так и не понял - в плане обслуживания оставлять реорганизацию индексов с "костылями" :
USE [Name]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
USE [Name]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = OFF)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
Или нет ?
Забить и делать только обновление статистики .....
Кстати операция Восстановить индекс -тоже не будет работать без "костылей" теперь ?
Я поражаюсь 1С - че то сделают, но как нормально поправить в скрипте SQL - не пишут.
Они там вообще офигели ?
"Важно! Начиная с версии платформы 8.3.22 необходимо выполнять дефрагментацию индексов по следующему алгоритму:
До дефрагментации индекса необходимо включить страничные блокировки. Пример команды: ALT ER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON);
Выполнить дефрагментацию.
Обратно выключить страничные блокировки. Пример команды: ALT ER INDEX index_name ON table_name SET (ALLOW_PAGE_LOCKS = OFF, ALLOW_ROW_LOCKS = ON);"
Мне что каждую таблицу включать/выключать в скрипте ?
Нельзя было общее решение хотя бы для базы описать ?
Заставляют пользоваться написанным кем то кодом ......
1. Плохо понимаю в SQL это правильно написано ?:
USE [Name]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
USE [Name]
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = OFF)'
EXEC sp_MSforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_ROW_LOCKS= ON)'
GO
Почему по две строки ...?
2. А Это нормально еженедельно как советуют в 1С - сключать/выключить все таблицы ...? Индексы и так реорганизуются долго еще и этот костыль теперь .....
(90) Гдето на просторах встречал статью, что у самой 1С, чуть ли не петабайтная база на сиквеле в которой вообще регламентные не делают, и все работает.....
Вот всё очень правильно 1С делает - поднимает уровень требуемых знаний для обслуживания баз. Отсекаются необразованные, общий уровень сообщества повышается.
напишите уже кто-нибудь годный скрипт дефрагментации индексов для всех БД:
чтобы в начале блокировки включал (ALLOW_PAGE_LOCKS = ON) - потом дефрагментировал (например скриптом Tavalik) - под конец блокировки выключал (ALLOW_PAGE_LOCKS = OFF)
это же будет полезно всему сообществу и снимет все вопросы.
- А у меня на SQL 2000 не запускается!
- Как запустить скрипт без конфигуратора?
- Я скачал, запустил у меня все повисло я вас засужу!
- Вы офигели неработоспособное выкладывать?
...
Вот, на тестовой базе отработало. Но у меня пока нет 22 релиза.
Проверьте кто может.
Да, обрабатывает все пользовательские базы подходящие под маску @namelike
use master
SET NOCOUNT ON;
DECLARE @namelike varchar(100) = 'Введите_маску_базы_символ%' -- Отбор по имени базы
DECLARE @database_id varchar(100) -- ID баз данных
DECLARE @database_name varchar(100) -- Имена баз данных
DECLARE @command nvarchar(4000); -- инструкция T-SQL для дефрагментации либо реиндексации
DECLARE @subject as NVARCHAR(1000) = '' -- тема сообщения
DECLARE @finalmessage as NVARCHAR(4000) = '' -- текст сообщения
-- Отберем базы для выполнения операций
DECLARE DBcursor CURSOR FOR
(
SEL ECT
database_id as database_id,
name as database_name
FR OM sys.databases d
WHERE
d.name <> 'tempdb'
AND d.name <> 'master'
AND d.name <> 'model'
AND d.name <> 'msdb'
AND d.state_desc = 'ONLINE' -- база должна быть в сети
AND d.name like @namelike -- база должна содержать указанное слово
)
OPEN DBcursor
FETCH NEXT FR OM DBcursor INTO @database_id,@database_name
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT N'----------------------------------------------------------'
PRINT N'USE [' + @database_name + N']'
SET @command =
N'USE [' + @database_name + N']
DECLARE @object_id int; -- ID объекта
DECLARE @index_id int; -- ID индекса
DECLARE @partition_number bigint; -- количество секций если индекс секционирован
DECLARE @schemaname nvarchar(130); -- имя схемы в которой находится таблица
DECLARE @objectname nvarchar(130); -- имя таблицы
DECLARE @indexname nvarchar(130); -- имя индекса
DECLARE @partitionnum bigint; -- номер секции
DECLARE @fragmentation_in_percent float; -- процент фрагментации индекса
DECLARE @command nvarchar(4000); -- инструкция T-SQL для дефрагментации либо ренидексации
-- Отбор таблиц и индексов с помощью системного представления sys.dm_db_index_physical_stats
-- Отбор только тех объектов которые:
-- являются индексами (index_id > 0)
-- фрагментация которых более 5%
-- количество страниц в индексе более 50
SEL ECT
object_id,
index_id,
partition_number,
avg_fragmentation_in_percent AS fragmentation_in_percent
INTO #work_to_do
FR OM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, ''LIMITED'')
WHERE index_id > 0
AND avg_fragmentation_in_percent > 5.0
AND page_count > 50;
-- Объявление Открытие курсора курсора для чтения секций
DECLARE partitions CURSOR FOR SEL ECT * FR OM #work_to_do;
OPEN partitions;
-- Цикл по секциям
FETCH NEXT FROM partitions INTO @object_id, @index_id, @partition_number, @fragmentation_in_percent;
WHILE @@FETCH_STATUS = 0
BEGIN
-- Собираем имена объектов по ID
SEL ECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
FROM sys.objects AS o
JOIN sys.schemas as s ON s.schema_id = o.schema_id
WH ERE o.object_id = @object_id;
SEL ECT @indexname = QUOTENAME(name)
FR OM sys.indexes
WH ERE object_id = @object_id AND index_id = @index_id;
SELECT @partition_number = count (*)
FR OM sys.partitions
WH ERE object_id = @object_id AND index_id = @index_id;
-- Если фрагментация менее или равна 30% тогда дефрагментация, иначе реиндексация
IF @fragmentation_in_percent < 30.0
SET @command = N''ALT ER INDEX '' + @indexname + N'' ON '' + @schemaname + N''.'' + @objectname + N'' SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON);'';
SET @command = @command + N''ALT ER INDEX '' + @indexname + N'' ON '' + @schemaname + N''.'' + @objectname + N'' REORGANIZE;'';
SET @command = @command + N''ALT ER INDEX '' + @indexname + N'' ON '' + @schemaname + N''.'' + @objectname + N'' SET (ALLOW_PAGE_LOCKS = OFF , ALLOW_ROW_LOCKS = ON);'';
IF @fragmentation_in_percent >= 30.0
SET @command = N''ALT ER INDEX '' + @indexname + N'' ON '' + @schemaname + N''.'' + @objectname + N'' REBUILD'';
IF @partition_number > 1
SET @command = @command + N'' PARTITION='' + CAST(@partition_number AS nvarchar(10));
-- Выполняем команду
PRINT N'' Executed: '' + @command;
EXEC sp_executesql @command
-- Следующий элемент цикла
FETCH NEXT FR OM partitions INTO @object_id, @index_id, @partition_number, @fragmentation_in_percent;
END;
-- Закрытие курсора
CLOSE partitions;
DEALLOCATE partitions;
-- Удаление временной таблицы
DR OP TABLE #work_to_do;';
BEGIN TRY
EXEC sp_executesql @command
SET @finalmessage = @finalmessage + 'Успешное выполнение операций обслуживания индексов для базы данных ' + @database_name + CHAR(13) + CHAR(13)
END TRY
BEGIN CATCH
-- Ошбика выполнения операции
SET @subject = 'БЫЛИ ОШИБКИ при выполнении операций обслуживания индексов '
SET @finalmessage = @finalmessage + 'ОШИБКА обслуживания индекса для базы данных ' + @database_name + CHAR(13) + CHAR(13)
+ 'Код ошибки: ' + CAST(ERROR_NUMBER() as nvarchar(10)) + CHAR(13) + CHAR(13)
+ 'Текст ошибки: ' + ERROR_MESSAGE() + CHAR(13) + CHAR(13)
+ 'Текст T-SQL: ' + CHAR(13) + @command + CHAR(13) + CHAR(13)
END CATCH;
-- Следующая база данных
FETCH NEXT FR OM DBcursor INTO @database_id, @database_name
END;
CLOSE DBcursor;
DEALLOCATE DBcursor;
SELECT
@subject as subject,
@finalmessage as finalmessage
GO
напишите уже кто-нибудь годный скрипт дефрагментации индексов для всех БД:
чтобы в начале блокировки включал (ALLOW_PAGE_LOCKS = ON) - потом дефрагментировал (например скриптом Tavalik) - под конец блокировки выключал (ALLOW_PAGE_LOCKS = OFF)
это же будет полезно всему сообществу и снимет все вопросы.