1. 背景
业务出现异常后,或者某个sql导致系统卡顿。需要问题后需要溯源,需要获取这个sql是在哪个客户端的IP发起的。
2. cs架构
客户端直接连接数据库,可以很方便查询,采用通过sql_id找到客户端、进程或者port等,默认的模式是没有ip地址记录
select machine,program,port from GV$SESSION where sql_id=
或者
select machine,program,port from GV$ACTIVE_SESSION_HISTORY where sql_id=
select machine,program,port from dba_hist_ACTIVE_SESS_HISTORY where sql_id=
再通过数据库监听查询或者应用服务器
2.1. 案例说明
select machine,program,port from GV$SESSION where sql_id=
或者 GV$ACTIVE_SESSION_HISTORY 的表获取到
通过获取machine、program、port这几个字段。
再通过数据库监听日志只获取
cat listener.log|grep 51880|grep Thin
注意:发现监控日志中记录的计算机的主机名和session中记录的可能不一致
3. BS架构
bs架构和cs架构的不同点,bs采用多层架构,是应用服务连接数据库的,获取到的ip也是应用服务器的ip地址。
以java应用服务器为例,需要查询到客户端的ip发起端。
有个技巧:java服务的应用名称都是叫JDBC Thin Client,这样一台服务器中有多个java服务是无法区别的,可以手工区别名称来定义不同的java服务,如java应用的配置文件中,针对链接池配置,这样你的应用名称就变成了oracle-monitor
data-source-properties:
"[v$session.program]": oracle-monitor
有以下几种方式
-
通过nginx,客户端连接nginx,nginx转发到应用服务器中。再配置时间和请求的交易来定位,需要记录应用服务器的日志,日志格式类似
log_format main '$remote_addr - remote_user [time_local] "request" ' 'status $body_bytes_sent $request_time upstream_response_time "http_referer" '
'$connection upstream_addr "http_x_forwarded_for" "$http_cookie" ';
$remote_addr:这个就是客户端的ip
- 没有nginx,应用容器采用tomcat,可以查看tomcat的请求日志
- 还有应用端记录登录日志来获取
4. 数据库登录触发器
登录的时候,可以再session记录ip地址,这样就不需要到监控日志中去查询具体的ip地址
CREATE OR REPLACE TRIGGER on_logon_trigger
AFTER LOGON ON DATABASE
BEGIN
DBMS_APPLICATION_INFO.SET_CLIENT_INFO(SYS_CONTEXT('USERENV', 'IP_ADDRESS'));
END;
SELECT * FROM gv$session WHERE client_info 这个字段中就会体现ip地址
5. 总结
追溯源头的ip地址
- 通过慢的sql_id来获取客户端、应用、port,来定位ip地址。BS架构中应用服务名可以在链接池中设置不同的应用名。可以新增一个登录的触发器,记录一下ip更加方便
- BS架构需要定位客户端,需要通过请求和时间等,再通过nginx或者tomcat访问日志来定位