如何使用 SQL Server Express 安排每日备份?

65

我正在运行一个小型 Web 应用程序,使用 SQL Server Express(2005)作为后端。我可以通过 SQL 脚本创建备份,但是,我想将其定期安排在每天运行。作为额外选项(应该有),我想只保留最后 X 个备份(出于节省空间的原因)。请指点?

[编辑] 在 SQL Server Express 中不可用 SQL Server Agent...


你可以使用 SQLBackupAndFTP https://sqlbackupandftp.com/ 轻松完成此操作。 - Alexandr Omelchenko
你可以查看这个链接,https://dev59.com/qXNA5IYBdhLWcg3wpfmu#29893738。这是一个批处理文件,用于创建 SQL Server Express 数据库备份并保留最近的 10 个备份(自动删除旧备份)。应该使用 Windows 计划程序定期自动执行。 - Supawat Pusavanno
6个回答

55

Eduardo Molteni提供了一个很好的答案:

使用Windows计划任务:

在批处理文件中

"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE" -S 
(local)\SQLExpress -i D:\dbbackups\SQLExpressBackups.sql

在 SQLExpressBackups.sql 文件中

BACKUP DATABASE MyDataBase1 TO  DISK = N'D:\DBbackups\MyDataBase1.bak' 
WITH NOFORMAT, INIT,  NAME = N'MyDataBase1 Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10

BACKUP DATABASE MyDataBase2 TO  DISK = N'D:\DBbackups\MyDataBase2.bak' 
WITH NOFORMAT, INIT,  NAME = N'MyDataBase2 Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10

GO

8
有没有办法在创建备份文件时附加时间戳,以避免写入现有文件? - Zo Has
太好了!另外,我必须遵循这个链接来获取正确的权限以创建备份文件:https://dev59.com/4m865IYBdhLWcg3wKLJP - audub
1
如果你想备份更多天数,可以将INIT参数替换为NOINIT。INIT表示备份文件总是从头开始重写。你应该使用带有时间戳的方式,就像你说的那样,或者使用NOINIT参数将备份附加到现有文件中。最好使用类似RETAINDAYS参数的东西,否则备份文件会无限增长。在时间戳的情况下,你需要自己解决它。请参阅http://technet.microsoft.com/en-us/library/ms186865.aspx获取更多信息。 - Michal Bernhard
请记得在SQL安装文件夹中设置备份位置。我曾经出现过这样的错误:"SQL Server 操作系统错误 5: 5 (拒绝访问。)",因为我将备份设定到了 SQL server 安装文件夹之外(SQL Server 数据库引擎服务账户必须具有读/写新文件夹的权限)。或者,可以参考这个解决方案 - full_prog_full
4
对于 SQL Server 2014 Express,SqlCmd.exe 的位置现在位于:“C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\SQLCMD.EXE”。 - André Haupt

54

在 SQL Server Express 中无法使用 SQL Server agent。我之前的做法是创建一个 SQL 脚本,然后将其作为定时任务每天运行,您可以创建多个定时任务以适应备份计划/保留期。我在定时任务中使用的命令是:

"C:\Program Files\Microsoft SQL Server\90\Tools\Binn\SQLCMD.EXE" -i"c:\path\to\sqlbackupScript.sql"


可爱、漂亮、流畅。干杯! - Nick Haslam
1
只有在您拥有访问服务器的那种权限时才能运行。 - cregox
3
Microsoft提供了一个很好的脚本和详细的指导来完成这个任务。它主要缺少清理旧备份文件的步骤。http://support.microsoft.com/kb/2019698 - pseudocoder

7

使用此脚本动态备份服务器上的所有数据库。然后根据文章创建批处理文件。创建两个批处理文件非常有用,一个用于全量备份,另一个用于差异备份。然后在任务计划程序中创建两个任务,一个用于全量备份,另一个用于差异备份。

-- // Copyright © Microsoft Corporation.  All Rights Reserved.
-- // This code released under the terms of the
-- // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
USE [master] 
GO 
/****** Object:  StoredProcedure [dbo].[sp_BackupDatabases] ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

-- ============================================= 
-- Author: Microsoft 
-- Create date: 2010-02-06
-- Description: Backup Databases for SQLExpress
-- Parameter1: databaseName 
-- Parameter2: backupType F=full, D=differential, L=log
-- Parameter3: backup file location
-- =============================================

CREATE PROCEDURE [dbo].[sp_BackupDatabases]  
            @databaseName sysname = null,
            @backupType CHAR(1),
            @backupLocation nvarchar(200) 
AS 

       SET NOCOUNT ON; 

            DECLARE @DBs TABLE
            (
                  ID int IDENTITY PRIMARY KEY,
                  DBNAME nvarchar(500)
            )

             -- Pick out only databases which are online in case ALL databases are chosen to be backed up
             -- If specific database is chosen to be backed up only pick that out from @DBs
            INSERT INTO @DBs (DBNAME)
            SELECT Name FROM master.sys.databases
            where state=0
            AND name=@DatabaseName
            OR @DatabaseName IS NULL
            ORDER BY Name

            -- Filter out databases which do not need to backed up
            IF @backupType='F'
                  BEGIN
                  DELETE @DBs where DBNAME IN ('tempdb','Northwind','pubs','AdventureWorks')
                  END
            ELSE IF @backupType='D'
                  BEGIN
                  DELETE @DBs where DBNAME IN ('tempdb','Northwind','pubs','master','AdventureWorks')
                  END
            ELSE IF @backupType='L'
                  BEGIN
                  DELETE @DBs where DBNAME IN ('tempdb','Northwind','pubs','master','AdventureWorks')
                  END
            ELSE
                  BEGIN
                  RETURN
                  END

            -- Declare variables
            DECLARE @BackupName varchar(100)
            DECLARE @BackupFile varchar(100)
            DECLARE @DBNAME varchar(300)
            DECLARE @sqlCommand NVARCHAR(1000) 
        DECLARE @dateTime NVARCHAR(20)
            DECLARE @Loop int                  

            -- Loop through the databases one by one
            SELECT @Loop = min(ID) FROM @DBs

      WHILE @Loop IS NOT NULL
      BEGIN

-- Database Names have to be in [dbname] format since some have - or _ in their name
      SET @DBNAME = '['+(SELECT DBNAME FROM @DBs WHERE ID = @Loop)+']'

-- Set the current date and time n yyyyhhmmss format
      SET @dateTime = REPLACE(CONVERT(VARCHAR, GETDATE(),101),'/','') + '_' +  REPLACE(CONVERT(VARCHAR, GETDATE(),108),':','')  

-- Create backup filename in path\filename.extension format for full,diff and log backups
      IF @backupType = 'F'
            SET @BackupFile = @backupLocation+REPLACE(REPLACE(@DBNAME, '[',''),']','')+ '_FULL_'+ @dateTime+ '.BAK'
      ELSE IF @backupType = 'D'
            SET @BackupFile = @backupLocation+REPLACE(REPLACE(@DBNAME, '[',''),']','')+ '_DIFF_'+ @dateTime+ '.BAK'
      ELSE IF @backupType = 'L'
            SET @BackupFile = @backupLocation+REPLACE(REPLACE(@DBNAME, '[',''),']','')+ '_LOG_'+ @dateTime+ '.TRN'

-- Provide the backup a name for storing in the media
      IF @backupType = 'F'
            SET @BackupName = REPLACE(REPLACE(@DBNAME,'[',''),']','') +' full backup for '+ @dateTime
      IF @backupType = 'D'
            SET @BackupName = REPLACE(REPLACE(@DBNAME,'[',''),']','') +' differential backup for '+ @dateTime
      IF @backupType = 'L'
            SET @BackupName = REPLACE(REPLACE(@DBNAME,'[',''),']','') +' log backup for '+ @dateTime

-- Generate the dynamic SQL command to be executed

       IF @backupType = 'F' 
                  BEGIN
               SET @sqlCommand = 'BACKUP DATABASE ' +@DBNAME+  ' TO DISK = '''+@BackupFile+ ''' WITH INIT, NAME= ''' +@BackupName+''', NOSKIP, NOFORMAT'
                  END
       IF @backupType = 'D'
                  BEGIN
               SET @sqlCommand = 'BACKUP DATABASE ' +@DBNAME+  ' TO DISK = '''+@BackupFile+ ''' WITH DIFFERENTIAL, INIT, NAME= ''' +@BackupName+''', NOSKIP, NOFORMAT'        
                  END
       IF @backupType = 'L' 
                  BEGIN
               SET @sqlCommand = 'BACKUP LOG ' +@DBNAME+  ' TO DISK = '''+@BackupFile+ ''' WITH INIT, NAME= ''' +@BackupName+''', NOSKIP, NOFORMAT'        
                  END

-- Execute the generated SQL command
       EXEC(@sqlCommand)

-- Goto the next database
SELECT @Loop = min(ID) FROM @DBs where ID>@Loop

END

批处理文件可以看起来像这样:

sqlcmd -S localhost\myDB -Q "EXEC sp_BackupDatabases @backupLocation='c:\Dropbox\backup\DB\', @backupType='F'"  >> c:\Dropbox\backup\DB\full.log 2>&1

并且

sqlcmd -S localhost\myDB -Q "EXEC sp_BackupDatabases @backupLocation='c:\Dropbox\backup\DB\', @backupType='D'"  >> c:\Dropbox\backup\DB\diff.log 2>&1

这种方法的优点是,如果添加或删除数据库,甚至不需要在脚本中列出数据库,也不需要更改任何内容。JohnB的答案对于只有一个数据库的服务器更好/更简单,而这种方法更适合多个数据库的服务器。

太棒了!感谢您的帮助!点赞! - Piotr Kula

4

MSSQLTips网站上有一些非常有用的文章,最相关的是 "自动化SQL Server 2005 Express备份和删除旧备份文件"

基本方法是使用Windows任务计划程序设置两个任务。一个任务运行TSQL脚本,为所有MSSQL数据库(除了TEMPDB)生成单独的备份文件,并将数据库名称和日期/时间戳作为文件名保存到指定目录中。第二个任务运行VBScript脚本,遍历该目录并删除所有超过3天的.BAK扩展名文件。

这两个脚本需要根据您的环境进行轻微编辑(路径,保留这些数据库转储的时间),但非常接近插入即可运行的状态。

请注意,如果您在这些脚本或目录权限方面不认真对待,可能会存在安全问题,因为它们是文本文件,需要以某种级别的特权运行。请勿疏忽。


1
值得注意的是 - 如果您正在使用DFS自动推送备份文件到其他系统,请记住,.bak通常是一个被排除的扩展名 - 要么更改它,要么更改过滤器。 - fencepost

3
我们使用以下组合:
  1. Cobian Backup 进行计划和维护

  2. ExpressMaint 进行备份

这两个工具都是免费的。流程是将ExpressMaint脚本作为Cobian“备份前”事件来进行备份。我通常会让它覆盖之前的备份文件。然后,Cobian将从中提取zip / 7zip并将其存档到备份文件夹中。在Cobian中,您可以指定要保留的完整副本数量,进行多个备份周期等。
ExpressMaint命令语法示例:
expressmaint -S HOST\SQLEXPRESS -D ALL_USER -T DB -R logpath -RU WEEKS -RV 1 -B backuppath -BU HOURS -BV 3 

Cobian已经死了 ;( - Piotr Kula
1
@PiotrKula Cobian Backup仍然是免费软件,可从此网站https://www.cobiansoft.com/下载。 - user797717

1
你可以在服务器对象中创建一个备份设备,比如说

BDTEST

然后创建一个包含以下命令的批处理文件

sqlcmd -S 192.168.1.25 -E -Q "BACKUP DATABASE dbtest TO BDTEST"

假设我们用名称来说

backup.bat

然后你可以调用。

backup.bat

根据您的方便,在任务计划程序中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接