Oracle ではプロファイルを使ってユーザーごとに同時接続数・CPU 使用量・接続時間などのリソース制限を設定できます。さらにログオントリガーを使えば時間帯や IP アドレスによるログイン制御も可能です。
本記事では、プロファイルのリソース制限、RESOURCE_LIMIT パラメータの有効化、ログオントリガーによる高度な制御、アカウントのロック/アンロックまで解説します。
・プロファイルのリソース制限パラメータ一覧
・RESOURCE_LIMIT パラメータの有効化(リソース制限を機能させる前提条件)
・SESSIONS_PER_USER で同時接続数を制限する方法
・CONNECT_TIME / IDLE_TIME で接続時間を制限する方法
・ログオントリガーで時間帯 / IP アドレスを制限する方法
・アカウントのロック / アンロック
・FAILED_LOGIN_ATTEMPTS でログイン失敗時のロック設定
前提: RESOURCE_LIMIT パラメータの有効化
プロファイルのリソース制限(SESSIONS_PER_USER / CPU_PER_SESSION / CONNECT_TIME 等)は、
RESOURCE_LIMIT パラメータが TRUE でないと無視されます。パスワード制限(PASSWORD_LIFE_TIME 等)は RESOURCE_LIMIT に関係なく常に有効です。-- 現在の設定を確認 SHOW PARAMETER resource_limit; -- デフォルト: FALSE(リソース制限は無効) -- 有効化(即時反映、再起動不要) ALTER SYSTEM SET resource_limit = TRUE SCOPE=BOTH;
プロファイルのリソース制限パラメータ
| パラメータ | デフォルト | 単位 | 説明 |
|---|---|---|---|
| SESSIONS_PER_USER | UNLIMITED | 数 | ユーザーあたりの同時セッション数の上限 |
| CONNECT_TIME | UNLIMITED | 分 | 1 セッションの最大接続時間。超過すると自動切断 |
| IDLE_TIME | UNLIMITED | 分 | アイドル状態の最大時間。超過すると自動切断 |
| CPU_PER_SESSION | UNLIMITED | 1/100 秒 | 1 セッションあたりの最大 CPU 使用時間 |
| CPU_PER_CALL | UNLIMITED | 1/100 秒 | 1 回の SQL 実行あたりの最大 CPU 時間 |
| LOGICAL_READS_PER_SESSION | UNLIMITED | ブロック | 1 セッションの最大論理読み取りブロック数 |
| LOGICAL_READS_PER_CALL | UNLIMITED | ブロック | 1 回の SQL 実行の最大論理読み取りブロック数 |
| PRIVATE_SGA | UNLIMITED | バイト | 共有サーバーモード時の最大 SGA 使用量 |
| COMPOSITE_LIMIT | UNLIMITED | ― | 上記リソースの加重合計の上限 |
リソース制限はプロファイル単位で定義し、ALTER USER … PROFILE でユーザーに適用します。同じプロファイルを複数ユーザーに適用できるため、ロール別(開発者用 / アプリ用 / DBA 用)に管理するのが効率的です。
SESSIONS_PER_USER で同時接続数を制限する
-- 同時接続 3 セッションまでに制限するプロファイル
CREATE PROFILE limited_session LIMIT
SESSIONS_PER_USER 3;
-- ユーザーに適用
ALTER USER dev_user PROFILE limited_session;
-- 4 つ目のセッションを開こうとすると:
-- ORA-02391: exceeded simultaneous SESSIONS_PER_USER limit
-- ユーザーごとの現在のセッション数 SELECT username, COUNT(*) AS session_count FROM v$session WHERE username IS NOT NULL GROUP BY username ORDER BY session_count DESC;
CONNECT_TIME / IDLE_TIME で接続時間を制限する
-- 接続時間 60 分、アイドル 15 分で自動切断するプロファイル
CREATE PROFILE time_limited LIMIT
CONNECT_TIME 60 -- 最大接続時間: 60 分
IDLE_TIME 15; -- アイドル制限: 15 分
ALTER USER dev_user PROFILE time_limited;
-- CONNECT_TIME 超過: ORA-02399 で自動切断
-- IDLE_TIME 超過: ORA-02396 で自動切断
・SQL*Plus を開いたまま放置するユーザーへの対策
・アプリケーション接続プールの放置セッション対策
・データベースのセッション枯渇を防止
ただしアプリケーションの接続プール(JDBC 等)が IDLE_TIME で切断されないよう、プール側の keep-alive 設定を確認してください。
実用的なプロファイル設計例
-- 開発者用: 接続制限あり、パスワード制限は緩め
CREATE PROFILE dev_profile LIMIT
SESSIONS_PER_USER 5
CONNECT_TIME 480 -- 8 時間
IDLE_TIME 30 -- 30 分
PASSWORD_LIFE_TIME UNLIMITED
FAILED_LOGIN_ATTEMPTS 10;
-- アプリ接続用: セッション数は多め、時間制限なし
CREATE PROFILE app_profile LIMIT
SESSIONS_PER_USER 100
CONNECT_TIME UNLIMITED
IDLE_TIME UNLIMITED
PASSWORD_LIFE_TIME UNLIMITED
FAILED_LOGIN_ATTEMPTS 5;
-- DBA 用: 制限なし
CREATE PROFILE dba_profile LIMIT
SESSIONS_PER_USER UNLIMITED
CONNECT_TIME UNLIMITED
IDLE_TIME UNLIMITED
PASSWORD_LIFE_TIME 90
FAILED_LOGIN_ATTEMPTS 3;
-- ユーザーに割り当て
ALTER USER dev_user PROFILE dev_profile;
ALTER USER app_user PROFILE app_profile;
ALTER USER admin_user PROFILE dba_profile;
ログオントリガーで高度な接続制御
プロファイルでは対応できない時間帯制限やIP アドレス制限は、AFTER LOGON トリガーで実現します。
時間帯によるログイン制限
-- 22:00〜7:00 の間はログインを禁止
CREATE OR REPLACE TRIGGER trg_restrict_logon_time
AFTER LOGON ON DATABASE
BEGIN
IF USER NOT IN ('SYS', 'SYSTEM') THEN
IF TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) >= 22
OR TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) < 7 THEN
RAISE_APPLICATION_ERROR(-20001,
'22:00-7:00 の間はログインできません');
END IF;
END IF;
END;
/
IP アドレスによるログイン制限
-- 特定 IP アドレスからのみ接続を許可
CREATE OR REPLACE TRIGGER trg_restrict_logon_ip
AFTER LOGON ON DATABASE
DECLARE
v_ip VARCHAR2(100);
BEGIN
IF USER = 'ADMIN_USER' THEN
v_ip := SYS_CONTEXT('USERENV', 'IP_ADDRESS');
IF v_ip NOT IN ('10.0.1.100', '10.0.1.101', '192.168.1.50') THEN
RAISE_APPLICATION_ERROR(-20002,
'このIPアドレスからの接続は許可されていません: ' || v_ip);
END IF;
END IF;
END;
/
同時接続数の高度な制限(プロファイルの代替)
-- RESOURCE_LIMIT を TRUE にできない環境での代替手段
CREATE OR REPLACE TRIGGER trg_limit_sessions
AFTER LOGON ON DATABASE
DECLARE
v_count NUMBER;
BEGIN
IF USER = 'APP_USER' THEN
SELECT COUNT(*) INTO v_count
FROM v$session WHERE username = 'APP_USER';
IF v_count > 50 THEN
RAISE_APPLICATION_ERROR(-20003,
'APP_USER のセッション数が上限(50)を超えています');
END IF;
END IF;
END;
/
トリガーにバグがあると全ユーザーがログインできなくなる場合があります。SYS / SYSTEM ユーザーはトリガーの対象外にしておいてください。万が一の場合は
sqlplus / as sysdba で接続してトリガーを DROP します。アカウントのロック / アンロック
-- アカウントをロック(ログイン不可にする) ALTER USER dev_user ACCOUNT LOCK; -- アカウントをアンロック ALTER USER dev_user ACCOUNT UNLOCK; -- 状態の確認 SELECT username, account_status, lock_date FROM dba_users WHERE username = 'DEV_USER';
FAILED_LOGIN_ATTEMPTS による自動ロック
-- 5 回失敗で自動ロック、1 時間後に自動アンロック
CREATE PROFILE strict_login LIMIT
FAILED_LOGIN_ATTEMPTS 5
PASSWORD_LOCK_TIME 1/24; -- 1/24 日 = 1 時間
ALTER USER target_user PROFILE strict_login;
-- PASSWORD_LOCK_TIME = UNLIMITED の場合: DBA が手動でアンロックするまで永久ロック
-- PASSWORD_LOCK_TIME = 1 の場合: 1 日後に自動アンロック
| account_status | 意味 | 対処 |
|---|---|---|
| OPEN | 正常 | ― |
| LOCKED | 手動でロックされた | ALTER USER … ACCOUNT UNLOCK |
| LOCKED(TIMED) | ログイン失敗で自動ロック | PASSWORD_LOCK_TIME 経過後に自動解除、または手動 UNLOCK |
| EXPIRED | パスワード期限切れ | ALTER USER … IDENTIFIED BY new_pw |
| EXPIRED & LOCKED | 期限切れ + ロック | ALTER USER … IDENTIFIED BY new_pw ACCOUNT UNLOCK |
現在の設定を確認する
-- ユーザーのプロファイル割り当てを確認
SELECT username, profile, account_status
FROM dba_users
WHERE username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB')
ORDER BY profile, username;
-- プロファイルのリソース制限を確認
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE resource_type = 'KERNEL' -- リソース制限
ORDER BY profile, resource_name;
-- パスワード制限を確認
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE resource_type = 'PASSWORD'
ORDER BY profile, resource_name;
実務パターン集
パターン(1): 開発者の同時接続を 3 に制限
ALTER SYSTEM SET resource_limit = TRUE SCOPE=BOTH;
CREATE PROFILE dev_limited LIMIT
SESSIONS_PER_USER 3
IDLE_TIME 30;
ALTER USER dev_user PROFILE dev_limited;
パターン(2): 退職者のアカウントを即時ロック
-- 退職者のアカウントを即時ロック ALTER USER ex_employee ACCOUNT LOCK; -- 既存セッションの強制切断(必要に応じて) -- SID / SERIAL# を確認 SELECT sid, serial# FROM v$session WHERE username = 'EX_EMPLOYEE'; -- 切断 ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
パターン(3): 本番 DB に夜間のみ接続を許可
-- 業務時間(9:00〜18:00)のみ接続を許可するトリガー
CREATE OR REPLACE TRIGGER trg_business_hours_only
AFTER LOGON ON DATABASE
BEGIN
IF USER = 'BATCH_USER' THEN
IF TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) BETWEEN 9 AND 17 THEN
RAISE_APPLICATION_ERROR(-20010,
'BATCH_USER は業務時間中(9:00-18:00)は接続できません');
END IF;
END IF;
END;
/
パターン(4): アイドルセッションの一括切断
-- 30 分以上アイドルのユーザーセッションを確認
SELECT sid, serial#, username, status,
last_call_et/60 AS idle_minutes
FROM v$session
WHERE status = 'INACTIVE'
AND type = 'USER'
AND last_call_et > 1800; -- 1800 秒 = 30 分
-- 一括切断用 SQL を生成
SELECT 'ALTER SYSTEM KILL SESSION ''' || sid || ',' || serial# || ''' IMMEDIATE;'
FROM v$session
WHERE status = 'INACTIVE' AND type = 'USER' AND last_call_et > 1800;
よくある質問
sqlplus / as sysdba(OS 認証)で接続できます。SYS ユーザーは AFTER LOGON ON DATABASE トリガーの影響を受けません。接続後に DROP TRIGGER trigger_name; で問題のトリガーを削除してください。まとめ
ユーザーごとの接続制限の要点をまとめます。
| やりたいこと | 方法 |
|---|---|
| リソース制限を有効化(前提条件) | ALTER SYSTEM SET resource_limit = TRUE SCOPE=BOTH |
| 同時接続数を制限 | CREATE PROFILE … LIMIT SESSIONS_PER_USER N |
| 接続時間を制限 | CREATE PROFILE … LIMIT CONNECT_TIME N |
| アイドル時間で自動切断 | CREATE PROFILE … LIMIT IDLE_TIME N |
| 時間帯でログインを制限 | AFTER LOGON ON DATABASE トリガーで RAISE_APPLICATION_ERROR |
| IP アドレスでログインを制限 | SYS_CONTEXT(‘USERENV’, ‘IP_ADDRESS’) をトリガーで判定 |
| アカウントを手動ロック | ALTER USER … ACCOUNT LOCK |
| ログイン失敗で自動ロック | FAILED_LOGIN_ATTEMPTS N + PASSWORD_LOCK_TIME N |
プロファイルの全パラメータは「ユーザープロファイル完全ガイド」、パスワード有効期限は「パスワードの有効期限を無制限にする方法」、ユーザーの作成と権限は「ユーザー作成と権限付与の完全ガイド」も併せて参照してください。

