Отправляет email-рассылки с помощью сервиса Sendsay

Открыто о СУБД Oracle на русском

  Все выпуски  

Открыто о СУБД Oracle на русском : login.sql, курсоры и экспорт/импорт больших объемов данных


Информационный Канал Subscribe.Ru

Выпуск 9

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   

Заранее благодарна за любую помощь.
Конни Халпин

и он ответил

См. решение в http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:553222846752 . V$OPEN_CURSOR представляет набор кешированных сервером курсоров. Запрос

          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

Полученный набор файлов импортируется следующим образом:

date > export.test
cat `echo $FN.* | sort` | gzip -d > $PIPE &
imp userid=sys file=$PIPE show=y full=y >>& export.test
date >> export.test
rm -f $PIPE

К сожалению, у меня под рукой сейчас нет сервера с такой большой базой на UNIX, так что попробовать вам придется самостоятельно. Думаю, поможет. Упаковывать, кстати, не обязательно - можно просто выполнить cat $PIPE.


В следующем выпуске

Опять точно не знаю. Возможно, как и было обещано, - Том Кайт о мутирующих таблицах. Следите за новостями на сайте проекта Open Oracle.

С наилучшими пожеланиями,

  В.К.



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное