DROP DATABASE neden bu kadar uzun sürüyor? (MySQL)


46

Yeni CentOS kurulumu.

Büyük bir DB (2GB sql dosyası) ithalatı çalıştırıyordum ve bir sorunla karşılaştım. SSH müşterisi bağlantıyı kopardı ve ithalat donuyor gibiydi. MySQL oturum açmak için başka bir pencere kullandım ve ithalat, belirli bir 3M satır masasında sıkışmış, ölü gibi görünüyordu.

Bu yüzden denedim

DROP DATABASE huge_db;

15-20 dakika sonra, hiçbir şey. Başka bir pencerede yaptım:

/etc/init.d/mysqld restart

DROP DB penceresi mesajlandı: SUNUCU KAPATMASI. Sonra fiziksel sunucuyu yeniden başlattım.

MySQL'e tekrar giriş yaptım, kontrol ettim ve db hala oradaydı.

DROP DATABASE huge_db;

tekrar ve yine 5 dakika bekliyorum.

Bir kez daha, yeni kurulum. huge_db(Sistem DBS dışında) sadece db. Yemin ederim, bu kadar önce ve sonra db'leri bu kadar büyük düşürdüm, ama belki yanılıyorum.

Veritabanını başarıyla düşürdüm. 30 dakika gibi bir şey aldı. Ayrıca, mysqldump içe aktarmanın öldüğünü düşündüğümde yanıldığımı düşündüğümü de unutmayın. Terminal bağlantısı koptu, ancak işlemin hala devam ettiğini düşünüyorum. Büyük olasılıkla ithalat orta masasını (3M sıra tablosu) ve muhtemelen db boyunca yolun 3/4'ünü öldürdüm. "Top" un daha fazla kullanması gerektiğine benzeyen belleklerin sadece% 3'ünü kullanarak mysql göstermesi yanıltıcıydı.

DB'nin bırakılması 30 dakika sürdü, bu yüzden yine sunucuyu yeniden başlatmam gerekmeyebilirdi ve muhtemelen DROP'un bitmesini beklemiş olabilirdim, ancak mysql'in DROP sorgusu almak için nasıl tepki vereceğini bilmiyorum. Aynı db, mysqldump ile aktardığı.

Yine de, soru hala devam ediyor, neden tek yapmanız gereken tüm db dosyalarını silmek ve DB'ye tüm referansları info_schema'dan kaldırmak olduğu zaman neden 2GB'lık bir veritabanını DROP'a çekmek 30 dakika + alıyor? Problem ne?

Yanıtlar:


73

Süreci öldürmek yerine, eğer MySQL içinde yapsaydınız daha güvenli olurdu:

$ 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 |
+-----+------+-----------+-------------------+---------+------+-------+------------------+

174 no'lu sorgu, 'example' veritabanının blokajını siler. Bu nedenle, herhangi bir işlemi öldürmeden önce MySQL'in sorguyu sonlandırmaya çalışmasına izin verin:

$ mysqladmin kill 174

Öldüğünü processlistonaylamak için yukarıdaki komutu tekrar çalıştırın .

Bu işe yaramazsa, belki de hatalı işlemi öldürmeye bakabilirsiniz, ancak bundan önce MySQL sunucusunu yeniden başlatmayı deneyebilirsiniz.

MySQL kabuğunda 'SHOW FULL PROCESSLIST' ve 'KILL 174' gibi komutları da çalıştırabilirsiniz, örneğin yalnızca MySQL istemcisine sahipseniz. Asıl mesele, kesinlikle gerekli olmadıkça, kabuktaki 'kill' yöntemini kullanarak işlemi öldürmekten kaçınmaktır.

Genel olarak konuşursanız ya mysqlda kullanabilirsiniz mysqladmin. Buna rağmen çoğu zaman bu gibi komutlar çalıştırmanıza gerek yoktur; Sorguları düzenli olarak öldürmeye başladığınızda bir şey kesinlikle yanlıştır ve bu sorunu çözmekten daha iyi olursunuz (sorgu işlemini öldürmek sadece belirtiyi tedavi etmek demektir).


1
@BugsBuggy Başka bir işlem (örneğin bir web sunucusu veya bu durumda bir içe aktarma işlemi) çalışıyorsa ve veritabanına bağlıysa, bunun ortaya çıkabileceği yaygın bir yoldur. Eğer kesilirken DROP DATABASEkomutu tüm bağlantıların kapatılıncaya kadar sunucu devam etmeyecektir.
Stefan Magnuson,

11

İthalat işleminin öldüğünü düşündüğüm halde muhtemelen devam ediyordu.

DROP DATABASEKomut muhtemelen ran önce ithal bitirmek için veritabanı için bekledi.

Yani, DROP DATABASEuzun zaman almak yerine , muhtemelen sadece ithalat oldu.

Başkası bunu okursa ve bir veritabanını içe aktarıp veritabanını iptal etmeye çalışıyorsa ve veritabanını bırakmayı deniyorsa, önce içe aktarma için PID'yi (işlem kimliği) bulup bunu farklı bir terminalden çalıştırmanızı öneririz:

$ kill [PID]

... [PID] işlem için gerçek PID olacaktır.

Diğer terminal hala bağlıysa, derhal alma işlemini durdurmalısınız.

Ayrıca SHOW PROCESSLISTphpMyAdmin SQL sekmesinde de çalıştırabilirsiniz . Sonuçta ortaya çıkan tablo çalışan işlemleri gösterir ve öldürmek istediğiniz satırın yanındaki 'x' işaretini tıklamanız gerekir.

O zaman koş

DROP DATABASE `database_name`;

Ve her şey temiz olmalı.


Bir başka cevap, süreci mysql içinde öldürmenin, onu dışarıdan yapmaktan daha iyi olduğunu ileri sürdü. Bu cevabı test etmedim, ancak çok makul görünüyor. Bu yüzden bunun yerine "kabul edilmiş cevap" olarak işaretledim.


3

Bırakmadan önce youra veritabanındaki en büyük tabloları kesmeye çalışın. Güvenlik duvarı trafiğinin MySQL arşivleriyle çalışırken çok benzer bir davranış gördüm ve bu çok yardımcı oldu.


MySQL belgelerine göre, "Kesikli işlemler, satırları birer birer silmekten çok daha hızlı olan tabloyu düşürür ve yeniden yaratır", bu nedenle bırakmanın kesilmesinin anlamı yoktur - dev.mysql.com/doc/refman/8.0/tr/ truncate-table.html
ejoubaud


3

Ben de aynı problemle karşılaştım. Fakat bu sefer şov işlem listesini kontrol ettim; daha uzun süre izinlerin kontrol edildiğini söyledi. Sonra mysqld_safe'nin root olarak çalıştığını ve klasör seviyesi izinlerinin sadece mysql kullanıcıları için olduğunu gördüm. Bu yüzden sorguyu öldürdüm, tabi ki uzun süredir öldürüldüğünü söylemiştim ama tepki vermesini bekledim, daha sonra sorguyu öldürdüm ve grup düzeyine ekleyerek ve 770'e chmod ekleyerek klasör düzeyinde izinleri değiştirdim. Sonra idam ettim. Aynı damla veritabanı filan; 20GB veritabanı için 2 saniye içinde benim için çalıştı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.