Могу ли я восстановить одну таблицу из полного файла mysql mysqldump?


194

У меня есть резервная копия mysqldump моей базы данных mysql, состоящей из всех наших таблиц, которая составляет около 440 мегабайт. Я хочу восстановить содержимое только одной из таблиц формы mysqldump. Это возможно? Теоретически, я мог бы просто вырезать раздел, который перестраивает таблицу, которую я хочу, но я даже не знаю, как эффективно редактировать текстовый документ такого размера.


2
FWIW, вы также можете использовать mydumper . Это создает логический дамп, такой как mysqldump, но он выводит отдельные файлы для каждой таблицы и может выполнять как дамп, так и загрузку многопоточную, поэтому занимает меньше времени.
— Билл Карвин

Ответы:


290

Вы можете попробовать использовать sed, чтобы извлечь только ту таблицу, которую вы хотите.

Допустим, имя вашей таблицы mytableи файл mysql.dump - это файл, содержащий ваш огромный дамп:

$ sed -n -e '/CREATE TABLE.*`mytable`/,/CREATE TABLE/p' mysql.dump > mytable.dump

Это скопирует в файл mytable.dumpто, что находится между CREATE TABLE mytableследующей и следующей, CREATE TABLEсоответствующей следующей таблице.

Затем вы можете настроить файл, mytable.dumpкоторый содержит структуру таблицы mytableи данные (список INSERT).


5
Это даже лучше, чем мой ответ, так как он также заботится о CREATE TABLE, но вы должны искать с обратными кавычками, чтобы не получить другую таблицу с именем "thisismytabletoo".
— JCCyC

1
Правда. Я не был уверен, что имена таблиц во всех дампах mysql всегда заключены в кавычки или возможно также использование CREATE TABLE mytable. Мы можем легко адаптировать первое регулярное выражение, если знаем, как выглядит дамп. Вторая проблема может быть, если таблица mytable не уникальна (одна в базе данных db1, а другая в базе данных db2). Оба будут экспортированы в файл mytable.dump. Если таблица не уникальна, мы можем использовать ту же команду sed, сначала с CREATE DATABASE, чтобы извлечь только нужную базу данных. Затем используйте команду sed с CREATE TABLE.
— uloBasEI

13
Сладкий! Не забудьте добавить DROP TABLE вверху и удалить DROP TABLE [следующая таблица] внизу файла.
— Натан

20
Чтобы не добавлять / удалять DROP TABLE, более полезно сопоставлять по Table structure for tableкомментарию, а не сопоставлять по CREATE TABLE. Это гарантирует, что следующая таблица не будет удалена, если кто-то забудет удалить ее оператор DROP TABLE, и позволит использовать конвейер для восстановления таблицы с одной командой (gzip | sed | mysql). Однако это решение зависит от синтаксиса комментариев mysqldump (я не знаю, насколько он стандарт).
— Olexa

12
С модификацией Olexa это прекрасно: sed -n -e '/ Структура таблицы для. * `Mytable /, / Структура таблицы для / p' whole.sql> mytable.sql
— deeenes

120

Я использовал модифицированную версию команды sed uloBasEI. Он включает в себя предыдущую команду DROP и читает, пока mysql не выполнит сброс данных в вашу таблицу (UNLOCK). У меня работал (ре) импорт wp_users на кучу сайтов Wordpress.

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' mydump.sql > tabledump.sql

3
на самом деле это гораздо лучшее решение, чем выбранное в качестве ответа выше. Не могу поверить, что не получил больше голосов.
— 13:30

9
Я предлагаю добавить как минимум кавычки в название таблицы: `mytable`чтобы избежать совпадения таблиц mytable2и т. Д., Как было в моем случае.
— bartekbrak

3
Вы только что спасли мою задницу
— Габриэль Alack

1
@ user706420 Хм, ты уверен, что твой терминал не виноват? sedне должно мешать кодированию ...
— bryn

6
Для тех, у кого файлы SQL не содержат DROP TABLE(у моего дампа MySQL этого не было) может потребоваться использовать: здесь sed -n -e '/-- Table structure for table ``<Table Name>/,/UNLOCK TABLES/p' <SQL File> > table.sql используются комментарии к таблицам, представленные перед каждой таблицей в дампе MySQl, и обеспечиваются такие строки, как /*!40101 SET @saved_cs_client = @@character_set_client */;get include .
— hamx0r

50

Это можно сделать проще? Вот как я это сделал:

Создать временную базу данных (например, восстановить):

mysqladmin -u root -p создать восстановить

Восстановите полный дамп в базе данных temp:

mysql -u root -p restore <fulldump.sql

Дамп таблицы, которую вы хотите восстановить:

mysqldump restore mytable> mytable.sql

Импортировать таблицу в другую базу данных:

mysql -u root -p база данных <mytable.sql


2
Это то, что нужно большинству людей.
— sjas

2
Согласно этому предложению по редактированию , вы должны добавить параметр «--one-database», чтобы убедиться, что вы восстанавливаете только одну базу данных, а не уничтожаете все остальное.
— SL Barth - Восстановить Монику

7
Для действительно огромной базы данных это может быть очень странно - восстановить 150 ГБ данных для одной таблицы размером 100 МБ.
— Enyby

Я просто запустил это без "--one-database", и он все равно слил таблицы. Это не удалило мои существующие таблицы.
— Касим

1
Очень плохая практика! У меня было несколько БД в дампе, и, пытаясь восстановить только одну, удалил все остальные.
— AndreyP

11

Простым решением было бы просто создать дамп только таблицы, которую вы хотите восстановить отдельно. Вы можете использовать команду mysqldump для этого со следующим синтаксисом:

mysqldump -u [user] -p[password] [database] [table] > [output_file_name].sql

Затем импортируйте его как обычно, и он будет импортировать только выгруженную таблицу.


9

Так или иначе, любой выполняющий процесс должен будет просмотреть весь текст дампа и каким-то образом его проанализировать. Я бы просто за

INSERT INTO `the_table_i_want`

и передать вывод в MySQL. Взгляните на первую таблицу в дампе, чтобы убедиться, что вы правильно сделали INSERT.

Изменить: ОК, на этот раз получил правильное форматирование.


Я туп, что не сразу подумал о том, чтобы разоблачить это. Кажется, Grep спасает мой бекон каждый день. Два других предложения были также удачными и полностью тем, что я сделал бы без доступных чудес grep. Спасибо вам всем!
— Мёбиус

6
Если вы думаете, что любите grep, то,
— изучая

7

Вы должны попробовать команду @bryn, но с разделителем `в противном случае вы также извлечете таблицы, содержащие префикс или суффикс, это то, что я обычно делаю:

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' dump.sql > mytable.sql

Также для целей тестирования вы можете изменить имя таблицы перед импортом:

sed -n -e 's/`mytable`/`mytable_restored`/g' mytable.sql > mytable_restored.sql

Для импорта вы можете использовать команду mysql:

mysql -u root -p'password' mydatabase < mytable_restore.sql

6
  1. Резервное копирование

    $ mysqldump -A | gzip > mysqldump-A.gz
  2. Восстановить одну таблицу

    $ mysql -e "truncate TABLE_NAME" DB_NAME
    $ zgrep ^"INSERT INTO \`TABLE_NAME" mysqldump-A.gz | mysql DB_NAME
    

4

Один из возможных способов справиться с этим - восстановить временную базу данных и вывести только эту таблицу из временной базы данных. Затем используйте новый скрипт.



3
sed -n -e '/-- Table structure for table `my_table_name`/,/UNLOCK TABLES/p' database_file.sql > table_file.sql

Это лучшее решение, чем некоторые другие, описанные выше, потому что не все дампы SQL содержат DROP TABLEоператор. Этот будет работать все виды свалок.


2

Это тоже может помочь.

# mysqldump -u root -p database0 > /tmp/database0.sql
# mysql -u root -p -e 'create database database0_bkp'
# mysql -u root -p database0_bkp < /tmp/database0.sql
# mysql -u root -p database0 -e 'insert into database0.table_you_want select * from database0_bkp.table_you_want'

2

Таблица должна иметь одинаковую структуру как в дампе, так и в базе данных.

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql.tar.gz | mysql -u<user> -p<password> database_name`

или

`zgrep -a ^"INSERT INTO \`table_name" DbDump-backup.sql | mysql -u<user> -p<password> database_name`

1

Большинство современных текстовых редакторов должны иметь возможность обрабатывать текстовые файлы такого размера, если ваша система соответствует этому.

Во всяком случае, мне пришлось сделать это очень быстро, и у меня не было времени, чтобы найти какие-либо инструменты. Я установил новый экземпляр MySQL, импортировал всю резервную копию и затем выплюнул только ту таблицу, которую хотел.

Затем я импортировал эту таблицу в основную базу данных.

Это было утомительно, но довольно легко. Удачи.


1

Вы можете использовать редактор vi. Тип:

vi -o mysql.dump mytable.dump

открыть как весь дамп, так mysql.dumpи новый файл mytable.dump. Найдите нужную вставку в строку, нажав, /а затем введите фразу, например: «вставить в` mytable` ", затем скопируйте эту строку, используя yy. Переход к следующему файлу ctrl+wзатем down arrow keyвставьте скопированную строку с pp. Наконец, сохраните новый файл, набрав :wqи достаточно редактора vi :q.

Обратите внимание , что если вы сбросили данные с помощью нескольких вставок можно скопировать (дернул) все из них сразу , используя , Nyyв котором Nесть число строк , которые будут скопированы.

Я сделал это с файлом размером 920 МБ.


0

Получить хороший текстовый редактор, как Notepad ++ или Vim (если вы уже владеете им). Найдите имя таблицы, и вы сможете выделить только команды CREATE, ALTER и INSERT для этой таблицы. Навигация может быть проще с помощью клавиатуры, а не мыши. И я бы позаботился о том, чтобы у вас было достаточно памяти или ОЗУ, чтобы не было проблем с загрузкой всего файла сразу. Как только вы выделите и скопируете нужные вам строки, было бы неплохо сделать резервную копию только скопированной части в свой собственный файл резервной копии, а затем импортировать ее в MySQL.


1
Это на самом деле очень легко сделать и понятно даже новичкам. Я не знаю, почему за это проголосовали.
— Карл Йохан Валлнер

0

Блоки SQL блокируются с помощью «Структура таблицы для таблицы my_table» и «Сброс данных для таблицы my_table».

Вы можете использовать командную строку Windows следующим образом, чтобы получить номера строк для различных разделов. Настройте искомую строку по мере необходимости.

найти / n "для таблицы` "sql.txt

Будет возвращено следующее:

---------- SQL.TXT

[4384] - Структура таблицы для таблицы my_table

[4500] - Сброс данных для таблицы my_table

[4514] - Структура стола для стола some_other_table

... и т.д.

Это даст вам номера строк, которые вам нужны ... сейчас, если бы я только знал, как их использовать ... расследование.


0

Еще в 2008 году мне тоже нужно было это сделать. Я написал Perl-скрипт, который это сделает, и теперь это мой метод выбора. Также кратко изложено, как сделать это в awk или как восстановить в другом месте и извлечь. Недавно я добавил этот метод sed в список. Вы можете найти скрипт и другие методы здесь: http://blog.tsheets.com/2008/tips-tricks/extract-a-single-table-from-a-mysqldump-file.html



0

Упомянутые ранее решения «sed» хороши, но, как уже упоминалось, не на 100% безопасны

  • У вас могут быть команды INSERT с данными, содержащими: ... CREATE TABLE ... (что угодно) ... mytable ...

  • или даже точную строку "CREATE TABLE` mytable`; " например, если вы храните команды DML!

(и если таблица огромная, вы не хотите проверять это вручную)

Я бы проверил точный синтаксис используемой версии дампа и провел бы более строгий поиск по шаблону:

Избегайте ". *" И используйте "^", чтобы убедиться, что мы начинаем с начала строки. И я бы предпочел взять начальный «DROP»

В целом, это работает лучше для меня:

sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.