L ỜI CAM ĐOAN
2.3.1. Một số storage engine có sẵn
Phần này giới thiệu một số storage engine được MySQL AB phát triển và được tích hợp sẵn hoặc không (tùy phiên bản) trên máy chủ MySQL. Các storge engine này có thể được chia theo 2 nhóm: các storage engine không hỗ trợ giao tác và các storage engine có hỗ trợ giao tác. Để kiểm tra các storage engine này có sẵn hay không trong một phiên bản MySQL nào đó, sử dụng câu lệnh SHOW ENGINES.
2.3.1.1. MyISAM
Là storage engine mặc định từ phiên bản 3.23 cho đến phiên bản 5.5.5 thì đổi thành InnoDB. MyISAM là cơ chế truy cập tệp được sử dụng trong hầu hết các ứng
dụng kho dữ liệu, thương mại điện tử, các ứng dụng doanh nghiệp. Các tệp MyISAM
là mở rộng của ISAM (phương thức truy cập tệp tuần tự theo chỉ mục) có bổ sung các
tối ưu như các cơ chế đánh chỉ mục và tối ưu hóa tăng tốc độ. Trong MyISAM, điều
khiển đồng thời bằng các khóa mức bảng.
MyISAM được đánh giá là một storage engine đáng tin cậy cho các ứng dụng yêu cầu tìm kiếm dữ liệu nhanh, do đó phù hợp với các ứng dụng cần hiệu suất đọc dữ liệu
cao.
Về phương diện lưu trữ vật lí: dữ liệu được lưu trữ theo dòng, mỗi bảng
MyISAM được lưu trữ trên ba tệp:
Các tệp <tên bảng>.Myd: chứa các dòng dữ liệu
Các tệp <tên bảng>.Myi: chứa các chỉ mục của bảng.
Định dạng bảng lưu trữ: MyISAM hỗ trợ các định dạng tệp sau:
- Cố định (fixed hay static): là định dạng mặc định cho các bảng MyISAM. Nó là
định dạng được sử dụng khi trong bảng không chứa các cột kiểu VARCHAR, TEXT hay BLOB. Khi đó, mỗi cột có độ dài cố định, và hệ quả là mỗi dòng sẽ có độ dài cố định. Điều đó có nghĩa là khi một dòng bất kì bị xóa thì chúng chỉ bị thay thế bởi các
dòng có cùng chiều dài nên không bị phân mảnh. Đây là định dạng bảng đơn giản nhất
và an toàn nhất và nhanh nhất vì việc tìm kiếm dữ liệu dựa trên số dòng trên bảng chỉ
mục. Lấy số dòng đó nhân với độ dài dòng có thể tính ngay được vị trí của dòng đó
trên tệp. Hơn nữa, khi duyệt bảng, quá trình đọc đĩa được thực hiện dễ dàng bằng cách đọc một hằng số của các dòng.
Định dạng cố định có những ưu điểm sau:
Rất nhanh
Dễ dàng lưu đệm
Dễ xây dựng lại sau đổ vỡ, bởi vì các dòng được lưu trữ tại các vị trí cố định
Không bị phân mảnh
Tuy nhiên, yêu cầu nhiều không gian đĩa hơn các định dạng khác
-Định dạng động (dynamic): là định dạng được sử dụng khi trong bảng chứa các
cột kiểu VARCHAR có độ dài lớn hơn 3, TEXT, hoặc BLOB hoặc nếu bảng được tạo
với lựa chọn ROW_FORMAT = DYNAMIC.
Mỗi dòng sẽ có một header để chỉ ra độ dài của dòng đó. Trong định dạng lưu trữ
này, các dòng có thể cần một lượng không gian lớn. Khi xóa một dòng (hoặc dòng
được chỉnh sửa có độ dài nhỏ hơn), không gian trống tạo ra có thể được sử dụng lại. Do đó, định dạng này có thể sử dụng hiệu quả không gian lưu trữ nhưng cũng rất dễ
xảy ra phân mảnh giữa các dòng và hệ quả là làm giảm hiệu suất truy cập bảng. Đặc điểm:
Phức tạp hơn.
Không gian lưu trữ ít hơn nhiều so với định dạng cố định
Sử dụng không gian lưu trữ cho mỗi dòng hiệu quả hơn, vì không gian được
cấp theo đúng nhu cầu. Tuy nhiên, rất dễ phân mảnh.
Khó khăn hơn khi xây dựng lại sau đổ vỡ, vì các dòng có thể bị phân thành nhiều mảnh và các liên kết (các đoạn) có thể bị mất.
Các định dạng cố định và động được lựa chọn tự động phụ thuộc vào kiểu dữ liệu đang sử dụng trong bảng đó.
- Định dạng nén (compressed): là định dạng chỉ đọc được sinh ra bởi công cụ
myisampack, các bảng nén có thể giải nén bằng myisamchk. Tỉ lệ nén có thể đạt tới
75%.
Các bảng nén có đặc điểm sau:
Sử dụng ít không gian đĩa, có ích khi sử dụng trên các đĩa có tốc độ chậm (như CD-ROM).
Mỗi dòng được nén độc lập nên rất ít chi phí truy cập. Mỗi cột được nén khác nhau. Thường sử dụng cây Huffman khác nhau cho mỗi cột. Sử dụng một vài kiểu nén như: nén không gian hậu tố, nén không gian tiền tố.
Số có giá trị là 0 được lưu trữ sử dụng 1 bit.
Nếu giá trị trong một cột kiểu integer có phạm vi nhỏ, kiểu đó được lưu trữ sử
dụng kiểu nhỏ nhất. Ví dụ, một cột BIGINT (8 byte) có thể được lưu trữ như một
cột TINYINT (1 byte) nếu tất cả các giá trị của nó nằm trong phạm vi từ -128
đến 127.
Nếu một cột chỉ có một tập nhỏ các giá trị, kiểu dữ liệu được chuyển đổi sang
kiểu ENUM.
Một cột có thể sử dụng bất kì sự kết hợp của các kiểu nén trên. Có thể nén trên các dòng độ dài cố định và độ dài động.
Các phương thức lập chỉ mục:
B-Tree: thường được sử dụng. Công thức tính kích thước của tệp chỉ mục: (key – length + 4)/0.67.
R-Tree: lập chỉ mục cho các dữ liệu địa lí.
Full text: thiết kế riêng cho hệ thống tìm kiếm fulltext của MySQL.
Điều khiển đồng thời: MyISAM sử dụng các khóa mức bảng. Trong thực tế,
MyISAM sử dụng 3 loại khóa:
- READ LOCAL: được sử dụng bởi các truy vấn chỉ đọc, kiểu khóa này hiếm khi chặn các thao tác chỉnh sửa cũng như ngăn chặn dữ liệu thay đổi trong suốt quá trình truy vấn.
- Các khóa đọc (hay khóa chia sẻ): chặn các thao tác chỉnh sửa, gồm cả thao tác chèn. Nó thường được sử dụng khi một công cụ bên ngoài như myisamcheck cần truy cập trực tiếp tới một bảng.
- Các khóa ghi (hay khóa độc quyền): sử dụng với các câu lệnh xóa (DELETE),
chỉnh sửa (UPDATE) và đôi khi cả chèn (INSERT). Tất cả các thao tác đọc ghi dữ liệu
MyISAM không hỗ trợ giao tác. Để hiệu quả các định dạng lưu trữ luôn được thực
thi trong chế độ AUTOCOMMIT = 1. Các khối chỉ mục được lưu trữ tạm thời trên bộ đệm chính.
Dữ liệu được sao lưu sử dụng mysqldump (SQL Scripts) hoặc mysqlhotcopy (sao chép nhị phân của các tệp bảng).
Một số giới hạn của MyISAM: Giới hạn lưu trữ: 256 TB
Giới hạn các dòng trên một bảng là: 232(1.844E+19). Giới hạn các cột trên một chỉ mục là: 16
Độ dài khóa tối đa là: 1000 byte. Tuy nhiên có thể thay đổi bằng cách thay đổi
nguồn và dịch lại.
2.3.1.2. InnoDB
Sự bùng nổ của Internet cùng với sự cải thiện vượt bậc của khả năngổ cứng và bộ
nhớ trong những năm gần đây khiến cho yêu cầu về tính đồng thời, tính sẵn sàng, độ
tin cậy và khôi phục sau sự cố được quan tâm nhiều hơn. Nhận thấy xu hướng đó, đến
phiên bản 5.5.5. MySQL đã quyết định sử dụng InnoDB là một storage engine mặc định thay thế cho MyISAM.
Một số đặc trưng chính nổi bật của InnoDB:
Về phương diện lưu trữ vật lí: InnoDB lưu trữ các bảng và chỉ mục trong một
không gian bảng riêng (tablespace), có thể chứa trong một vài tệp (hoặc một vùng đĩa
nguyên). Các bảng InnoDB có thể rất lớn. Khi khởi động InnoDB, MySQL tạo một tệp
dữ liệu tự động mở rộng 10MB có tên là ibdata1 và 2 tệp đăng nhập (log file) có tên là
ib_logfile0 và ib_logfile1 có dung lượng mỗi tệp là 5MB trong thư mục MySQL. Khi tạo bảng InnoDB, các tệp định nghĩa bảng .frm không chỉ được lưu trữ trong thư mục
CSDL mà còn được duy trì một entry trong từ điển dữ liệu nội bộ bên trong không gian bảng.
Điều khiển đồng thời: sử dụng cơ chế khóa mức dòng và đọc nhất quán kiểu Oracle làm tăng tính nhất quán và tăng hiệu quả sử dụng tài nguyên. Để đạt được tính đồng thời cao hơn, InnoDB sử dụng cơ chế điều khiển đồng thời đa phiên bản
(MVCC).
Các chế độ khóa: InnoDB sử dụng cơ chế khóa 2 pha: khóa ngầm định với 2 loại
khóa chuẩn: khóa chia sẻ, khóa độc quyền và khóa tường minh được triển khai sử
dụng một số cơ chế khóa đa phạm vi cho phép đồng thời tồn tại các khóa bản ghi và các khóa cho toàn bộ bảng.
Các khóa chuẩn (ngầm định) gồm:
Khóa độc quyền (X): cho phép một giao tác được chỉnh sửa và xóa một dòng. Ngoài ra, InnoDB cũng sử dụng các khóa mục tiêu (intention lock) để thực hiện
khóa trên nhiều mức phạm vi khác nhau. Các khóa mục tiêu là các khóa mức bảng, thể
hiện loại khóa nào mà một giao tác sẽ yêu cầu tiếp theo cho một dòng trong bảng.
InnoDB sử dụng 2 loại khóa mục tiêu (giả thiết rằng giao tác T yêu cầu một khóa trên bảng t):
Khóa mục tiêu chia sẻ (IS): khi giao tác T định thiết lập khóa S trên từng dòng trong bảng t, được thiết lập thông qua câu lệnh SELECT … LOCK IN SHARE
MODE.
Khóa mục tiêu độc quyền (IX): giao tác T định thiết lập các khóa X trên các dòng
đó, được thiết lập thông qua câu lệnh SELECT … FOR UPDATE.
Giao thức khóa mục tiêu như sau:
Trước khi một giao tác có thể yêu cầu một khóa S trên một dòng trong bảng t, trước tiên, nó phải yêu cầu một khóa IS hoặc một khóa mạnh hơn trên t.
Trước khi một giao tác có thể yêu cầu một khóa X trên một dòng, trước tiên nó phải yêu cầu một khóa IX trên t.
Các luật có thể được tổng kết trong bảng 2.1. Khóa sẽ được cấp cho các yêu cầu giao tác tương thích với các khóa đang tồn tại và ngược lại sẽ không cấp khóa nếu không tương thích. Giao tác đợi cho đến khi các khóa xung đột đang tồn tại được giải
phóng. Nếu một yêu cầu khóa xung đột với một khóa đã tồn tại và không được cấp
quyền, nó có thể gây ra deadlock và xuất hiện một lỗi.
Bảng 2.1: Ma trận khả năng tương thích giữa các kiểu khóa trong InnoDB [8]
X IX S IS
X Xung đột Xung đột Xung đột Xung đột
IX Xung đột Tương thích Xung đột Tương thích
S Xung đột Xung đột Tương thích Tương thích
IS Xung đột Tương thích Tương thích Tương thích
Như vậy, các khóa mục tiêu không khóa bất kì thứ gì ngoại trừ các yêu cầu khóa trên toàn bộ bảng. Mục đích chính của IS và IX là chỉ ra rằng có một dòng đang bị
khóa hoặc sắp được khóa trên một bảng.
Các kiểu khóa: Trong InnoDB, các khóa mức dòng thực chất là các khóa bản ghi
chỉ mục. Có một số kiểu khóa bản ghi như sau:
Khóa bản ghi (record lock): là khóa trên các bản ghi chỉ mục.
Khóa khoảng trống (gap lock): là khóa trên khoảng trống giữa các bản ghi chỉ mục
Khóa Next – key: là sự kết hợp giữa một khóa bản ghi và một khóa khoảng trống
trên khoảng trống trước bản ghi chỉ mục đó. Nếu một phiên chứa khóa S hoặc X trên bản ghi r thì một phiên khác không thể chèn một bản ghi chỉ mục mới vào khoảng
trống trước r.
Các khóa bản ghi luôn khóa các bản ghi ngay cả khi bảng được định nghĩa không
chứa chỉ mục. Trong trường hợp đó, InnoDB tạo một chỉ mục cụm và sử dụng chỉ mục
cụm đó để khóa bản ghi.
Hỗ trợ giao tác: Được thiết kế theo mô hình ACID với các giao tác có khả năng
commit, rollback, khôi phục sau đổ vỡ để bảo vệ dữ liệu của người dùng. CSDL được
duy trì trong một trạng thái nhất quán tại mọi thời điểm – sau mỗi thao tác commit
hoặc rollback, và trong khi thực hiện các giao tác trong tiến trình. Đồng thời, các giao
tác được cách ly với các giao tác khác tránh xung đột; Kết quả của các giao tác là bền
vững: giao tác chỉ thành công khi tất cả các lệnh đã được hoàn thành hoặc không gì cả. Do đó, CSDL được đảm bảo an toàn trước những nguy cơ đổ vỡ hệ thống, lỗi nguồn,
…
Các mức cách ly:được triển khai trên cả 4 mức cách ly chuẩn của MySQL. Mặc định là REPEATABLE READ với chiến lược khóa next – key để ngăn chặn đọc ma (đọc “phantom”).
Khi thực thi trong mức cách ly repeatable read, vấn đề xảy ra khi bên trong cùng một giao tác, nếu cùng một truy vấn tạo ra những tập kết quả khác nhau tại những thời điểm khác nhau, gọi là đọc “phantom” (đọc ma). Giả sử bảng child có chỉ mục trên cột
ID, có giá trị trong các ID 90 và 102 và có yêu cầu đọc và khóa mọi dòng trong bảng
có ID lớn hơn 100. Nếu chỉ khóa trên các bản ghi chỉ mục trong vùng được duyệt thì một giao tác khác có thể chèn một dòng mới vào bảng có ID=101. Nếu thực thi cùng một câu lệnh SELECT trong cùng giao tác sau đó thì có thể nhìn thấy dòng 101, khi
đó, dòng 101 gọi là dòng phantom. Để ngăn chặn điều này, sử dụng thuật toán Next – key, InnoDB không chỉ khóa trên bản ghi mà cả khoảng trống trước bản ghi đó. Do đó,
nó không chỉ khóa bản ghi 102 mà khóa cả khoảng trống có ID = 101, và một giao tác
khác không thể chèn dữ liệu vào bảng trên các dòng có ID >100.
Vấn đề Deadlock: Deadlock là một vấn đề kinh điển của CSDL hỗ trợ giao tác
nhưng nó không nguy hiểm trừ khi xảy ra thường xuyên và không thể thực hiện được
những câu lệnh đơn giản.
InnoDB tự động phát hiện deadlock và rollback một hoặc nhiều giao tác để phá vỡ
deadlock. Khi InnoDB thực thi rollback hoàn toàn một giao tác, mọi khóa khóa bởi giao tác đó được giải phóng. Tuy nhiên, nếu chỉ có một câu lệnh SQL rollback khi gặp
lỗi thì các khóa được thiết lập bởi câu lệnh vẫn có thể bị giữ do InnoDB không thể biết được khóa nào được thiết lập bởi câu lệnh nào.
Nếu một câu lệnh SELECT gọi tới một hàm lưu trữ trong một giao tác và câu lệnh
bên trong của hàm đó lỗi, câu lệnh bị khôi phục lại (rollback) và nếu rollback được
thực thi thì sau đó, toàn bộ giao tác bị khôi phục lại (rollback).
Chỉ mục: InnoDB sử dụng các loại chỉ mục sau:
Chỉ mục cụm: được xây dựng dựa trên các khóa chính của bảng, chứa các giá trị
dữ liệu theo cấu trúc B-Tree.
- Nếu định nghĩa khóa chính PRIMARY KEY cho một bảng, InnoDB sẽ sử dụng
khóa chính đó như là chỉ mục cụm.
- Nếu không định nghĩa khóa chính cho bảng, InnoDB sử dụng chỉ mục UNIQUE
có mọi cột khóa not NULL đầu tiên làm chỉ mục cụm.
- Nếu bảng không có khóa chính và chỉ mục UNIQUE phù hợp, InnoDB sinh ra
một chỉ mục cụm ẩn trên các cột chứa giá trị ID dòng. Các dòng được sắp xếp bởi giá
trị ID mà InnoDB gán cho. ID dòng là một trường 6 byte mà giá trị sẽ tăng đơn điệu
khi chèn một dòng mới. Do đó, các dòng được sắp xếp bởi các ID dòng như thứ tự
chèn vật lí.
Chỉ mục phụ: mọi chỉ mục khác ngoài chỉ mục cụm được gọi là chỉ mục phụ. Mỗi
bản ghi của chỉ mục phụ chứa khóa chỉ mục (index key) và giá trị khóa chính. Giá trị
khóa chính được sử dụng để xác định chỉ mục cụm. Nếu khóa chính quá dài sẽ tốn
nhiều không gian lưu trữ do đó nên sử dụng các khóa chính ngắn.
Chỉ mục băm: Nếu một bảng InnoDB nằm gọn trong bộ nhớ trong, chỉ mục băm
có thể tăng tốc độ truy vấn bằng cách cho phép tìm kiếm trực tiếp một phần tử bất kì, trả ra giá trị chỉ mục vào trong một tập các con trỏ đã được sắp xếp. InnoDB có một cơ
chế giám sát chỉ mục. Nếu nhận thấy truy vấn có thể đạt được hiệu quả từ việc xây
dựng chỉ mục băm, nó sẽ tạo chỉ mục băm một cách tự động. Chỉ mục băm được xây
dựng dựa trên chỉ mục B-tree của bảng. InnoDB có thể xây dựng một chỉ mục băm