it-swarm-eu.dev

Proč DROP DATABASE trvá tak dlouho? (MySQL)

Nová instalace CentOS.

Spustil jsem import velké DB (soubor 2 GB sql) a měl jsem problém. Zdá se, že klient SSH ztratil připojení a zdálo se, že import zamrzl. Použil jsem další okno pro přihlášení k mysql a import vypadal mrtvý, přilepený na konkrétní 3M řádkovou tabulku.

Tak jsem to zkusil

DROP DATABASE huge_db;

O 15-20 minut později nic. V dalším okně jsem udělal:

/etc/init.d/mysqld restart

Okno DROP DB zaslalo zprávu: SERVER SHUTDOWN. Poté jsem fyzicky server restartoval.

Přihlášen zpět do mysql, zkontrolován a db tam byl pořád, běžel

DROP DATABASE huge_db;

znovu a znovu čekám už asi 5 minut.

Opět je to čerstvá instalace. The huge_db je jediný db (jiný než systémové dbs). Přísahám, že jsem předtím a rychle odhodil db, ale možná se mýlím.

Úspěšně jsem zrušil databázi. Trvalo to asi 30 minut. Také si všimněte, že jsem se mýlil, když jsem si myslel, že import mysqldump byl mrtvý. Koncové připojení bylo ztraceno, ale myslím, že proces stále běží. S největší pravděpodobností jsem zabil importovanou střední tabulku (3M řádkovou tabulku) a pravděpodobně 3/4 cesty skrz celou db. Bylo zavádějící, že „top“ ukázal, že mysql využívá pouze 3% paměti, když se zdálo, že by měl používat více.

Vypuštění DB skončilo po 30 minutách, takže jsem znovu nemusel restartovat server a možná bych mohl jen čekat na dokončení DROP, ale nevím, jak by mysql reagoval na získání dotazu DROP pro stejný db, který importuje přes mysqldump.

Stále zůstává otázkou, proč trvá 30min +, než DROP 2GB databázi ztratí, když vše, co by mělo udělat, je odstranit všechny soubory db a odstranit všechny odkazy na DB z information_schema? Co je velký problém?

49
Buttle Butkus

Spíše než zabití procesu by bylo bezpečnější, kdybyste to udělali v 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 |
+-----+------+-----------+-------------------+---------+------+-------+------------------+

Dotaz s ID 174 je blokačním odstraněním „vzorové“ databáze, takže než zabijete jakékoli procesy, nejprve nechte MySQL pokusit se dotaz ukončit:

$ mysqladmin kill 174

Znovu spusťte příkaz processlist výše a potvrďte, že byl zabit.

Pokud to nefunguje, možná byste se mohli podívat na zabití procesu errant, ale předtím byste se mohli pokusit restartovat server MySQL.

V prostředí MySQL můžete také spouštět příkazy jako 'SHOW FULL PROCESSLIST' a 'KILL 174', například pokud máte nainstalovaného pouze klienta MySQL. Hlavním bodem je vyhnout se zabíjení procesu pomocí 'kill' ve Shell, pokud to není nezbytně nutné.

Obecně lze použít buď mysql nebo mysqladmin. Neměli byste však často spouštět podobné příkazy; jakmile začnete pravidelně zabíjet dotazy, je něco rozhodně špatně a vy byste měli být lépe napravit tento problém (zabíjení procesu dotazu pouze řeší příznak).

80
Stefan Magnuson

Přestože jsem si myslel, že proces importu zemřel, pravděpodobně to stále probíhalo.

Příkaz DROP DATABASE Pravděpodobně čekal na dokončení importu databáze před spuštěním.

Takže namísto toho, aby DROP DATABASE Trvalo dlouhou dobu, pravděpodobně to byl jen import.

Pokud to někdo přečte a pokouší se zrušit import databáze a zrušit databázi, doporučujeme nejprve najít PID (id procesu) pro import a spustit jej z jiného terminálu:

$ kill [PID]

... kde [PID] bude skutečný PID procesu.

Pokud je druhý terminál stále připojen, měli byste okamžitě zastavit import.

Na kartě phpMyAdmin SQL můžete také spustit SHOW PROCESSLIST. Výsledná tabulka ukazuje běžící procesy a kliknutí na „x“ vedle řádku, který chcete zabít, by mělo udělat trik.

Pak běžte

DROP DATABASE `database_name`;

A všechno by mělo být čisté.


Další odpověď navrhla, že zabití procesu v mysql je lepší než dělat to zvenčí. Tuto odpověď jsem netestoval, ale zní velmi věrohodně. Takže místo této jsem ji označil jako „přijímanou odpověď“.

11
Buttle Butkus

Pokuste se oříznout největší tabulky ve vaší databázi, než ji pustíte. Při práci s archivy MySQL firewallu jsem viděl velmi podobné chování, což nesmírně pomohlo.

3
Tim Brigham

Čelil jsem stejnému problému. Tentokrát jsem však zkontroloval seznam procesů; řekla, že bude kontrolovat povolení na delší dobu. Pak jsem zjistil, že mysqld_safe běží jako root, zatímco oprávnění na úrovni složky je pouze pro uživatele mysql. Proto jsem zabil dotaz, samozřejmě, že to trvalo dlouho říkat jeho v zabitém stavu, ale čekal jsem, až na to odpoví, pak to zabil dotaz a změnil oprávnění na úrovni složky na root také přidáním do skupiny a chmod na 770. Pak jsem provedl stejný pokles databáze bla; fungovalo to pro mě za 2 sekundy pro 20GB databázi.

3
Mannoj

První věc, která přijde na mysl, je stav Checking Permissions...

Když vydáte DROP DATABASE mydb; Je zkontrolováno vše uvnitř/var/lib/mysql/mydb, aby se zjistilo, zda existují oprávnění OS pro právo zrušit každý soubor.

Někteří si mysleli, že snížení počtu uživatelů mysql může pomoci

3
RolandoMySQLDBA