I. Hiện trạng
Hiện trạng:
- Hệ thống hiện tại khi thực hiện chạy batch theo như lịch trình thì lâu lâu nó lại phát sinh lỗi ORL-01555
エラーメッセージ:ORA-01555: スナップショットが古すぎます: ロールバック・セグメント番号***、名前"_SYSSMU[segment-name]$"が小さすぎます
Nguyên nhân:
- Sau một hồi google tiếng anh, tiếng em, tiếng nhật, tiếng Việt, hỏi bạn, hỏi anh, hỏi đồng nghiệp thì nguyên nhân có thể là một trong hai dưới đây:
- Khi mà thực hiện update/insert/delete 1 số lượng lớn records trong 1 transaction mà nó vượt giới hạn bộ nhớ của UNDO-TableSpace --> lỗi
- Thanh niên B đang update/insert/delete 1 số records và commit trong 1 khoảng thời gian ngắn, khi commit thì Oracle sẽ xóa đi những records ko cần thiết trong rollback segment. Nhưng hiện tại có 1 thanh niên A lại đang run Select với consistent View trước khi commit --> dữ liệu đang đọc bị thay đổi --> lỗi
II. Định nghĩa
Như ở trên xuất hiện 2 cái định nghĩa lạ(đối với mình lúc tìm hiểu cái lỗi này) như là UNDO-TableSpace và Rollback Segment. Nên tiện gg rồi note lại luôn để khỏi quên.
1. UNDO
- Như đúng cái tên của nó thì mục đích được tạo ra để trả về lại cái trước đó.
- Thêm 1 cái cho dễ hiểu là Undo-data - là các data được Oracle tạo ra khi thực hiện các transaction thay đổi dữ liệu.
- Mục đích để Rollback lại giữ liệu của các Transaction nêu cần.
- Nó tồn tại cho đến khi Transaction kết thúc (commit, rollback)
2. Rollback Segment
- Là database structures, dùng để track thông tin UNDO (như khái niệm đã nói ở trên)
III. Giải thích hiện tượng
1. Nguyên nhân 1
- Cái này có thể hiểu rằng như là khi bạn update số lượng quá lớn các records trong 1 transaction, thì tại đây các Undo-Record bắt đầu được khởi tạo
- Thế rồi khi Undo-tableSpace nó bị đầy nhưng mà Transaction vẫn chưa xong thì sẽ như thế nào? --> thì thằng sau nó sẽ ngồi lên đầu thằng trước (overwrite)
- Oracle đã tạo ra UNDO_RETENTION dùng để quản lý thời gian có thể lưu UNDO, nó kiểu như là thời gian bạn thể thể viết thêm / lưu trữ các UNDO mới. Khi mà mà giá trị biến này càng nhỏ thời thời gian lưu trữ càng ngắn, UNDO-TableSpace lại càng nhỏ.
- Thế rồi ngày lúc này thì Transaction lại bị rollback thì thế nào??? Dữ liệu cũ ko còn do đã bị ngồi lên đầu --> dữ liệu rollback bị thay đổi ---> Lỗi được trả về
2. Nguyên nhân 2
-
Để tới nguyên nhân 2 thì phải tới với khái niệm:
- Cơ chế read consistency : đơn giản hiểu như là khi thực hiện long running SQL mà nó được thực thi lúc 10h sáng đi, thì luôn đảm bảo các rows nó nhận luôn là trạng thái như lúc 10h sáng cho dù câu SQL đấy nó có chạy tới ngày hôm sau.
- Qua định nghĩa trên thì có thể hiểu ko thể vừa đọc vừa ghi 1 bản ghi tại 1 thời điểm.
- Nếu vừa đọc vừa ghi thì dẫn tới hiện tượng lock lẫn nhau để nó đảm bảo tính nhất quán cho chính câu truy vấn của nó
- Cơ chế read consistency : đơn giản hiểu như là khi thực hiện long running SQL mà nó được thực thi lúc 10h sáng đi, thì luôn đảm bảo các rows nó nhận luôn là trạng thái như lúc 10h sáng cho dù câu SQL đấy nó có chạy tới ngày hôm sau.
-
Qua đó có thể thấy khi mà câu lệnh SELECT đang chạy, mà dữ liệu trong Rollback segment (nới chứa các Undo) bị thay đổi thì lại ko đảm bảo được tính Nhất quán. Vậy ngoài nguyên nhân là UNDO-TableSpace ko đủ thì nguyên nhân nào có thể gây ra sự thay đổi data UNDO??? Đó là khi Transaction nó COMMIT. Nhìn lại định nghĩa của UNDO có thể thấy nếu transaction commit thì dữ liệu UNDO được giải phóng, cũng có nghĩa là đã bị thay đổi --> Dẫn đến phát sinh lỗi ở phía sử dụng câu lệnh SELECT.
Trích từ Oracle
It all boils down to the size of the undo tablespace and the undo retention, in the end…just as manual management boiled down to the size, amount, and usage of rollback segments. Committing frequently is a peroxide band-aid: it covers up the problem, tries to clean it, but in the end it just hurts and causes problems for otherwise healthy processes.
Qua đây sẽ phát sinh thêm Transaction và cách hoạt động của SELECT trong Database sẽ nghiêng cứu và viết tiếp về nó.