安全永久删除数据库的最佳做法是什么?

Jon*_*des 10 sql-server delete maintenance

我们有一个“有机”的环境,这意味着人们在代码上堆积了十年,而几乎没有监督或文档。我使用的服务器有几个我认为不再使用的数据库;我很想删除它们,只留下我实际使用的三个。

在鲁莽的极端情况下,我可以禁用这些数据库并等待有人尖叫;另一方面,我可以让它们永远运行“以防万一”。在确定是否正在使用服务器方面,您发现哪些步骤很有价值,以及如何使用?

此外,您建议采取哪些步骤来确保在禁用系统的过程中,它们在一段时间内保持方便地可逆(例如,重命名对象而不是彻底删除它们)?

谢谢!

Sql*_*hes 6

您可以尝试设置仅捕获连接以及它们连接到哪个数据库的跟踪。我会让它运行一会儿,然后确保没有任何东西连接到它。

一个问题是,如果您在主数据库上打开了一些代码,但在代码中调用了另一个数据库。我不确定指向您的数据库的代码有多糟糕。

我还会查询您所有的工作,并确保没有人指向该数据库

如果您拥有正确版本的 SQL(2008 R2 企业版),也可以使用 SQL 审计。

当有人登录到该数据库时,您还可以使用登录触发器来更新表。这将显示是否有任何内容连接到该数据库。


Rol*_*DBA 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)
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

上次在任何数据库中访问表的时间:

SELECT MAX(update_time) last_accessed FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','mysql');
Run Code Online (Sandbox Code Playgroud)

最近 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;
Run Code Online (Sandbox Code Playgroud)

这些只是如何从 MySQL 获取此类元数据的几个示例。我确信 Oracle 和 SQL Server 有类似或更好的方法。

一旦确定数据库(或模式)被访问的频率或频率,您应该手动转储/导出老化的数据库以及模式本身的副本(除了数据)。请原谅我的回答与数据库无关。SQLServer 和 Oracle DBA 也应该在这里说出他们的答案,因为模式是数据库实例中的集合的概念在 MySQL 中是模糊的,但在 SQLServer 和 Oracle 中却被严格遵循。