апр 122013
 

Това ми се наложи да го правя наскоро и искам да си запиша скриптовете за бъдеща употреба. Целта ми беше да дропна избрани job-ове и да ги създам с друг потребител. Но може да се направи и при всяка нужда от промяна.

За стандартните dbms_job използвах следния скрипт:

create or replace function get_dbms_job_ddl(v_job in number) return varchar2 is
  v_tmp varchar2(4000);
begin
	dbms_ijob.full_export(v_job, v_tmp);
	return v_tmp;
end;
/

select 'dbms_ijob.remove(' || job || ');'
  from dba_jobs
 where log_user = 'OLDUSER';

select replace(get_dbms_job_ddl(job), '''OLDUSER''', '''NEWUSER''')
  from dba_jobs
 where log_user = 'OLDUSER';

Ако има job-ове с по-дълъг WHAT, може да се наложи използването на CLOB вместо varchar2(4000). Оставям тази промяна на любопитния читател ;-)
Също така REPLACE-а може да счупи нещо, така че внимавайте какво копирате.

За DBMS_SCHEDULER jobs използвах (внимание! Изиска допълнителна обработка. Прочети до края):

select 'exec DBMS_SCHEDULER.drop_job (job_name => ''' || owner || '.' || job_name || ''');'
  from dba_scheduler_jobs
 where job_creator = 'OLDUSER';

select dbms_metadata.get_ddl('PROCOBJ', job_name, owner)
  from dba_scheduler_jobs
 where job_creator = 'OLDUSER';

Като цяло DBMS_METADATA не се справя много блестящо. Първо типа на обекта е невероятното ‘PROCOBJ’ (PROCedural OBJect), което звучи като някаква набързо скалъпена кръпка. Освен това направи някакви безумни кавички, които след това с replace-нах за да изглежда по-добре. А най-тъпото е, че изобщо не се усети да сложи owner при създаването на job-а, та трябваше да го лепя на ръка.
Но все пак свърши грубата работа.

 Posted by at 7:05
апр 102013
 

Не знам защо, ама много се кефя като видя да действат разни дребни детайли в огромната и сложна машина Oracle. Сега ще ви разкажа за един такъв случай. Може да бъде поучителен, интересен или скучен – зависи от това дали си имате работа с oracle и дали сте dba или developer :)

Всичко започна със супер спешния мейл от един Development manager от високо ниво. Новоразработената функционалност ХYZ се бави (12-13 сек), и са идентифицирали проблема в конкретна заявка към БД:

select .... from SOME_TABLE where IP = :1 and ACTIVE_DATE > current_timestamp - :2;

Не ми трябваше много време да видя, че се случва full table scan на таблицата, която има милиони редове. Няма индекс нито по IP, нито по ACTIVE_DATE. Да, разбира се цялата таблица отдавна е почервеняла в паметта и няма physical IO, но дори LIO отнема време.

Без много надежда попитах дали не могат да използват някоя от вече индексираните колони. Ами не, не може. За тази функционалност имаме само тези предикати.

Ами ок, ще правим тогава индекс по (IP, ACTIVE_DATE). Направих индекса на една от DEV базите и помолих да тестват. Оказа се, че няма ефект. Ъ.

Реших да сръчкам Oracle да се взема в ръце. Може ли такава простотия! Да му направя аз перфектния индекс, а той въобще да не го вземе предвид! Пуснах му един Тuning advisor да се съвземе. Каква беше изненадата ми, когато и Tuning advisor не откри индекса! Но пък ми подсказа къде е заровено кучето:

The predicate TO_NUMBER(“IP”)=:B1 used at line ID 1 of the execution plan contains an implicit data type conversion on indexed column “IP”. This implicit data type conversion prevents the optimizer from selecting indices on table “SOME_TABLE”

Евала, добре са го написали. Като врял и кипял (и бивш девелопър) веднага се усетих какво е станало. Язък, след толкова години развития на IDE-та и фреймуорци, грешките са си същите.

Проблема е, че колонката в таблицата е тип VARCHAR2. Bind-а обаче го подаваме като NUMBER. Ако няма bind, това веднага се хваща само с поглед върху заявката. Но в случая трябваше да гледам във V$SQL_BIND_CAPTURE. Или да накарам някой девелопър да си го погледне – и да го оправи.

Тук искам да отворя една малка скоба относно ползването на графични инструменти като OEM CC. Хубави са, и ти дават много удобства, но в момента леко ме подведоха. Същата тази информация можех да си я извадя по-рано ако не ме беше домързяло да пусна един dbms_xplan.display_cursor. Ето какво показва той:

SQL_ID  436wr79chvhqx, child number 0
-------------------------------------
select ...
  from SOME_TABLE 
 where IP = :1
   and ACTIVE_DATE > current_timestamp - :2
 
Plan hash value: 2330990216
 
----------------------------------------------------------------------------------------
| Id  | Operation         | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                    |       |       | 12528 (100)|          |
|*  1 |  TABLE ACCESS FULL| SOME_TABLE         |     1 |    87 | 12528   (2)| 00:02:31 |
----------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter((TO_NUMBER("IP")=:1 AND 
              "ACTIVE_DATE">CURRENT_TIMESTAMP(6)-:2))

И така идваме до същината на този пост. Оправиха си кода девелъпърите, започнаха да подават IP-то като стринг. Индекса захапа и плана стана следния:

SQL_ID  4ktc94z4ypdpu, child number 0
-------------------------------------
select ...
  from SOME_TABLE 
 where IP = :1
   and ACTIVE_DATE > current_timestamp - :2
 
Plan hash value: 3569887601
 
-----------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                       |       |       |     4 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| SOME_TABLE            |     1 |    87 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_SOME_TABLE_IP_TIME  |     1 |       |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("IP"=:1 AND "ACTIVE_DATE">CURRENT_TIMESTAMP(6)-:2 AND 
              "ACTIVE_DATE" IS NOT NULL)

Забелязахте ли промяната в предикатите? Появи се AND "ACTIVE_DATE" IS NOT NULL. Това optimizer-а сами си го е измислил!

От една страна, в b-tree индексите не се слагат null стойностите. За да използваме индекс, ние трябва да сме сигурни, че не ни трябват евентуалните редове с null в съответната колонка. Т.е. Oracle трябва да е сигурен, че потребителя, подал заявката, не търси тези данни. От друга страна оптимизатора знае, че няма дата, по-малка от null – или по-голяма. За това си позволява да забучи един измислен предикат във where клаузата, който му отваря пътя към използване на индекса.

Да, нещо дребно, ама ме кефи :)

 Posted by at 6:51

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

 Общи  Коментарите са изключени
апр 012013
 

(към първа част)

Ден N

Добре, днес е време за Голямата Пушка- Metalink ноти 729903.1, 400886.1 и 444164.1. В тях пише как се трейсва паралелно изпълнение. не е много добре обяснено, така че интерпретацията на логовете ще е чисто налучкване (демек може и да бъркам нещо).

Помолих погромистите да пуснат _px_trace в кода на ETL-а. Един emergency release и сме готови за изпълнението довечера.

Ден N+1
Мамка му! Тази нощ е минало бързо :-(

Единствената промяна е включването на _px_trace за сесията, която пуска точно тази заявка (и изключване след края на заявката). Нищо друго!

Бързо или бавно, не ми се чака. Искам да проверя дали може да се прочете нещо от тези логове. Както вече предупредих, не съм специализирал четене на PX trace.
На ред 5694 (да, преминах през 5693 реда преди да намеря нещо интересно за моя случай) намираме:

2013-02-20 01:53:58.837069*:PX_Granule:kxfr.c@5598:kxfrFlushObjs(): flushed 4436 objects and 0 temp objects
        kxfrialo                                                       [   24520/ 23550]
          best object 0x21f7ab9ce0
            hgt:0 blks:21872380 acp:0 nds:1 thr:4
kxfrialo                                                       [   24520/     0]
          threads requested = 4 (from kxfrComputeThread())
kxfrialo                                                       [   24520/     0]
          adjusted no. threads = 4 (from kxfrAdjustDOP())
kxfrAllocSlaves                                                [   24520/     0]
          DOP trace -- call kxfpgsg to get 4 slaves

Добре, ще използваме parallel 4. Тук искам да напомня, че за да се изпълни parallel X, трябват поне 2 x X процеса – X producers и X consumers.

2013-02-20 01:53:58.837069*:PX_Messaging:kxfp.c@9448:kxfpgsg():         reqthreads:4 KXFPLDBL/KXFPADPT/ load balancing:on adaptive:on
2013-02-20 01:53:58.837069*:PX_Messaging:kxfp.c@17464:kxfpiinfo():      inst [cpus:mxslv]
2013-02-20 01:53:58.837069*:PX_Messaging:kxfp.c@17468:kxfpiinfo():      1    [16  :32   ]
2013-02-20 01:53:58.837069*:PX_Messaging:kxfp.c@22218:kxfpGetNumActiveSlaves():
        number of active slaves on the instance: 24,number of active slaves but available to use: 0
2013-02-20 01:53:58.837069*:PX_Messaging:kxfp.c@17785:kxfpclinfo():     inst(load:user:pct:fact:servtarget:queued:started:granted:active:active(free)): aff
2013-02-20 01:53:58.837069*:PX_Messaging:kxfp.c@17791:kxfpclinfo():     1   (30  :1   :100:53  :256   :0     :0      :0      :24    :0     )
          load adapt num servers requested to = 4 (from kxfpAdaptDOP())
kxfpgsg                                                        [   24520/     0]
          getting 2 sets of 4 threads, client parallel query execution flg=0x230

Ако не греша, изглежда че 24 паралени процеса вече са заети от някой. Wtf? Да видим какво става нататък

          Height=4, Affinity List Size=0, inst_total=1, coord=1
          Insts     1
          Threads   4
kxfpg1sg                                                       [   24520/     0]
          q:0x22ffaeb5e0 req_threads:4 nthreads:4 unit:1 #inst:1 normal
          jStart:0  jEnd:32  jIncr:1 isGV:0  i:0 instno:1 kxfpilthno:4
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P000 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P001 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P002 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P003 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P004 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P005 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P006 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P007 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P008 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P009 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P010 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P011 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P012 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P013 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P014 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P015 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P016 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P017 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P018 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P019 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P020 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P021 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P022 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]
          trying to get slave P023 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24520/     0]

Очевидно P000 до P023 го дават много заети, не и се занимава с нас.

kxfpg1srv                                                      [   24520/     0]
          trying to get slave P024 on instance 1 for q:0x22ffaeb5e0
          slave P024 is local
          found slave P024 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24520/     0]
          Creating local slave 24 flg:30
kxfpcre1                                                       [   24520/     0]
          Creating slave 24 flg:30
          free descriptor found dp:0x21319a0e48
          Allocated slave P024 dp:0x21319a0e48 flg:4
          Got It. 1 so far.
kxfpg1srv                                                      [   24530/    10]
          trying to get slave P025 on instance 1 for q:0x22ffaeb5e0
          slave P025 is local
          found slave P025 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24530/     0]
          Creating local slave 25 flg:30
kxfpcre1                                                       [   24530/     0]
          Creating slave 25 flg:30
          free descriptor found dp:0x21319a0da8
          Allocated slave P025 dp:0x21319a0da8 flg:4
          Got It. 2 so far.
kxfpg1srv                                                      [   24550/    20]
          trying to get slave P026 on instance 1 for q:0x22ffaeb5e0
          slave P026 is local
          found slave P026 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24550/     0]
          Creating local slave 26 flg:30
kxfpcre1                                                       [   24550/     0]
          Creating slave 26 flg:30
          free descriptor found dp:0x21319a0a70
          Allocated slave P026 dp:0x21319a0a70 flg:4
          Got It. 3 so far.
kxfpg1srv                                                      [   24560/    10]
          trying to get slave P027 on instance 1 for q:0x22ffaeb5e0
          slave P027 is local
          found slave P027 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24560/     0]
          Creating local slave 27 flg:30
kxfpcre1                                                       [   24560/     0]
          Creating slave 27 flg:30
          free descriptor found dp:0x21319a09d0
          Allocated slave P027 dp:0x21319a09d0 flg:4
          Got It. 4 so far.
kxfpPrepareJoin                                                [   24580/    20]
          grln:3 grlr:3 size:1536 var:486 evntCnt:11 eventSize:466 totSize:2014
kxfpg1sg                                                       [   24580/     0]
          wait reply from qref 0x22fd47e038
kxfpg1sg                                                       [   24580/     0]
          received reply from qref 0x22fd47e038
kxfpg1sg                                                       [   24580/     0]
          wait reply from qref 0x22fd481aa8
kxfpg1sg                                                       [   24580/     0]
          received reply from qref 0x22fd481aa8
kxfpg1sg                                                       [   24580/     0]
          wait reply from qref 0x1f23ebf38
kxfpg1sg                                                       [   24580/     0]
          received reply from qref 0x1f23ebf38
kxfpg1sg                                                       [   24580/     0]
          wait reply from qref 0x1f23ebc90
kxfpg1sg                                                       [   24580/     0]
          received reply from qref 0x1f23ebc90
kxfpg1sg                                                       [   24580/     0]
          got 4 servers (sync), errors=0x0 returning
kxfpg1sg                                                       [   24580/     0]
          q:0x22ffaeb5e0 req_threads:4 nthreads:4 unit:1 #inst:1 normal
          jStart:0  jEnd:32  jIncr:1 isGV:0  i:0 instno:1 kxfpilthno:4

добре, създадохме си първата група от 4 процеса. Трябват ни още толкова…

kxfpg1srv                                                      [   24580/     0]
          trying to get slave P000 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P001 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P002 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P003 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P004 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P005 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P006 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P007 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P008 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P009 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P010 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P011 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P012 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P013 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P014 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P015 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P016 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P017 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P018 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P019 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P020 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P021 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P022 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P023 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P024 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P025 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P026 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]
          trying to get slave P027 on instance 1 for q:0x22ffaeb5e0
kxfpg1srv                                                      [   24580/     0]

P000-P027 са заети (всъщност P024-P027 са заети от нас)

          trying to get slave P028 on instance 1 for q:0x22ffaeb5e0
          slave P028 is local
          found slave P028 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24580/     0]
          Creating local slave 28 flg:30
kxfpcre1                                                       [   24580/     0]
          Creating slave 28 flg:30
          free descriptor found dp:0x21319a0698
          Allocated slave P028 dp:0x21319a0698 flg:4
          Got It. 1 so far.
kxfpg1srv                                                      [   24600/    20]
          trying to get slave P029 on instance 1 for q:0x22ffaeb5e0
          slave P029 is local
          found slave P029 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24600/     0]
          Creating local slave 29 flg:30
kxfpcre1                                                       [   24600/     0]
          Creating slave 29 flg:30
          free descriptor found dp:0x21319a05f8
          Allocated slave P029 dp:0x21319a05f8 flg:4
          Got It. 2 so far.
kxfpg1srv                                                      [   24610/    10]
          trying to get slave P030 on instance 1 for q:0x22ffaeb5e0
          slave P030 is local
          found slave P030 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24610/     0]
          Creating local slave 30 flg:30
kxfpcre1                                                       [   24610/     0]
          Creating slave 30 flg:30
          free descriptor found dp:0x21319a02c0
          Allocated slave P030 dp:0x21319a02c0 flg:4
          Got It. 3 so far.
kxfpg1srv                                                      [   24630/    20]
          trying to get slave P031 on instance 1 for q:0x22ffaeb5e0
          slave P031 is local
          found slave P031 dp:0x21319a0220 flg:0
kxfpcrel                                                       [   24630/     0]
          Creating local slave 31 flg:30
kxfpcre1                                                       [   24630/     0]
          Creating slave 31 flg:30
          free descriptor found dp:0x21319a0220
          Allocated slave P031 dp:0x21319a0220 flg:4
          Got It. 4 so far.
kxfpPrepareJoin                                                [   24640/    10]
          grln:3 grlr:3 size:1536 var:486 evntCnt:11 eventSize:466 totSize:2014

kxfpg1sg                                                       [   24640/     0]
          wait reply from qref 0x1f23eb740
kxfpg1sg                                                       [   24640/     0]
          received reply from qref 0x1f23eb740
kxfpg1sg                                                       [   24640/     0]
          wait reply from qref 0x1f23eb498
kxfpg1sg                                                       [   24640/     0]
          received reply from qref 0x1f23eb498
kxfpg1sg                                                       [   24640/     0]
          wait reply from qref 0x1f23eb1f0
kxfpg1sg                                                       [   24650/    10]
          received reply from qref 0x1f23eb1f0
kxfpg1sg                                                       [   24650/     0]
          wait reply from qref 0x1f23eaf48
kxfpg1sg                                                       [   24650/     0]
          received reply from qref 0x1f23eaf48
kxfpg1sg                                                       [   24650/     0]
          got 4 servers (sync), errors=0x0 returning

Ох, мина на косъм. Имаме и другите четири – P028-P031. Напомням, че лимита е сетнат на 32. Днес имахме късмет.

2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10118:kxfpgsg():        Acquired 8 slaves on 1 instances avg height:4 #set:2 qser:893953
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10128:kxfpgsg():        P024 inst 1 spid 31409
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10128:kxfpgsg():        P025 inst 1 spid 31413
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10128:kxfpgsg():        P026 inst 1 spid 31417
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10128:kxfpgsg():        P027 inst 1 spid 31422
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10137:kxfpgsg():        P028 inst 1 spid 31427
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10137:kxfpgsg():        P029 inst 1 spid 31433
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10137:kxfpgsg():        P030 inst 1 spid 31438
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10137:kxfpgsg():        P031 inst 1 spid 31443
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10144:kxfpgsg():        Instance(servers):
2013-02-20 01:53:58.965839*:PX_Messaging:kxfp.c@10147:kxfpgsg():        inst:1 #slvs:8

Да видим какво ще се случи следващата нощ.

 Posted by at 6:37
мар 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
мар 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
мар 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
мар 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
фев 192013
 

ОК, и тази година се получи добре. Ще взема да запиша рецептата и технологията – хем да не я забравя, хем да я споделя.

Месото, което си взимам, в 1 част свински бут, 1 част телешко и 1 част свински гърди (обезкостени). Тук искам да уточня – гърдите са доста мазно нещо. Това не е лошо, напротив. Ял съм суджук само от телешко, без сланина – ми то е като трески. Ние в България имаме такъв вкус – ако не ни е мазничко, не е вкусно. Пък и дори с тази рецепта пак се получава доста по-чисто и по-малко сланинесто от кой да е купешки суджук/луканка/салам. Имам чувството, че в купешките слагат по 50% чиста сланина! (съвсем субективно, разбира се). Да не говорим че в домашния суджук няма жили и други странни примеси…

Та така. Аз взех по ~7 килограма от трите меса. Миналата година това стигна да имаме хубав домашен суджук до август :)

Месото се нарязва на парчета с размер 5-6 см и се омесва с подправките. Това се прави, за да може подправките да се разпределят хубаво в целия обем. Подправките, които сложих, са (пропорция на килограм месо):
22 грама сол/кг
5 грама кимион/кг (кимиона е сърцето на суджука)
5 г червен пипер/кг
1-2 г чубрица/кг
1-2 г черен пипер/кг
1 г сминдух или чимен на прах/кг (това не е задължително; тази година сложих чимен за експеримента и не се оплаквам от резултата :-) )
В повечето рецепти из нета пише да се слага селитра. Аз не слагам и пак си го ядем до средата на годината. До колкото знам селитрата помага да се запази червения цвят на месото като пресича някои процеси на окисляване (може и да се лъжа). Но това хич не ми звучи като нещо “домашно” и естествено. Пък и не ме бърка че суджука е по-кафяв – важен е вкуса. А за дълготрайността се грижат солта (да, тя не се слага заради вкуса) и изсушаването (и то не се прави заради външния вид). А, и най-вече фризера.

Понеже нямам кухненска везна, грамажите ги целя “на око”. Все пак, на 21-22 кила месо, 2-3 грама повече или по-малко кимион няма да се усетят чак толкова.

И така, омесвам нарязаното месо с подправките и ги оставям на хладно за 24 часа, да си поемат. Чак след това се намесва мелачката. Смилам нещата на най-едрата решетка (все пак няма да правя кренвирши). Смляното месо може да се опита на вкус – дали има нужда от още нещо – под формата на кюфтета :)

След като смеля всичко, го оставям на хладно да изпръхне още поне 24 часа. През това време го меся доста интензивно (тежка работа) през 5-6 часа. Меси се като тесто, с двете ръце, със запретнати ръкави :-)

След това идва време за пълненето в червата. Тежка и пипкава работа. Моята мелачка си има фуния за черва. То друг начин няма, де – освен с разни специализирани машини. Тук искам да вметна някои технологични тънкости относно самите черва:
- използвам тънки свински черва
- черва се намира трудно – няма ги по хипермаркетите :-) . До сега съм ги намирал само по кланници, като единицата е “една връзка” – към 90-100 метра. В зависимост от дебелината, стига за 30-60 килограма сурово месо
- червата могат да стоят в хладилника с години, стига да са добре осолени
- червата са доста по-здрави, от колкото изглеждат. Не се късат лесно. Но се късат когато очакваш най-малко :-/
- разплетете връзката на отделни черва. Покрай този процес човек осъзнава от къде идва израза “оплетени като свински черва”
- преди да нанижете червото на фунията, го накиснете за 2-3 минути в хладка вода. Подчертавам – хладка. Ако е гореща, червото се свива и няма нанизване
- има един много тарикатски метод за самото нанизване на червото върху фунията: хванете единия край, налейте вътре малко хладка вода (да запълни 3-4 см от дължината) и започвайте да нанизвате. Водата ще се движи пред фунията, като при това ще “смазва” червото за по-лесно нанизване. После ще си се изтече от другия край

Човек постепенно си изгражда технология за пълненето. То си е работа за двама, де – един да пълни в машинката, друг да управлява червото. Още няколко съвета:
- опитайте се да не оставяте въздух в червото, до колкото е възможно
- пълненето не трябва да е много плътно, нито много рехаво
- при пълнене с мелачка НЕ се поставят решетка и нож. Както казах, не правим кренвирши. Моята машинка има една пластмасова псевдо-решетка (всъщност само 3 “спици”), което се постава колкото да държи винта
- напълнете цялото черво, като на всеки Х сантиметра оставяте по 2-3 пръста празно за срязване. Чак след това се занимавайте с рязане/завързване
- по-тънките черва ги пълня на по-дълги парчета и после стават “подкови”. Имаше някои по-дебели, които изглеждат тъпо на подкови – тях ги пълня на по-къси парчета и ги оставям “прави”

И последния технологичен етап е сушенето. Сушилника си го правих аз – от идеен проект, през разкрояване на летвичките, сглобяване, лакиране, до облицоване с фина метална мрежа, което да пази от почти всичко: бръмбари/мухи до птици и котки. Само от айдуци не пази, ама там няма спасение – стискаш палци и това е.

В първите етапи на сушенето суджука трябва да се “плоска” (или “валира”) на всеки 1-2 дни. Целта е хем да придобие форма, хем да се размесва месото вътре. По време на плоскането, особено в началото, се оглеждайте за въздушни мехурчета останали от пълненето. Ако видите мехурче с въздух, пукнете червото с карфичка и изкарайте въздуха.

Когато позасъхне продукцията, плоскането се разрежда, докато накрая остава само висене и чакане. За колко време става – зависи от, хм, времето. Ако е хубаво, студено и ветровито – може да стане и за по-малко от 2 седмици. Ако е мъгливо, може да иде и 2 месеца. Важно е от време на време да се пробва, да не се пресуши. Ако стане на треска, не е вкусен.

После го слагам във фризера и така трае с месеци. Изваждам по някое парче да се размрази и режа с керамиката. От така описаната смес (21-22 кг) се получиха около 70-80 парчета, които след изсъхването са около 8 кг. Колко вино ще изпие – това си зависи от човека.

Добър апетит!

 Posted by at 19:26
фев 122013
 

Търсим свежо попълнение за DBA екипа в Skrill – екипа, в който работя от 3 години. Обявата с повечко подробности е пусната в Jobs.bg. Прекрасно осъзнавам, че не можем да намерим универсален войник, който да знае всичко; за това по-редките “дарби” сме ги изписали като appreciated. Като цяло всеки, който има солиден опит с управление на любимата ми БД, е добре дошъл (в смисъл, да изпрати CV).

Склонен съм да отговоря на някой по-общи въпроси и тук, но подмятания от типа на “колко пари горе-долу давате” или “каква е паролата за sys на вашите бази” няма да минат :)

Ако се чудите дали си заслужава, помислете над следното – в България има към 7 милиона жители. Колко клиента има най-голямата финансова институция? Нашите са над 33 милиона…

 Posted by at 13:24
яну 092013
 

В момента зреят – да, навън.

На студа.

Някои са прави, други – на подкови:

sudjuk

Надявам се до края на месеца да са готови. А за догодина мисля да сглобя по-голям сушилник. Че така като са наблъскани съхнат бавно.
Като си го проектирах този, не съм предполагал колко много хубави неща могат да се “случват” вътре…

sudjuk2

 Posted by at 20:26