Журнал транзакций SQL

Для MS SQL 2008/2012 рекомендации ИТС уже устарели, кроме того и раньше они не всегда помогали. В статье попытался собрать наиболее полный комплект информации по данному вопросу.
В своё время в одном месте всего этого не нашел, поэтому думаю будет полезно.
Популярная статья ИТС http://its.1c.ru/db/metod81#content:2373:1 устарела — теперь уменьшение размера журнала транзакций стало не самой простой операцией.
Собственно там рекомендуется следующий скрипт:
BACKUP LOG Имя_Базы_Данных WITH TRUNCATE_ONLY

DBCC SHRINKFILE(Имя_Файла_Журнала_Транзакций)

Если выполнить его в MS SQL 2008/2012 получите ошибку:
‘truncate_only’ is not a recognized BACKUP option

Подробно:

Что теперь делать?
Решения, собственно два:
1)
USE
ALTER DATABASE SET RECOVERY SIMPLE
go
DBCC SHRINKFILE (_log, 1);
ALTER DATABASE SET RECOVERY FULL
go
2)
USE
BACKUP LOG TO DISK=’NUL:’
go
DBCC SHRINKFILE (_log, 1)
go
Если «Урезанием лога» не злоупотреблять (т.е. сокрашать лог вместе с полной копией) то по большому счету не принципиально каким методом пользоваться.
Второй вроде как правильнее, зато первый «надежнее».
На этом казалось бы можно и остановиться, но зачем тогда отдельную статью писать. Нет, конечно это ещё не всё. Обычно вопросы про урезание лога возникают когда это сделать не получается.
Притом способы, описанные выше, как правило, описаны не раз, все их освоили и проблем не вызывают.
Итак, если все действия, описанные выше не помогли — лог файл по-прежнему занимает N гигабайт. Переходим к плану B:
select log_reuse_wait_desc from sys.databases
В результате можете получить 3 варианта:
а. Пусто — Обычно это означает что у БД лог можно хоть сейчас полностью сократить, могу предложить только попробовать ещё раз Shrink, а если не поможет — переходить к плану C
b. Log_Backup — Нормальный варинат. В данном случае говорит о том, что Backup Log не выполнено, или выполнено некорректно
b. Replication — значит что ваш лог не обрезается из за репликации — скорее всего ошибки.
с. Active transactions — Самая частая ситуация — в базе есть подвисшие транзакции, с ними нужно разобраться.
Replication — Репликация для систем на платформе 1С, пожалуй, бессмысленное дело. Потому как Read only баз MS SQL не бывает, средства создания распределенных систем в 1С есть собственне (да, я про РИБ). Для обеспечения отказоустойчивости гораздо лучше подходят кластерные технологии. Собственно рекоммендация простая:
sp_removedbreplication »
Собственно после этого бэкап и Shrink помогут. Если же вопреки здравому смыслу вы всё-таки хотите сохранить репликацию БД то конечно выполнять эту команду нельзя, а нужно разбираться с ошибками репликации. Но это уже тема отдельной статьи.
Active transactions — наиболее популярная история. В базе есть транзакции, которые не завершены, и чего то ожидают. Чащи всего такие транзакции получаются при потере сетевого соединения или «вылете» клиента 1С в момент записи в БД. В этом случае нужно собственно узнать какая транзакция «повисла»:
DBCC OPENTRAN
После выполнения этой команды вы получите примерно следующий результат:
Transaction information for database ‘master’.
Oldest active transaction:
SPID (server process ID) : 52
UID (user ID) : -1
Name : user_transaction
LSN : (518:1576:1)
Start time : May 5 2014 3:30:07:197PM
SID : 0x010500000000000515000000a065cf7e784b9b5fe77c87709e611500
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
Из этого обилия информации ключевым является Start Time и SPID. Если транзакция в базе 1С выполняется боле нескольких секунд это уже означает что что-то не так. А если start Time будет минут 10 или более от текущего времени — такие транзакции (сеансы) нужно завершать. Но предварительно я бы рекоммендовал узнать что эта транзакция делала.
Для завершения процесса можно ввести команду
KILL
Где Process ID — это тот самый SPID полученный на предыдущем шаге. При этом незавершенные транзакции откатятся средствами MS SQL Server. Возможно при «убийстве» процесса будут завершены и несколько сеансов 1С, но вряд ли много. Сервер 1С поддерживает собственный пул соединений с MS SQL, соответственно соединения из этого пула используются только тогда, когда серверу что-то нужно от СУБД. При этом если соединение занято (а оно как видим занято) вряд ли оно будет использоваться для других процессов.
Но предварительно (!) если хотите всё-таки разобраться в проблеме рекомендую выполнить скрипт вроде:
DECLARE @sqltext VARBINARY(128)
SELECT @sqltext = sql_handle
FROM sys.sysprocesses
WHERE spid =
SELECT TEXT
FROM sys.dm_exec_sql_text(@sqltext)
GO
В результате вы получите текст команды SQL Server, на которой, собственно, всё и «зависло». Из неё вам нужна будет таблица в которую производилась запись, далее используя функцию «ПолучитьСтруктуруХраненияБазыДанных()» вы определите таблицу в терминах объектов метаданных в которую производилась запись и смотрите код. Как правило такие неприятные последствия происходят:
1) Ошибки в сетевых подключениях (для толстого клиента в т.ч. в сетевых подключениях клиентов, для тонкого — только в проблемах сети между сервером 1С и MS SQL).
2) Каких то неправильных действиях (отправка почты, запись в файл, запуск внешних обработок, чтения из файла) производимых в транзакциях (при записи, при проведении)
Собственно от них надо избавляться.
Если ничего не помогло (или план B)
ВНИМАНИЕ! Перед выполнением процедур, описанных ниже, сделать полную резервную копию файлов БД MS SQL нужно обязательно!!!!
Есть ещё один — более радикальный способ решения вопроса роста журнала транзакций MS SQL. Но я лично его бы не рекомендовал к использованию. Тем не менее, специалисты Microsoft тоже могут ошибаться,
и SQL Server может содержать ошибки, о которых мы регулярно читаем в BugFix, или же наблюдаем сами, поэтому приведу и этот способ.
Суть его заключается в том что журнал транзакций просто удаляется и создается новый. При этом вы конечно теряете информацию из него и БД можно будет восстановить только из полной копии (которую вы конечно перед этим сделали).
Конечно при этом, особенно если в базе были всё-таки не зафиксированные может быть нарушена логическая целостность, но для этого запускается CheckDB которая в общем и целом приводит базу в порядок. Для аналогии это то же самое что в 1С проврять ссылочную целостность с опцией «Удалять если не найден». Если транзакция полностью не зафиксирована, но от неё остались частично данные, что противоречит принципу атомарности транзакций — эти данные будут удалены.
Итак приступим:
1) Detach БД из списка
2) Фал *.ldf удаляем (вы же его сохранили уж, да?)
3) Файл *.mdf переименовываем (в любое имя какое нравится)
4) В MS SQL создаём новую (!!!) БД с тем же именем, с каким была «больная» БД
5) Останавливаем MS SQL Server
6) Новый *.mdf файл удаляем, а старый переименовываем под «старое имя», подменяя тем самым файл новой БД
7) Запускаем MS SQL Server. При этом будет «битая БД», далее мы её исправляем
8) ALTER DATABASE SET EMERGENCY
9) exec sp_dboption , ‘single user’, ‘TRUE’
Монопольный режим работы с БД
10) DBCC CHECKDB (, REPAIRALLOWDATA_LOSS)
Ключевая операция — «возвращает БД к жизни». Может выполняться достаточно долго — до получаса на больших БД. Ни в коем случае не прерывайте эту операцию. Результат, где будут собраны исправленные ошибки
на всякий случай сохраните
11) exec sp_dboption , ‘single user’, ‘FALSE’
Сбрасываем монопольный режим
12) ALTER DATABASE SET ONLINE
Делаем базу доступной.
После чего получаем БД с чистым новеньким логом. На самом деле операция достаточно проста и в большинстве случае не несёт никаких критических последствий. Но всё-таки рекомендую прибегать к ней только в крайнем случае. Описана она не раз и в разных вариациях. Привожу свой вариант, который показался наиболее простым и понятным.

Tags: 1С, erp, ms sql, Администрирование

При обновлении бухгалтерии, на этапе сохранения, получил следующую ошибку:

по причине: Ошибка СУБД: Microsoft SQL Server Native Client 11.0: Журнал транзакций для базы данных «acc_main» переполнен. Причина: «LOG_BACKUP». HRESULT=80040E14, SQLSrvr: SQLSTATE=42000, state=2, Severity=11, native=9002, line=1
Идем на сервер и первым делом проверяем место на дисках,

А оно закончилось нужно потом почистить хард или увеличивать объем, а пока порежем лог

Открываем SQL Server Management Studio

Это ошибка Microsoft SQL Server — переполняется лог транзакций и не очищается. Урезать его возможно различными способами, в том числе и с помощью стандартной оснастки, но не всегда данная операция получается, и размер файла лога остается прежним. Как вариант предлагаю следующее решение из двух строчек( где acc_main — название базы Бух)

Код SQL USE acc_main ALTER DATABASE acc_main SET RECOVERY SIMPLE DBCC SHRINKFILE (acc_main, 50); ALTER DATABASE acc_main SET RECOVERY FULL

Результат выполнения:

Тоже самое можно сделать вручную:

Шаг 1. Установить модель восстановления Простая (Simple). Правой кнопкой на базе — Свойства(Properties) — Параметры(Options) — 4-й сверху пункт Модель восстановления(Recovery model) — Простая(Simple) — OK.

Шаг 2. Выполнить шринк (сжатие) лога транзакций. Правой кнопкой на базе — Задачи(Tasks) — Сжать(Shrink) — Файлы(Files) — установить Тип файла(File type) — Журнал(Log) — в Операция сжатия(Shrink action) — выбрать Реорганизовать страницы, перед тем осводить неиспользуемое место(Reorganize pages before releseasing unused space) — Сжать файл (Shrink file to) — указать приемлемый размер лога.

Шаг 3. Установить модель восстановления Полная(Full). Правой кнопкой на базе — Свойства(Properties) — Параметры(Options) — 4-й сверху пункт Модель восстановления(Recovery model) — Полная(Full) — OK.

В дополнении скажу, что можно сохранить лог в файл и выполнить шринк так(BaseDB — имя базы данных):

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

Увеличиваем размер журнала транзакций.

Запускаем SQL Server Management Studio, заходим в свойства базы и выбираем пункт .

Для типа файла «Журнал» увеличиваем максимальный размера файла для авторасширения.

Сжимаем файл журнала транзакций.

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

Запускаем SQL Server Management Studio, заходим в свойства базы и выбираем пункт . Модель восстановления выбираем «Простая» и нажимаем ОК.

Далее правой клавишей мышки по базе и выбираем из контекстного меню — —

Тип сжатия: Журнал
Операция сжатия: Реорганизовать файлы, перед тем как освободить неиспользуемое место
И указываем размер до которого необходимо сжать, например 0.

Теперь нужно вернуться в свойства базы к пункту и переключить модель восстановления на «Полная».

Ошибка СУБД:
Microsoft OLE DB Provider for SQL Server: Журнал транзакций для базы данных «zup» заполнен. Чтобы обнаружить причину, по которой место в журнале не может быть повторно использовано, обратитесь к столбцу log_reuse_wait_desc таблицы
sys. databases HRESULT=80040E14, SQLStvr: Error state=2, Severity=11,native=9002, line=1
или
Ошибка СУБД:
Microsoft OLE Provider for SQL Server: The transaction log for database «DataBase” is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column is sys.database
HRESULT=80040E14, SQLSTATE=4 2000, native=9002
Решение:
1. Посмотрите сколько свободного места осталось на дисках, может его нет и логу некуда записаться…
2. Это ошибка Microsoft SQL Server — переполняется лог транзакций и не очищается. Урезать его возможно различными способами, в том числе и с помощью стандартной оснастки, но не всегда данная операция получается, и размер файла лога остается прежним. Как вариант предлагаю следующее решение из двух строчек:
для использования убрать символ _

Add a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *