sql server 日志文件结构及误操作数据找回

sql server 日志文件结构及误操作数据找回

一. 概述

  在sql server 里有数据文件.mdf和日志文件.ldf,日志文件是sqlserver数据库的另一个重要组成部分,日志文件记录了所有事务以及每个事务对数据库所做的修改。为了提高数据库的性能, sqlserver 数据是缓存在内存里,并没有实时写入到磁盘,直到数据库出现检查点(checkpoint)或者内存不足必须(Lazy Write)将数据的修改写入到磁盘。 sql server在开启了事务并对内存中的数据进行修改时,会生成日志记录。 sqlserver 对数据页的插入修改删除都是在内存中完成后提交事务,但并不会同步到硬盘的数据页上。 为了保证数据库事务的一致性 如(服务器崩溃,断电)等 内存中的修改没有来得及写入硬盘,下次重启时候要能够恢复到一个事务一致的时间点,就必须依赖于事务日志。

     1.1 存储结构

  与数据文件不同 日志文件不是按页/区来进行组织的。每个物理日志文件是分成多个虚拟日志单元,虚拟日志单元没有固定大小,且数量不固定, 管理员也不能配置大小和数量。 例如:日志文件每自动增长一次(默认是按10%的空间扩展),会至少增加一个虚拟单元。

  事务日志是一种回绕的文件。例如一个数据库里的日志文件包括5个虚拟日志单元,在创建数据库时,逻辑日志文件从物理文件的始端开始,新的日志记录被添加到逻辑日志未端,然后向物理日志未端扩张。

  当逻辑日志的末端到达物理日志的末端时,新的日志记录将回绕到物理日志文件的始端继续向后写(这是因为日志备份会截断使日志空间重用)。

  下图是日志文件的流程图,当日志备份后虚拟日志1和虚拟日志2会被截断,虚拟日志3成为了逻辑日志的开头,当虚拟日志3和虚拟日志4在使用后,再次备份时,由于日志文件是一个回绕的文件,此时又从虚拟日志1开始。
   图1  日志文件的外观

  sql server 日志文件结构及误操作数据找回

  图2 事务日志的循环使用

     sql server 日志文件结构及误操作数据找回

   在一个虚拟日志单元里,分成很多块,块内有具体的日志记录,每条日志记录有一个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是未公开的命令,所以未找到相关说明, 如下图所示 包括了当前序号号,操作类型,事务号等相关信息。

sql server 日志文件结构及误操作数据找回

 二. ApexSQL Log工具

  由于dbcc log数据不太直观,现通过第三方工具ApexSQL Log来查看,该工具可以看到对上面表的创建,插入,更新,删除的操作记录,在数据库日志文件里还标注了起始时间表,以及操作由哪个用户执行的,对于每一个操作,可以看到更具体的更新信息。

    这是刚刚操作的二条记录如下图所示

    sql server 日志文件结构及误操作数据找回

  选中insert 该行可以找到该语句做undo (撤消回滚 旧值覆盖)和redo(提交 新值覆盖)

  sql server 日志文件结构及误操作数据找回

-- 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 可能是因为该软件需要付费。

sql server 日志文件结构及误操作数据找回

  总结: 使用truncate table 来删除操作是不会记录日志的,且无法做undo操作。日志记录与实际修改的数据量有关,每一条记录的修改都会保存日志记录。sql server日志里面能读到数据修改前的值和修改后的值。

 

参考文献:

  sq lserver2012实施与管理实战指南

转载于:https://www.cnblogs.com/MrHSR/p/9346369.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101519.html原文链接:https://javaforall.net

(0)
上一篇 2021年6月9日 下午6:00
下一篇 2021年6月9日 下午7:00


相关推荐

  • pycharm2021.11.2激活码(注册激活)

    (pycharm2021.11.2激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html0E14HXZ4QL-eyJsaWN…

    2022年3月29日
    42
  • layoutParams的用法

    layoutParams的用法沙翁向昨天要经验 向今天要结果 向明天要动力 Android 开发 LayoutParams 的用法 LayoutParams 继承于 Android View ViewGroup LayoutParams nbsp nbsp nbsp nbsp LayoutParams 相当于一个 Layout 的信息包 它封装了 Layout 的位置 高 宽等信息 假设在屏幕上一块区域是由一个 Layout

    2026年3月18日
    2
  • MCP协议详解:复刻Manus全靠它,为什么说MCP是Agent进化的一大步?

    MCP协议详解:复刻Manus全靠它,为什么说MCP是Agent进化的一大步?

    2026年3月15日
    2
  • Redis集群详解

    Redis集群详解Redis集群详解Redis有三种集群模式,分别是:*主从模式*Sentinel模式*Cluster模式三种集群模式各有特点,关于Redis介绍可以参考这里:NoSQL(二)——RedisRedis官网:https://redis.io/,最新版本5.0.4主从模式主从模式介绍主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从…

    2022年6月13日
    27
  • ptrace使用简介

    ptrace使用简介ptrace 提供了一种机制使得父进程可以观察和控制子进程的执行过程 ptrace 还可以检查和修改子进程的可执行文件在内存中的 image 及子进程所使用的寄存器中的值 通常来说 主要用于实现对进程插入断点和跟踪子进程的系统调用 用法示例 include sys ptrace h include sys types h include sys wait h include unistd h include unistd h sys sys sys

    2026年3月17日
    2
  • 绘制高斯隶属函数

    绘制高斯隶属函数绘制高斯隶属函数模糊理论高斯型隶属函数实现模糊理论模糊理论以连续隶属函数理论为基础 它可以分为五个分支 模糊数学 模糊系统 不确定性和信息 模糊决策 模糊逻辑与人工智能 隶属函数是用于表示模糊集的数学工具 它表示元素属于模糊集的 真实度 隶属函数的值介于 0 和 1 之间 这似乎是概率 但它是一个不同的概念 它代表了一个程度 高斯隶属函数是其隶属函数之一 高斯型隶属函数高斯型隶属函数

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号