2008-09-10 25 views
28

Tôi cần nhanh chóng (và buộc) giết tất cả các phiên bên ngoài kết nối với cơ sở dữ liệu Oracle của tôi mà không cần sự giám sát và quản trị viên.Làm thế nào tôi có thể giết tất cả các phiên kết nối với cơ sở dữ liệu oracle của tôi?

Tôi không muốn chỉ khóa cơ sở dữ liệu và cho phép người dùng thoát một cách duyên dáng.

Làm cách nào để tôi viết kịch bản này?

Trả lời

42

Câu trả lời này bị ảnh hưởng nặng nề bởi một cuộc nói chuyện ở đây: http://www.tek-tips.com/viewthread.cfm?qid=1395151&page=3

ALTER SYSTEM ENABLE RESTRICTED SESSION; 

begin  
    for x in ( 
      select Sid, Serial#, machine, program 
      from v$session 
      where 
       machine <> 'MyDatabaseServerName' 
     ) loop 
     execute immediate 'Alter System Kill Session '''|| x.Sid 
        || ',' || x.Serial# || ''' IMMEDIATE'; 
    end loop; 
end; 

tôi bỏ qua giết phiên có nguồn gốc trên máy chủ cơ sở dữ liệu để tránh giết chết tắt các kết nối của Oracle cho chính nó.

+0

tôi nhận được ORA-06.550. HỆ THỐNG ALTER dường như không được phép bên trong đầu tiên kết thúc –

+0

Tôi đã sửa mã. – BIBD

1

Hãy thử kích hoạt trên đăng nhập

insted của người dùng ngắt kết nối cố gắng bạn không nên cho phép họ kết nối.

Có và ví dụ về trình kích hoạt như vậy.

CREATE OR REPLACE TRIGGER rds_logon_trigger 
AFTER LOGON ON DATABASE 
BEGIN 
    IF SYS_CONTEXT('USERENV','IP_ADDRESS') not in ('192.168.2.121','192.168.2.123','192.168.2.233') THEN 
    RAISE_APPLICATION_ERROR(-20003,'You are not allowed to connect to the database'); 
    END IF; 

    IF (to_number(to_char(sysdate,'HH24'))< 6) and (to_number(to_char(sysdate,'HH24')) >18) THEN 
    RAISE_APPLICATION_ERROR(-20005,'Logon only allowed during business hours'); 
    END IF; 

END; 
+0

Điều này thực sự sẽ hoạt động nếu mục tiêu của tôi là giới hạn quyền truy cập vào phạm vi hoặc thời gian IP cụ thể. Mục tiêu của tôi là buộc tất cả người dùng của tôi phải truy cập vào cơ sở dữ liệu, không ngăn chặn thông tin đăng nhập. Cảm ơn, mặc dù - Tôi sẽ ghi nhớ điều đó. – BIBD

7

Trước khi phiên giết chết, nếu có thể làm

ALTER SYSTEM ENABLE RESTRICTED SESSION; 

dừng phiên mới từ kết nối.

+0

Có thực sự, điều này làm cho giải pháp của tôi hoàn chỉnh hơn. – BIBD

2

Nếu bạn muốn dừng người dùng mới kết nối, nhưng cho phép phiên hiện tại để tiếp tục cho đến khi họ không hoạt động, bạn có thể đặt cơ sở dữ liệu trong chế độ quiesce:

ALTER SYSTEM QUIESCE RESTRICTED; 

Từ Oracle Database Administrator's Guide:

Phiên hoạt động không phải DBA sẽ tiếp tục cho đến khi chúng trở thành không hoạt động. Phiên hoạt động là phiên hiện tại là bên trong giao dịch, truy vấn, tìm nạp hoặc câu lệnh PL/SQL; hoặc phiên hiện đang nắm giữ bất kỳ tài nguyên được chia sẻ nào (ví dụ: dung dịch). Không phiên không hoạt động được phép trở thành hoạt động ... Khi tất cả phiên phi DBA trở thành không hoạt động, ALTER SYSTEM quiesce GIỚI HẠN CỦA tuyên bố hoàn tất, và cơ sở dữ liệu là trong tình trạng tĩnh

+0

Tôi sẽ ghi nhớ điều đó. Trong trường hợp của tôi, tôi muốn khởi động người dùng mà không phải chờ giao dịch của họ kết thúc (một số trong số đó là khá dài). Mọi người ra khỏi hồ bơi NGAY BÂY GIỜ !!! – BIBD

1

Tôi tìm thấy đoạn mã bên dưới hữu ích. Lấy từ: http://jeromeblog-jerome.blogspot.com/2007/10/how-to-unlock-record-on-oracle.html

select 
owner||'.'||object_name obj , 
oracle_username||' ('||s.status||')' oruser , 
os_user_name osuser , 
machine computer , 
l.process unix , 
s.sid||','||s.serial# ss , 
r.name rs , 
to_char(s.logon_time,'yyyy/mm/dd hh24:mi:ss') time 
from v$locked_object l , 
dba_objects o , 
v$session s , 
v$transaction t , 
v$rollname r 
where l.object_id = o.object_id 
and s.sid=l.session_id 
and s.taddr=t.addr 
and t.xidusn=r.usn 
order by osuser, ss, obj 
; 

Sau đó chạy:

Alter System Kill Session '<value from ss above>' 
; 

Để giết phiên riêng lẻ.

11

Như SYS:

startup force; 

tàn bạo, nhưng vẫn tao nhã.

1

Để trả lời câu hỏi hỏi, đây là SQL chính xác nhất để hoàn thành công việc, bạn có thể kết hợp nó với vòng PL/SQL để thực sự chạy giết tuyên bố:

select ses.USERNAME, 
    substr(MACHINE,1,10) as MACHINE, 
    substr(module,1,25) as module, 
    status, 
    'alter system kill session '''||SID||','||ses.SERIAL#||''';' as kill 
from v$session ses LEFT OUTER JOIN v$process p ON (ses.paddr=p.addr) 
where schemaname <> 'SYS' 
    and not exists 
    (select 1 
     from DBA_ROLE_PRIVS 
     where GRANTED_ROLE='DBA' 
      and schemaname=grantee) 
    and machine!='yourlocalhostname' 
order by LAST_CALL_ET desc; 
4

Tôi đã sử dụng một cái gì đó như thế này trong một thời gian để giết phiên của tôi trên một máy chủ chia sẻ. Dòng đầu tiên của 'nơi' có thể được loại bỏ để giết các buổi tất cả các phi 'sys':

BEGIN 
    FOR c IN (
     SELECT s.sid, s.serial# 
     FROM v$session s 
     WHERE (s.Osuser = 'MyUser' or s.MACHINE = 'MyNtDomain\MyMachineName') 
     AND s.USERNAME <> 'SYS' 
     AND s.STATUS <> 'KILLED' 
) 
    LOOP 
     EXECUTE IMMEDIATE 'alter system kill session ''' || c.sid || ',' || c.serial# || ''''; 
    END LOOP; 
END; 
2

thông tin bổ sung

quan trọng thay đổi 11g Oracle để thay đổi phiên phiên kill

Oracle tác giả Mladen Gogala lưu ý rằng dấu @ phải được yêu cầu để giết phiên khi sử dụng cột inst_id:

alter system kill session '130,620,@1'; 

http://www.dba-oracle.com/tips_killing_oracle_sessions.htm

0

Nếu Oracle đang chạy trong Unix/Linux thì chúng ta có thể grep cho tất cả các kết nối khách hàng và giết nó

grep tất cả các quá trình oracle client:

ps-ef | grep LOCAL = KHÔNG | grep -v grep | awk '{print $ 2}' | wc -l

Giết tất cả oracle quá trình khách hàng:

kill -9 ps -ef | grep LOCAL=NO | grep -v grep | awk '{print $2}'