SQL SERVER 事务日志

   谈到事务日志就不得不谈下检查点 Checkpoint ,简称 CKP. 事务日志和检查点都是为了数据库的快速恢复而存在的。我们需要知道检查点是干什么的,它和事务日志有什么关系。

  CKP是干什么的?

  总所周知,数据的更改并没有直接写入mdf/ndf 数据文件中,而是写入了buffer pool中; 当CKP被触发后,检查点将“全部”脏数据页从当前数据库的buffer pool刷新到数据文件上。所谓的脏数据,是那些被更改的 data page ,在内存中却没有写入磁盘。全部脏数据包括已提交的数据更改和未提交的数据更改。刷新到数据文件是指将数据更改的后镜像copy写入数据文件,对数据的更改会保留一个前镜像和一个后镜像,好比我们修改文章,先保存原文作为前镜像,而后将修改后的文章作为后镜像。同时CKP也会flush cached log 到日志文件中 点击打开链接 .我更愿意将CKP看作是一个闹钟,我们可以对它按照一个规则定时,然后提醒SQL的部件data writer / log writer去干活。

  总之,大多数情况下,什么时候数据更改写入数据文件,是由CKP决定的。

  CKP什么时候被触发

  备份数据库 (全备,差异备份,日志备份)

  checkpoint命令

  关闭数据库

  Alter database命令

  自动的检查点触发 (SQL依据recovery interval 服务器配置选项建议的时间上限触发检查点 或者日志已满 70%触发检查点)

  间接检查点 (SQL 2012 新特性 ,详情参与点击打开链接)

  CKP, Lazywriter, Eagerwriter的区别

  总所周知这三个SQL的process都会将脏数据写入数据文件,但是它们的目的和触发条件完全不同

  CKP的使用目的是为了在SQL intance停止后(例如断电),快速的instance recovery。它是一个时间点的标记,标记了数据库恢复的起始点。在这个起始点,所有的脏数据copy都写入了磁盘(它不会释放内存空间),从而在以后的恢复过程中节省时间。

  Lazy writer是为了更好的利用buffer pool。 它会定期检查data cache,按照LRU算法,将长期未使用到的dirty page 写入磁盘, 清除dirty page释放内存空间。

  Eager writer 是为BCP等批量插入而存在的。该进程会写入与无日志记录的操作(例如大容量插入和选择插入)相关联的脏数据页。该进程允许以并行方式创建和写入新页。也就是说,调用操作不必等待整个操作完成,即可将页写入磁盘 (摘于msdn点击打开链接 )。这样可以保证Buffer Pool有足够的空间完成批量操作。

  CKP和事务日志有什么关系呢?

  与其说是与事务日志的关系,不如说是与事务日志序列号(Log Sequence Number, 简称LSN)的关系,在我以后的blog会对LSN做阐述。

  检查点触发有一个起始时间点,这个时间点会被记录在事务日志里,获得一个CKP起始时间点LSN。当完成脏数据写后,CKP同样在日志文件里记录一个结束时间点的LSN。检查点还会记录一个最小恢复LSN (minLSN), minLSN必须存在检查点记录里才能成功进行回滚(roll back / undo), minLSN告诉了SQL Server 可以回滚的最远时间点。至于minLSN是什么,SQL如何定义minLSN,SQL server如何使用它,在我以后的blog做阐述)这里只要记住CKP会纪录这个minLSN,它很对undo很重要。

时间: 2025-01-18 23:12:12

SQL SERVER 事务日志的相关文章

SQL Server事务日志的几个常用操作

我们知道,SQL Server事务日志主要是用来记录所有事务对数据库所做的修改,如果系统出现故障,它将成为最新数据的唯一来源.日志的操作常有以下几个应用: 一.事务日志文件LDF的丢失 当我们不小删除或者LDF文件丢失的时候,数据库只剩下MDF文件,此时直接通过附加MDF是无法恢复数据库的,那我们怎么样才能恢复数据库呢?我们可以把SQL Server的日志文件分为两种形式:一类是无活动事务的日志,另一类是有活动事务的日志,我们分别根据两种情况来进行数据库恢复. 1.无活动事务的日志恢复 当文件并

SQL Server事务日志被填满的原因是什么

SQL Server事务日志可能会被填满,这会阻止之后的数据库操作,包括UPDATE, DELETE, INSERT 和CHECKPOINT. 事务日志填满会导致1105错误: Can't allocate space for object syslogs in database dbname because the logsegment is full. If you ran out of space in syslogs, dump the transaction log. Otherwis

人人都是 DBA(VI)SQL Server 事务日志

原文:人人都是 DBA(VI)SQL Server 事务日志 SQL Server 的数据库引擎通过事务服务(Transaction Services)提供事务的 ACID 属性支持.ACID 属性包括: 原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability) 事务日志(Transaction Log) 事务日志(Transaction Log)存储的是对数据库所做的更改信息,让 SQL Server 有机会恢复数据库.而恢复

SQL Server 事务和锁详解

最近在项目中进行压力测试遇到了数据库的死锁问题,简言之,如下的代码在 SERIALIZABLE 隔离级别造成了死锁:  代码如下 复制代码 SELECT @findCount=COUNT(id) FROM MyTable WHERE [fk_related_id]=@Argument IF (@findCount > 0) BEGIN ROLLBACK TRANSACTION RETURN ERROR_CODE END INSERT INTO MyTable ([fk_related_id],-

winform 项目删除sql server事务问题

问题描述 winform 项目删除sql server事务问题 当我点击删除时报下面错误,是什么意思? 怎么解决?项目是winform 数据库是sql server 如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务.命令的 Transaction 属性尚未初始化. 事务部分代码 bool isSucess = false; using (DbBase DbContext = new DbBase(connectionName)) { using (IDbTra

如何使Microsoft SQL Server的日志文件不会增大

server 说   明:如何使Microsoft SQL Server的日志文件不会增大? 如何缩小MSSQL的日志文件已经是一个经常性的问题了,不过这个问题在精华区已经有不少答案了,我这里也不再赘述.现在我们讨论一下治本的问题,即如何使日志文件不再增大? 先介绍一个简单的方法.就是把数据库的故障还原模型设置为"简单"(SQL2K).这样它就会在Checkpoint的时候截断日志.具体操作方法是:1.在Enterprise Manager中右键点数据库,"属性|选项|故障还

SQL Server 压缩日志与减少SQL Server 文件大小的方法

一般不建议做第4,6两步,第4步不安全,有可能损坏数据库或丢失数据.第6步如果日志达到上限,则以后的数据库处理会失败,在清理日志后才能恢复. 1.清空日志 DUMP TRANSACTION 库名 WITH NO_LOG 2.截断事务日志 BACKUP LOG 数据库名 WITH NO_LOG 3.收缩数据库文件 (如果不压缩,数据库的文件不会减小企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件 选择日志文件--在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M

教你维护SQL Server数据库日志。

[导读]教你维护SQL Server数据库日志. 交易日志(即oracle中的事务)(Transaction logs)是数据库结构中非常重要但又经常被忽略的部分.由于它并不像数据库中的schema那样活跃,因此很少有人关注交易日志. 交易日志是针对数据库改变所做的记录,它可以记录针对数据库的任何操作,并将记录结果保存在独立的文件中.对于任何每一个交易过程,交易日志都有非常全面的记录,根据这些记录可以将数据文件恢复成交易前的状态.从交易动作开始,交易日志就处于记录状态,交易过程中对数据库的任何操

SQL语句实现SQL Server 2000及Sql Server 2005日志收缩(批量)_MsSql

复制代码 代码如下: DECLARE @name VARCHAR(25) DECLARE @SQL VARCHAR(1000) DECLARE @logid INT DECLARE sysdatabase_name CURSOR FOR SELECT name FROM master.dbo.sysdatabases OPEN sysdatabase_name FETCH NEXT FROM sysdatabase_name INTO @name WHILE @@FETCH_STATUS = 0