<?xml version="1.0" ?><rss version="2.0"><channel><title></title><link>http://it-blogs.com/my-oracle</link><description>Записки для начинающих о СУБД Oracle</description> <language></language><pubDate>Tue, 06 Jan 2009 00:00:00 GMT</pubDate><lastBuildDate>Tue, 06 Jan 2009 00:00:00 GMT</lastBuildDate><item><title>recover database until time '2008-12-11:12:00:00' using backup controlfile;</title><link>http://it-blogs.com/my-oracle/post-334.aspx</link><description>&lt;p&gt;На небольшом сервере безвозвратно погиб винчестер.От базы остался холодный бекап и архивные файлы журнализации. Это не так уж плохо.&lt;/p&gt;&lt;p&gt;На другом сервере создали базу с таким же именем. Новую базу остановили. Далее файлы данных, файл инициализации, файл паролей подменили.Так как управляющие файлы были потеряны вместе с базой, пришлось использовать управляющие файлы из бекапа.&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
startup mount
recover database until time '2008-12-11:12:00:00' using backup controlfile;
alter database open resetlogs;
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;База открылась и все ок.&lt;/p&gt;
</description><pubDate>Tue, 16 Dec 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-334.aspx</guid><comments>http://it-blogs.com/my-oracle/post-334-comments.aspx</comments></item><item><title>В очередной раз об ORA-00600: internal error code, arguments: [12700].А также ORA-01498: block check failure</title><link>http://it-blogs.com/my-oracle/post-330.aspx</link><description>&lt;p&gt;Согласитесь, бывают радости в нашей жизни. На этот раз  - ORA-00600: internal error code, arguments: [12700], [58262], …….&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Предлагаю действовать так:
&lt;code&gt;
&lt;pre&gt;
SELECT owner, object_name, object_type, object_id, data_object_id
FROM dba_objects
WHERE data_object_id = 58262 – это число из сообщения об ошибке.
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;Таким образом, узнали с каким объектом проблемы. &lt;/p&gt;
&lt;p&gt;Если проблемы в индексе, то тут легко и просто. Удалили и пересоздали. &lt;/p&gt;
&lt;p&gt;Если это таблица, то есть несколько вариантов: &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
попробуем  сберечь информацию из  таблицы: 
&lt;code&gt;&lt;pre&gt;create table my_temp_table as select * from my_table_corrupt; &lt;/pre&gt;&lt;/code&gt;
Затем поломанную таблицу удаляем и создаем вновь из нашей временной.&lt;/li&gt;
&lt;li&gt;Поменяем только характеристики блоков данных (см &lt;a href=http://my-oracle.it-blogs.com/post-43.aspx&gt;здесь&lt;/a&gt;). Например, &lt;code&gt;&lt;pre&gt;
alter table my_table_corrupt  pctfree хх, pctused хх; 
alter table t move;&lt;/pre&gt;&lt;/code&gt;&lt;li&gt;
&lt;li&gt;можно попробовать перенести в другое табличное пространство 
&lt;code&gt;&lt;pre&gt;alter table t move tablespace tbs_new;&lt;/pre&gt;&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;

&lt;p&gt;Если из этих относительно хороших вариантов ничего не сработало, то пробуем дальше: &lt;/p&gt;
&lt;li&gt;
&lt;code&gt;&lt;pre&gt;
ANALYZE TABLE [название поломанного объекта] VALIDATE STRUCTURE;
ANALYZE TABLE [название поломанного объекта] VALIDATE STRUCTURE CASCADE.
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;И если мы получим здесь сообщение  - ORA-01498: block check failure - see trace file, то поступим так, как советует &lt;a href=http://dbaforums.org/oracle/index.php?showtopic=2194
&gt; здесь&lt;/a&gt;  Donald K. Burleson &lt;/p&gt;

&lt;/p&gt;А именно:
&lt;code&gt;
&lt;pre&gt;
DBMS_REPAIR.CHECK_OBJECT
=========================

CHECK_OBJECT procedure checks the specified object and populates the repair
table with information about corruption and repair directive(s).  Validation
consists of block checking all blocks in the object.  All blocks previously
marked corrupt will be skipped.

Note: In the initial release of DBMS_REPAIR the only repair is to mark the 
      block as software corrupt.

SQL&gt; @checkObject
SQL&gt; set serveroutput on
SQL&gt;
SQL&gt; declare
  2    rpr_count int;
  3  begin
  4    rpr_count := 0;
  5  dbms_repair.check_object (
  6    schema_name =&gt; 'SYSTEM',
  7    object_name =&gt; 'T1',
  8    repair_table_name =&gt; 'REPAIR_TABLE',
  9    corrupt_count =&gt; rpr_count);
10    dbms_output.put_line('repair count: ' || to_char(rpr_count));
11  end;
12  /
repair count: 1

PL/SQL procedure successfully completed.

SQL&gt; desc repair_table
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
OBJECT_ID                                NOT NULL NUMBER
TABLESPACE_ID                            NOT NULL NUMBER
RELATIVE_FILE_ID                          NOT NULL NUMBER
BLOCK_ID                                  NOT NULL NUMBER
CORRUPT_TYPE                              NOT NULL NUMBER
SCHEMA_NAME                              NOT NULL VARCHAR2(30)
OBJECT_NAME                              NOT NULL VARCHAR2(30)
BASEOBJECT_NAME                                    VARCHAR2(30)
PARTITION_NAME                                    VARCHAR2(30)
CORRUPT_DESCRIPTION                                VARCHAR2(2000)
REPAIR_DESCRIPTION                                VARCHAR2(200)
MARKED_CORRUPT                            NOT NULL VARCHAR2(10)
CHECK_TIMESTAMP                          NOT NULL DATE
FIX_TIMESTAMP                                      DATE
REFORMAT_TIMESTAMP                                DATE

SQL&gt; select object_name, block_id, corrupt_type, marked_corrupt,
  2  corrupt_description, repair_description
  3  from repair_table;

OBJECT_NAME                      BLOCK_ID CORRUPT_TYPE MARKED_COR
------------------------------ ---------- ------------ ----------
CORRUPT_DESCRIPTION
--------------------------------------------------------------------------------
REPAIR_DESCRIPTION
--------------------------------------------------------------------------------
T1                                      3            1 FALSE
kdbchk: row locked by non-existent transaction
        table=0  slot=0
        lockid=32  ktbbhitc=1
mark block software corrupt
&lt;/pre&gt;
&lt;/code&gt;
&lt;/li&gt;&lt;/ol&gt;







</description><pubDate>Tue, 25 Nov 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-330.aspx</guid><comments>http://it-blogs.com/my-oracle/post-330-comments.aspx</comments></item><item><title>ORA-1991 Database mounted in Exclusive Mode. Как побороть?</title><link>http://it-blogs.com/my-oracle/post-325.aspx</link><description>&lt;p&gt;ОС - WINXP SP2, Oracle 9i. Проблема: база монтируется,  но не открывается. В алерте имеем такое сообщение:&lt;/p&gt;&lt;code&gt;
&lt;pre&gt;
Database mounted in Exclusive Mode.
ORA-1991 signalled during: alter database mount exclusive...
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;Решить эту проблему помогло пересоздание парольного файла: &lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
orapwd file=C:\oracle\ora92\database\pwdmydb.ora password=sys entries=2
&lt;/pre&gt;
&lt;/code&gt;
</description><pubDate>Thu, 06 Nov 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-325.aspx</guid><comments>http://it-blogs.com/my-oracle/post-325-comments.aspx</comments></item><item><title>Oracle Listener crash in Windows или о том, что лучше выполнить одну команду, чем ОС переустанавливать.ORA-12520</title><link>http://it-blogs.com/my-oracle/post-324.aspx</link><description>&lt;p&gt;Дела давно прошедших дней, но сегодня вспомнилось. В одном нашем филиале с сервером начались какие-то непонятные вещи происходить: к серверу с утра подключается несколько (5-7) пользователей и работают в поте лица. Затем ни один пользователь не мог подключиться к базе. &lt;/p&gt;&lt;p&gt;ОС - WINXP SP2.Сообщения были по поводу проблем с Oracle Listener – сейчас не могу точно вспомнить, какое именно сообщение было об ошибке. Очень долго не могли разобраться, в чем дело. Во всех оракловский протоколах не могли найти никакого внятного объяснения такой ситуации. Пришлось переустанавливать операционку и оракл.  Как потом оказалось, что можно было обойтись всего лишь командой: &lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
netsh winsock reset catalog
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;Нашли мы это &lt;a href=http://www.pythian.com/blogs/319/oracle-listener-crash-in-windows &gt;здесь&lt;/a&gt;. На другом сервере в этом же филиале проверили.&lt;/a&gt;

&lt;p&gt; P.S. Сегодня запускали в промышленную эксплуатацию новый сервер на Microsoft Windows Server 2003 R2 Server 5.2 Service Pack 2 (32-bit). Через несколько часов работы, когда число юзеров начало немеряно расти, начали вылазить ошибки:
&lt;code&gt;
&lt;pre&gt;ORA-12520: TNS:listener could not find available handler for requested type of server
&lt;/pre&gt;
&lt;/code&gt;
воспользовались изложеным выше рецептом.Помогло.
&lt;p&gt;
</description><pubDate>Thu, 06 Nov 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-324.aspx</guid><comments>http://it-blogs.com/my-oracle/post-324-comments.aspx</comments></item><item><title>Cache buffer chains. Логическое чтение (LIO)  - это плохо?</title><link>http://it-blogs.com/my-oracle/post-319.aspx</link><description>&lt;p&gt;Большинство (или я ошибаюсь?) начинающих администраторов добиваются того, чтобы все (на сколько это вообще возможно) необходимые на протяжении дня данные для работы пользователей находились в буферном кэше, чтобы им приходилось, как можно меньше обращаться к диску за данными. То есть администраторы стремятся к увеличению логического( LIO ) чтения и, соответственно, уменьшению физического ( PIO ) чтения. Показателем этой деятельности есть buffer hit ratio, который стремится к 100%. При высоком значении этого показателя считается, что проблем с чтением данных  в базе нет. &lt;/p&gt;&lt;p&gt;Но бывают такие ситуации, что логическое чтение  - это зло. Это случается тогда, когда большое число логический чтений приводит к избыточному использованию CPU и защелок, к конкуренции за защелки. А это в свою очередь приводит к росту ожиданий серверных процессов и, значит, наш пользователь ощущает явное замедление работы своего приложения. И ему как-то все равно, что наш  buffer hit ratio равен 100%. Вся наша оптимизация оказалась безрезультативной. В тоже время стоит заметить, что конкуренция за защелки – явление весьма редкое, говорящее о неувязках при выполнении кода, либо о большом количестве процессов, в одно и тоже время выполняющих одинаковые действия.
О том насколько дорого логическое чтение, стоит ли бороться с физическим чтением, как уменьшить избыточное чтение прочитайте в замечательной &lt;a href=#millsap&gt;статье&lt;/a&gt; Why You Should Focus on LIOs Instead of PIOs .Cary Millsap/Hotsos Enterprises, Ltd.&lt;/p&gt;

&lt;p&gt;А дальше, немного в нашем контексте о &lt;strong&gt;Cache buffer chains&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Давайте вспомним о &lt;a href= http://my-oracle.it-blogs.com/post-41.aspx&gt;защелках&lt;/a&gt;, &lt;a href= http://my-oracle.it-blogs.com/post-260.aspx&gt;групповых защелках&lt;/a&gt;, &lt;a href= http://my-oracle.it-blogs.com/post-242.aspx&gt;буферном кэше&lt;/a&gt;, &lt;a href=http://my-oracle.it-blogs.com/post-247.aspx &gt;x$bh&lt;/a&gt;, &lt;a href= http://my-oracle.it-blogs.com/post-264.aspx&gt;цепочках блоков&lt;/a&gt; и все с этими понятиями связанное.&lt;/p&gt;

&lt;p&gt;Предположим, что наша база стала &#171;тормозить&#187;, с помощью нехитрых манипуляций (v$latchholder,v$latch_children (miss , sleeps), v$system_event, V$SESSION_WAIT, V$SESSION_WAIT_HISTORY) удалось выяснить – непомерно поднялся уровень CBC (Cache buffer chains). Что это означает?&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Дальше идут личные мои умозаключения, поэтому к ним прошу относиться очень осторожно, скептически. &lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Блоки в буферном кэше  организованы в цепочки, каждая цепочка имеет защелку. Если очень многим пользователям в одно и тоже время нужен один и тот же блок или блоки, которые находятся в одной цепочке, вот в этих случаях и наблюдается высокий уровень Cache buffer chains. То есть все наши пользователи борются за одну защелку, стерегущую цепочку блоков. Если буфер данных у Вас большой, то, возможно, в цепочке находится один блок. Значит, в этом случае все сражаются за один блок (но тогда растет еще и buffer busy waits). Возможен также вариант, что Вы очень значительно увеличили размер буферного кеша, а число защелок  _db_block_hash_latches осталось прежним. Поэтому  цепочки образовались достаточно длинными, следовательно, поиск по ним значительно увеличился по времени, а это привело к возникновению конкуренции.&lt;/p&gt; 

&lt;p&gt;Или, например, неэффективный план запроса спровоцировал излишнее  LIO:  из-за неподходящего индекса серверный процесс сначала читает блоки, а затем выясняется (после использования  фильтра), что эти блоки нам не нужны.  Хотя интенсивно потреблялись ресурсы: CPU, защелки.&lt;/p&gt;
&lt;p&gt;Наши дальнейшие действия должны быть направлены на уменьшение LIO. Для начала найдем объекты с горячими блоками: &lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
select bh.tch,bh.tim,object_.owner,object_.object_name,object_.object_type
from x$bh bh,v$latch_children l_c,dba_objects object_  
where owner not in ('SYS','SYSMAN') and l_c.name = 'cache buffers chains' and tch&lt;&gt;0 and bh.obj=object_.data_object_id and bh.hladdr = l_c.addr 
order by 1 desc
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;&lt;i&gt;Я не удивлюсь, если этим объектом окажется sys.dual! Классический пример: использование без особой надобности select sysdate from dual или select seq_my.nextval from dual.&lt;/i&gt;&lt;/p&gt; 
&lt;p&gt;Предположим, что нашли объекты с горячими блоками. С помощью v$sqlarea ищем запросы, вызвавшие работу с &#171;горячими&#187; блоками.Следующий запрос может быть Вам полезным в этом:&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
select tch,owner,object_name,sql_text from v$sqlarea s,
(select * from (select bh.tch,bh.tim,object_.owner,object_.object_name,object_.object_type
from x$bh bh,v$latch_children l_c,dba_objects object_  
where owner not in ('SYS','SYSMAN','SYSTEM') and l_c.name = 'cache buffers chains'and object_.object_type='TABLE'
 and tch&gt;10 and bh.obj=object_.data_object_id and bh.hladdr = l_c.addr order by tch desc) where rownum&lt;10) b
where instr(s.sql_text,object_name)&gt;0
&lt;/pre&gt;
&lt;/code&gt;

&lt;p&gt;А дальше возможны варианты:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; менять запросы.&lt;/li&gt;
&lt;li&gt; менять среду выполнения этих запросов.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;По поводу первого варианта: идти по этому пути самое правильное решение. Оптимизация запросов, приводящих к избыточному логическому чтению  - это и есть лечение болезни. Методы борьбы с этим явлением: проанализировать план выполнения запроса, а далее  -  переписать запрос, добавить/изменить индексы, настроить запросы с помощью hint , возможно стабилизировать план запроса. &lt;/p&gt;

&lt;p&gt;После проработки первого варианта или когда нет возможности корректировки запросов, можно приступить и ко второму варианту. &lt;/p&gt;
&lt;p&gt;В основном, нужно попробовать побороть неудачный расклад блоков по цепочкам (защелкам) -  добиваться такого размещения блоков в буферном кэше, чтобы очень часто востребованные блоки не попадали в одну цепочку, не висели на одной защелке.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Увеличивать число защелок? &lt;/li&gt;
&lt;li&gt;Увеличивать (уменьшить – поможет в незначительном числе случаев) размер буферного кэша? (Может дать увеличение числа хэш бакетов, а если увеличить до  более, чем  2048М, то и число защелок увеличится. Таким образом,  произойдет изменение перераспределения блоков в цепочках, цепочки уменьшатся.) &lt;/li&gt;
&lt;li&gt; Работать над параметрами db_block_hash_latches,db_block_hash_buckets?&lt;/li&gt;
&lt;li&gt;Если проблемы вызваны непомерной нагрузкой на индекс (index root), то значение _db_handles_cached с 5 поменять на 10?&lt;/li&gt;
&lt;li&gt;Изменять pctfree, inittrans в объектах с горячими блоками? (Уменьшит число записей в блоке) &lt;/li&gt;
&lt;li&gt;Пытаться использовать пулы KEEP/RECYCLE? &lt;/li&gt;
&lt;li&gt;Сделать перемещение таблицы /реблид индекса? (чтобы изменились адреса составляющих его блоков). &lt;/li&gt;
&lt;li&gt;alter session set events 'immediate trace name flush_cache'; ? (Недокументированное очищение кэша буферов. Будьте осторожны!!!!) &lt;/li&gt;
&lt;li&gt;Изменить PGA_AGGREGATE_TARGET? &lt;/li&gt;
&lt;li&gt;Установить space_management=auto ? &lt;/li&gt;
&lt;li&gt;Пробовать сегментировать, использовать блоки разного (как правило, меньшего) размера для горячих объектов? &lt;/li&gt;
&lt;li&gt;Попробовать использовать реверсивные индексы (reverse)? &lt;i&gt; В индексе с обращением ключа (reverse-key index) применяется обращение байтов индексируемой колонки числового типа. Этот прием позволяет получать равномерное распределение значений колонок среди блок-листов индекса со структурой B-Tree. Этот индекс хорошо подходит для индексирования колонок с последовательной нумерацией или нумерацией с заданным шагом. Заметим, что такие индексы применяются только для возвращения отдельных строк, и с их помощью нельзя выполнить поиск значений в некотором диапазоне. Вы не можете применить опцию REVERSE к битовым индексам и исключительно индексным таблицам.&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; Отвечать на все эти вопросы ВАМ. Будьте осторожны! Решение за Вами.&lt;/p&gt;
&lt;p&gt;Обязательно учтите &lt;a href=http://dbataj.blogspot.com/2007/10/oracle-latch.html&gt;мнение&lt;/a&gt; Тома Кайта:&lt;/p&gt;
&lt;p id=tom&gt;Latch: cache buffers chains&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Possible Causes&lt;p&gt;&lt;/i&gt;
&lt;ol&gt;
&lt;li&gt; Repeated access to a block (or small number of blocks), known as a hot block&lt;/li&gt;
&lt;li&gt; From AskTom:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Contention for these latches can be caused by: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; Very long buffer chains.&lt;/li&gt;
&lt;li&gt;very very heavy access to the same blocks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;i&gt;Possible Suggestion&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;From AskTom:&lt;/p&gt;
&lt;p&gt;When I see this, I try to see what SQL the waiters are trying to execute. Many times, 
what I find, is they are all running the same query for the same data (hot blocks). If 
you find such a query -- typically it indicates a query that might need to be tuned (to 
access less blocks hence avoiding the collisions). &lt;/p&gt;

&lt;p&gt;If it is long buffer chains, you can use multiple buffer pools to spread things out. You 
can use DB_BLOCK_LRU_LATCHES to increase the number of latches. You can use both 
together. &lt;/p&gt;

&lt;p&gt;The cache buffers chains latches are used to protect a buffer list in the buffer cache. These latches are used when searching for, adding, or removing a buffer from the buffer cache. Contention on this latch usually means that there is a block that is greatly contended for (known as a hot block). &lt;/p&gt;

&lt;p&gt;To identify the heavily accessed buffer chain, and hence the contended for block, look at latch statistics for the cache buffers chains latches using the view V$LATCH_CHILDREN. If there is a specific cache buffers chains child latch that has many more GETS, MISSES, and SLEEPS when compared with the other child latches, then this is the contended for child latch. &lt;/p&gt;

&lt;p&gt;This latch has a memory address, identified by the ADDR column. Use the value in the ADDR column joined with the X$BH table to identify the blocks protected by this latch. For example, given the address (V$LATCH_CHILDREN.ADDR) of a heavily contended latch, this queries the file and block numbers: &lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
SELECT OBJ data_object_id, FILE#, DBABLK,CLASS, STATE, TCH
FROM X$BH
WHERE HLADDR = 'address of latch'
ORDER BY TCH;
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;
X$BH.TCH is a touch count for the buffer. A high value for X$BH.TCH indicates a hot block. &lt;/p&gt;

&lt;p&gt;Many blocks are protected by each latch. One of these buffers will probably be the hot block. Any block with a high TCH value is a potential hot block. Perform this query a number of times, and identify the block that consistently appears in the output. After you have identified the hot block, query DBA_EXTENTS using the file number and block number, to identify the segment. &lt;/p&gt;

&lt;p&gt;After you have identified the hot block, you can identify the segment it belongs to with the following query: &lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
SELECT OBJECT_NAME, SUBOBJECT_NAME
FROM DBA_OBJECTS
WHERE DATA_OBJECT_ID = &amp;obj;
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;In the query, &amp;obj is the value of the OBJ column in the previous query on X$BH. &lt;/p&gt;


&lt;p id=millsap&gt;&lt;strong&gt;Why You Should Focus on LIOs Instead of PIOs .Cary Millsap/Hotsos Enterprises, Ltd. &lt;/strong&gt;Отличная статья (полностью ее найдёте в сети). В статье Вы найдете ответы на многие вопросы. Во сколько операции ввода-вывода на диск медленнее, чем  в памяти? Что такое &#171;логическое чтение&#187;? Насколько рентабельнее логическое чтение от физического? Стоит ли стремиться к тому, чтобы все необходимые блоки были в памяти? Как побороть излишнее LIO?&lt;/p&gt;
&lt;i&gt;&lt;strong&gt;Executive Summary &lt;/strong&gt;
&lt;p&gt;Many Oracle educators teach that reducing the number of PIO calls should be the top priority of SQL optimization. However, in our field work, we commonly eliminate 50% or more of the response time from slow Oracle applications, even after they’ve been tuned to execute no PIO calls. The secret is that Oracle LIO calls are more expensive than many people understand. In this paper, I explain the following research results: &lt;/p&gt;&lt;ul&gt;
&lt;li&gt;LIO processing is the number-one bottleneck for many business processes today, even on systems with “excellent” database buffer cache hit ratios.  &lt;li&gt;
&lt;li&gt;Excessive LIO call frequency is a major scalability barrier, because LIOs consume two of the system’s most expensive resources: CPU and latches.&lt;/li&gt;
&lt;li&gt;Even if you could have an infinite amount of memory and achieve a perfect 100% database buffer cache hit ratio, your system will be inefficient and unscalable if it executes more Oracle LIO calls than it needs to. &lt;/li&gt;
&lt;li&gt;The statistics that database administrators commonly track can lead you to believe that PIO processing is your bottleneck when it’s not. Do not increase disk or memory capacity until after you determine the impact of PIO latency upon your end-user response times.&lt;/li&gt;
&lt;li&gt;If you will focus on LIO reduction from the very beginning of a SQL optimization task instead of PIO reduction, then you will usually eliminate most of your PIOs by side-effect, because most of your PIOs are motivated by LIO calls in the first place.&lt;/li&gt;&lt;/ul&gt;
…

&lt;p&gt;&lt;strong&gt;How to Eliminate LIOs &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When either CPU service or waits for “latch free” is a big part of your users’ response times, then you probably have an LIO problem. If you do, then the most economically efficient way to solve the problem is probably to optimize the SQL that causes too many LIOs. A high-LIO SQL statement running in one program at a time is a problem for one user who is waiting for the program’s output. It’s possibly a problem for other users as well, if they are competing for scarce CPU and latch resources with the high-LIO statement. A high-LIO statement running in dozens of concurrent programs is a catastrophic problem for everyone. In both problems, it is difficult to make any real progress by masking the issue by manipulating memory or disks. The permanent long-term solution is to eliminate unnecessary LIOs.&lt;/p&gt;
 
&lt;p&gt;It’s not so hard to do. Step one: focus your attention upon LIO reduction, not PIO reduction. Stop measuring performance by watching your database buffer cache hit ratio, especially for individual SQL statements. When you look at tkprof output, pay attention to the query and current columns. When you look at v$sql, pay attention to the buffer_gets column. Don’t stop optimizing if a query consumes more than 100 LIOs per row returned,even if you’ve figured out how to reduce the PIO count for the query to zero. Lookups and simple joins should require fewer than 10 LIOs per row returned.&lt;/p&gt;
&lt;p&gt;By eliminating LIOs first (before you try to reduce the PIO count), you will save time and money, because you’ll be reducing the fundamental unit of work in Oracle from which most resource consumption derives. Remember, a program can have a PIO count of zero and still run for hours. But a program with a low LIO count will consume only a small amount of CPU service, a small number of latch acquisitions, and of course a necessarily small number of 
PIOs as well, because a small number of LIOs will nearly always motivate only a small number of PIOs. Only after you have optimized the LIO requirement of an Oracle program should you consider a memory of disk upgrade. The query optimization software in the Oracle kernel gets smarter with every release (for an interesting article on this subject, see [Gorman 2001]). But still, the Oracle performance analyst will encounter systems in which the number one cause of performance trouble is poor query optimization. Some of the more common mistakes that we 
see in the field include:   &lt;/p&gt;

&lt;p&gt;Executing unnecessary business functions. There is no more efficient or effective system optimization technique than to determine that a business is expending scarce system resources to produce output that either nobody looks at, or output whose business function can be suitably replaced by less expensive output. Performance analysts who isolate themselves from the functional requirements of a business application also isolate themselves from opportunities to eliminate unnecessary business functions. To optimize workload, you must understand the business of that workload.   &lt;/p&gt;
&lt;p&gt;Carrying massive amounts of row source data through several stages of a complicated execution plan, only to filter out most of the rows in a late stage of the plan. Use hints and stored outlines if you must, but force Oracle to filter data as early in an execution plan as you can.   The idea that all full-table scans are bad. Full-table scans are efficient in their place; use them when they are more efficient than index-driven plans. If you are in doubt about whether a full-table scan is efficient, test it. &lt;/p&gt;
&lt;p&gt;The idea that all nested loops plans are good. Nested loops execution plans are notorious for driving “excellent” database buffer cache hit ratios, because they tend to revisit the same Oracle blocks over and over again. Replacing nested loops plans with other joins (full-table scans driving either hash joins or sort-merge joins, for example) can sometimes result in spectacular performance improvements.   &lt;/p&gt;
&lt;p&gt;Failure to use array processing. Fetching data one row at a time also drives “excellent” database buffer cache hit ratios, because they also tend to cause Oracle to revisit the same blocks over and over again. Using Oracle array operations will reduce not only LIO frequencies, but often enormous amounts of network traffic as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;In system optimization and capacity planning exercises since 1990, several of my colleagues and I have created reliable SQL performance forecasts by using the assumption that a LIO+PIO operation costs about 100 times as much as a bare LIO. However, many people believe that the relative cost is 10,000-to-1. Fortunately, the average latencies of LIO+PIO and bare LIO for an Oracle session are simple to compute. In this paper, I have explained how to use easily obtainable operational data to determine for certain which ratio is closer to the truth. In 71 trace files uploaded to www.hotsos.com, the relative performance difference is only a factor of 37. The average LIO latency in our test data is about 50 microseconds; that is, Oracle LIOs execute at a typical pace of only about 20,000 per second. The average PIO latency in our data is about 2 milliseconds, which is faster than typical disk hardware latencies because of the effects of various I/O subsystem memory buffers. &lt;/p&gt;
&lt;p&gt;The “myth of 10,000” is more than just an inconsequential technical detail. The myth is dangerous because it motivates performance analysts to make a dreadful mistake: to assume that you can optimize a system by eliminating PIOs. On the contrary, the most important optimization goal for the Oracle performance analyst is to reduce LIO counts. Even if you could install 1-millisecond disks and an infinite amount of memory for your database buffer cache, your Oracle system performance would be constrained as it probably is now, by the CPU capacity required to process all of your application’s LIO calls. &lt;/p&gt;
&lt;p&gt;In the field, Oracle performance analysts who focus on LIO reduction routinely eliminate 50% or more of the CPU and elapsed time required to perform key business functions. Not only does LIO call reduction yield a beneficial impact upon CPU consumption, but it eliminates potentially large segments of user response time wasted on “latch free” events. Even systems with no PIO calls can waste tens of hours of CPU time per day if they execute too many LIO calls. Ironically, systems with extremely high (99%+) database buffer cache hit ratios are especially good can-didates for LIO call reduction
</description><pubDate>Tue, 28 Oct 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-319.aspx</guid><comments>http://it-blogs.com/my-oracle/post-319-comments.aspx</comments></item><item><title>Cursor_sharing='FORCE'  - удивительные последствия: rows will be truncated</title><link>http://it-blogs.com/my-oracle/post-312.aspx</link><description>&lt;p&gt;Сегодня мне нужно было выгрузить информацию в спул –файл. Данные форматировались с помощью функции rpad. Получили ошибки - &#171;rows will be truncated&#187;. В чем же дело?&lt;/p&gt;&lt;p&gt;Результат разборок с этой проблемой -  виноват параметр инициализации Cursor_sharing, вернее, его значение 'FORCE' .  Может кто-то знает почему?
А я Вам предлагаю самим попробовать ( для чистоты эксперимента лучше после изменения значения параметра перегружать экземпляр ) :&lt;/p&gt;
 &lt;code&gt;
&lt;pre&gt;
&lt;i&gt;conn sys/пароль@строка_коннекта as sysdba
alter system set cursor_sharing=’FORCE’;
set linesize 90
select  ‘1111111111’,’1111111111’ from dual;
select  rpad( ‘1111111111’,10) test1,rpad(’2222222’,10) test2,rpad(’333333’,10) test3 from dual;
&lt;/i&gt;


SQL&gt; conn sys/ пароль@строка_коннекта as sysdba
Connected.
SQL&gt;&lt;strong&gt; alter system set cursor_sharing='FORCE';&lt;/strong&gt;

System altered.

SQL&gt; set linesize 90
SQL&gt; select  '1111111111','1111111111' from dual;

'1111111111'                     '1111111111'
-------------------------------- --------------------------------
1111111111                       1111111111

SQL&gt; select  rpad( '1111111111',10) test1,rpad('2222222',10) test2,rpad('333333',10) test3 from dual;

TEST1
------------------------------------------------------------------------------------------
TEST2
------------------------------------------------------------------------------------------
TEST3
------------------------------------------------------------------------------------------
1111111111
2222222
333333

&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt; Получается, что если к столбцу применяется rpad, то значение столбца выводится с новой строки.
&lt;code&gt;
&lt;pre&gt;
&lt;i&gt;
conn sys/ пароль@строка_коннекта as sysdba
&lt;strong&gt;alter system set cursor_sharing=’FORCE’;&lt;/strong&gt;
set linesize 90
&lt;strong&gt;SET WRAP OFF&lt;/strong&gt;
&lt;strong&gt;Set TrimSpool ON&lt;/strong&gt;
select  ‘1111111111’,’1111111111’ from dual;
select  rpad( ‘1111111111’,10) test1,rpad(’2222222’,10) test2,rpad(’333333’,10) test3 from dual;
&lt;/i&gt;
SQL&gt; conn sys/ пароль@строка_коннекта as sysdba
Connected.
SQL&gt; alter system set cursor_sharing='FORCE';

System altered.

SQL&gt; set linesize 90
SQL&gt; SET WRAP OFF
SQL&gt; Set TrimSpool ON
SQL&gt; select  '1111111111','1111111111' from dual;

'1111111111'                     '1111111111'
-------------------------------- --------------------------------
1111111111                       1111111111

SQL&gt; select  rpad( '1111111111',10) test1,rpad('2222222',10) test2,rpad('333333',10) test3 from dual;
rows will be truncated

rows will be truncated


TEST1
------------------------------------------------------------------------------------------
1111111111
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;А если использовать WRAP OFF, то, вообще, выводится в спул только первый столбец и сообщение &quot;rows will be truncated&quot;.Изменим параметр: cursor_sharing=’EXACT’&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;&lt;i&gt;
conn sys/ пароль@строка_коннекта as sysdba
&lt;strong&gt;alter system set cursor_sharing=’EXACT’;&lt;/strong&gt;
set linesize 90
SET WRAP OFF
Set TrimSpool on
select  ‘1111111111’,’1111111111’ from dual;
select  rpad( ‘1111111111’,10) test1,rpad(’2222222’,10) test2,rpad(’333333’,10) test3 from dual;
&lt;/i&gt;
SQL&gt; conn sys/ пароль@строка_коннекта as sysdba
Connected.
SQL&gt; set linesize 90
SQL&gt; SET WRAP OFF
SQL&gt; Set TrimSpool on
SQL&gt; select  '1111111111','1111111111' from dual;

'111111111 '111111111
---------- ----------
1111111111 1111111111

SQL&gt; select  rpad( '1111111111',10) test1,rpad('2222222',10) test2,rpad('333333',10) test3 from dual;

TEST1      TEST2      TEST3
---------- ---------- ----------
1111111111 2222222    333333
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;При таком значении параметра cursor_sharing в спул выводится все корректно. Чудеса!&lt;/p&gt;
</description><pubDate>Mon, 06 Oct 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-312.aspx</guid><comments>http://it-blogs.com/my-oracle/post-312-comments.aspx</comments></item><item><title>Убить неактивные сессии! Параметр resource_limit.</title><link>http://it-blogs.com/my-oracle/post-285.aspx</link><description>&lt;p&gt;На одном подшефном  сервере работаю нерадивые пользователи: подключаются к серверу с утреца и идут курить на несколько часиков.  Научить их жизни не получается. Пришлось побороть их  следующим образом:&lt;/p&gt;&lt;code&gt;
&lt;pre&gt;
Alter system set resource_limit=true scope=both;

ALTER PROFILE &quot;DEFAULT&quot; LIMIT IDLE_TIME 15;
&lt;/pre&gt;
&lt;/code&gt;

&lt;p&gt;Всем пользователям назначили этот профиль.Таким образом ограничили &#171;курение&#187; 15 минутами. Злостные &#171;курильщики&#187; получают сообщение: ORA-02396: exceeded maximum idle time, please connect again&lt;/p&gt;
</description><pubDate>Fri, 11 Jul 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-285.aspx</guid><comments>http://it-blogs.com/my-oracle/post-285-comments.aspx</comments></item><item><title>ARCHIVELOG  или NOARCHIVELOG? Вот в чем вопрос?</title><link>http://it-blogs.com/my-oracle/post-282.aspx</link><description>&lt;p&gt;Самая ПЕРВАЯ  обязанность администратора – поддержка базы данных в рабочем состоянии. Даже если в системе происходит сбой (пропало питание, носитель пришел в непригодность и т.д.), администратор должен в максимально сжатые сроки поднять базу без потерь данных.  Значит, к сбоям администратор должен готовиться загодя. &lt;/p&gt;&lt;p&gt;Для начала администратор должен решить вопрос: &lt;a href= http://my-oracle.it-blogs.com/post-279.aspx&gt; ARCHIVELOG &lt;/a&gt; или &lt;a href= http://my-oracle.it-blogs.com/post-278.aspx&gt;NOARCHIVELOG&lt;/a&gt;? Исходя из ответа на него, и будет строиться стратегия резервирования. &lt;/p&gt;
&lt;p&gt;Выполните следующий запрос, чтобы знать режим работы ваше базы:&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
select log_mode from v$database;
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;При эксплуатации базы данных в режиме NOARCHIVELOG  формируются данные для восстановления лишь при  сбое экземпляра (instance recovery) – оперативные журналы повторного выполнения. Такая ситуация возникает, например , при отключении питания.&lt;/p&gt;

&lt;p&gt;При эксплуатации базы данных в режиме ARCHIVELOG  формируются данные для восстановления как при сбое экземпляра (instance recovery), так и при сбое носителя (media recovery) – оперативные и архивные журналы повторного выполнения.&lt;/p&gt;

&lt;p&gt;Каждый способ имеет преимущества и недостатки (см. таблицу). Поэтому администратору приходится самому решать проблему выбора. &lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;ARCHIVELOG   &lt;/td&gt;&lt;td&gt;NOARCHIVELOG&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Дополнительная нагрузка на сервер&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Восстановление без потерь данных&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Горячее резервное копирование&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Возможность создания &#171;горячей&#187; резервной базы данных (standby)&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Восстановление на указанный момент времени&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Instance recovery&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Media recovery&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Необходимость наличия носителей больших объемов&lt;/td&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;

&lt;p&gt;Главное:&lt;/p&gt;
&lt;p&gt;В режиме noarchivelog восстановление возможно только на момент создания последнего бэкапа.&lt;/p&gt;
&lt;p&gt;В режиме archivelog восстановление возможно до момента времени последней фиксации транзакции.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Важно:&lt;/strong&gt; если не делать бэкапы, то режим archivelog вообще не имеет смысла, так как восстановление происходить путем применения архивных журналов к последнему корректному бэкапу(накат вперед).&lt;/p&gt;
&lt;p&gt;Мое решение: тестовая база – NOARCHIVELOG; промышленная – ARCHIVELOG. И будь почти спокоен!
&lt;/p&gt;</description><pubDate>Mon, 07 Jul 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-282.aspx</guid><comments>http://it-blogs.com/my-oracle/post-282-comments.aspx</comments></item><item><title>DROP USER . ORA-00604: error occurred at recursive SQL level 1 ORA-00942: table or view does not exist</title><link>http://it-blogs.com/my-oracle/post-261.aspx</link><description>&lt;p&gt;На одном из  подопечных  серверов нужно было удалить пользователя. Но на команду DROP USER my_user cascade было получено сообщение: &#171;ORA-00604: error occurred at recursive SQL level 1 ORA-00942: table or view does not exist&#187;.&lt;/p&gt;&lt;p&gt;Ничего лучшего не могли придумать, как только получить файл трассировки:&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
alter session set sql_trace=true;

DROP USER my_user cascade;
&lt;/pre&gt;
&lt;/code&gt;
&lt;p&gt;Снова получаем ошибку:
ORA-00604: error occurred at recursive SQL level 1 ORA-00942: table or view does not exist&lt;/p&gt;

&lt;p&gt;Но теперь имеем файл трассировки. В нем находим :&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
PARSE ERROR #15:len=78 dep=1 uid=0 oct=7 lid=0 tim=677704568731 err=942
delete from system.aq$_internet_agent_privs WHERE db_username = NLS_UPPER(:1)
EXEC #1:c=1203125,e=19331497,p=60,cr=902,cu=0,mis=0,r=0,dep=0,og=4,tim=677704635416
ERROR #1:err=604 tim=67771625
STAT #2 id=1 cnt=0 pid=0 pos=1 obj=3475 op='TABLE ACCESS FULL OBJ#(3475) '
&lt;/pre&gt;
&lt;/code&gt;

&lt;p&gt;Как оказалось,  таблички system.aq$_internet_agent_privs как раз и не было в этой базе данных.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Вывод:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Файл трассировки - это хорошо!&lt;/p&gt;</description><pubDate>Tue, 17 Jun 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-261.aspx</guid><comments>http://it-blogs.com/my-oracle/post-261-comments.aspx</comments></item><item><title>ORA-01578: ORACLE data block corrupted (file # string, block # string)</title><link>http://it-blogs.com/my-oracle/post-216.aspx</link><description>&lt;p&gt; На сервере oracle 9i версии 9.2.0.6.0 получили в алерте такое сообщение. Нам повезло- отделались малой кровью. Выполнили запрос:&lt;/p&gt;
&lt;code&gt;
&lt;pre&gt;
SELECT SEGMENT_TYPE,OWNER||'.'||SEGMENT_NAME

FROM DBA_EXTENTS 

WHERE FILE_ID = [номер file#] AND [номер block#] BETWEEN BLOCK_ID

AND BLOCK_ID+BLOCKS -1;
&lt;/pre&gt;
&lt;/code&gt;

Пострадал индекс. Удалили его и создали заново. Все завершилось успешно. </description><pubDate>Wed, 02 Apr 2008 00:00:00 GMT</pubDate><guid>http://it-blogs.com/my-oracle/post-216.aspx</guid><comments>http://it-blogs.com/my-oracle/post-216-comments.aspx</comments></item></channel></rss>