web-dev-qa-db-ja.com

プリンシパルが存在しないため、データベースプリンシパルとして実行できません-DBリストア

クライアントの1つからデータベースバックアップを1つ受け取りましたが、それをシステムに復元しようとしています。

私はグーグルでこの問題を検索しようとし、提案されたソリューションのほとんどを試しましたが、どれも機能していません。データベースの復元後、このエラーの具体的な解決策を誰かが提案できますか?

エラーのスクリーンショット Screenshot of error

前もって感謝します!

5
iKishanSojitra

データベースを復元すると、database usersが含まれます。これらのユーザーは、別のSQL Serverへのバックアップと復元を実行するたびに、データベースとともに転送されます。

ソースSQLサーバーとターゲットSQLサーバーには、SQLサーバーログインがあります。これらのログインは、SQL Serverアカウント(ネイティブSQL Serverログイン)またはWindowsサーバー/ドメインアカウント(Windowsアカウント)のいずれかです。

SQL Serverログイン

SQL Serverログイン(ネイティブSQLログインまたはWindowsアカウント)はmasterデータベースに格納され、各SQLログインに一意のSIDが割り当てられています。システムカタログビュー sys.server_principals をクエリすると、SQL Serverログインのリストを取得できます。

select * from sys.server_principals

SQL ServerインスタンスのSQL Serverログインのリストを受け取ります。

注:これらはSQL Serverログインであり、データベースユーザーではありません。

データベースユーザー

次のクエリを発行して、各ユーザーデータベースのシステムカタログビュー sys.database_principles をクエリすることで、データベースユーザーにクエリを実行できます。

USE [<your_db>]
GO
SELECT * FROM sys.database_principals

データベース特権が割り当てられているデータベースユーザーのリストが表示されます。

注:これらはデータベースユーザーであり、SQL Serverログインではありません。

通常の動作

データベースを作成し、特定の権限を持つ「ユーザー」をデータベースに割り当てると、実際には次のことを行います(一部はバックグラウンドで)。

  1. パスワード(sys.server_principal)を使用したSQL Serverログインの作成
  2. データベースにデータベースユーザーを作成する(sys.database_principal
  3. データベースユーザーへの権限の付与(権限に応じて、さまざまなテーブルで)

この場合、SQLログインのSID(sys.server_principal)は、データベースユーザーのSID(sys.database_principal)と一致します。

復元動作

ソースSQL Serverからデータベースを復元すると、ソースデータベースのデータベースユーザー(ネイティブSQL ServerログインとローカルWindowsアカウントのみ)のSIDが異なりますターゲットサーバー上のSQL Server Loginsよりも。これは、SIDがソースとターゲットのネイティブSQL ServerログインまたはローカルWindowsアカウントで一意であるためです。

SQL Serverはこれらの値をActive Directoryから取得するため、Windowsドメインアカウントに基づくSQL Serverログインは常に同じSIDを持ちます。

データベースをソースからターゲットのSQL Serverに復元すると、ユーザーがSQL Serverインスタンスのsys.server_principalsシステム管理カタログにリストされていても、ネイティブSQL ServerログインのSIDが一致しませんsys.database_principals復元されたデータベースのシステム管理カタログ。

解決

これを修正し、「SQL Serverログイン|権限」または「データベースプロパティ|権限」をナビゲートできるようにするには、これらの孤立したデータベースユーザーをSQL Serverログインに再リンクします。

ユーザーデータベースに切り替えて、孤立したデータベースユーザーをクエリします。

USE [your_db]
GO
sp_change_users_login 'Report'

ユーザーが孤立していると報告された場合は、SQL Serverログインデータベースユーザー次のコマンドを発行します。

USE [your_db]
GO
sp_change_users_lgoin 'Update_one', '<database_user>', '<sql_server_login>'

これにより、ターゲットインスタンスの(ネイティブ)SQL Serverログイン(sys.server_principal)が、復元されたデータベースのデータベースユーザー(sys.database_principal)に再リンクされます。

オルタナティブ

sp_change_users_loginは非推奨であるため、- ALTER USER ステートメントで同じことを実現できます。

USE [<your_db>]
GO
ALTER USER <database_user> 
    WITH LOGIN = <sql_server_login>

ある場合には

...クライアントからデータベースバックアップを受け取ったときに、データベースユーザーにリンクするための対応するSQL Serverログインがない場合があります。その場合は、復元したデータベースに権限を割り当てずにSQL Serverログインを作成し、新しく作成したSQL Serverログインを上記のステートメントを使用してデータベースユーザーにリンクできます。

8

表示されているエラーは、SSMSダイアログ(画像上)が起動するコードに由来します。

そのダイアログを介して一部のユーザーの有効な権限についてサーバーに尋ねると、サーバーは選択されたユーザーを偽装しようとします。つまり、test_usereffective permissions起動するコードは次のとおりです。

EXECUTE AS USER = N'test_user';
SELECT 
    permission_name AS [Permission]
FROM fn_my_permissions(N'[yourDB]', N'DATABASE')
ORDER BY permission_name;
REVERT;

これは、ユーザー(test_user)がログインなしで作成された場合です。

ユーザーが対応するログインを持っている場合、サーバーはその対応するログインを偽装しようとします。これは、login = win groupの場合、より多くのユーザーに対応する可能性があるためです。

たとえば、ユーザーがcertificateから作成される場合もありますが、この場合に実行されるコードを監視できません。

SQL Server Profilerを使用するだけで、サーバーでどのコードが実行されるかを確認するには、偽装しようとしているものを特定して、エラーの原因を見つけます

私はWindowsグループの特定のケースでこのエラーを受け取る方法を知っています:偽装することはできないため、正確にそのエラーが発生します。

その他の考えられる原因:そのユーザーを偽装する権限がない可能性があります。コードをsysadminとして実行していますか?そうでない場合、これはあなたのケースである可能性があります

[〜#〜]更新[〜#〜]

たった今再現できました。 復元されたデータベースを別のサーバーに移植した孤立したユーザーは、偽装しようとすると同じエラーが発生します

孤立したユーザーと同じ名前の(sidが異なる)ログインが存在する場合は、次のコードを実行してこれを修正できます。

alter user test_user with login = test_user

対応するログインがない場合は、同じsidで再作成するか、新しいログインを作成して、上記のように既存のユーザーを更新します。

このユーザーがまったく必要ない場合は、ドロップしてください

0
sepupic