Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tại sao InnoDB cung cấp thông tin không gian trống rõ ràng là sai

(Đây là câu trả lời cho một số câu hỏi nằm trong phần Nhận xét.)

Chữ viết nhầm Không gian "trống" chỉ bao gồm toàn bộ các khối, không phải phòng trống bên trong các khối và nhiều chi tiết khác.

Trường hợp 1: Tất cả các bảng đều ở ibdata1 - SHOW TABLE STATUS (hoặc truy vấn tương đương thành information_schema sẽ hiển thị cùng một Data_free giá trị, cụ thể là bao nhiêu miễn phí trong ibdata1 . Không gian này có thể được tái sử dụng bởi bất kỳ bảng nào. Thật khó để trả lại không gian cho hệ điều hành.

Trường hợp 2: Tất cả các bảng đều là file_per_table - Bây giờ mỗi Data_free đề cập đến không gian cho bảng. Và SUM() là có ý nghĩa. (ibdata1 vẫn tồn tại, nhưng nó không chứa bất kỳ bảng thực nào; có rất nhiều thứ khác mà InnoDB cần.)

Trường hợp 3: Hỗn hợp - Nếu bạn bật / tắt file_per_table vào nhiều thời điểm khác nhau, một số bảng sẽ ở trong ibdata1, một số sẽ có không gian bảng riêng.

Trường hợp 4: TẠO TABLESPACE trong 5.7 - Ví dụ, bạn có thể có một vùng bảng cho mỗi cơ sở dữ liệu.

Trường hợp 5: Bảng ĐỐI TÁC - Mỗi phân vùng hoạt động giống như một bảng.

Trường hợp 6: 8,0 - Sẽ có nhiều thay đổi hơn nữa.

Cơ sở dữ liệu ==Thư mục Trong cây thư mục của MySQL, mỗi cơ sở dữ liệu có thể được xem như một thư mục hệ thống tệp. Trong thư mục đó có thể thấy một số tập hợp các tệp cho mỗi bảng. .frm tệp chứa định nghĩa bảng. Nếu một .ibd tệp tồn tại, bảng đã được tạo bằng tệp_per_table. Đây có thể là cách đáng tin cậy nhất để khám phá xem bảng có phải là file_per_table hay không. (8.0 sẽ có những thay đổi đáng kể ở đây.)

Tôi có thể sử dụng lại bao nhiêu dung lượng ? Không có câu trả lời tốt. Thông thường, việc chèn một hàng sẽ tìm thấy khoảng trống trong khối mà nó thuộc về và Data_free sẽ không bị thu hẹp. Tuy nhiên, nếu có (các) phân chia khối, Data_free có thể giảm một số bội số của 16KB (kích thước khối) hoặc 4MB ("kích thước phạm vi" - hoặc có thể là 8MB?). Ngoài ra, các lần chèn ngẫu nhiên dẫn đến trung bình các khối BTree đầy khoảng 69%.

Thay đổi innodb_file_per_table không có hiệu lực cho đến khi CREATE TABLE tiếp theo hoặc ALTER TABLE . Và sau đó nó chỉ ảnh hưởng đến vị trí đặt dữ liệu + chỉ mục mới được tạo / sao chép (ibdata1 hoặc .ibd). Nó sẽ không phá hủy dữ liệu.

Bảng lớn thường có 4MB đến 7MB Data_free. Khi tính toán bạn có thể thêm bao nhiêu hàng, đừng lập kế hoạch để Data_free giảm xuống dưới phạm vi đó.

Avg_row_size nên hữu ích. Nhưng đôi khi nó (và Hàng) gần đúng kém. Sản phẩm của họ (Data_length) luôn đúng. Vì vậy, điều này có thể là một ước tính tốt về "hàng cần chạy trước khi lấy thêm dung lượng từ OS:

(Data_free - 7M) / Avg_row_size

Đề xuất về vùng bảng :Đặt các bảng 'lớn' vào file_per_table. Đặt các bảng 'nhỏ' trong ibdata1 hoặc các không gian bảng dành riêng cho cơ sở dữ liệu (5.7). Xin lỗi, không có đề xuất đơn giản nào về ranh giới giữa 'lớn' và 'nhỏ'. Và thật vụng về khi di chuyển một bảng:SET global innodb_file_per_table = ...;; đăng xuất; đăng nhập (để nhận toàn cầu); ALTER TABLE tbl ENGINE=InnoDB; . Và nó nhất thiết phải là một bản sao đầy đủ của bảng.

( Báo trước :Tôi đã bỏ sót nhiều chi tiết.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Xây dựng mối quan hệ bậc ba bằng Laravel Eloquent Relationships

  2. Kết hợp hai bảng với sql JOIN?

  3. Ruby mysql2 nhiều câu lệnh trong một truy vấn

  4. Làm cách nào để chèn javascript vào cơ sở dữ liệu mysql?

  5. Tìm kiếm chuỗi trong cột văn bản trong MySQL