login.sql, курсоры и экспорт/импорт больших объемов данных
Уважаемые подписчики! Этот выпуск посвящен нескольким вопросам. Сначала - давно
обещанное: как дядя Том получает такие симпатичные приглашения в своих сеансах SQL*Plus. Затем один из довольно давних ответов Тома Кайта на сайте
asktom.oracle.com на вопрос о количестве открытых курсоров. И, наконец, мой первый "самостоятельный" ответ
на вопрос подписчиков о том, как переносить данные с одной версии на другую, если размер файла экспорта получается более 2 Гбайт.
Еще раз прошу прощения за большой перерыв между выпусками. Слишком много
интересных ответов публикует сейчас Том Кайт - читаю, и не остается времени на переводы...
Приглашения в SQL*Plus
Информативное и полезное приглашение в SQL*Plus, вместо стандартного "SQL> ",
можно получить, создав в каталоге сценариев файл login.sql (или
общесистемный - glogin.sql, в каталоге $ORACLE_HOME/sqlplus/admin)
с примерно таким текстом:
set termout off
define new_prompt='nolog'
column value new_value new_prompt
select username || '@' ||
substr(global_name,
1,
DECODE(instr(global_name, '.'), 0, LENGTH(global_name), instr(global_name,'.') - 1)
) || ':' || host_name
value
from global_name, gv$instance, user_users;
set sqlprompt "&new_prompt> "
set termout on
В результате, получим приглашение следующего вида:
SCOTT@TRAINING:CREATOR>
т.е. "пользователь@экземпляр:хост", что, согласитесь, приятно.
Дядю Тома спросили, откуда взялись открытые курсоры:
Том,
Объясни, пожалуйста, почему я вижу открытые курсоры в представлении
V$OPEN_CURSOR, хотя совершенно точно из закрыла. Действительно ли они
открыты? Я написала небольшой пример, иллюстрирующий мой вопрос:
SQL> start cursortest
SQL> select sql_text
2 from v$open_cursor where upper(sql_text) like ('%CURSORTEST%');
no rows selected
SQL> create or replace procedure testit
2 as
3 junk varchar2(1);
4 CURSOR dual_cursor
5 IS
6 SELECT dummy cursortest
7 FROM dual;
8 begin
9 open dual_cursor;
10 fetch dual_cursor into junk;
11 close dual_cursor;
12 end;
13 /
Procedure created.
SQL> --
SQL> begin testit;end;
2 /
PL/SQL procedure successfully completed.
SQL> --
SQL> select sql_text
2 from v$open_cursor where upper(sql_text) like ('%CURSORTEST%');
SQL_TEXT
------------------------------------------------------------
SELECT DUMMY CURSORTEST FROM DUAL
select a.value, b.name
from v$mystat a, v$statname b
where a.statistic# = b.statistic#
and a.statistic#= 3
дает фактическое количество действительно открытых курсоров
Обсуждение
Запрос всегда возвращает 1 открытый курсор. Комментарий читателя из США 25 июня 2002 года
Привет, Том!
Два вопроса:
1. Я выполняю твой запрос
select a.value, b.name
from v$mystat a, v$statname b
where a.statistic# = b.statistic#
and a.statistic#= 3;
и всегда получаю один и тот же результат для всех своих баз данных (их 9).
VALUE NAME
--------- ------------------------
1 opened cursors current
Я думаю, это неправильно.
2. Когда я выполняю
select count(*) from v$open_cursor;
я получаю в результате 1996. Но в файле параметров инициализации установлено:
Open cursors = 1000
Как это может быть? Ты ранее объяснил, что v$open_cursor - это не
открытые сейчас курсоры. Не должно ли быть возвращаемое из v$open_cursor
значение количества строк меньше, чем указано в файле параметров инициализации,
в моем случае - 1000, хотя это количество и не соответствует количеству действительно
открытых курсоров? В базе данных никаких проблем нет.
Большое спасибо.
Ответ дяди Тома
1) ну ... и почему вы так думаете? Постарайтесь объяснить, почему вы считаете это
неправильным (мне это неправильным не кажется)
SQL*Plus: Release 8.1.7.0.0 - Production on Tue Jun 25 15:35:20 2002
(c) Copyright 2000 Oracle Corporation. All rights reserved.
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.3.0 - Production
With the Partitioning option
JServer Release 8.1.7.3.0 - Production
ops$tkyte@ORA817DEV.US.ORACLE.COM> select a.value, b.name
2 from v$mystat a, v$statname b
3 where a.statistic# = b.statistic#
4 and a.statistic#= 3;
VALUE NAME
---------- ------------------------------
1 opened cursors current
2) select sid, count(*) from v$open_cursor group by sid
open_cursor хранится по сеансам. Вы выбираете по всем сеансам сразу.
Оригинал обсуждения этого вопроса можно найти
здесь.
Экспорт/импорт данных объемом более 2 Гбайт в ОС UNIX
Мне недавно прислали вопрос о том, как перенести базу данных с Oracle 7 на более
новую версию в ОС UnixWare, если файл экспорта - большой. Понятно, что можно экспортировать по схемам или по таблицам, но это решение - не универсальное.
Предлагаю возможный вариант решения, который я прочитал в книге Тома Кайта. Суть в том, чтобы использовать именованные каналы (named pipes) - специальные
файлы в UNIX System V, для которых, в частности, нет ограничения на предельный размер
2 Гбайта. Представленный ниже сценарий для командного интерпретатора ksh,
построенный по мотивам предложенного дядей Томом, разбивает файл экспорта на
блоки размером менее 2 Гбайт, которые затем еще и упаковываются с помощью
gzip:
#!/bin/ksh
FN=exp.`date +%j_%Y`.dmp # имя файла, включающее дату
MAXSIZE=500m # максимальный размер файла-блока
PIPE="/tmp/exp_orcl$$.dmp" # имя используемого именованного канала
EXPORT_WHAT="full=y compress=n" # опции экспорта
# переходим в каталог, где размещаются файлы экспорта
cd /home/oracle/exp
# удаляем файлы, оставшиеся после предыдущего экспорта
rm -f expbkup.log export.test exp.*.dmp.* $PIPE
# создаем именованный канал
mknod $PIPE p
# записываем дату и время начала экспортирования в журнал
date > expbkup.log
# главная часть: в фоновом режиме читаем из канала, пакуем и разбиваем на блоки
(gzip < $PIPE) | split -b $MAXSIZE - $FN. &
# теперь начинаем экспортировать - gzip уже ждет данных в именованном канале
exp userid=sys buffer=20000000 file=$PIPE $EXPORT_WHAT >>& expbkup.log
date >> expbkup.log
Полученный набор файлов импортируется следующим образом:
К сожалению, у меня под рукой сейчас нет сервера с такой большой базой на UNIX,
так что попробовать вам придется самостоятельно. Думаю, поможет. Упаковывать, кстати, не обязательно - можно просто выполнить cat $PIPE.
В следующем выпуске
Опять точно не знаю. Возможно, как и было обещано, - Том Кайт о мутирующих
таблицах. Следите за новостями на
сайте проекта Open Oracle.