2010-02-02 3 views
10

Chúng tôi có một cơ sở dữ liệu Oracle và bảng tài khoản khách hàng có khoảng một triệu hàng. Trong những năm qua, chúng tôi đã xây dựng bốn giao diện người dùng khác nhau (hai trong Oracle Forms, hai trong. Net), tất cả đều được sử dụng. Chúng tôi có một số tác vụ nền (cả hai đều liên tục và được lên lịch).Cách tìm các hàng bị khóa trong Oracle

Đôi khi, đôi khi giữ một khóa dài (hơn 30 giây) trên một hàng trong bảng tài khoản, khiến một trong các tác vụ nền liên tục bị lỗi. Nhiệm vụ nền được đề cập sẽ tự khởi động lại sau khi cập nhật hết giờ. Chúng tôi tìm hiểu về nó một vài phút sau khi nó xảy ra, nhưng sau đó khóa đã được phát hành.

Chúng tôi có lý do để tin rằng đó có thể là giao diện người dùng không đúng, nhưng không thể tìm thấy "khẩu súng hút thuốc".

Tôi đã tìm thấy một số truy vấn liệt kê các khối, nhưng đó là khi bạn có hai công việc cạnh tranh cho một hàng. Tôi muốn biết những hàng nào có khóa khi không nhất thiết phải là một công việc thứ hai cố gắng lấy khóa.

Chúng tôi đang trên 11g nhưng đã gặp sự cố kể từ 8i.

Trả lời

10

Oracle khái niệm khóa của khóa học hoàn toàn khác với khái niệm của các hệ thống khác.

Khi một hàng trong Oracle bị khóa, bản ghi sẽ được cập nhật với giá trị mới (nếu có) và, ngoài ra, khóa (về bản chất là con trỏ đến khóa giao dịch nằm trong phân đoạn rollback) ngay vào hồ sơ.

Điều này có nghĩa là khóa bản ghi trong Oracle có nghĩa là cập nhật siêu dữ liệu của bản ghi và phát hành viết trang logic. Ví dụ: bạn không thể làm SELECT FOR UPDATE trên vùng bảng chỉ đọc.

Hơn thế nữa, bản thân các bản ghi không được cập nhật sau khi cam kết: thay vào đó, phân đoạn rollback được cập nhật.

Điều này có nghĩa là mỗi bản ghi lưu giữ một số thông tin về giao dịch đã cập nhật lần cuối, ngay cả khi giao dịch đã mất từ ​​lâu. Để tìm hiểu xem giao dịch có đang hoạt động hay không (và, do đó, nếu bản ghi còn sống hay không), bạn phải truy cập phân đoạn quay lại.

Oracle không có trình quản lý khóa truyền thống và điều này có nghĩa là có được danh sách tất cả các khóa yêu cầu quét tất cả các bản ghi trong tất cả các đối tượng. Quá trình này sẽ mất quá nhiều thời gian.

Bạn có thể nhận được một số khóa đặc biệt, như đối tượng siêu dữ liệu bị khóa (sử dụng v$locked_object), khóa chờ (sử dụng v$session) v.v ... chứ không phải danh sách tất cả các khóa trên tất cả các đối tượng trong cơ sở dữ liệu.

+0

Cant' bạn sử dụng V $ LOCK để có được tất cả các ổ khóa? Ngay cả khi bạn không thể xác định các hàng cụ thể đang bị khóa, ít nhất bạn cũng biết bảng nào. –

4

Thay vì khóa, tôi khuyên bạn nên xem giao dịch dài hạn, sử dụng v$transaction. Từ đó bạn có thể tham gia v$session, sẽ cung cấp cho bạn ý tưởng về giao diện người dùng (thử cột chương trình và máy) cũng như người dùng.

4

Nhìn vào dba_blockers, dba_waiters và dba_locks để khóa. Các tên phải tự giải thích.

Bạn có thể tạo công việc chạy, ví dụ, mỗi phút một lần và ghi lại các giá trị trong dba_blockers và sql_id hiện hoạt hiện tại cho phiên đó. (thông qua v $ phiên và v $ sqlstats).

Bạn cũng có thể muốn xem v $ sql_monitor.Điều này sẽ được mặc định đăng nhập tất cả SQL mất nhiều hơn 5 giây. Nó cũng hiển thị trên trang Giám sát SQL trong Enterprise Manager.

+0

'dba_blockers' và các chế độ xem khác mà bạn đã đề cập sẽ chỉ liệt kê các khóa đang chờ. @op quy định rằng anh ta muốn tất cả các khóa, không chỉ những người trên hồ sơ được contended. – Quassnoi

+0

Nhưng nếu không có gì bị chặn thì phiên có thể khóa miễn là nó thích vì nó sẽ không ảnh hưởng đến hiệu suất. Chỉ các khóa chặn ảnh hưởng đến hiệu suất. – PenFold

1

bạn có thể tìm thấy những bảng bị khóa trong Oralce bằng cách truy vấn với truy vấn sau đây

select 
    c.owner, 
    c.object_name, 
    c.object_type, 
    b.sid, 
    b.serial#, 
    b.status, 
    b.osuser, 
    b.machine 
from 
    v$locked_object a , 
    v$session b, 
    dba_objects c 
where 
    b.sid = a.session_id 
and 
    a.object_id = c.object_id;