Jak mogę monitorować postęp importu dużego pliku .sql?

204

Importuję 7 GB, foobar.sqlaby przywrócić tabelę w lokalnej bazie danych.

$ mysql -h localhost -u root 'my_data' < foobar.sql

$ mysql --version
/usr/local/mysql/bin/mysql  Ver 14.12 Distrib 5.0.96, for apple-darwin9.8.0 (i386) using readline 5.1

Jak mogę monitorować jego postęp?

qazwsx
źródło
1
Odpowiedzi na to pytanie pokazują, że jest to wyraźny brak klienta mysql
William Entriken

Odpowiedzi:

267

Jeśli tylko importujesz z pliku zrzutu z CLI na * nix, np

mysql -uxxx -pxxx dbname < /sqlfile.sql

następnie najpierw zainstaluj przeglądarkę potoków w systemie operacyjnym, a następnie spróbuj czegoś takiego:

pv sqlfile.sql | mysql -uxxx -pxxxx dbname

który pokaże pasek postępu podczas działania programu.

Jest to bardzo przydatne i można go również użyć do oszacowania postępu mysqldump.

pv zrzuca sqlfile.sqli przekazuje je do mysql (z powodu operatora potoku). Podczas dumpingu pokazuje postęp. Fajne jest to, że mysql pobiera dane tylko tak szybko, jak to możliwe, aby pv mógł pokazać postęp importu. Nie mam żadnego dowodu. Ale wydaje się, że tak. Wydaje mi się, że używany jest bufor, ale w pewnym momencie myślę, że mysqlnie czyta więcej danych, gdy jest nadal zajęty przetwarzaniem.

Zrzut ekranu przeglądarki rur

Obrabować
źródło
1
Domyślam się, że mysql może mieć bufor, w którym niektóre dane mogą być przesyłane strumieniowo, bez pełnego „przetworzenia” (tj. Jeśli wystąpi błąd, pv może nieco zawyżać to, co faktycznie dostaje). Ale ogólnie tak działają rury. To ten sam powód, dla którego możesz to zrobić sudo hd /dev/sda1 | lessi nie masz całej partycji systemowej w pamięci.
snapfractalpop
2
@ snapfractalpop pvw wielu przypadkach nie będzie zbyt dokładne, ponieważ niektóre fragmenty SQL zajmą więcej czasu niż inne. Linia, która tworzy prostą wstawkę, będzie na przykład działać znacznie szybciej niż ta, która tworzy się na indeksie w tabeli, która ma już na przykład wiele wierszy. Ale przybliżona idea postępu, wyjście powinno być pomocne, chyba że używany bufor odczytu mysqljest szczególnie duży (dla wejścia 7 Gb bufor musiałby być bardzo duży, aby pvwyjście nie było w ogóle przydatne.
David Spillett,
1
@DavidSpillett rzeczywiście. Twój komentarz odzwierciedla moje odczucia. Zasadniczo pv jest surowy, ale skuteczny. Najbardziej podoba mi się to, jak ogólnie jest. Takie jest piękno rur unixowych (dziękuję McIlroy).
snapfractalpop
1
@rob To jest wspaniały koleś, czy mógłbyś też podać przykład mysqldump?
Josue Alexander Ibarra
Bardzo fajne rozwiązanie! Jeśli hasło jest ustawione ręcznie, pv nie czeka, aż wyświetli się jego postęp
Pierre de LESPINAY
26

Jeśli już rozpocząłeś import, możesz wykonać to polecenie w innym oknie, aby zobaczyć aktualny rozmiar baz danych. Może to być pomocne, jeśli znasz całkowity rozmiar importowanego pliku .sql.

SELECT table_schema "Data Base Name", sum( data_length + index_length ) / 1024 / 1024 "Data Base Size in MiB" 
FROM information_schema.TABLES GROUP BY table_schema;  

Źródło : http://forums.mysql.com/read.php?108,201578,201578


Dokumentacja MySQL 8.0 zawiera następujące informacje na temat dokładności:

DATA_LENGTH

W przypadku MyISAM DATA_LENGTH to długość pliku danych w bajtach.

W przypadku InnoDB DATA_LENGTH jest przybliżoną ilością pamięci przydzielonej dla indeksu klastrowego w bajtach. W szczególności jest to rozmiar indeksu klastrowego na stronach pomnożony przez rozmiar strony InnoDB.

 

INDEX_LENGTH

W przypadku MyISAM INDEX_LENGTH to długość pliku indeksu w bajtach.

W przypadku InnoDB, INDEX_LENGTH jest przybliżoną ilością pamięci przydzielonej dla indeksów nieklastrowanych, w bajtach. W szczególności jest to suma rozmiarów indeksów nieklastrowanych na stronach pomnożonych przez rozmiar strony InnoDB.

Josh Grinberg
źródło
Moja tabela ma teraz 12 GiB zgodnie z poleceniami z tej odpowiedzi i nadal jest importowana. Mój plik sqldump ma tylko 5 GiB. Byłbym zainteresowany wyjaśnieniem tej rozbieżności
lucidbrot,
17

Gdy wykonujesz mysqldump pojedynczej bazy danych, wszystkie tabele są zrzucane w kolejności alfabetycznej.

Oczywiście ponowne ładowanie mysqldump do bazy danych odbywałoby się również w kolejności alfabetycznej.

Możesz po prostu zrobić POKAŻ PROCESLISTĘ; i sprawdź połączenie DB z uruchomionym programem mysqldump. Po ponownym załadowaniu zrzutu połączenie DB zniknie.

Jeśli chcesz wiedzieć, jakie tabele znajdują się w pliku zrzutu, uruchom to dla foobar.sql

cat foobar.sql | grep "^CREATE TABLE" | awk '{print $3}'

AKTUALIZACJA 2012-05-02 13:53 EDT

Przepraszamy za niedostrzeganie, że jest tylko jedna tabela.

Jeśli tabelą jest MyISAM, jedynym sposobem monitorowania jest z punktu widzenia systemu operacyjnego. Powód? Tabela jest blokowana przed zapisem podczas ponownego ładowania. Czego szukasz? Rozmiar plików .MYDi .MYI. Oczywiście należy porównać to z wielkością tabeli wcześniej na innym serwerze DB, z którego importowano.

Jeśli tabelą jest InnoDB i masz włączoną opcję innodb_file_per_table , jedynym sposobem monitorowania jest z punktu widzenia systemu operacyjnego. Powód? Tabela jest blokowana przed zapisem podczas ponownego ładowania. Czego szukasz? Rozmiar .ibdpliku Oczywiście należy porównać to z wielkością tabeli wcześniej na innym serwerze DB, z którego importowano.

Jeśli tabelą jest InnoDB i masz wyłączoną tabelę pliku_wnodb_per_table , nawet punkt widzenia systemu operacyjnego nie może pomóc.

AKTUALIZACJA 2012-05-02 13:56 EDT

W ubiegłym roku poruszyłem coś takiego: Jak uzyskać% postępu dla „type db.sql | mysql”

AKTUALIZACJA 2012-05-02 14:09 EDT

Ponieważ standardowy skrypt mysqldump blokuje tabelę w następujący sposób:

LOCK TABLES `a` WRITE;
/*!40000 ALTER TABLE `a` DISABLE KEYS */;
INSERT INTO `a` VALUES (123),(451),(199),(0),(23);
/*!40000 ALTER TABLE `a` ENABLE KEYS */;
UNLOCK TABLES;

wtedy nie ma sposobu, aby uzyskać postęp z mysql, dopóki blokada tabeli nie zostanie zwolniona.

Jeśli możesz uzyskać LOCK TABLESi UNLOCK TABLESskomentować z pliku zrzutu ...

  • jeśli tabela to MyISAM, SELECT COUNT (*) będzie działać
  • jeśli tabelą jest InnoDB, WYBIERZ LICZBĘ (*) prawdopodobnie spowolni / zatrzyma ładunek, aż do zakończenia liczenia
RolandoMySQLDBA
źródło
To się udało. Dzięki. Ostatnie pytanie dotyczy z doświadczenia, czy wiesz, czy czas importowania jest mniej więcej liniowy w odniesieniu do rozmiarów plików .MYDi .MYI?
qazwsx
1
Przeładowanie tabeli jest liniowe. Odbudowy indeksu są liniowe. Lata temu nie było tak, jak zaryzykowałem to jako pytanie do MySQL ( lists.mysql.com/mysql/202489 ) i wspomniałem o tym w DBA StackExchange ( dba.stackexchange.com/a/2697/877 )
RolandoMySQLDBA
8

Co 2 sekundy zobaczysz uruchomione procesy.

watch 'echo "show processlist;" | mysql -uuser -ppassword';

Jeśli chcesz, aby rzadziej, to dodaj -n xgdzie x oznacza liczbę sekund. 5 sekund to:

watch -n 5 'echo "show processlist;" | mysql -uuser -ppassword';
Marcelo Luiz Onhate
źródło
Czy możesz opublikować przykładowy wynik? Ponadto, czy pokazuje tylko proces, czy naprawdę wskazuje postęp importu, o który tak naprawdę prosiłem?
qazwsx
To taki pomocny kod. Dziękuję
NarayaN
6

Jeśli chcesz tylko sprawdzić, czy jest zablokowany, możesz wykonać zapytanie

show processlist; 

i zobacz, co jest wykonywane.

SCL
źródło
5

Jako rozwiązanie dla kogoś, kto nie może zmusić PV do pracy lub dla którego PV kłamie. Możesz monitorować rozmiar pliku ibdata1 w / var / lib / mysql, który zawiera dane. Skończy się to tym samym rozmiarem (lub około) rozmiaru pliku na serwerze źródłowym.

Jeśli istnieje wiele tabel, możesz także zobaczyć, jak pojawiają się one kolejno w / var / lib / mysql / <nazwa bazy danych>.

Zdarzyło mi się korzystać z tego faktu niedawno, gdy długoterminowa baza danych utworzyła plik dziennika o wielkości około 20G przez okres trzech lub czterech lat. Zauważyłem, że przeniesienie trwało wieki i wykorzystałem tę technikę do monitorowania postępów.

Myślę, że jest mało prawdopodobne, aby nadejdzie dzień, kiedy baza danych nie będzie zawierać żadnego pliku. Tymczasem możesz monitorować plik, aby zobaczyć, jak przebiega transfer. Metoda, którą zasugerowałem, była czymś, co można zrobić w takiej czy innej formie od czasu napisania pierwszej bazy danych SQL. Nigdy nie zamierzałem sugerować, że jest to jakaś „oficjalna” technika, na której mógłby polegać ręczny dżokej. Zakłada ogólny poziom biegłości w posługiwaniu się komputerami w ogóle, a w szczególności Uniksem.

nerak99
źródło
2

Jeśli twoja baza danych jest cicha (tzn. Nie ma innych użytkowników) i chcesz po prostu zobaczyć aktywność odczytu / zapisu, dlaczego po prostu nie zrobić czegoś takiego:

mysqladmin -h<host>-uroot -p<yourpass> extended -r -i 10 |grep 'row'

Zobaczysz liczbę odczytów / zapisów / wstawień / oczekiwań / aktualizacji.

Jeśli wstawiasz na przykład, zobaczysz coś takiego:

Innodb_rows_inserted                          | 28958 

Gdzie 28958 to liczba wierszy wstawionych dla twojego interwału (w moim przypadku 10 sekund).

użytkownik113373
źródło
1

Dla kogoś, kto szuka przykładowego podglądu potoku przy użyciu mysqldumpCiebie, zrobiłbyś coś takiego:

mysqldump -hxxx -uxxx -p dbname | pv -W > dump.sql

-WFlaga tylko mówi pv czekać na pierwszy bajt przyjść przed pokazujący postęp (po wierszu)

Mauricio Trajano
źródło
0

Możesz monitorować import w folderze \ Msql \ Data [nazwa bazy danych]

Hotcronchy
źródło
0

Ok, kolejne obejście. Ale to może być najgorsza i niedokładna opcja.

To powiedziawszy, oto moje rozwiązanie dla systemu Windows:

Otwórz Menedżera zadań naciskając

CTRL + SHIFT + ESC

Skopiuj wartość prędkości dysku „mysqld.exe”

e.g. 11mb/s

Umieść to w kalkulatorze takim jak ten: https://techinternets.com/copy_calc?do

Oszacuj ETA. Moja sprawa była:

Speed: 8 MB/s
Size: 4.9 GB
0 Hours, 11 Minutes and 29 Seconds

Wyniki:

Beg -> 11:19
ETA -> 11:31
End -> 11:39
Daniel
źródło
-1

Jestem zaskoczony, że nikt nie napisał „mysql -v” jako opcji. Jeśli utknie, wyjście zatrzyma się.

dtc
źródło
3
„Monitorowanie postępów” zwykle oznacza próbę oszacowania, jak daleko proces się posunął lub kiedy się zakończy, co mysql -vnie jest możliwe. Ponadto przesłanie 7 GB danych do terminala znacznie spowolni przywracanie.
mustaccio
rozumiem, dziękuję za wyjaśnienie. to prawda, wyjście o pojemności 7 GB nie byłoby dobre, aby wyprowadzić je do terminala. Myślę, że użycie -v było tylko dla małego lokalnego przypadku testowego, w którym mój db po prostu utknął.
dtc
2
Ta sugestia pomogła mi wskazać problem, choć może być niepraktyczny w przypadku dużych plików. (Mój był mały).
Casey Perkins