Чи можу я відновити одну таблицю з повного файлу 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
Це навіть приємніше моєї відповіді, оскільки він також піклується про ТВОРЧУ СТОЛЮ, але вам слід шукати за допомогою зворотних цитат, щоб не отримати ще одну таблицю під назвою "thisismytabletoo".
JCCyC

1
Правда. Я не був впевнений, чи завжди назви таблиць у всіх дамбах mysql оточені зворотним котируванням чи якщо "CREATE TABLE mytable" також може бути можливим. Ми можемо легко адаптувати перший регулярний вираз, якщо знаємо, як виглядає дамп. Друга проблема може бути, якщо таблиця mytable не є унікальною (одна в базі даних db1, а інша в базі даних db2). Обидва будуть експортовані у файл mytable.dump. Якщо таблиця не є унікальною, ми можемо використовувати ту саму команду sed, спочатку CREATE DATABASE, щоб витягти лише потрібну базу даних. Потім скористайтеся командою sed за допомогою CREATE TABLE.
uloBasEI

13
Солодке! Не забудьте додати таблицю DROP TABLE вгорі та видалити таблицю DROP [next table] у нижній частині файлу.
Натан

20
Для не додавання / видалення DROP TABLE корисніше співставляти Table structure for tableкоментарі, а не зіставляти CREATE TABLE. Це забезпечить, що наступна таблиця не буде відкинута, якщо хтось забуде видалити свій оператор DROP TABLE, і дозволить проводити конфігурування для відновлення таблиці з однією командою (gzip | sed | mysql). Однак це рішення залежить від синтаксису коментарів mysqldump (я не знаю, наскільки це стандартно).
Олекса

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
це насправді набагато краще рішення, ніж обране вище як відповідь. Не можу повірити, що це не отримало більше грошей.
rICh

9
Я пропоную додати до назви таблиці щонайменше цитати зворотнього відбору: `mytable`щоб уникнути відповідності таблиць mytable2тощо, як у моєму випадку
bartekbrak

3
ти щойно врятував мою попу
Габріель Алак

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 */;як включення.
hamx0r

50

Це можна зробити простіше? Ось як я це зробив:

Створіть тимчасову базу даних (наприклад, відновлення):

mysqladmin -u root -p створити відновлення

Відновити повний дамп у базі даних temp:

mysql -u root -p відновити <fulldump.sql

Вивантажте таблицю, яку потрібно відновити:

mysqldump відновити mytable> mytable.sql

Імпортуйте таблицю в іншу базу даних:

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


2
Це те, що потрібно більшості людей.
sjas

2
Відповідно до цієї пропозиції щодо редагування , вам слід додати параметр "--one-database", щоб переконатися, що ви відновите лише одну базу даних і не знищити все інше.
SL Barth - Відновіть Моніку

7
Для справді величезних db це може бути дуже дивно - відновити 150 ГБ даних для однієї таблиці розміром 100 Мб.
Енібі

Я просто запустив це без "--one-database", і він все ще добре об'єднав таблиці. Це не видалило мої існуючі таблиці.
Касим

1
Дуже погана практика! У мене було декілька БД на дамп, і, намагаючись відновити лише одну, видалив усі інші.
АндрейП

11

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

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

Потім імпортуйте його як звичайний, і він буде імпортувати лише скинуту таблицю.


9

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

INSERT INTO `the_table_i_want`

і трубопровід виводу в mysql. Подивіться на першу таблицю на смітнику раніше, щоб переконатися, що ви отримуєте ВСТУП правильний шлях.

Редагувати: Добре, цього разу отримано форматування.


Я тупий за те, що не відразу думаю поздоровитись. Греп рятує мій бекон щодня, здається. Інші дві пропозиції також були вибухаючими, і я б абсолютно не зробив, якщо б не було чудових помилок. Дякую вам всім!
Мобіус

6
Якщо ти думаєш, що любиш греп, коли ти навчишся awk, ти станеш його щасливим секс-рабом: en.wikipedia.org/wiki/Awk
JCCyC

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

Отримайте гідний текстовий редактор, наприклад, Блокнот ++ або 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

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



0

Згадані раніше рішення "sed" є приємними, але, як зазначалося, не на 100% безпечними

  • У вас можуть бути команди INSERT з даними, що містять: ... СТВОРИТИ ТАБЛИЦЮ ... (що завгодно) ... 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.