GET /ords/hr/employees/ # 列表(支持分页) GET /ords/hr/employees/:id # 单条记录 POST /ords/hr/employees/ # 创建记录 PUT /ords/hr/employees/:id # 更新记录 DELETE /ords/hr/employees/:id # 删除记录
3.2.3 参数化查询
在 Handler 中支持多种参数绑定方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-- 带分页和过滤的查询 BEGIN ORDS.DEFINE_HANDLER( p_module_name =>'employees.api', p_pattern =>'search', p_method =>'GET', p_source_type =>'json/query', p_source =>'SELECT employee_id, first_name, last_name, salary FROM employees WHERE (:min_salary IS NULL OR salary >= :min_salary) AND (:dept_id IS NULL OR department_id = :dept_id) ORDER BY salary DESC' ); COMMIT; END; /
调用示例:
1 2
# 查询薪资大于 5000 且部门 ID 为 50 的员工 curl -X GET "https://api.example.com/ords/hr/emp/search?min_salary=5000&dept_id=50"
-- 创建存储过程:计算部门薪资统计 CREATEOR REPLACE PROCEDURE hr.get_dept_salary_stats( p_dept_id IN NUMBER, p_avg_salary OUT NUMBER, p_max_salary OUT NUMBER, p_min_salary OUT NUMBER, p_emp_count OUT NUMBER ) AS BEGIN SELECTAVG(salary), MAX(salary), MIN(salary), COUNT(*) INTO p_avg_salary, p_max_salary, p_min_salary, p_emp_count FROM employees WHERE department_id = p_dept_id; END; /
-- 暴露为 REST API BEGIN ORDS.DEFINE_MODULE( p_module_name =>'salary.api', p_base_path =>'/salary/' ); COMMIT; END; /
BEGIN ORDS.DEFINE_TEMPLATE( p_module_name =>'salary.api', p_pattern =>'dept-stats' ); COMMIT; END; /
sqlplus -S / as sysdba <<EOF | tail -1 SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF SELECT ROUND((used.bytes / total.bytes) * 100, 2) FROM (SELECT tablespace_name, SUM(bytes) bytes FROM dba_data_files WHERE tablespace_name = UPPER('${TABLESPACE_NAME}') GROUP BY tablespace_name) total, (SELECT tablespace_name, SUM(bytes) bytes FROM dba_segments WHERE tablespace_name = UPPER('${TABLESPACE_NAME}') GROUP BY tablespace_name) used WHERE total.tablespace_name = used.tablespace_name(+); EOF
case"$METRIC"in "sessions") sqlplus -S / as sysdba <<'EOF' | tail -1 SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF SELECT COUNT(*) FROM v\$session WHERE status = 'ACTIVE'; EOF ;; "archive_rate") sqlplus -S / as sysdba <<'EOF' | tail -1 SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF SELECT ROUND(SUM(blocks * block_size) / 1024 / 1024, 2) FROM v\$archived_log WHERE first_time > SYSDATE - 1/24 AND dest_id = 1; EOF ;; "dg_lag") sqlplus -S / as sysdba <<'EOF' | tail -1 SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF SELECT VALUE FROM v\$dataguard_stats WHERE NAME = 'apply lag'; EOF ;; esac
case"$OBJECT_TYPE"in "tablespace") sqlplus -S / as sysdba <<'EOF' SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF SELECT '{"data":[' FROM dual; SELECT LISTAGG('{"{#TABLESPACE_NAME}":"' || tablespace_name || '"}', ',') WITHIN GROUP (ORDER BY tablespace_name) FROM dba_tablespaces WHERE contents = 'PERMANENT'; SELECT ']}' FROM dual; EOF ;; esac
# 表空间使用率 [[metric]] context = "oracle_tablespace" metricsdesc = { pct_used = "Tablespace percent used", free_mb = "Free space in MB", total_mb = "Total space in MB" } request = """ SELECT t.tablespace_name, ROUND((1 - (f.free_bytes / t.total_bytes)) * 100, 2) as pct_used, ROUND(f.free_bytes / 1024 / 1024, 2) as free_mb, ROUND(t.total_bytes / 1024 / 1024, 2) as total_mb FROM (SELECT tablespace_name, SUM(bytes) total_bytes FROM dba_data_files GROUP BY tablespace_name) t, (SELECT tablespace_name, SUM(bytes) free_bytes FROM dba_free_space GROUP BY tablespace_name) f WHERE t.tablespace_name = f.tablespace_name(+) """
# Active Session Count [[metric]] context = "oracle_session" metricsdesc = { active_count = "Number of active sessions", total_count = "Total sessions" } request = """ SELECT SUM(CASE WHEN status='ACTIVE' THEN 1 ELSE 0 END) as active_count, COUNT(*) as total_count FROM v$session WHERE type = 'USER' """
# DG Stats [[metric]] context = "oracle_dg" metricsdesc = { apply_lag_seconds = "Data Guard apply lag in seconds", transport_lag_seconds = "Transport lag in seconds" } request = """ SELECT EXTRACT(DAY FROM TO_DSINTERVAL(VALUE)) * 86400 + EXTRACT(HOUR FROM TO_DSINTERVAL(VALUE)) * 3600 + EXTRACT(MINUTE FROM TO_DSINTERVAL(VALUE)) * 60 + EXTRACT(SECOND FROM TO_DSINTERVAL(VALUE)) as apply_lag_seconds FROM v$dataguard_stats WHERE name = 'apply lag' """
# Top SQL by Elapsed Time [[metric]] context = "oracle_top_sql" metricsdesc = { elapsed_seconds = "SQL elapsed time", executions = "SQL executions", buffer_gets = "Buffer gets" } request = """ SELECT ROWNUM as sql_rank, ROUND(elapsed_time / 1000000, 2) as elapsed_seconds, executions, buffer_gets FROM ( SELECT elapsed_time, executions, buffer_gets FROM v$sql ORDER BY elapsed_time DESC ) WHERE ROWNUM <= 10 """
配置 systemd 服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# /etc/systemd/system/oracledb_exporter.service [Unit] Description=Oracle DB Exporter After=network.target
# 2. 在节点1上执行 opatch auto # 该命令会自动完成: # - 停止节点1上的数据库实例 # - 应用 GI Home 补丁 # - 应用 DB Home 补丁 # - 启动节点1上的数据库实例 cd /u01/patches/36233123 $ORACLE_HOME/OPatch/opatch auto /u01/patches/36233123 \ -ocmrf /u01/patches/ocm.rsp
# 验证回滚 $ORACLE_HOME/OPatch/opatch lsinventory sqlplus / as sysdba SQL> select PATCH_ID, ACTION, STATUS, DESCRIPTION from DBA_REGISTRY_SQLPATCH order by ACTION_TIME;
-- 查看SYSAUX中审计占用空间 SELECT occupant_name, space_usage_kbytes, ROUND(space_usage_kbytes/1024, 2) AS usage_mb FROM V$SYSAUX_OCCUPANTS WHERE occupant_name LIKE'%AUDIT%';
-- 查询最近7天的登录失败记录 SELECT event_timestamp, dbusername, client_identifier, action_name, return_code, userhost, terminal, authentication_type FROM DBA_UNIFIED_AUDIT_TRAIL WHERE action_name IN ('LOGON', 'LOGOFF') AND return_code !=0 AND event_timestamp > SYSTIMESTAMP -INTERVAL'7'DAY ORDERBY event_timestamp DESC;
-- 统计失败登录的用户分布 SELECT dbusername, COUNT(*) AS fail_count FROM DBA_UNIFIED_AUDIT_TRAIL WHERE action_name ='LOGON' AND return_code !=0 AND event_timestamp > SYSTIMESTAMP -INTERVAL'7'DAY GROUPBY dbusername ORDERBY fail_count DESC;
特权操作审计
审计所有 DBA 角色用户的敏感操作,防止特权滥用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
-- 创建特权操作审计策略 CREATE AUDIT POLICY dba_operations_policy PRIVILEGES ALTERSYSTEM, ALTER DATABASE, ALTERUSER, DROPUSER, CREATEANYTABLE, ALTERANYTABLE, DROPANYTABLE WHEN'SYS_CONTEXT(''USERENV'',''SESSION_USER'') NOT IN (''SYS'',''SYSTEM'')' EVALUATE PER SESSION;
-- 启用 AUDIT POLICY dba_operations_policy BY USERS WITH GRANTED ROLES DBA;
策略创建完成后,可以查看策略的详细定义:
1 2 3 4 5
-- 查看策略详情 SELECT POLICY_NAME, AUDIT_OPTION, AUDIT_OPTION_TYPE, OBJECT_SCHEMA, OBJECT_NAME, COMMON FROM AUDIT_UNIFIED_POLICIES WHERE POLICY_NAME ='DBA_OPERATIONS_POLICY';
3.3 FGA 配置
细粒度审计(FGA)通过 DBMS_FGA 包实现,是 Unified Auditing 中最灵活的审计方式。与普通操作审计不同,FGA 支持基于 WHERE 条件精确控制审计范围,适合对敏感数据的按条件审计。
Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=dbserver)(PORT=1521))) Services Summary... Service "ORCL" has 1 instance(s). Instance "ORCL", status READY, has 1 handler(s) for this service...