首页 > 数据库 >[20241013]sqlplus spool与文件覆盖.txt

[20241013]sqlplus spool与文件覆盖.txt

时间:2024-10-14 20:12:48浏览次数:7  
标签:txt 20241013 -- spool sqlplus oracle home tmp123 book01p

[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

标签:txt,20241013,--,spool,sqlplus,oracle,home,tmp123,book01p
From: https://www.cnblogs.com/lfree/p/18464924

相关文章

  • Centos7---k8s集群 20241013
    目录一、硬件准备(虚拟主机)二、环境准备1、所有机器关闭防火墙2、所有机器关闭selinux3、所有机器关闭swap4、所有机器上添加主机名与ip的对应关系5、在所有主机上将桥接的ipv4流量传递到iptables的链三、为所有节点安装docker四、集群部署1、为所有节点修改仓库,安......
  • SQLPlus执行成功但数据没有更新的原因及解决办法
    在使用sqlplus执行SQL文件时,如果执行成功但数据没有更新,可能有以下几个原因导致:1.没有提交事务在Oracle数据库中,执行UPDATE,INSERT,DELETE等操作后,默认不会自动提交事务。如果没有显式地提交事务,修改的数据将不会永久保存。解决办法:确保在SQL文件或命令行......
  • oracle之spool详细使用总结
    一、通过spool命令,可以将select数据库的内容写到文件中,通过在sqlplus设置一些参数,使得按指定方式写到文件中(1)常规使用spool方法,将set的一些命令和spool,select等放入.sql脚本中,然后再sqlplus中运行该脚本。以下为logmnr.sql脚本,在sqlplus中执行@logmnr.sql就可以写入文件record......
  • 本地机Spool出某个表的字段名和数据到csv
    之前是通过sqlcl提供的SETSQLFORMATcsv导出数据到csv文件,这次是想尝试仅仅是使用SQLplus中的spool导出数据数据准备SQL>SELECT*FROMEMPORDERBYEMPNO;EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO_________________________......
  • 本地机spool导出多个查询结果到多个CSV文件
    问题需要在PL/SQLdeveloper上多次手动重复查询导出大量数据。解决使用sqlcl中提供的SETSQLFORMATcsv和SQLplus提供的Spool导出数据到csv文件。代码setserveroutputonsettermoutoffspoolD:\SpoolFile\tmp_script.sqlDECLARETYPETYPE_ARRAYISVARRAY(10)O......
  • [20240818]测试21c下sqlplus show recyclebin的小问题2.txt
    [20240818]测试21c下sqlplusshowrecyclebin的小问题2.txt--//以前测试过,链接[20210722]sqlplus下showrecycebin的小问题.txt--//注:recycebin拼写错误应该是recyclebin.--//这个问题当时也是浪费了大量实际,我记忆遇到问题时是上午,执行showrecyclebin;[注空格+;],linux......
  • [20240813]跟踪sqlplus登录执行了什么5(21c).txt
    [20240813]跟踪sqlplus登录执行了什么5(21c).txt--//跟踪看看sqlplus21c版本访问数据库21c时,在执行用户调用命令前执行一些什么sql语句。1.环境:[email protected]:1521/book>@prxx==============================PORT_STRING                  :x86_64/L......
  • ProcessPoolExecutor 的递归使用挂起
    问题我尝试将aProcessPoolExecutor与递归调用一起使用,但它不起作用。我在下面创建了一个最小的示例fromconcurrent.futuresimportProcessPoolExecutorfromtimeimportsleepexecutor=ProcessPoolExecutor()i=3deftest():globaliprint(......
  • oracle sqlplus 常用命令
    连接命令conn[ect]用法:conn用户名/密码@网络服务名[assysdba/sysoper]当用特权用户身份连接时,必须带上assysdba或是assysoperdisc[onnect]SQL>connscott/tigger已连接。SQL>disc从OracleDatabase10gEnterpriseEditionRelease10.2.0.1.0-Productio......
  • 湘潭大学软件工程专业oracle-sqlplus安装教程
    前言笔者在网上找了一些教程,但是没有装好,或者不知道啥原因,反正就是登不进去老师要求的系统,连接不上服务器,非常苦恼,请教了一下同学,终于弄好了,本文希望能帮助到和我一样有相同困扰的同学下载压缩包首先是下载安装包,按照我的理解,应该是下载下面这个压缩包就行了先打开老师......