0

这个问题的重点是为什么会发生这种情况。

我们从另一台发生故障的服务器恢复了数据库。恢复成功,但是当我们尝试运行任何存储过程(使用“sa”登录或具有完全管理员访问权限的基于 Windows 的登录)时,我们收到此错误:

无法作为数据库主体执行,因为主体“dbo”不存在,无法模拟这种类型的主体,或者您没有权限。

很多 SO 用户都有同样的问题,所以我遵循了相关的答案。例如,以下两个片段:

EXEC sp_changedbowner 'dbo';
ALTER AUTHORIZATION ON DATABASE::MyDb TO dbo;

...导致:

找不到主体“dbo”,因为它不存在或您没有权限。

在以前的服务器(和我的恢复开发服务器)上,没有dbo 用户可以重新关联为所有者。我不确定如何找到principal,但它在 Schema 中列出。

  1. 是什么原因导致找不到“dbo”,或者 dbo 主体发生了什么?
  2. 可以恢复/重建吗?
  3. dbo 是否必须链接到实际的登录帐户?
4

1 回答 1

1

数据库所有者是服务器级别的主体(即登录名)或 Windows 用户(不一定具有登录名)。如评论中所述,dbo是数据库主体而不是服务器主体(假设您碰巧没有名为 的登录名dbo)。

所有者存储在主数据库中,并作为目录视图的owner_sid列可见:sys.databases

SELECT name AS DatabaseName, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName
FROM sys.databases
WHERE name = N'MyDb';

数据库所有者也作为知名dbo用户存储在数据库本身中:

SELECT SUSER_SNAME(sid) AS OwnerName, sid
FROM sys.database_principals AS dp
WHERE name = N'dbo';

当一个数据库被恢复并且它不存在时,所有者(授权)最初被设置为恢复数据库的人。但是,dbo数据库本身中的条目保持不变。这导致所有者sys.databasessys.database_principals dbo用户之间的不匹配。ALTER AUTHORIZATION ON DATABASE必须在还原后与所需所有者一起执行以更正不匹配。

下面的脚本演示了执行还原的个人未以sa.

CREATE DATABASE MyDb; --database is owned by current login

ALTER AUTHORIZATION ON DATABASE::MyDb TO sa; --sa is an example; can be any login

--shows owners are same (sa)
SELECT name AS DatabaseName, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName
FROM sys.databases
WHERE name = N'MyDb';

SELECT SUSER_SNAME(sid) AS OwnerName, sid
FROM MyDb.sys.database_principals AS dp
WHERE name = N'dbo';

BACKUP DATABASE MyDb TO DISK=N'C:\Backups\MyDb.bak' WITH INIT;

DROP DATABASE MyDb;

RESTORE DATABASE MyDb FROM DISK=N'C:\Backups\MyDb.bak';

--shows owners are different (current user and sa)
SELECT name AS DatabaseName, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName
FROM sys.databases
WHERE name = N'MyDb';

SELECT SUSER_SNAME(sid) AS OwnerName, sid
FROM MyDb.sys.database_principals AS dp
WHERE name = N'dbo';

ALTER AUTHORIZATION ON DATABASE::MyDb TO sa; --sa is an example; can be any login

--shows owners are same (sa)
SELECT name AS DatabaseName, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName
FROM sys.databases
WHERE name = N'MyDb';

SELECT SUSER_SNAME(sid) AS OwnerName, sid
FROM MyDb.sys.database_principals AS dp
WHERE name = N'dbo';

以下是有关数据库所有者主体的文档的摘录。

新的所有者主体必须是以下之一:

A SQL Server authentication login.
A Windows authentication login representing a Windows user (not a group).
A Windows user that authenticates through a Windows authentication login representing a Windows group.
于 2021-04-29T11:20:57.527 回答