单个48TB大小SQL Server数据库备份导致日志文件无法截断

SQL Server 版本:SQL Server 2019
背景
在一个48T大小的单数据库环境中,采用简单恢复模式,日志文件大小限制为600G。执行一次完整备份时,耗时超过12小时,导致日志文件无法截断并达到上限,后续事务无法正常写入,导致整个数据库不可用。

问题现象
LDF日志文件中的虚拟日志文件 (VLF) 全部为活动状态,导致日志无法正常截断。由于日志文件大小达到了600G的限制,后续的事务写入失败,导致数据库操作停滞。

排查思路
排查思路一般有下面几个:
1、大事务导致日志无法截断:可能是未提交的大事务阻止了日志的截断。
2、特殊环境:如复制 (Replication)、镜像 (Mirroring)、可用性组 (AG)、变更数据捕获 (CDC) 等场景下,备用端异常会导致主端无法截断日志。
3、未及时备份事务日志:在完整恢复模式下,未及时备份事务日志导致日志文件增长。
4、数据库恢复时间设置:修改过数据库恢复时间,可能导致checkpoint延迟,从而延长日志文件的截断时间。

排查步骤
按照下面思路进行逐一排查
1、确认数据库恢复模式:数据库为简单恢复模式,排除事务日志备份问题(思路3)。
2、检查运行环境:数据库为单机模式,排除复制、镜像、AG等场景(思路2)。
3、检查长时间事务:使用 `DBCC OPENTRAN` 检查,未发现长时间运行的事务,排除大事务问题(思路1)。
4、检查数据库恢复设置:`TARGET_RECOVERY_TIME` 和 `recovery interval` 为默认值,排除恢复时间问题(思路4)。
5、检查阻塞情况:未发现阻塞问题。
6、检查SQL Agent作业:除了完整备份外,未发现其他作业运行。
7、检查写入逻辑:与开发人员沟通得知,该数据库为日常批量数据写入,日志写入量超过400G。

问题原因分析
这里面我们需要从数据库完整备份的原理入手,解剖备份的细节,分析原因,一般来说,数据库完整备份分为两个阶段:
1、第一阶段:记录备份开始时的LSN,生成快照式备份。
2、第二阶段:快照备份结束后,记录最新的LSN,并将这两次LSN之间的事务日志写入备份。
由于数据库较大,备份时间超过12个小时,导致备份操作一直处于第一阶段,无法进入到第二阶段。这期间,日志文件中的事务无法截断,12小时内的事务量超过600GB,导致LDF日志文件被打爆。

优化建议
最后的解决方案是,开启SQL Server 2019的ADR(加速数据库恢复)功能,完整备份时候,日志文件只有少量增长,问题解决。
启用 ADR 的步骤
确保使用的是 SQL Server 2019 或 SQL Server 2022,因为 ADR 是从 SQL Server 2019 开始引入的。

--开启数据库的ADR功能
ALTER DATABASE [YourDatabaseName]
SET ACCELERATED_DATABASE_RECOVERY = ON;
GO --检查 ADR 状态
SELECT name, is_accelerated_database_recovery_on
FROM sys.databases
WHERE name = 'YourDatabaseName'; --关闭 ADR
ALTER DATABASE [YourDatabaseName]
SET ACCELERATED_DATABASE_RECOVERY = OFF;
GO

这里有如下几个优化思路:
1、多文件备份:将默认的单文件备份改为多文件备份,可以提升备份效率,缩短备份时间。(之前介绍过SQL Server的一个不显眼的功能备份文件分割)
2、升级SQL Server版本:升级到SQL Server 2019或SQL Server 2022,启用ADR(加速数据库恢复)功能,通过SLOG实现日志及时截断。
3、业务拆分:尽管不现实,但从业务上进行拆分也可以减少单一数据库的事务量。


总结

在SQL Server 2019中,一个48TB数据库因备份耗时过长,导致日志文件无法截断并达到上限,阻碍事务写入。
本文介绍了多种解决方案包括多文件分割备份、启用数据库ADR功能。
最终启用数据库ADR功能解决了问题。这里要注意的是,一定要尽量使用最新的数据库版本,例如SQL Server 2019或者SQL Server 2022,
保证能使用到最新功能,可以摆脱很多麻烦。

补充:数据库完整备份原理
在完整备份过程中,即使数据库处于简单恢复模式,备份依然会拷贝未提交事务的日志。对于长时间运行的事务,备份会包含足够的日志信息来撤销这些未提交的事务。
因此,即使数据库的MDF文件较小,日志文件(LDF)也可能会导致备份文件非常大。
这与MySQL的Xtrabackup的原理几乎是一样的,备份开始时生成一个开始LSN,结束时生成一个结束LSN,如果有未提交事务,MySQL8.0的undoxx文件会非常大

参考文章
https://learn.microsoft.com/en-us/sql/relational-databases/accelerated-database-recovery-concepts?view=sql-server-ver16
https://www.mssqltips.com/sqlservertip/5971/accelerated-database-recovery-in-sql-server-2019/
https://medium.com/ricos-note/accelerated-database-recovery-a7f0d30b1e0

本文版权归作者所有,未经作者同意不得转载。

单个48TB大小SQL Server数据库备份导致日志文件无法截断的更多相关文章

  1. SQL Server 数据库清空ldf日志文件

    USE [master] ALTER DATABASE [DB_Develop] SET RECOVERY SIMPLE WITH NO_WAIT ALTER DATABASE [DB_Develop ...

  2. sql server数据库备份单个表的结构和数据生成脚本

    1.使用场景:sql server数据库备份单个表的结构和数据,在我们要修改正式系统的数据的一天或者多条某些数据时候,要执行update语句操作,安全稳健考虑,最好先做好所修改的表的结构和数据备份! ...

  3. sql server数据库备份单个表的结构和数据生成脚本【转】

    1.使用场景:sql server数据库备份单个表的结构和数据,在我们要修改正式系统的数据的一天或者多条某些数据时候,要执行update语句操作,安全稳健考虑,最好先做好所修改的表的结构和数据备份! ...

  4. SQL Server数据库 备份A库,然后删除A库,再还原A库,此时数据库一直显示“正在还原”的解决方法

    SQL Server数据库 备份A库,然后删除A库,再还原A库,此时数据库一直显示"正在还原"的解决方法: A库一直显示"正在还原". 在这种状态下,由于未提交 ...

  5. SQL Server数据库备份的镜像

    SQL Server数据库备份的镜像 一个完整备份可以分开镜像 USE master GO BACKUP DATABASE [testdatabase] TO DISK = N'C:\testdata ...

  6. SQL Server数据库备份:通过Windows批处理命令执行

    通过Windows批处理命令执行SQL Server数据库备份 建立mybackup.bat ,输入以下内容直接运行该脚本,即可开始自动备份数据库也可把该脚本加入windows任务计划里执行. --- ...

  7. (图解版)SQL Server数据库备份与还原

        本文介绍了SQL Server数据库备份的两种方式.一种是直接拷贝数据库中的文件mdf 和日志文件ldf,另一种是生成脚本语言. 第一种方式:     选中需要备份的数据库,将数据库从运行的数 ...

  8. SQL Server数据库备份(本机)

    基础的SQL Server数据库备份存储过程 /**************************************************************************** ...

  9. SQL server数据库备份还原问题备忘(亲测有效)

    问题一:SQL server数据库备份还原方法 http://www.cnblogs.com/zgqys1980/archive/2012/07/04/2576382.html 问题二:无法执行 BA ...

  10. sql server 数据库备份历史记录

    sql server 数据库备份历史记录 SELECT ),SERVERPROPERTY('Servername'))AS Server, bs.database_name, bs.backup_st ...

随机推荐

  1. yb 课堂实战之视频列表接口开发+API权限路径规划 《三》

    开发JsonData工具类 package net.ybclass.online_ybclass.utils; public class JsonData { /** * 状态码,0表示成功过,1表示 ...

  2. P1387

    #include<iostream> #include<utility> using namespace std; typedef long long ll; #define ...

  3. 将虚拟机跑在ceph之中

    目录 openStack对接ceph 1. cinder对接ceph 1.1 ceph创建存储池 1.2 ceph授权 1.3 下发ceph文件 1.4 修改globals文件 1.5 部署cinde ...

  4. 为什么学编程都从helloworld开始?

    你好世界 回忆上次内容 上次 了解了 游乐场规则 REPL       添加图片注释,不超过 140 字(可选)   print函数 可以输出 字符串"h"     添加图片注释, ...

  5. ElementUI 基于vue+sortable.js实现表格行拖拽

    基于vue+sortable.js实现表格行拖拽 By:授客 QQ:1033553122 实践环境 sortablejs@1.13.0 vue@2.6.11 element-ui@2.13.2 安装s ...

  6. SpringSecurity:hasAuthority与自定义权限校验

    springsecurity中有两种权限控制方法 1.基于注解 @PreAuthorize("hasAuthority('syst:add')") 他的作用是在controller ...

  7. 【SpringCloud】Re03 Feign

    Feign是一个声明式的HttpClient?更简洁的实现Http请求发送 安装Feign组件: 配置Feign的依赖坐标: <?xml version="1.0" enco ...

  8. 【Layui】07 徽章 Badge

    文档地址: https://www.layui.com/demo/badge.html 圆点徽章: <span class="layui-badge-dot">< ...

  9. 【TypeScript】02 面向对象

    [联合类型] 联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值. 注意:只能赋值指定的类型,如果赋值其它类型就会报错. var val:strin ...

  10. 《Python数据可视化之matplotlib实践》 源码 第四篇 扩展 第十三章

    图  13.10 import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np mpl.rcParams[&q ...