Sql server Shrinking Transaction Log [closed] - sql-server

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I test bulk insert daily on my table for an ongoing project, the bulk files are around 1200000 records per day.
The transaction log keeps on increasing. I shirked my transaction log once which was of 9 gb, no backup has yet been taken.
Is it wise to shrink the transaction log like this.
Can I shrink the log after a full backup or need to back up the log separately?
Thanks

Here is great link, this is a summary of the info:
How do you clear the SQL Server transaction log?
Some things you don't want to do
Back up the log with TRUNCATE_ONLY option and then SHRINKFILE. For one, this TRUNCATE_ONLY option has been deprecated and is no longer available in current versions of SQL Server. Second, if you are in FULL 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, using DBCC SHRINKFILE or ALTER 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.
How do you clear the SQL Server transaction log?

Back up the transaction log (I assume the database is in full recovery) and then shrink file
DBCC SHRINKFILE (2, x)
(x is target size in MB)
Make sure to leave some free space in the file to avoid autogrowths.
You can also switch to simple recovery before shrinking if this didn't work as expected, and then switch back to full.
If the log continues to grow, check
select log_reuse_wait_desc from sys.databases
for the database in question.

Related

How the unallocated space in SQL Server affects copying to another SQL Server

I am a newbie in SQL Server, I have a task to move the whole SQL Server to another.
I am trying to estimate how much space I need in the new SQL Server.
I ran EXEC sp_spaceused
And the following came up:
When I look into the output, it seems that the Database is using ~122GB (reserved), but when looking in the total database size (mdf + ldf) it is ~1.8 TB.
Does that mean when I copy the Database from the existing SQL Server to a new one I will need ~1.8 TBs into the new?
I am thinking about creating a back-up and copy the back-up to the new Server. How does the back-up takes into consideration the unallocated space? Does the back gets closer to the reserved or the database_size? I understand that this is without taking into consideration the uncompressed in the back-up, which will improve the file size.
Thx for the help.
The backup file will be much smaller than 1.8TB, since unallocated pages are not backed up. But the log and data files themselves will be restored to an identical size, so you will need 1.8TB on the target in order to restore the database in its current state.
Did you check to see if your log file is large due to some uncontrolled growth that happened at some point and is maybe no longer necessary? If this is where all your size is, it's quite possible you can fix this before the move. Make sure you have a full backup and take at least one log backup, then use DBCC SHRINKFILE to bring the log file back into the right stratosphere, especially if it was caused by either a one-time abnormal event or a prolonged log backup neglect that has now been addressed.
I really don't recommend copying/moving the mdf/ldf files (background) or using the SSMS UI to "do a copy" since you can have much greater control over what you're actually doing by using proper BACKUP DATABASE and RESTORE DATABASE commands.
How do I verify how much of the log data is being used?
If you're taking regular log backups (or are in simple recovery), it should usually be a very small % of the file. DBCC SQLPERF(LogSpace); will tell you % in use for all log files.
To minimize the size that the log will require in the backup file itself, then:
if full recovery, back up the log first.
if simple recovery, run a couple of CHECKPOINT; commands first.

What is the best possible way to tackle SQL Server transaction logs filling up disk space?

I need the best shortest possible way to handle SQL Server transaction log files as my disk will be having a problem in saving them, in future. I don't know how to tackle this Low Disk Space issue, as my drive's free space is already in MB's.
Now, I don't know that whether the logs will be lost or affected if I move them to some other drive or will it effect the transactions or how to save the future logs depending on some previous transactions, if the disk space is completely full. Someone please help!!
Lets first take something off the table: do not delete or move any database mdf or ldf file. You'll end up corrupting and loosing the database.
You need to investigate why is the log growing. Go read Factors That Can Delay Log Truncation. Follow the steps in the article to identify why is the log growing.
If the reasons is anything else but 'LOG_BACKUP', post an update with the reason you discovered and we can take give further advise.
If the reason is LOG_BACKUP then we can proceed. You have a database in non-SIMPLE recovery mode which is not being backed up correctly. You need to answer a question: Why is the database not in SIMPLE recovery mode? This is a business decision question so we cannot possibly know the answer.
If you don't know the answer to above or if you realize that SIMPLE recovery mode is acceptable, then we can do the quick fix. Change the recovery model to SIMPLE then run DBCC SHRINKFILE to shrink the log.
If you need a non-SIMPLE recovery model then you need to set up a proper log backup plan and start taking log backups. Read Transaction Log Backups and Use the Maintenance Plan Wizard. See See How to shrink the SQL Server Log to understand why you need to take repeated log backups until the SHRINKFILE is effective, due to the circular nature of the log.
First, you should read the excellent answer written by Remus Rusanu.
At the beginning, he wrote:
Lets first take something off the table: do not delete or move any database mdf or ldf file. You'll end up corrupting and loosing the database.
To clarify: It is possible to move the log file to another drive in order to free space on the current drive.
It's just that you can't/shouldn't just move the file in Windows Explorer while the database is in use by SQL Server.
Disclaimer: You probably won't need to do this if you follow the steps in Remus' answer.
But it's possible that you still may want to move the log file to a different drive.
Either for performance reasons (SQL Server ist faster if database and log file are on two different physical drives, because there are lots of writes to the log file), or if you still have a disk space problem (even if you shrink the log file or back it up regularly, some day the database size will grow so that the drive is too small to hold both files).
To move the log file (or the database file) to another location, you need to:
detach the database from SQL Server
move the file(s)
re-attach the database and specify the new file location(s)
Here are two tutorials with screenshots how to do this:
Move SQL Server transaction log files to a different location via TSQL and SSMS
Move SQL Server transaction log to another disk

How large does a log file get after it updates every database table field?

My general question is, say you have a SQL Server 2005 database that's 20G in size and a log file that is empty. If you run a series of updates that touch each table and each row exactly once, will the log file grow to the same size as the database? Or will this depend on other factors?
I'm asking this question because of a database update I'm performing. I have a database used by some proprietary software. Updates are made to every table and every field. The software does not have a verbose output, just a checkbox for "not done"/"done". Because there's no descriptive output, I'm trying to figure out how to tell if it's close to the end.
So, is the log file likely to be the same size as the database when everything has been touched? Or does the log file contain different information that doesn't depend on the database size in this way?
As a rule of thumb the size of log generated for any update is about 1.5x the size of the update. So if you update 20Gb worth of data, you generate 30Gb worth of log.
But there are some things to consider:
Size of log generated does not need necessarily translates to log file size. Under SIMPLE recovery model the log file used can be automatically recycled as soon as the transaction commits (I'm omitting some details for brevity) so 30gb log size can fit in a 1gb file, by continuously recycling the used log. Under FULL and BULK recovery model the log gets similarly recycled when a database log backup is performed. So if you don't update everything in one transaction, your log should recycle and not grow.
Some operations can be minimally logged. TRUNCATE, INSERT BULK being the typical examples. Minimal logging takes a tiny fraction of normal logging.
Right now you should be looking at the log percent used (DBCC SQLPERF(logspace)) and also monitor if any log growth events are occurring.
Not the answer your looking for, but I think it's unlikely to relate to the size of the database in any meaningful way. Just wait it out. :)

How do I shrink my SQL Server Database?

I have a Database nearly 1.9Gb Database in size, and MSDE2000 does not allow DBs that exceed 2.0Gb
I need to shrink this DB (and many others like this at various client locations).
I have found and deleted many 100's of 1000's of records which are considered unneeded:
these records account for a large percentage of some of the main (largest) tables in the Database. Therefore it's reasonable to assume much space should now be retrievable.
So now I need to shrink the DB to account for the missing records.
I execute DBCC ShrinkDatabase('MyDB')...... No effect.
I have tried the various shrink facilities provided in MSSMS.... Still no effect.
I have backed up the database and restored it... Still no effect.
Still 1.9Gb
Why?
Whatever procedure I eventually find needs to be replayable on a client machine with access to nothing other than OSql or similar.
ALTER DATABASE MyDatabase SET RECOVERY SIMPLE
GO
DBCC SHRINKFILE (MyDatabase_Log, 5)
GO
ALTER DATABASE MyDatabase SET RECOVERY FULL
GO
This may seem bizarre, but it's worked for me and I have written a C# program to automate this.
Step 1: Truncate the transaction log (Back up only the transaction log, turning on the option to remove inactive transactions)
Step 2: Run a database shrink, moving all the pages to the start of the files
Step 3: Truncate the transaction log again, as step 2 adds log entries
Step 4: Run a database shrink again.
My stripped down code, which uses the SQL DMO library, is as follows:
SQLDatabase.TransactionLog.Truncate();
SQLDatabase.Shrink(5, SQLDMO.SQLDMO_SHRINK_TYPE.SQLDMOShrink_NoTruncate);
SQLDatabase.TransactionLog.Truncate();
SQLDatabase.Shrink(5, SQLDMO.SQLDMO_SHRINK_TYPE.SQLDMOShrink_Default);
This is an old question, but I just happened upon it.
The really short and correct answer is already given and has the most votes. That is how you shrink a transaction log, and that was probably the OP's problem. And when the transaction log has grown out of control, it often needs to be shrunk back, but care should be taken to prevent future situations of a log from growing out of control. This question on dba.se explains that. Basically - Don't let it get that large in the first place through proper recovery model, transaction log maintenance, transaction management, etc.
But the bigger question in my mind when reading this question about shrinking the data file (or even the log file) is why? and what bad things happen when you try? It appears as though shrink operations were done. Now in this case it makes sense in a sense - because MSDE/Express editions are capped at max DB size. But the right answer may be to look at the right version for your needs. And if you stumble upon this question looking to shrink your production database and this isn't the reason why you should ask yourself the why? question.
I don't want someone searching the web for "how to shrink a database" coming across this and thinking it is a cool or acceptable thing to do.
Shrinking Data Files is a special task that should be reserved for special occasions. Consider that when you shrink a database, you are effectively fragmenting your indexes. Consider that when you shrink a database you are taking away the free space that a database may someday grow right back into - effectively wasting your time and incurring the performance hit of a shrink operation only to see the DB grow again.
I wrote about this concept in several blog posts about shrinking databases. This one called "Don't touch that shrink button" comes to mind first. I talk about these concepts outlined here - but also the concept of "Right-Sizing" your database. It is far better to decide what your database size needs to be, plan for future growth, and allocate it to that amount. With Instant File Initialization available in SQL Server 2005 and beyond for data files, the cost of growth is lower - but I still prefer to have a proper initial application - and I'm far less scared of white space in a database than I am of shrinking in general with no thought first. :)
DBCC SHRINKDATABASE works for me, but this is its full syntax:
DBCC SHRINKDATABASE ( database_name, [target_percent], [truncate] )
where target_percent is the desired percentage of free space left in the database file after the database has been shrunk.
And truncate parameter can be:
NOTRUNCATE
Causes the freed file space to be retained in the database files. If not specified, the freed file space is released to the operating system.
TRUNCATEONLY
Causes any unused space in the data files to be released to the operating system and shrinks the file to the last allocated extent, reducing the file size without moving any data. No attempt is made to relocate rows to unallocated pages. target_percent is ignored when TRUNCATEONLY is used.
...and yes no_one is right, shrinking datbase is not very good practice becasue for example :
shrink on data files are excellent ways to introduce significant logical fragmentation, becasue it moves pages from the end of the allocated range of a database file to somewhere at the front of the file...
shrink database can have a lot of consequence on database, server.... think a lot about it before you do it!
on the web there are a lot of blogs and articles about it.
Late answer but might be useful useful for someone else
If neither DBCC ShrinkDatabase/ShrinkFile or SSMS (Tasks/Shrink/Database) doesn’t help, there are tools from Quest and ApexSQL that can get the job done, and even schedule periodic shrinking if you need it.
I’ve used the latter one in free trial to do this some time ago, by following short description at the end of this article:
https://solutioncenter.apexsql.com/sql-server-database-shrink-how-and-when-to-schedule-and-perform-shrinking-of-database-files/
All you need to do is install ApexSQL Backup, click "Shrink database" button in the main ribbon, select database in the window that will pop-up, and click "Finish".
You will also need to shrink the individual data files.
It is however not a good idea to shrink the databases. For example see here
You should use:
dbcc shrinkdatabase (MyDB)
It will shrink the log file (keep a windows explorer open and see it happening).
Here's another solution: Use the Database Publishing Wizard to export your schema, security and data to sql scripts. You can then take your current DB offline and re-create it with the scripts.
Sounds kind of foolish, but there are a couple advantages. First, there's no chance of losing data. Your original db (as long as you don't delete your DB when dropping it!) is safe, the new DB will be roughly as small as it can be, and you'll have two different snapshots of your current database - one ready to roll, one minified - you can choose from to back up.
"Therefore it's reasonable to assume much space should now be retrievable."
Apologies if I misunderstood the question, but are you sure it's the database and not the log files that are using up the space? Check to see what recovery model the database is in. Chances are it's in Full, which means the log file is never truncated. If you don't need a complete record of every transaction, you should be able to change to Simple, which will truncate the logs. You can shrink the database during the process. Assuming things go right, the process looks like:
Backup the database!
Change to Simple Recovery
Shrink db (right-click db, choose all tasks > shrink db -> set to 10% free space)
Verify that the space has been reclaimed, if not you might have to do a full backup
If that doesn't work (or you get a message saying "log file is full" when you try to switch recovery modes), try this:
Backup
Kill all connections to the db
Detach db (right-click > Detach or right-click > All Tasks > Detach)
Delete the log (ldf) file
Reattach the db
Change the recovery mode
etc.
I came across this post even though I needed to SHRINKFILE on MSSQL 2012 version which is little trickier since 2000 or 2005 versions. After reading up on all risks and issues related to this issue I ended up testing. Long story short, the best results I got were from using the MS SQL Server Management Studio.
Right-Click the DB -> TASKS -> SHRINK -> FILES -> select the LOG file
You also have to modify the minimum size of the data and log files. DBCC SHRINKDATABASE will shrink the data inside the files you already have allocated. To shrink a file to a size smaller than its minimum size, use DBCC SHRINKFILE and specify the new size.
Delete data, make sure recovery model is simple, then skrink (either shrink database or shrink files works). If the data file is still too big, AND you use heaps to store data -- that is, no clustered index on large tables -- then you might have this problem regarding deleting data from heaps: http://support.microsoft.com/kb/913399
I recently did this. I was trying to make a compact version of my database for testing on the road, but I just couldn't get it to shrink, no matter how many rows I deleted. Eventually, after many other commands in this thread, I found that my clustered indexes were not getting rebuilt after deleting rows. Rebuilding my indexes made it so I could shrink properly.
Not sure how practical this would be, and depending on the size of the database, number of tables and other complexities, but I:
defrag the physical drive
create a new database according to my requirements, space, percentage growth, etc
use the simple ssms task to import all tables from the old db to the new db
script out the indexes for all tables on the old database, and then recreate the indexes on the new database. expand as needed for foreign keys etc.
rename databases as needed, confirm successful, delete old
I think you can remove all your log with switch from full to simple recovery. Right click on your Database and select Properties and select Options and change
Recovery mode to Simple
Containment type to None
When you've set the recovery model to Simple (and enabled auto-shrink), it is still possible that SQL Server can not shrink the log. It has to do with checkpoints in the log (or lack thereof).
So first run
DBCC CHECKDB
on your database. After that the shrink operation should work like a charm.
Usually I use the Tasks>Shrink>Files menu and choose the logfile with the option to reorganise pages.

How do you clear the SQL Server transaction log?

I'm not a SQL expert, and I'm reminded of the fact every time I need to do something beyond the basics. I have a test database that is not large in size, but the transaction log definitely is. How do I clear out the transaction log?
Making a log file smaller should really be reserved for scenarios where it encountered unexpected growth which you do not expect to happen again. If the log file will grow to the same size again, not very much is accomplished by shrinking it temporarily. Now, depending on the recovery goals of your database, these are the actions you should take.
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;
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(255) = N'\\backup_share\log\testdb_'
+ CONVERT(CHAR(8), GETDATE(), 112) + '_'
+ REPLACE(CONVERT(CHAR(8), GETDATE(), 108),':','')
+ '.trn';
BACKUP LOG foo TO DISK = #path WITH INIT, COMPRESSION;
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:
USE [master];
GO
ALTER DATABASE Test1
MODIFY FILE
(NAME = 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(yourdb_log, 200);
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 CHECKPOINTs.
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;
GO
CHECKPOINT; -- run twice to ensure file wrap-around
GO
DBCC SHRINKFILE(yourdb_log, 200); -- unit is set in MBs
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 then SHRINKFILE. For one, this TRUNCATE_ONLY option has been deprecated and is no longer available in current versions of SQL Server. Second, if you are in FULL 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, using DBCC SHRINKFILE or ALTER 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.
A blog post I wrote in 2009, when I saw a few "here's how to shrink the log file" posts spring up.
A blog post Brent Ozar wrote four years ago, pointing to multiple resources, in response to a SQL Server Magazine article that should not have been published.
A blog post by Paul Randal explaining why t-log maintenance is important and why you shouldn't shrink your data files, either.
Mike Walsh has a great answer covering some of these aspects too, including reasons why you might not be able to shrink your log file immediately.
-- DON'T FORGET TO BACKUP THE DB :D (Check [here][1])
USE AdventureWorks2008R2;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2008R2_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY FULL;
GO
From: DBCC SHRINKFILE (Transact-SQL)
You may want to backup first.
DISCLAIMER: Please read comments below this answer carefully before attempting it, and be sure to check the accepted answer. As I said nearly 5 years ago:
if anyone has any comments to add for situations when this is NOT an
adequate or optimal solution then please comment below
Turns out there were :-)
Original Answer:
Right click on the database name.
Select Tasks → Shrink → Database
Then click OK!
I usually open the Windows Explorer directory containing the database files, so I can immediately see the effect.
I was actually quite surprised this worked! Normally I've used DBCC before, but I just tried that and it didn't shrink anything, so I tried the GUI (2005) and it worked great - freeing up 17 GB in 10 seconds
In Full recovery mode this might not work, so you have to either back up the log first, or change to Simple recovery, then shrink the file. [thanks #onupdatecascade for this]
--
PS: I appreciate what some have commented regarding the dangers of this, but in my environment I didn't have any issues doing this myself especially since I always do a full backup first. So please take into consideration what your environment is, and how this affects your backup strategy and job security before continuing. All I was doing was pointing people to a feature provided by Microsoft!
Below is a script to shrink the transaction log, but I’d definitely recommend backing up the transaction log before shrinking it.
If you just shrink the file you are going to lose a ton of data that may come as a life saver in case of disaster. The transaction log contains a lot of useful data that can be read using a third-party transaction log reader (it can be read manually but with extreme effort though).
The transaction log is also a must when it comes to point in time recovery, so don’t just throw it away, but make sure you back it up beforehand.
Here are several posts where people used data stored in the transaction log to accomplish recovery:
How to view transaction logs in SQL Server 2008
Read the log file (*.LDF) in SQL Server 2008
USE DATABASE_NAME;
GO
ALTER DATABASE DATABASE_NAME
SET RECOVERY SIMPLE;
GO
--First parameter is log file name and second is size in MB
DBCC SHRINKFILE (DATABASE_NAME_Log, 1);
ALTER DATABASE DATABASE_NAME
SET RECOVERY FULL;
GO
You may get an error that looks like this when the executing commands above
“Cannot shrink log file (log file name) because the logical
log file located at the end of the file is in use“
This means that TLOG is in use. In this case try executing this several times in a row or find a way to reduce database activities.
Here is a simple and very inelegant & potentially dangerous way.
Backup DB
Detach DB
Rename Log file
Attach DB
New log file will be recreated
Delete Renamed Log file.
I'm guessing that you are not doing log backups. (Which truncate the log). My advice is to change recovery model from full to simple. This will prevent log bloat.
If you do not use the transaction logs for restores (i.e. You only ever do full backups), you can set Recovery Mode to "Simple", and the transaction log will very shortly shrink and never fill up again.
If you are using SQL 7 or 2000, you can enable "truncate log on checkpoint" in the database options tab. This has the same effect.
This is not recomended in production environments obviously, since you will not be able to restore to a point in time.
This technique that John recommends is not recommended as there is no guarantee that the database will attach without the log file. Change the database from full to simple, force a checkpoint and wait a few minutes. The SQL Server will clear the log, which you can then shrink using DBCC SHRINKFILE.
Most answers here so far are assuming you do not actually need the Transaction Log file, however if your database is using the FULL recovery model, and you want to keep your backups in case you need to restore the database, then do not truncate or delete the log file the way many of these answers suggest.
Eliminating the log file (through truncating it, discarding it, erasing it, etc) will break your backup chain, and will prevent you from restoring to any point in time since your last full, differential, or transaction log backup, until the next full or differential backup is made.
From the Microsoft article onBACKUP
We recommend that you never use NO_LOG or TRUNCATE_ONLY to manually
truncate the transaction log, because this breaks the log chain. Until
the next full or differential database backup, the database is not
protected from media failure. Use manual log truncation in only very
special circumstances, and create backups of the data immediately.
To avoid that, backup your log file to disk before shrinking it. The syntax would look something like this:
BACKUP LOG MyDatabaseName
TO DISK='C:\DatabaseBackups\MyDatabaseName_backup_2013_01_31_095212_8797154.trn'
DBCC SHRINKFILE (N'MyDatabaseName_Log', 200)
The SQL Server transaction log needs to be properly maintained in order to prevent its unwanted growth. This means running transaction log backups often enough. By not doing that, you risk the transaction log to become full and start to grow.
Besides the answers for this question I recommend reading and understanding the transaction log common myths. These readings may help understanding the transaction log and deciding what techniques to use to "clear" it:
From 10 most important SQL Server transaction log myths:
Myth: My SQL Server is too busy. I don’t want to make SQL Server transaction log backups
One of the biggest performance intensive operations in SQL Server is an auto-grow event of the online transaction log file. By not making transaction log backups often enough, the online transaction log will become full and will have to grow. The default growth size is 10%. The busier the database is, the quicker the online transaction log will grow if transaction log backups are not created
Creating a SQL Server transaction log backup doesn’t block the online transaction log, but an auto-growth event does. It can block all activity in the online transaction log
From Transaction log myths:
Myth: Regular log shrinking is a good maintenance practice
FALSE. Log growth is very expensive because the new chunk must be zeroed-out. All write activity stops on that database until zeroing is finished, and if your disk write is slow or autogrowth size is big, that pause can be huge and users will notice. That’s one reason why you want to avoid growth. If you shrink the log, it will grow again and you are just wasting disk operation on needless shrink-and-grow-again game
Use the DBCC ShrinkFile ({logicalLogName}, TRUNCATEONLY) command. If this is a test database and you are trying to save/reclaim space, this will help.
Remember though that TX logs do have a sort of minimum/steady state size that they will grow up to. Depending upon your recovery model you may not be able to shrink the log - if in FULL and you aren't issuing TX log backups the log can't be shrunk - it will grow forever. If you don't need TX log backups, switch your recovery model to Simple.
And remember, never ever under any circumstances delete the log (LDF) file! You will pretty much have instant database corruption. Cooked! Done! Lost data! If left "unrepaired" the main MDF file could become corrupt permanently.
Never ever delete the transaction log - you will lose data! Part of your data is in the TX Log (regardless of recovery model)... if you detach and "rename" the TX log file that effectively deletes part of your database.
For those that have deleted the TX Log you may want to run a few checkdb commands and fix the corruption before you lose more data.
Check out Paul Randal's blog posts on this very topic, bad advice.
Also in general do not use shrinkfile on the MDF files as it can severely fragment your data. Check out his Bad Advice section for more info ("Why you should not shrink your data files")
Check out Paul's website - he covers these very questions. Last month he walked through many of these issues in his Myth A Day series.
To Truncate the log file:
Backup the database
Detach the database, either by using Enterprise Manager or by executing : Sp_DetachDB [DBName]
Delete the transaction log file. (or rename the file, just in case)
Re-attach the database again using: Sp_AttachDB [DBName]
When the database is attached, a new transaction log file is created.
To Shrink the log file:
Backup log [DBName] with No_Log
Shrink the database by either:
Using Enterprise manager :-
Right click on the database, All tasks, Shrink database, Files, Select log file, OK.
Using T-SQL :-
Dbcc Shrinkfile ([Log_Logical_Name])
You can find the logical name of the log file by running sp_helpdb or by looking in the properties of the database in Enterprise Manager.
First check the database recovery model. By default, SQL Server Express Edition creates a database for the simple recovery
model (if I am not mistaken).
Backup log DatabaseName With Truncate_Only:
DBCC ShrinkFile(yourLogical_LogFileName, 50)
SP_helpfile will give you the logical log file name.
Refer to:
Recover from a full transaction log in a SQL Server database
If your database is in Full Recovery Model and if you are not taking TL backup, then change it to SIMPLE.
It happened with me where the database log file was of 28 GBs.
What can you do to reduce this?
Actually, log files are those file data which the SQL server keeps when an transaction has taken place. For a transaction to process SQL server allocates pages for the same. But after the completion of the transaction, these are not released suddenly hoping that there may be a transaction coming like the same one. This holds up the space.
Step 1:
First Run this command in the database query explored
checkpoint
Step 2:
Right click on the database
Task> Back up
Select back up type as Transaction Log
Add a destination address and file name to keep the backup data (.bak)
Repeat this step again and at this time give another file name
Step 3:
Now go to the database
Right-click on the database
Tasks> Shrinks> Files
Choose File type as Log
Shrink action as release unused space
Step 4:
Check your log file
normally in SQL 2014 this can be found at
C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014EXPRESS\MSSQL\DATA
In my case, its reduced from 28 GB to 1 MB
To my experience on most SQL Servers there is no backup of the transaction log.
Full backups or differential backups are common practice, but transaction log backups are really seldom.
So the transaction log file grows forever (until the disk is full).
In this case the recovery model should be set to "simple".
Don't forget to modify the system databases "model" and "tempdb", too.
A backup of the database "tempdb" makes no sense, so the recovery model of this db should always be "simple".
Take a backup of the MDB file.
Stop SQL services
Rename the log file
Start the service
(The system will create a new log file.)
Delete or move the renamed log file.
Database → right click Properties → file → add another log file with a different name and set the path the same as the old log file with a different file name.
The database automatically picks up the newly created log file.
Try this:
USE DatabaseName
GO
DBCC SHRINKFILE( TransactionLogName, 1)
BACKUP LOG DatabaseName WITH TRUNCATE_ONLY
DBCC SHRINKFILE( TransactionLogName, 1)
GO
Slightly updated answer, for MSSQL 2017, and using the SQL server management studio.
I went mostly from these instructions https://www.sqlshack.com/sql-server-transaction-log-backup-truncate-and-shrink-operations/
I had a recent db backup, so I backed up the transaction log. Then I backed it up again for good measure.
Finally I shrank the log file, and went from 20G to 7MB, much more in line with the size of my data.
I don't think the transaction logs had ever been backed up since this was installed 2 years ago.. so putting that task on the housekeeping calendar.
Backup DB
Detach DB
Rename Log file
Attach DB (while attaching remove renamed .ldf (log file).Select it and remove by pressing Remove button)
New log file will be recreated
Delete Renamed Log file.
This will work but it is suggested to take backup of your database first.
Some of the other answers did not work for me: It was not possible to create the checkpoint while the db was online, because the transaction log was full (how ironic). However, after setting the database to emergency mode, I was able to shrink the log file:
alter database <database_name> set emergency;
use <database_name>;
checkpoint;
checkpoint;
alter database <database_name> set online;
dbcc shrinkfile(<database_name>_log, 200);
DB Transaction Log Shrink to min size:
Backup: Transaction log
Shrink files: Transaction log
Backup: Transaction log
Shrink files: Transaction log
I made tests on several number of DBs: this sequence works.
It usually shrinks to 2MB.
OR by a script:
DECLARE #DB_Name nvarchar(255);
DECLARE #DB_LogFileName nvarchar(255);
SET #DB_Name = '<Database Name>'; --Input Variable
SET #DB_LogFileName = '<LogFileEntryName>'; --Input Variable
EXEC
(
'USE ['+#DB_Name+']; '+
'BACKUP LOG ['+#DB_Name+'] WITH TRUNCATE_ONLY ' +
'DBCC SHRINKFILE( '''+#DB_LogFileName+''', 2) ' +
'BACKUP LOG ['+#DB_Name+'] WITH TRUNCATE_ONLY ' +
'DBCC SHRINKFILE( '''+#DB_LogFileName+''', 2)'
)
GO

Resources