InnoDB là một trong những công cụ lưu trữ được sử dụng rộng rãi nhất trong MySQL. Công cụ lưu trữ này được biết đến như một công cụ lưu trữ có độ tin cậy cao và hiệu suất cao và những ưu điểm chính của nó bao gồm hỗ trợ khóa cấp hàng, khóa ngoài và theo mô hình ACID. InnoDB thay thế MyISAM làm công cụ lưu trữ mặc định kể từ MySQL 5.5, được phát hành vào năm 2010.
Công cụ lưu trữ này có thể cực kỳ hiệu quả và mạnh mẽ nếu được tối ưu hóa đúng cách - hôm nay chúng ta sẽ xem xét những điều chúng ta có thể làm để làm cho nó hoạt động ở mức tốt nhất có thể, nhưng trước khi chúng ta đi sâu vào vào InnoDB, tuy nhiên, chúng ta nên hiểu mô hình ACID nói trên là gì.
ACID là gì và tại sao nó lại quan trọng?
ACID là một tập hợp các thuộc tính của các giao dịch cơ sở dữ liệu. Từ viết tắt này có nghĩa là bốn từ:Tính nguyên tử, Tính nhất quán, Tính cô lập và Độ bền. Nói tóm lại, các thuộc tính này đảm bảo rằng các giao dịch cơ sở dữ liệu được xử lý một cách đáng tin cậy và đảm bảo tính hợp lệ của dữ liệu bất chấp lỗi, mất điện hoặc bất kỳ vấn đề nào như vậy. Hệ thống quản lý cơ sở dữ liệu tuân thủ các nguyên tắc này được cho là DBMS tuân thủ ACID. Đây là cách mọi thứ hoạt động trong InnoDB:
- Tính nguyên tử đảm bảo rằng các câu lệnh trong giao dịch hoạt động như một đơn vị không thể phân chia và tác động của chúng được nhìn nhận một cách tổng thể hoặc hoàn toàn;
- Cơ chế ghi nhật ký của MySQL xử lý tính nhất quán ghi lại tất cả các thay đổi đối với cơ sở dữ liệu;
- Isolation đề cập đến khóa ở cấp độ hàng của InnoDB;
- Độ bền cũng được duy trì vì InnoDB duy trì một tệp nhật ký theo dõi tất cả các thay đổi đối với hệ thống.
Hiểu InnoDB
Bây giờ chúng ta đã đề cập đến ACID, có lẽ chúng ta nên xem xét cách nhìn của InnoDB. Đây là cách InnoDB trông như thế nào từ bên trong (hình ảnh lịch sự của Percona):
InnoDB InternalsTừ hình ảnh trên, chúng ta có thể thấy rõ ràng rằng InnoDB có một vài các thông số quan trọng đối với hiệu suất của nó và những thông số này như sau:
- Tham số innodb_data_file_path mô tả không gian bảng hệ thống (không gian bảng hệ thống là vùng lưu trữ cho từ điển dữ liệu InnoDB, bộ đệm ghi và thay đổi kép và hoàn tác nhật ký). Tham số mô tả tệp nơi dữ liệu bắt nguồn từ bảng InnoDB sẽ được lưu trữ;
- Tham số innodb_buffer_pool_size là bộ đệm bộ nhớ mà InnoDB sử dụng để lưu dữ liệu và chỉ mục của các bảng;
- Tham số innodb_log_file_size mô tả kích thước của tệp nhật ký InnoDB;
- Tham số innodb_log_buffer_size được sử dụng để ghi vào các tệp nhật ký trên đĩa;
- Tham số innodb_flush_log_at_trx_commit kiểm soát sự cân bằng giữa tuân thủ ACID nghiêm ngặt và hiệu suất cao hơn;
- Tham số innodb_lock_wait_timeout là khoảng thời gian tính bằng giây mà một giao dịch InnoDB chờ khóa hàng trước khi từ bỏ;
- Tham số innodb_flush_method xác định phương thức được sử dụng để chuyển dữ liệu sang tệp dữ liệu InnoDB và tệp nhật ký có thể ảnh hưởng đến thông lượng I / O.
InnoDB cũng lưu trữ dữ liệu từ các bảng của nó trong một tệp có tên ibdata1 - tuy nhiên, các bản ghi được lưu trữ trong hai tệp riêng biệt có tên ib_logfile0 và ib_logfile1:tất cả ba tệp đó đều nằm trong / var / lib / mysql danh mục.
Để làm cho InnoDB hoạt động hiệu quả nhất có thể, chúng tôi phải tinh chỉnh các thông số này và tối ưu hóa chúng nhiều nhất có thể bằng cách xem xét các tài nguyên phần cứng có sẵn của chúng tôi.
Điều chỉnh InnoDB để có hiệu suất cao
Để điều chỉnh hiệu suất của InnoDB trên phần cứng của bạn, hãy làm theo các bước sau:
-
Để tự động mở rộng innodb_data_file_path, hãy chỉ định thuộc tính autoextend trong cài đặt và khởi động lại máy chủ. Ví dụ:
innodb_data_file_path=ibdata1:10M:autoextend
Khi tham số autoextend được sử dụng, tệp dữ liệu sẽ tự động tăng kích thước thêm 8 MB mỗi khoảng thời gian được yêu cầu. Một tệp dữ liệu tự động mở rộng mới cũng có thể được chỉ định như vậy (trong trường hợp này, tệp dữ liệu mới được gọi là ibdata2):
innodb_data_file_path=ibdata1:10M;ibdata2:10M:autoextend
-
Khi sử dụng InnoDB, cơ chế chính được sử dụng là vùng đệm. InnoDB phụ thuộc rất nhiều vào vùng đệm và theo nguyên tắc chung, tham số innodb_buffer_pool_size phải chiếm khoảng 60% đến 80% tổng số RAM có sẵn trên máy chủ. Hãy nhớ rằng bạn cũng nên để lại một số RAM cho các quá trình đang chạy trong HĐH;
-
InnoDB’s innodb_log_file_size phải được đặt càng lớn càng tốt, nhưng không lớn hơn mức cần thiết. Trong trường hợp này, hãy nhớ rằng kích thước tệp nhật ký lớn hơn sẽ tốt hơn cho hiệu suất, nhưng kích thước càng lớn thì thời gian khôi phục sau khi gặp sự cố càng nhiều. Do đó, không có giải pháp "một kích thước phù hợp với tất cả", nhưng người ta nói rằng kích thước kết hợp của các tệp nhật ký phải đủ lớn. Điều này giúp máy chủ MySQL thường xuyên làm việc với hoạt động kiểm tra và xả đĩa. Điều này giúp tiết kiệm quá nhiều IO CPU và ổ đĩa và có thể chạy trơn tru trong thời gian cao điểm hoặc hoạt động khối lượng công việc cao. Mặc dù cách tiếp cận được đề xuất là tự kiểm tra và thử nghiệm và tự tìm ra giá trị tối ưu;
-
Giá trị innodb_log_buffer_size phải được đặt thành ít nhất 16M. Bộ đệm nhật ký lớn cho phép các giao dịch lớn chạy mà không cần ghi nhật ký vào đĩa trước khi các giao dịch cam kết lưu một số I / O đĩa;
-
Khi điều chỉnh innodb_flush_log_at_trx_commit, hãy nhớ rằng tham số này chấp nhận ba giá trị - 0, 1 và 2. Với giá trị 1, bạn sẽ tuân thủ ACID và với các giá trị 0 hoặc 2, bạn sẽ có được hiệu suất cao hơn, nhưng độ tin cậy kém hơn vì trong trường hợp đó, các giao dịch mà nhật ký chưa được chuyển vào đĩa có thể bị mất khi gặp sự cố;
-
Để đặt innodb_lock_wait_timeout thành một giá trị thích hợp, hãy nhớ rằng tham số này xác định thời gian tính bằng giây (giá trị mặc định là 50) trước phát hành lỗi sau và khôi phục báo cáo hiện tại:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
-
Trong InnoDB, có sẵn nhiều phương thức xả. Theo mặc định, cài đặt này được đặt thành “async_unbuffered” trên máy Windows nếu giá trị được đặt thành NULL và thành “fsync” trong máy Linux. Dưới đây là các phương pháp và công việc của chúng:
Phương pháp xả InnoDB | Mục đích |
bình thường | InnoDB sẽ sử dụng I / O không đồng bộ mô phỏng và I / O được đệm. |
bỏ bộ đệm | InnoDB sẽ sử dụng I / O không đồng bộ mô phỏng và I / O không đệm. |
async_unbuffered | InnoDB sẽ sử dụng I / O không đồng bộ của Windows và I / O không đệm. Cài đặt mặc định trên máy Windows. |
fsync | InnoDB sẽ sử dụng hàm fsync () để xóa dữ liệu và các tệp nhật ký. Cài đặt mặc định trên máy Linux. |
O_DSYNC | InnoDB sẽ sử dụng O_SYNC để mở và xóa các tệp nhật ký và hàm fsync () để xóa các tệp dữ liệu. O_DSYNC nhanh hơn O_DIRECT, nhưng dữ liệu có thể nhất quán hoặc không nhất quán do độ trễ hoặc sự cố hoàn toàn. |
nosync | Được sử dụng để kiểm tra hiệu suất nội bộ - không được hỗ trợ. |
littlesync | Được sử dụng để kiểm tra hiệu suất nội bộ - không được hỗ trợ. |
O_DIRECT | InnoDB sẽ sử dụng O_DIRECT để mở các tệp dữ liệu và hàm fsync () để xóa cả dữ liệu và tệp nhật ký. So với O_DSYNC, O_DIRECT ổn định hơn và dữ liệu nhất quán hơn, nhưng chậm hơn. Bộ nhớ đệm hệ điều hành sẽ được tránh sử dụng cài đặt này - cài đặt này là cài đặt được khuyến nghị trên các máy Linux. |
O_DIRECT_NO_FSYNC | InnoDB sẽ sử dụng O_DIRECT trong quá trình xả I / O - phần “NO_FSYNC” xác định rằng hàm fsync () sẽ bị bỏ qua. |
- Bạn cũng nên xem xét việc bật cài đặt innodb_file_per_table. Tham số này được BẬT theo mặc định trong MySQL 5.6 trở lên. Tham số này giúp bạn giải quyết các vấn đề quản lý liên quan đến bảng InnoDB bằng cách lưu trữ chúng trong các tệp riêng biệt và tránh các từ điển chính và bảng hệ thống bị cồng kềnh. Việc bật biến này cũng giúp tránh phải đối mặt với sự phức tạp khi khôi phục dữ liệu khi một bảng nhất định bị hỏng
- Bây giờ bạn đã sửa đổi các cài đặt này theo hướng dẫn được nêu ở trên, bạn gần như đã sẵn sàng để bắt đầu! Trước khi bắt đầu chạy, có lẽ bạn nên theo dõi tệp bận rộn nhất trong toàn bộ cơ sở hạ tầng InnoDB - ibdata1.
Xử lý ibdata1
Có một số lớp thông tin được lưu trữ trong ibdata1:
- Dữ liệu của các bảng InnoDB;
- Chỉ mục của bảng InnoDB;
- Siêu dữ liệu bảng InnoDB;
- Dữ liệu điều khiển đồng thời đa vũ trụ (MVCC);
- Bộ đệm viết đôi - bộ đệm như vậy cho phép InnoDB khôi phục từ các trang đã viết một nửa. Mục đích của bộ đệm như vậy là để ngăn chặn dữ liệu bị hỏng;
- Bộ đệm chèn - bộ đệm như vậy được InnoDB sử dụng để đệm các bản cập nhật cho cùng một trang để chúng có thể được thực hiện ngay lập tức chứ không phải lần lượt.
Khi xử lý các tập dữ liệu lớn, tệp ibdata1 có thể cực kỳ lớn và đây có thể là cốt lõi của một vấn đề rất khó chịu - tệp chỉ có thể phát triển và theo mặc định, nó không thể thu nhỏ. Bạn có thể tắt MySQL và xóa tệp này nhưng điều này không được khuyến khích trừ khi bạn biết mình đang làm gì. Khi bị xóa, MySQL sẽ không hoạt động bình thường vì từ điển và bảng hệ thống không còn, do đó bảng hệ thống chính bị hỏng.
Để thu nhỏ ibdata1 một lần và mãi mãi, hãy làm theo các bước sau:
- Kết xuất tất cả dữ liệu từ cơ sở dữ liệu InnoDB. Bạn có thể sử dụng mysqldump hoặc mysqlpump cho hành động này;
- Bỏ tất cả cơ sở dữ liệu ngoại trừ cơ sở dữ liệu mysql, performance_schema và information_schema;
- Dừng MySQL;
- Thêm phần sau vào tệp my.cnf của bạn:
[mysqld] innodb_file_per_table = 1 innodb_flush_method = O_DIRECT innodb_log_file_size = 25% of innodb_buffer_pool_size innodb_buffer_pool_size = up to 60-80% of available RAM.
- Xóa các tệp ibdata1 và ib_logfile * (các tệp này sẽ được tạo lại khi khởi động lại MySQL tiếp theo);
- Khởi động MySQL và khôi phục dữ liệu từ kết xuất bạn đã lấy trước đó. Sau khi thực hiện các bước nêu trên, tệp ibdata1 sẽ vẫn phát triển, nhưng nó sẽ không còn chứa dữ liệu từ các bảng InnoDB nữa - tệp sẽ chỉ chứa siêu dữ liệu và mỗi bảng InnoDB sẽ tồn tại bên ngoài ibdata1. Bây giờ, nếu bạn truy cập thư mục / var / lib / mysql, bạn sẽ thấy hai tệp đại diện cho mỗi bảng mà bạn có với công cụ InnoDB. Các tệp sẽ giống như vậy:
- demotable.frm
- demotable.ibd
Tệp .frm chứa tiêu đề công cụ lưu trữ và tệp .ibd chứa dữ liệu bảng và chỉ mục của bảng của bạn.
Trước khi triển khai các thay đổi, hãy đảm bảo tinh chỉnh các thông số theo cơ sở hạ tầng của bạn. Các thông số này có thể tạo ra hoặc phá vỡ hiệu suất của InnoDB, vì vậy hãy đảm bảo luôn theo dõi chúng. Bây giờ bạn nên đi!
Tóm tắt
Tóm lại, tối ưu hóa hiệu suất của InnoDB có thể là một lợi ích lớn nếu bạn phát triển các ứng dụng yêu cầu tính toàn vẹn dữ liệu và hiệu suất cao cùng một lúc - InnoDB cho phép bạn thay đổi dung lượng bộ nhớ mà engine được phép tiêu thụ, để thay đổi kích thước tệp nhật ký, phương pháp xả mà công cụ sử dụng, v.v. - những thay đổi này có thể làm cho InnoDB hoạt động cực kỳ hiệu quả nếu chúng được điều chỉnh đúng cách. Trước khi thực hiện bất kỳ cải tiến nào, hãy cẩn thận với hậu quả của các hành động của bạn đối với cả máy chủ và MySQL của bạn.
Như mọi khi, trước khi tối ưu hóa bất kỳ thứ gì cho hiệu suất, hãy luôn thực hiện (và kiểm tra!) sao lưu để bạn có thể khôi phục dữ liệu của mình nếu cần và luôn kiểm tra bất kỳ thay đổi nào trên máy chủ cục bộ trước khi triển khai các thay đổi cho phiên bản sản xuất.