在为某客户构建hands-on实验环境时,由于测试环境有限,我们在同一环境中建立了一套ADG环境。数据库是单实例,版本为19.21,并使用了多租户选项。在测试的PDB中,名为demo1,我们创建了测试用户jingyu。然而,我们遇到了一个问题:当使用sqlplus连接时,会随机连接到主库或者备库。 排查定位问题并不复杂,因为在这样的环境中,监听lsnrctl status可以看到对应的服务下存在两个实例,一个是主库,一个是ADG备库。但是,在修改配置tnsnames.ora时,指定具体实例的语法却让我走了弯路。 监听服务如下: Service "demo1.sub00000000000.xxvcn.xxxxxxvcn.com" has 2 instance(s). Instance "DB0913", status READY, has 1 handler(s) for this service... Instance "DB0913_DG", status READY, has 1 handler(s) for this service... tnsnames.ora配置如下: DEMO1 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = demo.sub00000000000.xxvcn.xxxxxxvcn.com)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = demo1.sub00000000000.xxvcn.xxxxxxvcn.com) ) ) 这里面就是标准配置,HOST那里写主机名或IP地址,这里同一环境,所以主备库肯定一样,端口也是标准的1521,service_name是默认的pdb服务名,也一样。所以当使用: sqlplus jingyu/pwd@demo1 连接就会随机连接到主库或者备库。而我们应该指定到底是连接主库还是备库。正确的方法是查阅Oracle官方文档说明,可以找到这个参数: 6.9.7 INSTANCE_NAME Purpose To identify the database instance to access. Usage Notes Set the value to the value specified by the INSTANCE_NAME parameter in the initialization parameter file. Put this parameter under the CONNECT_DATA parameter. 说的非常明白,在CONNECT_DATA参数下面,添加INSTANCE_NAME指定要连接的实例。所以,正确的做法应该是这样配置: P_DEMO1 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = demo.sub00000000000.xxvcn.xxxxxxvcn.com)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = demo1.sub00000000000.xxvcn.xxxxxxvcn.com) (INSTANCE_NAME = DB0913) ) ) S_DEMO1 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = demo.sub00000000000.xxvcn.xxxxxxvcn.com)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = demo1.sub00000000000.xxvcn.xxxxxxvcn.com) (INSTANCE_NAME = DB0913_DG) ) ) 然后,指定清楚别名来区分主备库的连接: --连接主库: sqlplus jingyu/pwd@p_demo1 --连接备库: sqlplus jingyu/pwd@s_demo1 非常简单对吧? 可是自己最开始偷懒,直接问了LLM的AI,结果前期得到各种风马牛不相及的答案。比如让我去加(ROLE=PRIMARY)、(ROLE=PHYSICAL STANDBY)这样的参数,或者是(SID=DB0913)、(SID=DB0913_DG)。这次终于算是让我切身感受了LLM的幻觉问题有多严重。 由于前段时间通过AI快速辅助我解决了一个疑难问题,让我树立了对AI的信心。可是这次,如此简单的问题,给出的答案经过测试却完全不对。 看来客观事实是,目前针对专业性问题,AI的局限性其实还是很大的,不怕你说不知道,就怕一本正经的胡说八道。另外提供给AI非常精准的提示词也是非常有挑战的一件事情,比如这个问题,我相信如果提示词写的足够好,也可能会得到正确答案,但很可能前提是你知道这个参数。比如我查阅了官方手册,再试图引导去问的时候,的确可以得出正确的答案,可这个意义还有多大很值得商榷。 AI这样的回答给人带来的迷惑性极大,导致明明很简单的一个技术问题,却浪费了很多时间。不过,也不能因噎废食,相信随着技术的进步,通过更好的通用LLM,辅助加上专业领域知识RAG的检索增强,一定会得到越来越可靠的答案给我们做参考,但目前看起来很长一段时间内,都还需要专家来严格把关最终结果。
判断任务过期时间自定义函数: create or replace function GetUrgentState(m_TaskID varchar2, m_SendTime date, m_flag varchar2) return varchar2 IS myDate date; ExpireTime date; strsql varchar2(200); begin myDate := m_SendTime; strsql := ‘select max(EXPIRETIME) from t_wf_supervise where TASKID =”’ || m_TaskID || ””; execute immediate strsql into ExpireTime; –没有到期时间 就是正常状态 if ExpireTime is null then if m_flag = ‘String’ then return ‘正常’; end if; if m_flag = ‘Img’ then return ‘cb_execute。 gif’; end if; end if; –未发送任务,就是判断当前时间 if m_SendTime is null then myDate := sysdate; end if; if ExpireTime gif’; end if; end if; –小于3天的任务预警。