和用户、登录、密码与安全标识号(SID)一起移动数据库
--王成辉翻译整理,转贴请注明出处
--原帖地址
导言
正如大多数人了解的那样,从一个服务器移动数据库是相对简单的。你可以使用分离附加,或使用备份恢复。如果数据库有很少的用户和登录的话,这是个正确的方法。然而,一个数据库有成百上千个用户的话就是另一种情形了。特别是对你的商业或组织来说是一个很紧急的任务时。想象一下由于服务器登录的移动产生的数据库孤立用户使你在收到250个用户抱怨密码不起作用时你的经理是多么的抓狂。有很多介绍快速移动数据库和移动登录的文章。本文介绍在移动数据库的同时移动相应的用户,和他们在你有兴趣移动到一个新服务器上的特定数据库上的所有的信息。
这是什么意思?
在SQL7服务器之间,DTS的传输登录任务可以传输登录和用户,但不包括密码。在SQL7到SQL2000之间或SQL2000之间,DTS传输登录能传输登录、用户和密码,但原来的SID(安全标识号)都将变成孤立用户,这意味着DBA不得不回去重新映射数据库用户和登录。……这是什么意思?
下面我们来看看怎样得到数据库、关联的用户以及所有不仅为你的用户也为你而让事情流程平稳所需要的所有信息。这包括他们的密码、服务器登录和SID。为了达到本文的目的,原始的服务器将称为ServerA,而目标服务器将称为ServerB。
第一步——备份
首先且最重要的是,在ServerA上得到数据库的最近的全备份。使用类似下面的一个脚本。STATS关键字用于显示备份进度,对大数据库来说这是有用的。
BACKUP DATABASE DummyDatabase TO DISK = '//Networkshare/DummyDatabase_dump.BAK' WITH INIT, NAME = DummyDatabase DESCRIPTION = ' DummyDatabase INIT BackupFull', STATS=1 RESTORE VERIFYONLY FROM DISK = '//Networkshare/DummyDatabase_dump.BAK' WITH STATS=1复制该备份文件到ServerB的特定位置。还不要恢复,仅仅复制备份文件即可。
下一步——得到登录信息
载入和更改脚本
在登录到ServerA的master数据库时要载入的脚本,它在微软的知识库KB246133可以找到。这会在你的master数据库里创建两个存储过程,分别为sp_hexadecimal和sp_help_revlogin。我们将轮流使用sp_help_revlogin和sp_hexadecimal。
如果你仅关心一个数据库,你不需要所有的服务器登录。为了限制sp_help_revlogin仅显示一个数据库的结果,简单的修改一下它。首先你需要知道你感兴趣的数据库的ID。你可以通过在master里运行下面的语句得到。
SELECT * FROM sysdatabases
找到你感兴趣的数据库的ID。我们将为示例使用ID为5的数据库。现在你可以更改sp_help_revlogin存储过程来仅仅给出特定数据库的登录信息,注意更改后的语句如下:
ALTER PROCEDURE sp_help_revlogin @login_name sysname = NULL AS DECLARE @name sysname DECLARE @xstatus int DECLARE @binpwd varbinary (256) DECLARE @txtpwd sysname DECLARE @tmpstr varchar (256) DECLARE @SID_varbinary varbinary(85) DECLARE @SID_string varchar(256) IF (@login_name IS NULL) DECLARE login_curs CURSOR FOR SELECT sid, name, xstatus, password FROM master..sysxlogins WHERE srvid IS NULL AND name <> 'sa' and dbid = 5 ELSE
DECLARE login_curs CURSOR FOR SELECT sid, name, xstatus, password FROM master..sysxlogins WHERE srvid IS NULL AND name = @login_name and dbid = 5 .................
运行SP_HELP_REVLOGIN
更改存储过程后,运行它。Sp_help_revlogin过程的输出一个登录列表和一定数量的看上去神秘的东西。这儿需要考虑的一个重要的事情是如果ServerA上的这些登录中的任何一个在ServerB上是否已经存在。如果存在,你需要不去包括这些用户。例如,如果登录testuser2在ServerB上存在,那么你需要去掉testuser2的部分。否则你会收到一个“服务器登录已经存在”的错误消息。你也需要改变这些用户去使用存在ServerB上的密码来从ServerA中移动数据库。
在ServerB上运行ServerA里sp_help_revlogin脚本的输出结果。这将创建服务器登录、SID和密码。
注意
尽管不确定,这些用户在ServerB上可能需要有一个缺省的数据库设置,依赖于应用程序设置。如果你要用户的缺省数据库设置也移过来的话,计划稍后执行sp_defaultdb存储过程。你需要登录列表。如果列表很大,你可以使用各种文本编辑器或者Excel来产生重复的脚本,如下:
EXEC master..sp_defaultdb 'testuser', 'DummyDatabase' EXEC master..sp_defaultdb 'testuser2', 'DummyDatabase' .......................
最后一步——恢复
现在是时候在ServerB上恢复数据库了。使用类似下面的脚本……注意With Move参数,万一ServerA和ServerB上的文件存储位置不一样。
RESTORE DATABASE DummyDatabase FROM DISK = 'R:/DummyDatabase_dump.bak' WITH MOVE 'Dummy_data' TO 'R:/Program Files/Microsoft SQL Server/MSSQL/Data/DummyDatabase_data.mdf', MOVE 'Dummy_Log'
TO 'R:/Program Files/Microsoft SQL Server/MSSQL/Data/DummyDatabase_log.ldf', STATS=1
在ServerB上成功恢复之后,浏览一下数据库的用户。所有的用户都将映射到登录。如果没有的话,整理孤立用户并重新映射到正确的服务器登录。
结论
从一个服务器移动数据库、用户、登录和密码到另一个服务器是有一点痛苦。但既然你按照这个过程去做的话痛苦很有希望不那么大了。