Паралелни мотики – част 1

 Общи  Коментарите са изключени за Паралелни мотики – част 1
Мар. 272013
 

Това ми отне доста време да го дебъгна. Първо, самия процес върви за час-час и половина когато е ОК и за 4-5 часа когато е зле. Второ, това е част от ETL процес, който работи през нощта – трудно се наблюдава „на живо“. Трето, един път тръгва наред, следващия се скапва. Но най-гадното е, че като се опитам да го reproduce-на, винаги си върви както трябва. А накрая се оказа и че повредата не е в този statement, просто той си го отнася заради други грешки. Но да преминем към фактите.

Ден 1
Оплакването е, че една от стъпките на нощния ETL процес е минала бавно. Този процес се движи от един сравнително сложен job chain от трийсетина стъпки, които ту вървят в паралел, ту се изчакват, абе корава работа. За щастие е много добре инструментиран и веднага се вижда кое кога е тръгнало, колко неща са вървяли по това време и така.

Разбира се, никой нищо не е пипал – последната промяна в ETL-а е от сряда, а проблема се проявява в събота (и в неделя, и в понеделник…). В такива моменти много добра подсказка може да даде графиката за изпълнение на заявката от OEM Cloud Cotntrol. Ето какво се вижда за един „бърз“ и един „бавен“ ден:

screenshot-1.

Симтомите са ясни – само една сесия работи по въпроса, няма паралелно изпълнение. Нека да видим плана от последното изпълнение (предната нощ):

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name                     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                        |                          |       |       |       |    11M(100)|          |       |       |        |      |            |
|   1 |  LOAD AS SELECT                         |                          |       |       |       |            |          |       |       |        |      |            |
|   2 |   PX COORDINATOR                        |                          |       |       |       |            |          |       |       |        |      |            |
|   3 |    PX SEND QC (RANDOM)                  | :TQ10012                 |   445M|  1737G|       |    11M  (1)| 31:41:37 |       |       |  Q1,12 | P->S | QC (RAND)  |
|   4 |     HASH JOIN OUTER BUFFERED            |                          |   445M|  1737G|   779M|    11M  (1)| 31:41:37 |       |       |  Q1,12 | PCWP |            |
|   5 |      PX RECEIVE                         |                          |    33M|  2738M|       |   104K  (2)| 00:17:41 |       |       |  Q1,12 | PCWP |            |
|   6 |       PX SEND HASH                      | :TQ10010                 |    33M|  2738M|       |   104K  (2)| 00:17:41 |       |       |  Q1,10 | P->P | HASH       |
|   7 |        VIEW                             |                          |    33M|  2738M|       |   104K  (2)| 00:17:41 |       |       |  Q1,10 | PCWP |            |
|   8 |         WINDOW SORT                     |                          |    33M|  1636M|  1896M|   104K  (2)| 00:17:41 |       |       |  Q1,10 | PCWP |            |
|   9 |          HASH JOIN RIGHT OUTER          |                          |    33M|  1636M|       |  5799  (17)| 00:00:59 |       |       |  Q1,10 | PCWP |            |
|  10 |           PX RECEIVE                    |                          |    33M|   409M|       |   544  (19)| 00:00:06 |       |       |  Q1,10 | PCWP |            |
|  11 |            PX SEND HASH                 | :TQ10007                 |    33M|   409M|       |   544  (19)| 00:00:06 |       |       |  Q1,07 | P->P | HASH       |
|  12 |             PX BLOCK ITERATOR           |                          |    33M|   409M|       |   544  (19)| 00:00:06 |       |       |  Q1,07 | PCWC |            |
|  13 |              INDEX FAST FULL SCAN       | DIM_xxxx_x_xx_x_xxx_xx_x |    33M|   409M|       |   544  (19)| 00:00:06 |       |       |  Q1,07 | PCWP |            |
|  14 |           PX RECEIVE                    |                          |    33M|  1227M|       |  5092  (15)| 00:00:52 |       |       |  Q1,10 | PCWP |            |
|  15 |            PX SEND HASH                 | :TQ10008                 |    33M|  1227M|       |  5092  (15)| 00:00:52 |       |       |  Q1,08 | P->P | HASH       |
|  16 |             HASH JOIN RIGHT OUTER       |                          |    33M|  1227M|       |  5092  (15)| 00:00:52 |       |       |  Q1,08 | PCWP |            |
|  17 |              PX RECEIVE                 |                          |   152K|  1786K|       |    11   (0)| 00:00:01 |       |       |  Q1,08 | PCWP |            |
|  18 |               PX SEND BROADCAST         | :TQ10000                 |   152K|  1786K|       |    11   (0)| 00:00:01 |       |       |  Q1,00 | P->P | BROADCAST  |
|  19 |                PX BLOCK ITERATOR        |                          |   152K|  1786K|       |    11   (0)| 00:00:01 |       |       |  Q1,00 | PCWC |            |
|  20 |                 TABLE ACCESS FULL       | DIM_xxxxxxxx             |   152K|  1786K|       |    11   (0)| 00:00:01 |       |       |  Q1,00 | PCWP |            |
|  21 |              PX BLOCK ITERATOR          |                          |    33M|   849M|       |  5015  (14)| 00:00:51 |       |       |  Q1,08 | PCWC |            |
|  22 |               TABLE ACCESS FULL         | DIM_xxxxxxxx             |    33M|   849M|       |  5015  (14)| 00:00:51 |       |       |  Q1,08 | PCWP |            |
|  23 |      PX RECEIVE                         |                          |   448M|  1713G|       |  5689K  (1)| 16:03:56 |       |       |  Q1,12 | PCWP |            |
|  24 |       PX SEND HASH                      | :TQ10011                 |   448M|  1713G|       |  5689K  (1)| 16:03:56 |       |       |  Q1,11 | P->P | HASH       |
|  25 |        VIEW                             |                          |   448M|  1713G|       |  5689K  (1)| 16:03:56 |       |       |  Q1,11 | PCWP |            |
|  26 |         SORT UNIQUE                     |                          |   448M|    50G|    54G|  5689K  (1)| 16:03:56 |       |       |  Q1,11 | PCWP |            |
|  27 |          WINDOW SORT                    |                          |   448M|    50G|    54G|  5689K  (1)| 16:03:56 |       |       |  Q1,11 | PCWP |            |
|  28 |           PX RECEIVE                    |                          |   448M|    50G|       |   120K (16)| 00:20:21 |       |       |  Q1,11 | PCWP |            |
|  29 |            PX SEND HASH                 | :TQ10009                 |   448M|    50G|       |   120K (16)| 00:20:21 |       |       |  Q1,09 | P->P | HASH       |
|  30 |             HASH JOIN                   |                          |   448M|    50G|       |   120K (16)| 00:20:21 |       |       |  Q1,09 | PCWP |            |
|  31 |              PX RECEIVE                 |                          |    21 |   126 |       |     2   (0)| 00:00:01 |       |       |  Q1,09 | PCWP |            |
|  32 |               PX SEND BROADCAST         | :TQ10001                 |    21 |   126 |       |     2   (0)| 00:00:01 |       |       |  Q1,01 | P->P | BROADCAST  |
|  33 |                PX BLOCK ITERATOR        |                          |    21 |   126 |       |     2   (0)| 00:00:01 |       |       |  Q1,01 | PCWC |            |
|  34 |                 TABLE ACCESS FULL       | DIM_xxx_xxx              |    21 |   126 |       |     2   (0)| 00:00:01 |       |       |  Q1,01 | PCWP |            |
|  35 |              HASH JOIN                  |                          |   448M|    47G|       |   119K (16)| 00:20:12 |       |       |  Q1,09 | PCWP |            |
|  36 |               PX RECEIVE                |                          |     8 |   128 |       |     2   (0)| 00:00:01 |       |       |  Q1,09 | PCWP |            |
|  37 |                PX SEND BROADCAST        | :TQ10002                 |     8 |   128 |       |     2   (0)| 00:00:01 |       |       |  Q1,02 | P->P | BROADCAST  |
|  38 |                 PX BLOCK ITERATOR       |                          |     8 |   128 |       |     2   (0)| 00:00:01 |       |       |  Q1,02 | PCWC |            |
|  39 |                  TABLE ACCESS FULL      | DIM_xxx_xxxxxx           |     8 |   128 |       |     2   (0)| 00:00:01 |       |       |  Q1,02 | PCWP |            |
|  40 |               HASH JOIN                 |                          |   448M|    40G|       |   118K (15)| 00:20:03 |       |       |  Q1,09 | PCWP |            |
|  41 |                PX RECEIVE               |                          |   135 |  2160 |       |     2   (0)| 00:00:01 |       |       |  Q1,09 | PCWP |            |
|  42 |                 PX SEND BROADCAST       | :TQ10003                 |   135 |  2160 |       |     2   (0)| 00:00:01 |       |       |  Q1,03 | P->P | BROADCAST  |
|  43 |                  PX BLOCK ITERATOR      |                          |   135 |  2160 |       |     2   (0)| 00:00:01 |       |       |  Q1,03 | PCWC |            |
|  44 |                   TABLE ACCESS FULL     | DIM_xxx_xxxx             |   135 |  2160 |       |     2   (0)| 00:00:01 |       |       |  Q1,03 | PCWP |            |
|  45 |                HASH JOIN                |                          |   455M|    34G|       |   117K (15)| 00:19:54 |       |       |  Q1,09 | PCWP |            |
|  46 |                 PX RECEIVE              |                          |    55 |   385 |       |     2   (0)| 00:00:01 |       |       |  Q1,09 | PCWP |            |
|  47 |                  PX SEND BROADCAST      | :TQ10004                 |    55 |   385 |       |     2   (0)| 00:00:01 |       |       |  Q1,04 | P->P | BROADCAST  |
|  48 |                   PX BLOCK ITERATOR     |                          |    55 |   385 |       |     2   (0)| 00:00:01 |       |       |  Q1,04 | PCWC |            |
|  49 |                    TABLE ACCESS FULL    | DIM_xxxxxxxx             |    55 |   385 |       |     2   (0)| 00:00:01 |       |       |  Q1,04 | PCWP |            |
|  50 |                 HASH JOIN               |                          |   463M|    32G|       |   116K (14)| 00:19:45 |       |       |  Q1,09 | PCWP |            |
|  51 |                  PX RECEIVE             |                          |   152K|  1786K|       |    12   (9)| 00:00:01 |       |       |  Q1,09 | PCWP |            |
|  52 |                   PX SEND BROADCAST     | :TQ10005                 |   152K|  1786K|       |    12   (9)| 00:00:01 |       |       |  Q1,05 | P->P | BROADCAST  |
|  53 |                    PX BLOCK ITERATOR    |                          |   152K|  1786K|       |    12   (9)| 00:00:01 |       |       |  Q1,05 | PCWC |            |
|  54 |                     TABLE ACCESS FULL   | DIM_xxxxxxxx             |   152K|  1786K|       |    12   (9)| 00:00:01 |       |       |  Q1,05 | PCWP |            |
|  55 |                  HASH JOIN              |                          |   557M|    32G|       |   115K (13)| 00:19:34 |       |       |  Q1,09 | PCWP |            |
|  56 |                   PX RECEIVE            |                          |     2 |    10 |       |     2   (0)| 00:00:01 |       |       |  Q1,09 | PCWP |            |
|  57 |                    PX SEND BROADCAST    | :TQ10006                 |     2 |    10 |       |     2   (0)| 00:00:01 |       |       |  Q1,06 | P->P | BROADCAST  |
|  58 |                     PX BLOCK ITERATOR   |                          |     2 |    10 |       |     2   (0)| 00:00:01 |       |       |  Q1,06 | PCWC |            |
|  59 |                      TABLE ACCESS FULL  | DIM_xxxxxxxxx            |     2 |    10 |       |     2   (0)| 00:00:01 |       |       |  Q1,06 | PCWP |            |
|  60 |                   PX PARTITION RANGE ALL|                          |   557M|    30G|       |   114K (12)| 00:19:22 |     1 |  4429 |  Q1,09 | PCWC |            |
|  61 |                    TABLE ACCESS FULL    | FACT_xxxxxx              |   557M|    30G|       |   114K (12)| 00:19:22 |     1 |  4429 |  Q1,09 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

А! Шах с пешката. Всичко изглежда доста паралелно. Значи оптимизатора е решил да подходи паралелно към заявката, но execution engine е решил да не се съобрази и да си го изпълни серийно.

Реших да го пусна аз, на ръка, да видим какво ще стане. Ами какво да стане – мина си паралелно, за час и десет минути. Както и да го въртях, ако не му махна хинта parallel, не тръгва серийно! И да, хинта си го има в заявката, която се изпълнява.

Тук искам да вмъкна един от безценните съвети на Jonathan Lewis относно хинта parallel. Този хинт има доста малка тежест. Той не казва на оптимизатора „изпълни това с такъв и такъв паралелизъм“. Не, той само подсказва „абе я погледни тук дали няма да е далавера ако използваме паралелизъм X“. Да, обаче при нас случая не е такъв – оптимизатора съвсем чинно си съставя паралелен план. Така си е записано и във v$sql_plan. Т.е. оптимизатора, който е виновен по default за повечето проблеми, тук не е сгрешил. Съответно стандартните подходи като baselines или sql profiles няма да хванат дикиш.

След като си утрепах няколко часа в опити да го reproduce-на, денят свърши незадоволително. При тестове всичко е наред. Да видим какво ще стане нощес. Нали утрото било по-мъдро от вечерта…

Ден 2

Отново е минало бавно. Това е много дразнещо. Колкото и да се опитвам да го пусна – минава „бързо“ (относително – за час и нещо). А като си тръгне самó, се прецаква. Най-вбесяващото е, че плана в SQL cache отново е паралелен, но изпълнението е серийно.

Може би не ни достигат parallel query slaves? Хайде за довечера ще ги вдигнем от 20 на 32:

alter system set parallel_max_servers=32;

Ден 3

Пак е минало серийно 🙁

Петък е, ден на майстора. Няма да го разбутвам, че да не се налага спешна намеса през уикенда. Все пак върви и така. И приключва преди изгрев слънце.

(следва продължение)

 Posted by at 7:01

OBIEE databаse requirements

 Общи  Коментарите са изключени за OBIEE databаse requirements
Мар. 222013
 

Смях, смях през сълзи.

Чета installation guide-а на Oracle Business Intelligence и се чудя кой ли титан на мисълта е написал това в документацията:

Ensure that your database is not hardened for security purposes. Installing Oracle Business Intelligence against a hardened database is not supported.

Явно Oracle Business Intelligence Enterprise Edition Plus – продукт, който струва една торба с пари – е предвиден за употреба само в малки шивашки фирмички и квартални магазинчета. Защото всяка организация с по-сериозни намерения трябва да се грижи и за сигурността на своята БД.

Но пък така е по-лесно…

 Posted by at 9:35

ORA-16631: Operation requires shutdown of database/instance „“

 Общи  Коментарите са изключени за ORA-16631: Operation requires shutdown of database/instance „“
Мар. 052013
 

Още една мотика. Случва се следното
– конфигурация от 4 БД (1 primary и 3 standby)
– рестартираме единия standby. Всичко минава по план
– dgmgrl обаче мисли друго:

DGMGRL> show configuration

Configuration - DG

  Protection Mode: MaxAvailability
  Databases:
    primary  - Primary database
    standby1 - Physical standby database
    standby2 - Physical standby database (disabled)
    standby3 - Logical standby database (disabled)

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

(disabled) – WTF? трябва да уточня, че сме рестартирали standby1 – другите не сме ги и пипали.

Хайде да опитаме най-лесното

DGMGRL> enable database standby2;

Следва изненада:

ORA-16631: Operation requires shutdown of database/instance ""

Ъъъ… кой, точно, инстанс да рестартирам?

Единственото хубаво на тази грешка е, че води до правилната нота в металинк:
Metalink note 1258074.1

Ora-16631: Operation Requires Shutdown Of Database Or Instance „“ On Physical Standby

Applies to:
Oracle Server – Enterprise Edition – Version: 11.1.0.7 and later [Release: 11.1 and later ]
Information in this document applies to any platform.

Symptoms

ORA-16631: Operation requires shutdown of database/instance „“

Cause
Both the primary and standby were shutdown in an graceful fashion.
Since standby is shutdown before primary, standby is marked as shutdown disabled
standby is restarted first and then the primary.
standby sends a bootstrap request to the primary but since it’s not started yet,
it’s request goes unanswered. When primary is then started and as part of
its bootstrap processing the primary intentionally leaves the standby in a
shutdown disabled state. The FSFO state then transitions to an unsynchronized
state since the standby is not available.

Solution
— on primary –-

dgmgrl /
edit database 'standby db unique name here' set state='ONLINE';
show configuration;
exit

( or )

–- on standby —

sqlplus / as sysdba
shu immediate
startup mount

Е, вярно, при нас проблема е и при physical, и при logical standby. Освен това не съм рестартирал нито тях, нито primary базата. Мога само да предполагам, че когато standby1 е казал на primary „аз си заминавам“, primary някак се е объркал и е отписал всичките БД. После standby1 е изгрял и е изпратил bootstrap сигнал. Тогава primay го е вписал в конфигурацията, оставяйки другите два на сухо.
Но поне Solution-а работи. Естествено избрах първия като много по-малко инвазивен. Че знам ли като рестартирам standby2 какво ще стане със standby1… 🙂

 Posted by at 4:36

PLS-00201: identifier ‘SECRETUSER.ASHVIEWER’ must be declared

 Общи  Коментарите са изключени за PLS-00201: identifier ‘SECRETUSER.ASHVIEWER’ must be declared
Мар. 012013
 

Проблема се случи като се опитах да deploy-на ASH Analytics на една БД. Преди сме го правили и не е имало драми. Явно е някакъв нов фичур на най-най новия OEM Cloud control. Наскоро пачнахме OMS-а до 12.1.0.2.1 (последното PSU от януари) и от тогава се е сбъгясало.

ASH Analytics се пуска, по принцип, доста лесно. Doug Burns го показа в лекцията си „Falling in Love All Over Again: OEM 12c Performance Page Enhancements“ на последната сбирка на БГПО. Като цяло трябва да има един юзър с подходящите привилегии (то си казва какво му трябва). След като имате такъв потребител, нацъквате от страничката на съответната БД Performance home -> ASH analytics, давате креденшълите и той си се деплойва сам, използвайки OEM job. Да ама в новата версия деплоймънта гръмва безславно с

Error while executing the script : oracle.sysman.assistants.common.dbutil.SQLFatalErrorException:
Error creating PL/SQL Object PRVT_AWR_DATA : PACKAGE BODY – PLS-00201: identifier ‘SECRETUSER.ASHVIEWER’ must be declared
Error creating PL/SQL Object PRVT_AWR_DATA : PACKAGE BODY – PL/SQL: Statement ignored
at line number – 2580
Driver SQL Script encountered errors.
Fail

Като ми гръмна три пъти се убедих, че проблема не е в мен. Разбира се, такъв проблем не е описан нито в Metalink, нито в нета.

За щастие в самото начало job-а си казва кои скриптове ще изпълнява. За още по-голямо щастие пакетите не са wrap-нати и може лесно да се проследи какво го боли. А болката е, че sql скрипта е подреден грешно.

Файловете се намират на OEM APP сървъра, в plugins/oracle.sysman.db.oms.plugin_12.1.0.3.0/sql/db/latest/instance/. Реда, в който се опитва да ги изпълни, е:

prvs_awr_data.sql
prvt_awr_data.sql
prvs_awr_data_cp.sql
prvt_awr_data_cp.sql
dbms_compare_period.sql
prvt_compare_period.sql
eaddm_pkgdef.sql
eaddm_pkgbody.sql
ashviewer_pkgdefs.sql
ashviewer_pkgbodys.sql

Още втория файл гръмва с горепосочената грешка, защото търси пакета ashviewer. Както виждаме по-надолу, този пакет се създава от последните два файла. Оправията е да се пуснат в следния ред:

prvs_awr_data.sql

ashviewer_pkgdefs.sql
ashviewer_pkgbodys.sql

prvt_awr_data.sql
prvs_awr_data_cp.sql
prvt_awr_data_cp.sql
dbms_compare_period.sql
prvt_compare_period.sql
eaddm_pkgdef.sql
eaddm_pkgbody.sql

След това ASH Analytics работи без проблеми.

 Posted by at 14:03