Как я могу контролировать ход импорта большого файла .sql?


204

Я импортирую 7 ГБ foobar.sqlдля восстановления таблицы в локальной базе данных.

$ 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

Как я могу контролировать его прогресс?


1
Ответы на этот вопрос показывают, что это явный недостаток клиента mysql
Уильям Энтрикен

Ответы:


267

Если вы просто импортируете из файла дампа из CLI на * nix, например,

mysql -uxxx -pxxx dbname < /sqlfile.sql

затем сначала установите pipe viewer в вашей ОС, затем попробуйте что-то вроде этого:

pv sqlfile.sql | mysql -uxxx -pxxxx dbname

который покажет индикатор выполнения при запуске программы.

Это очень полезно, и вы также можете использовать его, чтобы получить оценку прогресса mysqldump.

PV сбрасывает sqlfile.sqlи передает их в MySQL (из-за оператора канала). Пока он сбрасывает, он показывает прогресс. Круто то, что mysql принимает данные только с той скоростью, с которой они могут их обрабатывать, поэтому pv может показать ход импорта. У меня нет никаких доказательств. Но, похоже, так. Я предполагаю, что используется некоторый буфер, но в какой-то момент я думаю, mysqlчто не читает больше данных, когда он все еще занят обработкой.

Скриншот Pipe Viewer


1
Я бы предположил, что mysql может иметь буфер, в который могут быть переданы некоторые данные без полной «обработки» (т. Е. Если произойдет ошибка, pv может немного переоценить то, что на самом деле входит). Но в целом так работают трубы. Это та же самая причина, по которой вы можете сделать это sudo hd /dev/sda1 | lessи не хранить весь системный раздел в памяти.
snapfractalpop

2
Во pvмногих случаях @snapfractalpop не будет слишком точным, поскольку для обработки некоторых частей SQL требуется больше времени, чем для других. Строка, представляющая собой простую вставку, будет выполняться намного быстрее, чем строка, которая создает индекс, например, в таблице, в которой уже есть много строк. Но, по грубому представлению о прогрессе, вывод должен быть полезен, если только используемый буфер чтения не mysqlявляется особенно большим (для входа 7 ГБ буфер должен быть очень большим, чтобы pvвывод вывода вообще не был полезен.
Дэвид Спиллетт

1
@DavidSpillett действительно. Ваш комментарий отражает мои чувства. По сути, PV это сырой, но эффективный. Что мне больше всего нравится в этом, так это то, насколько оно общее. Такова красота unix pipe (спасибо Макилрой).
snapfractalpop

1
@rob Это классно, чувак, не могли бы вы привести пример mysqldump?
Хосе Александр Ибарра

Очень хорошее решение! Если пароль является ручным, pv не будет ждать его отображения, хотя
Pierre de LESPINAY

27

Если вы уже начали импорт, вы можете выполнить эту команду в другом окне, чтобы увидеть текущий размер ваших баз данных. Это может быть полезно, если вы знаете общий размер импортируемого файла .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;  

Кредит: http://forums.mysql.com/read.php?108,201578,201578


В MySQL 8.0 Эталонные состояния следующее о точности:

DATA_LENGTH

Для MyISAM DATA_LENGTH - длина файла данных в байтах.

Для InnoDB DATA_LENGTH - приблизительный объем памяти, выделенный для кластеризованного индекса, в байтах. В частности, это размер кластеризованного индекса в страницах, умноженный на размер страницы InnoDB.

 

INDEX_LENGTH

Для MyISAM INDEX_LENGTH - длина индексного файла в байтах.

Для InnoDB INDEX_LENGTH - приблизительный объем памяти, выделенный для некластеризованных индексов, в байтах. В частности, это сумма размеров некластеризованного индекса в страницах, умноженная на размер страницы InnoDB.


Моя таблица теперь в 12 ГиБ в соответствии с командами из этого ответа, и все еще импортирует. Мой файл sqldump только 5 ГиБ. Мне было бы интересно объяснить это несоответствие
lucidbrot

17

Когда вы выполняете mysqldump для одной базы данных, все таблицы выводятся в алфавитном порядке.

Естественно, перезагрузка mysqldump в базу данных также будет в алфавитном порядке.

Вы могли бы просто сделать ПРОЦЕСС ШОУ; и найдите соединение с БД, в котором запущен mysqldump. Когда дамп перезагружается, соединение с БД исчезнет.

Если вы хотите знать, какие таблицы находятся в дамп-файле, запустите этот файл для foobar.sql

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

ОБНОВЛЕНИЕ 2012-05-02 13:53 EDT

Извините, что не заметил, что есть только одна таблица.

Если таблица - MyISAM, единственный способ отслеживать это с точки зрения ОС. Причина? В течение перезагрузки таблица заблокирована от записи. Что ты ищешь? Размер .MYDи .MYIфайлы. Конечно, вам нужно сравнить это с тем, какой размер таблицы был раньше на другом сервере БД, с которого вы импортировали.

Если таблица InnoDB и у вас включена innodb_file_per_table , единственный способ отслеживать это с точки зрения ОС. Причина? В течение перезагрузки таблица заблокирована от записи. Что ты ищешь? Размер .ibdфайла. Конечно, вам нужно сравнить это с тем, какой размер таблицы был раньше на другом сервере БД, с которого вы импортировали.

Если таблица InnoDB и у вас отключен innodb_file_per_table , даже точка зрения ОС не может помочь.

ОБНОВЛЕНИЕ 2012-05-02 13:56 ПО ВОСТОЧНОМУ ВРЕМЕНИ

В прошлом году я говорил об этом: как получить% прогресса для "type db.sql | mysql"

ОБНОВЛЕНИЕ 2012-05-02 14:09 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Так как стандартная запись mysqldump блокирует таблицу следующим образом:

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;

тогда нет никакого способа получить прогресс от mysql, пока не будет снята блокировка таблицы.

Если вы можете получить LOCK TABLESи UNLOCK TABLESпрокомментировать из файла дампа ...

  • если таблица MyISAM, SELECT COUNT (*) будет работать
  • если таблица InnoDB, SELECT COUNT (*), вероятно, будет замедлять / останавливать загрузку до окончания подсчета

Это сработало. Благодарю. Последний вопрос, исходя из опыта, знаете ли вы, является ли время импорта приблизительно линейным по отношению к размеру файла .MYDи .MYI?
qazwsx

1
Перезагрузка таблицы является линейной. Перестройки индекса являются линейными. Несколько лет назад это было не так, как я решил это как вопрос к MySQL ( lists.mysql.com/mysql/202489 ), и я упомянул об этом в DBA StackExchange ( dba.stackexchange.com/a/2697/877 )
RolandoMySQLDBA,

8

Каждые 2 секунды вы увидите запущенные процессы.

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

Если вы хотите, чтобы это происходило реже, добавьте, -n xгде x - количество секунд. 5 секунд будет:

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

Можете ли вы опубликовать пример вывода? Кроме того, это просто показывает процесс или действительно показывает прогресс импорта, о котором я действительно просил?
qazwsx

Это такой полезный код. Спасибо
НараяN

6

Если вы просто хотите проверить, не остановился ли он, вы можете запросить

show processlist; 

и посмотрим, что выполняется.


5

Как решение для тех, кто не может заставить работать pv или для кого он лжет. Вы можете отслеживать размер файла ibdata1 в / var / lib / mysql, который содержит данные. Это приведет к тому же размеру (или около того) размера файлов на вашем исходном сервере.

Если таблиц много, вы также можете посмотреть, как они появляются одна за другой в / var / lib / mysql / <имя базы данных>.

Я случайно использовал этот факт недавно, когда долгосрочная база данных создала файл журнала около 20G в течение трех или четырех лет. Я заметил, что передача занимала много времени, и использовал эту технику для мониторинга прогресса.

Я думаю, что маловероятно, что наступит день, когда база данных не будет включать файл где-либо или другим. Между тем, вы можете отслеживать файл, чтобы увидеть, как происходит передача. Метод, который я предложил, был тем, что вы могли бы сделать в той или иной форме с момента написания первой базы данных sql. Я никогда не собирался предполагать, что это какая-то «официальная» техника, к которой может прибегнуть ручной жокей. Это предполагает общий уровень владения компьютерами в целом и Unix в частности.


2

Если ваша БД в остальном тихая (т. Е. Не активны другие пользователи) и вы хотите просто увидеть чтение / запись, почему бы просто не сделать что-то вроде:

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

Вы увидите количество операций чтения / записи / вставки / ожидания / обновления.

Если вы вставляете, например, вы увидите что-то вроде:

Innodb_rows_inserted                          | 28958 

Где 28958 - количество строк, вставленных за ваш интервал (в моем случае 10 секунд).


1

Для того, кто ищет пример программы просмотра каналов, mysqldumpвы просто сделаете что-то вроде этого:

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

-WФлаг просто говорит р ждать первых байты прийти перед показом прогресса (после приглашения)



0

Хорошо, еще одна работа вокруг. Но это может быть худшим и неточным вариантом.

Тем не менее, вот мое решение для Windows:

Откройте диспетчер задач, нажав

CTRL + SHIFT + ESC

Скопируйте "mysqld.exe" значение скорости диска

e.g. 11mb/s

Поместите это в калькулятор, как этот: https://techinternets.com/copy_calc?do

Оцените ETA. Мой случай был:

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

Результаты:

Beg -> 11:19
ETA -> 11:31
End -> 11:39

-1

Я так удивлен, что никто не выложил «mysql -v» в качестве опции. Если он застрянет, выход остановится.


3
«Мониторинг прогресса» обычно означает попытку оценить, насколько далеко продвинулся процесс или когда он завершится, что mysql -vне принесет результатов. Кроме того, выброс 7 ГБ данных в терминал значительно замедлит восстановление.
Мустаччо

я вижу, спасибо за объяснение. это правда, выходной 7 ГБ не будет хорошо для вывода в терминал. Я предполагаю, что я использовал -v только для небольшого локального теста, где моя БД просто застряла.
DTC

2
Это предложение помогло мне точно определить проблему, какой бы непрактичной она ни была для больших файлов. (Шахта была маленькая).
Кейси Перкинс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.