Могу ли я восстановить одну таблицу из полного файла 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.