DBCC SHRINKFILE у файлі журналу не зменшує розмір навіть після РЕЗЕРВНОГО ВХОДУ НА ДИСК


77

У мене є база даних [Моя БД], яка містить таку інформацію: Розмір MDF
SQL Server 2008
: 30 ГБ
Розмір LDF: 67 ГБ

Я хотів максимально зменшити файл журналу, і тому я розпочав своє прагнення, щоб зрозуміти, як це зробити. Застереження: Я не DBA (і навіть не наближаюся до DBA), і прогресував, відчуваючи це завдання.

По-перше, я просто зайшов у SSMS, властивості БД, Файли та відредагував значення початкового розміру (МБ) до 10. Це зменшило файл журналу до 62 ГБ (не зовсім тих 10 МБ, які я ввів). Отже, я підключив SQL Profiler, побачив, що викликається DBCC SHRINKFILE. Потім я ввів цю команду в редактор запитів, і ось результати.

DBCC SHRINKFILE (N'My DB_Log' , 10)

І результат був:

Cannot shrink log file 2 (My DB_Log) because the logical log file located at the end of the file is in use.
DbId   FileId      CurrentSize MinimumSize UsedPages   EstimatedPages
------ ----------- ----------- ----------- ----------- --------------
8      2           8044104     12800       8044104     12800

(1 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Потім я провів кілька досліджень з цього приводу і виявив таке:

http://support.microsoft.com/kb/907511

Це говорить про те, що мені потрібно зробити резервну копію файлу журналу до shrinkfile, щоб файли віртуального журналу були звільнені, і shrinkfile міг виконати свою роботу - я не знаю, що це означає ... Я просто перефразую тут :)

Отже, я вирішив спробувати зробити резервну копію файлу журналу, а потім зробити DBCC SHRINKFILE (і я змінив новий розмір файлу журналу на 12800, оскільки це був мінімальний розмір, визначений у результатах попередньої команди DBCC SHRINKFILE)

BACKUP LOG [My DB] TO DISK = 'D:\SQLBackup\20110824-MyDB-Log.bak'
GO
DBCC SHRINKFILE (N'My DB_Log' , 12800)
GO

Результат був таким же, як і перший обхід. Я можу отримати лише файл журналу до 62 ГБ.

Я не впевнений, що я роблю неправильно і що мені слід спробувати далі.


щоб цього не повторювалося, слід запустити резервні копії журналів або встановити простий режим відновлення.
DForck42

3
Моєю проблемою було встановлення ПАУЗОВОГО РЕПЛІКУВАННЯ / ДЗЕРКАЛЕННЯ - здається, що sql не скоротить тлоги, якщо вважає, що вони потрібні для реплікації. Це, мабуть, не буде проблемою для багатьох людей, але деяким це може допомогти.
pettys

Відповіді:


43

На додаток до вже зроблених кроків, вам доведеться встановити простий режим відновлення, перш ніж зможете зменшити журнал.

ЦЕ НЕ РЕКОМЕНДОВАНА ПРАКТИКА для виробничих систем ... Ви втратите здатність відновлюватись до певного часу з попередніх резервних копій / файлів журналів.

Див. Приклад B на цій сторінці msdn DBCC SHRINKFILE (Transact-SQL) для прикладу та пояснення.


Просто з цікавості, чи можна побачити, що таке режим відновлення, пройшовши інтерфейс SSMS? Я переглянув властивості БД, але не побачив. Найближчою була сторінка Властивості / Параметри, яка відображає значення Відновлення / Перевірка сторінки.
Ед Сінек,

Знайшов - його немає в списку "Інші варіанти". Це вгорі сторінки - одне з трьох спадних меню. Дякую.
Ед Сінек,

5
Я збирався запропонувати запустити цей запит: виберіть recovery_model_desc, з sys.databases де name = 'ім'я бази даних'
jlnorsworthy

Дякую. Ключовим було зміна моделі відновлення :)
Аліреза,

133

Гаразд, ось рішення для зменшення фізичного розміру файлу транзакції, але без зміни режиму відновлення на простий.

Знайдіть у вашій базі даних ідентифікатор файлу журналу, використовуючи такий запит.

SELECT * FROM sys.database_files;

У моєму випадку файлом журналу є file_id 2. Тепер ми хочемо знайти віртуальні журнали, що використовуються, і зробимо це за допомогою наступної команди.

DBCC LOGINFO;

Тут ви можете побачити, чи використовуються які-небудь віртуальні журнали, перевіривши, чи є статус 2 (використовується) або 0 (безкоштовно). При скороченні файлів порожні віртуальні журнали фізично видаляються, починаючи з кінця файлу, поки він не досягне першого використовуваного стану. Ось чому скорочення файлу журналу транзакцій іноді скорочує його частково, але не видаляє всі безкоштовні віртуальні журнали.

Якщо ви помітили статус 2, що трапляється після 0, це блокує термоусадочну систему, щоб вона повністю не зменшила файл. Щоб обійти це, зробіть ще одну резервну копію журналу транзакцій і негайно запустіть ці команди, надавши ідентифікатор файлу, знайдений вище, та розмір, до якого ви хотіли б зменшити свій файл журналу.

-- DBCC SHRINKFILE (file_id, LogSize_MB)
DBCC SHRINKFILE (2, 100);
DBCC LOGINFO;

Потім відобразиться розподіл віртуального журналу, і, сподіваємось, ви помітите, що його було дещо зменшено. Оскільки файли віртуальних журналів не завжди розподіляються по порядку, можливо , вам доведеться зробити резервну копію журналу транзакцій пару разів і знову виконати цей останній запит ; але я звичайно можу зменшити його в межах резервної копії або двох.


6
Працював як оберіг. Резервне копіювання 99% безкоштовного журналу зайняло лише секунду, і файл відразу збільшився з понад 22000 МБ до 200 МБ. Це слід позначити як правильну відповідь.
Трійко

Я ціную довідкову інформацію. Однак я все ще застряг, бо думаю, що ваше рішення зводиться до рішення, яке оригінальний плакат спробував і не зміг приступити до роботи. Вашим рішенням є запуск "РЕЗЕРВНОГО ЛОГОСТИКА ... ПЕРЕЙТИ DBCC SHRINKFILE ..." кілька разів, поки він не спрацює? Я пробував кілька разів безрезультатно, і, схоже, ОП спробував це також без успіху. Просто хочу пояснити, чи не пропускаю я чогось у вашій відповіді.
pettys

3
ОНОВЛЕННЯ: моя проблема полягала в тому, що призупинена настройка реплікації / дзеркального відображення блокувала журнал. Можливо, це невеликий край.
pettys

4
@pettys так, якщо ви хочете зменшити файл до мінімально можливого розміру, вам потрібно зробити резервне копіювання, зменшення, резервне копіювання та зменшення - все за один раз. Причиною (я думаю, що це передбачається) є те, що термоусадочна система лише зменшує розмір файлу журналу до розміру "використаних сторінок" з часу останньої резервної копії; ймовірно, щоб звести до мінімуму необхідність нарощувати файл журналу, корисний для виробничого середовища, де відбувається регулярне завантаження та резервне копіювання. Вищезазначене намагається продемонструвати та налагодити це. Якщо у вашому журналі є 0, це може бути зменшено ще більше. Якщо ні, тоді можуть виникнути проблеми із випуском сторінок ваших резервних копій журналів.
Раддеж

13

Я використовую цей скрипт на SQL Server 2008 R2.

USE [db_name]

ALTER DATABASE [db_name] SET RECOVERY SIMPLE WITH NO_WAIT

DBCC SHRINKFILE([log_file_name]/log_file_number, wanted_size)

ALTER DATABASE [db_name] SET RECOVERY FULL WITH NO_WAIT

6
І, якщо ви зробите це, ви перервали ланцюжок резервного копіювання журналу транзакцій - таким чином, якщо, після скидання до ПОВНОГО відновлення, трапиться катастрофа ... ви на 100% втратите дані, ЩОБ ви не розпочали резервне копіювання ПОВНЕ або DIFF скидання до ПОВНОГО ВІДНОВЛЕННЯ. Крім того, З НЕ_ЗАЧЕКАЙТЕ означає, що Ви не даєте часу на виконання транзакцій під час польоту. Кращим варіантом буде ЗАВАНТАЖЕННЯ ПІСЛЯ 10 СЕКУНД (або щось подібне).
Michael K. Campbell

Як отримати ім'я чи номер журналу_файлу?
Kiquenet

10

Спробуйте це

ALTER DATABASE XXXX  SET RECOVERY SIMPLE

use XXXX

declare @log_File_Name varchar(200) 

select @log_File_Name  = name from sysfiles where filename like '%LDF'

declare @i int = FILE_IDEX ( @log_File_Name)

dbcc shrinkfile ( @i , 50) 


2

Я пробував багато способів, але це працює.

Зразок коду доступний у DBCC SHRINKFILE

USE DBName;  
GO  
-- Truncate the log by changing the database recovery model to SIMPLE.  
ALTER DATABASE DBName  
SET RECOVERY SIMPLE;  
GO  
-- Shrink the truncated log file to 1 MB.  
DBCC SHRINKFILE (DBName_log, 1);  --File name SELECT * FROM sys.database_files; query to get the file name
GO  
-- Reset the database recovery model.  
ALTER DATABASE DBName  
SET RECOVERY FULL;  
GO

1
Це насправді погана ідея, вона пропонується у прийнятій зараз відповіді із застереженням про те, чому це ПОГОЛО!
Джеймс Дженкінс

0

Я вирішив цю проблему, взявши повне резервне копіювання та транзакційне резервне копіювання. Іноді процес резервного копіювання не завершується, і це одна з причин, чому файл .ldf не стискається. Спробуйте це. У мене це спрацювало.


-1

Завдяки @ user2630576 та @ Ed.S.

наступне спрацювало:

BACKUP LOG [database] TO DISK = 'D:\database.bak'
GO

ALTER DATABASE [database] SET RECOVERY SIMPLE

use [database]

declare @log_File_Name varchar(200)

select @log_File_Name = name from sysfiles where filename like '%LDF'

declare @i int = FILE_IDEX ( @log_File_Name)

dbcc shrinkfile ( @i , 50)

ALTER DATABASE [database] SET RECOVERY FULL

Це насправді погана ідея, вона пропонується у прийнятій зараз відповіді із застереженням про те, чому це ПОГОЛО!
Джеймс Дженкінс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.