{"id":36171,"date":"2019-10-31T22:09:58","date_gmt":"2019-10-31T19:09:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/po-sledam-highload-siberia-2019-8-zadach-po-oracle\/"},"modified":"2019-10-31T22:09:58","modified_gmt":"2019-10-31T19:09:58","slug":"po-sledam-highload-siberia-2019-8-zadach-po-oracle","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/po-sledam-highload-siberia-2019-8-zadach-po-oracle","title":{"rendered":"Po \u015bladach Highload++ Siberia 2019 \u2014 8 zada\u0144 zwi\u0105zanych z Oracle","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Cze\u015b\u0107!<\/p>\n<p>24-25 czerwca w Nowosybirsku odby\u0142a si\u0119 konferencja Highload++ Syberia 2019. Nasi ludzie r\u00f3wnie\u017c tam byli. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.highload.ru\/siberia\/2019\/abstracts\/5211\">referat<\/a><\/noindex> \u00abKontenerowe bazy Oracle (CDB\/PDB) i ich praktyczne zastosowanie w rozwoju oprogramowania\u00bb, tekstowa wersja pojawi si\u0119 nieco p\u00f3\u017aniej. To by\u0142o super, dzi\u0119kujemy. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/olegbunin\/\" class=\"user_link\">olegbunin<\/a><\/noindex> za organizacj\u0119 oraz wszystkim, kt\u00f3rzy przyszli. <\/p>\n<p><img decoding=\"async\" alt=\"Po \u015bladach Highload++ Siberia 2019 \u2014 8 zada\u0144 zwi\u0105zanych z Oracle\" src=\"\/wp-content\/uploads\/2019\/07\/27f4707d4bb5968eaaa5c4748ff467cd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nW tym po\u015bcie chcieliby\u015bmy podzieli\u0107 si\u0119 z Wami zadaniami, kt\u00f3re by\u0142y na naszym stoisku, aby\u015bcie mogli sprawdzi\u0107 swoj\u0105 wiedz\u0119 na temat Oracle. Poni\u017cej \u2013 8 zada\u0144, opcje odpowiedzi i wyja\u015bnienie.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Jak\u0105 maksymaln\u0105 warto\u015b\u0107 sekwencji zobaczymy w wyniku wykonania nast\u0119puj\u0105cego skryptu?<\/h3>\n<p><\/p>\n<pre><code class=\"sql\">create sequence s start with 1;\n \nselect s.currval, s.nextval, s.currval, s.nextval, s.currval\nfrom dual\nconnect by level &lt;= 5;\n<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>1<\/li>\n<li>5<\/li>\n<li>10<\/li>\n<li>25<\/li>\n<li>\u017badn\u0105, wyst\u0105pi b\u0142\u0105d.<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>Zgodnie z dokumentacj\u0105 Oracle (cytowane z 8.1.6):<br \/>\nW ramach pojedynczego zapytania SQL, Oracle zwi\u0119kszy sekwencj\u0119 tylko raz na ka\u017cdy wiersz. Je\u015bli zapytanie zawiera wi\u0119cej ni\u017c jedno odniesienie do NEXTVAL w sekwencji, Oracle zwi\u0119ksza sekwencj\u0119 tylko raz i zwraca t\u0119 sam\u0105 warto\u015b\u0107 dla wszystkich wyst\u0105pie\u0144 NEXTVAL. Je\u015bli zapytanie zawiera odniesienia zar\u00f3wno do CURRVAL, jak i NEXTVAL, Oracle zwi\u0119ksza sekwencj\u0119 i zwraca t\u0119 sam\u0105 warto\u015b\u0107 dla CURRVAL i NEXTVAL, niezale\u017cnie od ich kolejno\u015bci w zapytaniu.<\/p>\n<p>W ten spos\u00f3b, <b>maksymalna warto\u015b\u0107 b\u0119dzie odpowiada\u0107 liczbie wierszy, czyli 5.<\/b>.<\/p>\n<h3>Ile wierszy znajdzie si\u0119 w tabeli w wyniku wykonania nast\u0119puj\u0105cego skryptu?<\/h3>\n<p><\/p>\n<pre><code class=\"sql\">create table t(i integer check (i &lt; 5));\n \ncreate procedure p(p_from integer, p_to integer) as\nbegin\n    for i in p_from .. p_to loop\n        insert into t values (i);\n    end loop;\nend;\n\/\n \nexec p(1, 3);\nexec p(4, 6);\nexec p(7, 9);<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>0<\/li>\n<li>3<\/li>\n<li>4<\/li>\n<li>5<\/li>\n<li>6<\/li>\n<li>9<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>Zgodnie z dokumentacj\u0105 Oracle (cytowane z 11.2):<\/p>\n<p>Przed wykonaniem jakiegokolwiek zapytania SQL, Oracle oznacza niejawny punkt zapisu (niedost\u0119pny dla Ciebie). Nast\u0119pnie, je\u015bli zapytanie zako\u0144czy si\u0119 niepowodzeniem, Oracle automatycznie cofa je i zwraca stosowny kod b\u0142\u0119du do SQLCODE w SQLCA. Na przyk\u0142ad, je\u015bli zapytanie INSERT powoduje b\u0142\u0105d, pr\u00f3buj\u0105c wstawi\u0107 duplikat warto\u015bci w unikalnym indeksie, zapytanie jest cofane.<\/p>\n<p>Zg\u0142oszenie procedury sk\u0142adowanej z klienta jest r\u00f3wnie\u017c traktowane i przetwarzane jako pojedyncze zapytanie. W ten spos\u00f3b pierwsze wywo\u0142anie procedury sk\u0142adowanej ko\u0144czy si\u0119 pomy\u015blnie, wstawiaj\u0105c trzy rekordy; drugie wywo\u0142anie procedury sk\u0142adowanej ko\u0144czy si\u0119 b\u0142\u0119dem i cofa czwarty rekord, kt\u00f3ry uda\u0142o si\u0119 wstawi\u0107; trzecie wywo\u0142anie ko\u0144czy si\u0119 b\u0142\u0119dem, <b>a w tabeli znajduj\u0105 si\u0119 trzy rekordy.<\/b>.<\/p>\n<h3>Ile wierszy znajdzie si\u0119 w tabeli w wyniku wykonania nast\u0119puj\u0105cego skryptu?<\/h3>\n<p><\/p>\n<pre><code class=\"sql\">create table t(i integer, constraint i_ch check (i &lt; 3));\n \nbegin\n    insert into t values (1);\n    insert into t values (null);\n    insert into t values (2);\n    insert into t values (null);\n    insert into t values (3);\n    insert into t values (null);\n    insert into t values (4);\n    insert into t values (null);\n    insert into t values (5);\nexception\n    when others then\n        dbms_output.put_line(&#039;Ups!&#039;);\nend;\n\/<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>1<\/li>\n<li>2<\/li>\n<li>3<\/li>\n<li>4<\/li>\n<li>5<\/li>\n<li>6<\/li>\n<li>7<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>Zgodnie z dokumentacj\u0105 Oracle (cytowane z 11.2):<\/p>\n<p>Ograniczenie sprawdzaj\u0105ce pozwala okre\u015bli\u0107 warunek, kt\u00f3ry ka\u017cda linia w tabeli musi spe\u0142nia\u0107. Aby spe\u0142ni\u0107 to ograniczenie, ka\u017cda linia w tabeli musi spe\u0142nia\u0107 warunek jako PRAWDA lub nieznany (z powodu warto\u015bci null). Kiedy Oracle ocenia warunek ograniczenia sprawdzaj\u0105cego dla okre\u015blonej linii, jakiekolwiek nazwy kolumn wyst\u0119puj\u0105ce w warunku odnosz\u0105 si\u0119 do warto\u015bci kolumn w tej linii.<\/p>\n<p>W ten spos\u00f3b warto\u015b\u0107 null przejdzie sprawdzenie, a anonimowy blok b\u0119dzie wykonywany pomy\u015blnie do momentu pr\u00f3by wstawienia warto\u015bci 3. Po tym bloku obs\u0142ugi b\u0142\u0119d\u00f3w b\u0142\u0105d zostanie zgaszony, nie b\u0119dzie rollbacku i <b>w tabeli pozostan\u0105 cztery linie<\/b> z warto\u015bciami 1, null, 2 i znowu null.<\/p>\n<h3>Jakie pary warto\u015bci zajm\u0105 t\u0119 sam\u0105 ilo\u015b\u0107 miejsca w bloku?<\/h3>\n<p><\/p>\n<pre><code class=\"sql\">create table t (\n    a char(1 char),\n    b char(10 char),\n    c char(100 char),\n    i number(4),\n    j number(14),\n    k number(24),\n    x varchar2(1 char),\n    y varchar2(10 char),\n    z varchar2(100 char));\n \ninsert into t (a, b, i, j, x, y)\n    values ('Y', 'W\u0142adzio', 10, 10, 'D', 'W\u0142adzio');\n<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>A i X<\/li>\n<li>B i Y<\/li>\n<li>C i K<\/li>\n<li>C i Z<\/li>\n<li>K i Z<\/li>\n<li>I i J<\/li>\n<li>J i X<\/li>\n<li>Wszystkie wymienione<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>Przedstawiamy fragmenty dokumentacji (12.1.0.2) dotycz\u0105ce przechowywania r\u00f3\u017cnych typ\u00f3w danych w Oracle.<\/p>\n<p><b>Typ danych CHAR<\/b><br \/>\nTyp danych CHAR okre\u015bla \u0142a\u0144cuch znakowy o sta\u0142ej d\u0142ugo\u015bci w zestawie znak\u00f3w bazy danych. Podczas tworzenia bazy danych okre\u015blasz zestaw znak\u00f3w bazy danych. Oracle zapewnia, \u017ce wszystkie warto\u015bci przechowywane w kolumnie CHAR maj\u0105 d\u0142ugo\u015b\u0107 okre\u015blon\u0105 przez rozmiar w wybranej semantyce d\u0142ugo\u015bci. Je\u015bli wstawisz warto\u015b\u0107, kt\u00f3ra jest kr\u00f3tsza od d\u0142ugo\u015bci kolumny, Oracle dope\u0142ni warto\u015b\u0107 spacjami do d\u0142ugo\u015bci kolumny.<\/p>\n<p><b>Typ danych VARCHAR2<\/b><br \/>\nTyp danych VARCHAR2 okre\u015bla \u0142a\u0144cuch znakowy o zmiennej d\u0142ugo\u015bci w zestawie znak\u00f3w bazy danych. Podczas tworzenia bazy danych okre\u015blasz zestaw znak\u00f3w bazy danych. Oracle przechowuje warto\u015b\u0107 znakow\u0105 w kolumnie VARCHAR2 dok\u0142adnie tak, jak j\u0105 podajesz, bez dope\u0142niania spacjami, pod warunkiem, \u017ce warto\u015b\u0107 nie przekracza d\u0142ugo\u015bci kolumny.<\/p>\n<p><b>Typ danych NUMBER<\/b><br \/>\nTyp danych NUMBER przechowuje zera, a tak\u017ce pozytywne i ujemne liczby sta\u0142e o warto\u015bciach bezwzgl\u0119dnych od 1.0 x 10-130 do, ale nie w\u0142\u0105czaj\u0105c 1.0 x 10126. Je\u015bli okre\u015blisz wyra\u017cenie arytmetyczne, kt\u00f3rego warto\u015b\u0107 ma warto\u015b\u0107 bezwzgl\u0119dn\u0105 wi\u0119ksz\u0105 lub r\u00f3wn\u0105 1.0 x 10126, Oracle zwraca b\u0142\u0105d. Ka\u017cda warto\u015b\u0107 NUMBER wymaga od 1 do 22 bajt\u00f3w. Bior\u0105c to pod uwag\u0119, rozmiar kolumny w bajtach dla konkretnej liczbowej warto\u015bci danych NUMBER(p), gdzie p jest dok\u0142adno\u015bci\u0105 danej warto\u015bci, mo\u017cna obliczy\u0107 za pomoc\u0105 nast\u0119puj\u0105cego wzoru: <i>ROUND((length(p)+s)\/2))+1<\/i> gdzie s wynosi zero, je\u015bli liczba jest dodatnia, a s wynosi 1, je\u015bli liczba jest ujemna.<\/p>\n<p>Ponadto, zaprezentujmy fragment dokumentacji dotycz\u0105cy przechowywania warto\u015bci Null.<\/p>\n<p>Warto\u015b\u0107 null oznacza brak warto\u015bci w kolumnie. Null wskazuje na brakuj\u0105ce, nieznane lub nieodpowiednie dane. Nulls s\u0105 przechowywane w bazie danych, je\u015bli znajduj\u0105 si\u0119 mi\u0119dzy kolumnami z warto\u015bciami danych. W takich przypadkach wymagaj\u0105 1 bajta do przechowywania d\u0142ugo\u015bci kolumny (zero). Ostatnie nulls w wierszu nie wymagaj\u0105 przechowywania, poniewa\u017c nowy nag\u0142\u00f3wek wiersza sygnalizuje, \u017ce pozosta\u0142e kolumny w poprzednim wierszu s\u0105 null. Na przyk\u0142ad, je\u015bli ostatnie trzy kolumny w tabeli s\u0105 null, to dla tych kolumn nie s\u0105 przechowywane \u017cadne dane.<\/p>\n<p>Na podstawie tych danych budujemy rozwa\u017cania. Zak\u0142adamy, \u017ce w bazie danych u\u017cywana jest kodowanie AL32UTF8. W tym kodowaniu rosyjskie litery zajm\u0105 2 bajty.<\/p>\n<p>1) A i X, warto\u015b\u0107 pola a 'Y' zajmuje 1 bajt, warto\u015b\u0107 pola x '\u0414' \u2013 2 bajty<br \/>\n2) B i Y, \u2018Wania\u2019 w b zostanie uzupe\u0142nione spacjami do 10 znak\u00f3w i zajmie 14 bajt\u00f3w, \u2018Wania\u2019 w d \u2013 zajmie 8 bajt\u00f3w.<br \/>\n3) C i K. Oba pola maj\u0105 warto\u015b\u0107 NULL, po nich znajduj\u0105 si\u0119 znacz\u0105ce pola, dlatego zajmuj\u0105 po 1 bajcie.<br \/>\n4) C i Z. Oba pola maj\u0105 warto\u015b\u0107 NULL, ale pole Z jest ostatnie w tabeli, dlatego nie zajmuje miejsca (0 bajt\u00f3w). Pole C zajmuje 1 bajt.<br \/>\n5) K i Z. Podobnie jak w poprzednim przypadku. Warto\u015b\u0107 w polu K zajmuje 1 bajt, w Z \u2013 0.<br \/>\n6) I i J. Zgodnie z dokumentacj\u0105, obie warto\u015bci zajm\u0105 po 2 bajty. D\u0142ugo\u015b\u0107 obliczamy wed\u0142ug wzoru podanego w dokumentacji: round( (1 + 0)\/2) +1 = 1 + 1 = 2.<br \/>\n7) J i X. Warto\u015b\u0107 w polu J zajmie 2 bajty, a warto\u015b\u0107 w polu X zajmie 2 bajty.<\/p>\n<p><b>Podsumowuj\u0105c, poprawne pary to: C i K, I i J, J i X.<\/b><\/p>\n<p><\/p>\n<h3>Jaki b\u0119dzie przybli\u017cony clustering factor indeksu T_I?<\/h3>\n<p><\/p>\n<pre><code class=\"sql\">create table t (i integer);\n \ninsert into t select rownum from dual connect by level &lt;= 10000;\n \ncreate index t_i on t(i);\n<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>Rz\u0119dy dziesi\u0105tek<\/li>\n<li>Rz\u0119dy setek<\/li>\n<li>Rz\u0119dy tysi\u0119cy<\/li>\n<li>Rz\u0119dy dziesi\u0105tek tysi\u0119cy<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>Zgodnie z dokumentacj\u0105 Oracle (cytowane z 12.1):<\/p>\n<p>Dla indeksu B-drzewiastego, clustering factor indeksu mierzy fizyczne grupowanie wierszy w stosunku do warto\u015bci indeksu.<\/p>\n<p>Clustering factor pomaga optymalizatorowi zdecydowa\u0107, czy skanowanie indeksu, czy pe\u0142ne skanowanie tabeli jest bardziej efektywne dla niekt\u00f3rych zapyta\u0144. Niski clustering factor oznacza wydajne skanowanie indeksu.<\/p>\n<p>Clustering factor bliski liczbie blok\u00f3w w tabeli oznacza, \u017ce wiersze s\u0105 fizycznie uporz\u0105dkowane w blokach tabeli wed\u0142ug klucza indeksu. Je\u015bli baza danych wykonuje pe\u0142ne skanowanie tabeli, wtedy tendencja jest, aby pobiera\u0107 wiersze w kolejno\u015bci, w jakiej s\u0105 przechowywane na dysku posortowane wed\u0142ug klucza indeksu. Clustering factor bliski liczbie wierszy oznacza, \u017ce wiersze s\u0105 przypadkowo rozsiane po blokach bazy danych w stosunku do klucza indeksu. Je\u015bli baza danych wykonuje pe\u0142ne skanowanie tabeli, wtedy wiersze nie b\u0119d\u0105 pobierane w \u017cadnej posortowanej kolejno\u015bci wed\u0142ug tego klucza indeksu.<\/p>\n<p>W tym przypadku dane s\u0105 idealnie posortowane, dlatego clustering factor b\u0119dzie r\u00f3wny lub bliski liczbie zaj\u0119tych blok\u00f3w w tabeli. Dla standardowego rozmiaru bloku wynosz\u0105cego 8 kilobajt\u00f3w mo\u017cna oczekiwa\u0107, \u017ce w jednym bloku zmie\u015bci si\u0119 oko\u0142o tysi\u0105ca ciasnych warto\u015bci number, dlatego liczba blok\u00f3w, a co za tym idzie clustering factor, b\u0119dzie <b>rz\u0119dami dziesi\u0105tek<\/b>.<\/p>\n<h3>Jakie warto\u015bci N spowoduj\u0105, \u017ce poni\u017cszy skrypt zostanie pomy\u015blnie wykonany w standardowej bazie danych z domy\u015blnymi ustawieniami?<\/h3>\n<p><\/p>\n<pre><code class=\"sql\">create table t (\n    a varchar2(N char),\n    b varchar2(N char),\n    c varchar2(N char),\n    d varchar2(N char));\n \ncreate index t_i on t (a, b, c, d);\n<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>100<\/li>\n<li>200<\/li>\n<li>400<\/li>\n<li>800<\/li>\n<li>1600<\/li>\n<li>3200<\/li>\n<li>6400<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>Zgodnie z dokumentacj\u0105 Oracle (cytowane z 11.2):<\/p>\n<p>Logiczne limity bazy danych<\/p>\n<p><strong>Pozycja<\/strong><br \/>\n<strong>Typ limitu<\/strong><br \/>\n<strong>Warto\u015b\u0107 limitu<\/strong><\/p>\n<p>Indeksy<br \/>\nCa\u0142kowity rozmiar indeksowanej kolumny<br \/>\n75% rozmiaru bloku bazy danych minus pewne narzuty<\/p>\n<p>\nTak wi\u0119c ca\u0142kowity rozmiar indeksowanych kolumn nie powinien przekracza\u0107 6KB. Dalsze zale\u017cy od wybranej kompresji bazy. Dla kompresji AL32UTF8 jeden znak mo\u017ce zajmowa\u0107 maksymalnie 4 bajty, wi\u0119c w 6 kilobajtach w najgorszym przypadku zmie\u015bci si\u0119 oko\u0142o 1500 znak\u00f3w. Dlatego Oracle zabroni tworzenia indeksu przy N = 400 (gdy d\u0142ugo\u015b\u0107 klucza w najgorszym przypadku wyniesie 1600 znak\u00f3w * 4 bajty + d\u0142ugo\u015b\u0107 rowid), podczas gdy <b>przy N = 200 (i mniej)<\/b> tworzenie indeksu zadzia\u0142a bez problem\u00f3w.<\/p>\n<h3>Operator INSERT z hintem APPEND s\u0142u\u017cy do \u0142adowania danych w trybie direct. Co si\u0119 stanie, je\u015bli zostanie zastosowany do tabeli, na kt\u00f3rej jest wyzwalacz?<\/h3>\n<p><\/p>\n<ul>\n<li>Dane zostan\u0105 za\u0142adowane w trybie direct, wyzwalacz zadzia\u0142a tak, jak powinien.<\/li>\n<li>Dane zostan\u0105 za\u0142adowane w trybie direct, ale wyzwalacz nie zostanie uruchomiony.<\/li>\n<li>Dane zostan\u0105 za\u0142adowane w trybie conventional, wyzwalacz zadzia\u0142a tak, jak powinien.<\/li>\n<li>Dane zostan\u0105 za\u0142adowane w trybie conventional, ale wyzwalacz nie zostanie uruchomiony.<\/li>\n<li>Dane nie b\u0119d\u0105 za\u0142adowane, zostanie zg\u0142oszony b\u0142\u0105d.<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>W zasadzie to pytanie bardziej dotycz\u0105ce logiki. Aby znale\u017a\u0107 prawid\u0142ow\u0105 odpowied\u017a, zaproponowa\u0142bym nast\u0119puj\u0105cy model rozumowania:<\/p>\n<ol>\n<li>Wstawienie w trybie direct realizowane jest poprzez bezpo\u015brednie formowanie bloku danych, omijaj\u0105c silnik SQL, co zapewnia du\u017c\u0105 pr\u0119dko\u015b\u0107. Dlatego trudno jest zapewni\u0107 uruchomienie wyzwalacza, je\u015bli w og\u00f3le jest to mo\u017cliwe, i nie ma sensu, poniewa\u017c i tak znacznie spowolni\u0142by wstawienie.<\/li>\n<li>Nieuruchomienie wyzwalacza spowoduje, \u017ce w przypadku identycznych danych w tabeli, stan bazy jako ca\u0142o\u015b\u0107 (innych tabel) b\u0119dzie zale\u017ca\u0142 od tego, w jakim trybie zosta\u0142y te dane wstawione. Oczywiste jest, \u017ce zrujnowa\u0142oby to integralno\u015b\u0107 danych i nie mo\u017ce by\u0107 stosowane jako rozwi\u0105zanie w produkcji.<\/li>\n<li>Niemo\u017cno\u015b\u0107 wykonania \u017c\u0105danej operacji, og\u00f3lnie m\u00f3wi\u0105c, traktuje si\u0119 jako b\u0142\u0105d. Nale\u017cy jednak pami\u0119ta\u0107, \u017ce APPEND to hint, a og\u00f3lna logika hint\u00f3w polega na tym, \u017ce s\u0105 one brane pod uwag\u0119, je\u015bli to mo\u017cliwe, je\u015bli nie, to operator jest wykonywany bez uwzgl\u0119dnienia hintu.<\/li>\n<\/ol>\n<p>\nZatem oczekiwana odpowied\u017a to <b>dane zostan\u0105 za\u0142adowane w zwyk\u0142ym (SQL) trybie, wyzwalacz zadzia\u0142a.<\/b><\/p>\n<p>Zgodnie z dokumentacj\u0105 Oracle (cytowanej z 8.04):<\/p>\n<p>Naruszenia ogranicze\u0144 spowoduj\u0105, \u017ce polecenie zostanie wykonane szeregowo, korzystaj\u0105c z konwencjonalnej \u015bcie\u017cki wstawiania, bez ostrze\u017ce\u0144 ani komunikat\u00f3w o b\u0142\u0119dach. Wyj\u0105tkiem jest ograniczenie dotycz\u0105ce polece\u0144 uzyskuj\u0105cych dost\u0119p do tej samej tabeli wi\u0119cej ni\u017c raz w transakcji, co mo\u017ce spowodowa\u0107 komunikaty o b\u0142\u0119dach.<br \/>\nNa przyk\u0142ad, je\u015bli w tabeli wyst\u0119puj\u0105 wyzwalacze lub integralno\u015b\u0107 referencyjna, wskaz\u00f3wka APPEND zostanie zignorowana podczas pr\u00f3by u\u017cycia bezpo\u015bredniego wstawiania INSERT (szeregowego lub r\u00f3wnoleg\u0142ego), jak r\u00f3wnie\u017c wskaz\u00f3wka lub klauzula PARALLEL, o ile to mo\u017cliwe.<\/p>\n<h3>Co si\u0119 stanie podczas wykonania nast\u0119puj\u0105cego skryptu?<\/h3>\n<p><\/p>\n<pre><code class=\"sql\">create table t(i integer not null primary key, j integer references t);\n \ncreate trigger t_a_i after insert on t for each row\ndeclare\n    pragma autonomous_transaction;\nbegin\n    insert into t values (:new.i + 1, :new.i);\n    commit;\nend;\n\/\n \ninsert into t values (1, null);\n<\/code><\/pre>\n<p><\/p>\n<ul>\n<li>Wykonanie zako\u0144czone sukcesem<\/li>\n<li>B\u0142\u0105d z powodu b\u0142\u0119du sk\u0142adniowego<\/li>\n<li>B\u0142\u0105d zwi\u0105zany z niedopuszczalno\u015bci\u0105 transakcji autonomicznych<\/li>\n<li>B\u0142\u0105d zwi\u0105zany z przekroczeniem maksymalnej g\u0142\u0119boko\u015bci wywo\u0142a\u0144<\/li>\n<li>B\u0142\u0105d zwi\u0105zany z naruszeniem klucza obcego<\/li>\n<li>B\u0142\u0105d zwi\u0105zany z blokadami<\/li>\n<\/ul>\n<p>\n<b class=\"spoiler_title\">Odpowied\u017a<\/b>Tabela i wyzwalacz s\u0105 tworzone w pe\u0142ni poprawnie i ta operacja nie powinna prowadzi\u0107 do problem\u00f3w. Transakcje autonomiczne w wyzwalaczu s\u0105 r\u00f3wnie\u017c dozwolone, w przeciwnym razie niemo\u017cliwe by\u0142oby na przyk\u0142ad logowanie.<\/p>\n<p>Po wstawieniu pierwszego wiersza skuteczne uruchomienie wyzwalacza spowodowa\u0142oby wstawienie drugiego wiersza, co ponownie uruchomi\u0142oby wyzwalacz, wstawiaj\u0105c trzeci wiersz i tak dalej, a\u017c do momentu, gdy zapytanie nie zako\u0144czy\u0142oby si\u0119 z powodu przekroczenia maksymalnej g\u0142\u0119boko\u015bci wywo\u0142a\u0144. Jednak, pojawia si\u0119 jeszcze jeden subtelny moment. W momencie wykonywania wyzwalacza dla pierwszego wstawionego rekordu commit jeszcze nie zosta\u0142 wykonany. Dlatego wyzwalacz, dzia\u0142aj\u0105cy w transakcji autonomicznej, pr\u00f3bowa\u0142by wstawi\u0107 do tabeli wiersz, kt\u00f3ry odnosi si\u0119 przez klucz obcy do jeszcze nie zatwierdzonego rekordu. To prowadzi do oczekiwania (transakcja autonomiczna czeka na commit g\u0142\u00f3wnej, aby okre\u015bli\u0107, czy mo\u017cna wstawi\u0107 dane) i jednocze\u015bnie g\u0142\u00f3wna transakcja czeka na commit autonomicznej, aby kontynuowa\u0107 dzia\u0142anie po wyzwalaczu. <b>Wyst\u0119puje deadlock i w konsekwencji \u2013 transakcja autonomiczna jest anulowana z powodu problem\u00f3w zwi\u0105zanych z blokadami.<\/b>.<\/p>\n<p class=\"for_users_only_msg\">Tylko zarejestrowani u\u017cytkownicy mog\u0105 bra\u0107 udzia\u0142 w ankiecie. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Zaloguj si\u0119<\/a><\/noindex>, prosz\u0119.<\/p>\n<h2 class=\"default-block__polling-title\">By\u0142o trudno?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Jak dwa palce w nos, od razu wszystko rozwi\u0105za\u0142em poprawnie.<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Nie za bardzo, pomyli\u0142em si\u0119 w kilku pytaniach.<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Rozwi\u0105za\u0142em po\u0142ow\u0119 poprawnie.<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Dwa razy zgad\u0142em odpowied\u017a!<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Napisz\u0119 w komentarzach<\/p>\n<\/li>\n<\/ul>\n<p>    Zag\u0142osowa\u0142o 14 u\u017cytkownik\u00f3w. Wstrzyma\u0142o si\u0119 10 u\u017cytkownik\u00f3w.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/sportmaster_lab\/blog\/459680\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442! 24-25 \u0438\u044e\u043d\u044f \u0432 \u041d\u043e\u0432\u043e\u0441\u0438\u0431\u0438\u0440\u0441\u043a\u0435 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f Highload++ Siberia 2019. \u041d\u0430\u0448\u0438 \u0440\u0435\u0431\u044f\u0442\u0430 \u0442\u043e\u0436\u0435 \u0442\u0430\u043c \u0431\u044b\u043b\u0438 \u0434\u043e\u043a\u043b\u0430\u0434\u043e\u043c \u00ab\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043d\u044b\u0435 \u0431\u0430\u0437\u044b Oracle (CDB\/PDB) \u0438 \u0438\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u041f\u041e\u00bb, \u043c\u044b \u0432\u044b\u043b\u043e\u0436\u0438\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0437\u0436\u0435. \u0411\u044b\u043b\u043e \u043a\u0440\u0443\u0442\u043e, \u0441\u043f\u0430\u0441\u0438\u0431\u043e olegbunin \u0437\u0430 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0441\u0435\u043c, \u043a\u0442\u043e \u043f\u0440\u0438\u0448\u0451\u043b. \u0412 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":27053,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-36171","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442! 24-25 \u0438\u044e\u043d\u044f \u0432 \u041d\u043e\u0432\u043e\u0441\u0438\u0431\u0438\u0440\u0441\u043a\u0435 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f Highload++ Siberia 2019.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/po-sledam-highload-siberia-2019-8-zadach-po-oracle\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u043e \u0441\u043b\u0435\u0434\u0430\u043c Highload++ Siberia 2019 \u2014 8 \u0437\u0430\u0434\u0430\u0447 \u043f\u043e Oracle | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442! 24-25 \u0438\u044e\u043d\u044f \u0432 \u041d\u043e\u0432\u043e\u0441\u0438\u0431\u0438\u0440\u0441\u043a\u0435 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f Highload++ Siberia 2019.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/po-sledam-highload-siberia-2019-8-zadach-po-oracle\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:09:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:09:58+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47 \u015bladami Highload++ Siberia 2019 \u2014 8 zada\u0144 z Oracle | ProHoster","description":"Cze\u015b\u0107! 24-25 czerwca w Nowosybirsku odby\u0142a si\u0119 konferencja Highload++ Siberia 2019.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/po-sledam-highload-siberia-2019-8-zadach-po-oracle","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u043e \u0441\u043b\u0435\u0434\u0430\u043c Highload++ Siberia 2019 \u2014 8 \u0437\u0430\u0434\u0430\u0447 \u043f\u043e Oracle | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442! 24-25 \u0438\u044e\u043d\u044f \u0432 \u041d\u043e\u0432\u043e\u0441\u0438\u0431\u0438\u0440\u0441\u043a\u0435 \u043f\u0440\u043e\u0448\u043b\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f Highload++ Siberia 2019.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/po-sledam-highload-siberia-2019-8-zadach-po-oracle","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:09:58+00:00","article:modified_time":"2019-10-31T19:09:58+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"36171","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 02:18:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:49:43","updated":"2026-01-22 02:18:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/36171","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=36171"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/36171\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/27053"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=36171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=36171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=36171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}