Mengapa DROP DATABASE begitu lama? (MySQL)


46

Instalasi CentOS baru.

Saya menjalankan impor DB besar (file 2GB sql) dan punya masalah. Klien SSH tampaknya kehilangan koneksi dan impor tampaknya membeku. Saya menggunakan jendela lain untuk login ke mysql dan impor tampaknya sudah mati, terjebak pada tabel baris 3M tertentu.

Jadi saya mencoba

DROP DATABASE huge_db;

15-20 menit kemudian, tidak ada apa-apa. Di jendela lain, saya melakukannya:

/etc/init.d/mysqld restart

Jendela DROP DB mengirim pesan: SERVER SHUTDOWN. Kemudian saya benar-benar me-restart server fisik.

Masuk kembali ke mysql, diperiksa dan db masih di sana, berlari

DROP DATABASE huge_db;

lagi, dan lagi saya sudah menunggu sekitar 5 menit.

Sekali lagi, ini instalasi baru. Ini huge_dbadalah satu-satunya db (selain sistem dbs). Aku bersumpah aku sudah menjatuhkan db sebesar ini sebelumnya dan dengan cepat, tapi mungkin aku salah.

Saya telah berhasil menjatuhkan basis data. Butuh sekitar 30 menit. Perhatikan juga bahwa saya pikir saya salah ketika saya pikir impor mysqldump sudah mati. Koneksi terminal terputus, tapi saya pikir prosesnya masih berjalan. Saya kemungkinan besar membunuh impor mid-table (tabel baris 3M) dan mungkin 3/4 dari keseluruhan db. Itu menyesatkan bahwa "atas" menunjukkan mysql menggunakan hanya 3% dari memori, ketika sepertinya itu harus menggunakan lebih banyak.

Menjatuhkan DB akhirnya memakan waktu 30 menit, jadi, sekali lagi, saya mungkin tidak perlu me-restart server dan mungkin bisa saja menunggu DROP selesai, tapi saya tidak tahu bagaimana reaksi mysql untuk mendapatkan permintaan DROP untuk db yang sama yang diimpor melalui mysqldump.

Namun, pertanyaannya tetap, mengapa butuh 30 menit + untuk MENGHAPUS database 2GB padahal yang harus dilakukan adalah menghapus semua file db dan menghapus semua referensi ke DB dari information_schema? Apa masalahnya?

Jawaban:


73

Daripada mematikan prosesnya, akan lebih aman jika Anda melakukannya di 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 |
+-----+------+-----------+-------------------+---------+------+-------+------------------+

Permintaan dengan id 174 adalah penghapusan satu pemblokiran dari database 'contoh', jadi sebelum Anda membunuh proses apa pun terlebih dahulu, biarkan MySQL mencoba untuk menghentikan permintaan:

$ mysqladmin kill 174

Jalankan processlistperintah di atas lagi untuk mengonfirmasi bahwa itu sudah mati.

Jika ini tidak berhasil, maka Anda mungkin bisa melihat cara membunuh proses yang salah, tetapi sebelum itu Anda bisa mencoba me-restart server MySQL.

Anda juga dapat menjalankan perintah seperti 'SHOW FULL PROCESSLIST' dan 'KILL 174' di shell MySQL, misalnya jika Anda hanya menginstal klien MySQL. Poin utamanya adalah untuk menghindari mematikan proses menggunakan 'kill' di shell kecuali benar-benar diperlukan.

Secara umum Anda dapat menggunakan salah satu mysqlatau mysqladmin. Anda seharusnya tidak perlu menjalankan perintah seperti ini sesering itu; setelah Anda mulai membunuh kueri secara teratur, ada sesuatu yang pasti salah dan Anda akan lebih baik memperbaiki masalah itu (membunuh proses kueri hanya mengobati gejalanya).


1
@BugsBuggy Cara umum di mana ini dapat terjadi adalah jika proses lain (misalnya server web, atau dalam hal ini proses impor) sedang berjalan dan terhubung ke database. Ketika Anda mengeluarkan DROP DATABASEperintah, server tidak akan melanjutkan sampai semua koneksi telah ditutup.
Stefan Magnuson

11

Meskipun saya pikir proses impor telah mati, itu mungkin masih berjalan.

The DROP DATABASEperintah mungkin menunggu untuk database sampai akhir mengimpor sebelum berlari.

Jadi, daripada DROP DATABASEmemakan waktu lama, itu mungkin hanya impor.

Jika ada orang lain yang membaca ini dan mencoba untuk membatalkan impor database dan drop database, saya sarankan Anda pertama kali menemukan PID (id proses) untuk impor dan menjalankan ini dari terminal yang berbeda:

$ kill [PID]

... di mana [PID] akan menjadi PID aktual untuk proses tersebut.

Anda akan melihat impor berhenti segera jika terminal lain masih terhubung.

Anda juga bisa menjalankannya SHOW PROCESSLISTdi tab phpMyAdmin SQL. Tabel yang dihasilkan menunjukkan proses yang sedang berjalan, dan mengklik 'x' di sebelah baris yang ingin Anda bunuh harus melakukan trik.

Lalu lari

DROP DATABASE `database_name`;

Dan semuanya harus bersih.


Jawaban lain menyatakan bahwa mematikan proses di mysql lebih baik daripada melakukannya dari luar. Saya belum menguji jawaban itu, tetapi kedengarannya sangat masuk akal. Jadi saya telah menandainya sebagai "jawaban yang diterima" alih-alih yang ini.


3

Cobalah untuk memotong tabel terbesar di database Anda sebelum Anda menjatuhkannya. Saya melihat perilaku yang sangat mirip ketika bekerja dengan arsip lalu lintas firewall MySQL dan ini sangat membantu.


Menurut dokumen MySQL, "Operasi terpotong turun dan buat kembali tabel, yang jauh lebih cepat daripada menghapus baris satu per satu", jadi tidak ada gunanya memotong untuk drop - dev.mysql.com/doc/refman/8.0/en/ truncate-table.html
ejoubaud


3

Saya menghadapi masalah yang sama. Tapi kali ini saya memeriksa daftar proses show; katanya memeriksa izin untuk waktu yang lebih lama. Kemudian saya menemukan bahwa mysqld_safe sedang berjalan sebagai root sedangkan izin level folder hanya untuk pengguna mysql. Oleh karena itu saya membunuh permintaan, tentu saja butuh waktu lama mengatakan itu dalam keadaan terbunuh tetapi saya menunggu untuk bereaksi kemudian membunuh permintaan dan mengubah izin tingkat folder untuk me-root juga dengan menambahkannya ke grup dan chmod ke 770. Kemudian saya mengeksekusi drop database yang sama bla; itu berhasil bagi saya dalam 2 detik untuk database 20GB.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.