web-dev-qa-db-ja.com

SQL Serverデータベースがまだ使用されているかどうかを確認するにはどうすればよいですか?

いくつかのデータベースがまだ残っているSQL Serverインスタンスを廃止する予定です。

それらがまだユーザーまたはWebアプリケーションによって使用されているかどうかを確認するにはどうすればよいですか?

最後のクエリ日付を取得するために実行できるT-SQLクエリが含まれる forum thread が見つかりました。動作するようですが、この情報がデータベースを削除するのに十分有効であるかどうかを知りたいです。それは...ですか?

同様に役立つ代替方法がある場合。

34
jsauni

キャッシュから削除されて見逃してしまったアイテムや、使用頻度の低いデータベースについて気にする必要があります。

手元にないデータベースをドロップするのではなく、データベースをドロップせずにアクセスを防ぐためにオフラインにするか、アクセスを制限するためにRESTRICTED_USERモードにします。これを行うと、1〜2か月間その状態のままにして、時折使用されていないかどうかを確認できます。

また、そのデータベースでサーバー側のプロファイラートレースフィルターを使用することもできます。

30
NicCain

これらは私が過去に使用した方法です:

  1. データベースをオフラインにする/切り離す
  2. ユーザー/ログインアクセスの拒否
  3. プロファイラートレース

問題はこれです。誰もデータにアクセスしないと確信するまで、どれくらいの期間待機しますか?財務データの場合、日次、週次、月次、四半期、半年次、および年次で実行されるいくつかの項目があります。しかし、1年で十分でしょうか。また、少なくとも7年間データを使用できるようにしたいという要望もありました。あるケースでは、誰も使用していなくても、1つのシステムのデータは永久に存在する必要があると言われました。

最善のアドバイスはこれです。アクセスをオフにするために何をしても、すぐに再びオンにできることを確認してください。デタッチがこれに最適であることがわかりました。再接続のスクリプトを作成して、チームに「どこにあるか尋ねられたら、このスクリプトを実行する」ように指示するだけです。それは私たちに物事をできるだけ早く戻す最良の機会を与えてくれました。

14
SQLRockstar

私は彼の助言でニックに同意します。確実にする必要がある場合は、SQLクエリの一部がキャッシュされないか、何らかの理由でプロシージャキャッシュがパージされる可能性があるため、プロファイラ(サービス側トレース)を使用する必要があります。

通常、仮想ファイルの統計情報をチェックして、OSファイルレベルで読み取りまたは書き込みが発生していないか確認します。データベースがアクティブではない場合でも、ログバックアップ、フルバックアップなどを実行している場合は、小さな読み取り/書き込みが表示されますが、そのデータベースでの読み取り/書き込みアクティビティのアイデアも得られます。

データベースを削除する前に、少なくとも2つまたは3つの読み取り可能なバックアップ(テスト)が別の場所にあることを確認します。いつそれらが必要になるかはわかりません。

13
Sankar Reddy

次のクエリは、インデックス(およびヒープ)に対してユーザーIOを示しているため、クエリプランがキャッシュに保持されていることに依存せずに、最後の再起動以降使用されていないDBを示しています。これは仮想ファイルの統計を使用するのと同じですが、ここで使用されるDMVは、バックアップからIOアクティビティを除外します。プロファイラトレースを実行し続ける必要はなく、トリガーや監査は必要ありません。もちろん、 SQLサーバーを頻繁に再起動する(またはデータベースを頻繁に接続/シャットダウンする)これは適切な方法ではない可能性があります:-)

そうは言っても、このクエリがDBを削除できることを確認しているように見えても、definitely OFFLINE/detachを実行するか、しばらくの間ユーザーアクセスを拒否し、さらに前に尋ねるデューデリジェンスに同意します。実際にドロップ!

select [name] from sys.databases 
where database_id > 4
AND [name] NOT IN 
(select DB_NAME(database_id) 
from sys.dm_db_index_usage_stats
where coalesce(last_user_seek, last_user_scan, last_user_lookup,'1/1/1970') > 
(select login_time from sys.sysprocesses where spid = 1))
8
FloorDivision

私は、孤立したデータベースと孤立したデータベースが多数ある場所で働いていました。多くのタスクが季節的または年次であったため、実際に孤立しているかどうかを判断するのは困難でした。そのため、Webサイトは年間3〜4か月しか実行されません(たとえば、W2フォームは電子的に1/31に提出する必要があるため、Webサイトの処理これらは1月中旬から4月末にかけてのみ実行されました)。

行われたことは、次の組み合わせでした。
*すべての開発者に、データベースを使用しているかどうかを尋ねます(これらの電子メールは毎月送信されるか、バックアップに時間がかかりすぎるたびに送信されます)。
*データベースをオフラインにして、不平を言う人を確認します。
*サーバーの名前を変更して、不平を言う人を確認します。

先のとがった髪のボスだけが「完全かつ完全な」ドキュメントを許可する用意があったので、wikiは明示的に禁止され、スタッフの削減により、標準を満たすドキュメントが劇的に減少しました。

それが私次第である場合、各データベースの連絡先名(およびデータベースの目的の簡単な説明)が記載されたサーバーごとのWikiページがあります。 wikiに文書化されていないデータベースは、削除の公正なゲームになります。

2009年の時点でまだSQL Server 2000を使用している大規模な金融クライアントが1つあったため、そのクライアントが最終的にSQL Server 2005に移行するまで、SQL Server 2000インスタンスを1つ実行し続ける必要がありました。

3
Tangurena

次のソリューションは、インスタンスの下の特定のデータベースの一時的な合計、クリーン、ダーティページをMBで示しています(インターネットで見つかり、少し変更されています)。

SELECT
    (CASE WHEN ([database_id] = 32767) THEN 'Resource Database' ELSE DB_NAME (database_id) END) AS 'Database Name',
    COUNT(*) *8/1024 AS [TotalPages in MB],
    SUM(CASE WHEN ([is_modified] = 1) THEN 0 ELSE 1 END) *8/1024 AS [CleanPages in MB],
    SUM(CASE WHEN ([is_modified] = 1) THEN 1 ELSE 0 END) *8/1024 AS [DirtyPages in MB]
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY DB_NAME(database_id)

または

select value [DBid],attribute, last_execution_time ,text
from
sys.dm_exec_query_stats
cross apply
sys.dm_exec_plan_attributes(plan_handle)
cross apply
sys.dm_exec_sql_text(plan_handle)
where  attribute = 'dbid' 
order by last_execution_time desc

または

select value [DBid],attribute, last_execution_time ,text
from
sys.dm_exec_query_stats
cross apply
sys.dm_exec_plan_attributes(plan_handle)
cross apply
sys.dm_exec_sql_text(plan_handle)
--where dbid=8
where 
      text like '%idAdministrator%' and
      attribute = 'dbid' 
      and value>= 5 -- dbid >=5 for user databases but include resource database which
                     --you can exclude by its numer I don't remember at the moment
order by last_execution_time desc
2

別の2つの選択肢は次のとおりです。

  1. アクティビティを通知する(またはテーブルに保存する)DBにトリガーを作成します。
  2. DBの監査を有効にします。

    • DBバージョンによって異なります。
2
StanleyJohns