یکی از رایجترین سوالهای DBAهای تازهکار این است: «چرا فایل .ldf پایگاهدادهام چند برابر فایل .mdf شده؟» جواب کوتاه: SQL Server هر تراکنش را قبل از اعمال روی داده، ابتدا در Transaction Log ثبت میکند (به این مکانیزم Write-Ahead Logging میگویند). اگر این لاگ هیچوقت «پاکسازی» (Truncate) نشود، همیشه در حال رشد خواهد بود.
Truncate شدن Log به این معنی نیست که فایل کوچکتر میشود؛ یعنی فضای داخل همان فایل که دیگر لازم نیست (چون تراکنشهای مربوطه کامل شدهاند) دوباره قابل استفاده میشود. اگر Log هیچوقت Truncate نشود، فضای خالی داخلش تمام میشود و SQL Server مجبور است فایل را با Auto Growth بزرگتر کند — این همان چیزی است که باعث رشد بیرویه میشود.
مهمترین عامل در رفتار Transaction Log، تنظیم Recovery Model پایگاهداده است:
| Recovery Model | رفتار Log | چه زمانی مناسب است |
|---|---|---|
SIMPLE | بعد از هر Checkpoint، خودکار Truncate میشود | پایگاهدادههای تست/توسعه یا جایی که ازدسترفتن چند دقیقه داده قابل قبول است |
FULL | فقط با گرفتن Log Backup Truncate میشود | سیستمهای Production که نیاز به بازیابی تا لحظهی دقیق خرابی (Point-in-Time Recovery) دارند |
BULK_LOGGED | مشابه FULL، با لاگ کمتر برای عملیاتهای حجیم | Import های حجیم موقت |
FULL Recovery Model است، اما هیچوقت Log Backup گرفته نمیشود. در این حالت، Log تا ابد رشد میکند چون هیچ عاملی آن را Truncate نمیکند.اگر پایگاهداده روی FULL Recovery Model است (که برای اکثر سیستمهای Production توصیه میشود)، باید یک Job زمانبندیشده برای گرفتن Log Backup داشته باشی — مثلاً هر ۱۵ تا ۳۰ دقیقه:
-- گرفتن یک Log Backup (باعث Truncate شدن بخش استفادهشدهی Log میشود) BACKUP LOG ShopDB TO DISK = N'D:\Backups\ShopDB_log.trn';
برای آشنایی با انواع Backup و تفاوتشان، راهنمای تفاوت Full، Differential و Transaction Log Backup را ببین.
اگر با وجود گرفتن Log Backup، همچنان Log بزرگ میماند، این کوئری دلیل را نشان میدهد:
SELECT name, log_reuse_wait_desc FROM sys.databases WHERE name = N'ShopDB';
| log_reuse_wait_desc | معنی |
|---|---|
| NOTHING | مشکلی نیست، Log آزاد است |
| LOG_BACKUP | منتظر گرفتن Log Backup است |
| ACTIVE_TRANSACTION | یک تراکنش طولانی هنوز باز است (Commit/Rollback نشده) |
| REPLICATION | Replication هنوز این بخش از Log را نخوانده |
| AVAILABILITY_REPLICA | یک Replica در Always On هنوز همگام نشده |
بعد از رفع علت اصلی (مثلاً بعد از گرفتن یک Log Backup که Truncate را انجام میدهد)، میتوانی فضای اضافی را با DBCC SHRINKFILE واقعاً از فایل حذف کنی:
DBCC SHRINKFILE (ShopDB_log, 512);
log_reuse_wait_desc دقیقاً میگوید Log منتظر چیست.دورهی رایگان SQLFarsi را با درس تراکنشها ادامه بده.
ادامهی یادگیری