Did you ever have this annoying problem? About once every 2 months a customer will call panicky because the server is generating errors that say the "transaction log is full". Many (maybe most) customers don't know what it is or what it's for - but they suddenly have a problem with it. The transaction log is the history of all the database changes from the time of the last complete backup. It's purpose is to provide recovery for you AFTER the last complete backup. That is to say, if you have a complete backup from 1 a.m. and a transaction log, you could restore your database back to "1:00 a.m." status - and then restore it "forward" to a particular point in time.
This useful feature comes at a cost. Everything must be recorded in the transaction log. The transaction log on a database with many updates, deletes and inserts can grow ginormous (thanks Elf)! I saw one today that was 9 gigabytes for a 12 megabyte database - a logging and tracking database. Unless you've had this problem you may not know how to fix it. Here are two ways to do it.
Truncate and Shrink
Using the "sa" user and the "master database, run the following commands.
EXEC sp_dboption 'yourDatabaseName', 'trunc. log on chkpt.', 'TRUE'
This effectively causes the server to truncate the log the next time it runs a "checkpoint". A checkpoint is a synchronization task that flushes "dirty pages" to the disk. That sounds kind of naughty, but it really means that the server is periodically saving your data from the cache - where much of it is kept for speed reasons - to the disk, where it is stored "permanently". By changing the "trunc. log on chkpt." command you are telling the db that the next time it is safe to clear the transaction log to go ahead and do so.
Next you can "force" a checkpoint for your db. by running the following:
use yourdatabasename
checkpoint
go
You are now ready to "shrink" the database. MS SQL actually gives you a couple ways to do this, but the DBCC command is probably the easiest.
DBCC SHRINKDATABASE (yourdatabasename, 10)
What's that number 10 for? It's the "percent free" number. It leaves a certain amount of space (as a percentage) in the file. This is useful because it keeps the server from having to "resize" the file too often. This command will return a record set with some size parameters (in megabytes) showing you how successful you have been.
Detach and Reattach.
This is more complicated, but there are times when the DBCC command won't do because the database is too large or the process is failing for some reason (like disk size). Have care when using this method. Again in query analyzer run the following:
EXEC sp_detach_db 'yourdatabasename', 'true'
Note - at this point your database is no longer a member of the server - it's gone. The MDF and LDF file are still in the directory, but the db is no longer "online" - so be prepared. Now, go into the data directory (usually something like c:\mssql\data\) and find the
LDF file associated with the DB. The
LDF file is the log file the
MDF file is the actual data file. If you delete the MDF you are out of luck. Let me say it one more time.
Don't delete the MDF file. The LDF file is usually the name of your db + _log.ldf. For example, "pubs_log.ldf". Once you locate it, delete it. That's right, send it to the showers.
You now have a valid db file with no log file. Your next task is to "attach" it back to the server. Here's the code:
EXEC sp_attach_db @dbname = N'yourdatabasename',
@filename1 = N'
c:\Program Files\Microsoft SQL Server\MSSQL\Data\yourdatabasename_data.mdf'
If you look at the docs you will notice that it usually calls for 2 file names - the data
and the log - like this:
EXEC sp_attach_db @dbname = N'yourdatabasename',
@filename1 = N'
c:\Program Files\Microsoft SQL Server\MSSQL\Data\yourdatabasename_data.mdf',
@filename2 = N'
c:\Program Files\Microsoft SQL Server\MSSQL\Data\yourdatabasename_log.ldf'
If you leave off the log file however, you only get a warning. The stored proc creates a new log file for you and you are good to go. Remember, to use this method you are taking your DB off line until it is reattached,
and you are deleting the log file. That makes it a more drastic approach than the one above.