English 中文(简体)
优雅替换只读SQL Server数据库的最佳实践
原标题:
  • 时间:2008-12-16 18:38:11
  •  标签:

我有一个只读数据库,其中缓存了用于显示网站上页面的信息。有一些进程运行来生成数据库,而这些进程在不同的服务器上运行。当我需要更新现场数据库时,我将此数据库恢复到现场服务器,给它一个新名称和文件。然后,我删除现场数据库并将此数据库重命名为原始名称。目前,我使用存储过程来执行此操作,它通过 sp_who 和kill 杀死所有连接,然后使用drop database命令,然后是 sp_renamedb。现在,当我杀死所有连接时,它将在网站上为当前访问这些页面的人和网络爬虫引发错误,是否存在更好的执行此过程的方法?

最佳回答

可能您想要做的是使用命令将实时数据库脱机:

ALTER DATABASE name SET OFFLINE

您可以在此阅读更多信息:http://www.blackwasp.co.uk/SQLOffline.aspx,但其中写到:

上面的命令试图立即使指定的数据库离线。如果当前有用户或后台进程连接到该数据库,则无法完成该命令。在这种情况下,ALTER DATABASE语句将被阻塞,并将等待所有连接关闭。这确保没有事务意外回滚。在阻塞期间,不允许对数据库进行新的连接。 (Translation may vary depending on context and specific terminology used)

一旦数据库下线,您应该可以安全地执行恢复/重命名操作,并在完成后将其恢复在线。 在数据库处于脱机状态时,您可能需要进行某些操作以查看允许的内容。

如果您在离线状态下无法进行还原/重命名操作,您需要将其置于单用户模式下在线。

连接池或其他长期运行的连接可能会在此场景中引起问题。您可能需要设置一个脚本,在执行ALTER DATABASE SET OFFLINE命令后等待一段时间(如15分钟),如果数据库仍未下线,则可以重新使用WITOH NO_WAIT选项重新发出命令以强制其下线。

如果这对您来说不够高效,您还可以优雅地关闭SQL Server......在停止之前,它也会等待服务器中的所有工作完成。

问题回答

设置事务复制,将您的数据生成服务器作为发布者,将您的实时服务器作为订阅者。客户端连接不会察觉到任何变化。

+1 for Mike Sharek - I like your solution, it s very tidy and prevents users being disconnected abruptly (and very rudely).

Another alternative, if you don t want to sit around waiting for users to log off for hours. You could send an alert to connected clients through an AJAX mechanism you build into the site that basically sits "open" and waits for a notification from the server for a period before it times out and reconnects so essentially the XmlHttpObject is always waiting for a response. At the point of receiving the response, it displays it onscreen and then opens another connection. You then have an administrator interface that pushes out messages to the waiting AJAX component.

This would allow you to send a message in approximately realtime in a similar manner to the way Microsoft s Outlook Mobile Access works allowing users to be notified that in 10 minutes, the site is going down for maintenance.

I m not sure if there s any prebuilt components out there that do this, but I m sure it couldn t be too difficult to implement.

It doesn t help you out in the immediate sense, but it s worth thinking about for future releases of your site.

If you want to do something really seamless for your users. I would do something like this.

When you copy the new version of your database over give it a new name, maybe named with the datetime, depending on how often you update it. Once it is there tell your web application to start using the new database. This could be done by changing the connection string in the web.config, or having it a configuration database.

Once a certain amount of time has passed, based on the usage characteristics of your site remove the old database.





相关问题
热门标签