[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
[20241013]sqlplus spool与文件覆盖.txt
来源:这里教程网
时间:2026-03-03 20:42:06
作者:
编辑推荐:
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- 达梦数据库安装与配置
达梦数据库安装与配置
26-03-03 - 数据库管理-第248期 23ai:全球分布式数据库-分片数据分布方法(20241006)
- Oracle这款免费的代码平台,铁了心砸掉程序员饭碗!
Oracle这款免费的代码平台,铁了心砸掉程序员饭碗!
26-03-03 - 使用Oracle 19c,必须要注意这个Bug
使用Oracle 19c,必须要注意这个Bug
26-03-03 - 数据库管理-第249期 23ai:全球分布式数据库-请求路由与查询过程(20241008)
- 推荐几本学习Oracle初期阅读的书
推荐几本学习Oracle初期阅读的书
26-03-03 - oracle数据坏块处理(一)-通过rman备份修复
oracle数据坏块处理(一)-通过rman备份修复
26-03-03 - golden gate目录从standby端迁移到primary端
golden gate目录从standby端迁移到primary端
26-03-03 - Oracle数据恢复—异常断电导致Oracle数据库数据库打不开的数据恢复案例
- 数据库管理-第244期 一次无法switchover的故障处理(20240928)
