Колко тежък е един commit
Posted in Oracle on Jun 29th, 2009
Ще започна с кратко припомняне към изискванията към БД при commit:
- I: преди да се случи commit, всички промени на данни са неокончателни и трябва да не се виждат от другите потребители. С други думи, за всички потребители освен мен, промените, които правя не съществуват, докато не ги потвърдя с commit
- A: не е допустимо в нито един момент половината промени да излязат видими и успешни, а другите - не. Или всичките (може и милиони) редове са променени, или нито един
- C: при commit промените, които съм направил, изведнъж започват да се виждат и да важат за другите потребители на системата. И това трябва да стане in an instant, в един момент да се видят всичките промени, които не са се виждали
- D: когато кажа commit (и БД ми потвърди, че е изпълнила командата), моите данни трябва да са наистина фиксирани на диска. Ако след една секунда спре тока, моите данни трябва вече да са окончателно записани
(Това е свободна интерпретация около изискванията за ACID транзакции, които трябва да изпълнява всяка смислена СУБД)
Една от мантрите на хората, които са запознати с начина на действие на Oracle database е, че една транзакция трябва да е толкова голяма, колкото го налага бизнес логиката. Хората, които използват някои други СУБД, се притесняват, че aко направят твърде много промени в една транзакция, че се забави фиксирането им (commit). Но това не важи в чудесният свят на Оracle.
Ще покажа един пример от практиката (имената на главните герои са променени за да защитя личният им живот от намесата на журналисти). Наложи ми се да претакам голям обем от данни между 2 БД, при това - през мрежата. Като цяло скоростта на прехвърляне не ми беше голям проблем, тъй процедурата се наложи еднократно. За това не съм се напъвал да оптимизирам нещата, просто ги пуснах да се случат:
SQL> set timi on
SQL> insert /*+ append */ into some_big_table
2 select * from other_big_table@other_db
3 where . . .;
284379885 rows created
Elapsed: 01:23:12.05
SQL> commit;
