Tại sao InnoDB lưu trữ tất cả các cơ sở dữ liệu trong một tệp?


51

Thật tiện lợi khi MyISAM đã sử dụng để lưu trữ mỗi bảng trong một tệp tương ứng. InnoDB đã có những tiến bộ về nhiều mặt, nhưng tôi tự hỏi tại sao InnoDB lưu trữ tất cả các cơ sở dữ liệu trong một tệp ( ibdata1theo mặc định).

Tôi hiểu rằng InnoDB sẽ ánh xạ vị trí của dữ liệu trong tệp theo các tệp chỉ mục riêng lẻ cho các bảng, nhưng tôi không hiểu tại sao nó trộn tất cả dữ liệu trong một tệp. Và quan trọng hơn, tại sao trộn dữ liệu của tất cả các cơ sở dữ liệu trên máy chủ?

Một tính năng thú vị của MyISAM là người ta có thể sao chép / dán thư mục cơ sở dữ liệu sang máy khác và sau đó sử dụng cơ sở dữ liệu (không có kết xuất).

Câu trả lời:


66

Kiến trúc của InnoDB yêu cầu sử dụng bốn loại trang thông tin cơ bản

  • Bảng dữ liệu trang
  • Bảng chỉ mục trang
  • Bảng MetaData
  • Dữ liệu MVCC (để hỗ trợ Cách ly giao dịch và Tuân thủ ACID )
    • Phân đoạn rollback
    • Hoàn tác không gian
    • 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 đại diện hình ảnh của ibdata1

Theo mặc định, innodb_file_per_table bị tắt. Điều này khiến tất cả bốn loại trang thông tin hạ cánh một tệp có tên ibdata1. Nhiều người cố gắng trải đều dữ liệu bằng cách tạo nhiều tệp ibdata. Điều này có thể dẫn đến sự phân mảnh dữ liệu và các trang chỉ mục.

Đây là lý do tại sao tôi thường khuyên bạn nên dọn dẹp cơ sở hạ tầng InnoDB, sử dụng tệp ibdata1 mặc định và không có gì hơn .

Sao chép là rất nguy hiểm vì cơ sở hạ tầng mà InnoDB hoạt động. Có hai cơ sở hạ tầng cơ bản

  • innodb_file_per_table bị vô hiệu hóa
  • kích hoạt innodb_file_per_table

InnoDB ( vô hiệu hóa innodb_file_per_table )

Với innodb_file_per_table bị vô hiệu hóa, tất cả các loại thông tin InnoDB này đều nằm trong ibdata1. Biểu hiện duy nhất của bất kỳ bảng InnoDB nào ngoài ibdata1 là tệp .frm của bảng InnoDB. Sao chép tất cả dữ liệu InnoDB cùng một lúc yêu cầu sao chép tất cả / var / lib / mysql.

Sao chép một bảng InnoDB cá nhân là hoàn toàn không thể. Bạn phải kết xuất MySQL để trích xuất kết xuất của bảng dưới dạng biểu diễn logic của dữ liệu và các định nghĩa chỉ mục tương ứng của nó. Sau đó, bạn sẽ tải kết xuất đó sang cơ sở dữ liệu khác trên cùng một máy chủ hoặc máy chủ khác.

InnoDB ( kích hoạt innodb_file_per_table )

Với innodb_file_per_table được bật, dữ liệu bảng và các chỉ mục của nó nằm trong thư mục cơ sở dữ liệu bên cạnh tệp .frm. Ví dụ: đối với bảng db1.mytable, biểu hiện của bảng InnoDB bên ngoài ibdata1 sẽ là:

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

Không gian bảng hệ thống ibdata1

Tất cả siêu dữ liệu cho db1.mytable vẫn nằm trong ibdata1 và hoàn toàn không có cách nào khác . Làm lại nhật ký và dữ liệu MVCC vẫn còn tồn tại với ibdata1.

Khi nói đến phân mảnh bảng, đây là những gì xảy ra với ibdata1:

  • innodb_file_per_table được bật : bạn có thể thu nhỏ db1.mytables bằngALTER TABLE db1.mytable ENGINE=InnoDB;hoặcOPTIMIZE TABLE db1.mytable;. Điều này dẫn đến /var/lib/mysql/db1/mytable.ibd nhỏ hơn về mặt vật lý mà không bị phân mảnh.
  • innodb_file_per_table bị vô hiệu hóa : bạn không thể thu nhỏ db1.mytables bằngALTER TABLE db1.mytable ENGINE=InnoDB;hoặcOPTIMIZE TABLE db1.mytable;vì nó nằm trong ibdata1. Chạy một trong hai lệnh thực sự, làm cho bảng liền kề và nhanh hơn để đọc và ghi vào. Thật không may, điều đó xảy ra ở cuối ibdata1. Điều này làm cho ibdata1 phát triển nhanh chóng. Điều này được đề cập đầy đủ trong bài viết Dọn dẹp InnoDB của tôi .

CẢNH BÁO (hoặc NGUY HIỂM như Robot sẽ nói trong Lost in Space )

Nếu bạn đang nghĩ đến việc chỉ sao chép tệp .frm và .ibd, bạn đang xếp hàng vào thế giới bị tổn thương. Sao chép tệp .frm và .ibd của bảng InnoDB chỉ tốt khi và chỉ khi bạn có thể đảm bảo rằng id vùng bảng của tệp .ibd khớp chính xác với mục nhập id vùng bảng trong siêu dữ liệu của tệp ibdata1 .

Tôi đã viết hai bài đăng trong DBA StackExchange về khái niệm id không gian bảng này

Đây là một liên kết tuyệt vời về cách gắn lại bất kỳ tệp .ibd nào vào ibdata1 trong trường hợp id không gian bảng không khớp: http : //www.chrryptender.com/?tag=innodb-error-tablespace-id-in-file . Sau khi đọc nó, bạn sẽ nhận ra ngay lập tức rằng việc sao chép các tệp .ibd chỉ là điên rồ.

Đối với InnoDB, bạn chỉ cần một cái gì đó để di chuyển

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

để tạo một bản sao của bảng InnoDB.

Nếu bạn đang di chuyển nó sang một máy chủ DB khác, hãy sử dụng mysqldump.

Liên quan đến việc trộn tất cả các bảng InnoDB từ tất cả các cơ sở dữ liệu, tôi thực sự có thể thấy sự khôn ngoan khi làm như vậy. Tại công ty lưu trữ DB / Web của chủ nhân, tôi có một Máy khách MySQL có một bảng trong một cơ sở dữ liệu có các ràng buộc được ánh xạ tới một bảng khác trong cơ sở dữ liệu khác trong cùng một phiên bản MySQL. Với một kho lưu trữ siêu dữ liệu phổ biến, nó giúp hỗ trợ giao dịch và khả năng hoạt động MVCC trên nhiều cơ sở dữ liệu.


Có nghĩa là khi tôi sử dụng tệp innodb trên mỗi bảng được bật và Nếu tôi cần nhập dữ liệu của mình từ máy chủ này sang máy chủ khác, tôi sẽ chỉ phải sử dụng mysqldump chứ không phải bất kỳ công cụ nào khác như Percona xtrabackup?
tesla747

14

Bạn có thể chuyển đổi InnoDB để lưu trữ các bảng trên mỗi tệp bằng cách thêm innodb-file-per-bảng vào cnf của bạn.

Innodb thực sự chỉ quan tâm đến các trang dữ liệu ở mức cơ bản. Trên thực tế, bạn có thể thiết lập InnoDB để chỉ sử dụng một thiết bị khối thô không có hệ thống tập tin nào! http://dev.mysql.com/doc/refman/5.5/en/innodb-raw-devices.html

Có các tiện ích để lưu trữ các bảng cho tệp như có thể dễ dàng lấy lại không gian đã sử dụng thông qua tối ưu hóa.

Ngay cả với các tệp trên mỗi bảng, bạn không thể sao chép các tệp ibd một cách dễ dàng vì InnoDB là giao dịch và lưu trữ thông tin về trạng thái của nó trong các tệp nhật ký / ibdata được chia sẻ trên toàn cầu.

Điều đó không có nghĩa là nó không thể được thực hiện. Nếu bảng ngoại tuyến, bạn có thể loại bỏ / nhập các không gian bảng và sao chép .idbs xung quanh http://dev.mysql.com/doc/refman/5.5/en/innodb-multipl-tablespaces.html


Không nghi ngờ gì về việc InnoDB là một công cụ linh hoạt, nhưng tôi không hiểu cách lưu trữ tất cả dữ liệu trong một tệp có lợi (vì cấu trúc mới này đã được triển khai trong InnoDB so với MyISAM).
Googlebot

Tôi nghĩ rằng đó là một trong những điều muộn màng là 20/20 điều. Tùy chọn tệp trên mỗi bảng đã được thêm vào sau khi innodb lần đầu tiên lăn ra khỏi kệ. Bên ngoài cung cấp cho nó thiết bị khối riêng để tránh chi phí hệ thống tập tin, tôi không thể đưa ra lý do tại sao kết hợp tất cả chúng lại với nhau tốt hơn (và toàn bộ thiết bị khối là tranh luận riêng). Tất cả các thiết lập innodb của tôi có tệp trên mỗi bảng được bật.
atxdba

Đó là điểm quan trọng, không dựa vào hệ thống tập tin có thể là vô giá nhưng nó không hoạt động theo mặc định. Vì vậy, một vài người dùng sẽ sử dụng nó.
Googlebot

1
Tùy chọn một tệp cho mỗi bảng có thể gây hại nếu bạn có nhiều bảng và không có nhiều RAM (ví dụ, một cửa hàng Magento có thể có khoảng 1000 bảng). Và cài đặt tệp mở cũng phải được tối ưu hóa (xem xét các giới hạn của hệ điều hành). Vì vậy, sử dụng một cách thận trọng.
ypercubeᵀᴹ

Nó chắc chắn có thể đặt một damper vào những nỗ lực phục hồi. Có, bạn nên có một bản sao lưu, nhưng nếu bạn không, InnoDB làm cho mọi thứ khó khăn hơn vì cấu trúc này.
mikato

10

Đây là hành vi mặc định nhưng không bắt buộc. Từ tài liệu MySQL, sử dụng không gian bảng mỗi bảng :

Theo mặc định, tất cả các bảng và chỉ mục InnoDB được lưu trữ trong không gian bảng hệ thống. Cách khác, bạn có thể lưu trữ mỗi bảng InnoDB và các chỉ mục của nó trong tệp riêng của nó . Tính năng này được gọi là nhiều không gian bảng khác nhau vì mỗi bảng được tạo khi cài đặt này có hiệu lực có không gian bảng riêng.

Về lý do, lý do có lẽ là các kiến ​​trúc khác nhau của hai động cơ (MyISAM và InnoDB). Ví dụ: trong InnoDB, bạn không thể sao chép tệp .ibd sang cơ sở dữ liệu hoặc cài đặt khác. Giải thích (từ cùng một trang):

Cân nhắc tính di động cho các tệp .ibd

Bạn không thể tự do di chuyển các tệp .ibd giữa các thư mục cơ sở dữ liệu như bạn có thể với các tệp bảng MyISAM. Định nghĩa bảng được lưu trữ trong không gian bảng chia sẻ InnoDB bao gồm tên cơ sở dữ liệu. ID giao dịch và số thứ tự nhật ký được lưu trữ trong các tệp không gian bảng cũng khác nhau giữa các cơ sở dữ liệu.


Câu trả lời rất nhiều thông tin và làm rõ vấn đề, nhưng tôi vẫn tò mò làm thế nào một tập tin lớn chứa tất cả các cơ sở dữ liệu có thể cải thiện hiệu suất (nếu có).
Googlebot

Hiệu suất không tốt hơn vì có một tệp cho tất cả. Các đặc điểm khác nhau, như khóa cấp hàng, thay vì cấp bảng, giúp thực hiện. Và tất nhiên, lợi thế chính là các giao dịch và các ràng buộc FK (và do đó tính toàn vẹn của cơ sở dữ liệu).
ypercubeᵀᴹ

1
Bạn hoàn toàn đúng về tính toàn vẹn! Tôi hiểu tại sao tốt hơn là đặt tất cả các bảng của cơ sở dữ liệu vào một tệp singe; nhưng tôi không hiểu tại sao đặt tất cả các cơ sở dữ liệu (hoàn toàn độc lập) vào cùng một tệp. InnoDB theo mặc định chỉ sử dụng một tệp để lưu trữ dữ liệu.
Googlebot
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.