Bisakah saya mengembalikan satu tabel dari file mysqlump mysql penuh?

194

Saya memiliki cadangan mysqldump dari database mysql saya yang terdiri dari semua tabel kami yaitu sekitar 440 MB. Saya ingin mengembalikan konten hanya dari satu tabel dari mysqldump. Apakah ini mungkin? Secara teoritis, saya hanya bisa memotong bagian yang membangun kembali tabel yang saya inginkan tetapi saya bahkan tidak tahu cara mengedit dokumen teks dengan ukuran itu secara efektif.

Mobius
sumber
2
FWIW, Anda juga bisa menggunakan mydumper . Ini menciptakan dump logis seperti mysqldump, tetapi output file terpisah per tabel, dan dapat melakukan dumping dan memuat multi-threaded, sehingga membutuhkan waktu lebih sedikit.
Bill Karwin

Jawaban:

289

Anda dapat mencoba menggunakan sed untuk mengekstrak hanya tabel yang Anda inginkan.

Katakanlah nama tabel Anda mytabledan file mysql.dump adalah file yang berisi dump besar Anda:

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

Ini akan menyalin dalam file mytable.dumpyang terletak di antara CREATE TABLE mytabledan yang berikutnya CREATE TABLEsesuai dengan tabel berikutnya.

Anda kemudian dapat menyesuaikan file mytable.dumpyang berisi struktur tabel mytable, dan data (daftar INSERT).

uloBasEI
sumber
5
Itu bahkan lebih baik daripada jawaban saya karena itu mengurus CREATE TABLE juga, tetapi Anda harus mencari dengan backquote agar tidak mendapatkan meja lain yang disebut "thisismytabletoo".
JCCyC
1
Benar. Saya tidak yakin apakah nama tabel di semua dump mysql selalu dikelilingi oleh backquote atau apakah "CREATE TABLE mytable" juga bisa dimungkinkan. Kita dapat dengan mudah mengadaptasi regexp pertama jika kita tahu bagaimana tampilannya. Masalah kedua bisa jadi jika tabel mytable tidak unik (satu di database db1, dan satu lagi di database db2). Keduanya akan diekspor dalam file mytable.dump. Jika tabel tidak unik, kita bisa menggunakan perintah sed yang sama, pertama dengan CREATE DATABASE untuk mengekstraksi hanya database yang benar. Kemudian, gunakan perintah sed dengan CREATE TABLE.
uloBasEI
13
Manis! Jangan lupa untuk menambahkan DROP TABLE di bagian atas dan menghapus DROP TABLE [tabel berikutnya] di bagian bawah file.
Nathan
20
Untuk tidak menambah / menghapus DROP TABLE, lebih baik mencocokkan dengan Table structure for tablekomentar, daripada mencocokkan dengan CREATE TABLE. Ini akan memastikan bahwa tabel berikutnya tidak akan turun jika seseorang lupa untuk menghapus pernyataan DROP TABLE, dan memungkinkan pemipaan untuk pengembalian tabel perintah tunggal (gzip | sed | mysql). Namun, solusi ini tergantung pada sintaks komentar mysqldump (saya tidak tahu bagaimana standarnya).
Olexa
12
Dengan modifikasi Olexa, itu sempurna: sed -n -e '/ Struktur tabel untuk. * `Mytable /, / Struktur tabel untuk / p' whole.sql> mytable.sql
deeenes
120

Saya menggunakan versi modifikasi dari perintah sed uloBasEI. Ini termasuk perintah DROP sebelumnya, dan membaca sampai mysql selesai membuang data ke meja Anda (UNLOCK). Bekerja untuk saya (kembali) mengimpor wp_users ke banyak situs Wordpress.

sed -n -e '/DROP TABLE.*`mytable`/,/UNLOCK TABLES/p' mydump.sql > tabledump.sql
Bryry
sumber
3
ini sebenarnya solusi yang jauh lebih baik daripada yang dipilih sebagai jawaban, di atas. Tidak percaya itu tidak mendapatkan lebih banyak upvotes.
KAYA
9
Saya sarankan menambahkan setidaknya tanda kutip backtick ke nama tabel: `mytable`untuk menghindari tabel yang cocok mytable2dan seterusnya seperti dalam kasus saya.
bartekbrak
3
Anda baru saja menyelamatkan pantat saya
Gabriel Alack
1
@ user706420 Hmm, apakah Anda yakin terminal Anda tidak bisa disalahkan? sedseharusnya tidak mengganggu pengodean ...
bryn
6
Bagi mereka yang memiliki file SQL yang tidak mengandung DROP TABLE(dump MySQL saya tidak memiliki ini) mungkin ingin menggunakan: sed -n -e '/-- Table structure for table ``<Table Name>/,/UNLOCK TABLES/p' <SQL File> > table.sql Ini menggunakan komentar tabel yang diberikan sebelum setiap tabel dalam dump MySQl, dan memastikan baris seperti /*!40101 SET @saved_cs_client = @@character_set_client */;disertakan.
hamx0r
50

Ini bisa dilakukan dengan lebih mudah? Beginilah cara saya melakukannya:

Buat basis data sementara (mis. Pulihkan):

mysqladmin -u root -p buat restore

Kembalikan dump penuh di database temp:

mysql -u root -p mengembalikan <fulldump.sql

Buang tabel yang ingin Anda pulihkan:

mysqldump mengembalikan mytable> mytable.sql

Impor tabel di database lain:

mysql -u root -p database <mytable.sql

Martijn Kools
sumber
2
Inilah yang kebanyakan orang butuhkan.
sjas
2
Menurut saran edit ini , Anda harus menambahkan parameter "--satu-database", untuk memastikan Anda hanya mengembalikan satu database dan tidak menghancurkan yang lainnya.
SL Barth - Reinstate Monica
7
Untuk db yang sangat besar, ini bisa sangat aneh - mengembalikan 150 GB data untuk satu tabel 100 MB.
Enyby
Saya hanya menjalankan ini tanpa "--satu-database" dan masih menggabungkan tabel dengan baik. Itu tidak menghapus tabel saya yang ada.
Qasim
1
Latihan yang sangat buruk! Saya memiliki beberapa DB di dump, dan mencoba mengembalikan hanya satu, menghapus yang lainnya.
AndreyP
11

Solusi sederhana adalah dengan membuat dump hanya dari tabel yang ingin Anda pulihkan secara terpisah. Anda dapat menggunakan perintah mysqldump untuk melakukannya dengan sintaks berikut:

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

Kemudian impor seperti biasa, dan itu hanya akan mengimpor tabel yang dibuang.

Brom558
sumber
9

Dengan satu atau lain cara, proses apa pun yang harus melalui seluruh teks dump dan menguraikannya dengan cara tertentu. Saya hanya akan menerima

INSERT INTO `the_table_i_want`

dan pipa output ke mysql. Lihatlah tabel pertama di dump sebelumnya, untuk memastikan Anda mendapatkan INSERT dengan cara yang benar.

Sunting: Oke, perbaiki pemformatan kali ini.

JCCyC
sumber
Aku bodoh karena tidak segera berpikir untuk mencengkeramnya. Grep menyimpan bacon saya setiap hari, tampaknya. Dua saran lainnya juga merupakan saran dan apa yang akan saya lakukan tanpa keajaiban grep tersedia. Terima kasih semua!
Mobius
6
Jika Anda berpikir Anda menyukai grep, ketika Anda belajar awk, Anda akan menjadi budak seks yang bahagia: en.wikipedia.org/wiki/Awk
JCCyC
7

Anda harus mencoba perintah @bryn tetapi dengan `pembatas jika tidak, Anda juga akan mengekstrak tabel yang memiliki awalan atau akhiran, inilah yang biasanya saya lakukan:

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

Juga untuk tujuan pengujian, Anda mungkin ingin mengubah nama tabel sebelum mengimpor:

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

Untuk mengimpor Anda dapat menggunakan perintah mysql:

mysql -u root -p'password' mydatabase < mytable_restore.sql
Maxime Biette
sumber
6
  1. Cadangkan

    $ mysqldump -A | gzip > mysqldump-A.gz
  2. Pulihkan satu tabel

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

Salah satu cara yang mungkin untuk mengatasinya adalah dengan mengembalikan ke basis data sementara, dan membuang hanya tabel itu dari basis data sementara. Kemudian gunakan skrip baru.

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

Ini adalah solusi yang lebih baik daripada beberapa yang lain di atas karena tidak semua SQL dumps berisi DROP TABLEpernyataan. Yang ini akan bekerja akan semua jenis kesedihan.

Weston Ganger
sumber
2

Ini mungkin membantu juga.

# 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'
Pjl
sumber
2

Tabel harus menyajikan struktur yang sama di dump dan database.

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

atau

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

Sebagian besar editor teks modern harus dapat menangani file teks sebesar itu, jika sistem Anda sesuai dengan itu.

Bagaimanapun, saya harus melakukannya sekali dengan sangat cepat dan saya tidak punya waktu untuk menemukan alat apa pun. Saya membuat instance MySQL baru, mengimpor seluruh cadangan dan kemudian memuntahkan hanya tabel yang saya inginkan.

Lalu saya mengimpor tabel itu ke database utama.

Itu membosankan tetapi agak mudah. Semoga berhasil.

Bryan Migliorisi
sumber
1

Anda dapat menggunakan vi editor. Tipe:

vi -o mysql.dump mytable.dump

untuk membuka seluruh dump mysql.dumpdan file baru mytable.dump. Temukan penyisipan yang sesuai dengan menekan /dan kemudian ketik frasa, misalnya: "masukkan ke dalam` mytable` ", lalu salin baris itu menggunakan yy. Beralih ke file berikutnya ctrl+wsaat itu down arrow key, tempelkan baris yang disalin pp. Akhirnya simpan file baru dengan mengetik :wqdan cukup vi editor oleh :q.

Perhatikan bahwa jika Anda telah membuang data menggunakan banyak sisipan, Anda dapat menyalin (menarik) semuanya sekaligus menggunakan Nyyyang Nmerupakan jumlah baris yang akan disalin.

Saya telah melakukannya dengan file berukuran 920 MB.

mtoloo
sumber
0

Dapatkan editor teks yang layak seperti Notepad ++ atau Vim (jika Anda sudah mahir melakukannya). Cari nama tabel dan Anda harus bisa menyorot perintah CREATE, ALTER, dan INSERT untuk tabel itu. Mungkin lebih mudah menavigasi dengan keyboard Anda daripada menggunakan mouse. Dan saya akan memastikan Anda menggunakan mesin dengan banyak atau RAM sehingga tidak akan memiliki masalah memuat seluruh file sekaligus. Setelah Anda menyorot dan menyalin baris yang Anda butuhkan, itu akan menjadi ide yang baik untuk membuat cadangan hanya bagian yang disalin ke file cadangan sendiri dan kemudian mengimpornya ke MySQL.

Cameron
sumber
1
Ini sebenarnya sangat mudah dilakukan dan dimengerti bahkan oleh pemula. Saya tidak tahu, mengapa ini diturunkan.
Karl Johan Vallner
0

Potongan SQL diblokir dengan "Struktur tabel untuk tabel my_table" dan "Membuang data untuk tabel my_table."

Anda dapat menggunakan baris perintah Windows sebagai berikut untuk mendapatkan nomor baris untuk berbagai bagian. Sesuaikan string yang dicari sesuai kebutuhan.

temukan / n "untuk tabel` "sql.txt

Berikut ini akan dikembalikan:

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

[4384] - Struktur tabel untuk tabel my_table

[4500] - Membuang data untuk tabel my_table

[4514] - Struktur tabel untuk tabel some_other_table

... dll.

Itu memberi Anda nomor baris yang Anda butuhkan ... sekarang, jika saya hanya tahu bagaimana menggunakannya ... menyelidiki.

Kuyenda
sumber
0

Solusi 'sed' yang disebutkan sebelumnya bagus tetapi seperti yang disebutkan tidak 100% aman

  • Anda mungkin memiliki perintah INSERT dengan data yang mengandung: ... CREATE TABLE ... (apa pun) ... mytable ...

  • atau bahkan string yang tepat "CREATE TABLE` mytable`; " jika Anda menyimpan perintah DML misalnya!

(dan jika meja sangat besar Anda tidak ingin memeriksanya secara manual)

Saya akan memverifikasi sintaks yang tepat dari versi dump yang digunakan, dan memiliki pencarian pola yang lebih ketat:

Hindari ". *" Dan gunakan "^" untuk memastikan kita mulai dari awal baris. Dan saya lebih suka mengambil 'DROP' awal

Secara keseluruhan, ini bekerja lebih baik untuk saya:

sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump
phil_w
sumber