Að feta í fótspor Highload++ Siberia 2019 - 8 verkefni á Oracle

РџСЂРІРμы!

Dagana 24.-25. júní var ráðstefnan Highload++ Siberia 2019 haldin í Novosibirsk. Strákarnir okkar voru þar líka skýrslu „Oracle gámagagnagrunnar (CDB/PDB) og hagnýt notkun þeirra fyrir hugbúnaðarþróun“, við munum birta textaútgáfu aðeins síðar. Það var flott, takk olegbunin fyrir samtökin, sem og alla sem komu.

Að feta í fótspor Highload++ Siberia 2019 - 8 verkefni á Oracle
Í þessari færslu viljum við deila með þér vandamálunum sem við áttum í básnum okkar svo þú getir prófað Oracle þekkingu þína. Fyrir neðan niðurskurðinn eru 8 dæmi, svarmöguleikar og útskýringar.

Hvert er hámarks raðgildi sem við munum sjá eftir að keyra eftirfarandi handrit?

create sequence s start with 1;
 
select s.currval, s.nextval, s.currval, s.nextval, s.currval
from dual
connect by level <= 5;

  • 1
  • 5
  • 10
  • 25
  • Nei, það verður villa

SvaraSamkvæmt Oracle skjölum (vitnað í 8.1.6):
Innan einni SQL yfirlýsingu mun Oracle auka röðina aðeins einu sinni í hverri röð. Ef setning inniheldur fleiri en eina tilvísun í NEXTVAL fyrir röð, hækkar Oracle röðina einu sinni og skilar sama gildi fyrir öll tilvik NEXTVAL. Ef setning inniheldur tilvísanir í bæði CURRVAL og NEXTVAL, hækkar Oracle röðina og skilar sama gildi fyrir bæði CURRVAL og NEXTVAL óháð röð þeirra innan yfirlýsingarinnar.

Þannig er hámarksgildið mun samsvara fjölda lína, það er 5.

Hversu margar línur verða í töflunni sem afleiðing af því að keyra eftirfarandi skriftu?

create table t(i integer check (i < 5));
 
create procedure p(p_from integer, p_to integer) as
begin
    for i in p_from .. p_to loop
        insert into t values (i);
    end loop;
end;
/
 
exec p(1, 3);
exec p(4, 6);
exec p(7, 9);

  • 0
  • 3
  • 4
  • 5
  • 6
  • 9

SvaraSamkvæmt Oracle skjölum (vitnað í 11.2):

Áður en SQL staðhæfing er keyrð, merkir Oracle óbeinan vistunarpunkt (ekki í boði fyrir þig). Síðan, ef staðhæfingin mistekst, veltir Oracle henni sjálfkrafa til baka og skilar viðeigandi villukóða til SQLCODE í SQLCA. Til dæmis, ef INSERT setning veldur villu með því að reyna að setja inn tvítekið gildi í einstaka vísitölu, er yfirlýsingunni snúið til baka.

Að hringja í HP frá viðskiptavininum er einnig litið á og unnið sem ein yfirlýsing. Þannig lýkur fyrsta HP símtalinu með góðum árangri, eftir að hafa sett inn þrjár færslur; annað HP símtal endar með villu og rúllar fjórðu metinu sem það náði að setja inn; þriðja símtalið mistekst, og það eru þrjú met í töflunni.

Hversu margar línur verða í töflunni sem afleiðing af því að keyra eftirfarandi skriftu?

create table t(i integer, constraint i_ch check (i < 3));
 
begin
    insert into t values (1);
    insert into t values (null);
    insert into t values (2);
    insert into t values (null);
    insert into t values (3);
    insert into t values (null);
    insert into t values (4);
    insert into t values (null);
    insert into t values (5);
exception
    when others then
        dbms_output.put_line('Oops!');
end;
/

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

SvaraSamkvæmt Oracle skjölum (vitnað í 11.2):

Ávísunarþvingun gerir þér kleift að tilgreina skilyrði sem hver röð í töflunni verður að uppfylla. Til að fullnægja takmörkunum verður hver röð í töflunni að gera skilyrðið annað hvort TRUE eða óþekkt (vegna núlls). Þegar Oracle metur stöðvunarskilyrði fyrir tiltekna línu, vísa öll dálknöfn í ástandinu til dálkgildanna í þeirri röð.

Þannig mun gildið núll standast eftirlitið og nafnlausa blokkin verður keyrð með góðum árangri þar til reynt er að setja inn gildið 3. Eftir þetta mun villumeðferðarblokkin hreinsa undantekninguna, engin afturköllun á sér stað, og það verða fjórar línur eftir í töflunni með gildi 1, null, 2 og aftur null.

Hvaða pör af gildum munu taka jafn mikið pláss í blokkinni?

create table t (
    a char(1 char),
    b char(10 char),
    c char(100 char),
    i number(4),
    j number(14),
    k number(24),
    x varchar2(1 char),
    y varchar2(10 char),
    z varchar2(100 char));
 
insert into t (a, b, i, j, x, y)
    values ('Y', 'Вася', 10, 10, 'Д', 'Вася');

  • A og X
  • B og Y
  • C og K
  • C og Z
  • K og Z
  • Ég og J
  • J og X
  • Allt skráð

SvaraHér eru brot úr skjölunum (12.1.0.2) um vistun ýmiss konar gagna í Oracle.

CHAR gagnategund
CHAR gagnategundin tilgreinir stafistreng með fastri lengd í stafasetti gagnagrunnsins. Þú tilgreinir gagnagrunnsstafasettið þegar þú býrð til gagnagrunninn þinn. Oracle tryggir að öll gildi sem geymd eru í CHAR dálki hafi þá lengd sem tilgreind er eftir stærð í merkingarfræði lengdar sem valin er. Ef þú setur inn gildi sem er styttra en dálklengdin, þá eykur Oracle gildið í dálklengd.

VARCHAR2 Gagnategund
VARCHAR2 gagnagerðin tilgreinir stafastreng með breytilegri lengd í stafasetti gagnagrunnsins. Þú tilgreinir gagnagrunnsstafasettið þegar þú býrð til gagnagrunninn þinn. Oracle geymir stafsgildi í VARCHAR2 dálki nákvæmlega eins og þú tilgreinir það, án tómrar fyllingar, að því tilskildu að gildið fari ekki yfir lengd dálksins.

NUMBER Gagnategund
NUMBER gagnategundin geymir núll sem og jákvæðar og neikvæðar fastar tölur með algildum frá 1.0 x 10-130 til en ekki með 1.0 x 10126. Ef þú tilgreinir reikniorð sem hefur algildi sem er stærra en eða jafnt og 1.0 x 10126, þá skilar Oracle villu. Hvert NUMBER gildi krefst frá 1 til 22 bæti. Að teknu tilliti til þessa er hægt að reikna dálkstærðina í bætum fyrir tiltekið tölulega gagnagildi NUMBER(p), þar sem p er nákvæmni tiltekins gildis, með eftirfarandi formúlu: ROUND((lengd(p)+s)/2))+1 þar sem s er núll ef talan er jákvæð og s er 1 ef talan er neikvæð.

Að auki skulum við taka útdrátt úr skjölunum um að geyma núllgildi.

Núll er skortur á gildi í dálki. Núll gefa til kynna vantar, óþekkt eða óviðeigandi gögn. Núll eru geymd í gagnagrunninum ef þau falla á milli dálka með gagnagildum. Í þessum tilvikum þurfa þeir 1 bæti til að geyma lengd dálksins (núll). Núll á eftir í röð þurfa enga geymslu vegna þess að nýr línuhaus gefur til kynna að dálkarnir sem eftir eru í fyrri röðinni séu núllir. Til dæmis, ef síðustu þrír dálkarnir í töflu eru núll, þá eru engin gögn geymd fyrir þessa dálka.

Byggt á þessum gögnum byggjum við rökhugsun. Við gerum ráð fyrir að gagnagrunnurinn noti AL32UTF8 kóðun. Í þessari kóðun munu rússneskir stafir taka 2 bæti.

1) A og X, gildi reits a 'Y' tekur 1 bæti, gildi reits x 'D' tekur 2 bæti
2) B og Y, 'Vasya' í b gildið verður fyllt með bilum allt að 10 stöfum og mun taka 14 bæti, 'Vasya' í d mun taka 8 bæti.
3) C og K. Báðir reitirnir hafa gildið NULL, á eftir þeim eru marktækir reitir, svo þeir taka 1 bæti.
4) C og Z. Báðir reitirnir hafa gildið NULL, en reiturinn Z er sá síðasti í töflunni, þannig að hann tekur ekki pláss (0 bæti). Reitur C tekur 1 bæti.
5) K og Z. Svipað og fyrra tilvikið. Gildið í K reitnum tekur 1 bæti, í Z – 0.
6) I og J. Samkvæmt skjölunum munu bæði gildin taka 2 bæti. Við reiknum út lengdina með því að nota formúluna sem er tekin úr skjölunum: round( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J og X. Gildið í J reitnum mun taka 2 bæti, gildið í X reitnum mun taka 2 bæti.

Alls eru réttu valkostirnir: C og K, I og J, J og X.

Hver verður um það bil þyrpingastuðull T_I vísitölunnar?

create table t (i integer);
 
insert into t select rownum from dual connect by level <= 10000;
 
create index t_i on t(i);

  • Um tugir
  • Um hundruð
  • Um þúsundir
  • Um tugi þúsunda

SvaraSamkvæmt Oracle skjölum (vitnað í 12.1):

Fyrir B-tré vísitölu mælir vísitöluþyrpingarstuðullinn líkamlega flokkun raða í tengslum við vísitölugildi.

Vísitalaklasunarstuðullinn hjálpar fínstillingu að ákveða hvort vísitöluskönnun eða heildartöfluskönnun sé skilvirkari fyrir ákveðnar fyrirspurnir). Lágur þyrpingastuðull gefur til kynna skilvirka vísitöluskönnun.

Klustunarstuðull sem er nálægt fjölda blokka í töflu gefur til kynna að línurnar séu líkamlega raðar í töflureitnum eftir vísitölulyklinum. Ef gagnagrunnurinn framkvæmir fulla töfluskönnun, þá hefur gagnagrunnurinn tilhneigingu til að sækja línurnar þar sem þær eru geymdar á diski raðað eftir vísitölulyklinum. Þyrpingastuðull sem er nálægt fjölda raða gefur til kynna að línurnar séu dreifðar af handahófi yfir gagnagrunnsblokkina í tengslum við vísitölulykilinn. Ef gagnagrunnurinn framkvæmir fulla töfluskönnun, þá myndi gagnagrunnurinn ekki sækja línur í neinni röð eftir þessum vísitölulykli.

Í þessu tilviki eru gögnin helst flokkuð, þannig að klasastuðullinn verður jafn eða nálægt fjölda upptekinna blokka í töflunni. Fyrir staðlaða blokkastærð upp á 8 kílóbæti má búast við að um þúsund þröng tölugildi passi í einn blokk, þannig að fjöldi blokka og þar af leiðandi verður klasaþátturinn um tugi.

Við hvaða gildi N verður eftirfarandi handrit keyrt með góðum árangri í venjulegum gagnagrunni með stöðluðum stillingum?

create table t (
    a varchar2(N char),
    b varchar2(N char),
    c varchar2(N char),
    d varchar2(N char));
 
create index t_i on t (a, b, c, d);

  • 100
  • 200
  • 400
  • 800
  • 1600
  • 3200
  • 6400

SvaraSamkvæmt Oracle skjölum (vitnað í 11.2):

Rökfræðileg gagnagrunnsmörk

Liður
Tegund af mörkum
Takmarksgildi

Vísitölur
Heildarstærð verðtryggðs dálks
75% af stærð gagnagrunnsblokkarinnar að frádregnum kostnaði

Þannig ætti heildarstærð verðtryggðra dálka ekki að vera meiri en 6Kb. Hvað gerist næst fer eftir völdum grunnkóðun. Fyrir AL32UTF8 kóðun getur einn stafur tekið að hámarki 4 bæti, þannig að í versta falli passa 6 kílóbæt um 1500 stafi. Þess vegna mun Oracle banna stofnun vísitölu við N = 400 (þegar lyklalengd í versta falli er 1600 stafir * 4 bæti + breiddarlengd), á meðan við N = 200 (eða minna) að búa til vísitöluna mun virka án vandræða.

INSERT stjórnandinn með APPEND vísbendingunni er hannaður til að hlaða gögnum í beinan ham. Hvað gerist ef það er sett á borðið sem kveikjan hangir á?

  • Gögnin verða hlaðin í beinni stillingu, kveikjan mun virka eins og búist var við
  • Gögnin verða hlaðin í beinni stillingu, en kveikjan verður ekki keyrð
  • Gögnin verða hlaðin í hefðbundnum ham, kveikjan mun virka eins og hún á að gera
  • Gögnin verða hlaðin í hefðbundnum ham, en kveikjan verður ekki keyrð
  • Gögnin verða ekki hlaðin, villa verður skráð

SvaraÍ grundvallaratriðum er þetta meira spurning um rökfræði. Til að finna rétta svarið myndi ég stinga upp á eftirfarandi röksemdalíkani:

  1. Innsetning í beinni stillingu er framkvæmd með beinni myndun gagnablokkar, framhjá SQL vélinni, sem tryggir mikinn hraða. Það er því mjög erfitt, ef ekki ómögulegt að tryggja framkvæmd kveikjunnar, og það er ekkert vit í þessu, þar sem það mun samt verulega hægja á innsetningunni.
  2. Ef ekki er hægt að framkvæma kveikjuna mun það leiða til þess að ef gögnin í töflunni eru þau sömu, mun ástand gagnagrunnsins í heild (aðrar töflur) ráðast af því í hvaða hátt þessi gögn voru sett inn. Þetta mun augljóslega eyðileggja gagnaheilleika og er ekki hægt að nota það sem lausn í framleiðslu.
  3. Vanhæfni til að framkvæma umbeðna aðgerð er almennt meðhöndluð sem villa. En hér ættum við að muna að APPEND er vísbending og almenn rökfræði vísbendinga er sú að tekið er tillit til þeirra ef mögulegt er, en ef ekki, er stjórnandinn keyrður án þess að taka tillit til vísbendingarinnar.

Þannig að væntanlegt svar er gögnin verða hlaðin í venjulegri (SQL) ham, kveikjan kviknar.

Samkvæmt Oracle skjölum (vitnað í 8.04):

Brot á takmörkunum munu valda því að yfirlýsingin er keyrð í röð, með hefðbundinni innskotsslóð, án viðvarana eða villuboða. Undantekning er takmörkun á yfirlýsingum sem fá aðgang að sömu töflu oftar en einu sinni í viðskiptum, sem getur valdið villuboðum.
Til dæmis, ef kveikjur eða tilvísunarheilleiki eru til staðar á borðinu, þá verður APPEND vísbendingin hunsuð þegar þú reynir að nota beinhleðslu INSERT (raðnúmer eða samhliða), sem og PARALLEL vísbendingu eða ákvæði, ef einhver er.

Hvað mun gerast þegar eftirfarandi handrit er keyrt?

create table t(i integer not null primary key, j integer references t);
 
create trigger t_a_i after insert on t for each row
declare
    pragma autonomous_transaction;
begin
    insert into t values (:new.i + 1, :new.i);
    commit;
end;
/
 
insert into t values (1, null);

  • Árangursrík frágangur
  • Bilun vegna setningafræðivillu
  • Villa: Sjálfvirk viðskipti eru ekki gild
  • Villa sem tengist því að fara yfir hámarks hreiðursímtala
  • Villa við brot á erlendum lyklum
  • Villa tengd læsingum

SvaraTaflan og kveikjan eru búin til alveg rétt og þessi aðgerð ætti ekki að leiða til vandamála. Sjálfstæð viðskipti í kveikju eru einnig leyfð, annars væri skráning ekki möguleg, til dæmis.

Eftir að fyrstu röðin var sett inn myndi vel heppnuð kveikja valda því að önnur röðin var sett inn, sem veldur því að kveikjan hleypur aftur, þriðju röðin sett inn og svo framvegis þar til yfirlýsingin mistókst vegna þess að hámarkshreiður útkalla var farið yfir. Hins vegar kemur annar lúmskur punktur við sögu. Á þeim tíma sem kveikjan er framkvæmd hefur commit ekki enn verið lokið fyrir fyrstu innsettu skrána. Þess vegna reynir kveikja sem keyrir í sjálfvirkri færslu að setja inn í töfluna línu sem vísar erlendum lykli í færslu sem hefur ekki enn verið framkvæmt. Þetta leiðir til bið (sjálfráða færslan bíður eftir að aðalfærslan skuldbindur sig til að sjá hvort hún geti sett inn gögn) og á sama tíma bíður aðalfærslan eftir að sjálfstæða færslan haldi áfram að virka eftir kveikjuna. Kyrrstaða kemur upp og þar af leiðandi er hætt við sjálfstæð viðskipti af ástæðum sem tengjast læsingum.

Aðeins skráðir notendur geta tekið þátt í könnuninni. Skráðu þig inn, takk.

Það var erfitt að?

  • Eins og tveir fingur, ákvað ég strax allt rétt.

  • Reyndar ekki, ég hafði rangt fyrir mér í nokkrum spurningum.

  • Ég leysti helminginn rétt.

  • Ég giskaði á svarið tvisvar!

  • Ég skrifa í athugasemdir

14 notendur kusu. 10 notendur sátu hjá.

Heimild: www.habr.com

Bæta við athugasemd