前记:
原系统挂了,把用户数据库移到新服务器上,附加后出现很多孤立用户。然后一个一个排除很麻烦。才想起了备份系统数据库是多么重要啊。
以下是孤立用户的解决方法。
sql server 的用户安全管理分两层,整个服务器一层,每个数据库一层。一个用户,在每一层上都有账号,在两个层面上都会分配不同的权力。
服务器层的账号,叫登录账号(Login),可以设置它管理整个sql server服务器,开启跟踪,修改sql server安全配置,备份所有数据库等。
数据库层的账号,叫数据库用户(database user),可以设置对这个特定数据库有读写,修改表结构、存储过程定义等权限。
所以服务器层面的安全,是设置在服务器的登录账号上的。登录账号的信息,存放在master数据库里。
查询master数据库里的sys.server_principals视图,可见每个登录账号都有一个唯一的编号sid.
对于一个windows login,它的SID就是windows用户在域里的SID, sql server不会做改变。
对于sql Login,除了它的名字,sql server还会在创建的时候给它随机生成一个SID,一样的名字,每次生成的SID都有可能不一样。
数据库层的“数据库用户”,可以通过查询 sys.database_principals了解用户信息。
SQL SERVER登录账号必须要和某个数据库用户相对应后,才能被数据库接纳。 对应就是要用户数据库sys.database_principals里的SID和master数据库sys.server_principals里的SID匹配起来。一个登陆账户和数据库用户的名字可以不一样,但是SID必须一样。
对于windows登陆账号,如果新的服务器和原先的服务器在同一个域中,那么同样的windows账号会有一样的SID.用户数据库恢复在新服务器上后,只需将windows登陆账号加入sql server。因为两个SID值是一样的,用户数据库sys.database_principals里的SID和master数据库sys.server_principals里的SID 可以自动匹配。那么Windows账号可以自动继续使用用户数据库。
对于SQL登陆账号就有问题。假设原先的服务器上有个SQL登陆账号名叫AppDBUser。它对应用户数据库test库里的用户AppDBUser。用户数据库sys.database_principals里的SID和master数据库sys.server_principals里的SID 是相同的。当AppDBUser登陆SQL SERVER 后,可以被映射到数据库用户AppDBUser,拥有它上边赋予的权限。
当用户数据库恢复到新服务器上后,master数据库sys.server_principals里并没有这个账号。但是test数据库中还是有AppDBUser这个用户。这个用户被孤立啦。
若要检测孤立用户,执行以下
use test
sp_change_users_login @Action='Report'
输出中会列出当前数据库中未链接到任何SQL SERVER登录名的用户以及相应的安全标示符(SID)。
这个时候首先在sql server服务器里假如 AppDBUser这个sql 登陆账号。可是,新服务器为这个登陆账号生成的SID是随机的。和原先服务器上的值会不一样。还是不能使用。此时,管理员需要重新链接AppDBuser服务器登陆账户和数据库用户AppDBUser.将它们的SID改成一致的。
使用下面语句,将他们改成一致的。
sp_change_users_login @Action='update_one',@UserNamePattern='AppDBUser',@LoginName='AppDBUser'
重要:
如果能将master数据库和用户数据库一起恢复到新服务器上,两边的SID就会一致。
备份系统数据库很重要,从此可以看出。