Feed on
Posts
Comments

Преди няколко дни си поръчах компютърни компоненти от онлайн магазина Ango.bg. Понеже пуснах поръчката вечерта, нещата бяха задействани на другия ден, след като ми се обадиха да потвърдя. Веднага, след като потвърдих поръчката, започнах да получавам email известяване за статуса и: “Обработва се”, “Предадено на куриер”, “Доставя се”. Дори в последнтие 2 mail-а беше вписан и номер на товарителница. Като цяло за сега съм много доволен от обслужването от Ango.

И така, зареден с оптимизъм реших да проверя дали на сайта на куриера (Speedy) няма случайно възможност за проследяване на пратката. Оптимизамът ми се отплати - наистина има проследяване на пратка по номер на товарителница. И ето, проследявам си аз пратката:

От тук разбрах, че моята пратка е приета в офис цели 6 пъти, и е изпратена от офис 2 пъти. Не е като да няма информация ;-)

Флейма на сутринта беше хакнатият сайт на Станишев. До преди половин час изглеждаше така:

Народа казва - каквото повикало, такова се обадило. Или ако сееш вятър, ще жънеш буря. Червените направиха една изключително черна предизборна кампания, която надмина дори бълванията на Атака. И двата “запомнящи се” клипа залагат на разпалване на страхове. А, както казва учителя Йода, Fear leads to anger. Anger leads to hate. Hate leads to suffering”.

Направо съм изненадан колко много се издъниха. В последните години стратегията на БСП беше да се гради младежкото крило на партията, да се привличат младите, които никога не са им били сила. (Всъщност доста добър ход в тази посока е и концерта на Любе, който организират в петък - браво.) Но с тези черни клипове, с които се опитват да наплашат “ядрото” на електората си - червените бабички - нещата изглеждат съвсем различно. Изобщо не искам да говоря и до колко са истински (как така Костов ще насече “АЕЦ Козлодуй” с брадва?). Просто самото внушение, което си е доста силно, отблъсква младите.

И ето така се е стигнало до хакването на сайта. Защото без съмнение то е направено от човек, който се е подразнил от огромният негативизъм в кампанията на “социалистите”. Изказванията на хакера са леко крайни, но всъщност казват с народни думи това, което много хора мислят.

Сещам се за малко странна аналогия - изказването на Доган преди десетина дни, което подпали позаспалата предизборна кампания. Доган не излъга, просто каза нещо, което всички знаят, ама не смеят да кажат.

BTW, браво на админите на сайта. Не знам кога е станало deface-ването, но към 9:20 сайта се върна в оригиналният си вид. От това си вадя два извода:
- имали са достатчно пресен бекъп, поздравления
- не са служители в някое министерство (за да вършат работа толкова рано…)

Ще започна с кратко припомняне към изискванията към БД при commit:
- I: преди да се случи commit, всички промени на данни са неокончателни и трябва да не се виждат от другите потребители. С други думи, за всички потребители освен мен, промените, които правя не съществуват, докато не ги потвърдя с commit
- A: не е допустимо в нито един момент половината промени да излязат видими и успешни, а другите - не. Или всичките (може и милиони) редове са променени, или нито един
- C: при commit промените, които съм направил, изведнъж започват да се виждат и да важат за другите потребители на системата. И това трябва да стане in an instant, в един момент да се видят всичките промени, които не са се виждали
- D: когато кажа commit (и БД ми потвърди, че е изпълнила командата), моите данни трябва да са наистина фиксирани на диска. Ако след една секунда спре тока, моите данни трябва вече да са окончателно записани
(Това е свободна интерпретация около изискванията за ACID транзакции, които трябва да изпълнява всяка смислена СУБД)

Една от мантрите на хората, които са запознати с начина на действие на Oracle database е, че една транзакция трябва да е толкова голяма, колкото го налага бизнес логиката. Хората, които използват някои други СУБД, се притесняват, че aко направят твърде много промени в една транзакция, че се забави фиксирането им (commit). Но това не важи в чудесният свят на Оracle.

Ще покажа с един пример от практиката (имената на главните герои са променени, за да защитя личният им живот от намесата на журналисти). Наложи ми се да претакам голям обем от данни между 2 БД, при това - през мрежата. Като цяло скоростта на прехвърляне не ми беше голям проблем, тъй процедурата се наложи еднократно. За това не съм се напъвал да оптимизирам нещата, просто ги пуснах да се случат:

  1. SQL> SET timi ON
  2. SQL> INSERT /*+ append */ INTO some_big_table
  3.   2  SELECT * FROM other_big_table@other_db
  4.   3    WHERE . . .;
  5.  
  6. 284379885 rows created
  7.  
  8. Elapsed: 01:23:12.05
  9. SQL> COMMIT;
  10.  
  11. COMMIT complete.
  12.  
  13. Elapsed: 00:00:00.71

Как се случва това?

Всъщност при commit почти няма работа, която трябва да се свърши. Благодарение на супер подлият механизъм за четене на данни в Oracle, въпреки изискването I, промените се случват върху самите данни преди да се знае дали ще се последва commit или rollback. С други думи когато insert-а вмъква данните, той не работи върху тяхно копие в някоя staging area, а наистина върши работата върху реалните данни, без да се интересува от това, че транзакцията не е завършила (освен това променя данните само в паметта, без да се интересува дали са записани на диска).

Впоследствие, при изпълнение на изискване D, commit-а също не се оглежда дали блоковете с данни, променени от транзакцията, са записани на диска. Важно е redo log buffer-а да е записан. За това моя процес хич не се занимава да помни кои блокове е променил, или да ги издирва по време на commit.

Единствената работа, която трябва да се свърши при commit, е да се запише в една система таблица края на транзакцията (т.е. един update на един ред, което удовлетворята изискванията C и A), и да се flush-не незаписаната част от redo log буфера в redo log файловете (което ни гаранитра D). Последното не е голяма хамалогия, защото rego log буфера така или иначе се записва от background process-а LGWR редовно във redo log файловете:
- на всеки 3 секунди
- ако има 1 MB незаписани данни в redo log buffer
- ако redo log buffer е пълен на 1/3 от размера си
- при всеки commit

И така, въпреки че транзакцията може да помени много гигабайти данни, при commit най-много да има 1 MB за записване. И това е в най-лошият случай: ако този 1 MB се е случил в последните 3 секунди и е нямало друг commit в тези 3 секунди. Това не е много :)

Тук, обаче, излизат няколко подробности:
- ако използвам олигофренски код (примерно, скрит в някой java framework), който прави commit при всеки единичен statement (дори и нищо да не е променил), ще разкажа играта на LGWR. Ясно защо - защото всеки commit сритва lgwr да пише. Всъщност този проблем е частично заобиколен при по-новите версии на pl/sql, но това си е материал за отделна статия
- от описанието си личи, че Oracle е проектиран за бързо и лесно commit-ване. Не така стоят нещата при rollback. Ако трябва да направя rollback на една тлъста транзакция, ще ми отнеме много време (не и в конкретния случай, защо - по-надолу). Но предвид факта, че транзакциите се правят с идеята да завършват успешно (поне в 90+ процента от случаите), бързият commit срещу бавен rollback е доба сделка. Не така стояха нещата в една информационна система, за която се сещам (писана за една държавна структура). В тази система 87% от транзакциите завършваха с rollback. Btw, програмата беше писана на java ;-)

* * *

Все пак има и ограничение за размера на транзакцията. Това ограничение е в размера на undo сегмента - той може да е произволно голям, но не и безкраен. Когато се достигне зададеното от администратора или от размера на твърдия диск ограничение за размера му (има и технологично ограничение, но то е абсурдно голямо), транзакцията гръмва и се случва автоматичен rollback. Защото БД иска винаги да е сигурна, че няма да остави данните неконсистентни.

Но… всъщност ако става дума за пренасяне на много големи по размер данни (както е в случая), има един хитър номер: подсказката /*+ append */, която съм използвал в примера. Така нещата хем стават по-бързо, хем почти не се генерира undo. Това е благодарение на механизма с гръмкото име “Direct-Path Load”. Но за това друг път, тоя постинг и без това стана безсрамно дълъг…

Любопитен факт:
Не знам дали сте забелязали, но при Oracle commit не е валидна SQL команда. В SQLPlus, както и във всеки друг инструмент за работа с данни в oracle, изразите commit и rollback се превръщат в извикване на OCI (или аналогична) функция XCTEND

Хем съм чел за тази мотика, но пак не съм я запомнил…

Правих (или преписвах) една процедура, която прехвърля данни за един месец от едн място на друго. И двете таблици (да кажем, че са source_tab и dest_tab) са partitioned, но с различна организация: source_tab има partition за всеки ден, а dest_tab е историческа и като такава е нацепена на месец (и компресирана). Така че exchange partition не ми върши работа. За това процедурата, съвсем схематично, изглежда така:

  1. ALTER INDEX dest_tab_index MODIFY PARTITION part_to_be_loaded UNUSABLE;
  2.  
  3. INSERT /*+ append */ INTO dest_tab
  4. SELECT FROM source_tab
  5. WHERE record_date BETWEEN ;
  6.  
  7. ALTER INDEX dest_tab_index REBUILD PARTITION part_to_be_loaded;
  8.  
  9. do_some_checks;
  10.  
  11. IF (transfer_is_succesfull) THEN
  12.   FOR part_names IN (the partitions FROM source_tab) LOOP
  13.     ALTER TABLE source_tab TRUNCATE PARTITION …;
  14.     DBMS_STATS.gather_table_stats(ownname => owner,
  15.                                   tabname => source_tab,
  16.                                   partname => daily_partition_name,
  17.                                   estimate_percent => NULL, – the partition is empty anyway
  18.                                   cascade => TRUE);
  19.   END LOOP;
  20.  
  21.   DBMS_STATS.gather_table_stats(ownname => owner,
  22.                                 tabname => dest_tab,
  23.                                 partname => monthly_partition_name,                                    
  24.                                 estimate_percent => 25,
  25.                                 cascade => TRUE);
  26. END IF;

Ключовият момент тук е събирането на статистиките. След truncate на всеки partition от таблицата-източник, събирам статистика за него, за да знае оптимизатора, че е празен. Това става в цикъл за всички дневни партишъни от прехвърленият месец. На края събирам статистики и за новозареденият partition в таблицата dest_tab.

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

(Сигурен съм, че който е настъпвал тази мотика, вече знае какъв е проблема)

На края реших да поогледам какво, аджеба, прави още моята процедурка. Съвсем изненадващо открих, че тя се мотае на генерирането на статистики за празните партишъни. Още по-изненадан бях, когато видях и каква заявка изпълнява - заявка за пресмятане на статистика за цялата таблица source_tab. Която си е доволно голяма.

Разковничето е в настройките по подразбиране на процедурата dbms_stats.gather_table_stats, и по-точно на стойността по подразбиране на параметъра granularity. Този параметър, според документацията, има следните стойности:

‘ALL’ - gathers all (subpartition, partition, and global) statistics

‘AUTO’- determines the granularity based on the partitioning type. This is the default value.

‘DEFAULT’ - gathers global and partition-level statistics. This option is obsolete, and while currently supported, it is included in the documentation for legacy reasons only. You should use the ‘GLOBAL AND PARTITION’ for this functionality. Note that the default value is now ‘AUTO’.

‘GLOBAL’ - gathers global statistics

‘GLOBAL AND PARTITION’ - gathers the global and partition level statistics. No subpartition level statistics are gathered even if it is a composite partitioned object.

‘PARTITION ‘- gathers partition-level statistics

‘SUBPARTITION’ - gathers subpartition-level statistics.

И така, по подразбиране, ако подадем име на partition и не подадем стойност за granularity, процедурата събира статистика за разпределението на данните в цялата таблица И в съответетеният partition. И така 30 пъти в моя цикъл.

Оправията, след като проблема е ясен, е следната:

  1. DBMS_STATS.gather_table_stats(ownname => owner,
  2.                                 tabname => source_tab,
  3.                                 partname => daily_partition_name,
  4.                                 granularity=> 'PARTITION', – !!!
  5.                                 estimate_percent => NULL,
  6.                                 cascade => TRUE);

Между другото, както се вижда, преди зареждането на данните правя partition-а на единствения non-unique индекс на dest_tab unusable и го rebuild-вам чак след наливането на данните. Според измерванията ми в конкретния случай това ми спестява около 18% от времето за зареждане, от които после 4% отиват за rebuild (прилагам и разни хватки като parallel и даже nologging). T.е. всичко става около 14% по-бързо.

Днес в любимият ми източник на непрофесионална журналистика ме посреща следното заглавие:

КАТ ни дебне вече и отзад

Ставало дума за ново оборудване в патрулките. Ама не ме питайте за какво се сетих първо… :)

Време е

Тази сутрин пристигнах в офиса и беше слънчево.

Преди 20 минути изведнъж се стъмни. Сякаш някой цъкна копчето на лампата. Изведнъж притъмня.

А сега започна и да вали. Едри капки, в комбинация със силен вятър. И се усилва - и дъжда, и вятъра.

В такива дни ми се иска да си дремя вкъщи, завит с някое леко одеалце. И да си чета някое хубаво фентъзи или фантастика.

Обаче ще бачкам. Съдба… :)

Попаднах на следната обява от родния ми “Технически университет - Габрово”

Технически университет – Габрово търси да назначи асистент по математика на постоянен трудов договор.

Кандидатите трябва да притежават образователно-квалификационната степен “магистър”. Съгласно закона за висшето образование кандидатите трябва да са не по-възрастни от 35 години. Необходими са умения в областта на линейната алгебра, аналитичната геометрия и математическият анализ.

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

Катедра “Висша математика” осигурява обучение преди започване на работа.

Документи се подават до 25 юни 2009г. За допълнителна информация…

Изрично е записано, че не ти трябват нито компютърна грамотност, нито владеене на английски език. И наистина, тези умения не са ти необходими за да преподаваш суха математика на младите студенти, дошли да се научат, примерно, на “Компютърни системи и технологии”.

В крайна сметка, кой каза, че математиката има нещо общо с компютрите?

Любопитен съм дали Nicodile може да каже нещо по въпроса ;-)

125 пъти повече

Покрай цялата дандания с евроизборите най-дълго ще помня въпроса на една баба, която интервюираха по някоя телевизия:

Аз взимам 120 лева пенсия и с нея се изхранвам. Колко гърла има един евродепутат, че да взима 15000 лева?

Много мисля над този въпрос. Нормално е да има разлика в доходите. Но тук става дума за 125 пъти (!) разлика. 12 500 процента, за любителите на статистиката. При това без да задълбаваме в допълнителните доходи на евродепутатите.

Наистина, по 125 гърла ли имат тези хора? Света ревна за високите заплати на провалилите се мениджъри. А то май не е само в банки и мега-корпорации.

Много може да си говорим за това, че излъчените от нас евродепутати не трябва да ходят голи и боси сред колегите си, ама… 125 пъти?

Ако приемем, че това са парите, с които трябва да се изхранва… наистина, колко гърла има един евродепутат?

Ако приемем, че това е заплащането за заслугите… дали е направил нещо повече от бабата с десетки години стаж? Дали е дал на света или на народа си 2, 3, 5 пъти повече от нея? Заслужил ли 10 пъти повече? А 125 пъти?

Аз също взимам добри пари (е, далеч от евродпутатска заплата, но все пак много добри). Но често се замислям за това как в търсенето на все повече и повече губим връзката с реалността. Замислям се как бих живял със 120 лева, както живеят 1/4 от българите. Или хайде, с 400-500-600 лева, с колкото живеят много хора които също като мен бачкат здраво, но не са имали късмет с избора на професия. Не са имали късмет с дарбите, ако щеш. Хора, които се изгърбват от работа в нещастен (не по тяхна вина) завод в северозападнала България.

Как бих живял с доходите на един музеен работник, какъвто е майка ми? Или с доходите на шивачка в някой шивашки цех, като леля ми? Или на продавач в сладкарница, като един мой близък приятел… който има същите нужди, каквито имам и аз.

Но разликата между мен и тези хора бледнее в сравнение с разликата между бабата и нейният представител в европейския парламент. Той дали се замисля за това с какво е заслужил тази разлика? 125 пъти…

И то на тема “Oracle Clustering” :)

Под постинга ми за ASM: Fast Mirror Resync се разрази малка, но много емоционална дискусия на тема Oracle CRS.

Там човекът, който се представя за владетел на подземното царство и не смее да застане с името си зад своите думи, ми направи показно как се води технологичен спор. Въпреки че някои неща от материята не са му много ясни (примерно не знае принципа на действие на VIP-а), успя, според думите на негов фен да ме завре в миша дупка по тема, която ми е много близко до сърцето. Това стана предимно с обиди към мен, към екипа, в който работя, към създателите на CRS и към самата технология, а не с конструктивните предложения, за които помолих. Но явно проработи, защото ето, аз се признавам за победен :)

И така, за всички, които искат да се научат да дебатират на технически теми, предлагам кратко помагало:

Относно екипа, в който работя: “някой не си е оптимизирал базата и не си е мръднал пръста за да прегледа какво прави Oracle и какви select-и се блъскат вътре”. Това е странно мнение за човек, който не е виждал кода, който се изпълнява, но е убеден, че го познава.

Относно технологиите, за кото спорим: “Oracle CRS (заместник на клъстерни решения от други vendor-и, complete FAIL)”. И още: “ASM-а е някакъв опит да се заместят storage вендор-те, което само по себе си е complete fail. Тук владетелят на подземното царство изрази много ясно и твърдо своята позиция. Още нещо: малоумието на CRS-a” - да няма неясноти относно отношението на автора.

Малко мнения за някои от големите IT компании: “за справка на некадърниците виж HP, Microsoft, Oracle със тоя CRS-а “. От тук можем да разберем колко тежък е живота на Хадес, колко страда душата му (всъщност боговете имат ли души?) от факта, че е принуден да работи с продукти, създадени от некадърници.

Ето и едно по-конкретно оплакване от CRS: “Само олигофрен би halt-нал машина…” и още “утре като се овапца нещо аз ще си троша тиквата с техните недомислици и меко казано малоумни решения на някои проблеми”. Тук отново авторът е болезнено експресивен, в желанието си да внуши на заблудения си противнуик в спора истината за обсъждания продукт.

А ето и оценката на анонимният дебатиращ за това от къде черпя информация: “На презентации и разни други fancy изпълнения, в които всичко се рисува в розови цветове съм се нагледал доста. Това е marketing crap, който един професионалист изобщо не го вълнува.”

Следват някои оценки за моят професионализъм и подготвеност по темата, върху която дебатираме: “Като за човек, който се изказва толкова компетентно по въпросите на клъстерните технологии, знаеш учудващо малко по тази тема…”. След един час Хадес установява, че аз не просто знам учудващо малко:“просто се дразня страшно много когато хора дават мнения по въпроси по които хал хабер си нямат…”. Ето и оценката за моят стил на дебатиране: “цитира разни slide-ве на разни хора, като папагал…”.

Тук Хадес обяснява отказа да застане зад своите думи: “Аз нямам кой знае какъв опит и репутация, рядко ми се налага да правя шарени презентации и да разтягам локуми. С това моето желание да споделям моите мизерни знания и наблюдения с пубнликата бяха поставени на мястото, което заслужават - в миша дупка, т.е. почти в подземното царство.

И за финал ето и едно мнение за разработчиците в Oracle: “някой дето го е пусал това няма акъл за 5 пари. С тази последна кама аз бях тотално разбит. Защото кой ще смее да защитата технология, разработена от човек с топлкова евтин ментален капацитет?

:-)

ASM: disk_repair_time

В понеделник писах за приятната възможност на ASM за Fast Mirror Resync. Тогава забравих да спомена за един параметър (също нов в 11g), който е от съществено значение за тази функционалност: disk_repair_time.

Параметъра disk_repair_time указва колко време след отпадането на един диск имаме приятната възможност за Fast Mirror Resync.

Когато даден диск отпадне от дисковата си група, ASM започва да си води сметка кои от разположените върху него extents са променени в “отсъствие” на диска. Тази информация се записва под формата на нещо като bitmap в ASM Header-а. На базата на този bitmap се прави и самият fast mirror resync когато се появи диска.

Обаче тази информация не може да се пази вечно. И вместо да се затормозяваме с някакъв синтаксис за триене на информация от тотално загинал диск, Oracle са го направили автоматично. След изтичането на определен период от време, информацията в този битмап се затрива; затрива се и всичката информация за съществуването на този диск (т.е. той се бори за загубен завинаги) - нещо като автоматичен drop disk. От това има две последствия:

- Ако успеем да възстановим диска, но това се случи след изтичането на периода, указан от disk_repair_time, той не се разпознава от системата като “свой” и трябва да се добави като нов диск с add disk
- Когато изтече периода за disk_repair_time, поради drop-ването на диска започва ребалансиране на extent-и по наличните дискове. Това може да се възпрепятства ако се настори asm_power_limit=0.

Синтаксиса за сетване на параметъра disk_repair_time e:

  1. SQL> ALTER DISKGROUP data SET ATTRIBUTE 'disk_repair_time' = '12h';
  2.  
  3. Diskgroup altered.

Проверка на текущата стойност се прави с:

  1. SELECT GROUP_NUMBER, VALUE FROM v$asm_attribute WHERE name='disk_repair_time';
  2.  
  3. GROUP_NUMBER VALUE
  4. ———— ——————————
  5.            1 12h
  6.            2 3.6h

Стойността по подразбиране, при стандартна ASM инсталация, е 3.6 часа. Тази стойност е взета от някаква статистика за средното време за отстраняване на хардуерен проблем с кабели, RAID контролери и т.н. Естествено, в България времето за доставка на един обикновен infinband кабел е поне 2 седмици (ако имаш късмет), така че това не важи за нас.

Според Oracle този параметър може да се сетне на произволно високa стойност. Това, обаче, е нож с две остриета: колкото повече време си дадем за оправяне на проблема (с последващ елементарен и бърз fast mirror resync), толкова по-дълго данните ни остават без mirror.

Older Posts »