เหตุใดฐานข้อมูล DROP จึงใช้เวลานานมาก (MySQL)


46

ใหม่การติดตั้ง CentOS

ฉันกำลังเรียกใช้การนำเข้าฐานข้อมูลขนาดใหญ่ (ไฟล์ 2GB sql) และมีปัญหา ไคลเอ็นต์ SSH ดูเหมือนจะสูญเสียการเชื่อมต่อและการนำเข้าดูเหมือนจะหยุดชะงัก ฉันใช้หน้าต่างอื่นเพื่อเข้าสู่ mysql และการนำเข้าดูเหมือนจะตายติดอยู่ในตารางแถว 3M โดยเฉพาะ

ดังนั้นฉันจึงพยายาม

DROP DATABASE huge_db;

15-20 นาทีต่อมาไม่มีอะไร ในหน้าต่างอื่นฉันทำ:

/etc/init.d/mysqld restart

หน้าต่าง DROP DB ส่งข้อความ: SERVER SHUTDOWN จากนั้นฉันก็รีสตาร์ทฟิสิคัลเซิร์ฟเวอร์

กลับเข้าสู่ mysql ตรวจสอบและ db ยังคงมีอยู่วิ่ง

DROP DATABASE huge_db;

อีกครั้งและอีกครั้งฉันรอประมาณ 5 นาที

เป็นการติดตั้งใหม่อีกครั้ง huge_dbเป็นฐานข้อมูลเท่านั้น (นอกเหนือจากดีบีเอสระบบ) ฉันสาบานว่าฉันทิ้ง db ของขนาดใหญ่นี้มาก่อนและอย่างรวดเร็ว แต่บางทีฉันผิด

ฉันทำฐานข้อมูลสำเร็จแล้ว ใช้เวลาประมาณ 30 นาที โปรดทราบด้วยว่าฉันคิดว่าฉันเข้าใจผิดเมื่อฉันคิดว่าการนำเข้า mysqldump นั้นตายไปแล้ว การเชื่อมต่อเทอร์มินัลหายไป แต่ฉันคิดว่ากระบวนการยังทำงานอยู่ ฉันน่าจะฆ่าการนำเข้าโต๊ะกลาง (ตารางแถว 3M) และอาจ 3/4 ของทางผ่านฐานข้อมูลทั้งหมด มันทำให้เข้าใจผิดว่า "top" แสดง mysql โดยใช้หน่วยความจำเพียง 3% เมื่อมันดูเหมือนว่าควรใช้มากกว่านี้

การทิ้งฐานข้อมูลจบลงด้วยการใช้เวลา 30 นาทีดังนั้นอีกครั้งฉันอาจไม่ต้องรีสตาร์ทเซิร์ฟเวอร์และอาจรอให้ DROP เสร็จสิ้น แต่ฉันไม่รู้ว่า mysql จะตอบสนองต่อการสอบถาม DROP ได้อย่างไร db เดียวกันกับที่มันกำลังนำเข้าผ่าน mysqldump

ยังคงคำถามยังคงอยู่ทำไมถึงใช้เวลา 30 นาที + ถึง DROP ฐานข้อมูล 2GB เมื่อสิ่งที่ต้องทำคือลบไฟล์ db ทั้งหมดและลบการอ้างอิงทั้งหมดไปยัง DB จาก information_schema? เรื่องใหญ่อะไร

คำตอบ:


73

แทนที่จะฆ่ากระบวนการมันจะปลอดภัยกว่าถ้าคุณทำใน MySQL:

$ mysqladmin processlist -u root -p
Enter password: 
+-----+------+-----------+-------------------+---------+------+-------+------------------+
| Id  | User | Host      | db                | Command | Time | State | Info             |
+-----+------+-----------+-------------------+---------+------+-------+------------------+
| 174 | root | localhost | example           | Sleep   | 297  |       |                  |
| 407 | root | localhost |                   | Query   | 0    |       | show processlist |
+-----+------+-----------+-------------------+---------+------+-------+------------------+

แบบสอบถามที่มี id 174 เป็นหนึ่งในการปิดกั้นการลบฐานข้อมูล 'ตัวอย่าง' ดังนั้นก่อนที่คุณจะฆ่ากระบวนการใด ๆ ก่อนให้ MySQL พยายามที่จะยุติการสืบค้น:

$ mysqladmin kill 174

เรียกใช้processlistคำสั่งด้านบนอีกครั้งเพื่อยืนยันว่ามันถูกฆ่า

หากวิธีนี้ใช้ไม่ได้ผลคุณอาจดูที่การฆ่ากระบวนการที่ผิดพลาด แต่ก่อนหน้านั้นคุณอาจลองรีสตาร์ทเซิร์ฟเวอร์ MySQL

นอกจากนี้คุณยังสามารถเรียกใช้คำสั่งเช่น 'SHOW FULL PROCESSLIST' และ 'KILL 174' ในเปลือก MySQL ได้ตัวอย่างเช่นถ้าคุณติดตั้งไคลเอนต์ MySQL เท่านั้น ประเด็นหลักคือการหลีกเลี่ยงการฆ่ากระบวนการโดยใช้ 'kill' ในเชลล์เว้นแต่จำเป็นจริงๆ

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


1
@BugsBuggy วิธีทั่วไปที่สามารถเกิดขึ้นได้คือหากกระบวนการอื่น (เช่นเว็บเซิร์ฟเวอร์หรือในกรณีนี้กระบวนการนำเข้า) กำลังทำงานและเชื่อมต่อกับฐานข้อมูล เมื่อคุณออกDROP DATABASEคำสั่งเซิร์ฟเวอร์จะไม่ดำเนินการต่อจนกว่าการเชื่อมต่อทั้งหมดจะถูกปิด
Stefan Magnuson

11

แม้ว่าฉันคิดว่ากระบวนการนำเข้าเสียชีวิต แต่ก็อาจยังทำงานอยู่

DROP DATABASEคำสั่งอาจจะรอสำหรับฐานข้อมูลที่จะเสร็จสิ้นก่อนที่จะนำเข้ามันวิ่ง

ดังนั้นแทนที่จะDROP DATABASEใช้เวลานานอาจเป็นเพียงการนำเข้า

หากใครอ่านสิ่งนี้และพยายามที่จะยกเลิกการนำเข้าฐานข้อมูลและปล่อยฐานข้อมูลฉันขอแนะนำให้คุณหา PID (รหัสกระบวนการ) สำหรับการนำเข้าและเรียกใช้จากเทอร์มินัลอื่น:

$ kill [PID]

... โดยที่ [PID] จะเป็น PID จริงสำหรับกระบวนการ

คุณควรเห็นการหยุดการนำเข้าทันทีหากสถานีอื่นยังคงเชื่อมต่ออยู่

คุณสามารถเรียกใช้SHOW PROCESSLISTในแท็บ phpMyAdmin SQL ตารางผลลัพธ์แสดงกระบวนการที่กำลังทำงานอยู่และการคลิก 'x' ถัดจากแถวที่คุณต้องการฆ่าควรทำเคล็ดลับ

จากนั้นเรียกใช้

DROP DATABASE `database_name`;

และทุกอย่างต้องสะอาด


คำตอบอีกข้อเสนอแนะว่าการฆ่ากระบวนการภายใน mysql นั้นดีกว่าการทำจากภายนอก ฉันยังไม่ได้ทดสอบคำตอบนั้น แต่ฟังดูน่าเชื่อถือมาก ดังนั้นฉันจึงทำเครื่องหมายว่าเป็น "คำตอบที่ยอมรับ" แทนคำตอบนี้


3

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


อ้างอิงจากเอกสารของ MySQL, "ตัดการดำเนินการทิ้งและสร้างตารางใหม่ซึ่งเร็วกว่าการลบแถวทีละหนึ่ง" ดังนั้นจึงไม่มีประเด็นใดที่จะตัดทอนให้ดรอป - dev.mysql.com/doc/refman/8.0/en/ truncate-table.html
ejoubaud

3

สิ่งแรกที่อยู่ในใจคือสถานะ Checking Permissions...

เมื่อคุณออกDROP DATABASE mydb;ทุกอย่างภายใน / var / lib / mysql / mydb จะถูกตรวจสอบเพื่อดูว่าสิทธิ์ OS มีอยู่สำหรับสิทธิ์ที่จะวางทุกไฟล์

บางคนรู้สึกว่าการลดจำนวนผู้ใช้ mysql อาจช่วยได้


3

ฉันประสบปัญหาเดียวกัน แต่ครั้งนี้ฉันตรวจสอบรายการกระบวนการ; กล่าวว่าการตรวจสอบสิทธิ์เป็นเวลานาน จากนั้นฉันพบว่า mysqld_safe ทำงานเป็น root ในขณะที่สิทธิ์ระดับโฟลเดอร์นั้นมีไว้สำหรับผู้ใช้ mysql เท่านั้น ดังนั้นฉันจึงฆ่าแบบสอบถามซึ่งแน่นอนว่ามันใช้เวลานานในการบอกว่าอยู่ในสถานะถูกฆ่า แต่ฉันรอให้มันตอบสนองแล้วมันก็ฆ่าแบบสอบถามและเปลี่ยนสิทธิ์ระดับโฟลเดอร์ไปที่รูทด้วยการเพิ่มเข้าไปในกลุ่มและ chmod เป็น 770 หยดฐานข้อมูลเดียวกัน blah; มันทำงานได้ดีสำหรับฉันใน 2 วินาทีสำหรับฐานข้อมูล 20GB

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