| Gzu521.com我的学习网 |
|
1. 如何缩小mssql的日志文件已经是一个经常性的问题了,不过这个问题在精华区已经有不少答案了,我这里也不再赘述。 现在我们讨论一下治本的问题,即如何使日志文件不再增大? 先介绍一个简单的方法。 就是把数据库的故障还原模型设置为“简单”(sql2k)。这样它就会在checkpoint的时候截断日志。 具体操作方法是: 1、在enterprise manager中右键点数据库,“属性|选项|故障还原”,选择“简单”就可以了,如果是sql7,在“属性|选项”中有一个“trunc. log on chkpt. ”,选中就可以了。 2、如果不想用enterprise manager,在query analyser或者isql里面执行 exec sp_dboption ’your_dbname’, ’trunc. log on chkpt.’, ’true’ 就可以了 但是,要注意的是,这样做了之后,虽然日志不会增大,但是也意味着你一旦出现误操作,将不会有利用日志恢复的机会。(如何利用日志来恢复请参见精华区的faq) 所以,绝对不建议在生产数据库上截断日志,除非你有充足的理由和足够的把握,或者…… 承担责任的不是你。 既然这种方法不安全,下面我将介绍一种安全的方法。 大家都知道,SQL Server 在完成事务日志备份时将自动截断事务日志中的不活动部分。这些不活动的部分包含已完成的事务,因此在恢复过程中不再使用。相反,事务日志的活动部分包含仍在运行但尚未完成的事务。sql server 将重新使用事务日志中这些截断的非活动空间,而不是任由事务日志继续增大并占用更多的空间。 所以,我们备份事务日志就可以使日志文件不再增大了。 但是呢,日志文件一直放着也不是个办法,删除呢,又会失去恢复的可能性。 我们可以结合完全备份来做。做过完全备份之前的事务日志就可以删除了。 比如说,一个备份计划,每天一次完全备份,保留7天内的,每15分钟一次事务日志备份,保留2天的。 用数据库维护计划向导可以很方便的建立备份计划,不过一定要记得设置保留多久的备份哦,否则硬盘空间被备份给占满了就坏事了。 2. 前几天也碰到日志文件过大的问题,数据库实际大小为600m, 日志文件实际大小为33m, 但日志文件占用空间为2.8g!!! 试了多种方式,shirnk database, truncate log file, 都没办法将文件缩小。无论如何,这应该算sql server的一个bug吧。 后来找到下面的代码,就可以将日志文件缩小到自己想要的大小了。把代码copy到查询分析器里,,然后修改其中的3个参数(数据库名,日志文件名,和目标日志文件的大小),运行即可(我已经用过多次了) ----- set nocount on declare @logicalfilename sysname, @maxminutes int, @newsize int use marias -- 要操作的数据库名 select @logicalfilename = ’marias_log’, -- 日志文件名 @maxminutes = 10, -- limit on time allowed to wrap log. @newsize = 100 -- 你想设定的日志文件的大小(m) -- setup / initialize declare @originalsize int select @originalsize = size from sysfiles where name = @logicalfilename select ’original size of ’ + db_name() + ’ log is ’ + convert(varchar(30),@originalsize) + ’ 8k pages or ’ + convert(varchar(30),(@originalsize*8/1024)) + ’mb’ from sysfiles where name = @logicalfilename create table dummytrans (dummycolumn char (8000) not null) declare @counter int, @starttime datetime, @trunclog varchar(255) select @starttime = getdate(), @trunclog = ’backup log ’ + db_name() + ’ with truncate_only’ dbcc shrinkfile (@logicalfilename, @newsize) exec (@trunclog) -- wrap the log if necessary. while @maxminutes > datediff (mi, @starttime, getdate()) -- time has not expired and @originalsize = (select size from sysfiles where name = @logicalfilename) and (@originalsize * 8 /1024) > @newsize begin -- outer loop. select @counter = 0 while ((@counter < @originalsize / 16) and (@counter < 50000)) begin -- update insert dummytrans values (’fill log’) delete dummytrans select @counter = @counter + 1 end exec (@trunclog) end select ’final size of ’ + db_name() + ’ log is ’ + convert(varchar(30),size) + ’ 8k pages or ’ + convert(varchar(30),(size*8/1024)) + ’mb’ from sysfiles where name = @logicalfilename drop table dummytrans set nocount off |
责任编辑:gzu521