一. 概述
在sql server 里有数据文件.mdf和日志文件.ldf,日志文件是sqlserver数据库的另一个重要组成部分,日志文件记录了所有事务以及每个事务对数据库所做的修改。为了提高数据库的性能, sqlserver 数据是缓存在内存里,并没有实时写入到磁盘,直到数据库出现检查点(checkpoint)或者内存不足必须(Lazy Write)将数据的修改写入到磁盘。 sql server在开启了事务并对内存中的数据进行修改时,会生成日志记录。 sqlserver 对数据页的插入修改删除都是在内存中完成后提交事务,但并不会同步到硬盘的数据页上。 为了保证数据库事务的一致性 如(服务器崩溃,断电)等 内存中的修改没有来得及写入硬盘,下次重启时候要能够恢复到一个事务一致的时间点,就必须依赖于事务日志。
1.1 存储结构
与数据文件不同 日志文件不是按页/区来进行组织的。每个物理日志文件是分成多个虚拟日志单元,虚拟日志单元没有固定大小,且数量不固定, 管理员也不能配置大小和数量。 例如:日志文件每自动增长一次(默认是按10%的空间扩展),会至少增加一个虚拟单元。
事务日志是一种回绕的文件。例如一个数据库里的日志文件包括5个虚拟日志单元,在创建数据库时,逻辑日志文件从物理文件的始端开始,新的日志记录被添加到逻辑日志未端,然后向物理日志未端扩张。
当逻辑日志的末端到达物理日志的末端时,新的日志记录将回绕到物理日志文件的始端继续向后写(这是因为日志备份会截断使日志空间重用)。
下图是日志文件的流程图,当日志备份后虚拟日志1和虚拟日志2会被截断,虚拟日志3成为了逻辑日志的开头,当虚拟日志3和虚拟日志4在使用后,再次备份时,由于日志文件是一个回绕的文件,此时又从虚拟日志1开始。
图1 日志文件的外观
图2 事务日志的循环使用
在一个虚拟日志单元里,分成很多块,块内有具体的日志记录,每条日志记录有一个LSN(Log Sequence Number)编号,这个编号由三部分组成。第一部分是虚拟日志单元(Virtual Log File)序列号,第二部分是在虚拟日志单元中块的编号,第三部分是在块中日志记录的编号。对于某个LSN,其编号为000001D:000000FD:0002。 这表明这个LSN是属于虚拟日志000001D,该虚拟日志中属于块000000FD,在该块中对应记录2。
1.2 DBCC LOG
使用DBCC LOG来查看日志文件里存放了些什么信息, dbcc log(dbname, formart_id),formart_id 使用"3" 参数输出会比较详细。
Create database TestLog
go
use TestLog
go
Create Table Test(ID int,name nvarchar(50))
GO
Insert into Test Values(1,'aaaa')
update Test set name='bbbb' where ID=1
Go
dbcc traceon (3604)
go
dbcc log (TestLog,3)
由于dbcc log是未公开的命令,所以未找到相关说明, 如下图所示 包括了当前序号号,操作类型,事务号等相关信息。
二. ApexSQL Log工具
由于dbcc log数据不太直观,现通过第三方工具ApexSQL Log来查看,该工具可以看到对上面表的创建,插入,更新,删除的操作记录,在数据库日志文件里还标注了起始时间表,以及操作由哪个用户执行的,对于每一个操作,可以看到更具体的更新信息。
这是刚刚操作的二条记录如下图所示
选中insert 该行可以找到该语句做undo (撤消回滚 旧值覆盖)和redo(提交 新值覆盖)
-- Undo INSERT (0000001E:00000047:0013) done at 2018-07-29 09:49:55.570 by hsr-PC\hsr in transaction 0000:00000301 (Committed)
BEGIN TRANSACTION
DELETE FROM [dbo].[Test] WHERE /*** WARNING: WHERE CLAUSE FOR THIS STATEMENT WAS GENERATED FOR A TABLE WITH NO PRIMARY KEY AND NO CLUSTERED INDEX ***/[ID] = 1 AND [name] = N'aaaa' COLLATE Chinese_PRC_CI_AS
IF @@ROWCOUNT <= 1 COMMIT TRANSACTION ELSE BEGIN ROLLBACK TRANSACTION; PRINT 'ERROR: STATEMENT AFFECTED MORE THAN ONE ROW. ALL THE CHANGES WERE ROLLED BACK.' END
--Redo INSERT (0000001E:00000047:0013) done at 2018-07-29 09:49:55.570 by hsr-PC\hsr in transaction 0000:00000301 (Committed)
INSERT INTO [dbo].[Test] ([ID], [name]) VALUES (1, N'aaaa' COLLATE Chinese_PRC_CI_AS)
-- 下面ID=1的语句做四做操作
update Test set name='cccc' where ID=1
update Test set name='dddd' where ID=1
update Test set name='eeee' where ID=1
delete from Test where ID=1
下列记录了相应的操作,trial restricted 可能是因为该软件需要付费。
总结: 使用truncate table 来删除操作是不会记录日志的,且无法做undo操作。日志记录与实际修改的数据量有关,每一条记录的修改都会保存日志记录。sql server日志里面能读到数据修改前的值和修改后的值。
参考文献:
sq lserver2012实施与管理实战指南
sql server 日志文件结构及误操作数据找回的更多相关文章
-
误删SQL Server日志文件后怎样附加数据库
SQL Server日志文件因为误操作被删除,当附加数据库的时候提示:附加数据库失败. 解决办法如下: 1.新建一个同名数据库. 2.停止数据库服务,覆盖新建的数据库主文件(小技巧:最好放在同一个磁盘 ...
-
清理SQL Server日志释放文件空间的终极方法
清理SQL Server日志释放文件空间的终极方法 转自:http://www.cnblogs.com/dudu/archive/2013/04/10/3011416.html [问题场景]有一个数 ...
-
SQL Server日志文件庞大收缩方法(实测好用)
原文:SQL Server日志文件庞大收缩方法(实测好用) 这两个命令连续执行,间隔时间越少越明显(可多次运行),直到达到效果 --截断 BACKUP LOG CloudMonitor TO DISK ...
-
收缩SQL Server日志不是那么简单
收缩SQL Server日志不是那么简单的(翻译) 原文地址:http://rusanu.com/2012/07/27/how-to-shrink-the-sql-server-log/ 说明:本 ...
-
SQL Server 日志和代理的错误日志
本文介绍的日志不是事务日志,而是SQL Server 日志和代理的错误日志,按照主体把错误日志分为SQL Server.SQL Server Agent.Database Mail,以及 Window ...
-
SQL Server日志文件过大 大日志文件清理方法 不分离数据库
SQL Server日志文件过大 大日志文件清理方法 ,网上提供了很多分离数据库——〉删除日志文件-〉附加数据库 的方法,此方法风险太大,过程也比较久,有时候也会出现分离不成功的现象.下面的方式 ...
-
解决Sql Server 日志满了,设置收缩
解决Sql Server 日志满了,设置收缩: --查看文件占用空间 . '文件大小(MB)',* from sysfiles; ALTER DATABASE SpyData SET RECOVERY ...
-
SQL SERVER 日志写入原理浅析
昨天看到网上有一个关于SQL SERVER 课件,便随手下载了下来看看主要讲了些什么内容,于是看到了下面两个PPT页面 由于第一张PPT上的内容不太准确(日志文件中没有“日志页”的概念,只有VLF的概 ...
-
sql server日志传送实践(基于server 2008 R2)
SQL Server 2008 R2 主从数据库同步 相关参考:http://blog.itpub.net/30126024/viewspace-2639526/ sql server日志传送(基于s ...
随机推荐
-
关于http协议的理解
一.状态码 1.200:请求成功. 2.302:浏览器进行重定向. 3.304:资源已使用,即有缓存. 4.404:请求失败,请求的资源未在服务器上发现. 5.500:服务器端发生错误. 二.php获 ...
-
Bootstrap学习之路(3)---列表组件
列表是几乎所有网站都会用到的一个组件,正好bootstrap也给我们提供了这个组件的样式,下面我给大家简单介绍一下bootstrap中的列表组件的用法! 首先,重提一下引用bootstrap的核心文件 ...
-
struts2的配置和使用
一:配置stuts2的运行环境,把以下的包放到WEB-INF/lib目录下 1,structs2-core-2.1.6.jar struts的核心库 2,xwork-2.1.2.jar ...
-
.net调用Outlook 批量发送邮件,可指定Outlook中的账号来发送邮件
.net调用Outlook 批量发送邮件,可指定Outlook中的账号来发送邮件 源码可以在我的资源列表中下载: MPOEMail http://download.csdn.net/my VS2012 ...
-
2.9 while循环
while循环 <1>while循环的格式 while 条件: 条件满足时,做的事情1 条件满足时,做的事情2 条件满足时,做的事情3 ...(省略)... demo i = 0 whil ...
-
VD: error VERR_FILE_NOT_FOUND
virtualbox制作的镜像文件如果移动了位置,比如从C盘移到D盘,那么再次打开时会提示找不到文件. 解决办法: 打开virtualbox,在“管理”菜单中打开“虚拟介质管理”,在“虚拟硬盘”选项卡 ...
-
[ZJOI2012]旅游
题目: 这题意...还以为他说的线段是路径 写了好久的dp..写不出来 看了网上的题解..才知道就是两点连线 然后就是一般的平面图转对偶图的思想 然后算一下边数发现是颗树,求一下直径就好了 代码: # ...
-
Shell - 简明Shell入门12 - 定制输出(ColorOutput)
示例脚本及注释 #!/bin/bash echo -e "\033[32m" # 设置输出属性,绿色字体 echo "This is a test!" echo ...
-
基于Docker一键部署大规模Hadoop集群及设计思路
一.背景: 随着互联网的发展.互联网用户的增加,互联网中的数据也急剧膨胀.每天产生的数据量数以万计,本地文件系统和单机CPU已无法满足存储和计算要求.Hadoop分布式文件系统(HDFS)是海量数据存 ...
-
flask_wtf/wtforms几个坑点,先简单记此
1.@pluginquery.route('/app_include_plugins', methods=['GET','POST']) methods必须填写 2.plu_incl_app = St ...