2.1.1 Hệ thống đơn người dùng - hệ thống đa người dùng
Một tiêu chuẩn phân lớp một hệ thống cơ sở dữ liệu là theo số ngƣời dùng sử dụng hệ thống đồng thời tại cùng một thời điểm. DBMS là đơn ngƣời dùng nếu nhiều nhất một ngƣời dùng tại một thời điểm sử dụng hệ thống, và DBMS là đa ngƣời dùng nếu có nhiều ngƣời dùng sử dụng hệ thống tại một thời điểm, và do đó truy cập cơ sở dữ liệu đồng thời [6]. Ví dụ, một hệ thống đặt vé của hãng hàng không đƣợc sử dụng bởi hàng trăm đại lý bán hàng và các khách hàng đặt vé đồng thời. Các hệ thống trong các nhà băng, các hãng bảo hiểm, các sở giao dịch chứng khoán, các siêu thị và các hệ thống khác tƣơng tự đều đƣợc thao tác bởi nhiều ngƣời dùng, những ngƣời dùng này chấp nhận các giao tác đồng thời lên hệ thống.
Nhiều ngƣời dùng có thể truy cập vào các cơ sở dữ liệu đồng thời bởi vì đa chƣơng trình cho phép máy tính thực thi nhiều chƣơng trình, hoặc tiến trình, tại cùng một thời điểm. Nếu chỉ có một đơn vị xử lý trung tâm (CPU) tồn tại, nó chỉ có thể thực thi nhiều nhất một tiến trình tại một thời điểm. Tuy nhiên các hệ thống vận hành đa chƣơng trình thực thi một số lệnh của một tiến trình, sau đó hoãn tiến trình đó và thực thi một số lệnh của tiến trình tiếp theo, và tƣơng tự nhƣ vậy. Một tiến trình sẽ lại đƣợc tiếp tục tại điểm mà nó bị hoãn và nếu đƣợc tiếp tục thì nó lại sử dụng CPU. Do đó thực thi đồng thời
của các tiến trình thực chất là sự đan xen, nhƣ minh họa trong hình 2.1, thể hiện 2 tiến trình A và B thực thi đồng thời theo cách xen kẽ. Xen kẽ làm CPU bận khi một tiến trình đòi hỏi một thao tác vào hoặc ra (I/O), nhƣ việc đọc một khối từ đĩa. CPU đƣợc chuyển sang thực thi một tiến trình khác trong khoảng thời gian đó. Việc xen kẽ cũng dẫn đến một tiến trình làm việc bị trì hoãn bởi các tiến trình khác.
Nếu hệ thống máy tính có đa bộ xử lý (nhiều CPU), xử lý song song của đa tiến trình có thể thực hiện đƣợc, nhƣ minh họa bằng tiến trình C và D trong hình 2.1. Hầu hết lý thuyết điều khiển đồng thời trong cơ sở dữ liệu đƣợc phát triển từ xen kẽ đồng thời. Trong một DBMS đa ngƣời dùng, các mục dữ liệu lƣu trữ là các tài nguyên chính có thể đƣợc truy cập bởi các ngƣời dùng tƣơng tác hoặc các chƣơng trình ứng dụng một cách đồng thời, các chƣơng trình ứng dụng lấy và sửa thông tin trong cơ sở dữ liệu.
Hình 2.1 Xử lý xen kẽ - xử lý song song của các giao tác đồng thời
2.1.2 Các giao tác, thao tác đọc - ghi và các vùng đệm DBMS
Một giao tác là một đơn vị logic xử lý cơ sở dữ liệu, nó bao gồm một hoặc nhiều thao tác truy cập cơ sở dữ liệu, các thao tác có thể gồm chèn, xóa, sửa hoặc lấy thông tin. Các thao tác trong cơ sở dữ liệu cấu thành một giao tác
A A B B C CPU 1 D CPU2 thời gian t4 t1 t3 t2 t1
có thể đƣợc đƣa vào một chƣơng trình ứng dụng hoặc đƣợc chỉ rõ thông qua một ngôn ngữ truy vấn mức cao nhƣ SQL.
Các thao tác truy xuất cơ sở dữ liệu cơ bản mà một giao tác có thể có [4, 6]:
- Read_item(X): Đọc một mục dữ liệu có tên là X vào trong một biến chƣơng trình. Để đơn giản các ký hiệu, giả sử biến chƣơng trình cũng là X
- Write_item(X): Viết giá trị của biến chƣơng trình X vào một mục cơ sở dữ liệu có tên là X
Đơn vị cơ bản của dữ liệu chuyển từ đĩa vào bộ nhớ chính là một khối. Thực thi một lệnh read_item(X) bao gồm các bƣớc sau:
1. Tìm địa chỉ của khối đĩa chứa mục X
2. Sao chép khối đĩa đó vào bộ đệm (nếu khối đĩa đó chƣa có sẵn trong bộ đệm).
3. Sao chép mục X từ bộ đệm sang biến chƣơng trình có tên là X Thực thi một lệnh write_item(X) bao gồm các bƣớc sau:
1. Tìm địa chỉ của khối đĩa chứa mục X
2. Sao chép khối đĩa đó vào một vùng đệm (nếu khối đĩa đó chƣa có sẵn trong vùng đệm)
3. Sao chép mục X từ biến chƣơng trình tên là X vào vị trí đúng của nó trong bộ đệm
4. Lƣu khối đã đƣợc cập nhật từ vùng đệm trở lại đĩa
Bƣớc 4 thực tế là một bƣớc cập nhật cơ sở dữ liệu lên đĩa. DBMS sẽ duy trì một số vùng đệm trong bộ nhớ chính để lƣu các khối đĩa cơ sở dữ liệu chứa các mục cơ sở dữ liệu đang đƣợc xử lý. Khi các vùng đệm này đƣợc sử dụng, và các khối dữ liệu thêm phải đƣợc sao chép vào trong bộ nhớ, một số
cơ chế thay thế vùng đệm đƣợc sử dụng để chọn các vùng đệm hiện thời đƣợc thay thế.
Một giao tác bao gồm các thao tác read_item và write_item để truy cập và cập nhật cơ sở dữ liệu. Hình 2.2 thể hiện các ví dụ của 2 giao tác đơn giản. Bộ đọc của một giao tác là tập hợp của tất cả các mục mà giao tác đọc, và bộ ghi là tập tất cả các mục mà giao tác ghi. Ví dụ, một bộ đọc của T1 trong hình 2.2 là {X,Y} và bộ ghi của nó cũng là {X,Y}
Điều khiển đồng thời và các cơ chế khôi phục chủ yếu có liên quan với các lệnh truy cập cơ sở dữ liệu trong một giao tác. Các giao tác đƣợc chấp nhận bởi nhiều ngƣời dùng khác nhau có thể thực thi đồng thời và có thể truy cập cũng nhƣ cập nhật cùng các mục cơ sở dữ liệu. Nếu việc thực thi đồng thời này không đƣợc điều khiển sẽ dẫn đến một số vấn đề nhƣ một cơ sở dữ liệu không nhất quán.
2.1.3 Tại sao điều khiển đồng thời là cần thiết [1, 4, 6]
Một số vấn đề có thể xảy ra khi các giao tác đồng thời thực thi theo cách thức không đƣợc điều khiển. Ví dụ xét cơ sở dữ liệu đặt vé máy bay của hãng hàng không đã đƣợc đơn giản hóa, mỗi bản ghi trong cơ sở dữ liệu đƣợc lƣu trữ cho từng chuyến bay. Hình 2.2(a) thể hiện giao tác T1, giao tác này chuyển N chỗ từ một chuyến bay X sang chuyến bay Y (tƣơng ứng có X, Y
(a) T1 read_item (X); X:= X – N; write_item(X); read_item(Y); Y:= Y+N; write_item(Y); (b) T2 read_item (X); X:= X +M ; write_item(X);
57
chỗ ngồi). Hình 2.2(b) thể hiện giao tác T2 đơn giản hơn, giao tác này phục hồi M chỗ trên chuyến bay X. Để đơn giản hoá, không đƣa thêm các thành phần khác của giao tác nhƣ kiểm tra xem nếu nhƣ một chuyến bay có đủ chỗ sẵn sàng trƣớc khi đặt thêm các chỗ mới hay không.
Khi một chƣơng trình truy xuất cơ sở dữ liệu, nó có số các chuyến bay, ngày bay và số chỗ đã đƣợc đặt trƣớc nhƣ là các biến; do đó, cùng chƣơng trình đó có thể đƣợc sử dụng để thực thi nhiều giao tác với từng chuyến bay khác nhau và số chỗ đƣợc đặt khác nhau. Với mục đích điều khiển đồng thời, một giao tác là một lần thực thi riêng biệt của chƣơng trình trên một ngày bay, chuyến bay, số chỗ cụ thể. Trong hình 2.2(a) và (b), giao tác T1 và T2 là các lần thực thi riêng biệt của chƣơng trình cho các chuyến bay với số các chỗ đƣợc lƣu trong các mục dữ liệu X và Y trong cơ sở dữ liệu.
Vấn đề cập nhật không thành công: Vấn đề này xảy ra khi 2 giao tác truy cập vào cùng mục cơ sở dữ liệu, các giao tác này bao gồm các thao tác xen kẽ nhau làm cho giá trị của các mục dữ liệu không chính xác. Giả sử giao tác T1 và T2 đƣợc chấp nhận tại thời điểm xấp xỉ nhau, và các thao tác của chúng đƣợc xen kẽ nhƣ thể hiện trong hình 2.3(a); khi đó giá trị cuối cùng của mục X bị sai bởi vì T2 đọc giá trị của X trƣớc khi T1 thay đổi nó trong cơ sở dữ liệu và do đó kết quả giá trị cập nhật từ T1 sẽ bị mất. Ví dụ, nếu ban đầu có X=80 chỗ ngồi trên một chuyến bay. Giao tác T1 chuyển N=5 chỗ sang chuyến bay khác, sau đó giao tác T2 khôi phục M=4 chỗ trên chuyến bay. Kết quả cuối cùng số chỗ trên chuyến bay sau khi thay đổi phải là X=79, nhƣng vì có sự xen kẽ đồng thời xẩy ra nên kết quả thu đƣợc X=84 và đây là kết quả sai. a) read_item(X); X := X –N write_item(X); read_item(Y); T1 T2 Thời gian read_item(X); X:= X + M;
b) c) T1 T2 read_item(X); X:=X+N; write_item(X) ; read_item(Y); read_item(X); X:=X+M; write_item(X) ;
Hình 2.3. Một số vấn đề xảy ra khi thực thi đồng thời không được điều khiển. (a) Vấn đề cập nhật không thành công. (b) Vấn đề cập nhật tạm thời
T1 T3 sum:=0; read_item(A); sum:=sum +A; read_item(X); X:=X-N; write_item(X) read_item(X); sum:=sum+X; read_item(Y); sum:=sum+Y; read_item(Y); Y:=Y+N;
Vấn đề cập nhật tạm thời. Vấn đề này xảy ra khi một giao tác cập nhật một mục cơ sở dữ liệu và sau đó giao tác bị lỗi nhƣng các mục dữ liệu này lại đƣợc truy cập bởi giao tác khác trƣớc khi nó phải đƣợc trả lại giá trị ban đầu. Hình 2.3(b) thể hiện một ví dụ với T1 cập nhật giá trị X và sau đó bị lỗi trƣớc khi hoàn thành, do đó hệ thống phải thay đổi X trả lại giá trị ban đầu của nó. Trƣớc khi điều này đƣợc thực hiện thì T2 lại đọc giá trị tạm thời đó của X.
Vấn đề tóm tắt sai: Nếu một giao tác đang tính toán một hàm tổng hợp trên một số bản ghi trong khi các giao tác khác lại đang cập nhật bản ghi đó, dẫn đến kết quả của hàm tính toán có thể bị sai. Ví dụ, giả sử một giao tác T3 đang tính tổng số vé đƣợc đặt trƣớc trên tất cả các chuyển bay, trong khi giao tác T1 đang thực thi. Nếu sự đan xen của các thao tác thể hiện trong hình 2.3(c) xảy ra, kết quả của T3 sẽ bị thiếu hụt số chỗ N=5 bởi vì T3 đọc giá trị X sau khi N vé bị trừ đi. Nhƣng đọc giá trị Y trƣớc N vé đƣợc cộng thêm vào.
Vấn đề khác có thể xảy ra đƣợc gọi là đọc không lặp lại, có nghĩa là một giao tác T đọc một mục dữ liệu 2 lần và mục dữ liệu đó đƣợc thay đổi bởi giao tác khác T‟ giữa 2 lần đọc đó. Do đó, T nhận đƣợc hai giá trị khác nhau với hai lần đọc của cùng một mục dữ liệu. Điều này có thể xảy ra, nếu một khách hàng đang hỏi về số ghế còn trên một số chuyến bay, sau đó mới quyết định đặt vé dẫn đến có giao tác đọc số ghế hai lần trên một chuyến bay.
2.1.4 Tại sao khôi phục là cần thiết
Mỗi khi một giao tác đƣợc chấp nhận tới một DBMS để thực thi, hệ thống chịu trách nhiệm đảm bảo hoặc (1) tất cả các thao tác trong giao tác đƣợc kết thúc thành công và kết quả của chúng đƣợc ghi trong cở sở dữ liệu, hoặc (2) giao tác không có bất cứ ảnh hƣởng nào lên cơ sở dữ liệu hoặc lên các giao tác khác [3, 4, 6]. DBMS phải cho phép một số thao tác của một giao tác T có thể đƣợc áp dụng lên một cơ sở dữ liệu trong khi các thao tác khác
của T không đƣợc cho phép. Điều này xảy ra nếu sau khi một số thao tác của nó đƣợc thực hiện nhƣng sau đó bị lỗi trƣớc khi thực thi xong toàn bộ các thao tác.
Các kiểu lỗi: lỗi đƣợc phân thành lỗi thiết bị, lỗi hệ thống và lỗi giao tác. Có một số nguyên nhân có thể gây lỗi trong khi thực thi:
1. Lỗi máy tính: một phần cứng, phần mềm, hoặc lỗi mạng xảy ra trong hệ thống máy tính đối với thời gian thực thi giao tác.
2. Lỗi giao tác hoặc lỗi hệ thống: một số thao tác trong một giao tác có thể làm cho giao tác bị lỗi, nhƣ tràn bộ nhớ hoặc lỗi chia cho 0. Lỗi giao tác cũng có thể xảy ra do các giá trị của biến không đúng hoặc do một lỗi lập trình logic. Thêm vào đó, ngƣời dùng có thể ngắt một giao tác trong khi thực thi nó
3. Các lỗi cục bộ hoặc các điều kiện ngoại lệ phát sinh bởi giao tác: trong khi thực thi giao tác, các điều kiện nào đó có thể xảy ra việc một giao tác bắt buộc phải đƣợc loại bỏ. Ví dụ, dữ liệu cho giao tác có thể không tìm thấy.
4. Buộc tuân theo điều kiển đồng thời: phƣơng thức điều khiển đồng thời có thể quyết định bỏ qua một giao tác và khởi động lại sau đó, bởi vì nó vi phạm trật tự hoặc bởi vì một số giao tác đang trong trạng thái bế tắc.
5. Lỗi đĩa: một số khối đĩa có thể mất dữ liệu do không đọc đƣợc hoặc không ghi đƣợc. Điều này có thể xảy ra trong một thao tác đọc hoặc thao tác ghi của giao tác.
6. Các vấn đề vật lý và các thảm họa: các vấn đề này đƣợc xem nhƣ danh sách vô tận các vấn đề bao gồm nguồn điện, cháy, trộm, sự phá hoại, đĩa qúa tải...
Các lỗi thuộc kiểu 1, 2, 3 và 4 phổ biến hơn các lỗi thuộc kiểu 5 và 6. Khi một lỗi thuộc kiểu từ 1 đến 4 xảy ra, hệ thống phải giữ thông tin đầy đủ
để khôi phục lại sau lỗi đó. Lỗi đĩa hoặc các lỗi do thảm họa của kiểu 5 hoặc 6 không xảy ra một cách thƣờng xuyên.
2.2 Các khái niệm hệ thống và giao tác
2.2.1 Các trạng thái giao tác và các phép toán bổ xung
Một giao tác là một đơn vị nhỏ nhất của công việc, nó hoặc là đƣợc hoàn thành toàn bộ hoặc không làm gì cả. Đối với mục đích khôi phục, hệ thống cần lại lƣu vết khi một giao tác bắt đầu và kết thúc để xác nhận hoặc hủy bỏ. Do đó, bộ quản lý khôi phục lƣu vết của các thao tác dƣới đây [6]:
- BEGIN_TRANSACTION: đánh dấu bắt đầu thực thi một giao tác
- READ hoặc WRITE: Chỉ ra thao tác đọc hoặc viết trên các mục cơ sở dữ liệu đƣợc thực thi nhƣ một phần của giao tác
- END_TRANSACTION: Chỉ ra các thao tác READ và WRITE kết thúc và đánh dấu kết thúc thực thi giao tác. Tuy nhiên, tại điểm này cần phải kiểm tra xem sự thay đổi bởi giao tác đƣợc xác nhận hoặc giao tác đƣợc huỷ bỏ do vi phạm trật tự hoặc với một số lý do khác.
- COMMIT_TRANSACTION: báo hiệu kết thúc thành công của một giao tác, do đó bất kỳ sự thay đổi nào thực thi bởi giao tác đƣợc xác nhận tới cơ sở dữ liệu và sẽ không thể khôi phục.
- ROLLBACK (hoặc ABORT): báo hiệu giao tác kết thúc không thành công, do đó bất kỳ sự thay đổi hoặc ảnh hƣởng nào của giao tác tác động lên cơ sở dữ liệu phải đƣợc huỷ bỏ.
Hình 2.4 thể hiện sơ đồ trạng thái giao tác. Một giao tác đi vào trạng thái hoạt động ngay sau khi nó bắt đầu thực thi, nó có thể đƣa ra các thao tác READ và WRITE. Khi kết thúc giao tác, thì nó chuyển tới trạng thái đã xác nhận một phần. Tại điểm này, một số giao thức khôi phục đảm bảo rằng nếu lỗi hệ thống thì không đƣa ra kết quả và không ghi những thay đổi cơ sở dữ liệu của giao tác đó. Việc kiểm tra này thành công thì giao tác đƣợc xem là đã
tiếp cận đến điểm xác nhận và đƣa vào trạng thái xác nhận. Khi giao tác đƣợc xác nhận, nghĩa là nó đã thực thi thành công và toàn bộ sự thay đổi đó phải đƣợc lƣu trong cơ sở dữ liệu.
Tuy nhiên, một giao tác có thể dẫn tới trạng thái lỗi nếu một trong các lần kiểm tra bị lỗi hoặc nếu giao tác bị huỷ bỏ trong khi nó ở trạng thái hoạt