MS-SQL 数据库还原 - 只有一个文件组
MS-SQL Database Restore - Only one Filegroup
我目前正在为 MS-SQLBackup/Restore.
苦苦挣扎
情况:
我有一个 windows-服务 运行 可以创建频繁(每 15 分钟)自动备份并发送到网络存储。
问题:数据库包含很多临时表,我没有兴趣备份历史数据。
因此我已将历史表移动到第二个文件组。
我需要的是只包含数据库架构和主文件组数据的备份。
我需要从那个备份中再次恢复一个功能齐全的数据库。
此外,数据库处于简单恢复模式,正如我已经提到的,我需要通过 sql 命令来完成它,并且不能使用 SSMS 编写模式/数据脚本,因为我正在从 windows-以编程方式服务。
谢谢你的想法。
I need to do it by sql commands and cannot use the SSMS to
script the schema / data as I'm doing it from a windows-service
programatically.
您可以使用 SMO API 以编程方式编写 schema/data 脚本,这是 SSMS 使用的。
我会考虑为目标数据库中的 replicate 数据和对象创建另一个数据库,然后为这个新数据库执行上述备份(每 15 分钟一次)。
这是个坏主意。如果您需要经常备份数据,您应该使用完全恢复和日志备份。
在简单恢复中,所有读写文件组都必须包含在备份中。
在完全恢复中,您提出的建议在技术上是可行的(最好的可能)。您可以备份 PRIMARY 文件组,使用 recovery 恢复它,这将使所有辅助文件组失效。然后在临时表上关闭 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
我目前正在为 MS-SQLBackup/Restore.
苦苦挣扎情况: 我有一个 windows-服务 运行 可以创建频繁(每 15 分钟)自动备份并发送到网络存储。
问题:数据库包含很多临时表,我没有兴趣备份历史数据。
因此我已将历史表移动到第二个文件组。
我需要的是只包含数据库架构和主文件组数据的备份。
我需要从那个备份中再次恢复一个功能齐全的数据库。
此外,数据库处于简单恢复模式,正如我已经提到的,我需要通过 sql 命令来完成它,并且不能使用 SSMS 编写模式/数据脚本,因为我正在从 windows-以编程方式服务。
谢谢你的想法。
I need to do it by sql commands and cannot use the SSMS to script the schema / data as I'm doing it from a windows-service programatically.
您可以使用 SMO API 以编程方式编写 schema/data 脚本,这是 SSMS 使用的。
我会考虑为目标数据库中的 replicate 数据和对象创建另一个数据库,然后为这个新数据库执行上述备份(每 15 分钟一次)。
这是个坏主意。如果您需要经常备份数据,您应该使用完全恢复和日志备份。
在简单恢复中,所有读写文件组都必须包含在备份中。
在完全恢复中,您提出的建议在技术上是可行的(最好的可能)。您可以备份 PRIMARY 文件组,使用 recovery 恢复它,这将使所有辅助文件组失效。然后在临时表上关闭 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