【问题标题】:MS-SQL Database Restore - Only one FilegroupMS-SQL 数据库还原 - 只有一个文件组
【发布时间】:2022-01-18 14:53:35
【问题描述】:

我目前正在为 MS-SQL 备份/恢复而苦苦挣扎。

情况: 我有一个正在运行的 Windows 服务,它会创建频繁(每 15 分钟)自动备份并发送到网络存储。

问题:数据库包含许多临时表,我不希望备份历史数据。

因此,我已将历史记录表移至第二个文件组。

我需要的是一个仅包含数据库架构和主文件组数据的备份。

从该备份中,我需要再次恢复一个功能齐全的数据库。

此外,数据库处于简单恢复模式,正如我已经提到的,我需要通过 sql 命令执行此操作,并且不能使用 SSMS 编写架构/数据脚本,因为我正在以编程方式从 Windows 服务执行它。

感谢您的任何想法。

【问题讨论】:

  • 我必须承认,每 15 分钟运行一次完整备份似乎有点过头了。似乎您最好将数据库置于完全恢复模式并每 15 分钟使用一次事务日志备份。
  • 事实上,我们每天创建一个完整备份,每 15 分钟创建一次差异备份。日志备份存在问题,因为我们处于简单恢复模式。
  • 当然我们已经检查过了,但是我们不能使用部分备份,因为在简单恢复模式下,排除的文件组必须是只读的。由于它们包含时态表的历史数据,我们不能将其设为只读。
  • @DavidBrowne-Microsoft:所以没有办法从备份中排除某些表数据。?! :-/

标签: sql-server database-backups


【解决方案1】:

我需要通过 sql 命令执行,不能使用 SSMS 编写模式/数据的脚本,就像我从 Windows 服务中执行的那样 以编程方式。

您可以使用SMO API 以编程方式编写架构/数据脚本,这是 SSMS 使用的。

【讨论】:

  • 或者单独运行脚本中的每个批次,例如使用 .Net SqlCommand。
【解决方案2】:
  1. 这是个坏主意。如果您需要经常备份数据,则应使用完整恢复和日志备份。

  2. 在 SIMPLE 恢复中,所有读写文件组都必须包含在备份中。

  3. 在完全恢复中,您提出的建议在技术上是可行的(最好的一种)。您可以对 PRIMARY 文件组进行备份,通过恢复进行还原,这将使所有辅助文件组失效。然后在您的临时表上关闭 system_versioning 以使其可更新。

这是一个示例:

use master
drop database piecemealtest
go
/****** Object:  Database [piecemealtest]    Script Date: 12/15/2021 7:16:57 AM ******/
CREATE DATABASE [piecemealtest]
 ON  PRIMARY 
( NAME = N'piecemealtest', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\piecemealtest.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB ), 
 FILEGROUP [fg2] 
( NAME = N'fg2', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\fg2.ndf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'piecemealtest_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\piecemealtest_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB )
 
GO

ALTER DATABASE [piecemealtest] SET RECOVERY full
go
backup database piecemealtest to disk='nul'
GO

go
use piecemealtest



go
CREATE TABLE DepartmentHistory
(
    DeptID INT NOT NULL
  , DeptName VARCHAR(50) NOT NULL
  , ManagerID INT NULL
  , ParentDeptID INT NULL
  , SysStartTime DATETIME2 NOT NULL
  , SysEndTime DATETIME2 NOT NULL
) on fg2;
GO

CREATE CLUSTERED COLUMNSTORE INDEX IX_DepartmentHistory
    ON DepartmentHistory;
CREATE NONCLUSTERED INDEX IX_DepartmentHistory_ID_PERIOD_COLUMNS
    ON DepartmentHistory (SysEndTime, SysStartTime, DeptID);
GO

CREATE TABLE Department
(
    DeptID int NOT NULL PRIMARY KEY CLUSTERED
  , DeptName VARCHAR(50) NOT NULL
  , ManagerID INT NULL
  , ParentDeptID INT NULL
  , SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL
  , SysEndTime DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL
  , PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.DepartmentHistory));



go

insert into Department(DeptID,DeptName,ManagerId,ParentDeptID)
select object_id, 'dept' + name, 0,0
from sys.objects 

update Department set managerid = 4
update Department set managerid = 5

delete from Department where deptid %10 = 3

backup database piecemealtest filegroup='primary' to disk = 'piecemeal.primary.bak'

use master 
drop database piecemealtest

restore database piecemealtest filegroup='PRIMARY' from disk= 'piecemeal.primary.bak' with partial, recovery
--Msg 3127, Level 16, State 1, Line 71
--The file 'fg2' of restored database 'piecemealtest' is being left in the defunct state because the database is using the simple recovery model and the file is marked for read-write access. Therefore, only read-only files can be recovered by piecemeal restore.
--RESTORE DATABASE ... FILE=<name> successfully processed 393 pages in 0.010 seconds (306.396 MB/sec).

use piecemealtest 

select * from Department

update Department set managerid = 8 -- fails
--Msg 8653, Level 16, State 1, Line 78
--The query processor is unable to produce a plan for the table or view 'DepartmentHistory' because the table resides in a filegroup that is not online.
go
alter table Department set (system_versioning=off)
go
update Department set managerid = 8 -- works

【讨论】:

  • 感谢您提供示例代码。我们会在先考虑日志备份后尝试这种方式。
【解决方案3】:

我会考虑为目标数据库中的replicate 数据和对象创建另一个数据库,然后为这个新数据库执行上述备份(每 15 分钟一次)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多