一直以来,公司某游戏平台使用 SQL Server 作为数据存储解决方案。为了数据的安全,每天凌晨在本机上做一次备份。但随着时间的推移,原先并没有设计到备份需求的硬件配置,尤其是外部存储这块,已经快不能满足 SQL Server 备份文件日益丰满的身姿。(这句话好像谁说过?)

为了彻底解决这个病痛,我打算为其实施远程异地备份。但查阅无数资料,均找不到较好的解决之道。大部分方案都是在备份目的地建共享目录,新增一个用户并赋权。然后在数据库端写个存储过程,添加数据库维护计划并使用这个存储过程。这样做有太多弊端:对于操作系统来说,很不安全;对于硬件架构设计来说,必须满足同一内网的条件。于是乎,放弃这样的方案。

经过几天的折腾测试,最后我采用了这样的方案。虽然比较老土,但至少 DIY 出来了,也暂时性满足了需求,缓解了阶级矛盾:

1、打开 SQL Server 企业管理器,找到数据库维护计划。

2、添加一个数据库维护计划,为其设置一个优美而和谐的名字,并选择需要操作的数据库对象。

3、设置在本机磁盘上的备份选项。由于备份需要每日转移,所以我的设置是每天做一个轮巡。

4、然后在数据库服务器上架设一个 FTP 服务端,并添加一个指向数据库每日备份目录的帐户。

5、安装 WinRAR,然后编写一个批处理,通过 WinRAR 命令行将每日备份目录打包待传。有关 WinRAR 的命令行参数可以参考此文,我的批处理如下:

"C:\Program Files\WinRAR\WinRAR.exe" a -as -k -r -m5 -EP1 "D:\Task\bak_files\tmp.rar" "E:\Backups" 6、至此,数据库服务器上的备份打包已经准备好了,接下来就应该进行传输。由于数据库服务器上设置了 TCP/IP 策略,FTP 只能在被动模式下运行。如果用 Windows 自带的 FTP 命令行,就算能够建立连接,也是无法传输数据和执行操作命令的。这点非常郁闷,最后我放弃 FTP 命令行,在备份服务器上用 curl 解决了这个问题:

@set ftp_ip=0.0.0.0
@set ftp_port=1234
@set ftp_user=this_is_ftp_user
@set ftp_passwd=this_is_ftp_passwd
@set this_year=%date:~0,4%
@set this_month=%date:~5,2%
@set today=%date:~8,2%
@set remote_file_name=tmp.rar
@set local_store_path=E:\Backup\files
@set local_file_ext=rar

curl -o %local_store_path%\%this_year%-%this_month%-%today%.%local_file_ext% ftp://%ftp_user%:%ftp_passwd%@%ftp_ip%:%ftp_port%/%remote_file_name%
7、由于备份服务器的外部存储设备容量依然有限,需要想办法在每天获取数据库服务器上的备份之后,自动清理以前过期的备份文件。本来打算使用批处理来实现,苦于对批处理一窍不通,无奈向 Henry Xu 求助。我们的 Henry 操起无敌的 Microsoft Visual Studio 2005,刷刷刷刷几下就给我写了一个控制台程序,用于实现以上需求。限于商业约束,代码不便在此公开。但他的程序真的非常无敌,一个 88KB 的文件搞定一切,连一个扩展库都没有(就算有也一起封装进去了吧,我不懂 C++,瞎说的)。有了这个宝贝,接下来批处理就容易了。程序的执行参数是我们约定的,number30 代表保留30天备份,path_后面跟上备份目录的相对或绝对路径:

clear_backup.exe -number30 -path_..\files 8、最后一步就应该是删除数据库服务器上的临时备份打包。由于 FTP 处于被动模式,使用 FTP 命令行删除自然行不通。只能在数据库服务器上添加一个计划任务,在拖备份操作之后的时间执行下面的脚本:

del D:\Task\bak_files\tmp.rar /Q /F 至此,一个 SQL Server 数据库异地备份方案诞生了。还是那句话,虽然丑点了,但是真的很温柔。

标签: sql, backup, bat, c++

已有 2 条评论

  1. Spirit Spirit

    方法不错

  2. [...]前段时间折腾了一个 SQL Server 数据库异地备份解决方案,使用了一些不够完美不够和谐的方法完成了设计需求。昨天看到一款软件叫做 NcFTP,经过思考,有了下面的优化方案。原先的方案需要在双方服务器上安置批处理并加入计划任务,他们之间的先后顺序是没有握手联系的,只能依靠时间来排序。最佳途径应该还是只在一台服务器上安置批处理。原先需要在备份服务器上通过 curl 来 pull 当天的备份,现在[...]

添加新评论