浅谈几个SQL的日志概念 选择自 softj 的 Blog

      sql 2006-8-16 10:13
浅谈几个SQL的日志概念

今天抽出一点时间解释几个关于SQL日志的概念,他们也经常使初学者望而止步,反正计算机的术语都是很抽象的,所以第一感觉就是头疼,然后然后几次后就没感觉了.以下有些是从书上摘抄的,有的是从网上找的算是借花献佛吧!!

物理日志文件:
这个比较好理解,实实在在的东西,数据库目录下面的.ldf文件就是,有些人喜欢改后缀,感觉不大好,数据库的事务日志记录就在这里面

虚拟日志:
相信多数人有这个感觉,虚拟这个字眼总是神秘的代名词,虚拟个饭岛爱我喜欢,但虚拟日志,虚拟内存,虚拟。。。。,看了就讨厌。解释应该是这样的,对于一个或多个连续的物理日志文件,SQL SERVER在这些文件的内部又划分成了多个小的文件,称为虚拟日志文件,他是日志文件收缩和日志截断的最小单位,比如物理日志文件是400M,内部划分了4个100M的虚拟文件,收缩时你得到的是300M,200M,不可能得到239M,对于一个物理文件,会划分成多少个虚拟文件,这个由SQL自己维护,唯一可以人工干预的是指定较大的物理日志文件,并指定较大的增长比例,这样可能虚拟文件的块头会大点,数量会少点,系统的维护开销会低一点

逻辑日志:
不要头晕,硬着头皮看吧!!!感觉这个应该是数据库事务日志的真实写照,物理日志文件好比是一个容器,里面容纳的是日志记录,这些记录就称为逻辑日志,从物理日志文件的起点开始,逻辑日志顺序的生成,记录下数据库里发生的每个事务,这些事务被打上一个标签,LSN,顺序的排列下来,这样逻辑日志就在物理日志文件内慢慢的成长,直到充满了他,这个时候物理日志文件就会自动添加新的空间,以继续前面的步骤,这种情况是最直接的一种(从来不截断日志,基本上就是这样的),但事实上往往是复杂的多

检测点(checkpoint)和恢复周期(recovery interval):
checkpoint不是用于检查数据是否完整,页面连接是否正确的,他是由系统维护的一个进程(你也可以手工的执行),用于将高速缓存里的脏页刷新到磁盘,两者的配合算是惟妙惟肖,当缓存中的脏页积累到一定的数量,SQL估计演算这些脏页要花的时间快要接近设定的recovery interval(分钟)时,系统就会产生一个checkpoint,所以checkpoint的产生不是定时的,它由recovery interval和数据库的更新频繁度决定。如果你的数据库永远不用重启,永远不会出现什么故障,就这么一直运行下去,那么checkpoint和recovery interval就没有想象中的重要了,SQL总是先写日志,情况应该是这样的:用户提交一个更新操作,SQL在高速缓存里缓冲了需要的数据页和日志页,然后打上begin tran标签,对日志进行修改,再修改数据页,然后打上commit tran标签,最后把修改过的日志页刷新到磁盘上,在保证了这个步骤完成后,数据页才被写入磁盘,如果这个时候机器突然断电导致高速缓存中数据页的丢失,那么重启机器时SQL的恢复进程将根据已经刷新的日志记录来演算刚才的数据页,保证数据的完整性,这就好比支票已经开到了,但货却在路上丢了,凭借支票,你还是可以得到你的东西,像这种提交了又还没来得及刷新数据页到磁盘的日志事务可以称为活动日志,虽然概念不是这么定义的,但可以这么理解,因为一旦日志记录和其对应的数据页被刷新到磁盘的话,这条日志的作用也就完成了,并称为非活动的日志,他的唯一用处就是备份下来留着以后做日志恢复,所以SQL的逻辑日志你就应该知道大概是怎么个样子了,前面一大部分,是已经演算的日志记录(非活动日志),后面一部分,是还没有演算的(活动日志),活动部分的第一条事务称为MinLSN,系统会搁段时间利用检测点(checkpoint)演算活动日志,来缩短数据库重启时的恢复时间,在演算结束后,checkpoint会在日志里打上一个结束语,并将MinLSN标识给下一个紧跟着的活动事务日志,这也是下一个checkpoint的起点

截断事务日志:
这个概念很是让初学者费解,截断是什么意思???截断后日志还会增长吗???截断总有个断点吧,他是从哪里开始截断的阿???截断后会释放日志空间吗???等等。。。。现在逐一击破
首先截断是对SQL逻辑日志的一个清除过程,清除非活动的逻辑事务日志。可以想象断点应该是活动与非活动的边界处--MinLSN,他会将MinLSN前面的这段日志清除掉,逻辑日志的起点也会指向断点MinLSN处,清除出来的空间并不会返还给操作系统,而是被标识为非活动的虚拟日志文件,他表示当有新的日志记录进来时,这些空间可以被再次利用,所以截断日志并不会减小物理日志文件的大小,只是清理了里面的一些内容,以便新的日志记录可以进来,SQL总是以循环链表的方式使用物理日志文件的,当逻辑日志增长到物理日志文件的尽头时,他会循环到日志文件的首部搜索被截断而释放出来的空间,如果这个时候没有空间的话,说明物理日志已经用完了,就得增加物理日志的大小,如果磁盘也用尽了,系统就会返回一个错误提示。至于截断后日志是否还会增长,疑点可能存在于trunc log on chkpt上,当数据库处于这种状态时用户会发现他们的日志文件总是那么小一点点,道理很简单,检查点截断日志后,日志文件里面总会有空间容纳新的日志记录,自然是不会变大了,但也有特殊情况,当一个较长的事务运行时(比如一个长达2个小时的UPDATE语句),他会迅速的充满日志,并补充新的空间进来,这个时候系统是来不及截断的,这样物理日志文件就马上变大了,当事务完成后,截断再进行时,对文件的大小他是无能为力了,只是清理下刚才的战场而已,所以截断日志后逻辑日志是继续增长的,至于物理日志,要看你提交事务的大小了

最后的话题:
经常听到这样的说法,定期转存事务日志,以释放日志空间,backup log...with no_log,backup log...with truncate_only,这些只能使日志文件不变大,要想减小日志文件,还是要收缩日志文件,这样才真正将空间返还给操作系统,在sybase里面truncate_only和no_log还是有区别的,都是截断日志,但前者在截断之前会启动checkpoint,所以当你的日志完全被充满,truncate_only是不能成功的,他已经没有空间让你checkpoint,这时只能采用no_log(SQL里面我还不知道),还有一个关键字就是no_truncate,他表示备份但不截断日志(默认是截断的),在数据库因故障损坏时用这个备份日志特别有效

好了,就说这么多了,由于这部分的概念实在是太抽象,本人能力也非常有限,所以表述可能不大清楚,错误的地方请多多指教!!!

标签集:TAGS:
回复Comments() 点击Count()

回复Comments

{commenttime}{commentauthor}

{CommentUrl}
{commentcontent}