Cách tốt nhất để giảm kích thước của ibdata trong mysql là gì?


63

Tôi có một số máy chủ Sản xuất có ibdatatệp tăng kích thước từng ngày.

Nó đã tiêu thụ hết 290GB dung lượng.

Các bảng trong máy chủ chủ yếu là InnoDB và có các yêu cầu đọc và ghi cao.

Kích thước tệp nhật ký cũng tăng. Có một lượng lớn dữ liệu trong các bảng.

Làm thế nào tôi có thể kiểm soát kích thước ngày càng tăng của cả hai?

Tôi không sử dụng innodb_file_per_table.

Câu trả lời:


104

Hãy ghi nhớ tệp bận rộn nhất trong cơ sở hạ tầng InnoDB là / var / lib / mysql / ibdata1

Tệp này thường chứa nhiều lớp thông tin (khi innodb_file_per_table là 0)

  • Bảng dữ liệu
  • Bảng chỉ mục
  • Dữ liệu MVCC (Kiểm soát tương tranh đa biến)
    • Phân đoạn rollback
    • Hoàn tác không gian bảng
  • Bảng siêu dữ liệu
  • Xem đại diện hình ảnh

Nhiều người tạo ra nhiều tệp ibdata với hy vọng quản lý và hiệu suất không gian đĩa tốt hơn. Nó không giúp được.

Thật không may, BẢNG TỐI ƯU đối với bảng InnoDB được lưu trữ trong ibdata1 thực hiện hai điều:

  • Làm cho dữ liệu và chỉ mục của bảng tiếp giáp bên trong ibdata1
  • Nó làm cho ibdata1 phát triển vì dữ liệu liền kề được gắn vào ibdata1

Bạn có thể tách riêng Dữ liệu Bảng và Chỉ mục Bảng khỏi ibdata1 và quản lý chúng một cách độc lập bằng innodb_file_per_table . Để thu nhỏ ibdata1 một lần và mãi mãi, bạn phải làm như sau

Bước 01) MySQLDump tất cả các cơ sở dữ liệu vào một tệp văn bản SQL (gọi nó là SQLData.sql) ( Chi tiết tại đây )

Bước 02) Thả tất cả các cơ sở dữ liệu (trừ mysql, performance_schemainformation_schema)

Bước 03) Tắt máy mysql

Bước 04) Thêm các dòng sau vào /etc/my.cnf

[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G

Sidenote: Bất kể thiết lập của bạn cho innodb_buffer_pool_size, hãy đảm bảo innodb_log_file_size là 25% của innodb_buffer_pool_size.

Bước 05) Xóa ibdata1, ib_logfile0 và ib_logfile1

Tại thời điểm này, chỉ nên có lược đồ mysql trong / var / lib / mysql

Bước 06) Khởi động lại mysql

Điều này sẽ tạo lại ibdata1 ở mức 10MB, ib_logfile0 và ib_logfile1 ở mức 1G mỗi

Bước 07) Tải lại SQLData.sql vào mysql

ibdata1 sẽ phát triển nhưng chỉ chứa siêu dữ liệu bảng

Mỗi bảng InnoDB sẽ tồn tại bên ngoài ibdata1

Giả sử bạn có một bảng InnoDB có tên mydb.mytable. Nếu bạn truy cập vào / var / lib / mysql / mydb, bạn sẽ thấy hai tệp đại diện cho bảng

  • mytable.frm (Tiêu đề công cụ lưu trữ)
  • mytable.ibd (Trang chủ của dữ liệu bảng và chỉ mục bảng cho mydb.mytable)

ibdata1 sẽ không bao giờ chứa dữ liệu và chỉ mục InnoDB nữa.

Với tùy chọn innodb_file_per_table trong /etc/my.cnf, bạn có thể chạy OPTIMIZE TABLE mydb.mytablevà tệp /var/lib/mysql/mydb/mytable.ibdsẽ thực sự co lại.

Tôi đã làm điều này nhiều lần trong sự nghiệp là một DBA của MySQL

Trên thực tế, lần đầu tiên tôi làm điều này, tôi đã thu gọn tệp ibdata1 50GB thành 500MB.

Hãy thử một lần. Nếu bạn có thêm câu hỏi về điều này, gửi email cho tôi. Tin tôi đi Điều này sẽ làm việc trong ngắn hạn và trên đường dài. !!!

Nếu bạn muốn xem có bao nhiêu dữ liệu thực tế được lưu trữ trong MyISAM và InnoDB, vui lòng chạy truy vấn này:

SELECT IFNULL(B.engine,'Total') "Storage Engine",
CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(
FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(
FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',
SUBSTR(' KMGTP',pw+1,1),'B') "Table Size"
FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,
SUM(data_length+index_length) TSize FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema')
AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,
(SELECT 3 pw) A ORDER BY TSize;

Ngay cả với các cài đặt được đề xuất cho my.cnf (mà tôi đã có), xóa ib_logfile0 và 1 và sau đó bắt đầu mysql, các tệp mới được tạo và trong vài giây, chúng sẽ tăng kích thước của cơ sở dữ liệu như được hiển thị bởi truy vấn trên của bạn. Không chắc chắn nếu mysql sao chép tất cả các bảng và chỉ mục vào các tệp này trong khi vẫn duy trì mỗi bảng trong một tệp riêng biệt.
Allen King
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.