cod*_*dey 7 sql-server restore
在为每个租户设置数据库的多租户 Web 应用程序中,可以通过相当传统的方法手动备份和恢复数据库。
我正在为一个可能有 5,000-10,000 个租户的应用程序考虑这种类型的架构,并且为这么多租户数据库运行这种类型的过程会很麻烦。
如果我要为大量租户数据库实现这样一个过程:
对于如此大量的不同备份,是否可能会产生过多的性能开销?
如此大量的备份过程如何实现自动化?
如何跟踪如此大量的备份并确保还原操作获得正确的备份和要还原到的数据库?
如何实施控制来监控如此大量数据库的备份状态和完整性?
在我之前的工作中,我就是这样做的。我们在 500 个租户范围内,但是一旦超过 10 或 20 个,自动化部分会使实际数量变得不那么重要。
假设您的硬件可以在足够长的时间内处理 10,000 个数据库的备份,并且所有 10,000 个数据库的活动量都不足以在有或没有备份的情况下使您的服务器不堪重负,那么下一步是使整个过程自动化。这个模型的好处是,如果 10,000 个数据库最终使您的服务器不堪重负,那么将其中的一半移动到第二台服务器并根据租户将您的应用程序指向正确的实例要容易得多,而不是尝试翻录一半的数据来自单个数据库。你有一些是 FULL 的,一些是 SIMPLE 的,还是它们都在同一个恢复模型中?
我们有优先事项。所以有一个表来保存租户信息(在我的实现中有更多的列,但这应该是基础知识):
CREATE TABLE dbo.TenantBackups
(
TenantID INT PRIMARY KEY,
RecoveryModel VARCHAR(6),
Priority TINYINT
);
Run Code Online (Sandbox Code Playgroud)
然后是一个历史表(同样,在实际系统中更多,但出于问题的目的):
CREATE TABLE dbo.TenantBackupHistory
(
TenantID INT, -- FOREIGN KEY,
BackupType TINYINT, -- lookup for FULL, LOG, RESTORE_TEST
StartTime DATETIME,
EndTime DATETIME,
Status NVARCHAR(1000) -- almost always NULL but held true "exceptions"
);
Run Code Online (Sandbox Code Playgroud)
所以现在作业可以通过租户运行,按优先级排序,并执行备份。实际上,我们为优先级 1 和优先级 2-5 设置了不同的作业。
我们每晚通过在备份服务器上恢复完整备份来测试优先级 1 租户。我们还每晚从其他优先级中随机挑选 20 个数据库来测试它们的恢复情况。当然,配置了警报等,以便立即知道故障,如果异常不在我们正常的重试/错误处理范围内,则状态列将包含信息。
我们还使用SQL Sentry来链接作业,这样我们就不必担心调度缓冲区并尝试预测备份作业何时完成。对于优先级为 1 的数据库,我们不必费心等待备份作为一个整体完成;我们有一个后台线程,它会等待每个单独的完整备份完成,然后立即将其从队列中取出并启动复制/恢复测试过程。对于优先级 1 租户,我们还使用恢复的副本作为报告卸载 - 对于今天之前对数据感兴趣的任何报告(这是大多数报告),他们可以运行副本,因为它唯一缺少的是今天。
对于完全恢复租户(并非所有客户都需要时间点),日志备份作业可以轻松检查历史记录表以查看是否已经在进行任何类型的备份。但当然,错误处理和重试逻辑是全面实施的。
我知道这些是非常笼统的描述,但我希望它们为您指明正确的方向。如果您希望我扩展任何细节,请告诉我。
如果这些 5-10K 数据库上的备份是串行运行的,那么与在一个大型数据库上运行备份相比,性能应该不会有显着差异。如果您的数据库不大并且具有良好的 I/O 容量,您可能会同时运行几个备份,但我不会指望这一点。
您将希望远离“维护计划”类型的作业,因为您需要更多地控制发生的事情,而这些作业不会创建您想要的那种日志。另外,计划有一些奇怪的失败方式,但并不总是引起注意,尤其是在较旧的 SQL Server 版本上。编写一个程序来备份服务器上的所有数据库非常简单。该过程应保留一个日志表,该表描述了备份的数据库、备份的时间以及它转到的文件。文件名中可能应该有某种时间戳,以便轻松找到正确的文件。我会确保有一种方法可以将所有这些备份文件“分片”到不同的文件夹和文件系统中;不要只是将它们转储到一个文件夹中。您将需要一种自动方式来存档或删除“旧”备份。如果它也进入该日志表并将任何特定备份文件标记为“可用”、“存档”、“已删除”等,那就太好了。当然,您需要足够的存储空间来保存每个数据库的尽可能多的备份因为你愿意保留。
自动恢复更狡猾。部分是因为您可以快速清除错误的数据库,部分是因为您需要一种方法将数据库用户踢出以开始恢复。
可以通过 RESTORE HEADERONLY 和 RESTORE FILELISTONLY 读取备份,以验证即将恢复的内容。我会尝试将该信息构建到文件名中,因为查看文件名比摆弄 RESTORE 命令要容易得多。您可以编写一些快速的 CLR 命令来执行目录列表等操作,我不是 C# 天才,因此当我不得不这样做时,我在网上找到了几个示例。只需为文件名选择一个好的格式,然后坚持使用。类似于 SERVERNAME-INSTANCENAME-DATABASENAME-FULL-2012.04.18-09.24.00.bak 之类的东西。这样,很容易看到备份的来源和时间。确保您的恢复方案可以将数据库恢复到不同的服务器和/或在不同的数据库名称下。使用不同的数据库名称恢复到同一台服务器时,一个常见的问题是文件名冲突;您需要使用新文件。
所有这些都假设数据库在 SIMPLE 恢复模式下运行。如果数据库不是在 SIMPLE 模式下运行,您的问题就会成倍增加。您将需要更多空间来保存备份,因为您将需要 tlog 备份以及完整备份。运行事务日志备份可能是真正的问题,因为支持它们的单个作业可能无法在可接受的窗口中运行。(如果您保证时间点恢复为 15 分钟,那么如果作业需要 30 分钟来运行,那将无济于事。)如果 tlog 序列被破坏,或者您以某种方式丢失了完整备份,您需要能够备份一个或多个数据库,具体取决于出错的地方。选择数据库并将它们恢复到不同的实例上会很有用,以确保一切正常。DBA 不如他们上次的备份,
恢复代码会更复杂,特别是如果您认为租户可以自己进行恢复。
此外,除了备份这些数据库之外,您还需要创建类似的进程来运行 DBCC CHECKDB 并进行重新索引。我会查看 DBA 博客上提供的一些现有代码。您甚至可以找到一些可以重新制作成备份程序的东西。
最后,像您的业务一样测试一切。因为,它可能。确保您测试备份失败的情况(备份文件的空间不足,也许?)或者存在脱机或设置为访问受限或以某种方式损坏的数据库。当你运行你的测试时,监控系统的性能,最好是当它已经有一些负载时。
归档时间: |
|
查看次数: |
639 次 |
最近记录: |