Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.59/29: Рейтинг темы: голосов - 29, средняя оценка - 4.59
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240

Экстремальное увеличение размера файла журнала при удалении записей

18.05.2020, 08:19. Показов 6477. Ответов 28

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
При удалении записей из одной таблицы файл журнала очень сильно увеличивается в размерах, пока не займёт всё свободное место на диске. После этого операция удаления прекращается с ошибкой.
Размер базы - 2.1 ГБ.
В таблице, из которой удаляются записи, содержится 15 млн записей. Вместе с индексами она занимает примерно 1 ГБ (т.е. половину от общего размера базы). Удалить необходимо 13 млн записей. На диске, на котором расположена база и журнал свободно 17 ГБ. Файл журнала на момент возникновения ошибки имеет примерно такой же размер - 17 ГБ.
Много раз делал подобную операцию, всегда проходила без проблем (на этом же ПК и с таким же размером свободного места).
Пришлось удалять по частям.
Вопрос - по каким причинам размер журнала может превысить размер базы в 8 раз? И что можно сделать в такой ситуации (кроме удаления меньшими порциями)?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.05.2020, 08:19
Ответы с готовыми решениями:

Как уменьшить увеличение размера журнала базы?
Добрый день! Вопрос следующий - в ходе выполнения хранимой процедуры на MS сервере 2008 создается таблица, в которую помещаются записи из...

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

Увеличение размера файла
У меня есть на входе файл. Он открывается только для чтения (содержимое НЕ должно изменяться). Для дальнейшей работы необходимо, чтобы...

28
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,148
Записей в блоге: 3
18.05.2020, 09:30
Цитата Сообщение от СергейР Посмотреть сообщение
И что можно сделать в такой ситуации
перенести нужные данные в новую таблицу, первую дропнуть, новую переименовать

Цитата Сообщение от СергейР Посмотреть сообщение
по каким причинам размер журнала может превысить размер базы в 8 раз?
а где написано что нельзя?
при удалении что происходит?
1
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
18.05.2020, 09:49  [ТС]
Цитата Сообщение от qwertehok Посмотреть сообщение
перенести нужные данные в новую таблицу, первую дропнуть, новую переименовать
Спасибо, это вариант.

Цитата Сообщение от qwertehok Посмотреть сообщение
а где написано что нельзя?
при удалении что происходит?
Я понимаю, что фиксируются все изменения пока транзакция не завершится. Непонятно, почему при удалении ~800 Мб данных журнал увеличивается более чем в 17 раз.
Или это нормально? Просто я раньше никогда не наблюдал за размером журнала при удалении данных.
0
5962 / 4538 / 1094
Регистрация: 29.08.2013
Сообщений: 28,148
Записей в блоге: 3
18.05.2020, 09:55
Цитата Сообщение от СергейР Посмотреть сообщение
Или это нормально?
нормально
можно еще после каждой итерации удаления усекать журнал, но это так себе
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
18.05.2020, 10:12
Цитата Сообщение от СергейР Посмотреть сообщение
Или это нормально?
Нет, не нормально.
Смотрите есть ли на таблице триггеры или может она задействована в индексированных представлениях.

Если хотите выяснить что происходит, то можно удалить несколько строк и посмотреть, что пишется в ЖТ функцией sys.fn_dblog
0
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
18.05.2020, 11:16  [ТС]
Цитата Сообщение от invm Посмотреть сообщение
Смотрите есть ли на таблице триггеры или может она задействована в индексированных представлениях.
Триггеров нет. В представлениях не участвует
Есть первичный ключ (Identity) и два индекса, один по полям типа int, другой - int + datettime. Дефрагментация обоих индексов - 95%.
Удаление производилось по дате.

Провёл следующие эксперименты:
1. Провёл точно такую же операцию на рабочем компе с большим количеством свободного места. Данные удалились, журнал достиг 17.5 ГБ;
2. Переиндексировал всю базу. Результат тот же;
3. Сделал удаление по Id. То же самое.

Цитата Сообщение от invm Посмотреть сообщение
можно удалить несколько строк и посмотреть, что пишется в ЖТ функцией sys.fn_dblog
Буду копать в этом направлении...
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
18.05.2020, 11:29
СергейР, чудес не бывает.
При удалении в ЖТ пишется информация для undo, т.е. для обратной операции, т.е. для insert
Поэтому этой информации не может быть много больше, чем объем удаляемых данных и индексов.
И от критериев удаления это вообще не зависит.
1
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
19.05.2020, 08:01  [ТС]
Удалил, посмотрел.
На каждую удалённую строку в журнал добавляется 3 строки: на каждый индекс и первичный ключ. Вроде всё логично.
И ещё добавляется примерно 6% от общего количества записей с операцией LOP_SET_BITS. В итоге на 300 тыс удалённых записей получается примерно 318 тыс строк в журнале.
Какие именно поля анализировать в журнале?
P.S. Приложил файл в формате Excel (выгрузка из журнала после удаления 100 записей).
Вложения
Тип файла: 7z Журнал (удаление 100 записей).7z (77.4 Кб, 2 просмотров)
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
19.05.2020, 09:44
СергейР, у вас кластерная таблица. Соответственно, как и для всех индексов, строки не удаляются, а помечаются удаленными - LCX_MARK_AS_GHOST. Физически удаляются уже потом асинхронно системным процессом GHOST CLEANUP
Поэтому сразу вычислить насколько вырастет журнал не получится. Нужно с некоторой задержкой.
LOP_SET_BITS - операция модификации страницы PFS. Это служебные страницы для отслеживания свободного места на страницах данных.
0
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
19.05.2020, 10:24  [ТС]
Удалил 100 записей, подождал несколько минут и выгрузил данные (664 строки). Получается по 6+ строк на каждую удалённую запись. Что дальше с этим делать?
Вложения
Тип файла: 7z Журнал (удаление 100 записей+задержка).7z (131.6 Кб, 1 просмотров)
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
19.05.2020, 10:58
СергейР, анализировать записи ЖТ нужно было для поиска чего-либо, не относящегося именно к удалению строк. Такового не нашлось.

Посмотреть сколько транзакция съела в ЖТ можно так
T-SQL
1
2
3
4
5
6
7
8
9
10
begin tran;
delete from ...;
 
select
 sum(dt.database_transaction_log_bytes_used), sum(вt.database_transaction_log_bytes_used_system)
from
 sys.dm_tran_current_transaction ct join
 sys.dm_tran_database_transactions dt on dt.transaction_id = ct.transaction_id;
 
rollback;
И покажите оценочный план
T-SQL
1
2
3
4
5
6
set showplan_xml on;
go
delete from ...;
go
set showplan_xml off;
go
с реальной командой delete, откройте получившийся план выполнения, сохраните его в файл с расширением sqlplan и выложите сюда.

ЗЫ: Реально ничего не удалится, просто выведется оценочный план выполнения.
0
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
19.05.2020, 15:18  [ТС]
invm, сделал всё, как Вы написали. План приложил.

Первый скрипт выдал следующее:

(строк обработано: 12 901 826)

(строк обработано: 1)

Sum(dt.database_transaction_log_bytes_us ed), Sum(dt.database_transaction_log_bytes_us ed_system)
4 723 553 148, 0

Размер файла журнала - 17 592 896 КБ
Вложения
Тип файла: 7z Удаление данных (план выполнения).7z (2.3 Кб, 1 просмотров)
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
19.05.2020, 16:08
СергейР, удаление отожрало в журнале всего 4 Гб. В плане ничего лишнего нет.

Цитата Сообщение от СергейР Посмотреть сообщение
Файл журнала на момент возникновения ошибки имеет примерно такой же размер - 17 ГБ.
Так журнал растет до 17 Гб или просто его файл занимает 17 Гб?

Если первое, то растет не из-за удаления.
Если второе, то посмотрите, что вернет после возникновения ошибки запрос
T-SQL
1
select log_reuse_wait_desc from sys.databases where database_id = db_id('Наименование БД');
?
0
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
20.05.2020, 09:00  [ТС]
invm, журнал растёт при удалении записей.
После восстановления из бекапа размер файла журнала 42 МБ. А после завершения удаления 17 ГБ.
Никаких других операций с базой не делал.

Ограничил своодное место на диске с базой и журналом до 10 ГБ и запустил скрипт на удаление записей.
Когда файл журнала достиг 10 ГБ, а места на диске осталось 45 МБ скрипт прервался со следующей ошибкой:
Сообщение 9002, уровень 17, состояние 4, строка 2
Журнал транзакций для базы данных переполнен. Причина: "ACTIVE_TRANSACTION".

Ваш скрипт выдал выдал следующее:
log_reuse_wait_desc
------------------------------------------------------------
NOTHING
(строк обработано: 1)

P.S. То же самое он выдавал и до начала удаления.
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
20.05.2020, 13:17
СергейР, по вашим же данным обычная команда delete from where не может генерировать ЖТ на 17 Гб.
Можете скопировать таблицу + индексы в другую БД, запустить там удаление и посмотреть сколько ЖТ будет скушано.

Добавлено через 42 минуты
Кстати есть вариант, когда будет генерироваться большой объем ЖТ.
Это когда данные (или подавляющее большинство данных) в таблицу заносились при выключенном READ_COMMITTED_SNAPSHOT, а потом эту опцию включили.

Добавлено через 23 минуты
Ну и пример вышесказанного
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use master;
set ansi_nulls, quoted_identifier, xact_abort on;
go
 
create database TestDel;
alter database TestDel set read_committed_snapshot off;
go
 
use TestDel;
go
 
create table dbo.t (id int identity, a int, s char(20));
insert into dbo.t
 (a, s)
 select top (100000)
  1, 'a'
 from
  master.dbo.spt_values a cross join
  master.dbo.spt_values b;
go
 
begin tran;
delete from dbo.t where a > 0;
 
select
 'read_committed_snapshot = off', sum(dt.database_transaction_log_bytes_used), sum(dt.database_transaction_log_bytes_used_system)
from
 sys.dm_tran_current_transaction ct join
 sys.dm_tran_database_transactions dt on dt.transaction_id = ct.transaction_id;
 
rollback;
go
 
alter database TestDel set read_committed_snapshot on;
go
 
begin tran;
delete from dbo.t where a > 0;
 
select
 'read_committed_snapshot = on', sum(dt.database_transaction_log_bytes_used), sum(dt.database_transaction_log_bytes_used_system)
from
 sys.dm_tran_current_transaction ct join
 sys.dm_tran_database_transactions dt on dt.transaction_id = ct.transaction_id;
 
commit;
go
 
use master;
drop database TestDel;
go
0
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
21.05.2020, 15:19  [ТС]
Провёл 2 эксперимента:
1. В рабочей базе удалил из таблицы ссылки на внешние ключи (2 шт) и запустил скрипт на удаление с подсчётом размера транзакции.
Результат с точностью до байта совпал с предыдущими результатами.

2. Перенёс таблицу в новую пустую базу (данные переместил с помощью мастера импорта, индексы создал скриптами).
Ужал журнал транзакций до 1 МБ и запустил скрипт на удаление с подсчётом размера транзакции.
Скрипт выдал размер транзакции 4 679 034 288.
Изменение размеров файлов до и после удаления на скриншотах (слева - после сжатия ЖТ, справа - после удаления данных).
Практически те же самые показатели, что и при удалении из рабочей базы.

Опция READ_COMMITTED_SNAPSHOT в базе выключена. Принудительно я её точно не включал.
Миниатюры
Экстремальное увеличение размера файла журнала при удалении записей   Экстремальное увеличение размера файла журнала при удалении записей  
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
21.05.2020, 16:19
СергейР, чудес не бывает. Что-то, раздувающее ЖТ да происходит в БД.

1. Подготовьте обе БД к удалению. Желательно их вообще перевести в монопольный режим.
2. Очистите и усеките ЖТ в обеих.
3. В обеих выполните
T-SQL
1
2
3
4
5
6
7
begin tran;
 
select AllocUnitName, sum([Log Record Length]) from sys.fn_dblog(null, null) group by AllocUnitName order by 2 desc;
delete ...
select AllocUnitName, sum([Log Record Length]) from sys.fn_dblog(null, null) group by AllocUnitName order by 2 desc;
 
commit;
Сравните результаты.

ЗЫ: Может выполняться долго из-за sys.fn_dblog
0
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
22.05.2020, 13:11  [ТС]
Цитата Сообщение от invm Посмотреть сообщение
Сравните результаты.
Сжал ЖТ и перевёл базы в режим SINGLE USER. В каждой базе запустил скрипт.
Суммарное значение (по 3-м индексам) в обоих случаях примерно равно тому, что выдавали скрипты раньше ~4.5 ГБ.
Файлы журналов в обоих случаях достигли тех же размеров - 17.5 ГБ.
Миниатюры
Экстремальное увеличение размера файла журнала при удалении записей  
Вложения
Тип файла: Рабочая база - Группировка по объектам в ЖТ до и посл (33.9 Кб, 2 просмотров)
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
22.05.2020, 13:25
СергейР, смотрите в настройках БД размер приращения для файла журнала. Видимо стоит дефолтное 10%
Поставьте фиксированное значение, например 100 Мб или больше. Меньше не нужно - будет не очень хорошо.
0
12 / 13 / 5
Регистрация: 21.08.2012
Сообщений: 240
22.05.2020, 20:16  [ТС]
Цитата Сообщение от invm Посмотреть сообщение
СергейР, смотрите в настройках БД размер приращения для файла журнала. Видимо стоит дефолтное 10%. Поставьте фиксированное значение, например 100 Мб или больше.
Да, действительно. Стояло дефолтное 10%. Изменил на 100 Мб и ещё раз удалил данные. Итоговый размер файла ЖТ уменьшился на несколько десятков Мб.

Похоже, итоги поря подводить.
В таблице 15 млн записей. Первичный ключ и 2 индекса. Размер таблицы 500 Мб, размер индексов 600 Мб.
При удалении 13 млн записей (на каждую удаляемую запись создаётся 6 записей в ЖТ) размер транзакции, вычисленный скриптами, достигает 4.5 Гб. А размер файла ЖТ достигает 17.5 Гб.

У данного эффекта высокая повторяемость:
- в рабочей базе, в которой таблица заполнялась и в 2-х пустых базах, куда таблица импортировалась;
- на 2-х разных серверах (SQL Server 2012 Expr & SQL Server 2017 Expr);
- на 2-х ПК (Win 7 x32 & Win 10 x64);
- с приращением журнала в % (10%) и в мегабайтах (100 Мб);

Объяснить логически, как транзакция размером 4.5 Гб увеличивает размер файла ЖТ до 17.5 Гб (в 4 раза) я не могу. Но если эффект такой стабильный, может так и должно быть?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.05.2020, 20:16
Помогаю со студенческими работами здесь

Увеличение размера файла .exe
Здравствуйте! Возник вопрос о том, как увеличить размер файла, без его изменения иконки, пробовал команду: copy /B Исходный.EXE+Второй...

ошибка при удалении записей из бд
при удалении данных выскакивает ошибка: Удаление или изменение записи невозможно. В таблице "Аудитории" имеются связанные записи....

Упорядочить идентификаторы при удалении записей
Всем привет. Проблема такая, в таблице есть уникальный идентификатор записи 1,2,3, ..... и т.д. При удалении какой нить записи напр 2...

Ошибка при удалении повторяющихся записей
Добрый день! есть табличка Id_zavtag zav_number tag 1 5 5 2 ...

Исключительная ситуация при удалении записей
Доброго времени суток, возникла проблема при создании исключительной ситуации. Опишу проблему поподробнее, Есть таблица из которой будут...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru