Не могу зайти в 1С [MSSQL the transaction log for database is full ]

Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: 1
Ответить
Не могу зайти в 1С [MSSQL the transaction log for database is full ]
1c\ MSSQL не пускает в 1С пишет the transaction log for database is full
ошибкой HRESULT=80040E14
Собственно ошибка СУБД в 1c не заходит
В SQL server managment студию заходит
Решать проблему будем поэтапно:
Причина возникновения ошибки: "transaction log for database is full" говорит о том что либо кончилось место на массиве или log фаил (ldf) невозможно увеличить размер файла, т.к достигнут максимального значения: server management - выбираем нужную базу - property - files - autogrowth log напротив лог файла и увеличиваем поле: Maximum File Size
А теперь рассмотрим вариант, когда закончилось место на массиве где расположен log фаил(ldf) и его надо срочно уменьшить:  
Для урезания лога открываем Management Studio, выбираем нужную базу, нажимаем на ней правой клавишей мыши и в открывшемся контекстном меню выбираем пункт «Properties». Переходим на вкладку «Options» и изменяем модель восстановления базы (Recovery model) на Simple.

В том же контекстном меню переходим в раздел Tasks(Задачи) -> Shrink(Обрезка) -> Files(Файлы). В поле File type(Тип файла) выбираем Log, в поле File name(имя файла) указываем имя файла логов. В поле «Shrink action» выбираем «Reorganize pages before releasing unused space»(Реорганизовать страницы, перед тем как освободить неиспользуемое пространство), задаем желаемый размер файла и жмем ОК.

После завершения операции возвращаем режим восстановления базы обратно в Full.
Тоже самое можно проделать из Query Analizer с помощью скрипта:
USE ″Имя базы″
ALTER DATABASE ″Имя базы″ SET RECOVERY SIMPLE
DBCC SHRINKFILE (″Имя файла лога″, ″Желаемый размер″);
ALTER DATABASE ″Имя базы″ SET RECOVERY FULL
Услуги Системного Администратора - Работаю только с Юр. Лицами по договору обслуживания.
transaction log for database is full еще ряд вариантов по его уменьшению:
1)
USE [Database]
ALTER DATABASE [Database] SET RECOVERY SIMPLE
go
DBCC SHRINKFILE ([Database]_log, 1);
ALTER DATABASE [Database] SET RECOVERY FULL
go

2)
USE [Database]
BACKUP LOG [Database] TO DISK='NUL:'
go
DBCC SHRINKFILE ([Database]_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 '[Database]'

Собственно после этого бэкап и 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]

Где Process ID - это тот самый SPID полученный на предыдущем шаге. При этом незавершенные транзакции откатятся средствами MS SQL Server. Возможно при "убийстве" процесса будут завершены и несколько сеансов 1С, но  вряд ли много. Сервер 1С поддерживает собственный пул соединений с MS SQL, соответственно соединения из этого пула используются только тогда, когда серверу что-то нужно от СУБД. При этом если соединение занято (а оно как видим занято) вряд ли оно будет использоваться для других процессов.

Но предварительно (!) если хотите всё-таки разобраться в проблеме рекомендую выполнить скрипт вроде:

DECLARE @sqltext VARBINARY(128)
SELECT @sqltext = sql_handle
FROM sys.sysprocesses
WHERE spid = [Process ID]
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 [Database] SET EMERGENCY

9) exec sp_dboption [Database], 'single user', 'TRUE'
Монопольный режим работы с БД

10) DBCC CHECKDB ([Database], REPAIRALLOWDATA_LOSS)
Ключевая операция - "возвращает БД к жизни". Может выполняться достаточно долго - до получаса на больших БД. Ни в коем случае не прерывайте эту операцию. Результат, где будут собраны исправленные ошибки
на всякий случай сохраните

11) exec sp_dboption [Database], 'single user', 'FALSE'
Сбрасываем монопольный режим

12) ALTER DATABASE [Database] SET ONLINE
Делаем базу доступной.

После чего получаем БД с чистым новеньким логом. На самом деле операция достаточно проста и в большинстве случае не несёт никаких критических последствий. Но всё-таки рекомендую прибегать к ней только в крайнем случае. Описана она не раз и в разных вариациях. Привожу свой вариант, который показался наиболее простым и понятным.
Услуги Системного Администратора - Работаю только с Юр. Лицами по договору обслуживания.
И немного про причины и как оно должно быть:
Урезание логов производится автоматически, в зависимости от модели восстановления:

• В простой модели (Simple) — после достижения контрольной точки;
• В модели полного восстановления (Full) — после создания backup логов, при условии что со времени предыдущего backup была достигнута контрольная точка.

Подобная ситуация, как правило, происходит с моделью восстановления Full, при использовании которой лог нельзя обрезать до тех пор, пока в резервную копию не попали все транзакции. Это необходимо для того, чтобы обеспечить наличие непрерывную последовательность номеров (LSN) записей в журнале. Соответственно для урезания надо либо сделать полное резервное копирование БД, либо (что проще и быстрее) временно перевести ее в режим Simple.

Дифференцированный бэкап — это что-то среднее между полным бэкапом и бэкапом лога. В нем сохраняются изменения, сделанные с момента последнего полного бэкапа по настоящее время. Главным его преимуществом по сравнению с бэкапом лога является то, что для полного восстановления базы данных вам достаточно восстановить только лишь полный и последний дифференцированный бэкапы. Недостатком же является то, что вы не можете восстановить промежуточное состояние базы данных на какой-то момент времени — история изменения БД в дифференцированном бэкапе не сохраняется. Как и бэкап лога, такой бэкап бесполезен, если у вас нет полной копии базы данных.

т.е в модели Full вы можете делать Дифференцированный бэкап и очищать лог пред полным бэкапом базы.
И это надо делать автоматически а не в середине дня "шринковать" лог т.к после этой операции не будут работать Дифиринциальные бэкапы и инкриментные, до полного бэкапа базы.
Услуги Системного Администратора - Работаю только с Юр. Лицами по договору обслуживания.
Доброго всем суток.
Очень интересный и познавательный пост. А можно немного оп причинах и как избавиться от наполнения логов.
Спасибо!
В таком случае используйте простой модели (Simple) -  Данная модель восстановления будет хранить минимальный набор данных в журнале транзакций. При заполнении файла журнала транзакций на 70%, СУБД начнет писать данные о транзакциях в начало файла, затирая данные предыдущих транзакций. При этой модели файл журнала транзакций будет занимать отведенное для него место  и не представляется возможным  хранить историю транзакций.

СКРИПТ ДЛЯ ШРИНКОВАНИЯ ВСЕХ БАЗ НА СЕРВЕРЕ MSSQL
Услуги Системного Администратора - Работаю только с Юр. Лицами по договору обслуживания.
Страницы: 1
Ответить
Форма ответов
 
Текст сообщения*
:) ;) :D 8-) :( :| :cry: :evil: :o :oops: :{} :?: :!: :idea:
Защита от автоматических сообщений. Введите символы, изображенные на этой картинке в поле ввода &quote;Код подтверждения&quote;.