2009-03-11 32 views
22

Tôi đã đọc nhiều lần sau khi bạn xóa một hàng trong bảng InnoDB trong MySQL, không gian của nó không được sử dụng lại, vì vậy nếu bạn tạo nhiều INSERT thành bảng và sau đó DELETE định kỳ một số hàng mà bảng sẽ sử dụng ngày càng nhiều không gian trên đĩa, như thể các hàng không bị xóa.Không gian bị chiếm bởi các hàng đã xóa có được tái sử dụng không?

Gần đây tôi đã được thông báo rằng không gian bị chiếm bởi các hàng đã xóa sẽ được sử dụng lại nhưng chỉ sau khi một số giao dịch hoàn tất và thậm chí sau đó - không đầy đủ. Tôi bây giờ bối rối.

Ai đó có thể vui lòng hiểu điều này với tôi không? Tôi cần phải làm rất nhiều INSERTs vào một bảng InnoDB và sau đó mỗi X phút tôi cần phải xóa các bản ghi có hơn Y phút. Tôi có vấn đề với bảng InnoDB ngày càng phát triển ở đây không, hay nó là hoang tưởng?

Trả lời

30

Đó là hoang tưởng :)

DB không tăng kích thước không cần thiết, nhưng đối với vấn đề hiệu suất, không gian cũng không được giải phóng.

Điều bạn nghe nhiều nhất có thể là nếu bạn xóa các bản ghi không gian đó không được trả lại cho Hệ điều hành. Thay vào đó, nó được giữ như một không gian trống cho DB để tái sử dụng sau đó.

Điều này là do:

  • DB cần phải có một số không gian HD để lưu dữ liệu của nó; nếu nó không có bất kỳ không gian nào, nó sẽ đặt trước một số khoảng trống.
  • Khi bạn chèn một hàng mới, một phần không gian đó sẽ được sử dụng.
  • Khi bạn hết dung lượng trống, một khối mới sẽ được đặt trước, v.v.
  • Bây giờ, khi bạn xóa một số hàng, để tránh đặt nhiều khối hơn, không gian của nó được giữ miễn phí nhưng không bao giờ được đưa trở lại Hệ điều hành, vì vậy bạn có thể sử dụng lại sau này mà không cần đặt trước khối.

Như bạn thấy, không gian được sử dụng lại nhưng không bao giờ được trả lại. Đó là điểm mấu chốt cho câu hỏi của bạn.

+0

Seb, bạn có thể vui lòng cung cấp bất kỳ liên kết chính thức nào cho điều này không? –

+0

@GautamSomani Đây là câu trả lời 6 năm tuổi, tôi không có liên kết trong tầm tay nhưng tôi có thể tìm thấy điều này: https://dev.mysql.com/doc/refman/5.1/en/optimize-table.html: ' Các hàng đã xóa được duy trì trong một danh sách liên kết và các hoạt động INSERT tiếp theo sử dụng lại các vị trí hàng cũ. Bạn có thể sử dụng OPTIMIZE TABLE để lấy lại dung lượng không sử dụng và chống phân mảnh tệp dữ liệu. Sau những thay đổi sâu rộng đối với một bảng, tuyên bố này cũng có thể cải thiện hiệu suất của các câu lệnh sử dụng bảng, đôi khi đáng kể.' Tôi chắc chắn nếu bạn google, bạn sẽ có thể tìm thêm thông tin chính thức về điều này. – Seb

2

trong innodb, không có cách thực tế để giải phóng dung lượng.

  • sử dụng cho mỗi bảng tập tin ibdata, mà sẽ cho phép bạn xóa kỷ lục sao chép dữ liệu vào một bảng mới và xóa cũ bảng, do đó phục hồi hồ sơ.
  • sử dụng mysqldump và toàn bộ rất nhiều biên nhận để làm sạch toàn bộ máy chủ . Kiểm tra sau:
    http://dev.mysql.com/doc/refman/5.0/en/adding-and-removing.html

Tất cả những phương pháp này trở nên không thực tế khi bạn đang sử dụng các bảng lớn (trong trường hợp của tôi họ có nhiều hơn 250GB) và bạn phải giữ cho chúng được xóa hồ sơ để thực hiện tốt hơn.

Bạn sẽ phải suy nghĩ nghiêm túc, cho dù bạn có đủ không gian trên đĩa cứng của bạn để thực hiện một trong những chức năng trên (trong trường hợp của tôi, tôi không nghĩ rằng 1TB là đủ cho tất cả những hành động này)

với bảng Innotab (và mysql chính nó) tùy chọn là khá hạn chế nếu có kích thước cơ sở dữ liệu nghiêm trọng.

+0

Có các giải pháp cho điều này, với phiên bản InnoDB mới hơn và cấu hình đúng ('innodb_file_per_table'): http://dev.mysql.com/doc/innodb-plugin/1.0/en/innodb-other-changes-truncate. html http://dev.mysql.com/doc/refman/5.5/en/innodb-truncate-table-reclaim-space.html – Blaisorblade

Các vấn đề liên quan