马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
[20241013]sqlplus spool与文件覆盖.txt
--//这个问题在8月份遇到的问题,我发现在sqlplus下spool a.sql文件,并没有在当前目次产生a.sql文件,后来我发现建立在情况变量
--//ORACLE_PATH定义的目次下,其时以为本身打开多个会话,没有注意本身工作的当前目次。事后我测试,问题视乎消失了,我再没有仔
--//细探究。
--//昨天在使用spool命令时再次出现这种诡异的现象,才引起我的注意,这才发现问题的根本原因,通过例子将问题演示出来。
1.情况:
SCOTT@book01p> @ ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
$ echo -e "$SQLPATH\n$ORACLE_PATH"
/home/oracle/sqllaji:/home/oracle/sqllaji/tpt
/home/oracle/sqllaji:/home/oracle/sqllaji/tpt
--//我定义2个情况变量SQLPATH与ORACLE_PATH,在linux下ORACLE_PATH定义有用,windows下正好相反,建议如果记不住,两个都定义相
--//同的值。
2.测试:
--//session 1:
SCOTT@book01p> @ spid
SID SERIAL# PROCESS SERVER SPID PID P_SERIAL# C50
---- ---------- -------- --------- ---- --- ---------- --------------------------------------------------
275 27250 4289 DEDICATED 4291 66 12 alter system kill session '275,27250' immediate;
SCOTT@book01p> host pwd
/home/oracle/study/202410
--//当前执行sqlplus时的当前目次是/home/oracle/study/202410.
--//window 1:
$ pwd
/home/oracle/sqllaji
--//在/home/oracle/sqllaji目次下建立文件tmp123.txt。
$ echo $(date) >| tmp123.txt
$ cat tmp123.txt
Sun Oct 13 10:14:43 CST 2024
$ wc tmp123.txt
1 6 29 tmp123.txt
--//session 1:
SCOTT@book01p> spool tmp123.txt
--//window 1:
$ ls -l /proc/4291/fd | grep tmp
--//连接oracle的历程并没有看到打开tmp123.txt的文件句柄,其时测试也遇到类似困惑。不外马上明白应该看看sqlplus历程,因为我在
--//本地连接数据库,sqlplus历程对应前面显示PROCESS字段,也就是4289.
$ ls -l /proc/4289/fd | grep tmp
l-wx------. 1 oracle oinstall 64 2024-10-13 10:17:25 10 -> /home/oracle/sqllaji/tmp123.txt
--//可以发现在sqlplus下执行spool时,如果情况变量SQLPATH与ORACLE_PATH定义的目次该文件存在,优先将文件打开建立在该目次,这
--//样的效果导致情况变量SQLPATH与ORACLE_PATH对应文件被覆盖。
--//session 1:
SCOTT@book01p> spool tmp123.txt
SCOTT@book01p> @ver2
==============================
PORT_STRING : x86_64/Linux 2.4.xx
VERSION : 21.0.0.0.0
BANNER : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID : 0
PL/SQL procedure successfully completed.
SCOTT@book01p> spool off
--//window 1:
$ ls -l /proc/4289/fd | grep tmp
--//文件句柄关闭。
$ wc /home/oracle/sqllaji/tmp123.txt
25 106 1909 /home/oracle/sqllaji/tmp123.txt
--//对比前面的执行wc的输出,文件长度已经发生变化,该文件被破坏了。
--//这个在运维中应该引起足够注意,好的办理方法限制情况变量SQLPATH,ORACLE_PATH目次下的文件只读,或者
--//通过chattr修改文件目次属性,限制修改操作。不外这样认真正需要修改时要取消设置,比力麻烦。
--//别的spool时如果不指定sql后缀的文件,也许一定程度减少覆盖。
--//还有一个方法就是使用绝对目次。我以为最不可思议的地方是使用相对目次,竟然优先使用的也是SQLPATH或者ORACLE_PATH定义情况
--//的文件。
--//增补测试:
--//session 1,使用相对目次有问题!!
SCOTT@book01p> host pwd
/home/oracle/study/202410
SCOTT@book01p> spool ./tmp123.txt
--//window 1:
$ ls -l /proc/3796/fd | grep tmp
l-wx------. 1 oracle oinstall 64 2024-10-14 08:56:04 10 -> /home/oracle/sqllaji/tmp123.txt
--//session 1,使用绝对目次没有问题。
SCOTT@book01p> spool /home/oracle/study/202410/tmp123.txt
SCOTT@book01p> host ls -l /proc/3796/fd | grep tmp
l-wx------. 1 oracle oinstall 64 Oct 14 08:56 10 -> /home/oracle/study/202410/tmp123.txt
--//session 1,将文件建立在情况变量ORACLE_PATH指定的第2个目次下。
$ rm /home/oracle/sqllaji/tmp123.txt
SCOTT@book01p> host touch /home/oracle/sqllaji/tpt/tmp123.txt
--//采用相对目次。
SCOTT@book01p> spool ./tmp123.txt
SCOTT@book01p> host ls -l /proc/3796/fd | grep tmp
l-wx------. 1 oracle oinstall 64 Oct 14 08:56 10 -> /home/oracle/sqllaji/tpt-oracle-master/tmp123.txt
--//这样ls看到的文件属性前面有1个l,估计表示lock。
--//注:我的测试情况tpt是软连接指向tpt-oracle-master
$ ls -l | grep tpt
lrwxrwxrwx. 1 oracle oinstall 17 2021-11-22 09:28:29 tpt -> tpt-oracle-master
drwxr-xr-x. 19 oracle oinstall 20480 2024-10-14 09:09:10 tpt-oracle-master
drwxr-xr-x. 19 oracle oinstall 20480 2024-09-14 17:37:54 tpt-oracle-master.org
--//session 1,3个目次文件都存在的情况下:
SCOTT@book01p> host touch /home/oracle/sqllaji/tmp123.txt
SCOTT@book01p> host touch /home/oracle/sqllaji/tpt/tmp123.txt
SCOTT@book01p> host touch /home/oracle/study/202410/tmp123.txt
SCOTT@book01p> spool tmp123.txt
SCOTT@book01p> host ls -l /proc/3796/fd | grep tmp
l-wx------. 1 oracle oinstall 64 Oct 14 08:56 10 -> /home/oracle/sqllaji/tmp123.txt
--//优先使用情况变量ORACLE_PATH指向的第一个目次下的文件。
SCOTT@book01p> spool ./tmp123.txt
SCOTT@book01p> host ls -l /proc/3796/fd | grep tmp
l-wx------. 1 oracle oinstall 64 Oct 14 08:56 10 -> /home/oracle/sqllaji/tmp123.txt
3.增补测试:
--//如果是目次呢?
--//window 1:
$ pwd
/home/oracle/sqllaji
$ mkdir tmp123.txt
--//session 1:
SCOTT@book01p> spool tmp123.txt
SP2-0606: Cannot create SPOOL file "/home/oracle/sqllaji/tmp123.txt"
--//报错,再次证明我前面的分析正确,感觉oracle的sqlplus spool不应该这样计划,这样不小心会导致文件覆盖。
--//我前面执行spool a.sql,实际上正好破环了tpt目次a.sql,我其时发现直接删除该文件。因为我有时候需要修改tpt目次下文件,
--//原始文件我有备份。
$ pwd
/home/oracle/sqllaji
$ find . -name a.sql -print
./tpt-oracle-master.org/a.sql
--//a.sql 用来 Display CURRENT active sessions。
--//事后我测试,问题视乎消失了,实际上spool指定的文件不在情况变量SQLPATH与ORACLE_PATH中存在,问题天然不存在。
--//再次说明,做好运维一些细节很重要,不要放弃本身在工作中遇到的任何问题,最好条记,这样再次遇到就会做到临危不乱。
--//如果昨天不是spool a.sql,而tpt目次下正好有1个a.sql文件,这个问题也许永久不被发现。
4.收尾:
--//删除相干目次下tmp123.txt文件。
--//修复破坏现场。
$ pwd
/home/oracle/sqllaji
$ rmdir tmp123.txt
$ cp tpt-oracle-master.org/a.sql tpt/
SCOTT@book01p> @ a
A-Script: Display CURRENT active sessions...
no rows selected
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |