แนวทางปฏิบัติที่ดีที่สุดสำหรับการลบฐานข้อมูลอย่างถาวรคืออะไร


10

เรามีสภาพแวดล้อมที่ "เป็นธรรมชาติ" ซึ่งหมายถึงผู้คนวางโค้ดบนโค้ดเป็นเวลาสิบปีโดยมีการกำกับดูแลหรือเอกสารน้อยที่สุด เซิร์ฟเวอร์ที่ฉันใช้มีฐานข้อมูลหลายอย่างซึ่งฉันเชื่อว่าไม่ได้ใช้งานอีกต่อไป ฉันชอบที่จะลบพวกเขาและปล่อยให้ทั้งสามที่ฉันใช้จริง

ที่สุดโต่งเสี่ยงฉันสามารถปิดการใช้งานฐานข้อมูลเหล่านี้และรอให้ใครบางคนกรีดร้อง; ที่อื่นฉันสามารถปล่อยให้พวกเขาทำงานตลอดไป "ในกรณี" คุณพบว่าขั้นตอนใดมีค่าในการระบุว่ากำลังใช้เซิร์ฟเวอร์อยู่หรือไม่และอย่างไร

นอกจากนี้คุณจะแนะนำขั้นตอนใดเพื่อให้แน่ใจว่าในขณะที่มีการดำเนินการต่อไปในระบบปิดการใช้งานพวกเขายังคงสามารถย้อนกลับได้อย่างสะดวกเป็นระยะเวลาหนึ่ง (เช่นเปลี่ยนชื่อวัตถุแทนการลบทิ้ง)

ขอบคุณ!


1
นี่เป็นคำถามที่ชาญฉลาดสำหรับทุกวัย +1 สำหรับคำถามดังกล่าว ฉันหวังว่าคำถามนี้นำมาซึ่งการตอบสนองที่ดีกว่าเนื่องจาก DBAs ควรเผชิญกับสถานการณ์นี้ในอาชีพของพวกเขาในไม่ช้า
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 DBAs ควรจะตอบคำถามของพวกเขาที่นี่เช่นกันเนื่องจากแนวคิดของ schema ที่เป็นคอลเลกชันภายในอินสแตนซ์ฐานข้อมูลนั้นเบลอใน MySQL แต่ปฏิบัติตามอย่างเคร่งครัดใน SQLServer และ Oracle


เคล็ดลับที่ดีมาก ฉันจะรวบรวมชุดคำสั่งเพื่อติดตามการอัปเดต เพื่อประโยชน์ของคนรุ่นอนาคตต่อไปนี้เป็นข้อความค้นหาในระดับสคีมาสำหรับ 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

คุณสามารถลองตั้งค่าการติดตามที่จับการเชื่อมต่อและฐานข้อมูลที่เชื่อมต่อ ฉันจะปล่อยให้การทำงานนี้เล็กน้อยแล้วตรวจสอบให้แน่ใจว่าไม่มีอะไรเชื่อมต่อกับมัน

ปัญหาหนึ่งที่เกิดขึ้นคือถ้าคุณมีรหัสเปิดบน master db แต่มีการเรียก DB อื่นภายในรหัส ฉันไม่แน่ใจว่ารหัสนั้นแย่แค่ไหนที่ชี้ไปยังฐานข้อมูลของคุณ

ฉันจะค้นหางานทั้งหมดของคุณและตรวจสอบให้แน่ใจว่าไม่มีใครชี้ไปที่ฐานข้อมูลนั้น

คุณสามารถใช้การตรวจสอบ SQL ได้หากคุณมี SQL เวอร์ชันที่เหมาะสม (องค์กร 2008 R2)

คุณสามารถใช้ทริกเกอร์การเข้าสู่ระบบเพื่อปรับปรุงตารางเมื่อมีคนเข้าสู่ฐานข้อมูลนั้น นี่จะแสดงให้คุณเห็นหากมีสิ่งใดเชื่อมต่อกับฐานข้อมูลนั้น


คำตอบที่ดีมากโดยเฉพาะอย่างยิ่งเกี่ยวกับการเข้าสู่ระบบเรียก !!! MySQL ไม่มีอะไรแบบนั้นแม้ว่าฉันจะเลียนแบบได้ด้วยการเปิดใช้งานบันทึกทั่วไปและตรวจสอบที่อยู่ IP และฐานข้อมูลที่ระบุ ของคุณคือ +1 !!!
RolandoMySQLDBA

4

นอกจากนี้คุณจะแนะนำขั้นตอนใดเพื่อให้แน่ใจว่าในขณะที่มีการเดินหน้าต่อไปในระบบปิดการใช้งาน

ใน SQL Server คุณสามารถใช้ฐานข้อมูล " ออฟไลน์ " ซึ่งทำให้มีฐานข้อมูลอยู่ แต่ทำให้ไม่สามารถเชื่อมต่อกับรหัสผ่านได้ หากฐานข้อมูลเป็น "ออฟไลน์" จะยังคงมีอยู่และสามารถย้อนกลับได้ภายในไม่กี่นาที

ในงานสุดท้ายของฉันเรามีผลิตภัณฑ์บางอย่างที่เปิดดำเนินการเป็นเวลาหลายเดือนต่อปีดังนั้นการปิดหรือออฟไลน์ฐานข้อมูลสำหรับเดือนละครั้งจะไม่ถูกสังเกตเห็นโดยคนที่ทำงานกับผลิตภัณฑ์นั้น เป็นหนึ่งในตัวอย่างหนึ่งในผลิตภัณฑ์ที่เกี่ยวข้องกับรูปแบบ W-2 ดังนั้น 98% ของธุรกิจที่เกิดขึ้นในเดือนมกราคมและกุมภาพันธ์ (สำหรับ บริษัท ส่วนใหญ่ข้อมูลจะไม่สามารถใช้ได้จนกว่าจะถึงสัปดาห์แรกของเดือนมกราคมและกำหนดเส้นตายของรัฐบาลกลางสำหรับการยื่น ข้อมูลเป็นวันทำการสุดท้ายของเดือนมกราคม) เว็บเซิร์ฟเวอร์มักจะปิดตั้งแต่พฤษภาคม / มิถุนายนจนถึงธันวาคม

ที่ บริษัท นั้นเรามีสเปรดชีตที่มี "เจ้าของ" ของฐานข้อมูล - คนเดียวที่รับผิดชอบผลิตภัณฑ์ ในขณะที่คนอื่นสามารถทำการปรับปรุงโครงสร้างของตาราง "เจ้าของ" เป็นคนที่ไปเมื่อมีคำถามใด ๆ จะต้องถาม หากเจ้าของออกจาก บริษัท (หายากจนถึงปีที่แล้ว) จะมีคนได้รับมอบหมายให้เป็นเจ้าของคนใหม่ก่อนที่พวกเขาจะจากไป

ที่ บริษัท อื่น ๆ เราได้ทำการออฟไลน์ฐานข้อมูลไว้หนึ่งไตรมาสหากพวกเขาออฟไลน์โดยไม่ทำลาย (เช่นการรายงานรายเดือน / รายไตรมาส) พวกเขาจะได้รับการสำรองข้อมูลครั้งสุดท้ายและถูกลบ สิ่งนี้อนุญาตให้ใครบางคนกลับมาและกู้คืนฐานข้อมูล (ซึ่งใช้เวลาสองสามนาที) สำหรับสถานการณ์เหล่านั้นที่มีเรื่องราวเช่น "โอ้นั่นเป็นโครงการโจนส์ที่เราต้องตั้งไว้ในขณะที่โครงการเฟร็ดเสร็จแล้ว"


กรณีศึกษาขนาดเล็กที่ดี +1 !!!
RolandoMySQLDBA

@Tanguerna: ฉันคิดว่าฉันใช้คุณสมบัตินี้เมื่อหลายปีก่อน แต่มันเหมาะสำหรับบทบาทแบบนี้ขอบคุณมากที่เตือนฉัน
Jon of All Trades
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.