How do you clear the SQL Server transaction log?
First, take a full backup
Never make any changes to your database without ensuring you can restore it should something go wrong.
If you care about point-in-time recovery
(And by point-in-time recovery, I mean you care about being able to restore to anything other than a full or differential backup.)
Presumably your database is in FULL
recovery mode. If not, then make sure it is:
ALTER DATABASE testdb SET RECOVERY FULL;
-- and take another full backup here
-- so log backups are possible
Even if you are taking regular full backups, the log file will grow and grow until you perform a log backup - this is for your protection, not to needlessly eat away at your disk space. You should be performing these log backups quite frequently, according to your recovery objectives. For example, if you have a business rule that states you can afford to lose no more than 15 minutes of data in the event of a disaster, you should have a job that backs up the log every 15 minutes. Here is a script that will generate timestamped file names based on the current time (but you can also do this with maintenance plans etc., just don't choose any of the shrink options in maintenance plans, they're awful).
DECLARE @path nvarchar(4000) = CONCAT(
N'\\backup_share\log\testdb_',
CONVERT(char(8), GETDATE(), 112), N'_',
REPLACE(CONVERT(char(8), GETDATE(), 108),':',''),
N'.trn');
BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION;
WAITFOR DELAY '00:00:01';
GO 2 -- run twice to ensure file wrap-around
Note that \\backup_share\
should be on a different
machine that represents a different underlying storage device. Backing
these up to the same machine (or to a different machine that uses the
same underlying disks, or a different VM that's on the same physical
host) does not really help you, since if the machine blows up, you've
lost your database and its backups. Depending on your network
infrastructure it may make more sense to backup locally and then
transfer them to a different location behind the scenes; in either case,
you want to get them off the primary database machine as quickly as
possible.
Now, once you have regular log backups running, it should be
reasonable to shrink the log file to something more reasonable than
whatever it's blown up to now. This does not mean running SHRINKFILE
over and over again until the log file is 1 MB - even if you are
backing up the log frequently, it still needs to accommodate the sum of
any concurrent transactions that can occur. Log file autogrow events are
expensive, since SQL Server has to zero out the files (unlike data
files when instant file initialization is enabled), and user
transactions have to wait while this happens. You want to do this
grow-shrink-grow-shrink routine as little as possible, and you certainly
don't want to make your users pay for it.
Note that you may need to back up the log twice before a shrink is possible (thanks Robert).
So, you need to come up with a practical size for your log file.
Nobody here can tell you what that is without knowing a lot more about
your system, but if you've been frequently shrinking the log file and it
has been growing again, a good watermark is probably 10-50% higher than
the largest it's been. Let's say that comes to 200 MB, and you want any
subsequent autogrowth events to be 50 MB, then you can adjust the log
file size this way (where 'yourdb_log'
is the logical name of your database's log file, which you can find in sys.database_files
):
USE [master];
GO
ALTER DATABASE Test1
MODIFY FILE
(NAME = N'yourdb_log', SIZE = 200MB, FILEGROWTH = 50MB);
GO
Note that if the log file is currently > 200 MB, you may need to run this first:
USE yourdb;
GO
DBCC SHRINKFILE(N'yourdb_log', 200); -- unit is MB
GO
If you don't care about point-in-time recovery
If this is a test database, and you don't care about point-in-time recovery, then you should make sure that your database is in SIMPLE
recovery mode.
ALTER DATABASE testdb SET RECOVERY SIMPLE;
Putting the database in SIMPLE
recovery mode will make
sure that SQL Server re-uses portions of the log file (essentially
phasing out inactive transactions) instead of growing to keep a record
of all transactions (like FULL
recovery does until you back up the log). CHECKPOINT
events will help control the log and make sure that it doesn't need to
grow unless you generate a lot of t-log activity between CHECKPOINT
s.
Next, you should make absolute sure that this log growth was truly due to an abnormal event (say, an annual spring cleaning or rebuilding your biggest indexes), and not due to normal, everyday usage. If you shrink the log file to a ridiculously small size, and SQL Server just has to grow it again to accommodate your normal activity, what did you gain? Were you able to make use of that disk space you freed up only temporarily? If you need an immediate fix, then you can run the following:
USE yourdb;
GO
CHECKPOINT;
CHECKPOINT; -- run twice to ensure file wrap-around
GO
DBCC SHRINKFILE(N'yourdb_log', 200); -- unit is MB
GO
Otherwise, set an appropriate size and growth rate. As per the example in the point-in-time recovery case, you can use the same code and logic to determine what file size is appropriate and set reasonable autogrowth parameters.
Some things you don't want to do
Back up the log with
TRUNCATE_ONLY
option and thenSHRINKFILE
. For one, thisTRUNCATE_ONLY
option has been deprecated and is no longer available in current versions of SQL Server. Second, if you are inFULL
recovery model, this will destroy your log chain and require a new, full backup.Detach the database, delete the log file, and re-attach. I can't emphasize how dangerous this can be. Your database may not come back up, it may come up as suspect, you may have to revert to a backup (if you have one), etc. etc.
Use the "shrink database" option.
DBCC SHRINKDATABASE
and the maintenance plan option to do the same are bad ideas, especially if you really only need to resolve a log problem issue. Target the file you want to adjust and adjust it independently, usingDBCC SHRINKFILE
orALTER DATABASE ... MODIFY FILE
(examples above).Shrink the log file to 1 MB. This looks tempting because, hey, SQL Server will let me do it in certain scenarios, and look at all the space it frees! Unless your database is read only (and it is, you should mark it as such using
ALTER DATABASE
), this will absolutely just lead to many unnecessary growth events, as the log has to accommodate current transactions regardless of the recovery model. What is the point of freeing up that space temporarily, just so SQL Server can take it back slowly and painfully?Create a second log file. This will provide temporarily relief for the drive that has filled your disk, but this is like trying to fix a punctured lung with a band-aid. You should deal with the problematic log file directly instead of just adding another potential problem. Other than redirecting some transaction log activity to a different drive, a second log file really does nothing for you (unlike a second data file), since only one of the files can ever be used at a time. Paul Randal also explains why multiple log files can bite you later.
Be proactive
Instead of shrinking your log file to some small amount and letting it constantly autogrow at a small rate on its own, set it to some reasonably large size (one that will accommodate the sum of your largest set of concurrent transactions) and set a reasonable autogrow setting as a fallback, so that it doesn't have to grow multiple times to satisfy single transactions and so that it will be relatively rare for it to ever have to grow during normal business operations.
The worst possible settings here are 1 MB growth or 10% growth. Funny enough, these are the defaults for SQL Server (which I've complained about and asked for changes to no avail) - 1 MB for data files, and 10% for log files. The former is much too small in this day and age, and the latter leads to longer and longer events every time (say, your log file is 500 MB, first growth is 50 MB, next growth is 55 MB, next growth is 60.5 MB, etc. etc. - and on slow I/O, believe me, you will really notice this curve).
Further reading
Please don't stop here; while much of the advice you see out there about shrinking log files is inherently bad and even potentially disastrous, there are some people who care more about data integrity than freeing up disk space.
No comments:
Post a Comment
Note: only a member of this blog may post a comment.