tags:

views:

1315

answers:

4

I have a fairly large SQL Server database that is using SIMPLE recovery mode. We don't really have a need for up to the second recovery so i'd prefer we stay with this mode.

For some reason the transaction log for this database is massive (410 GB) with 99% of the space unallocated.

I've tried to shrink the file using ( DBCC SHRINKFILE (MyDatabase_log, 20000) )but it doesn't seem to work.

Anyone have any tips on why a SIMPLE recovery mode database would have such a huge file? I'd really like to get it shrunk way down.

+1  A: 

You're missing an argument in dbcc shrinkfile:

dbcc shrinkfile (MyDatabase_log, 20000, TRUNCATEONLY)

NOTRUNCATE is the default, which moves allocated blocks to the beginning of unallocated space. TRUNCATEONLY removes the unallocated space. So if you do a NOTRUNCATE followed by a TRUNCATEONLY, you get one slimmed down log.

Eric
I did try that. It didn't change anything. I did add a second log file to get the batabase back online when the space ran out. Maybe that's part of it?
Eric
@Eric (Good name, btw): Make sure then, that you're shrinking the right log. If you have two log files, you'll need to shrink both independently. Check in the Files section of the database properties for what they're called. I think the default is `MyDatabase_log_1`, but I'm going off the top of my head.
Eric
+2  A: 

It means you once had a single transaction that lasted for so long that it forced the log to grow 410GB. The log cannot be reused if there is an active transaction since the rollback information cannot be erased. Such an example would be if someone open an SSMS query, starts a transaction, updates a record and then goes in vacation. The transaction will be active and force the log to grow until is eventually committed or rolled back. When the transaction eventually ends the used space can finally be reclaimed, leaving a huge empty log file.

Another scenario is if you had about 200GB of data updated in a single transaction. The log will store the before and after images of the changes thus consuming twice the space, and it cannot be reused, again because is all one single transaction.

Update

I neglected to mention Replication that is also a factor that can prevent log truncation. And so is Mirroring, an distributed transaction (technically that is the same as an 'active transaction', but the DTC implication makes it a distinct case). The complete list and explanations is at Factors That Can Delay Log Truncation.

Remus Rusanu
It wouldn't show as unallocated space if it were mid-rollback/transaction, would it?
Eric
Thanks! This sounds very possible. Do you know what can be done to remove the log if it's in this locked state?
Eric
If it shows as unallocated the space must be already claimed back by the SIMPLE recovery mode. Does the `log_reuse_wait_desc` column of sys.databases for the database in question says `NOTHING` or not?
Remus Rusanu
CHECKPOINTNOTHINGACTIVE_TRANSACTIONNOTHINGREPLICATIONNOTHINGNOTHINGNOTHING
Eric
@Remus: That's what I thought. Since 99% of his space is unallocated, I figured there wasn't a hanging transaction. He's obviously confirmed that, though :)
Eric
@Eric can you restrict that only to the database of interest, not your entire server? There is at least one `REPLICATION` entry, do you have replication off the database in question?
Remus Rusanu
damn, there are two Eric lol.
Remus Rusanu
@Eric (OP) from the reply to no_one is clear you have replication from the database. Replication is another one of them log shrink/reuse restriction factors. You need all your subscribers to catch up, the server keeps track of who has received what in replication. If a subscriber is behind, it will cause the log to grow, same as an active transaction.
Remus Rusanu
I see. I bet this is the problem since I'm seeing lots of errors in my replication subscriber database. I'll try to turn off replication and see if that allows me to shrink the file.
Eric
@Remus: I may have misinterpreted your explanation but I thought Replication would only delay truncation of the Publishers transaction log if the transaction had not been committed to the Distributor database (as opposed to the Subscriber)?
John Sansom
Eric
@John: I think you are right. I'm not an expert in Replication, but it makes sense that only the distributor needs to read the log for transaction based replication, not each subscriber.
Remus Rusanu
@Remus: Hmmm I wonder then if the posters distribution database was the root cause, perhaps a space issue there...
John Sansom
@John: yes, replication can grow the log as such if the distributor is not reading the log: either the agents don't run (schedule is busted usually due to operator intervention) or they run but can't connect to the publisher.
Remus Rusanu
A: 

If you have only one mdf file and one log file, perhaps the simplest way will be to detach the database, rename the log and reattach the database. SQL Server will create a new log file. After that your huge log file can be safely deleted.

This though will not work if you have multiple data files.

no_one
Thanks. I did try this but it wouldn't let me detach because the database acts as a replication publisher.
Eric
A: 

Replication Publisher? Could this be the reason for the huge transaction log?