Hệ quản trị cơ sở dữ liệu MySQL đã thực sự làm được điều này thông qua việc triển khai các storage engine, nơi chứa một tập các cơ chế lưu trữ, truy cập, hỗ trợ giao tác, các cơ chế khóa
Trang 1ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
NGUYỄN THỊ KHUÊ
NGHIÊN CỨU PHƯƠNG PHÁP XÂY DỰNG STORAGE ENGINE CHO HỆ QUẢN TRỊ
CƠ SỞ DỮ LIỆU MYSQL
LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN
Hà Nội – 2012
Trang 2ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
NGUYỄN THỊ KHUÊ
NGHIÊN CỨU PHƯƠNG PHÁP XÂY DỰNG STORAGE ENGINE CHO HỆ QUẢN TRỊ
CƠ SỞ DỮ LIỆU MYSQL
Ngành: Công nghệ thông tin Chuyên ngành: Hệ thống thông tin
Mã số: 60 48 05
LUẬN VĂN THẠC SĨ CÔNG NGHỆ THÔNG TIN
NGƯỜI HƯỚNG DẪN KHOA HỌC: T.s Nguyễn Hải Châu
Hà Nội – 2012
Trang 3MỤC LỤC
LỜI CAM ĐOAN 1
MỤC LỤC 2
DANH MỤC CÁC KÍ HIỆU VÀ CHỮ VIẾT TẮT 4
DANH MỤC CÁC BẢNG 4
DANH MỤC CÁC HÌNH VẼ 4
MỞ ĐẦU 5
CHƯƠNG 1 TỔNG QUAN VỀ MYSQL 7
1.1 Hệ quản trị cơ sở dữ liệu MySQL 7
1.2 Kiến trúc MySQL 9
1.3 Truy vấn dữ liệu trên MySQL 11
1.3.1 Giao diện SQL 11
1.3.2 Phân tách 11
1.3.3 Tối ưu truy vấn 12
1.3.4 Thực thi truy vấn 13
1.3.5 Bộ đệm truy vấn 13
1.3.6 Cache và Buffer 15
1.4 Các đặc trưng của MySQL 16
1.4.1 Quản lí kết nối và an ninh 16
1.4.2 Quản lí đồng thời 17
1.4.3 Giao tác 18
1.4.4 Điều khiển đồng thời đa phiên bản (MVCC) 21
1.4.5 Chỉ mục 22
CHƯƠNG 2 MYSQL PLUGGABLE STORAGE ENGINE 25
2.1 Storage engine là gì? 25
2.2 Kiến trúc pluggable storage engine 27
2.3 Một số storage engine điển hình 28
2.3.1 Một số storage engine có sẵn 28
2.3.1.1 MyISAM 28
2.3.1.2 InnoDB 31
2.3.1.3 Archive 36
2.3.1.4 Federated 36
2.3.1.5 NDB Cluster 39
2.3.1.6 Memory 39
2.3.1.7 Merge 40
2.3.1.8 Blackhole 42
2.3.1.9 CSV 42
2.3.2 Lưu trữ theo cột và storage engine 43
2.3.2.1 Kĩ thuật lưu trữ theo cột 43
2.3.2.2 InfoBright 45
2.3.3 NoSQL và storage engine 46
2.3.3.1 NoSQL là gì? 46
2.3.3.2 HandlerSocket 48
2.4 Sử dụng storage engine có sẵn 49
2.4.1 Lựa chọn storage engine phù hợp 49
2.4.2 Một số thao tác cơ bản 50
Trang 4CHƯƠNG 3 XÂY DỰNG STORAGE ENGINE 53
3.1 Cơ sở hạ tầng của một storage engine 53
3.2 Mã nguồn của MySQL 54
3.3 Cấu trúc Handlerton 55
3.4 Lớp Handler 58
3.5 Quá trình tạo một storage engine mới .61
KẾT LUẬN 73
TÀI LIỆU THAM KHẢO 74
Trang 5DANH MỤC CÁC KÍ HIỆU VÀ CHỮ VIẾT TẮT
Từ viết tắt Mô tả
MVCC (Multiversion concurrence control) Điều khiển đồng thời đa phiên bản
DANH MỤC CÁC BẢNG
Bảng 2.1 Ma trận tương thích giữa các kiểu khóa trong InnoDB 32 Bảng 2.2 Bảng so sánh tính năng giữa CSDL quan hệ và NoSQL 35 Bảng 2.3 Bảng tổng kết một số đặc trưng của một số storage engine
Trang 6MỞ ĐẦU
Hiệu suất thực thi là một tiêu chí quan trọng đánh giá sự thành công của một hệ cơ
sở dữ liệu Đặc biệt trong thời đại bùng nổ thông tin hiện nay, khi mà khối lượng dữ liệu cực lớn và tăng nhanh chóng, không ngừng kéo theo những đòi hỏi cao về tốc độ cũng như tính hiệu quả của các hệ cơ sở dữ liệu Tổ chức lưu trữ dữ liệu và triển khai
cơ chế truy cập dữ liệu (hay còn gọi là thiết kế vật lí cơ sở dữ liệu) là một trong những giải pháp quan trọng, cơ bản được lựa chọn nhằm cải thiện đáng kể hiệu suất của hệ thống Tổ chức lưu trữ và truy cập dữ liệu hợp lí và hiệu quả có thể đem lại những hiệu quả bất ngờ trong một số trường hợp
Thực tế chỉ ra rằng, mặc dù hiện nay có rất nhiều cách thức lưu trữ và tổ chức truy cập dữ liệu khác nhau, từ cách phân đoạn dữ liệu, tổ chức tệp trên các thiết bị, lưu đệm các dữ liệu có tần suất truy cập thường xuyên, hay các cơ chế lập chỉ mục để truy cập nhanh tới dữ liệu, … Tuy nhiên, mỗi cách thức có những ưu điểm và hạn chế riêng, có thể tốt trong trường hợp này nhưng lại không hiệu quả trong trường hợp khác Hay nói một cách khác, không thể có cơ chế tốt nhất cho mọi trường hợp
Hơn nữa, mỗi hệ quản trị cơ sở dữ liệu hiện nay chỉ có thể triển khai một hoặc một vài cơ chế nhất định vì bản thân các cơ chế khác nhau có thể có những xung đột gây ảnh hưởng lẫn nhau Và tất nhiên hệ quả là, mỗi hệ quản trị cơ sở dữ liệu thường chỉ đáp ứng tốt nhu cầu cho một hoặc một vài miền ứng dụng trong những trường hợp nhất định
Như vậy, có thể khẳng định rằng, không có cơ chế lưu trữ và truy cập tệp tốt cho mọi trường hợp cũng như không thể triển khai mọi cơ chế truy cập tệp trong một hệ quản trị cơ sở dữ liệu Sẽ thật lí tưởng nếu có thể triển khai nhiều cơ chế tổ chức, truy cập tệp như là các gói giải pháp để đáp ứng nhu cầu của từng ứng dụng cụ thể và dễ dàng tra lắp cũng như gỡ bỏ ra khỏi hệ thống Hệ quản trị cơ sở dữ liệu MySQL đã thực sự làm được điều này thông qua việc triển khai các storage engine, nơi chứa một tập các cơ chế lưu trữ, truy cập, hỗ trợ giao tác, các cơ chế khóa, cách ly, nhằm bổ sung các kiểu lưu trữ mới, dễ dàng tra lắp vào máy chủ thông qua cơ chế pluggable storage engine Nó có thể là một storage engine đã được xây dựng sẵn hay bất kì một storage engine tự phát triển mới Vì vậy, MySQL có thể đáp ứng được nhiều nhu cầu của nhiều ứng dụng trong nhiều hoàn cảnh khác nhau Cơ chế pluggable storage engine đã tạo nên tính linh hoạt, mềm dẻo có lẽ duy nhất có của MySQL, góp phần không nhỏ vào sự thành công của MySQL với tư cách là một hệ quản trị cơ sở dữ liệu
mã nguồn mở phổ biến nhất hiện nay
Đề tài “Nghiên cứu phương pháp xây dựng storage engine cho hệ quản trị cơ sở
dữ liệu MySQL” hướng tới tìm hiểu kiến trúc pluggable storage engine của MySQL Thông qua việc tìm hiểu một số storage engine điển hình và một số xu hướng lưu trữ
dữ liệu nổi bật hiện nay cùng một số storage engine tiêu biểu của xu hướng đó (như
Trang 7lưu trữ dữ liệu theo cột với InfoBright, NoSQL với HandlerSocket), luận văn đưa ra một cái nhìn tổng quan về MySQL storage engine cũng như một số gợi ý khi lựa chọn storage engine phù hợp cho một ứng dụng Đồng thời, luận văn cũng hướng tới việc tìm hiểu những yếu tố cần cân nhắc khi xây dựng storage engine như lựa chọn cách tổ chức lưu trữ dữ liệu, cách thức lưu đệm, hỗ trợ chỉ mục, hỗ trợ giao tác, các yêu cầu đặc biệt,… và cuối cùng đi tới nghiên cứu một tiến trình xây dựng một storage engine mới được cho là khả thi
Nội dung chính của luận văn được chia thành 3 phần:
Chương 1: Tổng quan về hệ quản trị CSDL MySQL Chương này giới thiệu
tổng quan về hệ quản trị cơ sở dữ liệu MySQL gồm: kiến trúc tổng quan của MySQL, những đặc điểm cơ bản của MySQL và đặc biệt nhấn mạnh những điểm khác biệt của MySQL so với các hệ QTCSDL khác như: sử dụng lớp pluggable storage engine cung cấp tính linh hoạt cho MySQL bằng khả năng lựa chọn cơ chế lưu trữ và truy cập phù hợp với từng ứng dụng; sử dụng các bộ đệm truy vấn và nhiều cơ chế lưu đệm khác nhau để cải thiện tốc độ truy vấn; triển khai các cơ chế chỉ mục, quản lí giao tác và lập chỉ mục tại các storage engine, …
Chương 2: MySQL Pluggable storage engine Trong chương này đi sâu nghiên
cứu về một cơ chế đặc biệt có lẽ chỉ duy nhất có trong MySQL, pluggable storage engine MySQL đưa ra một khái niệm mới đặc biệt, storage engine, nhằm xây dựng
các cơ chế truy cập tệp phù hợp nhất với từng ứng dụng cụ thể Phần này cũng tìm hiểu một số storage engine có sẵn và một số xu hướng phát triển của các cơ chế tổ chức, truy cập dữ liệu nổi bật hiện nay cùng một vài storage engine điển hình của các
xu hướng đó Từ đó, đưa ra một số gợi ý khi lựa chọn storage engine sử dụng cho ứng dụng của người dùng
Chương 3 Xây dựng storage engine Nghiên cứu một quy trình xây dựng
storage engine từ việc đưa ra các lựa chọn chức năng cần có của một storage engine, tìm hiểu cấu trúc handlerton và lớp handler trong MySQL đến tiến trình các giai đoạn thực hiện xây dựng một storage engine mới và cuối cùng là thử nghiệm chương trình thực nghiệm cho tiến trình đó
Trang 8CHƯƠNG 1 TỔNG QUAN VỀ MYSQL
Sự phát triển mạnh mẽ của phong trào mã nguồn mở trong những năm gần đây đã thực sự đem lại cho nền công nghiệp phần mềm những triển vọng mới Ngay từ khi được Richard Stallman khởi xướng (năm 1970) đến khi hệ điều hành Linux ra đời (năm 1991, do Linux Torvalds người Phần Lan viết nhân) và cho đến ngày nay, phần mềm mã nguồn mở dần khẳng định được vị thế của mình, với cộng đồng người phát triển lên tới hàng triệu người trên khắp thế giới, cùng sự phổ biến của một số phần mềm nguồn mở như Linux, Apache HTTP server, OpenSSL, MySQL, BIND, Sendmail,… hay những câu chuyện thành công của các công ty kinh doanh mã nguồn
mở như MySQL AB, Red Hat, Slackware,… (điều mà những người chống phong trào
mã nguồn mở cho là “không tưởng”)
Trong phong trào đó, MySQL nổi lên như là một hệ quản trị cơ sở dữ liệu (hệ QTCSDL) phổ biến nhất hiện nay với khoảng 8 triệu bản cài đặt trên khắp thế giới Vậy MySQL là gì? Cái gì khiến nó trở thành hệ QTCDL thành công đến như vậy?
1.1 Hệ quản trị cơ sở dữ liệu MySQL
MySQL là hệ QTCSDL thuộc sở hữu của MySQL AB, AB là từ viết tắt của từ Thụy Điển “aktiebolag” nghĩa là công ty cổ phần hay công ty, được bắt đầu như một liên minh vốn đầu tư với mục tiêu xây dựng một hệ cơ sở dữ liệu quan hệ nguồn mở đáng tin cậy thay thế hệ cơ sở dữ liệu độc quyền thương mại MySQL AB tạo ra doanh thu bằng cách bán giấy phép thương mại, hỗ trợ và cung cấp các dịch vụ phát triển chuyên nghiệp gồm tư vấn, đào tạo, chứng nhận sản phẩm
MySQL là hệ QTCSDL quan hệ hỗ trợ đầy đủ các câu lệnh SQL Nó cho phép phát triển trên nhiều nền tảng phần cứng khác nhau Hơn nữa, MySQL được phát triển dựa trên ngôn ngữ C/C++, ngôn ngữ sử dụng để xây dựng gần như toàn bộ hệ điều hành Linux cũng như Microsoft Windows và Macintosh Nó được thiết kế dựa trên kiến trúc client/server MySQL được đánh giá là một hệ QTCSDL phát triển khá đầy
đủ và có độ tin cậy, tính ổn định, hiệu suất cao cũng như dễ sử dụng Đặc biệt, MySQL cung cấp một cơ chế tuyệt vời cho phép tổ chức lưu trữ dữ liệu theo nhiều cách khác nhau để đạt hiệu quả cao nhất phù hợp với từng hoàn cảnh cụ thể gọi là pluggable storage engine Điều đó khiến cho MySQL được đánh giá là có tính linh hoạt rất cao Tại tầng thấp nhất của hệ thống, các máy chủ được xây dựng dựa trên mô hình đa luồng Về mặt chức năng, nhiều phần trong lõi của MySQL được xây dựng từ những năm 1980 Đến năm 1995, ngôn ngữ truy vấn dữ liệu SQL được đưa vào hệ thống MySQL sử dụng trình biên dịch GNU C (GCC) có khả năng cung cấp tính mềm dẻo tuyệt vời cho mọi môi trường đích
Trang 9Các công cụ máy khách của MySQL phần lớn được viết bằng ngôn ngữ C nên có tính di động và tốc độ cao hơn Các thư viện máy khách, các cơ chế truy cập có thể được viết bằng bất kì ngôn ngữ lập trình nào như Net, Java, ODBC,…
MySQL sử dụng chiến lược phát triển song song để đảm bảo vẫn duy trì các phiên bản cũ trong khi phát triển các phiên bản mới Việc này tạo nên sự khác biệt cơ bản so với các phần mềm bản quyền thương mại, nơi mà ngay khi các nhà cung cấp đưa ra phiên bản mới thì các phiên bản cũ bị dừng lại Điều đó buộc các khách hàng phải thay đổi môi trường cùng với các nỗ lực phát triển kèm theo, đặc biệt khi có những thay đổi
về mặt kiến trúc Trong khi đó, MySQL cùng với chiến lược đa bản phát hành cho phép người dùng duy trì các sản phẩm lâu dài hơn mà vẫn đảm bảo được hỗ trợ Do
đó, khách hàng có nhiều thời gian chuẩn bị trước những bước thay đổi cần thiết đồng thời có thể đảm bảo sử dụng tài nguyên hiệu quả nhất mà không phải vội vã thay đổi
kế hoạch dài hạn
Sự phát triển của MySQL cũng như các phần mềm nguồn mở khác tuân theo tiến trình gồm nhiều giai đoạn Mỗi giai đoạn có thể có nhiều bản phân phối khác nhau Các giai đoạn phát triển như sau:
Giai đoạn 1: Giai đoạn phát triển (Development) – đây là giai đoạn mà các tập
tính năng hoặc sản phẩm mới được lập kế hoạch hoặc triển khai như một hướng phát triển mới
Giai đoạn 2: Alpha – là giai đoạn triển khai sàng lọc tính năng và chỉnh sửa khiếm khuyết (sửa lỗi)
Giai đoạn 3: Beta – các tính năng được “đóng băng” (không thể thêm các tính năng mới), bổ sung các kiểm thử chuyên sâu và triển khai dò tìm khiếm khuyết
Giai đoạn 4: Gamma – Về cơ bản, các sản phẩm trong giai đoạn này là mã đã được đóng băng và các vòng kiểm thử cuối cùng đã được tiến hành Các sản phẩm trong giai đoạn này thường là các ứng viên sẽ đưa ra phát hành
Giai đoạn 5: Stable – Nếu không tìm thấy khiếm khuyết nghiêm trọng, mã được công bố là ổn định và sẵn sàng để phân phối sản phẩm
Khi sử dụng MySQL, tùy vào mục đích sử dụng của người dùng mà có thể lựa chọn các bản phân phối phù hợp Tuy nhiên, nên sử dụng phiên bản alpha mới nhất cho những phát triển mới Điều đó tạo ra cơ hội tốt hơn khi bản chỉnh sửa đã được kiểm thử trước tại giai đoạn alpha
MySQL là một hệ QTCSDL mã nguồn mở tuân thủ theo giấy phép nguồn mở GPL (General Public License) MySQL AB sử dụng giấy phép nguồn mở GPL như là điểm chính trong mô hình kinh doanh MySQL AB thừa nhận cộng đồng mã nguồn
mở GNU cũng như các liên danh đầu tư với MySQL AB đều được kí kết dưới cùng một triết lí và giấy phép
Trang 10Đặc biệt, MySQL sử dụng khái niệm cấp phép kép (dual – license) Có nghĩa là, bên cạnh các sản phẩm tuân thủ đúng giấy phép nguồn mở GPL, MySQL cũng được cấp phép như một sản phẩm thương mại Một giấy phép thương mại cho phép MySQL
sở hữu mã nguồn, cũng như bản quyền về tên, logo, và các tài liệu liên quan Đây là điểm độc đáo khác hẳn với các công ty mã nguồn mở khác MySQL AB giữ lại các tài sản trí tuệ của phần mềm trong khi vẫn tận dụng sự hỗ trợ của cộng đồng những người phát triển trên toàn cầu để mở rộng và phát triển phần mềm Điều này đã khiến cho MySQL nhanh chóng trở thành một hệ QTCSDL mã nguồn mở ổn định, có tính linh hoạt và phổ biến nhất hiện nay
Vấn đề đặt ra là, khi MySQL vừa được cấp phép như phần mềm nguồn mở vừa được coi là phần mềm thương mại thì liệu có thực sự được phép chỉnh sửa hay không? Câu trả lời là có Bất kì người phát triển nào đều có thể chỉnh sửa MySQL, tất nhiên phải tuân thủ giấy phép nguồn mở GPL Đồng thời cũng có thể chỉnh sửa dưới giấy phép thương mại trong trường hợp muốn sử dụng bản chỉnh sửa cho những phát triển riêng hoặc gói hay nhúng MySQL vào trong sản phẩm thương mại đã có
1.2 Kiến trúc MySQL
So với rất nhiều hệ CSDL khác, MySQL có rất nhiều khác biệt Mặc dù MySQL không hoàn hảo nhưng nó lại được đánh giá là một hệ QTCSDL linh hoạt có khả năng làm việc tốt trong nhiều môi trường khác nhau đáp ứng nhiều mục đích đa dạng, đặc biệt là trong các ứng dụng web Hiện nay, MySQL có khả năng triển khai trong các ứng dụng nhúng, kho dữ liệu, lập chỉ mục nội dung và các phần mềm phân phối, các
hệ thống đòi hỏi tính sẵn sàng cao, các xử lí giao tác trực tuyến (OLTP), … MySQL
vô cùng linh hoạt theo nhiều cách khác nhau Nó có thể được cấu hình để chạy tốt trên nhiều nền tảng phần cứng và hỗ trợ cho nhiều kiểu dữ liệu khác nhau thông qua một
cơ chế độc đáo chỉ có duy nhất trên MySQL, pluggable storage engine Các storage engine được thiết kế độc lập với xử lí truy vấn và các nhiệm vụ khác trong máy chủ như một trình runtime plugin Tùy vào ứng dụng cụ thể, có thể lựa chọn cách thức lưu trữ dữ liệu, cách thể hiện và các đặc trưng tối ưu nhất thông qua việc lựa chọn các storage engine đã có phù hợp, hay tự xây dựng storage engine riêng
Kiến trúc hệ thống MySQL được mô tả như là một hệ thống phân lớp các hệ thống con Trong khi mã nguồn chưa được biên dịch thành các phần hoặc mô-đun riêng, mã nguồn của các hệ thống con được tổ chức dưới dạng cây phân cấp Hệ thống được phát triển dựa trên các thư viện cơ sở cung cấp các chức năng mức thấp như điều khiển luồng, tổ chức lưu trữ trong bộ nhớ, các thao tác mạng, đăng nhập, và thậm chí cả điều khiển truy cập và các thao tác quản lí Các thư viện này được kết hợp với nhau tạo thành các hệ thống con và các hệ thống con có thể được xây dựng dựa trên các hệ thống con khác Các hệ thống giao tiếp thông qua một giao diện API chuẩn Giao diện API này cho phép hệ thống MySQL vừa được sử dụng như một máy chủ độc lập, vừa
Trang 11như một hệ CSDL nhúng trong một ứng dụng lớn hơn Kiến trúc của MySQL được mô
tả chi tiết như hình 1.1 sau:
Hình 1.1 Kiến trúc của MySQL server, trong [4, pp.1185]
Lớp trên cùng là các lớp kết nối cơ sở dữ liệu (Connector): cung cấp phương thức truy cập cho các ứng dụng máy khách Các ứng dụng này có thể được viết bằng bất kì ngôn ngữ nào như C, Net, PHP, ODBC, …
Các công cụ phụ trợ được nhóm trong nhóm các tiện ích và dịch vụ quản lí gồm sao lưu và khôi phục dữ liệu, an ninh, nhân bản, phân cụm, quản trị, cấu hình, … Lớp nằm ngay dưới lớp kết nối là lớp connection pool Đây là lớp quản lí tất cả các truy cập của người dùng như xác thực người dùng, xử lí luồng, bộ nhớ, bộ đệm tiến trình cần thiết cho một kết nối của máy khách
Lớp kế tiếp là lớp quan trọng nhất của một hệ thống CSDL, nơi xử lí các truy vấn người dùng Tại lớp này, các truy vấn được đưa vào thông qua giao diện SQL, sau đó được phân tách, tối ưu, thực thi và lưu đệm
Sự độc đáo của MySQL được thể hiện trong lớp plugable storage engine Lớp này tạo nên sự linh hoạt cho hệ thống thông qua việc xây dựng các cách thức quản lí dữ liệu hoặc lưu trữ tệp hoặc các cơ chế truy cập đa dạng khác nhau Tính mềm dẻo này là duy nhất có ở MySQL Storage engine cung cấp khả năng điều chỉnh CSDL bằng cách cung cấp một vài cơ chế lưu trữ dữ liệu Máy chủ kết nối với các storage engine thông qua một giao diện storage engine chuẩn Giao diện này che giấu sự khác nhau giữa các storage engine và khiến chúng trong suốt tại tầng truy vấn Giao diện API chứa các chức năng mức thấp thực hiện các quá trình như là bắt đầu giao tác hoặc thêm dữ liệu
Trang 12vào một hàng với khóa chính đã biết, … Các storage engine không phân tách SQL hoặc kết nối với các storage engine khác; chúng chỉ trả lời yêu cầu từ một máy chủ Tầng thấp nhất của hệ thống là lớp truy cập tệp Tầng này chứa các cơ chế lưu trữ, đọc và ghi dữ liệu, hệ thống đọc và ghi các thông tin biên bản và sự kiện Đây cũng là lớp gần nhất với hệ điều hành cùng với các điều khiển luồng, tiến trình và bộ nhớ
1.3 Truy vấn dữ liệu trên MySQL
MySQL là một hệ QTCSDL quan hệ Các yêu cầu người dùng được đưa vào thông qua giao diện SQL, sau đó được phân tách, tối ưu, thực thi và cuối cùng, kết quả được gửi lại cho người dùng thông qua giao diện SQL
1.3.1 Giao diện SQL
Giao diện SQL cung cấp các cơ chế để nhận các câu lệnh và chuyển kết quả tới
người dùng Giao diện SQL của MySQL được xây dựng trên chuẩn ANSI (American National Standards Institute) và chấp nhận mọi câu lệnh SQL cơ bản như mọi máy chủ CSDL theo chuẩn ANSI khác Mặc dù rất nhiều câu lệnh trong MySQL có các lựa chọn không theo chuẩn ANSI nhưng những người phát triển vẫn tìm thấy điểm tương đồng với chuẩn này
Khi nhận được một yêu cầu kết nối tới máy chủ CSDL từ đường truyền mạng, một luồng (thread) được tạo ra cho mỗi kết nối Tiến trình xử lí luồng là phần quan trọng nhất trong máy chủ MySQL MySQL được xây dựng như một ứng dụng đa luồng thực
sự nơi mà mỗi luồng được thực thi độc lập so với các luồng khác Các câu lệnh SQL được lưu trữ theo một cấu trúc phân lớp và các kết quả được gửi tới người dùng bằng cách ghi các kết quả đó ra các phương thức truyền thông mạng
1.3.2 Phân tách
Khi một máy khách gửi tới một truy vấn, một luồng mới được tạo ra Câu lệnh SQL được chuyển tới bộ phân tách để xác nhận cú pháp (hoặc từ chối nếu có lỗi) Bộ phân tách của MySQL sử dụng kịch bản Lex-YACC được biên dịch bằng Bison Bộ phân tách sẽ xây dựng một cấu trúc truy vấn để thể hiện câu truy vấn viết bằng ngôn ngữ SQL trên bộ nhớ trong như là một cấu trúc cây (hay còn gọi là cây cú pháp trừu tượng) Sau đó sử dụng cấu trúc đó để thực thi truy vấn
Bộ phân tách sẽ đọc câu lệnh SQL, sau đó tách câu lệnh thành các phần và gán các tham số, các lựa chọn, các đoạn lệnh cho một cấu trúc các biến và danh sách Cấu trúc này sẽ được sử dụng cho mọi bước tiếp theo của tiến trình truy vấn Cấu trúc Lex chứa một danh sách các bảng được sử dụng, các tên trường tham chiếu đến, các điều kiện, các biểu thức và tất cả các phần của câu truy vấn đó trên những không gian lưu trữ phân biệt
Trang 13Bộ phân tách đọc các câu lệnh SQL và so sánh các biểu thức (gồm các token và các kí hiệu) với các luật định nghĩa trong mã nguồn Các luật này được xây dựng trong
mã nguồn sử dụng Lex và YACC và sau đó được biên dịch bằng Bison để phù hợp với
đó, việc xác thực được đưa tới quá trình tối ưu hóa Do đó, cấu trúc truy vấn từ bộ phân tách được đưa tới bộ xử lí truy vấn và điều khiển được chuyển tới bộ tối ưu truy vấn
1.3.3 Tối ưu truy vấn
MySQL sử dụng chiến lược SELECT – PROJECT – JOIN để cố gắng xây dựng lại truy vấn Đầu tiên, sử dụng câu lệnh SELECT để hạn chế số lượng các tuples, sau
đó thực hiện phép chiếu để để giảm số lượng các thuộc tính (trường) trên các tuples kết quả và cuối cùng thực hiện lệnh hợp theo điều kiện
Bước đầu tiên của quá trình tối ưu hóa là kiểm tra sự tồn tại của bảng và quyền truy cập của người dùng Nếu có lỗi thì một thông báo lỗi được đưa ra và điều khiển được trả về cho trình quản lí luồng Ngay khi các bảng được xác thực, chúng sẽ được
mở và các khóa thích hợp sẽ được sử dụng để điều khiển đồng thời
Ngay khi các công việc cài đặt và bảo trì được hoàn thành, trình tối ưu sử dụng cấu trúc truy vấn bên trong được phân tích bởi Lex và đánh giá điều kiện WHERE của truy vấn đó Các kết quả trả về như là các bảng tạm thời để chuẩn bị cho bước tiếp theo Nếu có xuất hiện phép toán UNION, trình tối ưu thực thi các đoạn SELECT của tất cả các câu lệnh trong vòng lặp trước khi tiếp tục
Bước tiếp theo của quá trình tối ưu hóa là thực thi phép chiếu Chúng được thực hiện theo cách thức tương tự như các đoạn giới hạn, lặp lại lưu trữ các kết quả tức thời như các bảng tạm thời và chỉ lưu lại các thuộc tính được chỉ định trong các cột được chỉ định trong câu lệnh SELECT Sau đó, cấu trúc được phân tích cho bất kì điều kiện JOIN nào được xây dựng sử dụng lớp join và gọi tới phương thức join::optimize() Tại bước này, truy vấn được tối ưu hóa thông qua việc đánh giá biểu thức và loại bỏ các điều kiện mà kết quả trong các nhánh chết hoặc các điều kiện luôn đúng hoặc luôn sai Trình tối ưu cố gắng loại bỏ các điều kiện tri thức tồi (known – bad) trong câu truy vấn trước khi thực thi lệnh join bởi vì lệnh join tốn nhiều chi phí cũng như thời gian nhất trong tất cả các phép toán quan hệ Cũng lưu ý rằng, bước tối ưu phép toán join được thực hiện cho mọi câu lệnh có mệnh đề WHERE hoặc HAVING bất kể nó có điều
Trang 14kiện join hay không Ngay khi tối ưu câu lệnh join được hoàn thành, trình tối ưu sử dụng một danh sách các câu lệnh điều kiện để định tuyến truy vấn tới một phương thức thư viện thích hợp để thực thi
1.3.4 Thực thi truy vấn
Gồm một tập các phương thức thư viện được thiết kế để triển khai các truy vấn cụ thể Ví dụ, phương thức mysql_insert() được thiết kế để chèn dữ liệu, phương thức mysql_select() được thiết kế để tìm và trả ra dữ liệu thỏa mãn mệnh đề WHERE Thư viện các phương thức này được lưu trữ trong rất nhiều tệp mã nguồn dưới cùng một tên tệp (ví dụ như sql_insert.cc hoặc sql_select.cc) Tất cả các phương thức đó đều có một tham số như một đối tượng luồng cho phép phương thức đó truy cập vào cấu trúc truy vấn bên trong và dễ dàng thực thi Kết quả thực thi của mỗi phương thức được trả
về sử dụng thư viện đường truyền thông mạng
1.3.5 Bộ đệm truy vấn
Rất nhiều hệ QTCSDL lưu lại các kế hoạch thực thi truy vấn (plan), do đó máy chủ có thể bỏ qua các bước phân tách và tối ưu hóa cho các truy vấn lặp lại MySQL không những làm được điều đó mà còn cho phép lưu đệm tập các kết quả truy vấn cho các câu lệnh SELECT Đây có thể coi là kĩ thuật duy nhất có trong MySQL
Bộ nhớ đệm truy vấn giữ lại chính xác các bit của kết quả truy vấn trả về cho người dùng Khi có một truy vấn đã được thực hiện trước đó rồi (xảy ra cache hit), thay vì phân tách, tối ưu và thực thi câu truy vấn, máy chủ chỉ đơn giản trả ra các kết quả đã được lưu trữ trước đó ngay lập tức Điều này làm tăng hiệu suất xử lí truy vấn
Bộ nhớ đệm truy vấn sẽ lưu vết tới các bảng mà câu truy vấn đó dùng, và nếu một trong các bảng đó thay đổi, nó sẽ làm mất hiệu lực truy cập vào bộ đệm cache Chính sách làm mất hiệu lực thô này dường như không hiệu quả khi những thay đổi trên bảng
có thể không ảnh hưởng tới các kết quả lưu trữ trong bộ đệm nhưng đó là hướng tiếp cận đơn giản với chi phí thấp, điều này rất quan trọng với các hệ thống thường xuyên bận
Bộ đệm truy vấn được thiết kế hoàn toàn trong suốt đối với các ứng dụng Các ứng dụng không cần biết dữ liệu được MySQL trả ra là từ trong bộ đệm hay do quá trình thực hiện truy vấn trên thực tế Các kết quả này là như nhau hay nói cách khác, bộ đệm truy vấn thường không làm thay đổi ngữ nghĩa
MySQL làm thế nào để kiểm tra một câu lệnh đã được thực thi trước đó hay chưa? Cách thức mà MySQL sử dụng ở đây vô cùng đơn giản và khá nhanh: bộ đệm là một bảng tìm kiếm Khóa tìm kiếm là một giá trị băm của câu truy vấn đó, CSDL đang sử dụng, phiên bản giao thức của máy khách và một giá trị hữu dụng có thể làm ảnh hưởng tới các giá trị byte thực tế trong kết quả truy vấn
Trang 15MySQL không phân tích cú pháp, “bình thường hóa” hoặc tham số hóa một câu lệnh khi kiểm tra câu lệnh đã được thực thi hay chưa Nó sử dụng chính xác câu lệnh
và các bit dữ liệu khác mà người dùng gửi tới Bất kì sự khác biệt nào như là trong các
kí tự, khoảng trống hoặc chú thích đều có thể khiến câu truy vấn đó không tương thích với câu truy vấn đã được lưu đệm trước đó Vì thế nên cẩn thận khi viết câu truy vấn
Sử dụng các kiểu và định dạng nhất quán là một thói quen tốt nhưng trong trường hợp này nó còn có thể giúp hệ thống nhanh hơn
Kết quả truy vấn sẽ không được lưu đệm nếu như câu truy vấn sinh ra nó không xác định Vì thế bất kì câu lệnh nào chứa các hàm không xác định như NOW(), CURRENT_DATE(), CURRENT_USER() hoặc CONNECTION_ID() đều sẽ không được lưu đệm Trong thực tế, bộ đệm truy vấn không làm việc với truy vấn yêu cầu các hàm do người dùng định nghĩa, các hàm lưu trữ, các biến người dùng, các bảng tạm thời, các bảng trong CSDL mysql, hoặc bất kì bảng nào chứa một độc quyền mức dòng Vậy MySQL có thực sự không kiểm tra bộ đệm nếu truy vấn chứa một hàm không xác định không? Thực ra không đúng như vậy, MySQL không thể biết một câu truy vấn có chứa một hàm không xác định trừ khi nó phân tách câu truy vấn đó, và việc tìm kiếm bộ đệm diễn ra trước khi thực hiện phân tách câu truy vấn Máy chủ lúc này chỉ kiểm tra xem câu truy vấn đó có bắt đầu bằng các kí tự SEL hay không
Bộ đệm truy vấn của MySQL có thể cải thiện hiệu suất nhưng nó cũng có một vài vấn đề cần lưu ý khi sử dụng Khi sử dụng bộ đệm truy vấn sẽ làm tăng thêm chi phí khi đọc và ghi dữ liệu:
Các truy vấn đọc dữ liệu phải kiểm tra bộ đệm trước khi bắt đầu
Nếu truy vấn đó được lưu đệm và chưa nằm trong bộ đệm, cần phải mất phí để lưu trữ kết quả sau khi sinh nó
Việc ghi dữ liệu cho các câu lệnh cũng mất chi phí Khi ghi dữ liệu phải làm mất hiệu lực truy cập vào bảng đang thay đổi của tất cả các truy vấn khác
Tuy nhiên, chi phí này không lớn lắm do đó bộ đệm truy vấn vẫn đạt được hiệu quả khả thi Nhưng vẫn còn một số vấn đề khác làm tăng thêm chi phí Đối với những người sử dụng InnoDB, các giao tác có thể hạn chế tính hữu ích của bộ đệm truy vấn Khi một câu lệnh bên trong một giao tác chỉnh sửa một bảng, máy chủ sẽ làm mất hiệu lực của bất kì câu truy vấn đã được lưu đệm tham chiếu tới bảng đó, ngay cả khi tính
đa phiên bản của InnoDB có thể che giấu những thay đổi của giao tác với các câu lệnh khác, bảng đó cũng không thể lưu đệm toàn cục cho đến khi giao tác được commit Do
đó, không có câu truy vấn nào trên bảng (cả bên ngoài và bên trong giao tác) có thể được lưu trữ cho đến khi giao tác được commit Như vậy, một giao tác có thời gian thực thi lâu sẽ làm tăng số lượng các bộ đệm truy vấn bị nhỡ
Việc làm mất hiệu lực cũng trở thành một vấn đề khi bộ đệm truy vấn lớn Nếu có quá nhiều truy vấn trên bộ đệm, việc làm mất hiệu lực có thể mất nhiều thời gian và
Trang 16khiến cho toàn bộ hệ thống ngưng lại trong khi nó vẫn đang làm việc Điều đó xảy ra
do có một khóa toàn cục trên bộ đệm truy vấn sẽ chặn tất cả các truy vấn cần tham chiếu đến nó Quá trình truy cập diễn ra cả khi kiểm tra truy vấn đã được thực hiện trước đó hay chưa và khi kiểm tra có bất kì truy vấn không hợp lệ
1.3.6 Cache và Buffer
Cache và Buffer đảm bảo dữ liệu có tần suất sử dụng thường xuyên nhất phải sẵn sàng theo cách thức hiệu quả nhất có thể Nói cách khác, dữ liệu phải thường trú và sẵn sàng được đọc tại mọi thời điểm Cache làm giảm thời gian phản hồi cho các yêu cầu dữ liệu bởi vì dữ liệu nằm ngay trong bộ nhớ trong mà không cần thiết phải truy tìm dữ liệu trên đĩa Hệ thống Cache được tạo ra để đóng gói tất cả các thao tác lưu đệm trong tập các hàm chuẩn Bộ nhớ đệm thường được triển khai trong các phần khác nhau của mã nguồn để phù hợp với kiểu dữ liệu được lưu đệm Các loại bộ đệm bao gồm:
Bộ đệm bảng: tối thiểu chi phí mở, đọc và đóng bảng (tệp frm trên đĩa) Bộ đệm
bảng được thiết kế để lưu trữ các metadata của bảng trong bộ nhớ trong Điều đó khiến cho một luồng (thread) đọc lược đồ của một bảng nhanh hơn mà không cần phải mở lại tệp đó mỗi khi truy cập đến Mỗi một luồng có danh sách các cấu trúc bộ đệm bảng của riêng nó Nó cho phép các luồng duy trì khung nhìn riêng của các bảng để nếu một luồng đang thay đổi một lược đồ bảng (nhưng chưa commit) thì các luồng khác có thể
sử dụng bảng đó với lược đồ ban đầu Cấu trúc này được lưu như một danh sách kết nối trong bộ nhớ trong và tương thích với mỗi luồng
Bộ đệm bản ghi: nâng cao khả năng đọc dữ liệu tuần tự từ các storage engine Bộ
đệm bản ghi thường chỉ được sử dụng trong khi duyệt bảng Nó hoạt động giống như một bộ đệm đọc trước (read-ahead buffer) bằng cách tìm kiếm trên một khối (block)
dữ liệu, nên làm giảm việc truy cập đĩa trong quá trình duyệt Như vậy hiệu suất sẽ được cải thiện Bộ đệm bản ghi cũng được sử dụng trong quá trình ghi dữ liệu một cách tuần tự bằng cách trước tiên ghi dữ liệu mới (hoặc sửa đổi) vào bộ nhớ đệm, sau
đó ghi dữ liệu từ bộ đệm vào đĩa khi đầy Bằng cách đó, hiệu suất ghi sẽ được cải thiện
Bộ đệm khóa: là bộ đệm được sử dụng cho các dữ liệu chỉ mục thường xuyên Bộ
đệm khóa được truy cập trong mọi thao tác đọc chỉ mục Nếu một chỉ mục được tìm thấy trong bộ đệm thì nó sẽ được đọc từ đó; ngược lại, một khối chỉ mục mới phải được đọc từ đĩa và đặt vào bộ đệm Kích thước bộ đệm có giới hạn cho nên không phải mọi khối của tệp chỉ mục được lưu trữ trong bộ nhớ trong Làm thế nào để hệ thống biết được khối nào vừa mới được sử dụng? Giải pháp đưa ra là sử dụng một hệ giám sát để kiểm soát tần suất sử dụng của các khối chỉ mục bằng cách lưu lại giá trị warm Warm nhận các giá trị: lạnh (BLOCK_COLD), ấm (BLOCK_WARM), và nóng (BLOCK_HOT) Khi các khối nguội và các khối mới trở nên ấm, các khối lạnh bị
Trang 17thanh lọc, các khối ấm được bổ sung vào Nó sử dụng chiến lược thay thế trang, bộ đệm khóa sẽ lưu vết các khối chỉ mục bị thay đổi (gọi là bị vấy bẩn – dirty) Khi một khối bị thay đổi (dirty) được thanh lọc, dữ liệu của nó được ghi trở lại tệp chỉ mục trước khi bị thay thế Ngược lại, khi một khối sạch (clean) được thanh lọc, nó đơn giản chỉ bị xóa ra khỏi bộ nhớ trong
Bộ đệm quyền truy cập: được sử dụng để lưu trữ các dữ liệu cấp quyền trên một
tài khoản người dùng Dữ liệu này được lưu trữ theo cùng một cách với danh sách điều khiển truy cập, nơi lập danh sách toàn bộ quyền của một người dùng đối với một đối tượng trong hệ thống Bộ đệm quyền sử dụng bảng băm FILO (vào trước, ra sau) Dữ liệu của bộ đệm được thu thập khi đọc các bảng phân quyền trong quá trình khởi tạo
và xác thực người dùng Việc lưu trữ các quyền đó trong bộ nhớ trong có thể tiết kiệm nhiều thời gian so với việc đọc dữ liệu từ bảng
Bộ đệm tên máy chủ (hostname): là bộ đệm chuyên dụng sử dụng cấu trúc ngăn
xếp Nó chứa tên máy chủ của tất cả các kết nối tới máy chủ Đây là dữ liệu được yêu cầu thường xuyên
Ngoài các cơ chế lưu đệm trên, MySQL cũng sử dụng thêm một số cơ chế khác để làm tăng hiệu suất sử dụng của toàn bộ hệ thống
Như vậy, giống như mọi hệ QTCSDL quan hệ khác, quá trình truy vấn dữ liệu của MySQL cũng tuân thủ theo đúng tiến trình truy vấn gồm các bước cơ bản như phân tách, tối ưu hóa, thực thi truy vấn MySQL hỗ trợ đầy đủ các câu lệnh SQL theo chuẩn ANSI, quá trình phân tách sử dụng kịch bản Lex – YACC, tối ưu truy vấn sử dụng chiến lược SELECT – PROJECT – JOIN, truy vấn được thực thi thông qua các phương thức thư viện chuẩn Hơn nữa, MySQL còn sử dụng rất nhiều cơ chế lưu đệm hiệu quả để làm tăng hiệu suất truy vấn dữ liệu, đặc biệt là cơ chế lưu đệm các kết quả truy vấn Đây chính là điểm độc đáo của MySQL
1.4 Các đặc trưng của MySQL
1.4.1 Quản lí kết nối và an ninh
Khi có một yêu cầu kết nối từ một máy khách tới một máy chủ, kết nối đó phải giành được một luồng (thread) riêng bên trong tiến trình của máy chủ Các truy vấn trong kết nối thực thi trong một luồng đơn lẻ, nằm trên một lõi hay một CPU Máy chủ lưu đệm các luồng, do đó không cần được tạo mới và hủy bỏ cho mỗi lần kết nối Khi các máy khách (ứng dụng) kết nối tới máy chủ MySQL, máy chủ cần xác thực máy khách (hay ứng dụng) đó Quá trình xác thực dựa trên tên người dùng, địa chỉ host ban đầu, và mật khẩu Giấy chứng nhận X 509 cũng có thể được sử dụng thông qua một kết nối Secure Sockets Layer (SSL) Khi một máy khách được kết nối, máy chủ xác thực liệu máy khách đó có quyền cho mỗi truy vấn mà nó đệ trình hay không
Trang 181.4.2 Quản lí đồng thời
Khi có nhiều truy vấn đồng thời yêu cầu dữ liệu tại cùng một thời điểm, MySQL
sẽ xử lí như thế nào? MySQL thực hiện quản lí đồng thời tại 2 mức: mức máy chủ và mức storage engine Ở đây chỉ xét quản lí đồng thời cho các thao tác đọc và ghi dữ liệu
Khi nhiều máy khách cùng đọc cùng một dữ liệu đồng thời, không có vấn đề gì xảy ra, do không có sự thay đổi dữ liệu Nhưng chuyện gì sẽ xảy ra nếu một máy khách cố gắng đọc dữ liệu trong khi một máy khách khác đang thay đổi nó Cũng giống như các hệ QTCSDL khác, MySQL sử dụng các cơ chế khóa để ngăn không cho máy khách đọc dữ liệu khi nó đang được thay đổi
MySQL sử dụng 2 loại khóa:
- Khóa chia sẻ (shared lock - S) hay khóa đọc (read lock): các khóa đọc trên một tài nguyên được chia sẻ, nghĩa là nhiều máy khách có thể đọc một tài nguyên tại một thời điểm mà không ảnh hưởng đến nhau
- Khóa độc quyền (exclusive lock - X) hay khóa ghi (write lock): khi có một máy khách thực hiện thao tác ghi dữ liệu thì mọi thao tác đọc tới dữ liệu đó bị chặn
Các khóa độc quyền (X) có độ ưu tiên cao hơn các khóa chia sẻ (S) Vì thế, một yêu cầu khóa ghi sẽ được đẩy lên trước trong hàng đợi khóa ngay cả khi quá trình đọc
đã sẵn sàng trên hàng đợi
Phạm vi khóa (Lock Granularity): Nhằm cải thiện hiệu suất sử dụng của một
tài nguyên, nên lựa chọn những thứ sẽ bị khóa Thay vì khóa toàn bộ tài nguyên, hiệu quả sẽ tốt hơn nếu chỉ khóa trên phần dữ liệu cần thay đổi Tốt hơn nữa, chỉ khóa chính xác những dữ liệu định thay đổi Giảm thiểu lượng dữ liệu bị khóa tại một thời điểm làm cho hiệu quả sử dụng đồng thời các tài nguyên tốt hơn, miễn là chúng không xung đột với nhau
Vấn đề là các khóa cũng sử dụng tài nguyên Tất cả các bước trong tiến trình khóa gồm lấy một khóa, kiểm tra khóa đó có rỗi hay không, giải phóng một khóa, … đều có chi phí nhất định Nếu một hệ thống dành quá nhiều thời gian quản lí khóa thay vì lưu trữ và truy tìm dữ liệu, hiệu suất có thể bị ảnh hưởng xấu
Một chiến lược khóa là sự thỏa hiệp giữa chi phí khóa và tính an toàn của dữ liệu,
và sự thỏa hiệp đó ảnh hưởng tới hiệu suất Hầu hết các máy chủ CSDL thương mại không có nhiều lựa chọn khóa nhưng MySQL lại cung cấp nhiều lựa chọn khóa thông qua các storage engine Các storage engine có thể triển khai các chiến lược khóa và phạm vi khóa của riêng nó Việc quản lí khóa là một quyết định rất quan trọng khi thiết kế storage engine Sử dụng các khóa ở các mức nhất định nào đó có thể đạt được hiệu quả cao hơn trong trường hợp này nhưng lại kém hơn trong trường hợp khác Bởi
vì MySQL cung cấp nhiều storage engine với rất nhiều chiến lược khóa khác nhau nên
Trang 19nó không yêu cầu một giải pháp chung Tuy nhiên, MySQL thường sử dụng hai chiến lược khóa quan trọng sau:
Các khóa mức bảng (Table lock): là chiến lược khóa cơ bản nhất và có chi phí
thấp nhất trong MySQL Một khóa bảng sẽ khóa toàn bộ bảng Khi một máy khách muốn ghi dữ liệu vào một bảng (insert, delete, updade, …), nó yêu cầu một khóa ghi (X) Mọi thao tác đọc/ghi dữ liệu khác lên bảng đó đều bị chặn Khi không đang thực hiện thao tác ghi trên bảng, các khóa đọc (S) được cấp cho người đọc, miễn là chúng không xung đột với các khóa đọc khác
Các biến thể của khóa mức bảng có thể đạt được hiệu suất tốt hơn trong một số tình huống đặc biệt Chẳng hạn, các khóa mức bảng READ LOCAL cho phép một vài kiểu ghi dữ liệu đồng thời
Mặc dù các storage engine có thể quản lí các khóa của riêng nó nhưng bản thân MySQL cũng sử dụng các khóa mức bảng cho nhiều mục đích Chẳng hạn, một máy chủ sử dụng một khóa mức bảng cho câu lệnh ALTER TABLE, không liên quan tới storage engine
Các khóa mức dòng (Row lock): triển khai khóa trên phạm vi từng dòng, là kiểu
khóa cung cấp tính đồng thời nhất (và mang lại chi phí tốt nhất) Khóa mức dòng là một chiến lược được sử dụng phổ biến trong InnoDB, Falcon, và một số storage engine khác Các khóa mức dòng được triển khai trong storage engine, chứ không phải trên máy chủ Hầu hết các storage engine thực thi khóa theo cách riêng và máy chủ hoàn toàn không hay biết về cách thức triển khai các khóa này
1.4.3 Giao tác
Một giao tác là một tập hợp các truy vấn SQL được coi như một đơn vị công việc đơn lẻ Nếu một máy CSDL có thể thực thi toàn bộ các câu truy vấn bên trong, giao tác thành công Ngược lại, nếu có bất kì truy vấn nào trong chúng không thể được thực hiện bởi vì một đổ vỡ hay một nguyên nhân khác, không có câu lệnh nào trong số chúng được thực hiện Giao tác có nghĩa hoặc là tất cả hoặc không gì cả
Mô hình ACID: Các giao tác tuân thủ mô hình ACID ACID viết tắt của
Atomicity, Consistency, Isolation, và Durability Chúng là tiêu chuẩn quan hệ chặt chẽ
mà một hệ thống xử lí giao tác tốt phải đạt được:
Atomicity (tính nguyên tử)
Một giao tác phải có chức năng như là một đơn vị công việc độc lập không thể chia nhỏ để toàn bộ giao tác hoặc được chấp nhận (commit) hoặc khôi phục lại (rollback) Giao tác không thể hoàn thành một phần: hoặc là tất cả hoặc không gì cả Consistency (tính nhất quán)
Trang 20Đảm bảo CSDL luôn luôn chuyển từ một trạng thái nhất quán này sang một trạng thái nhất quán khác
Máy chủ CSDL muốn đảm bảo ACID phải thực hiện rất nhiều thứ phức tạp Ngay khi tăng phạm vi khóa, để đảm bảo an ninh thì máy chủ CSDL phải thực hiện nhiều việc hơn Một máy chủ CSDL với các giao tác ACID cũng thường yêu cầu cấu hình CPU cao hơn, cần nhiều bộ nhớ trong và không gian đĩa hơn các máy chủ không chứa các giao tác ACID MySQL quản lí giao tác trong các storage engine Việc sử dụng các storage engine với tính tra lắp được khiến cho người dùng có thể linh hoạt quyết định khi nào ứng dụng cần tới các giao tác Nếu không thực sự cần, nên sử dụng một storage engine không hỗ trợ giao tác hoặc sử dụng các bảng khóa (LOCK TABLE) để đạt được mức bảo vệ cần thiết
Các mức độ cách ly: Chuẩn SQL định nghĩa 4 mức độ cách ly với các luật về
việc có thể nhìn thấy hay không nhìn thấy bên trong và bên ngoài một giao tác Mức cách ly thấp hơn cho phép tính đồng thời cao hơn và có chi phí thấp hơn
Các mức độ cách ly được liệt kê theo thứ tự từ thấp đến cao, gồm:
READ UNCOMMITED: tại mức này, các giao tác có thể nhìn thấy kết quả của các
giao tác không được commit Ít được sử dụng trong thực tế do hiệu quả không cao Phép đọc dữ liệu chưa được commit được gọi là “dirty read”
READ COMMITED: là mức cách ly mặc định cho hầu hết các hệ CSDL (nhưng
không phải cho MySQL) Tại mức này, một giao tác sẽ chỉ nhìn thấy những thay đổi của các giao tác đã được commit, và những thay đổi của nó không thể được nhìn thấy bởi các giao tác khác cho đến khi nó được commit Mức này thường được gọi là đọc
không lặp lại (nonrepeatable read), nghĩa là nếu thực hiện cùng một câu lệnh 2 lần thì
dữ liệu nhìn thấy sẽ khác nhau
nhau với mọi thao tác đọc Một vấn đề xảy ra ở mức cách ly này là: đọc ma - phantom read Một phantom read có thể xảy ra khi xem các dòng, một giao tác khác chèn một
Trang 21dòng mới vào chính các dòng đó và sau đó lại xem lại chúng; Như vậy bạn sẽ nhìn thấy một dòng “ma” (“phantom”) mới Để giải quyết vấn đề này, InnoDB và Falcon sử dụng kĩ thuật quản lí đồng thời đa phiên bản REPEATABLE READ là mức cách ly mặc định trong MySQL Tuy nhiên cũng có thể thay đổi các thiết đặt đó ở mức storage engine
SERIALIZABLE: là mức cách ly cao nhất Nó có thể xử lí vấn đề đọc phantom
bằng cách buộc các giao tác phải sắp thứ tự để chúng không thể xung đột SERIALIABLE đặt một khóa trên mọi dòng nó đọc Là mức cách ly ít được sử dụng
Deadlocks: Khi hai hay nhiều giao tác cùng giữ và yêu cầu khóa trên cùng một tài
nguyên, tạo ra một vòng lặp vô hạn, deadlock xảy ra Xét hai giao tác đang trên bảng StockPrice như sau:
Transaction #1
START TRANSACTION;
UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4;
UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3;
COMMIT;
Transaction #2
START TRANSACTION;
UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3;
UPDATE StockPrice SET high = 47.20 WHERE stock_id = 4;
Các hệ CSDL đã sử dụng rất nhiều cách phát hiện deadlock khác nhau Một số hệ thống tinh vi hơn, như là InnoDB, có thể nhận ra vòng lặp vô hạn và đưa ra một thông báo lỗi Một số hệ thống khác lại sử dụng timeout như là một giải pháp Các giao tác
sẽ kết thúc nếu một truy vấn vượt quá thời gian đợi (timeout) của khóa
Thứ tự và cách thức khóa phụ thuộc vào từng storage engine, cho nên một deadlock có thể xảy ra trong chuỗi câu lệnh của storage engine này nhưng vẫn chuỗi câu lệnh đó trong storage engine khác thì không Một số deadlock là không thể tránh khỏi bởi vì dữ liệu thực sự xung đột nhưng một số khác có thể là do cách thức hoạt động của storage engine
Khi phá vỡ deadlock, các giao tác thường bị rollback, một phần hoặc toàn bộ
Lưu biên bản giao tác: khiến cho giao tác được thực hiện hiệu quả hơn Thay vì chỉnh sửa bảng trên đĩa mỗi lần có thay đổi xảy ra, storage engine có thể chỉnh sửa trên bản sao dữ liệu trong bộ nhớ trong của nó Sau đó, storage engine ghi một bản ghi
Trang 22những thay đổi lên một biên bản giao tác nằm trên đĩa Cuối cùng, tại một thời điểm sau đó, tiến trình có thể chỉnh sửa bảng trên đĩa Như vậy vừa giảm được thời gian và
số lần truy cập đĩa lại vừa có tính bền vững do những thay đổi vẫn được ghi trên đĩa Điều này cũng cho quá trình xử lí nhanh hơn vì thay vì truy cập ngẫu nhiên trên nhiều nơi thì có thể truy cập tuần tự trên một vùng nhỏ Hầu hết các storage engine sử dụng
kỹ thuật này
Nếu có một đổ vỡ sau khi một chỉnh sửa được ghi lên một biên bản giao tác nhưng trước khi những thay đổi đó được tạo thành dữ liệu, storage engine có thể vẫn khôi phục được những thay đổi khi khởi động lại Phương thức khôi phục giữa các storage engine là khác nhau
Giao tác trong MySQL: MySQL AB cung cấp các storage engine hỗ trợ giao tác
như InnoDB, NDB cluster, Falcon,… Một vài engine bên thứ ba cũng hỗ trợ giao tác như solidDB và PBXT
Mặc định, MySQL được thực thi trong cơ chế autocommit =1 (hay ON) Điều đó
có nghĩa là, giao tác sẽ tự động thực hiện mỗi truy vấn độc lập
Nếu AUTOCOMMIT = 0 (hay OFF), giao tác được thực thi cho đến khi được COMMIT hoặc ROLLBACK Sau đó MySQL bắt đầu ngay một giao tác mới
Trộn các storage engine trong các giao tác: Trong MySQL, các giao tác được
thực thi ở các storage engine mà không được quản lí ở máy chủ Do đó, không thể trộn các storage engine khác nhau trong một giao tác
Khóa ngầm định và tường minh: InnoDB sử dụng giao thức khóa 2 pha Chúng
có thể đạt được khóa bất kì thời điểm nào trong một giao tác, nhưng không thể giải phóng khóa cho đến khi được COMMIT hoặc ROLLBACK Các khóa được giải phóng toàn bộ tại cùng thời điểm Đây là cơ chế khóa ngầm định và được InnoDB quản lí tự động Ngoài ra nó cũng hỗ trợ khóa tường minh, thứ mà chuẩn SQL không
hề đề cập đến, như là các khóa trên các bảng sẽ có yêu cầu khóa tiếp theo
Trong MySQL, giao tác được triển khai trong các storage engine Giao tác có thể
là một yếu tố quyết định tới việc lựa chọn một storage engine phù hợp với ứng dụng Mặc dù MySQL cũng hỗ trợ câu lệnh LOCK TABLES và UNLOCK TABLES được thực thi trên máy chủ nhưng chúng không thể thay thế cho giao tác Do đó, nếu một ứng dụng thật sự cần giao tác, hãy lựa chọn một storage engine hỗ trợ giao tác
1.4.4 Điều khiển đồng thời đa phiên bản (MVCC)
Hầu hết các storage engine hỗ trợ giao tác trong MySQL, như là InnoDB, Falcon,
và PBXT không sử dụng một cơ chế khóa mức dòng đơn giản Thay vào đó, chúng sử dụng khóa mức dòng trong sự kết hợp với một kĩ thuật để gia tăng tính đồng thời gọi
là điều khiển đồng thời đa phiên bản (Multiversion Concurrency Control – MVCC)
Trang 23Không chỉ MySQL, một số hệ CSDL khác như là Oracle, PostgreSQL, … cũng sử dụng kĩ thuật này
Điều khiển đồng thời đa phiên bản (MVCC) có thể coi là cải tiến của khóa mức dòng Nó tránh việc khóa tất cả các tài nguyên và trong nhiều trường hợp có thể đem lại chi phí thấp hơn nhiều Phụ thuộc vào cách triển khai, nó có thể cho phép đọc không khóa, trong khi chỉ khóa những bản ghi cần thiết khi thực hiện thao tác ghi MVCC hoạt động bằng cách giữ một snapshot của dữ liệu của một vài thời điểm
Do đó, giao tác có thể nhìn thấy dữ liệu nhất quán mà không quan tâm tới chúng đã thực thi bao lâu Điều đó cũng có nghĩa là các giao tác khác nhau có thể nhìn thấy những dữ liệu khác nhau trong cùng một bảng tại cùng một thời điểm Các storage engine khác nhau triển khai điều khiển đồng thời đa phiên bản khác nhau
Các chỉ mục B-Tree: tất cả các giá trị được lưu trữ theo thứ tự, mỗi trang lá có
cùng khoảng cách tới gốc Mỗi nút chứa dữ liệu của nó cùng với con trỏ tới con của
nó Quá trình tìm kiếm diễn ra từ gốc và tìm kiếm trên cây dựa trên khóa tìm kiếm Nó khiến cho quá trình tìm kiếm diễn ra nhanh chóng mà không phải thăm toàn bộ bảng
để tìm dữ liệu Thay vào đó, bắt đầu từ gốc, đi theo các con trỏ tới các nút con thỏa mãn điều kiện nào đó (ví dụ như key >value hoặc <=value) cho đến khi tìm thấy lá cần tìm hoặc khẳng định rằng giá trị đó không tồn tại
Một cải tiến khác của B-Tree là B+Tree Khi đó, tại mỗi nút bổ sung thêm con trỏ trỏ tới nút liền kề với nó, khiến cho quá trình tìm kiếm nhanh hơn
Hầu hết các storage engine của MySQL sử dụng chỉ mục B-Tree Tuy nhiên, cách thức lưu trữ trên đĩa không giống nhau dẫn tới hiệu suất đạt được có thể khác nhau Ví
dụ như: MyISAM sử dụng kĩ thuật nén tiền tố khiến cho các chỉ mục nhỏ hơn, trong khi InnoDB lại không sử dụng vì chúng không phù hợp với chiến lược tối ưu hóa của InnoDB Các chỉ mục MyISAM tham chiếu tới các dòng bằng vị trí vật lí của dòng đó
Trang 24nhưng InnoDB tham chiếu thông qua các giá trị khóa chính Mỗi cách làm có những lợi ích và hạn chế riêng
Chỉ mục băm (hash index): được xây dựng trên các bảng băm và chỉ hữu ích cho
các tìm kiếm chính xác sử dụng cho mọi cột trong chỉ mục đó
Tại mỗi dòng, các storage engine tính toán một mã băm của các cột chỉ mục Nó lưu trữ các mã băm trong chỉ mục và lưu trữ một con trỏ tới mỗi dòng của bảng băm
đó
Chỉ mục tiền tố (Prefix index): được sử dụng trong trường hợp phải lập chỉ mục
trên các cột có rất nhiều kí tự khiến cho chỉ mục lớn và chậm mà không thể dùng chỉ mục băm được
Giải pháp đưa ra là lập chỉ mục trên một vài kí tự đầu tiên thay vì trên toàn bộ giá trị Điều đó khiến các chỉ mục sử dụng ít không gian hơn nhưng đồng thời cũng ít tính chọn lọc hơn Tính chọn lọc của chỉ mục là tỉ số của số khoảng cách các giá trị chỉ mục trên tổng số dòng trên bảng (#T) và nằm trong khoảng từ 1/#T đến 1 Một chỉ mục có tính lựa chọn cao sẽ khiến cho MySQL lọc nhiều dòng hơn khi tìm kiếm Tiền tố của cột thường được lựa chọn để đạt được hiệu suất đủ tốt Đối với các cột
dữ liệu kiểu TEXT, BLOB hay các cột VARCHAR rất dài, phải sử dụng chỉ mục tiền
tố vì MySQL không cho phép lập chỉ mục trên toàn bộ độ dài của chúng
Hạn chế là phải lựa chọn tiền tố đủ dài để đạt hiệu suất cao đồng thời phải đủ ngắn
để hạn chế không gian Tiền tố nên đủ dài để khiến cho chỉ mục có tính hữu dụng gần như là khi lập chỉ mục trên toàn bộ cột
Chỉ mục cụm (clustered index): không phải là một kiểu chỉ mục, đó là một
hướng tiếp cận lưu trữ dữ liệu Khi một bảng có một chỉ mục cụm, các dòng của nó thực tế được lưu trữ trên các lá, các nút khác chỉ chứa các cột chỉ mục Thuật ngữ
“phân cụm” để chỉ rằng các dòng với các giá trị khóa liền kế được lưu trữ gần nhau Trên mỗi bảng chỉ có thể có duy nhất một chỉ mục cụm do không thể lưu trữ các dòng tại 2 nơi cùng lúc được
Lợi ích của chỉ mục cụm:
Lưu trữ các dữ liệu liên quan gần nhau
Truy cập dữ liệu nhanh hơn Một chỉ mục cụm giữ cả chỉ mục và dữ liệu trong một cấu trúc B-Tree, vì thế khi tìm kiếm các dòng từ một chỉ mục cụm thường nhanh hơn so với các trường hợp khác
Chỉ mục cuộn (covering index): Các truy vấn sử dụng các chỉ mục cuộn sử dụng
các giá trị khóa chính chứa tại các nút lá Chỉ mục là một cách để tìm kiếm các dòng một cách hiệu quả, nhưng MySQL cũng có thể sử dụng một chỉ mục để tìm kiếm dữ liệu trong một cột, vì thế nó không cần phải đọc dòng đó Các nút lá chứa giá trị mà
Trang 25chúng chỉ mục Một chỉ mục chứa tất cả dữ liệu cần thiết thỏa mãn một truy vấn gọi là chỉ mục cuộn
Chỉ mục gói (hay chỉ mục nén tiền tố): để giảm kích thước chỉ mục, cho phép
nhiều chỉ mục hơn phù hợp với bộ nhớ trong và cải thiện đáng kể hiệu suất trong một
số trường hợp
MyISAM gói mỗi khối chỉ mục bằng cách lưu trữ đầy đủ giá trị đầu tiên của khối, sau đó lưu trữ mỗi giá trị bổ sung trong khối đó bằng cách ghi số lượng các byte có cùng tiền tố và dữ liệu khác nhau của hậu tố Ví dụ, nếu giá trị đầu tiên là “perform”
và giá trị thứ hai là “performance” thì giá trị thứ 2 được lưu trữ là “7,ance”
Các khối nén sử dụng ít không gian hơn nhưng nó cũng làm quá trình thực thi lâu hơn Bởi vì mỗi tiền tố nén của giá trị phụ thuộc vào giá trị trước nó
Kết luận chương 1: MySQL là một hệ quản trị cơ sở dữ liệu mã nguồn mở phổ
biến nhất hiện nay MySQL sử dụng kiến trúc tương đồng với nhiều hệ quản trị CSDL quan hệ khác đồng thời cũng đưa ra một số giải pháp nổi bật như là triển khai nhiều bộ đệm (bộ đệm truy vấn, bộ đệm bảng, bản ghi,…), và đặc biệt là sử dụng kiến trúc pluggable storage engine độc đáo cho phép triển khai một cách linh hoạt các phương thức quản lí đồng thời, hỗ trợ giao tác, điều khiển đồng thời đa phiên bản và hỗ trợ chỉ mục riêng độc lập với máy chủ Điều đó khiến cho MySQL được đánh giá là một hệ QTCSDL có tính linh hoạt cao, đáp ứng được nhiều nhu cầu khác nhau của nhiều người dùng
Trang 26CHƯƠNG 2 MYSQL PLUGGABLE STORAGE ENGINE
Khi bắt đầu phát triển một ứng dụng CSDL bất kì, các cơ chế truy cập tệp hay còn gọi là thiết kế vật lí CSDL là một yếu tố quan trọng góp phần cải thiện hiệu suất thực thi của hệ CSDL
Mặc dù tốc độ truy cập tệp phụ thuộc rất nhiều vào tính hiệu quả và tính đơn giản của hệ thống tệp hỗ trợ bởi hệ điều hành nhưng nó có thể được cải thiện đáng kể dựa vào cách thức tổ chức lưu trữ dữ liệu và các phương thức truy cập tệp, từ đó cải thiện hiệu suất của toàn bộ hệ CSDL Hiện nay có rất nhiều cơ chế tổ chức dữ liệu như: phân đoạn dữ liệu theo nội dung dữ liệu hoặc ngữ cảnh và tổ chức dữ liệu trên cây phân cấp; tổ chức dữ liệu trên đĩa theo cấu trúc nhằm cung cấp một phương thức truy cập tối ưu; cơ chế lưu đệm các thông tin thường xuyên truy cập để giảm thiểu các thao tác vào/ra trên bộ nhớ ngoài nhằm cải thiện hiệu suất đọc/ghi dữ liệu, làm giảm chi phí lưu trữ và tìm kiếm dữ liệu; hay cơ chế lập chỉ mục nhằm tăng tốc độ truy cập và tìm kiếm dữ liệu trên bộ nhớ ngoài, phân cụm và nhân bản dữ liệu trên các hệ phân tán… Mục đích của các cơ chế tổ chức dữ liệu là tối thiểu chi phí vào/ra trong hệ CSDL, có nghĩa là:
- Sử dụng hiệu quả cấu trúc dữ liệu trên đĩa: cho phép tìm kiếm nhanh chóng và hiệu quả chỉ những dữ liệu có liên quan thông qua các con đường truy cập tối ưu nhất
- Tổ chức dữ liệu trên đĩa để chi phí vào/ra khi tìm kiếm dữ liệu liên quan là tối thiểu
Tuy nhiên, các nhà nghiên cứu cũng đã chỉ ra rằng, không có phương thức tổ chức truy cập tệp tốt cho mọi trường hợp Cho nên, tùy từng ứng dụng cụ thể và nhu cầu của người dùng có thể triển khai các phương pháp tốt nhất có thể
Nhận thấy được ý nghĩa và tầm quan trọng của các cơ chế truy cập tệp đối với hiệu suất của hệ CSDL, MySQL cung cấp một khả năng đặc biệt khi cho phép nhiều giải pháp triển khai cơ chế truy cập tệp phù hợp với những nhu cầu đặc thù của người dùng thông qua các storage engine
2.1 Storage engine là gì?
Storage engine hay thực chất là các kiểu bảng là một khái niệm mới do MySQL đưa ra Trong khi phát triển các ứng dụng, MySQL cho phép lựa chọn cách thức những bảng dữ liệu được lưu trữ dựa trên các storage engine phù hợp nhất với tình huống cụ thể Thậm chí, MySQL còn cho phép người dùng có thể tự thiết kế storage engine cho riêng mình và dễ dàng tra lắp vào hệ thống Điều này tạo nên tính linh hoạt vượt trội cùng với tính độc đáo duy nhất có của MySQL
Có rất nhiều lí do khi sử dụng storage engine, theo Arjen Lentz trong [9], lí do được đưa ra là:
Trang 27Thứ nhất, do sự tiến hóa của công nghệ Đối với người dùng, khi chỉnh sửa ứng
dụng, sẽ rất bất tiện nếu họ phải thực thi các công cụ chuyển đổi hoặc thậm chí kết xuất và nhập (import) toàn bộ dataset Thay vào đó, nếu chỉ cần chỉnh sửa máy chủ (để sửa lỗi và các tính năng khác mà không phải chuyển toàn bộ dữ liệu) sẽ tiết kiệm được nhiều thời gian, công sức và chi phí Điều đó có nghĩa là máy chủ phải hỗ trợ nhiều định dạng tệp
Thứ hai, Đối với những người phát triển máy chủ, việc thay đổi trong mã nguồn
có thể dẫn tới những yêu cầu thay đổi liên quan khác trong máy chủ, và hầu hết các mã mới luôn luôn có khả năng xảy ra lỗi Do đó việc thay đổi mã nguồn phía dưới, để mở rộng, không nên ảnh hưởng tới mã ở các lớp cao hơn, được gọi là trừu tượng
Thứ ba, Các ứng dụng khác nhau có các yêu cầu khác nhau về lưu trữ dữ liệu,
và một vài yêu cầu thậm chí có thể xung đột với nhau Các ứng dụng ngân hàng yêu cầu xử lí giao dịch an toàn cao hơn so với lưu lượng đăng nhập vào một website Khi
đó, cần có sự cân bằng (trade-off) và lựa chọn quyết định Không có công cụ nào phù hợp được với mọi ứng dụng và sẽ tốt hơn nếu một máy chủ có thể phục vụ hiệu quả cho nhiều hơn một loại ứng dụng
Thứ tư, về cơ bản phương tiện lưu trữ khác nhau đưa ra hướng tiếp cận khác
nhau Một đĩa cứng khác hoàn toàn so với RAM Dữ liệu lưu trữ trong một đĩa cứng
có thể chứa nhiều dữ liệu nhưng tốc độ đọc/ghi dữ liệu từ nó chậm hơn Ngược lại, RAM thì rất nhanh, nhưng lại giới hạn dung lượng Một vài thuật toán tìm kiếm được tối ưu cho RAM, các thuật toán khác được tối ưu cho lưu trữ dựa trên đĩa
MySQL storage engine gồm một tập các cơ chế lưu trữ, truy cập, hỗ trợ giao tác, các cơ chế khóa, cách ly,… nhằm bổ sung các kiểu lưu trữ mới cho máy chủ MySQL, làm nhiệm vụ cầu nối giữa máy chủ MySQL với hệ thống tệp của hệ điều hành Các storage engine có thể dễ dàng tra lắp vào trong MySQL thông qua một cơ chế đặc biệt gọi là MySQL pluggable storage engine Cơ chế này cho phép mọi storage engine đều
có thể tra lắp vào máy chủ sử dụng chung một giao diện chuẩn
Khi sử dụng storage engine, ứng dụng không cần phải biết dữ liệu được lưu trữ như thế nào MySQL sử dụng một storage engine mặc định cho các bảng mà nó tạo ra, chẳng hạn như InnoDB cho các phiên bản 5.5.5 trở lên hoặc MyISAM cho các phiên bản cũ hơn Do đó, nếu không có yêu cầu đặc biệt, thì không cần chỉ định storage engine Tuy nhiên, đối với các ứng dụng lớn hoặc có những yêu cầu truy cập đặc biệt, cần có sự lựa chọn phù hợp Một ứng dụng có thể sử dụng nhiều storage engine, bằng các lựa chọn storage engine trên từng bảng Thậm chí, các máy chủ cũng có thể chuyển đổi các bảng giữa các định dạng khác nhau sử dụng một câu lệnh ALTER TABLE đơn giản
Không chỉ đưa ra các storage engine đã được xây dựng sẵn, với cơ chế pluggable storage engine, MySQL còn cho phép một người phát triển bất kì có thể tự xây dựng
Trang 28một storage engine mới nhằm đáp ứng tốt nhất một nhu cầu đặc biệt nào đó của một ứng dụng cụ thể và tra lắp dễ dàng vào máy chủ Điều đó tạo nên tính linh hoạt, mềm dẻo tuyệt vời của MySQL
Một storage engine là một thành phần trong máy chủ CSDL MySQL chịu trách nhiệm thực hiện các phép toán dữ liệu vào/ra cho một CSDL cũng như là cho phép và bắt buộc các tập tính năng nhất định phục vụ nhu cầu của một ứng dụng riêng Khi sử dụng storage engine, chỉ quan tâm tới các tính năng cần cho ứng dụng, do đó, chi phí cho CSDL của hệ thống ít hơn, và kết quả cuối cùng là hiệu suất của hệ CSDL hiệu quả và cao hơn
2.2 Kiến trúc pluggable storage engine
Pluggable storage engine là một lớp trong kiến trúc của máy chủ MySQL như đã trình bày trong mục 1.2 Nó chịu trách nhiệm trừu tượng hóa lớp lưu trữ dữ liệu vật lí với các lớp logic của máy chủ và cung cấp các phép toán vào/ra mức thấp cho máy chủ Khi một hệ thống được phát triển theo kiến trúc phân lớp, việc cung cấp một cơ chế để sắp xếp và chuẩn hóa giao diện giữa các lớp là một tiêu chí quan trọng đánh giá
sự thành công của kiến trúc đó
Kiến trúc plugable storage engine trong MySQL cho phép các chuyên gia CSDL lựa chọn các storage engine phù hợp nhất với ứng dụng một cách nhanh chóng và dễ dàng Kiến trúc máy chủ MySQL cách ly các lập trình viên ứng dụng và các nhà quản trị CSDL (DBA) với các chi tiết triển khai mức thấp tại tầng vật lí, cung cấp các mô hình ứng dụng và các giao diện API nhất quán và đơn giản Do đó, mặc dù các cơ chế tra lắp có thể khác nhau với các storage engine khác nhau nhưng các ứng dụng được bảo vệ từ những khác biệt này
Kiến trúc pluggable storage engine cung cấp một tập chuẩn quản lý và các dịch vụ
hỗ trợ phổ biến cho mọi storage engine phía dưới Bản thân các storage engine là thành phần của máy chủ CSDL thực hiện các hoạt động trên dữ liệu được duy trì tại tầng vật lý
Kiến trúc pluggable storage engine cũng cung cấp phương thức lưu trữ hiệu quả cho nhiều nhu cầu khác nhau đặc biệt cho các ứng dụng chuyên biệt – như là kho dữ liệu, xử lí giao tác, hoặc các tình huống có độ sẵn sàng cao – trong khi vẫn có thể tận dụng các lợi thế khi sử dụng một tập giao diện và các dịch vụ một cách độc lập với bất
kì một storage engine nào
Các lập trình viên ứng dụng và các nhà quản trị CSDL tương tác với CSDL MySQL thông qua các tầng giao diện kết nối (Connector API) và dịch vụ có trên mỗi storage engine Nếu những thay đổi trong ứng dụng dẫn đến những yêu cầu thay đổi storage engine phía dưới, hoặc storage engine đó được bổ sung những thứ cần mới hoặc những thay đổi trong xử lý yêu cầu được thực hiện Kiến trúc máy chủ MySQL
Trang 29bảo vệ ứng dụng với những phức tạp phía dưới bằng cách thể hiện một giao diện API
có tính nhất quán và đơn giản trong sử dụng được áp dụng trong hầu hết các storage engine
Trong kiến trúc pluggable storage engine, các storage engine có thể được tải vào hoặc không từ một máy chủ đang chạy Chi tiết sẽ được bàn đến trong phần sử dụng storage engine mục 2.4.2
2.3 Một số storage engine điển hình
Các storage engine khiến cho MySQL được đánh giá là một hệ QTCSDL linh hoạt
có khả năng đáp ứng được nhiều nhu cầu người dùng trong nhiều tình huống khác nhau Các storage engine hiện nay là rất phong phú Nó có thể là các storage engine được chính MySQL AB, chủ sở hữu của MySQL phát triển, tích hợp sẵn hoặc không trong máy chủ MySQL; hoặc cũng có thể là một storage engine của bất kì bên thứ ba nào hoặc bất cứ ai có nhu cầu phát triển Sẽ là rất khó để có thể hiểu sâu về tất cả các storage engine, tuy nhiên, trong phạm vi nghiên cứu này, chỉ xin đưa ra một số storage engine điển hình thường hay dùng trong MySQL cũng như một số hướng tiếp cận tổ chức truy cập tệp nổi bật hiện nay và một vài storage engine đại điện cho các xu hướng
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>.frm: chứa thông tin cấu trúc bảng
Trang 30Cá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 đó
Trang 31- Đị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%
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 khác tới bảng đều bị chặn cho đến khi tiến trình hoàn thành và giải phóng khóa
Trang 32MyISAM 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:
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 chia sẻ (S): cho phép một giao tác được phép đọc một dòng
Trang 33Khó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 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
hoặc trước bản ghi đầu tiên hoặc sau bản ghi cuối cùng
Trang 34Khó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
Trang 35Nế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 trên tiền tố của độ dài khóa bất kì định nghĩa cho B-tree, phụ thuộc vào mẫu tìm kiếm
mà nó quan sát Chỉ mục băm có thể là một phần các trang thường xuyên truy cập
Toàn vẹn dữ liệu: Khi dữ liệu được lưu trữ trên nhiều bảng có liên quan, InnoDB
hỗ trợ ràng buộc tham chiếu FOREIGN KEY để duy trì toàn vẹn dữ liệu Các thao tác chỉnh sửa, xóa dữ liệu và các dữ liệu liên quan trên các bảng khác được thực hiện tự động Nếu chèn dữ liệu trong bảng phụ mà không có dữ liệu liên quan trong bảng chính, phép chèn đó không thể thực hiện
Nén dữ liệu: sử dụng cơ chế nén dữ liệu trên các bảng Việc nén dữ liệu khiến cho
kích thước CSDL nhỏ hơn, giảm chỉ phí vào/ra, và cải thiện thông lượng, và tăng độ hữu dụng của CPU Khi một bảng InnoDB được tạo với lựa chọn ROW_FORMAT = COMPRESSED, kích thước trang trên đĩa có thể giảm từ 16KB mặc định còn 1KB, 2KB, 4KB, 8KB hoặc 16KB cho các tệp ibd
Trang 36Sử dụng bộ đệm buffer pool để lưu trữ dữ liệu và các chỉ mục trong bộ nhớ
trong Thông thường, dữ liệu được sử dụng được xử lí trực tiếp từ bộ nhớ trong Bộ nhớ đệm này áp dụng cho nhiều loại thông tin và làm tăng đáng kể tốc độ xử lí Các máy chủ CSDL chuyên dụng, InnoDB có thể sử dụng tới 80% bộ nhớ vật lí để lưu đệm
Có thể tự do trộn các bảng InnoDB từ các storage engine khác nhau, thậm chí trong cùng một câu lệnh Ví dụ, kết hợp dữ liệu từ các bảng InnoDB và MEMORY trong một câu truy vấn đơn
Ngoài ra, InnoDB còn cung cấp một tập các tiện ích tối ưu bên trong khác như dự đoán trước khi đọc để tìm và nạp trước dữ liệu từ trên đĩa; sử dụng một bộ đệm chèn
để tăng tốc độ chèn; sử dụng cơ chế checksum để cảnh báo khi dữ liệu bị gián đoạn; tự động tối ưu cột khóa chính khi tạo bảng, làm tăng tốc độ tham chiếu tới cột khóa chính trong các mệnh đề WHERE, ORDER BY, GROUP BY và các toán hạng JOIN; khi một dòng được truy cập nhiều lần, sử dụng đặc tính Adaptive Hash Index để tìm kiếm nhanh hơn như thể chúng được lấy ra từ một bảng băm,…
Với rất nhiều ưu điểm nổi trội cùng với sự cải thiện không ngừng qua từng phiên bản, InnoDB là lựa chọn tốt nhất cho các ứng dụng đòi hỏi độ tin cậy và hiệu suất cao,
hỗ trợ giao tác với khả năng thực hiện truy vấn dữ liệu an toàn và bảo vệ dữ liệu người dùng
Bảng 2.2 sau đưa ra những so sánh các đặc trưng của MyISAM và InnoDB với tư cách là các storage engine mặc định của MySQL
Bảng 2.2: Bảng so sánh các đặc trưng giữa MyISAM và InnoDB
Lưu trữ vật lí Giới hạn lưu trữ: 256 TB
Dữ liệu lưu trữ trong 3 tệp: frm (tệp định nghĩa bảng), myd (tệp
dữ liệu) myi (tệp chỉ mục)
Giới hạn lưu trữ: 64 TB Lưu trữ trong không gian bảng riêng, dữ liệu có thể lưu trữ trên một hoặc nhiều tệp
Ưu điểm ổn định, tin cậy, có hiệu suất đọc
cao, hỗ trợ tìm kiếm fulltext
Độ tin cậy, hiệu suất cao, khả năng khôi phục dữ liệu sau sự cố Hạn chế Bảng dễ bị phân mảnh Phức tạp
Ứng dụng Không hỗ trợ giao tác, hỗ trợ tìm
kiếm fulltext, các ứng dụng cần hiệu suất đọc dữ liệu cao
Hỗ trợ giao tác, độ an toàn dữ liệu, độ tin cậy và hiệu suất cao
Trang 372.3.1.3 Archive
Các bảng Archive có khả năng lưu trữ một lượng lớn dữ liệu không lập chỉ mục trong một không gian cực nhỏ vừa đủ Mã nguồn của storage engine này nằm trong thư mục storage/archive
Khi tạo một bảng Archive, máy chủ tạo ra một tệp định nghĩa bảng được đặt tên là
<tên bảng>.frm và tệp dữ liệu được đặt tên là <tên bảng>.ARZ
ARCHIVE chỉ hỗ trợ phép toán INSERT và SELET mà không hỗ trợ các phép toán DELETE, REPLACE và UPDATE Nó cũng hỗ trợ các phép toán ORDER BY, các cột BLOB, và về cơ bản là tất cả các kiểu dữ liệu không gian khác
Phép toán INSERT: Các dòng dữ liệu được nén ngay khi chúng được chèn vào
bảng theo thuật toán lossless zlib Một số kiểu chèn được sử dụng:
- Chèn từng dòng: các dòng được chèn vào bộ đệm nén, và sau đó bộ đệm đưa dữ liệu vào bảng khi cần Quá trình chèn vào bộ đệm được bảo vệ bởi một khóa Archive
hỗ trợ khóa mức dòng và một hệ thống đệm đặc biệt cho khả năng chèn đồng thời cao
- Chèn số lượng lớn (bulk insert): chèn nhiều dòng đồng thời, các dòng chỉ có thể nhìn thấy khi nó được hoàn thành, trừ khi một quá trình chèn khác xảy ra tại cùng một thời điểm, trong trường hợp đó nó có thể thấy một phần
Khi khôi phục, các dòng được giải nén
Phép toán SELECT: duyệt toàn bộ bảng, tìm và đọc số dòng đang có dữ liệu
Câu lệnh SELECT sẽ được thực hiện như một lần đọc nhất quán
Như vậy, Archive là storage engine có khả năng tối ưu các phép toán chèn tốc độ cao làm tăng nhanh tốc độ đọc ghi dữ liệu đồng thời tối ưu được không gian lưu trữ do chỉ lưu trữ định dạng nén
2.3.1.4 Federated
Là storage engine cho phép truy cập dữ liệu từ một CSDL MySQL từ xa mà không sử dụng công nghệ nhân bản (replication) hay phân cụm (cluster) Dữ liệu không được lưu trữ trong các bảng địa phương mà được chuyển từ các bảng ở xa Một bảng Federated gồm có 2 thành phần:
- Một máy chủ từ xa (remote server): chứa một bảng cơ sở dữ liệu, gồm một
định nghĩa bảng (tệp frm) và một bảng dữ liệu tương ứng với bất kì kiểu nào được hỗ trợ bởi máy chủ mysqld từ xa, bao gồm cả kiểu MyISAM hoặc InnoDB
- Một máy chủ địa phương (local server): chứa một bảng CSDL, trong đó chứa
một định nghĩa bảng tương ứng với bảng trên máy chủ từ xa Định nghĩa bảng này được lưu trữ trong tệp frm Tuy nhiên, sẽ không lưu trữ tệp dữ liệu Thay vào đó, định nghĩa bảng sẽ chứa một xâu kết nối trỏ tới bảng trên máy chủ từ xa