데이터베이스를 안전하게 영구적으로 삭제하기위한 모범 사례는 무엇입니까?


10

우리는 "유기적 인"환경을 가지고 있습니다. 사람들은 최소한의 감독이나 문서화로 10 년 동안 코드에 코드를 쌓아 놓았습니다. 내가 사용하는 서버에는 더 이상 사용되지 않는 여러 데이터베이스가 있습니다. 나는 그것들을 삭제하고 실제로 사용하는 3 개만 남겨두고 싶습니다.

무모한 극단에서이 데이터베이스를 비활성화하고 누군가가 비명을 지르기를 기다릴 수있었습니다. 다른 쪽에서는 나는 "만약을 위해"영원히 뛰도록 내버려 둘 수있었습니다. 서버 사용 여부를 식별하는 데 어떤 단계가 도움이 되었습니까?

또한, 비활성화 시스템에서 앞으로 나아갈 때 일정 기간 동안 편리하게 되돌릴 수 있도록 (예 : 개체를 완전히 삭제하지 않고 이름을 바꾸는 것) 유지하기 위해 어떤 단계를 권장합니까?

감사!


1
이것은 연령대에 대한 매우 현명한 질문입니다. 그런 질문에 +1하십시오. DBA가 나중에이 상황에 직면하게 되었기 때문에이 질문이 더 큰 반응을 이끌어 내길 바랍니다.
RolandoMySQLDBA

와우, 좋은 포인트가 사방에! 그리고 RolandoMySQLDBA는 이미 모든 사람에게 감사를 표했습니다.
모든 거래의 존

답변:


4

또한 모든 테이블의 날짜 / 시간 스탬프를 확인하려고합니다. 시스템에서 모든 테이블에 대한 메타 데이터를 검색하고 마지막으로 업데이트 한 날짜 시간순으로 목록을 정렬 한 다음 날짜 시간순으로 출력을 desc 순서로 표시하십시오. 크기가 약간 변경 되어도 테이블 크기를 확인할 수 있습니다.

예를 들어 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에 구애받지 않는다는 것을 변명하십시오. 데이터베이스 인스턴스 내의 컬렉션 인 스키마 개념은 MySQL에서는 흐리게 표시되지만 SQLServer 및 Oracle에서는 매우 엄격하게 따르기 때문에 SQLServer 및 Oracle DBA도 여기에서 답변을 제시해야합니다.


아주 좋은 팁. 업데이트를 주시하기 위해 일련의 쿼리를 작성하겠습니다. 미래 세대의 이익을 위해 다음은 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
Jon of All Trades

6

연결과 연결하는 데이터베이스 만 캡처하는 추적을 설정하려고 시도 할 수 있습니다. 나는이 실행을 조금 남겨두고 아무것도 연결되어 있지 않은지 확인합니다.

그것에 대한 한 가지 문제는 마스터 DB에서 일부 코드가 열려 있지만 코드 내에서 다른 DB를 호출하는 경우입니다. DB를 가리키는 코드가 얼마나 나쁜지 잘 모르겠습니다.

또한 모든 작업을 쿼리하고 해당 DB를 가리키고 있지 않은지 확인하십시오.

올바른 버전의 SQL (2008 R2 enterprise)이있는 경우 SQL 감사를 사용할 수도 있습니다.

누군가가 해당 DB에 로그온 할 때 로그온 트리거를 사용하여 테이블을 업데이트 할 수도 있습니다. 어떤 것이 해당 DB에 연결되어 있는지 보여줍니다.


특히 로그인 트리거에 관한 매우 좋은 답변 !!! MySQL은 일반적인 로그를 활성화하고 지정된 IP 주소와 데이터베이스를 확인하여 에뮬레이션 할 수는 있지만 그런 것은 없습니다. 당신은 +1입니다!
RolandoMySQLDBA

4

또한, 시스템을 사용 중지 할 때 시스템이 일정 시간 동안 편리하게 가역적으로 유지되도록하기 위해 권장하는 단계

SQL Server에서는 데이터베이스를 " 오프라인 " 상태로 만들어 데이터베이스를 그대로두고 코드를 통해 연결할 수 없습니다. 데이터베이스가 "오프라인"인 경우 데이터베이스는 계속 사용 가능하며 몇 분 안에 되돌릴 수 있습니다.

마지막 직장에서 우리는 일년에 몇 달 동안 작동하는 일부 제품을 가지고 있었으므로 한 번에 몇 달 동안 데이터베이스를 끄거나 오프라인으로 전환하면 해당 제품을 사용하는 사람들은 데이터베이스를 알지 못했을 것입니다. 예를 들어, 제품 중 하나에 W-2 양식이 포함되어 있으므로 비즈니스의 98 %가 1 월과 2 월에 발생합니다 (대부분의 회사의 경우 1 월 첫 주까지는 데이터를 사용할 수 없으며 연방 규제 마감일은 정보는 1 월 마지막 영업일입니다). 웹 서버는 일반적으로 5 월에서 6 월까지 12 월까지 꺼졌습니다.

그 회사에는 데이터베이스의 "소유자"가있는 스프레드 시트가있었습니다. 한 사람이 제품을 담당했습니다. 다른 사람들이 테이블의 구조를 업데이트 할 수 있지만 "소유자"는 질문이있을 때 방문한 사람이었습니다. 소유자가 회사를 떠나면 (작년까지 드문 경우) 누군가가 떠나기 전에 새 소유자로 지정됩니다.

다른 회사에서는 분기별로 데이터베이스를 오프라인 상태로 만들었습니다 (예 : 월 / 분기 별보고 등). 이를 통해 누군가 "다시 프레드 프로젝트를 마치는 동안 따로 설정해야했던 jones 프로젝트"와 같은 상황에 대한 데이터베이스를 복원하고 복원 할 수 있습니다 (몇 분 소요).


멋진 미니 사례 연구, +1 !!!
RolandoMySQLDBA

@ Tanguerna : 몇 년 전에이 기능을 사용했다고 생각하지만, 이런 종류의 역할에 완벽하므로 나에게 상기시켜 주셔서 감사합니다.
모든 거래의 존
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.