Làm cách nào để thu nhỏ tệp innodb ibdata1 mà không bỏ tất cả cơ sở dữ liệu?


24

InnoDB lưu trữ tất cả các bảng trong một tệp lớn ibdata1.

Sau khi thả một bảng lớn, tệp sẽ giữ kích thước của nó cho dù bảng có lớn đến đâu. Làm cách nào tôi có thể thu nhỏ tệp đó mà không phải kết xuất và nhập lại toàn bộ cơ sở dữ liệu (có tổng số vài trăm GB)?

Tôi nghĩ lý do là bởi vì bạn vẫn có thể quay trở lại thả. Trong trường hợp của tôi, tôi không cần.

Câu trả lời:


30

Đây là một trong những chủ đề gây tranh cãi nhất mà tôi từng xử lý trong nhiều năm qua với tư cách là một DBA của MySQL và trong DBA StackExchange.

Nói một cách nhẹ nhàng, đơn giản là không có cách nào khác để thu nhỏ ibdata1 . Với innodb_file_per_table bị vô hiệu hóa, mỗi khi bạn chạy OPTIMIZE TABLEtrên bảng InnoDB, ibdata1 sẽ phát triển nhanh chóng. Dữ liệu được loại bỏ bằng cách sử dụng DROP TABLEDROP DATABASEkhông thể được khôi phục vì chúng là DDL, không phải DML. Tôi tin rằng Oracle và MSSQL có thể phục hồi DDL. MySQL không thể làm điều đó.

Có một số loại thông tin cư trú trong ibdata1

  • Bảng dữ liệu
  • Bảng chỉ mục
  • Bảng MetaData
  • Dữ liệu điều khiển MVCC
  • Double Write Buffer (Viết nền để ngăn chặn sự phụ thuộc vào bộ đệm của hệ điều hành)
  • Chèn bộ đệm (Quản lý các thay đổi đối với các chỉ mục phụ không duy nhất)

Sử dụng innodb_file_per_table=1sẽ cho phép bạn tạo các bảng mới với dữ liệu bảng và chỉ mục bảng được tạo bên ngoài ibdata1. Bạn có thể trích xuất bất kỳ bảng nào vẫn còn bên trong ibdata1 bằng cách sử dụng ALTER TABLE ... ENGINE=InnoDB;hoặc OPTIMIZE TABLEnhưng điều đó sẽ để lại khoảng trống không sử dụng lớn đó trong ibdata1.

Mặc dù vậy, bạn phải dọn sạch cơ sở hạ tầng InnoDB. Tôi đã viết bài đăng StackExchange về cách và lý do để làm điều này:

Tin tốt

Bạn chỉ phải đổ dữ liệu, tải lại một lần nữa và không bao giờ xem lại vấn đề này nữa . Chạy OPTIMIZE TABLEsau đó sẽ thực sự thu nhỏ .ibdtệp vùng bảng cho bất kỳ bảng InnoDB nào.


1
Sửa lỗi nhỏ: MSSQL và PostgreSQL có thể khôi phục DDL. Oracle không thể. Trong thực tế, Oracle phát hành một cam kết ngầm khi nhìn thấy DDL!
Chris Travers

1
@RolandoMySQLDBA kể từ phiên bản nào của MySQL, "tin tốt" về thu nhỏ tự động này hoạt động?
Gavriel

@Gavriel - Tôi nghĩ bạn đọc sai. Bạn vẫn phải đổ; xóa ibdata1; khởi động lại; và tải lại. Không tự động của ibdata1. (Thay đổi iblog * giờ đã đơn giản hơn.)
Rick James

2

InnoDB chỉ lưu trữ tất cả các bảng InnoDB của bạn trong ibdata1 nếu bạn không sử dụng cài đặt sau trong tệp mặc định my.cnf của mình:

innodb_file_per_table = 1

BẢNG DROP (và DROP DATABASE) không thể được khôi phục.

Đó không phải là lý do bạn không thể thu nhỏ ibdata1.

Đây là một giải thích viết tắt, nhưng ibdata1 chứa nội bộ InnoDB ngoài dữ liệu bảng của bạn. Theo hiểu biết của tôi, để thu nhỏ nó sẽ yêu cầu chống phân mảnh, đây không phải là một hoạt động được hỗ trợ.

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.