Tôi có thể khôi phục một bảng duy nhất từ ​​tệp mysqldump đầy đủ không?


194

Tôi có một bản sao lưu mysqldump của cơ sở dữ liệu mysql của tôi bao gồm tất cả các bảng của chúng tôi có dung lượng khoảng 440 megs. Tôi muốn khôi phục nội dung của chỉ một trong các bảng tạo thành mysqldump. Điều này có thể không? Về mặt lý thuyết, tôi chỉ có thể cắt bỏ phần xây dựng lại bảng mà tôi muốn nhưng tôi thậm chí không biết làm thế nào để chỉnh sửa hiệu quả một tài liệu văn bản có kích thước đó.


2
FWIW, bạn cũng có thể sử dụng mydumper . Điều này tạo ra một kết xuất logic như mysqldump, nhưng nó tạo ra các tệp riêng biệt trên mỗi bảng và nó có thể thực hiện cả việc đổ và tải đa luồng, do đó mất ít thời gian hơn.
Bill Karwin

Câu trả lời:


289

Bạn có thể thử sử dụng sed để chỉ trích xuất bảng bạn muốn.

Giả sử tên của bảng của bạn là mytablevà tệp mysql.dump là tệp chứa kết xuất khổng lồ của bạn:

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

Điều này sẽ sao chép trong tệp mytable.dumpnhững gì nằm giữa CREATE TABLE mytablevà tiếp theo CREATE TABLEtương ứng với bảng tiếp theo.

Sau đó, bạn có thể điều chỉnh tệp mytable.dumpchứa cấu trúc của bảng mytablevà dữ liệu (danh sách INSERT).


5
Điều đó thậm chí còn đẹp hơn câu trả lời của tôi vì nó cũng quan tâm đến TẠO TẠO, nhưng bạn nên tìm kiếm với các backquote để không lấy một bảng khác gọi là "thisismytabletoo".
JCCyC

1
Thật. Tôi không chắc chắn nếu tên bảng trong tất cả các bãi chứa mysql luôn được bao quanh bởi backquote hoặc nếu "CREATE TABLE mytable" cũng có thể có thể. Chúng ta có thể dễ dàng điều chỉnh regrec đầu tiên nếu chúng ta biết bãi rác trông như thế nào. Một vấn đề thứ hai có thể là nếu bảng mytable không phải là duy nhất (một trong cơ sở dữ liệu db1 và một vấn đề khác trong cơ sở dữ liệu db2). Cả hai sẽ được xuất trong tệp mytable.dump. Nếu bảng không phải là duy nhất, chúng ta có thể sử dụng cùng một lệnh sed, đầu tiên với CREATE DATABASE để chỉ trích xuất đúng cơ sở dữ liệu. Sau đó, sử dụng lệnh sed với CREATE TABLE.
uloBasEI

13
Ngọt! Nhớ thêm DROP TABLE ở trên cùng và xóa DROP TABLE [bảng tiếp theo] ở dưới cùng của tệp.
Nathan

20
Để không thêm / xóa DROP TABLE, sẽ hữu ích hơn khi so khớp bằng Table structure for tablenhận xét, thay vì khớp bằng CREATE TABLE. Điều này sẽ đảm bảo rằng bảng tiếp theo sẽ không bị hủy nếu người ta quên xóa câu lệnh DROP TABLE của nó và cho phép đường ống để khôi phục bảng lệnh đơn (gzip | sed | mysql). Tuy nhiên, giải pháp này phụ thuộc vào cú pháp nhận xét mysqldump (Tôi không biết nó chuẩn như thế nào).
Olexa

12
Với sửa đổi Olexa của nó hoàn hảo: sed -n -e '/ Bảng cấu trúc cho * `cấu trúc mytable /, / Bảng / p.' Whole.sql> mytable.sql
deeenes

120

Tôi đã sử dụng một phiên bản sửa đổi của lệnh sed của uloBasEI. Nó bao gồm lệnh DROP trước đó và đọc cho đến khi mysql hoàn thành việc đổ dữ liệu vào bảng của bạn (UNLOCK). Đã làm việc cho tôi (tái) nhập wp_users vào một loạt các trang Wordpress.

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

3
đây thực sự là một giải pháp tốt hơn nhiều so với giải pháp được chọn làm câu trả lời ở trên. Không thể tin rằng nó đã không nhận được nhiều sự ủng hộ hơn.
rICh

9
Tôi đề nghị thêm ít nhất các trích dẫn backtick vào tên bảng: `mytable`để tránh các bảng trùng khớp mytable2và như vậy trong trường hợp của tôi.
bartekbrak

3
bạn vừa cứu được mông tôi
Gabriel Alack 16/12/14

1
@ user706420 Hmm, bạn có chắc thiết bị đầu cuối của bạn không bị đổ lỗi? sedkhông nên can thiệp vào mã hóa ...
bryn

6
Đối với những người có tệp SQL không chứa DROP TABLE(kết xuất MySQL của tôi không có điều này) có thể muốn sử dụng: sed -n -e '/-- Table structure for table ``<Table Name>/,/UNLOCK TABLES/p' <SQL File> > table.sql Điều này giúp sử dụng các nhận xét bảng được cung cấp trước mỗi bảng trong kết xuất MySQl và đảm bảo các dòng như /*!40101 SET @saved_cs_client = @@character_set_client */;được bao gồm.
hamx0r

50

Điều này có thể được thực hiện dễ dàng hơn? Đây là cách tôi đã làm nó:

Tạo cơ sở dữ liệu tạm thời (ví dụ: khôi phục):

mysqladmin -u root -p tạo khôi phục

Khôi phục kết xuất đầy đủ trong cơ sở dữ liệu tạm thời:

Khôi phục gốc mys -u -p <Fulldump.sql

Kết xuất bảng bạn muốn khôi phục:

mysqldump khôi phục mytable> mytable.sql

Nhập bảng trong cơ sở dữ liệu khác:

cơ sở dữ liệu gốc-mys mys -p <mytable.sql


2
Đây là những gì hầu hết mọi người cần.
sjas

2
Theo đề xuất chỉnh sửa này , bạn nên thêm tham số "--one-database", để đảm bảo bạn chỉ khôi phục một cơ sở dữ liệu và không phá hủy mọi thứ khác.
SL Barth - Phục hồi Monica

7
Đối với db thực sự rất lớn, nó có thể rất kỳ lạ - khôi phục 150 GB dữ liệu cho một bảng 100 MB.
Enyby 7/07/2016

Tôi chỉ chạy cái này mà không có "--one-database" và nó vẫn hợp nhất các bảng. Nó không xóa các bảng hiện có của tôi.
Qasim

1
Thực hành rất tệ! Tôi đã có một vài DB trong kết xuất và cố gắng khôi phục chỉ một, xóa tất cả các DB khác.
AndreyP

11

Một giải pháp đơn giản là chỉ cần tạo một bãi chứa chỉ bảng bạn muốn khôi phục riêng. Bạn có thể sử dụng lệnh mysqldump để làm như vậy với cú pháp sau:

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

Sau đó, nhập nó như bình thường và nó sẽ chỉ nhập bảng bị đổ.


9

Bằng cách này hay cách khác, bất kỳ quá trình làm việc đó sẽ phải đi qua toàn bộ văn bản của bãi chứa và phân tích nó theo một cách nào đó. Tôi chỉ muốn grep cho

INSERT INTO `the_table_i_want`

và dẫn đầu ra vào mysql. Hãy nhìn vào bảng đầu tiên trong bãi rác trước đó, để chắc chắn rằng bạn đang nhận được INSERT đúng cách.

Chỉnh sửa: OK, có định dạng ngay lúc này.


Tôi chết lặng vì không nghĩ ngay đến việc gặt hái nó. Grep tiết kiệm thịt xông khói của tôi mỗi ngày, có vẻ như. Hai gợi ý khác cũng là những gợi ý và hoàn toàn là những gì tôi sẽ làm mà không có sự kỳ diệu của grep. Cảm ơn tất cả!
Mobius

6
Nếu bạn nghĩ rằng bạn yêu grep, khi bạn học awk, bạn sẽ trở thành nô lệ tình dục hạnh phúc của nó: en.wikipedia.org/wiki/Awk
JCCyC

7

Bạn nên thử lệnh @bryn nhưng với `delimiter nếu không bạn cũng sẽ trích xuất các bảng có tiền tố hoặc hậu tố, đây là điều tôi thường làm:

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

Ngoài ra, với mục đích thử nghiệm, bạn có thể muốn thay đổi tên bảng trước khi nhập:

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

Để nhập, bạn có thể sử dụng lệnh mysql:

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

6
  1. Sao lưu

    $ mysqldump -A | gzip > mysqldump-A.gz
  2. Khôi phục bảng đơn

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

4

Một cách có thể để giải quyết vấn đề này là khôi phục cơ sở dữ liệu tạm thời và kết xuất bảng đó từ cơ sở dữ liệu tạm thời. Sau đó sử dụng tập lệnh mới.



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

Đây là một giải pháp tốt hơn so với một số khác ở trên vì không phải tất cả các bãi chứa SQL đều chứa một DROP TABLEcâu lệnh. Điều này sẽ làm việc tất cả các loại bãi.


2

Điều này có thể giúp quá.

# 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

Bảng phải trình bày với cùng cấu trúc trong cả kết xuất và cơ sở dữ liệu.

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

hoặc là

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

1

Hầu hết các trình soạn thảo văn bản hiện đại sẽ có thể xử lý một tệp văn bản có kích thước đó, nếu hệ thống của bạn tùy thuộc vào nó.

Dù sao, tôi đã phải làm điều đó một lần rất nhanh và tôi không có thời gian để tìm bất kỳ công cụ nào. Tôi đã thiết lập một phiên bản MySQL mới, nhập toàn bộ bản sao lưu và sau đó nhổ ra bảng tôi muốn.

Sau đó, tôi nhập bảng đó vào cơ sở dữ liệu chính.

Đó là tẻ nhạt nhưng khá dễ dàng. Chúc may mắn.


1

Bạn có thể sử dụng trình soạn thảo vi. Kiểu:

vi -o mysql.dump mytable.dump

để mở cả hai bãi chứa mysql.dumpvà một tập tin mới mytable.dump. Tìm phần chèn thích hợp vào dòng bằng cách nhấn /và sau đó nhập cụm từ, ví dụ: "chèn vào` mytable` ", sau đó sao chép dòng đó bằng cách sử dụng yy. Chuyển sang tập tin tiếp theo ctrl+wsau đó down arrow key, dán dòng sao chép với pp. Cuối cùng lưu tập tin mới bằng cách gõ :wqvà khá vi biên tập bởi :q.

Lưu ý rằng nếu bạn đã đổ dữ liệu sử dụng nhiều chèn bạn có thể sao chép (yank) tất cả chúng cùng một lúc sử dụng Nyytrong đó Nlà số dòng để được sao chép.

Tôi đã thực hiện nó với một tập tin có kích thước 920 MB.


0

Nhận một trình soạn thảo văn bản phong nha như Notepad ++ hoặc Vim (nếu bạn đã thành thạo với nó). Tìm kiếm tên bảng và bạn sẽ có thể làm nổi bật chỉ các lệnh CREATE, ALTER và INSERT cho bảng đó. Nó có thể dễ dàng điều hướng bằng bàn phím của bạn hơn là chuột. Và tôi sẽ đảm bảo rằng bạn đang ở trên một máy có nhiều RAM hoặc để nó không gặp sự cố khi tải toàn bộ tệp cùng một lúc. Khi bạn đã tô sáng và sao chép các hàng bạn cần, sẽ là một ý tưởng tốt để sao lưu chỉ phần đã sao chép vào tệp sao lưu của chính nó và sau đó nhập nó vào MySQL.


1
Điều này thực sự rất dễ làm và dễ hiểu ngay cả với người mới bắt đầu. Tôi không biết, tại sao điều này lại bị hạ thấp.
Karl Johan Vallner

0

Các khối của SQL bị chặn với "Cấu trúc bảng cho bảng my_table" và "Kết xuất dữ liệu cho bảng my_table."

Bạn có thể sử dụng một dòng lệnh Windows như sau để lấy số dòng cho các phần khác nhau. Điều chỉnh chuỗi tìm kiếm khi cần thiết.

tìm / n "cho bảng` "sql.txt

Sau đây sẽ được trả lại:

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

[4384] - Cấu trúc bảng cho bảng my_table

[4500] - Bán dữ liệu cho bảng my_table

[4514] - Cấu trúc bảng cho bảng some_other_table

... Vân vân.

Điều đó giúp bạn có được số dòng bạn cần ... bây giờ, nếu tôi chỉ biết sử dụng chúng ... điều tra.


0

Trở lại '08 tôi cũng có nhu cầu làm điều này. Tôi đã viết một kịch bản Perl sẽ làm điều đó, và giờ đây là phương pháp lựa chọn của tôi. Cũng tóm tắt làm thế nào để làm điều đó trong awk hoặc làm thế nào để khôi phục ở nơi khác và giải nén. Gần đây tôi đã thêm phương pháp sed này vào danh sách. Bạn có thể tìm thấy tập lệnh và các phương thức khác tại đây: http://blog.tsheets.com/2008/tips-tricks/extract-a-single-table-from-a-mysqldump-file.html



0

Các giải pháp 'sed' được đề cập trước đó là tốt nhưng như đã đề cập không an toàn 100%

  • Bạn có thể có các lệnh INSERT với dữ liệu chứa: ... TẠO BẢNG ... (bất cứ điều gì) ... có thể ...

  • hoặc thậm chí chuỗi chính xác "CREATE TABLE` mytable`; " nếu bạn đang lưu trữ các lệnh DML chẳng hạn!

(và nếu bảng rất lớn, bạn không muốn kiểm tra bằng tay)

Tôi sẽ xác minh cú pháp chính xác của phiên bản kết xuất được sử dụng và có một tìm kiếm mẫu hạn chế hơn:

Tránh ". *" Và sử dụng "^" để đảm bảo chúng tôi bắt đầu từ đầu dòng. Và tôi muốn lấy 'DROP' ban đầu

Nói chung, điều này tốt hơn cho tôi:

sed -n -e '/^DROP TABLE IF EXISTS \`mytable\`;/,/^UNLOCK TABLES;/p' mysql.dump > mytable.dump
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.