MySQL InnoDB - khuyết điểm innodb_file_per_table?


32

Theo mặc định, MySQL InnoDB lưu trữ tất cả các bảng của tất cả các DB trong một tệp toàn cầu. Bạn có thể thay đổi điều này bằng cách đặt innodb_file_per_table trong cấu hình, sau đó tạo một tệp dữ liệu cho mỗi bảng.

Tôi tự hỏi tại sao innodb_file_per_tablekhông được bật theo mặc định. Có những nhược điểm khi sử dụng nó?

Câu trả lời:


32

Tôi có câu trả lời đầy đủ cho cái này.

Khi innodb_file_per_table được đặt vào vị trí và các bảng InnoDB mới có thể được thu nhỏ bằng cách sử dụng ALTER TABLE <innodb-table-name> ENGINE=InnoDB';Điều này sẽ thu nhỏ các .ibdtệp mới ĐẢM BẢO.

Nếu bạn chạy ALTER TABLE <innodb-table-name> ENGINE=InnoDB';trên bảng InnoDB được tạo trước khi bạn sử dụng innodb_file_per_table, nó sẽ lấy dữ liệu và chỉ mục cho bảng đó ra khỏi tệp ibdata1 và lưu trữ trong .ibdtệp, Điều này sẽ không bao giờ được sử dụng lại toàn bộ chim bồ câu trong ibdata1 .

Các ibdata1tập tin thường chứa bốn loại thông tin

  • 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 siêu dữ liệu (Từ điển dữ liệu)
  • 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)
  • Xem Pictorial Representation of ibdata1

Đây là cách được đảm bảo để thu nhỏ tệp ibdata1 mãi mãi ...

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)

BƯỚC 02) Bỏ tất cả các cơ sở dữ liệu (ngoại trừ các lược đồ mysql, information_schema và Performance_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
innodb_data_file_path=ibdata1:10M:autoextend

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 ( xem cập nhật bên dưới trước khi xóa! )

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 (không định cấu hình tùy chọn), 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 và dữ liệu MVCC không liên tục.

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 đi 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/etc/my.cnf , bạn có thể chạy OPTIMIZE TABLE mydb.mytableOR ALTER TABLE mydb.mytable ENGINE=InnoDB;và tệp /var/lib/mysql/mydb/mytable.ibdsẽ thực sự co lại.

Tôi đã thực hiện điều này nhiều lần trong sự nghiệp của mình với tư cách là một DBA MySQL mà không gặp nhiều vấn đề sau đó. 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 50MB.

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.

CẬP NHẬT 2013/07/02 15:08 EDT

Có một sự cảnh báo về vấn đề này mà tôi đã cập nhật trong các bài đăng khác của tôi nhưng tôi đã bỏ lỡ điều này: Tôi đang cập nhật câu trả lời của mình thêm một chút với innodb_fast_shutdown vì tôi đã sử dụng để khởi động lại mysql và dừng mysql để làm điều này. Bây giờ, một bước này rất quan trọng vì mọi giao dịch không được cam kết có thể có các bộ phận chuyển động khác trong và ngoài Nhật ký giao dịch InnoDB ( Xem Cơ sở hạ tầng của InnoDB ).

Xin lưu ý rằng việc đặt innodb_fast_shutdown thành 2 cũng sẽ xóa sạch các bản ghi nhưng các phần chuyển động hơn vẫn tồn tại và được chọn trên Crash Recovery trong quá trình khởi động của mysqld. Cài đặt 0 là tốt nhất.


Thông tin tuyệt vời - cảm ơn! 50GB >> 50MB - thật ấn tượng!
UpTheCux

Xin chào, tôi đã cố gắng thực hiện chính xác như bạn đã viết ở đây, vấn đề 'duy nhất' là máy chủ không bắt đầu sau đó. Nếu tôi làm dịch vụ mysql thì nó chỉ bị treo ở đó. Nếu tôi chuyển trở lại tập tin cnf cũ của tôi, mọi thứ đều ổn. Bạn đã có bất kỳ manh mối về điều này?
Nicola Peluchetti

Câu hỏi này dành cho Nicola: Bạn đã làm Bước 5 ???
RolandoMySQLDBA

Một câu hỏi khác cho @Nicola: Bạn có bao nhiêu RAM trong hệ thống của mình ???
RolandoMySQLDBA

2
Hãy cẩn thận! Tùy chọn innodb_fast_shutdown=0phải được đặt trong MySQL, trước khi tắt nó để xóa các tệp nhật ký! ( ib_logfile0ib_logfile1) Nếu không, bạn có thể mất dữ liệu!
Totor

12

Xem lỗi .

Có những nhược điểm khi sử dụng nó?

  • mở nhiều tập tin hơn
  • mở / mở lại trên cao
  • Tệp .ibd không co lại (xem 1 , 2 )

Tôi luôn sử dụng innodb_file_per_table trên các cơ sở dữ liệu lớn.


Ngay cả khi bạn không sử dụng nó, các tệp ibdata sẽ không bị thu hẹp, hoặc:
minaev

1
Cảm ơn. Tôi cũng tự hỏi tại sao không có tùy chọn để có tệp-per-db?
UpTheCux

1
@UpTheCalet, bảng là các thực thể. Cơ sở dữ liệu là các nhóm thực thể logic, thay vì các thực thể theo quyền riêng của chúng. Rõ ràng hơn với MyISAM, trong đó cơ sở dữ liệu là thư mục và bảng là tệp.
John Gardeniers

Chỉ muốn chỉ ra rằng trong khi các tệp .ibd không tự động thu nhỏ , thì cũng không ibdata1thay thế cho tệp trên mỗi bảng. Ít nhất là có thể thu nhỏ một .ibd bằng cách sử dụng optimize table, điều này không đáng kể so với thu hẹp ibdata1.
RomanSt

8

innodb_file_per_table được bật theo mặc định trong MariaDB.


1
Không phải của tôi (phiên bản mặc định trong CentOS 7). Bạn cần tương đương với MySQL 5.6.6 trở lên. Nếu không thì mặc định là tắt .
Cuộc đua nhẹ nhàng với Monica

2

Lý do tôi chọn không sử dụng innodb_file_per_tablelà vì mỗi bảng được đặt trong tệp riêng của mình, điều đó có nghĩa là mỗi bảng sẽ có một chi phí riêng (chữ ký tệp, v.v.) khiến cho tổng kích thước tổng thể của MySQLthư mục là lớn hơn nếu sử dụng một không gian bảng chia sẻ. Ngoài ra, có nhiều không gian bị lãng phí hơn do cụm chùng khi có nhiều tệp nhỏ thay vì một tệp lớn.

Cấp, chi phí bổ sung không phải là một số lượng lớn trong sơ đồ lớn, đặc biệt là nếu bạn đang sử dụng một ổ đĩa lớn hoặc có một cơ sở dữ liệu khổng lồ, nhưng đối với bản thân tôi (và có lẽ là nhiều người dùng gia đình trên mạng), tất cả đã được thêm vào và vẫn còn quá nhiều cho ổ đĩa nhỏ với các cụm lớn nơi tôi đang giữ cửa hàng MySQL của mình.

Ví dụ, lưu trữ cơ sở dữ liệu của tôi với cơ sở dữ liệu WordPress của tôi và một vài cơ sở dữ liệu nhỏ khác (phpBB, dev, một số xét nghiệm AMP, vv), chuyển đổi để mỗi bảng thay đổi nó từ 32MB đến 50MB, và thậm chí không được bao gồm ibdata1trong đó vẫn đòi hỏi một tối thiểu là 10MB , với tổng số ít nhất 60MB.

Như tôi đã nói, điều này có thể không phải là vấn đề quá lớn đối với một số người, đặc biệt là các doanh nghiệp, nhưng nếu bạn là người dùng gia đình chỉ lưu trữ trang web, blog, v.v. thì đó thực sự có thể là một yếu tố trong việc lựa chọn một nhà cung cấp máy chủ lưu trữ vì nhiều máy chủ giới hạn kích thước cơ sở dữ liệu của bạn ngoài tổng mức sử dụng đĩa.


1
Tôi đã nghĩ rằng bạn là người dở hơi (ai quan tâm đến mười megabyte ???) cho đến khi bạn hiểu rõ về hạn ngạch chặt chẽ tại các nhà cung cấp dịch vụ lưu trữ. Không bao giờ có thể nghĩ về điều đó.
Dan Pritts

@DanPritts, đặc biệt là máy chủ miễn phí. Bên cạnh đó, bạn có thể có một ổ đĩa khổng lồ, nhưng không phải ai cũng làm được. Tôi đã mở rộng phân vùng dữ liệu chính của mình từ 1GB lên 2GB trong năm ngoái vì nó quá chật, nhưng thậm chí 10 MB ở đây và 10 MB ở đó (đặc biệt là với các tệp nhật ký) có thể ăn nhanh. Ngoài ra, đừng quên cụm - chất thải cũng tăng lên. Cuối cùng, nó thậm chí không nhất thiết phải là ổ cứng . Ví dụ: hiện tại tôi đang chuyển đổi trang web của tôi thành một trang web của tôi để tôi có thể lưu trữ nó từ bất kỳ hệ thống nào, do đó, ổ đĩa flash 2 GB đã bị giới hạn. Vì vậy, giữ kích thước nhỏ và tránh viết là rất quan trọng. Và sau đó có các hệ thống nhúng!
Synetech

Ngoài ra, nó không phải là 10 MB (đó là kích thước tối thiểu tuyệt đối cho IBDATA1). Nó đã tăng từ 30MB đến ~ 85 MB. Bằng cách xóa toàn bộ nội dung và nhập kết xuất từ ​​đầu, tôi đã kết thúc với 69 MB thay vì 30 MB trước đó (một người đoán cơ sở dữ liệu nào chiếm hơn một nửa số đó). Vì một số lý do, mặc dù sử dụng mỗi bàn, tôi ibdata1vẫn là 18 MB. ☹
Synetech

Âm thanh giống như một cái gì đó tôi đã có với một cài đặt CMS với so với một cái mà không bật selinux, đánh giá từ các kích thước tệp 32M so với 50M. Tôi thực sự không thể tin vào những con số, bạn thậm chí có bao nhiêu cơ sở dữ liệu mà siêu dữ liệu của một số tệp có thể thêm kích thước MEGABYTES trên các hệ thống giống hệt nhau?
sjas

2

Chỉ cần thêm một chút thông tin

Kể từ khi mysql 5.6.6 được bật theo mặc định


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.