为什么完整备份不能截断事务日志

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 为此,当数据库处于完整恢复模式时(非特别说明,下文所提到都是完整恢复模式下的数据库),DBA们必须频繁地使用事务日志备份的方式来防止日志文件变得过大。

导言

完整备份不能截断事务日志,这是所有SQL Server DBA的一个常识,

为此,当数据库处于完整恢复模式时(非特别说明,下文所提到都是完整恢复模式下的数据库),DBA们必须频繁地使用事务日志备份的方式来防止日志文件变得过大。

这几乎成为了DBA们的一个定理,但,作为一个DBA,你证明过这个定理吗?你知道为什么完整备份不能截断事务日志吗?

 

一个错误的”常识“

将一个完整备份还原到新数据库时,新数据库无论是mdf还是ldf,其大小都跟原始数据库一模一样,

以至于我们认为完整备份包括了mdf中所有数据和ldf中的所有事务日志。这几乎成为了一些DBA的”常识“。

正是如此,我们有”理由“认为:数据库在完整备份后,ldf中的事务日志应该被截断,没必要再保存一个副本。

 

 

让“常识”站不住脚

按照这个”常识“,既然完整备份中包含了原始数据库中所有的事务日志,那通过完整备份还原得到的新数据库应该也含有同样的事务日志。下面我们通过一个小实验来验证实际情况是否是这样。

验证思路:

复制代码
--首先新建一个数据库和一张表,并将数据库设置完整恢复模式下 
 
 

CREATE DATABASE test;
USE Test; 
CREATE TABLE t1(col1 INT,col2 VARCHAR(25));
 ALTER DATABASE Test SET RECOVERY FULL;


--在表中插入5条数据
 
 

INSERT INTO t1 VALUES(1,'chen1');
INSERT INTO t1 VALUES(2,'chen2');
INSERT INTO t1 VALUES(3,'chen3');
INSERT INTO t1 VALUES(4,'chen4');
INSERT INTO t1 VALUES(5,'chen5');




--完整备份数据库
BACKUP DATABASE Test TO DISK='d:\temp\oldtest.bak'
--还原到新数据库 

RESTORE DATABASE test_new FROM DISK='d:\temp\oldtest.bak' WITH MOVE 'test' TO 'd:\temp\test.mdf' , MOVE 'test_log' TO 'd:\temp\test_log.ldf'    --对比新老数据库LDF中的事务日志大小  DBCC SQLPERF(LOGSPACE)
--结果:LDF文件大小相同
    --对比新老数据库LDF中的事务日志内容(通过ApexSQL Log软件分析新老数据库的LDF文件)
--结果:原数据库和新数据库的事务日志不相同
 
复制代码

 

结论1:

通过完整备份文件还原得到的数据库,尽管其LDF的大小与原数据库相同,但两者所包含的事务日志并不完全相同,如上例所述,原数据库test包含5条insert的事务日志,而新数据库test_new没有这些事务日志。如果完整备份截断了事务日志,则无论是原数据库的LDF文件还是完整备份文件,都将不包含事务日志,这无异于将数据库置于简单恢复模式下,显然不符合我们将数据库设置成完整恢复模式的初衷。

 

完整备份的那些事

通过上述实例我们已经有了足够的理由推翻那个错误的“常识”,但,这个例子似乎并不完美,因为它又将我们导向了另一个错误的极端——完整备份不包括任何事务日志。

真是这样的吗?

本质是是现象的根源,只有真正了解了数据库完整备份期间发生的那些事,我们才能揭开层层迷雾。

归纳起来,数据库的完整备份主要包括如下几个步骤:

    1. 执行Checkpoint,并标记此时数据库中事务日志的LSN

    2. 开始读取、拷贝data files中的数据

    3. 结束data files的读取和拷贝,并记录此时最后一个活动日志的起始LSN

    4. 读取并拷贝必需的日志文件

摘自:http://technet.microsoft.com/en-us/magazine/2009.07.sqlbackup.aspx#id0980008

8_thumb3

备注:读者在查看上述日志时,请先开启3004、3605、3502这三个跟踪标记。

 

DBCC TRACEON(3004,3605,3502,-1)

 

至此,我们已经明白了,在完整备份文件里,它虽然没有包含所有的事务日志,但在完整备份期间,拷贝日志的动作一直存在,按照SQL Server的说法,完整备份选择性的保存了数据库必需的事务日志。

为什么要选择性的保存这些必需事务日志呢?什么是“必需的事务日志”?而我的样例中新数据库为何没有任何事务日志?

 

在回答这些问题前,我们先看一下MSDN对完整备份文件的一个描述:

Full database backups represent the database at the time the backup finished.

也就是说,完整备份文件能够呈现数据库在备份完成时间点的所有数据,那么,这些足够多的事务日志的目的肯定是为了将数据库还原到备份完成时的时间点。

有了这个概念,我们来看一个完整备份的场景,下图绿色的数字代表完整备份的每个步骤:

  1. 执行事务A
  2. 执行完整备份和checkpoint,开始读取和拷贝数据文件
  3. 备份进程读取数据页X
  4. 执行事务B,改变数据页X的数据
  5. 结束事务B
  6. 结束对数据文件的读取和拷贝

 

 

9_thumb1

 

数据库的完整备份从时间点2持续到时间点7。

对于页面 X,在时间点3做了备份后,在时间点5被事务B做了修改,因此,此时备份文件中页面X的数据已经过期了、不准确,而备份进程不会回过头来重新读取页面X。因为“完整备份文件必须呈现数据库在备份完成时间点的所有数据”,所以,数据库必须备份事务B的日志,以便在数据库通过重做此日志还原到时间点7的状态。

对于事务A,其执行的时间早于备份的开始时间,且在数据文件备份期间一直没有结束,是这次完整备份的活动事务。

尽管事务A没有提交,但时间点2的checkpoint已将事务A所做的修改写入到数据文件中,如果完整备份文件没有包含事务A的日志,则这些未提交的修改将无法得到回滚,导致数据不一致的情况发生。

综上所述:

结论2

如果在完整备份前不存在活动事务,则必需的事务日志范围:从备份开始时的LSN到备份结束时的LSN;

如果在完整备份前存在活动事务,则必需的事务日志范围:从最早活动事务开始的LSN到备份结束时的LSN;

10_thumb2

 

在我之前的样例中,因为5条insert语句在数据库备份前已经执行完成并提交了,所以备份文件不会保存这些日志,因而在还原得到的新数据库中看不到这些日志。

至此,我们已经完成了这个定理的证明过程,感谢各位的耐心品读,欢迎大家批评指教。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1504 1
|
1月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
78 0
|
2月前
|
API C# 开发框架
WPF与Web服务集成大揭秘:手把手教你调用RESTful API,客户端与服务器端优劣对比全解析!
【8月更文挑战第31天】在现代软件开发中,WPF 和 Web 服务各具特色。WPF 以其出色的界面展示能力受到欢迎,而 Web 服务则凭借跨平台和易维护性在互联网应用中占有一席之地。本文探讨了 WPF 如何通过 HttpClient 类调用 RESTful API,并展示了基于 ASP.NET Core 的 Web 服务如何实现同样的功能。通过对比分析,揭示了两者各自的优缺点:WPF 客户端直接处理数据,减轻服务器负担,但需处理网络异常;Web 服务则能利用服务器端功能如缓存和权限验证,但可能增加服务器负载。希望本文能帮助开发者根据具体需求选择合适的技术方案。
78 0
|
2月前
|
C# Windows 监控
WPF应用跨界成长秘籍:深度揭秘如何与Windows服务完美交互,扩展功能无界限!
【8月更文挑战第31天】WPF(Windows Presentation Foundation)是 .NET 框架下的图形界面技术,具有丰富的界面设计和灵活的客户端功能。在某些场景下,WPF 应用需与 Windows 服务交互以实现后台任务处理、系统监控等功能。本文探讨了两者交互的方法,并通过示例代码展示了如何扩展 WPF 应用的功能。首先介绍了 Windows 服务的基础知识,然后阐述了创建 Windows 服务、设计通信接口及 WPF 客户端调用服务的具体步骤。通过合理的交互设计,WPF 应用可获得更强的后台处理能力和系统级操作权限,提升应用的整体性能。
77 0
|
2月前
|
数据库 Java 监控
Struts 2 日志管理化身神秘魔法师,洞察应用运行乾坤,演绎奇幻篇章!
【8月更文挑战第31天】在软件开发中,了解应用运行状况至关重要。日志管理作为 Struts 2 应用的关键组件,记录着每个动作和决策,如同监控摄像头,帮助我们迅速定位问题、分析性能和使用情况,为优化提供依据。Struts 2 支持多种日志框架(如 Log4j、Logback),便于配置日志级别、格式和输出位置。通过在 Action 类中添加日志记录,我们能在开发过程中获取详细信息,及时发现并解决问题。合理配置日志不仅有助于调试,还能分析用户行为,提升应用性能和稳定性。
42 0
|
2月前
|
SQL 安全 测试技术
【数据守护者必备】SQL数据备份与恢复策略全解析:从全量到日志备份,手把手教你确保企业信息万无一失的实战技巧!
【8月更文挑战第31天】数据库是企业核心业务数据的基石,为防止硬件故障、软件错误或人为失误导致的数据丢失,制定可靠的备份与恢复策略至关重要。本文通过一个在线购物平台的案例,详细介绍了使用 SQL Server 进行全量备份、差异备份及事务日志备份的方法,并演示了如何利用 SQL Server Agent 实现自动化备份任务。此外,还提供了数据恢复的具体步骤和测试建议,确保数据安全与业务连续性。
69 0
|
2月前
|
存储 关系型数据库 MySQL
深入MySQL:事务日志redo log详解与实践
【8月更文挑战第24天】在MySQL的InnoDB存储引擎中,为确保事务的持久性和数据一致性,采用了redo log(重做日志)机制。redo log记录了所有数据修改,在系统崩溃后可通过它恢复未完成的事务。它由内存中的redo log buffer和磁盘上的redo log file组成。事务修改先写入buffer,再异步刷新至磁盘,最后提交事务。若系统崩溃,InnoDB通过redo log重放已提交事务并利用undo log回滚未提交事务,确保数据完整。理解redo log工作流程有助于优化数据库性能和确保数据安全。
297 0
|
2月前
|
存储 SQL 关系型数据库
MySQL事务日志奥秘:undo log大揭秘,一文让你彻底解锁!
【8月更文挑战第24天】本文深入探讨了MySQL中undo log的关键作用及其在确保事务原子性和一致性方面的机制。MySQL通过记录事务前的数据状态,在需要时能回滚至初始状态。主要介绍InnoDB存储引擎下的undo log实现,包括undo segment和record的结构,而MyISAM则采用redo log保障持久性而非一致性。通过一个简单的SQL回滚示例,展示了undo log如何在实际操作中发挥作用,帮助读者更好地理解并运用MySQL事务管理功能。
201 0
|
2月前
|
Kubernetes Ubuntu Windows
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
【Azure K8S | AKS】分享从AKS集群的Node中查看日志的方法(/var/log)
100 3
|
1天前
|
存储 分布式计算 NoSQL
大数据-136 - ClickHouse 集群 表引擎详解1 - 日志、Log、Memory、Merge
大数据-136 - ClickHouse 集群 表引擎详解1 - 日志、Log、Memory、Merge
9 0