Порционный шринк базы

28.03.24

База данных - Администрирование СУБД

Скрипт позволяет высвобождать место в операционную систему, занятое файлом базы MS SQL в итерациях с заданным количеством мегабайт

О шринке расписывать не буду, яндекс полон ответов "Для чего, зачем и как".

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

Проблемы полноценного шринка базы:

1. Непонятно, сколько времени это займет с учетом нагрузки на базу (если приходится это делать на активно используемой базе)

2. Освобождение места произойдет непосредственно при окончании шринка.

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

Скрипт выводит информацию о прогрессе через print, оповещая о том, с какого размера база шринкуется и до какого, скорость обработки порции, прогнозируемая скорость для обработки всего доступного в базе пространства, количество Mb, оставшиеся для шринка.

Сам скрипт:

use YourBase -- Выберите базу для шринка

set NOCOUNT ON;

DECLARE @PortionInMB INT = 1000 -- Замените на нужное значение, количество МБ. освобождаемое за итерацию
DECLARE @StopSizeInMB INT = 1000 -- Количество свободного места в базе, при котором нужно прекратить шринк
DECLARE @CurrentSizeInMB INT
DECLARE @FreeSpaceInMB INT
DECLARE @CurrentDBName nvarchar(64) = DB_NAME()
DECLARE @MomentumSize INT
DECLARE @StartTime datetime2
DECLARE @EndTime datetime2
DECLARE @IterationTime INT
DECLARE @RequiredSeconds INT

SET @FreeSpaceInMB = (select convert(decimal(12,2),round((a.size-fileproperty(a.name,'SpaceUsed'))/128.000,2)) as FreeSpaceMB from dbo.sysfiles a where status & 64 = 0)

WHILE @FreeSpaceInMB > @StopSizeInMB
BEGIN
    SET @CurrentSizeInMB = (select convert(decimal(12,2),round(a.size/128.000,2)) as FileSizeMB from dbo.sysfiles a where status & 64 = 0)
    SET @FreeSpaceInMB = (select convert(decimal(12,2),round((a.size-fileproperty(a.name,'SpaceUsed'))/128.000,2)) as FreeSpaceMB from dbo.sysfiles a where status & 64 = 0)
	SET @MomentumSize = @CurrentSizeInMB - @PortionInMB

    IF @FreeSpaceInMB > @StopSizeInMB
    BEGIN
		SET @StartTime = CURRENT_TIMESTAMP
		print CONVERT(VARCHAR(100), CURRENT_TIMESTAMP) + ': Start shrink iteration for database [' + @CurrentDBName + ']. From ' + CONVERT(VARCHAR(100), @CurrentSizeInMB) 
			+ ' to ' + CONVERT(VARCHAR(100), @MomentumSize) + '. Remains: ' + CONVERT(VARCHAR(100), @FreeSpaceInMB - @PortionInMB - @StopSizeInMB) + ' Mb.'
		RAISERROR( '',0,1) WITH NOWAIT
		DBCC SHRINKFILE (@CurrentDBName , @MomentumSize)
		SET @EndTime = CURRENT_TIMESTAMP
		SET @RequiredSeconds = (@FreeSpaceInMB - @StopSizeInMB) / @PortionInMB * datediff(s, @StartTime, @EndTime)
		print 'Iteration successfull on ' + CONVERT(VARCHAR(100), datediff(s, @StartTime, @EndTime)) + ' sec. The required time for all iteration: '
			+ CONVERT(VARCHAR(100), @RequiredSeconds) + ' sec. Completion time: ' + CONVERT(VARCHAR(100), DATEADD(s,@RequiredSeconds,CURRENT_TIMESTAMP))
		RAISERROR( '',0,1) WITH NOWAIT
    END
    ELSE
    BEGIN
        BREAK;
    END
END
 
 Выводимые данные


Нюансы:

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

RAISERROR использован для оперативного получения информации, переданной в print.

скрипт шринк mssql dba sql порционный шринк shrinkfile shrinkdatabase

См. также

Администрирование СУБД Сервера Системный администратор Россия Бесплатно (free)

Доброго дня, коллеги. Рубрика - администрирование серверов 1С: Предприятие. Все еще остались живые сервера на платформе Windows, а в связи с этим и необходимость их обслуживать. На продуктивной среде, понятное дело, все должно работать, как часы, без всяких перезапусков и желательно 24/7, хотя для многих, скорее всего, это сферический коньв в вакуумен и большой техдолг по рефакторингу до такого результата. Поэтому скрипт, который приведу ниже, будет полезен не только на тестовых серверах, где идет активная разработка и эксперименты, которые могут выводить из строя службу сервера 1С, но и на продуктивных системах, описанных выше (да, с техдолгом, который почти невозможно устранить, и поэтому применяется костылирование с регулярным перезапуском службы).

23.07.2024    2824    mefalcon    12    

2

Администрирование СУБД Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

В статье описала свой опыт аудита 1С базы, порядок действий + статьи, которые сильно помогли в работе.

14.07.2024    6276    limonen    15    

19

Администрирование СУБД Платформа 1С v8.3 Россия Бесплатно (free)

Безопасное полное удаление пользователей из конфигураций 1С.

25.06.2024    978    It-digit    5    

1

Администрирование СУБД Системный администратор Платформа 1С v8.3 Бесплатно (free)

Ситуация: при обновлении серверной базы данных произошёл сбой и теперь невозможно войти ни в конфигуратор, ни в 1С:Предприятие по причине ошибки, вынесенной в заголовок. Рецепт лечения.

24.05.2024    1753    Kernelbug    9    

20

Администрирование СУБД Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

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

23.05.2024    8409    human_new    18    

55

Администрирование СУБД Системный администратор Платформа 1С v8.3 Бесплатно (free)

Краткое описание шагов по установке, настройке и применению инструмента 1С:Исполнитель на операционной системе РедОС, а также по борьбе с некоторыми возникающими ошибками.

06.05.2024    903    artemusII    0    

1

Администрирование СУБД Системный администратор Программист Платформа 1С v8.3 Бесплатно (free)

Статья для тех, кто столкнулся с необходимостью пересчета итогов для "больших таблиц" и нет возможности поставить на паузу ИБ для проведения работ.

25.04.2024    2882    virustam    33    

12
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. nvv1970 11.04.24 08:59 Сейчас в теме
Есть какая-то статистика, сколько времени занимает шринк относительно "обычного", когда освобождают сразу 50-90% базы? Т.е. это ускоряет или замедляет общий процесс?
2. Garilia 62 14.04.24 00:49 Сейчас в теме
(1) для моих кейсов порционный шринк всегда оказывался быстрее, да и в случае необходимости прервать операцию - прогресс шринка теряет только последнюю запущенную итерацию. На днях сравню время выполнения высвобождения 900 Гб из базы 3.7 ТБ обоими вариантами.
3. Garilia 62 17.04.24 14:53 Сейчас в теме
(1)
Дано:
База 3.7 ТБ
Свободно внутри базы - 877 ГБ
Операция полного шринка одной итерацией для базы - 15 часов и 5 минут
Порционный шринк - 22 часа.

Время для отпуска первой порции в текущей схеме распределения данных внутри базы - 2613 секунд, последующие по разному от 177 до 1700 секунд с порцией в 5000 МБ.

Скорость выполнения вероятно будет у всех разная, т.к. у меня 877 ГБ места получается после точечного вырезания определенных данных из файла базы, находящихся на всем поле размеченного пространства (свертка баз по последним N дням с сохранением ссылочной целостности для регистров и т.д. конкретно с этой базой чистились технологические таблицы и различные конф. данные - поэтому неразмеченные блоки располагаются практически везде)

На других базах, время для высвобождения первой порции памяти варьируется от 100+ секунд до 1000
METAL; nvv1970; +2 Ответить
4. sutygin 36 21.05.24 12:43 Сейчас в теме
(3) А имеет ли смысл делать вот это все, т.к. субд все равно займет не используемое пространство, а на размер бэкапов это не как не скажется?
5. Garilia 62 11.06.24 18:24 Сейчас в теме
(4) При восстановлении базы на сервере СУБД, она запросит такое количество пространства с учетом неразмеченных областей внутри файла базы.

Т.е. если взять две базы:
[0] Одна весит 100 ГБ, внутри базы неразмечено 50 ГБ
[1] Эта же база, но после шринка весит 50 ГБ, внутри базы неразмечено 0 ГБ

Файлы бэкапов будут весить одинаково

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

Так же, если произошла не самая нормальная реструктуризация, которая создала кучу ng таблиц в процессе, например возьмем какой нибудь регистр, при реструктуризации файл базы вырос на размер этой таблицы, условно - 300 ГБ. В случае если это не единственная база на диске, для возможности работоспособности других, необходимо либо увеличить диск, либо шринкануть разросшийся файл базы.

Update:
Отшринкованный файл бэкапа будет весить чуть меньше.
6. sutygin 36 11.06.24 22:15 Сейчас в теме
Ну попробую на своей, может действительно быстрее
Оставьте свое сообщение