データベースを安全に完全に削除するためのベストプラクティスは何ですか?


10

私たちは「有機的な」環境を持っています。つまり、人々は最小限の監視またはドキュメント化でコードにコードを10年間積み上げてきました。私が使用しているサーバーには、もう使用されていないと思われるいくつかのデータベースがあります。それらを削除して、実際に使用している3つだけを残したいです。

無謀な極端では、これらのデータベースを無効にして、誰かが悲鳴を上げるのを待つことができました。もう一方では、「念のため」、それらを永久に実行したままにすることができます。サーバーが使用されているかどうか、およびその方法を特定する上で、どのような手順が重要であると思いましたか?

また、システムを無効にすることで前進するときに、一定期間便利に元に戻せるようにするためにどのような手順を推奨しますか(オブジェクトを完全に削除するのではなく、名前を変更するなど)?

ありがとう!


1
これは長い間非常に鋭い質問です。そのような質問の+1。DBAは自分のキャリアでこの状況に後で直面するのが早いので、この質問がより大きな反応を引き出すことを願っています。
RolandoMySQLDBA

うわー、周りの素晴らしいポイント!そして、RolandoMySQLDBAはすでに私のためにすべての人に感謝するための面倒を見てくれました:)私はこれをもう少し開いたままにして、他に提案があるかどうかを確認します。
Jon of All Trades

回答:


4

また、すべてのテーブルの日時スタンプを確認する必要があります。システム内のすべてのテーブルのメタデータを検索し、そのようなリストを最後に更新された日時順に並べ、出力を日時順に降順で表示します。サイズのわずかな変化についても、テーブルのサイズを確認できます。

たとえば、MySQL 5.xでは、次のようなinformation_schema.tablesがあります。

mysql> desc information_schema.tables;
+-----------------+---------------------+------+-----+---------+-------+
| Field           | Type                | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+-------+
| TABLE_CATALOG   | varchar(512)        | NO   |     |         |       |
| TABLE_SCHEMA    | varchar(64)         | NO   |     |         |       |
| TABLE_NAME      | varchar(64)         | NO   |     |         |       |
| TABLE_TYPE      | varchar(64)         | NO   |     |         |       |
| ENGINE          | varchar(64)         | YES  |     | NULL    |       |
| VERSION         | bigint(21) unsigned | YES  |     | NULL    |       |
| ROW_FORMAT      | varchar(10)         | YES  |     | NULL    |       |
| TABLE_ROWS      | bigint(21) unsigned | YES  |     | NULL    |       |
| AVG_ROW_LENGTH  | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_LENGTH     | bigint(21) unsigned | YES  |     | NULL    |       |
| MAX_DATA_LENGTH | bigint(21) unsigned | YES  |     | NULL    |       |
| INDEX_LENGTH    | bigint(21) unsigned | YES  |     | NULL    |       |
| DATA_FREE       | bigint(21) unsigned | YES  |     | NULL    |       |
| AUTO_INCREMENT  | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_TIME     | datetime            | YES  |     | NULL    |       |
| UPDATE_TIME     | datetime            | YES  |     | NULL    |       |
| CHECK_TIME      | datetime            | YES  |     | NULL    |       |
| TABLE_COLLATION | varchar(32)         | YES  |     | NULL    |       |
| CHECKSUM        | bigint(21) unsigned | YES  |     | NULL    |       |
| CREATE_OPTIONS  | varchar(255)        | YES  |     | NULL    |       |
| TABLE_COMMENT   | varchar(2048)       | NO   |     |         |       |
+-----------------+---------------------+------+-----+---------+-------+
21 rows in set (0.01 sec)

列UPDATE_TIMEは、INSERT、UPDATE、またはDELETEが最後にテーブルに適用された最後の時間を記録します。次のようなクエリを実行して、各データベースが最後にアクセスされた日時を確認できます。

各データベースでテーブルに最後にアクセスした時間:

SELECT table_schema,MAX(update_time) last_accessed
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','mysql')
AND update_time IS NOT NULL
GROUP BY table_schema;

いずれかのデータベースでテーブルが最後にアクセスされたとき:

SELECT MAX(update_time) last_accessed FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','mysql');

テーブルにアクセスした最後の10日付:

SELECT * FROM
(SELECT * FROM
(SELECT last_accessed,COUNT(1) access_count
FROM (SELECT DATE(update_time) last_accessed
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','mysql')
AND update_time IS NOT NULL) A
GROUP BY last_accessed) AA
ORDER BY last_accessed DESC) AAA
LIMIT 10;

これらは、MySQLからそのようなメタデータを取得する方法のほんの一例です。OracleとSQL Serverには似たような、またはより良い方法があると思います。

データベース(またはスキーマ)へのアクセス頻度を確認したら、古いデータベースとスキーマ自体のコピーをデータとは別に手動でダンプ/エクスポートする必要があります。私の答えはDBにとらわれないわけではありません。SQLServerとOracleのDBAもここで回答を表明する必要があります。データベースインスタンス内のコレクションであるスキーマの概念は、MySQLでは曖昧ですが、SQLServerとOracleでは厳密に準拠しています。


とても良いヒントです。更新を監視するために一連のクエリをまとめます。将来の世代の利益のために、ここでは、スキーマ・レベルで、このようなAクエリは、MS SQLのために、です:SELECT S.name, MAX(T.modify_date) AS MostRecentDataModification FROM sys.schemas AS S INNER JOIN sys.tables AS T ON S.schema_id = T.schema_id GROUP BY S.name
すべての取引のジョン・

6

接続と接続先のデータベースのみをキャプチャするトレースを設定してみてください。これを少しの間実行したままにして、何も接続されていないことを確認します。

これに関する1つの問題は、マスターデータベースでいくつかのコードを開いているが、コード内で別のDBを呼び出す場合です。私はあなたのDBを指しているコードがどれほど悪いかわかりません。

また、すべてのジョブをクエリして、そのDBを指しているものがないことを確認します

適切なバージョンのSQL(2008 R2エンタープライズ)を使用している場合は、SQL監査を使用することもできます。

ログオントリガーを使用して、誰かがそのDBにログオンしたときにテーブルを更新することもできます。これは、何かがそのDBに接続しているかどうかを示します。


非常に良い答え、特にログイントリガーに関して!!! MySQLにはそのようなものはありませんが、一般的なログをアクティブにし、指定されたIPアドレスとデータベースをチェックすることでエミュレートできます。あなたは+1です!!!
RolandoMySQLDBA

4

また、システムを無効にすることを進めるときに、一定の期間、都合よく元に戻せるようにするために、どの手順を推奨しますか?

SQL Serverでは、データベースを「オフライン」にして、データベースをそのままにしておくことができますが、コードを介してデータベースに接続することはできません。データベースが「オフライン」の場合でも、データベースは引き続き使用可能であり、数分以内に元に戻すことができます。

私の最後の仕事では、年間数か月間稼働していた製品がいくつかあったため、一度に数か月間データベースをオフにしたりオフラインにしたりしても、その製品を使用している人は気付かなかったでしょう。一例として、製品の1つはW-2フォームを使用していたため、ビジネスの98%が1月と2月に行われます(ほとんどの企業では、データは1月の第1週と、情報は1月の最終営業日です)。Webサーバーは通常、5月〜6月から12月までオフになりました。

その会社では、データベースの「所有者」を含むスプレッドシートを用意しました-製品を担当する一人の人。他の人はテーブルの構造を更新することができましたが、「所有者」は質問が必要なときに頼りになる人でした。所有者が退職した場合(昨年までまれ)、誰かが退職する前に新しい所有者に割り当てられます。

他の会社では、データベースを四半期にわたってオフラインにしましたが、何も壊れずにオフラインのままである場合(月/四半期のレポートなど)、最後にもう一度バックアップされて削除されます。これにより、誰かが後で戻ってデータベースを復元できるようになります(数分かかります)。「ああ、それは、fredプロジェクトが終了するまでに準備しておかなければならなかったjonesプロジェクトのためのものでした。」


素敵なミニケーススタディ、+ 1 !!!
RolandoMySQLDBA

@Tanguerna:私は何年も前にこの機能を使用したと思いますが、この種の役割には最適です。思い出させてくれてありがとう。
Jon of All Trades、2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.