AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 255969
Accepted
James Jenkins
James Jenkins
Asked: 2019-12-20 07:31:47 +0800 CST2019-12-20 07:31:47 +0800 CST 2019-12-20 07:31:47 +0800 CST

伪简单的 SQL Server 恢复是真的吗?

  • 772

“伪简单 SQL Server 恢复”是术语和场景,我刚刚在(现已删除)新问题SQL Server Truncates Transaction Logs with Copy Only Backups的评论中了解到

我去了Rajendra Gupta 于 2019 年 10 月 7 日发表的 Pseudo-Simple SQL Server Recovery Model帖子,并在那里使用了一些代码,我自己的一些代码做了一些测试。

创建数据库(Rajendra 的代码)

CREATE DATABASE RecoveryModel;

并验证它是否完整(Rajendra 的代码)

SELECT name, 
    recovery_model_desc
FROM sys.databases
WHERE name = 'RecoveryModel';

做一些工作(Rajendra 的代码,稍作修改)

Use RecoveryModel
CREATE TABLE test(id INT);
GO 
INSERT INTO test
VALUES(1);
GO 5000

查看使用了多少日志空间(我的代码)

select file_id
, type_desc
, name
, substring([physical_name],1,3) AS [Drive]
, physical_name
, state_desc
, size / 128 as 'AllocatedSizeMB'
, FILEPROPERTY([name],'SpaceUsed') /128 AS 'SpaceUsedMB'  --Addapted from https://sqlperformance.com/2014/12/io-subsystem/proactive-sql-server-health-checks-1
, (1- (FILEPROPERTY([name],'SpaceUsed') / CAST (size AS MONEY))) *100 AS 'PercentFree'
, growth / 128 as 'GrowthSettingMB'

 from sys.database_files
 order by type_desc Desc, name

我们发现有日志正在填充。再次运行工作并检查大小,日志增长,不足为奇。

尝试运行 t-log(我的代码)

BACKUP LOG [RecoveryModel] TO  
DISK = N'E:\SQLBackups\RecoveryModel.trn' WITH NOFORMAT, NOINIT, SKIP, NOREWIND, NOUNLOAD 
GO

它失败并显示消息:

消息 4214,第 16 层,状态 1,第 8 行

无法执行 BACKUP LOG,因为没有当前数据库备份。

消息 3013,第 16 层,状态 1,第 8 行

BACKUP LOG 异常终止。

如果您尝试在“简单恢复”中备份数据库,那一点都不简单。你收到消息

消息 4208,第 16 层,状态 1,第 19 行

当恢复模式为 SIMPLE 时,不允许使用 BACKUP LOG 语句。使用 BACKUP DATABASE 或使用 ALTER DATABASE 更改恢复模式。

运行仅副本备份(我的代码)

BACKUP DATABASE [RecoveryModel] TO  
DISK = N'E:\SQLBackups\RecoveryModel.bak' WITH NOFORMAT, INIT, COPY_ONLY,  
NAME = N'RecoveryModel-Full Database Backup', SKIP, NOREWIND, NOUNLOAD
GO

它运行良好,检查日志空间并没有缩小。再运行几次工作负载,日志空间继续增长。运行 t-log 备份,它继续失败。

运行差异备份(我的代码)

BACKUP DATABASE [RecoveryModel] TO  
DISK = N'E:\SQLBackups\RecoveryModel.dif' WITH  DIFFERENTIAL , NOFORMAT, NOINIT,  
NAME = N'RecoveryModel-Diff Database Backup', SKIP, NOREWIND, NOUNLOAD
GO

它就像 t_log 一样失败

消息 3035,级别 16,状态 1,第 13 行无法为数据库“RecoveryModel”执行差异备份,因为当前数据库备份不存在。通过重新发出 BACKUP DATABASE 执行完整的数据库备份,省略 WITH DIFFERENTIAL 选项。

那么关于这个的“伪简单”是什么?日志增长,t-log 和差异备份失败。您有一个处于完全恢复状态的数据库,没有完全备份。

编辑它看起来像我的构建中的服务器特定的东西导致结果与其他人看到的不同。我接受了乔希的回答。

sql-server backup
  • 3 3 个回答
  • 391 Views

3 个回答

  • Voted
  1. Best Answer
    Josh Darnell
    2019-12-20T08:01:42+08:002019-12-20T08:01:42+08:00

    请参阅数据库恢复模型专家 Paul Randal 的这篇文章:新脚本:该数据库真的处于完全恢复模式吗?

    特别是这句话证实了“伪简单”恢复模型的行为:

    ...当您将数据库切换到完全恢复模式时,它实际上就像处于简单恢复模式一样,直到建立日志备份链(这通常称为“伪简单”)。

    Kimberly Tripp 在这里详细阐述了该主题:数据库维护最佳实践第三部分 – 事务日志维护

    这意味着一旦 SQL Server 知道它不再需要它们,它就会自动从事务日志中清除非活动记录。它不再需要将它们存储在日志中,因为没有人在使用日志

    我不完全同意您关于在完整备份之前在完整恢复模型中事务日志备份失败的说法“这一点都不简单”。这就像 SIMPLE 模型(不允许日志备份)。错误消息是不同的,因为它试图告诉最终用户如何解决问题。

    我在 SQL Server 2017 上尝试了您的测试,并且运行仅复制备份始终触发内部CHECKPOINT并清除日志(PercentFree日志文件增加)。

    在初始运行时,PercentFree_log 文件中的65.04.
    我运行了仅复制备份,然后PercentFree跳转到88.68.

    我通过以下扩展事件会话确认CHECKPOINT此时也运行了 a。

    CREATE EVENT SESSION [checkpointage] ON SERVER 
    ADD EVENT sqlserver.checkpoint_begin(
        ACTION(sqlserver.database_id)),
    ADD EVENT sqlserver.checkpoint_end(
        ACTION(sqlserver.database_id))
    ADD TARGET package0.event_file(SET filename=N'checkpointage')
    WITH (STARTUP_STATE=OFF)
    GO
    
    • 5
  2. Randolph West
    2019-12-20T16:38:10+08:002019-12-20T16:38:10+08:00

    伪简单意味着完全恢复模型中的数据库在进行第一次完全备份之前将表现得好像它处于简单恢复模型中一样(记录备份的最后一个日志序列号)。

    换句话说,处于完全恢复模式的数据库需要有效的备份链,而有效的备份链需要完全备份才能启动。然后,您可以根据自己的需要并行执行日志和差异备份,每个备份都基于此初始完整备份。

    正如您在运行的脚本中看到的那样,在您运行完整(仅复制)备份之前没有建立备份链。一旦运行,您就启动了一个备份链,但是因为您进行了仅复制备份,所以您混淆了事情。

    差异备份是减少需要还原到特定时间点的日志备份数量的捷径。它们依赖于不是 的完整备份, COPY ONLY因为仅复制备份不会重置用于跟踪自上次完整备份以来修改了哪些扩展区的差异位图。

    如果您进行了标准完整备份(没有COPY ONLY),您的差异将成功,并且数据库将不再处于伪简单状态。更令人困惑的是,如果没有完整(非仅复制)备份来启动链,在简单恢复模型中的数据库上差异备份也会失败。

    • 2
  3. James Jenkins
    2019-12-21T08:17:51+08:002019-12-21T08:17:51+08:00

    我(关于问题的 OP)不知道为什么“伪简单 SQL Server 恢复”按照多个帖子中的定义工作,但我没有通过这些测试在我的系统上看到它。

    在研究阶段,我将数据库放入SIMPLE并重新创建了测试,使用的日志文件大小与它相同FULL,这表明控制事务持久性但进一步测试排除了这一点。

    经过更多的研究和测试,我想通了!(感谢帮助我解决问题的同事。)

    • 我们使用 50MB 作为“模型”的起始大小,这意味着 RecoveryModel 的起始大小相同。(默认 SQL 2017 为 8MB)
    • 这创建了 4 个 VLF,每个大约 12.5MB
    • 我在上面的测试中使用的工作负载,每次运行都会在日志中创建大约 2MB 的数据。
    • 在进行COPY ONLY备份之前,我运行了 3 到 5 次测试工作负载(6 到 10MB 的日志)。
    • VLF 已用空间正在增长,但由于它从未填满第一个 VLF,它保持在状态 2,并且没有任何内容被释放。
    • 当测试似乎给出了意想不到的结果时,我删除了数据库并开始了一个新的测试。
    • 在后续测试中,我运行工作负载以创建约 15MB 的日志,然后运行COPY ONLY并使用空间下降到 2MB,第一个 VLF 返回状态 0,第二个 VLF 保持最后 2MB
    • 除了上面的代码之外,还可以使用下面的代码自己修改和测试来验证这一点。

    .

    USE [RecoveryModel]
    GO
    DBCC LOGINFO
    

    谈论 VLF 的相关信息:VLF太多 - 我如何截断它们?

    • 2

相关问题

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • Oracle 中的数据库备份 - 导出数据库还是使用其他工具?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve