20 мая 2008 г.

Подключение к iSQL*Plus как SYSDBA или SYSOPER в Oracle 9i

Как sysdba или sysoper можно подключиться через iSQL*Plus в Oracle 9i можно по другому url:
http://hostname:7776/isqlplusdba

По умолчанию на /isqlplusdba включена базовая аутентификация и при перед открытием страницы, запросит имя пользователя и пароль.
Чтоб добавить пользователя для базовой аутентификации в Oracle 9i используется стандартная утилита Apache - htpasswd (в Oracle10g - джава утилита jazn, о ней можно почитать здесь):

oracle@myhost $ cd $ORACLE_HOME/Apache/Apache/bin
oracle@myhost $ ./htpasswd -b $ORACLE_HOME/sqlplus/admin/iplusdba.pw username password
Тепер, при открытие в http://hostname:7776/isqlplusdba можно ввести логин (username) и пароль пользователя (password) и подключиться к базе данных как SYSDBA и SYSOPER.

Или же можно отключить базовую аутентификация в /isqlplusdba закомментировав 4 строчки в ORACLE_HOME/sqlplus/admin/isqlplus.conf:
<Location /isqlplusdba>
SetHandler fastcgi-script
Order deny,allow
#AuthType Basic
#AuthName 'iSQL*Plus DBA'
#AuthUserFile /u01/app/oracle/product/9.2.0.8.0/sqlplus/admin/iplusdba.pw
#Require valid-user
</Location>

Не забудьте перегрузить Apache после изменений:
oracle@hostname $ cd $ORACLE_HOME/Apache/Apache/bin
oracle@hostname $ ./apachectl stop
./apachectl stop: httpd stopped
oracle@hostname $ ./apachectl start
./apachectl start: httpd started
Теперь при открытии http://hostname:7776/isqlplusdba не будет запрашивать логин и пароль.

15 мая 2008 г.

DBMS_STATS или ANALYZE? (3)

Это продолжение темы "DBMS_STATS или ANALYZE?" Здесь я написала о том, почему Oracle рекомендует использовать dbms_stats вместо analyze, а здесь - о том, отличаются ли статистические данные собраные с помощью dbms_stats от данных, собранных с помощью analyze и если отличаются, то чем именно и кому из них верить.

Очередной вопрос: как определить, каким образом была собрана статистика? Пакетом dbms_stats или оператором analyze?

Столбец global_stats в представлениях dba_tables, dba_indexes, dba_tab_cols, dba_tab_columns, dba_tab_col_statistics определяет собрана глобальная статистика или нет.

Так как analyze не умеет собирать глобальную статистику (ее может собрать только dbms_stats), то можем сделать вывод, что если глобальная статистика собрана, то статистика была собрана с помощью dbms_stats, а если нет глобальной статистики - то статистика была собрана оператором analyze:

YES - собрана глобальная статистика, то есть статистика собрана с помощью dbms_stats
NO - статистика собрана с помощью аггрегирования статистики низлежащих партиций, субпартиций, то есть с помощью analyze

Вырезка из документации:

GLOBAL_STATS
For partitioned tables, indicates whether statistics were
collected for the table as a whole (YES) or were estimated from statistics on
underlying partitions and subpartitions (NO)
Подробней можно прочитать об этом на металинке Note: 236935.1.
SQL> analyze table emp compute statistics;
Table analyzed.

SQL> select table_name, partitioned, global_stats
2 from user_tables where table_name='EMP';
TABLE_NAME PARTITIONED GLOBAL_STATS
------------ ----------- ------------
EMP NO NO

SQL> exec dbms_stats.gather_table_stats(user, 'EMP', cascade=>true);
PL/SQL procedure successfully completed.

SQL> select table_name, partitioned, global_stats
2 from user_tables where table_name='EMP';
TABLE_NAME PARTITIONED GLOBAL_STATS
------------ ----------- ------------
EMP NO YES

DBMS_STATS или ANALYZE? (1)

И dbms_stats и analyze используются для сбора статистики, которая используются стоимостным оптимизатором (Cost-Based Optimizer) для построения планов выполнения. То есть их правильное использование оказывает очень большое влияние на производительность всей системы.
Но почему Oracle "настоятельно" рекомендует использовать пакет dbms_stats для сбора статистики вместо analyze?
Из документации Oracle:

"Oracle Corporation strongly recommends that you use the DBMS_STATS package rather than ANALYZE to collect optimizer statistics."
Так что же может dbms_stats, чего не может analyze:
- с помощью dbms_stats можно собирать системную статистику (analyze нет такой возможности)
(о системной статистике напишу отдельно, но "Oracle Corporation highly recommends that you gather system statistics.")
- с помощью dbms_stats можно собирать статистику в удаленной базе данных (через дблинк)
SQL> exec dbms_stats.gather_table_stats@remotedb('REMOTEUSER','REMOTETABLE',cascade=>true);
и еще:
"That package lets you collect statistics in parallel, collect global statistics for partitioned objects, and fine tune your statistics collection in other ways."
Кажется, что если Oracle рекомендует использовать dbms_stats для сбора статистики и имеет ряд преимуществ перед analyze, то зачем нужен analyze?

Здесь Том Кайт объясняет, что dbms_stats собирает статику только для оптимизатора (CBO).
А такие статистические данные, как количество перенесенных строк (chained rows), средний объем свободного места в блоке, количество неиспользованных блоков можно собрать только с помощью analyze.
Из документации Oracle :
"... you must use the ANALYZE statement rather than DBMS_STATS for statistics collection not related to the cost-based optimizer, such as:
To use the VALIDATE or LIST CHAINED ROWS clauses
To collect information on freelist blocks"
Если dbms_stats и analyze собирают одну и ту же статистику по объектам, то они собирают одинаковые данные?
Или эти данные отличаются?
Если отличаются, то кому из них верить?


Updated: 20 февраля, 2009
Попытаюсь ответить на эти вопросы: Некоторые столбцы/компоненты статистики, собранные dbms_stats-ом отличаются от той, которые собраны командой analyze.
Например кол-во строк (num_rows), высота индекса (blevel), конечно же НЕ отличаются.
А такие столбцы как avg_row_len, avg_col_len - отличаются: dbms_stat добавляет 1 байт за хранение длины столбца, а analyze - не учитывает байт, в котором хранится длина столбца. Вот что пишет Джонатан Льюис об этом:
As a general rule, the figures for bytes in execution plans are derived from the avg_col_len columns of user_tab_columns. The deprecated analyze command excludes the length byte(s) for the column, but the call to dbms_stats.gather_table_stats includes the length byte(s). Since the choice of build table in a hash join is affected by the size of the data sets involved, a switch from analyze to dbms_stats could (in principle) change the order of a hash join, or even cause the optimizer to use a different join mechanism.
В-общем, он говорит, что, в принципе, из-за этой разницы в статистике, оптимизатор может изменить план выполнения в зависимости от метода сбора статистики, так как статистика немного отличается.
Ответ на последний вопрос "Если отличаются, то кому из них верить?": Думаю достаточно иметь ввиду, что некоторые столбцы/компоненты статистики собранные dbms_stats-ом отличаются от той, которая собрана командой analyze. И, к тому же статистика нужна только оптимизатору, а вам она не нужна. Поэтому долго не думайте и собирайте статистику dbms_stats-ом, а чтоб увеличить скорость сбора, распараллельте или же собирайте с небольшим estimate-ом.

Здесь я написала о том, как определить, каким образом была собрана статистика: пакетом dbms_stats или оператором analyze.

14 мая 2008 г.

Где именно находится оптимизатор
в архитектуре Oracle RDBMS?

Oracle DBA обычно не интересуются вопросом "Где именно находится оптимизатор в архитектуре Oracle RDBMS?" Некоторые из моих знакомые ДБА отнесли его к категории вопросов о смысле жизни.
Но самый популярный ответ был "в ядре Oracle".

В книге Oracle Database 10g Insider Solutions пишут тоже самое:

"The Cost Based Optimizer is at the heart of the Oracle kernel and plays a large part in the efficient execution of SQL statements in Oracle Database 10g."
Но где именно находится это ядро (kernel)? Это обычный процесс? Если да, то можно ли его увидеть в юниксе в списке процессов командой "ps"?

Отрывок из книги Тома Кайта "Oracle для профессионалов: Архитектура и основные особенности":
"При получении запроса SELECT * FROM EMP именно выделенный/разделяемый сервер Oracle будет разбирать его и помещать в разделяемый пул (или находить соответствующий запрос в разделяемом пуле). Именно этот процесс создает план выполнения запроса. Этот процесс реализует план запроса, находя необходимые данные в буферном кеше или считывая данные в буферный кеш с диска. Такие серверные процессы можно назвать "рабочими лашадками" СУБД. Часто именно они потребляют основную часть процессорного времени в системе, поскольку выполняют сортировку, суммирование, соединения - в общем, почти все."
То есть функции оптимизатора выполняются серверными процессами и их мы можем увидеть в списке процессов:
oracle@myhost$ ps -ef  grep ora  grep LOCAL  more
oracle 22790 1 0 09:13:33 ? 0:03 oracleTESTDB (LOCAL=NO)
oracle 4426 1 0 11:20:58 ? 0:02 oracleTESTDB (LOCAL=NO)
oracle 29167 1 0 11:11:32 ? 0:01 oracleTESTDB (LOCAL=NO)
oracle 12778 1 0 09:53:02 ? 0:03 oracleTESTDB (LOCAL=NO)
oracle 14349 1 0 12:26:34 ? 0:01 oracleTESTDB (LOCAL=NO)
oracle 21141 1 0 11:47:35 ? 0:01 oracleTESTDB (LOCAL=NO)
oracle 11220 1 0 09:49:18 ? 0:06 oracleTESTDB (LOCAL=NO)
oracle 16823 1 0 11:40:49 ? 0:01 oracleTESTDB (LOCAL=NO)
oracle 26760 1 0 11:57:20 ? 0:01 oracleTESTDB (LOCAL=NO)
oracle 20814 1 0 09:09:42 ? 0:01 oracleTESTDB (LOCAL=NO)
oracle 17374 1 0 12:32:28 ? 0:02 oracleTESTDB (LOCAL=NO)
oracle 8911 1 0 22:14:38 ? 0:00 oracleTESTDB (LOCAL=NO)
Если серверные процессы разбирают все запросы (выполняют все функции оптимизатора), значит ли это, что:

Код самого оптимизатора находится в каждом серверном процессе?
Или серверные процессы всего лишь вызывают эти функции из ярда Oracle?
Или ядро Oracle - это и есть серверные процессы?


Для меня этот вопрос все еще остается открытым, если у кого-то есть идеи, буду рада их услышать.

Добавлено 16 мая, 2008:
Это ответ Джонатана Льюиса на этот вопрос (публикую с его разрешения):
There is one main executable for the database in Oracle distribution, and that is called oracle (on Unix systems, but oracle.exe on Windows).
This is the program that becomes pmon, smon, dbwr, s000, and all the other background processes when the instance starts up. The bits of code run from that executable vary across the different roles played in the instance.

As such, the optimiser is just part of the code that is called only by a program which is taking on the role of a dedicated server (oracle_{SID}_nnn in unix variants) or a shared server (oracle_{SID}_Snnn).

When people talk about the 'Oracle kernel' it's actually a very informal and inaccurate expression - they are trying to give a vague impression of the most commonly used part of the code with an emphasis, perhaps, on the code segments that do a lot of synchronised work in the shared memory area. But there is no specific process that you can see that is "the" kernel.

Regards

Jonathan Lewis
http://jonathanlewis.wordpress.com

Author: Cost Based Oracle: Fundamentals
http://www.jlcomp.demon.co.uk/cbo_book/ind_book.html

The Co-operative Oracle Users' FAQ
http://www.jlcomp.demon.co.uk/faq/ind_faq.html
Перевод:

Есть один основной бинарник в дистрибутиве Oracle, который так и называется oracle (в юникс системах, и oracle.exe в Windows). Когда стартуется инстанс, эта программа превращается в фоновые процессы pmon, smon, dbwr, s000 и тд.
В зависимости от роли, которую он выполняет в составе инстанса, выполняются отдельные биты кода этого бинарника.

Оптимизатор - это всего лишь кусочек кода, который вызывается программой, выполняющей роль выделенного сервера (oracle_{SID}_nnn в юниксе) или разделяемого сервера (oracle_{SID}_Snnn).

Когда люди говорят о "ядре Oracle", они на самом деле используют неформальное и не совсем точное выражение - они стараются дать смутное ощущение о часто используемой части кода, возможно имея ввиду сегменты кода, которые выполняют кучу синхронизированных операций в разделяемой памяти.
Но на самом деле нет отдельного процесса, которого можно увидеть и который являлся бы "ядром".

Прикольно, значит код самого оптимизатора находится в каждом серверном процессе.
Спасибо всем, кто участвовал в процессе выяснения местонахождения оптимизатора в архитектуре Oracle. Отдельное спасибо Джонатану Льюису, кстати всем, кто занимается тюнингом, рекомендую почитать его книжку Основы Стоимостной Оптимизации (Cost-Based Oracle Fundamentals).

6 мая 2008 г.

Одноблочное и многоблочное чтения
(single-block & multi-block read)

Если при полном просмотре таблицы (full table scan) выполняется многоблочное чтение, то это положительно влияет на производительность. То есть, за одну операцию ввода/вывода читается несколько блоков, и вся таблица будет прочитана с файла в буферный кэш за минимальное количество операций ввода/вывода.

Кол-во блоков, которое будет прочитано из файла в буферный кэш за одну системную операцию ввода/вывода устанавливается параметром db_file_multiblock_read_count. В OLTP системах он обычно равен от 8 до 16, а в OLAP системах от 32 и выше. На большинстве платформ значение db_file_multiblock_read_count может быть равен максимум 128, об это написано в предыдущей теме.

С помощью представления v$filestat можно посмотреть статистику по количеству одноблочных и многоблочных чтений. Описание полей из документации (только те, что интересуют нас и относятся к чтению):

FILE# Number of the file
PHYRDS Number of physical reads done
PHYBLKRD Number of physical blocks read
SINGLEBLKRDS Number of single block reads
В списке полей нет поля о кол-ве многоблочных чтений, но его мы можем получить отняв SINGLEBLKRDS (так как, за одну операцию одноблочного чтения читается один блок) от суммарного количества физических чтений PHYRDS:
MULTIRDS = PHYRDS-SINGLEBLKRDS
А кол-во блоков прочитанных в режиме многоблочного чтения можно получить отняв SINGLEBLKRDS от суммарного кол-ва прочитанных блоков PHYBLKRD:
MULTIBLKRDS = PHYBLKRD-SINGLEBLKRDS

Еще один важный параметр, который можно получить - это среднее количество блоков прочитанных в многоблочном чтении. Если этот параметр близок к db_file_multiblock_read_count, то это хорошо. Это значит, что при многоблочном чтении из файла в буферный кэш, за минимальное количество операций ввода/вывода, читается максимальное количество блоков.
BLKSMULTIBLKRDS = MULTIBLKRDS/MULTIRDS

Скрипт:
select round(SINGLEBLKRDS/PHYBLKRD,2) SINGLEBLKRDS_PCT,
round((PHYBLKRD-SINGLEBLKRDS)/PHYBLKRD,2) MULTIBLKRDS_PCT,
round((PHYBLKRD-SINGLEBLKRDS)/(PHYRDS-SINGLEBLKRDS),2) BLKSMULTIBLKRDS,
k.tablespace_name
from v$filestat t, dba_data_files k
where t.file#=k.file_id
order by 1

Здесь приблизительный результат:
SINGLEBLKRDS_PCT MULTIBLKRDS_PCT BLKSMULTIBLKRDS TABLESPACE_NAME
0 1 7,74 CCCTBS
0 1 7,83 CCCTBS
0 1 7,88 CCCTBS
0 1 15,73 USERS
0,01 0,99 7,88 CCCTBS
0,01 0,99 14,65 DDDDTBS
0,02 0,98 11,82 DATA_MED
0,03 0,97 11,73 DATA_MED
0,05 0,95 13,54 AAA_BBB
0,07 0,93 1,03 EEEETBS
0,26 0,74 14,49 DATA_SML
0,3 0,7 10,32 GGGDATA
0,31 0,69 9,35 SYSTEM
0,49 0,51 11,32 DATA_BIG
0,5 0,5 11,41 DATA_BIG
0,52 0,48 10 DATA_BIG
0,52 0,48 11,47 DATA_BIG
0,53 0,47 10,21 DATA_BIG
0,68 0,32 14,52 DATA_BIG
0,91 0,09 14,68 DATA_BIG_IX
0,91 0,09 15,28 DATA_BIG_IX
0,92 0,08 1 UNDO
0,92 0,08 14,81 DATA_BIG_IX
0,92 0,08 15,08 DATA_BIG_IX
0,93 0,07 15,32 DATA_BIG_IX
0,98 0,02 1 AAA_BBB_IX
0,99 0,01 1,65 FFFFTBS
1 0 1 DATA_SML_IX
1 0 1 DATA_MED_IX
Как показывает отчет, в табличных пространствах, где хранятся индексы (_IX) почти нет (или очень низкий процент) многоблочного чтения, думаю это из-за того, что в них нет таблиц, соответсвенно не бывает полных просмотров таблиц (table full scan) и очень низок процент fast full index scan.

5 мая 2008 г.

Максимальное значение db_file_multiblock_read_count

Параметр db_file_multiblock_read_count определяет количество блоков, которые будут считаны за одну системную операцию чтения.

Он используется стоимостным оптимизатором (Cost-based Optimizer) для вычисления суммарного кол-ва операций чтения для полного просмотра таблицы (full table scan).

Нередко стараются увеличить этот параметр, для улучшение производительности базы данных. Но необходимо тщательно выбирать значение этого параметра, так как слишком большое значение увеличит количество полных просмотров (full scan), а слишком маленькое значение увеличит использование индексов, даже в тех случаях, где полный просмотр таблиц был бы более эффективен.

Самый лёгкий способ узнать максимальный размер db_file_multiblock_read_count - это присвоить этому параметру очень большое значение и он скорректируется до максимально возможного размера:

SQL> select name, value from v$parameter
2 where name = 'db_file_multiblock_read_count';

NAME VALUE
------------------------------ ----------
db_file_multiblock_read_count 8

SQL> alter session set db_file_multiblock_read_count=100000000;

System altered

SQL>
SQL> select name, value from v$parameter
2 where name = 'db_file_multiblock_read_count';

NAME VALUE
------------------------------ ----------
db_file_multiblock_read_count
128

Этот запрос был выполнен на Oracle 9.2.0.8, размер блока БД - 8K, Solaris 5.9.
Максимальное значение этого параметра зависит от внутреннего параметра (константы) SSTIOMAX, который зависит от версии Oracle и размера блока базы данных. Это вырезка из Металинка Note:131530.1:
What is SSTIOMAX?
-----------------

SSTIOMAX is an internal parameter/constant used by oracle, which limits the
maximum amount of data transfer in a single IO of a read or write operation.
This parameter is fixed and cannot be tuned/changed.


Relationship between SSTIOMAX and db_file_multiblock_read_count (MBRC)
----------------------------------------------------------------------

More often than not, DBAs try to increase the db_file_multiblock_read_count
parameter (which can be set in the init.ora), in an attempt to optimize the
IO performance of the read and write operations.

Normally, with a higher value of MBRC, the IO performance is expected to be
better. So, users tend to increase this parameter to a higher value, in case
they find it beneficial. But, there is a limitation on this.

The limitation is, the product of db_block_size and MBRC cannot exceed the
SSTIOMAX. For example:

db_block_size * db_file_multiblock_read_count <= SSTIOMAX (which is predefined for a particular version of oracle) If the value of the product exceeds this, then the value of db_file_multiblock_read_count set in the init.ora is ignored and it is set as follows: db_file_multiblock_read_count = SSTIOMAX/db_block_size (rounded)

В Oracle 9i SSTIOMAX = 1M, то есть если
размер блока БД 16K, то максимальный размер db_file_multiblock_read_count = 1M / 16K = 64;
размер блока БД 8K, то максимальный размер db_file_multiblock_read_count = 1M / 8K = 128;
размер блока БД 4K, то максимальный размер db_file_multiblock_read_count = 1M / 4K = 256;

Для сравнения, в Oracle 7.3 SSTIOMAX был равен 128K.

4 мая 2008 г.

Создание табличного пространства, размер блока которого отличается от размера блока БД

Для создания табличного пространства, размер блока которого отличается от размера блока БД, необходимо выделить память под соответствующий db_Xk_cache_size
(db_2k_cache_size,db_4k_cache_size,db_8k_cache_size, db_16k_cache_size, db_32k_cache_size).

SQL> show parameter db_block_size

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
SQL> create tablespace tbs4k blocksize 4096
2 datafile '/u01/oradata/TESTDB/tbs4kTESTDB01.dbf'
3 size 10M autoextend on next 1M;
create tablespace tbs4k blocksize 4096
*
ERROR at line 1:
ORA-29339: tablespace block size 4096 does not match configured block sizes

SQL> show parameter cache_size

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 536870912
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0

SQL> alter system set db_4k_cache_size=16M scope=spfile;

System altered.

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL>
SQL> startup
ORACLE instance started.

Total System Global Area 1159537920 bytes
Fixed Size 730368 bytes
Variable Size 603979776 bytes
Database Buffers 553648128 bytes
Redo Buffers 1179648 bytes
Database mounted.
Database opened.

SQL> show parameter cache

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 16777216
db_8k_cache_size big integer 0
db_cache_advice string ON
db_cache_size big integer 536870912
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
object_cache_max_size_percent integer 10
object_cache_optimal_size integer 102400

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
session_cached_cursors integer 100
SQL> create tablespace tbs4k blocksize 4096
2 datafile '/u01/oradata/TESTDB/tbs4kTESTDB01.dbf'
3 size 10M autoextend on next 1M;

Tablespace created.