Compressing sqlplus output using a pipe
Recently I am involved in a project which requires a lot of data to be extracted from Oracle. The size of the data was so huge that the filesystems filled up. Compressing the output (using tar j (bzip2) or z (gzip)) is an obvious solution, but this can only be done after the files are created. This is why I proposed compressing the output without ever existing in uncompressed form.
This solution works with a so called ‘named pipe’, which is something for which I know for sure it can be done on Linux and unix. A named pipe has the ability to let two processes transfer data between each other. This solution will look familiar to “older” Oracle DBA’s: this was how exports where compressed from the “original” export utility (exp).
I’ve created a small script which calls sqlplus embedded in it, and executes sqlplus commands using a “here command”:
mknod /tmp/oracle.pipe p sqlplus / as sysdba << _EOF set escape on host nohup gzip -c < /tmp/oracle.pipe > /tmp/out1.gz \& spool /tmp/oracle.pipe select * from dual; spool off host nohup gzip -c < /tmp/oracle.pipe > /tmp/out2.gz \& spool /tmp/oracle.pipe select * from dual; spool off _EOF rm /tmp/oracle.pipe
First a pipe is created (mknod filename p). As far as I know, this command is the same on Linux and the unixes. This pipe is removed as the last step of the script.
Inside the sqlplus script, I issue the gzip operating system command using the ‘host’ command. The line with the host command starts the gzip command with the pipe as input, and output to a .gz file in /tmp. The process is put in the background using ‘&’.
Next, the sqlplus spool command starts output to the pipe, and I execute a dummy sql (select * from dual).
With ‘spool off’, the output to the pipe is stopped. This makes the gzip process in the background to stop.
Because the gzip process is not compressing anymore to the first file, it can be used for a second time, and more times of course.
The result is two gzipped files:
zcat -v /tmp/out*.gz /tmp/out1.gz: SQL> select * from dual; D - X SQL> spool off 84.2% /tmp/out2.gz: SQL> select * from dual; D - X SQL> spool off 84.2%
Do you also use SET TRIMOUT ON TRIMSPOOL ON ? Useful with large linesize.
Pingback: Compressing sqlplus output using a pipe | Oracle, Mysql och andra funderingar