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

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


person Mobius    schedule 18.06.2009    source источник
comment
FWIW, вы также можете использовать mydumper. Это создает логический дамп, такой как mysqldump, но выводит отдельные файлы для каждой таблицы, и он может выполнять как дамп, так и загрузку в многопоточном режиме, поэтому это занимает меньше времени.   -  person Bill Karwin    schedule 01.11.2014


Ответы (21)


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

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

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

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

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

person uloBasEI    schedule 18.06.2009
comment
Это даже лучше, чем мой ответ, поскольку он также заботится о CREATE TABLE, но вы должны искать с обратными кавычками, чтобы не получить другую таблицу с именем thisismytabletoo. - person JCCyC; 18.06.2009
comment
Правда. Я не был уверен, всегда ли имена таблиц во всех дампах mysql окружены обратными кавычками или CREATE TABLE mytable также возможно. Мы можем легко адаптировать первое регулярное выражение, если знаем, как выглядит дамп. Вторая проблема может заключаться в том, что таблица mytable не уникальна (одна в базе данных db1, а другая в базе данных db2). Оба будут экспортированы в файл mytable.dump. Если таблица не уникальна, мы можем использовать ту же команду sed, сначала с CREATE DATABASE, чтобы извлечь только нужную базу данных. Затем используйте команду sed с CREATE TABLE. - person uloBasEI; 18.06.2009
comment
Ага, JCCyC. Эта штука сделала именно то, что мне нужно, с нулевым обезьяньим бизнесом. Огромное спасибо вам и uloBasEl! - person Mobius; 19.06.2009
comment
Милая! Не забудьте добавить DROP TABLE вверху и удалить DROP TABLE [следующая таблица] внизу файла. - person Nathan; 21.05.2010
comment
Чтобы не добавлять / удалять DROP TABLE, более полезно сопоставить по комментарию Table structure for table, а не по CREATE TABLE. Это гарантирует, что следующая таблица не будет удалена, если кто-то забудет удалить ее оператор DROP TABLE, и разрешит конвейер для восстановления таблицы с помощью одной команды (gzip | sed | mysql). Однако это решение зависит от синтаксиса комментариев mysqldump (я не знаю, насколько это стандартно). - person Olexa; 26.02.2013
comment
С модификацией Olexa это идеально: sed -n -e '/ Структура таблицы для. * `Mytable /, / Структура таблицы для / p' whole.sql› mytable.sql - person deeenes; 27.05.2013
comment
Блестяще. Действительно неплохо. - person kmarks2; 23.08.2013
comment
Этот ответ лучше, он включает ТАБЛИЦУ ПЕРЕПАДА = ›stackoverflow.com/a/15857815/292408 - person Elijah Lynn; 31.10.2014
comment
Не забудьте добавить закрывающий обратный апостроф `после имени таблицы, иначе все таблицы с одинаковым префиксом будут сопоставлены. - person jotrocken; 02.03.2016
comment
Он отлично работает и для postgres $ sed -n -e '/COPY.*mytable/,/COPY/p' pg.dump > mytable.dump - Спасибо! - person gunzapper; 30.03.2016
comment
Кто-нибудь знает, как я могу заменить мою таблицу переменной в bash? `` Export VAR = my_table sed -n -e '/ CREATE TABLE. * _ 1 _ /, / Table structure for table / p' backup '' - person Kay; 13.01.2021

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

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' mydump.sql > tabledump.sql
person bryn    schedule 07.04.2013
comment
на самом деле это гораздо лучшее решение, чем то, которое было выбрано в качестве ответа выше. Не могу поверить, что он не получил больше голосов. - person rICh; 22.06.2013
comment
Я предлагаю добавить как минимум обратные кавычки к имени таблицы: `mytable`, чтобы избежать сопоставления таблиц mytable2 и так далее, как это было в моем случае. - person bartekbrak; 19.02.2014
comment
Максим, это не сработало, потому что в примере не было ни исходного файла, ни stdout и файла назначения. Я отредактировал пример, чтобы включить их (mydump.sql ›tabledump.sql), и теперь он должен работать. - person Elijah Lynn; 31.10.2014
comment
для меня sed дает неправильный формат файла, должен быть utf8, но является ansi. текст поврежден. - person user706420; 25.11.2014
comment
ты только что спас мою задницу - person Gabriel Alack; 16.12.2014
comment
@ user706420 Хм, а вы уверены, что ваш терминал не виноват? sed не должно мешать кодированию ... - person bryn; 17.12.2014
comment
@rICh этот ответ немного сложнее понять, и он требует хорошей структуры дампа sql. Кроме того, если вы хотите добавить DROP и другие дополнения, вы можете легко получить это из ответа uloBasEl. - person d.sergeiev; 23.12.2014
comment
Для тех, у кого есть файлы 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 */;. - person hamx0r; 16.02.2016
comment
Спасибо @WestonGanger. t Я считаю, что вы правы. Команда должна быть sed -n -e '/-- Table structure for table `<Table Name>`/,/UNLOCK TABLES/p' <SQL File> > table.sql - person hamx0r; 14.07.2016

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

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

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

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

mysql -u root -p restore ‹fulldump.sql

Выгрузите таблицу, которую вы хотите восстановить:

mysqldump восстановить mytable> mytable.sql

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

mysql -u root -p database ‹mytable.sql

person Martijn Kools    schedule 25.04.2013
comment
Это то, что нужно большинству людей. - person sjas; 23.04.2015
comment
Согласно этому предложению редактирования, вы должны добавить параметр --one-database, чтобы убедиться, что вы восстанавливаете только < b> одну базу данных и не уничтожайте все остальное. - person S.L. Barth; 05.09.2015
comment
Для действительно огромных db это может быть очень странно - восстановить 150 ГБ данных для одной таблицы размером 100 МБ. - person Enyby; 08.07.2016
comment
Я просто запустил это без --one-database, и он все равно отлично слил таблицы. Мои существующие таблицы не были удалены. - person Qasim; 26.07.2016
comment
Очень плохая практика! У меня было несколько БД в дампе, и я пытался восстановить только одну, а все остальные удалил. - person Andrey; 01.12.2016
comment
можно сделать из оболочки целиком, очень просто. нет необходимости редактировать файлы или знания sql. - person ; 15.05.2017
comment
@AndreyP Я использую mariadb, он отлично работал у меня, файл sql, происходящий из дампа таблицы, не имел никакого оператора drop для любой другой таблицы или самой db. Какую версию mysql вы использовали? - person ; 15.05.2017
comment
@ S.L.Barth Мне интересно, происходит ли это только тогда, когда есть несколько дампов db в одном файле - person ; 15.05.2017
comment
Это восстановило базу данных с сопоставлением по умолчанию латинского чего-то, в то время как моя исходная база данных была UTF-8, надеюсь, у меня не возникнут проблемы - person Freedo; 06.08.2019
comment
Имя таблицы может быть чувствительным к регистру. Проверьте имя таблицы в базе данных, запустив use restore; и show tables; в клиенте командной строки MySQL. - person Hari; 29.12.2020

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

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

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

person Brom558    schedule 08.08.2013

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

INSERT INTO `the_table_i_want`

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

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

person JCCyC    schedule 18.06.2009
comment
Я тупой из-за того, что сразу не подумал об этом. Кажется, Grep спасает мой бекон каждый день. Два других предложения также были удачными и полностью соответствовали тому, что я сделал бы, если бы не было доступно чудо grep. Спасибо вам всем! - person Mobius; 18.06.2009
comment
Если вы думаете, что любите grep, изучив awk, вы станете его счастливым сексуальным рабом: en.wikipedia. org / wiki / Awk - person JCCyC; 18.06.2009

Вам следует попробовать команду @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
person Maxime Biette    schedule 18.09.2013

  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
    
person y.tk    schedule 23.02.2015

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

person Tim Hoolihan    schedule 18.06.2009

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

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

person Weston Ganger    schedule 12.07.2016

Этот инструмент может быть тем, что вам нужно: tbdba-restore-mysqldump.pl

https://github.com/orczhou/dba-tool/blob/master/tbdba-restore-mysqldump.pl

например Восстановить таблицу из файла дампа базы данных:

tbdba-restore-mysqldump.pl -t ваша таблица -s yourdb -f backup.sql

person user1097790    schedule 14.12.2011

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

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

or

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

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

# 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'
person Pjl    schedule 02.01.2014

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

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

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

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

person Bryan Migliorisi    schedule 18.06.2009

Вы можете использовать редактор 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 МБ.

person mtoloo    schedule 02.02.2015

Я попробовал несколько вариантов, которые были невероятно медленными. Это разделило дамп размером 360 ГБ на таблицы за несколько минут:

Как разделить вывод из mysqldump в файлы меньшего размера?

person Kohjah Breese    schedule 22.04.2016

Упомянутые ранее решения 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
person phil_w    schedule 31.07.2014

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

person Cameron    schedule 18.06.2009
comment
На самом деле это действительно просто и понятно даже новичкам. Я не знаю, почему это отклонено. - person Karl Johan Vallner; 04.10.2017

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

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

find / n "для таблицы" "sql.txt

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

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

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

[4500] - Выгрузка данных для таблицы my_table

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

... так далее.

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

person Kuyenda    schedule 18.06.2009

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

person JaredC    schedule 09.11.2012

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

mysql -u root -p -D my_database_name < var/www/html/myproject/tbl_user.sql

person Yagnesh bhalala    schedule 22.02.2021

Я восхищаюсь некоторой изобретательностью здесь, но буквально нет причин использовать sed для ответа на вопрос OP.

Использование комментария --one-database - правильный ответ, встроенный в MySQL / MariaDB. Нет необходимости в сторонних взломах.

mysql -u root -p databasename --one-database < localhost.sql просто импортирует нужную базу данных.

Я также обнаружил, что в некоторых случаях при использовании этого для импорта серии баз данных он создавал для меня следующую базу данных в списке (но ничего в нее не помещал). Не уверен, почему это произошло, но это упростило восстановление.

С помощью этой команды введите пароль в интерактивном режиме, и он импортирует запрошенную базу данных.

person InterLinked    schedule 19.06.2021