Một yếu tố chính trong hiệu suất cơ sở dữ liệu là công cụ lưu trữ được sử dụng bởi cơ sở dữ liệu và cụ thể hơn là các bảng của nó. Các công cụ lưu trữ khác nhau cung cấp hiệu suất tốt hơn trong tình huống này so với tình huống khác. Để sử dụng chung, có hai ứng cử viên được xem xét. Đây là MyISAM, là công cụ lưu trữ MySQL mặc định, hoặc InnoDB, là một công cụ thay thế được tích hợp sẵn cho MySQL dành cho cơ sở dữ liệu hiệu suất cao. Trước khi có thể hiểu được sự khác biệt giữa hai công cụ lưu trữ, chúng ta cần hiểu thuật ngữ “khóa”.
Khóa trong MySQL là gì?
Để bảo vệ tính toàn vẹn của dữ liệu được lưu trữ trong cơ sở dữ liệu, MySQL sử dụng khóa. Nói một cách đơn giản, khóa có nghĩa là bảo vệ dữ liệu khỏi bị truy cập. Khi một khóa được áp dụng, không thể sửa đổi dữ liệu ngoại trừ truy vấn bắt đầu khóa. Khóa là một thành phần cần thiết để đảm bảo tính chính xác của thông tin được lưu trữ. Mỗi công cụ lưu trữ có một phương pháp khóa khác nhau được sử dụng. Tùy thuộc vào dữ liệu và thực tiễn truy vấn của bạn, một công cụ có thể hoạt động tốt hơn một công cụ khác. Trong loạt bài này, chúng ta sẽ xem xét hai loại khóa phổ biến nhất được sử dụng bởi hai công cụ lưu trữ của chúng tôi.
Khóa bảng: Kỹ thuật khóa toàn bộ bảng khi một hoặc nhiều ô trong bảng cần được cập nhật hoặc xóa. Khóa bảng là phương pháp mặc định được sử dụng bởi công cụ lưu trữ mặc định, MyISAM.
Ví dụ:MyISAM Table Locking | Cột A | Cột B | Cột C | |
Truy vấn 1 CẬP NHẬT | Hàng 1 | Viết | dữ liệu | dữ liệu |
Truy vấn 2 CHỌN (Chờ) | Hàng 2 | dữ liệu | dữ liệu | dữ liệu |
CẬP NHẬT Truy vấn 3 (Chờ) | Hàng 3 | dữ liệu | dữ liệu | dữ liệu |
Truy vấn 4 CHỌN (Chờ) | Hàng 4 | dữ liệu | dữ liệu | dữ liệu |
Truy vấn 5 CHỌN (Chờ) | Hàng 5 | dữ liệu | dữ liệu | dữ liệu |
Ví dụ minh họa cách một thao tác ghi đơn sẽ khóa toàn bộ bảng khiến các truy vấn khác phải đợi kết thúc truy vấn CẬP NHẬT. |
Khóa cấp hàng: Hành động khóa phạm vi hàng hiệu quả trong bảng khi một hoặc nhiều ô trong phạm vi được sửa đổi hoặc xóa. Khóa mức hàng là phương pháp được sử dụng bởi công cụ lưu trữ InnoDB và dành cho cơ sở dữ liệu hiệu suất cao.
Ví dụ:Khóa cấp hàng InnoDB | Cột A | Cột A | Cột A | |
Truy vấn 1 CẬP NHẬT | Hàng 1 | Viết | dữ liệu | dữ liệu |
Truy vấn 2 CHỌN | Hàng 2 | Đang đọc | dữ liệu | dữ liệu |
CẬP NHẬT Truy vấn 3 | Hàng 3 | dữ liệu | Viết | dữ liệu |
Truy vấn 4 CHỌN | Hàng 4 | Đang đọc | Đang đọc | Đang đọc |
Truy vấn 5 CHỌN | Hàng 5 | Đang đọc | dữ liệu | Đang đọc |
Ví dụ cho thấy cách sử dụng khóa cấp độ hàng cho phép nhiều truy vấn chạy trên các hàng riêng lẻ bằng cách chỉ khóa các hàng đang được cập nhật thay vì toàn bộ bảng. |
MyISAM so với InnoDB
Bằng cách so sánh hai công cụ lưu trữ, chúng ta đi đến mấu chốt của cuộc tranh cãi giữa việc sử dụng InnoDB thay vì MyISAM. Ứng dụng hoặc trang web có bảng được sử dụng thường xuyên hoạt động đặc biệt tốt bằng cách sử dụng công cụ lưu trữ InnoDB bằng cách giải quyết các tắc nghẽn khóa bảng. Tuy nhiên, câu hỏi về việc sử dụng cái này thay cho cái kia là chủ quan vì cả hai đều không hoàn hảo trong mọi tình huống. Có những điểm mạnh và hạn chế đối với cả hai công cụ lưu trữ. Kiến thức sâu sắc về cấu trúc cơ sở dữ liệu và các thực hành truy vấn là rất quan trọng để chọn công cụ lưu trữ tốt nhất cho các bảng của bạn.
MyISAM sẽ hoạt động tốt hơn InnoDB trên các bảng lớn đòi hỏi hoạt động đọc nhiều hơn so với hoạt động ghi. Khả năng đọc của MyISAM vượt trội hơn InnoDB vì việc khóa toàn bộ bảng nhanh hơn so với việc tìm ra hàng nào bị khóa trong bảng. Càng có nhiều thông tin trong bảng, InnoDB càng mất nhiều thời gian để tìm ra những thông tin nào không thể truy cập được. Nếu ứng dụng của bạn dựa vào các bảng khổng lồ không thay đổi dữ liệu thường xuyên, thì MyISAM sẽ hoạt động kém hơn InnoDB. Ngược lại, InnoDB hoạt động tốt hơn MyISAM khi dữ liệu trong bảng thay đổi thường xuyên. Bảng thay đổi ghi dữ liệu nhiều hơn đọc dữ liệu mỗi giây. Trong những tình huống này, InnoDB có thể theo kịp số lượng lớn yêu cầu dễ dàng hơn so với việc khóa toàn bộ bảng cho từng yêu cầu.
Tôi có nên sử dụng InnoDB với WordPress, Magento hoặc Joomla Sites không?
Câu trả lời ngắn gọn ở đây là có, trong hầu hết các trường hợp. Những người hữu ích nhất của Liquid Web trong Nhóm hỗ trợ lưu trữ đã gặp phải một số nút cổ chai khóa bảng khi khách hàng đang sử dụng một số ứng dụng web tiêu chuẩn ngày nay. Hầu hết người dùng của các ứng dụng bên thứ ba phổ biến như WordPress, Magento và Joomla có kiến thức hạn chế về các thành phần cơ sở dữ liệu cơ bản hoặc mã liên quan để đưa ra quyết định sáng suốt về công cụ lưu trữ. Hầu hết các tắc nghẽn khóa bảng từ các hệ thống quản lý nội dung (CMS) này thường được giải quyết bằng cách thay đổi tất cả các bảng của trang web thành InnoDB thay vì MyISAM mặc định. Nếu bạn đang lưu trữ nhiều loại CMS này trên máy chủ của mình, sẽ có lợi nếu thay đổi công cụ lưu trữ mặc định trong MySQL để sử dụng InnoDB cho tất cả các bảng mới để mọi cài đặt bảng mới bắt đầu với InnoDB.
Đặt công cụ lưu trữ mặc định
Đặt công cụ lưu trữ mặc định của bạn thành InnoDB bằng cách thêm default_storage_engine =InnoDB tới [mysqld] của tệp cấu hình hệ thống có tại:/etc/my.cnf. Khởi động lại dịch vụ MySQL là cần thiết để máy chủ phát hiện các thay đổi đối với tệp.
~ $ cat /etc/my.cnf
[mysqld]
log-error=/var/lib/mysql/mysql.err
innodb_file_per_table=1
default-storage-engine=innodb
innodb_buffer_pool_size=128M
Chuyển đổi tất cả các bảng giữa MyISAM và InnoDB
Thật không may, MySQL vốn không có tùy chọn để chuyển đổi bảng, để lại từng bảng được thay đổi riêng lẻ. Nhóm hỗ trợ của Liquid Web đã cùng nhau đưa ra một kế hoạch bảo trì dễ thực hiện cho quy trình này. Tập lệnh mà bạn có thể chạy trên máy chủ cần thiết thông qua quyền truy cập trình bao (SSH) sẽ chuyển đổi tất cả các bảng giữa các công cụ lưu trữ.
Lưu ý Lập kế hoạch phù hợp khi thực hiện các hoạt động hàng loạt có tính chất này chỉ trong trường hợp thời gian chết xảy ra. Thực tiễn tốt nhất là sao lưu tất cả Cơ sở dữ liệu MySQL của bạn trước khi thực hiện một thay đổi lớn này, làm như vậy sẽ cung cấp một điểm khôi phục dễ dàng để ngăn chặn bất kỳ mất mát dữ liệu nào.Bước 1: Chuẩn bị
Lên kế hoạch bắt đầu vào thời điểm trong ngày khi thời gian ngừng hoạt động sẽ gây ra hậu quả tối thiểu. Bản thân quá trình này không yêu cầu bất kỳ thời gian chết nào, tuy nhiên, có thể cần thời gian chết để phục hồi sau các trường hợp không lường trước được.
Bước 2: Sao lưu tất cả cơ sở dữ liệu vào một tệp tin
Lệnh dưới đây tạo một bản sao lưu tệp duy nhất của tất cả cơ sở dữ liệu có tên all-databases-backup.sqld và có thể bị xóa sau khi chuyển đổi thành công và không có vấn đề gì rõ ràng.
mysqldump --all-databases > all-databases-backup.sql
Bước 3: Ghi lại các công cụ bảng hiện có vào một tệp
Chạy tập lệnh sau để ghi các công cụ bảng hiện có vào tệp có tên table-engine-backup.sql . Sau đó, bạn có thể "nhập" hoặc "chạy" tệp này sau để chuyển đổi trở lại công cụ ban đầu của chúng nếu cần.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=",Engine,";") FROM information_schema.tables WHERE table_schema NOT IN("mysql","information_schema","performance_schema");' | tee table-engine-backup.sql
Nếu bạn cần hoàn nguyên công cụ bảng vì bất kỳ lý do gì, hãy chạy:
mysql < table-engine-backup.sql
Bước 4a: Chuyển đổi bảng MyISAM sang InnoDB
Lệnh dưới đây sẽ tiếp tục ngay cả khi một bảng bị lỗi và cho bạn biết bảng nào không chuyển đổi được. Kết quả đầu ra được lưu vào tệp có tên convert-to-innodb.log để phục hồi sau w.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=InnoDB;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "MyISAM";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-innodb.log
Bước 4b:Chuyển đổi tất cả các bảng InnoDB sang MyISAM
Lệnh này sẽ tiếp tục ngay cả khi một bảng bị lỗi và cho bạn biết bảng nào không chuyển đổi được. Kết quả đầu ra cũng được lưu vào tệp có tên convert-to-myisam.log để xem xét sau.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=MyISAM;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "InnoDB";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-myisam.log
Chuyển đổi một bảng duy nhất giữa MyISAM và InnoDB
Các lệnh sau minh họa cách thực hiện chuyển đổi một bảng.
Lưu ý Thay thế database_name bằng tên cơ sở dữ liệu thích hợp và table_name bằng tên bảng chính xác. Đảm bảo rằng bạn có một bản sao lưu hợp lệ của bảng được đề cập trước khi tiếp tục.
Sao lưu một bảng vào một tệp
mysqldump database_name table_name > backup-table_name.sql
Chuyển đổi một bảng thành InnoDB
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=InnoDB;’
Chuyển đổi một bảng thành MyISAM:
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=MyISAM;’
Hãy xem các bài viết khác của chúng tôi trong loạt bài này, Hiệu suất MySQL:Xác định các Truy vấn Dài, để xác định các truy vấn chậm trong cơ sở dữ liệu của bạn. Hãy theo dõi bài viết tiếp theo của chúng tôi, nơi chúng tôi sẽ đề cập đến bộ nhớ đệm và tối ưu hóa.