Tôi vô tình làm rơi cơ sở dữ liệu MySQL trên máy chủ của tôi. Có cách nào để khôi phục cơ sở dữ liệu bị mất không?
Tôi vô tình làm rơi cơ sở dữ liệu MySQL trên máy chủ của tôi. Có cách nào để khôi phục cơ sở dữ liệu bị mất không?
Câu trả lời:
Nếu bạn hành động nhanh, có cơ hội cao để lấy lại cơ sở dữ liệu của bạn. Cơ hội cao hơn cho InnoDB, đối với MyISAM, nó không phải là không, nhưng gần.
Vấn đề là khi MySQL thực thi DROP TABLE hoặc DROP DATABASE (về cơ bản là giống nhau) InnoDB không xóa sạch dữ liệu. Các trang với dữ liệu vẫn còn trên đĩa.
Tùy thuộc vào innodb_file_per_table, cài đặt quá trình khôi phục sẽ khác. Nếu innodb_file_per_table bị TẮT (mặc định cho đến 5.5) thì bảng bị hủy vẫn nằm trong ibdata1. Nếu innodb_file_per_table là ON (mặc định là 5.5) thì bảng bị loại bỏ nằm trong tệp .ibd tương ứng. MySQL loại bỏ tệp này khi thả bảng.
Điều đầu tiên cần làm là dừng mọi thao tác có thể để bảng của bạn không bị ghi đè. Nếu innodb_file_per_table TẮT thì đủ để ngăn chặn MySQL (kill -9 thậm chí còn tốt hơn, nhưng trước tiên hãy đảm bảo bạn giết safe_mysqld). Nếu innodb_file_per_table được BẬT thì phân vùng umount nơi MySQL lưu trữ dữ liệu của nó. Nếu datadir nằm trên phân vùng gốc, tôi khuyên bạn nên tắt máy chủ hoặc ít nhất là chụp ảnh đĩa. Hãy để tôi nhắc lại, mục tiêu là để ngăn chặn việc ghi đè bảng bị bỏ bởi MySQL hoặc hệ điều hành.
Có một công cụ cho phép làm việc với các trang InnoDB ở mức độ thấp, bộ công cụ phục hồi dữ liệu TwinDB . Tôi sẽ sử dụng nó để minh họa phục hồi undrop.
Bạn cần lấy phương tiện với bảng bị rớt (ibdata1 hoặc hình ảnh đĩa) và tìm các trang InnoDB trên đó. công cụ stream_parser từ bộ công cụ thực hiện nó.
./stream_parser -f /path/to/disk/image
Nó sẽ quét tệp, tìm các trang InnoDB và sắp xếp chúng theo loại và index_id. index_id là một định danh mà InnoDB sử dụng để chỉ một chỉ mục. Một bảng được lưu trữ trong chỉ mục CHÍNH. Để tìm thấy index_id là bảng bị bỏ của bạn, bạn cần khôi phục từ điển InnoDB .
Từ điển InnoDB được lưu trữ trong tệp ibdat1. Bạn cần quét tệp ibdata1 theo cách tương tự như trên:
./stream_parser -f /var/lib/mysql/ibdata1
Bây giờ bạn cần lấy các bản ghi từ các bảng từ điển InnoDB SYS_TABLES và SYS_INDEXES (giả sử bảng của bạn là sakila.actor):
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor
000000000B28 2A000001430D4D SYS_TABLES "sakila/actor" 158 4 1 0 0 "" 0
158 là bảng_id, hãy nhớ nó.
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158
000000000B28 2A000001430BCA SYS_INDEXES 158 376 "PRIMARY" 1 3 0 4294967295
000000000B28 2A000001430C3C SYS_INDEXES 158 377 "idx\_actor\_last\_name" 1 0 0 4294967295
Vì vậy, index_id của bảng bị mất của bạn (sakila.actor) là 376.
Bây giờ bạn có thể tìm nạp các bản ghi của bảng bị hủy từ InnoDB index_id 376. Bạn cần phải có cấu trúc bảng của bảng bị hủy, chính xác là câu lệnh CREATE TABLE mà bảng được tạo. Bạn có thể lấy nó ở đâu? Hoặc từ bản sao lưu cũ, hoặc từ nơi khác. Cũng có thể khôi phục cấu trúc từ từ điển InnoDB, nhưng tôi sẽ không trình bày nó trong câu trả lời này. Hãy giả sử bạn có nó.
./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t actor.sql > dump.tsv 2> load_cmd.sql
c_parser xuất các bản ghi dưới dạng kết xuất được phân tách bằng tab thành thiết bị xuất chuẩn. Kết xuất có thể được tải bằng lệnh LOAD DATA. c_parser in nó ra stderr.
Xem thêm chi tiết trong bài viết:
Không có cách nào dễ dàng để phá vỡ điều này với bạn. Sẽ không có vấn đề gì nếu bạn bỏ db thông qua phpmyadmin hoặc dòng lệnh. Nó đi rồi
Lỗi của con người là một lý do để có một chế độ dự phòng tốt.
Tôi không theo tôn giáo nhưng tôi sẽ nói một lời cầu nguyện với hy vọng nó không quá quan trọng.
Phụ thuộc vào thiết lập của bạn. Có thể khôi phục nếu bạn thiết lập hệ thống chính xác. Nếu bạn có một bản sao lưu, bạn có thể khôi phục nó. và sau đó áp dụng các bản ghi nhị phân cho đến điểm ngay trước khi bạn bỏ bảng.
http://dev.mysql.com/doc/refman/5.5/en/mysqlbinlog.html
Tôi khuyên bạn nên làm điều này trên một máy chủ khác, khi bạn đã khôi phục bảng, bạn có thể sử dụng mysqldump để giải nén nó và nhập trở lại máy chủ sản xuất của bạn. Đây sẽ không phải là một khôi phục nhanh, nhưng bạn có thể khôi phục dữ liệu.
Nếu bạn không biết những gì bạn đang làm, tôi sẽ đề nghị mở một hợp đồng hỗ trợ với một trong những công ty tư vấn mysql (pythian, percona, palamino có lẽ là tốt nhất) và nhờ họ giúp bạn điều này.
tôi mong điều may mắn nhất đến với em