在服务器的所有实例上备份所有数据库的 TSQL 解决方案?

Luk*_*ord 1 sql-server backup instance t-sql smo

我很确定我想要的当前实现是不可能的,sys.databases 目录视图在服务级别范围内可以了解其他 SQL Server 实例 (lol)。但我认为很多事情用电脑是不可能的,所以希望我能用不同的方式解决我的问题。

我已经创建了一个 PowerShell 解决方案,该解决方案使用 SMO 来备份所有实例上的所有数据库,但是由于安全原因,我无法在不将运行代理作业的代理帐户设为本地管理员的情况下使该解决方案工作服务器。

作为替代方案,我编写了一个 T-SQL 脚本,该脚本将作为代理作业运行,并每 15 分钟对 SQL Server 实例中的所有数据库进行完整、差异或事务备份。

    DECLARE @sql nvarchar(MAX) = N'';

--Check time for full backup
IF (DATENAME(weekday,getdate()) = 'Sunday' AND convert(time,getdate()) > '00:00' and convert(time,getdate()) < '00:15')
    BEGIN
        SELECT @sql += 'BACKUP DATABASE ' + QUOTENAME(name) 
                    + ' TO DISK = N''C:\backups\' + @@ServiceName  + '_' + name + '__' 
                    + cast(year(getdate()) as nvarchar(4)) + '_' + cast(month(getdate()) as nvarchar(2)) + '_' + cast(day(getdate()) as nvarchar(2)) + '__'
                    + cast(datepart(hour,getdate()) as nvarchar(2)) + '_' + cast(datepart(minute,getdate()) as nvarchar(2)) + '_' + cast(datepart(second,getdate()) as nvarchar(3)) +   '.bak'''
                    + ' WITH COMPRESSION
'
        FROM sys.databases
        WHERE name <> 'TempDB';
    END
--Check time for differential backup
ELSE IF (convert(time,getdate()) > '00:00' and convert(time,getdate()) < '00:15')
    BEGIN
        SELECT @sql += 'BACKUP DATABASE ' + QUOTENAME(name) 
                    + ' TO DISK = N''C:\backups\' + @@ServiceName  + '_' + name + '__' 
                    + cast(year(getdate()) as nvarchar(4)) + '_' + cast(month(getdate()) as nvarchar(2)) + '_' + cast(day(getdate()) as nvarchar(2)) + '__'
                    + cast(datepart(hour,getdate()) as nvarchar(2)) + '_' + cast(datepart(minute,getdate()) as nvarchar(2)) + '_' + cast(datepart(second,getdate()) as nvarchar(3)) +   '.diff'''
                    + ' WITH COMPRESSION, Differential
'
        FROM sys.databases
        WHERE name <> 'TempDB' and name <> 'Master';
    END
--Take transaction log backup
ELSE 
    BEGIN
        SELECT @sql += 'BACKUP LOG ' + QUOTENAME(name) 
                    + ' TO DISK = N''C:\backups\' + @@ServiceName  + '_' + name + '__' 
                    + cast(year(getdate()) as nvarchar(4)) + '_' + cast(month(getdate()) as nvarchar(2)) + '_' + cast(day(getdate()) as nvarchar(2)) + '__'
                    + cast(datepart(hour,getdate()) as nvarchar(2)) + '_' + cast(datepart(minute,getdate()) as nvarchar(2)) + '_' + cast(datepart(second,getdate()) as nvarchar(3)) +   '.trn'''
                    + ' WITH COMPRESSION
'
        FROM sys.databases
        WHERE name <> 'TempDB' and name <> 'Master';
    END
print @sql;
exec sp_Executesql @sql;
Run Code Online (Sandbox Code Playgroud)

这个脚本工作正常,但是它只备份一个实例上的所有数据库。目标是备份所有实例上的所有数据库。更好的解决方案是备份所有实例和所有服务器上的所有数据库。从我目前的知识来看,似乎有三种解决方案,(希望更多基于答案)

  1. 在每个实例的代理作业中使用此脚本。这会起作用,但似乎是一个丑陋的解决方案。
  2. 弄清楚如何为 Agent 代理授予成功运行实例感知 PowerShell 脚本的最低权限
  3. 考虑创建一个主服务器。我不熟悉这个选项,但我知道主服务器知道其他服务器,我可能能够获得所有服务器上所有数据库的列表。

Ste*_*ken 5

我已经多次设置选项 3,主服务器,但从未用于安排备份。我能够为性能数据收集安排作业,通过SQLCMD推送管理更改/脚本更新,并在多个实例上针对多个版本的 SQL Server 运行测试,以测试在 SP/CU 应用程序之后所做的任何意外更改(除其他外) )。

但问题是:您是否有理由希望从一台服务器备份所有实例上的所有数据库?将所有备份鸡蛋放在一个篮子里意味着只要该主服务器(或至少 SQL Server 代理)处于脱机状态,就不会完成任何备份。在每台服务器上都有备份作业是有充分理由的标准(无论它们是如何管理的)。

我强烈建议使用Ola Hallengrens 维护解决方案(整个维护包值得使用),而不是编写自己的备份语句。它只是有效,而且效果非常好。它为您提供了您从未想过但将来会需要的选项。

使用该脚本,您可以遍历实例列表,并对每个服务器执行 MaintenanceSolution.sql(您从 Olas 站点下载)。我已经使用一个批处理文件完成此操作,该批处理文件使用SQLCMD与每个服务器的可信连接,并将结果输出到每个服务器的 CSV(假设您对每个实例都有权限)。如果您在 SSMS 中使用注册服务器视图,您还可以一次针对给定组中的所有服务器执行该脚本。

除此之外,您正在查看诸如redgate SQL Backup Pro(我与他们没有任何隶属关系)、Idera SQL Safe Backup(同样,没有隶属关系)之类的东西来做您想做的事情,但是这些产品确实要花钱各自的试用期。

与从一个实例为所有服务器上的所有数据库安排备份相比,这两种解决方案中的任何一种都将为您提供更大的安全性。