10. januar 2002 - 11:59Der er
23 kommentarer og 3 løsninger
temp_segment
Når man laver et snapshot af en tabel som (inclusiv indexes) fylder ca. 15 gigabytes, hvor meget vil det temporære tablespace som snapshotet bliver lagt over i fylde:
Grunden til at jeg spørger er at jeg får fejl:
ORA-01652: unable to extend temp segment by in tablespace ORA-02063: preceding line from KOPI
I alt har jeg brug for at lave et snapshot af en hel database, som i alt fylder ca. 40 gigabytes.
Er der nogen som kender en løsning?
Løsningen kan ikke gå på en eksport da jeg har lavet triggere som genererer data til afledte felter.
Der findes desværre ikke en SQLUNLOAD, men EXPORT kunne måske bruges. Og så kan du bruge IMPORT til at \"loade\" med i et andet schema (i.e. bruger). Men jeg tror altså ikke at du kan klare dig med færre temp segmenter af den grund, men du kan da prøve.
I det tabeller jeg skal oversøre data til genererer jeg selv data til afledte felter (med en trigger) Ville denne trigger \'fyre\' hvis jeg importerer data til de omhandlende tabeller?
Det er umuligt at sige hvor meget temp der vil blive brugt ved en snapshot. Det afhænger af hvor meget plads index genereringen kræver. Det er en kæmpe sorteringsopgave at lave et index = meget temp. Men hvis du sørger for at indexet er på tabellen og inserter i klynger + commiter imellem, vil din temp blive frigivet. Er du sikker på at de temp tablespace har status temporary ?
Har du sørget for at initial og next står til det samme ? f.eks. 50 mb ? Procent increase skal stå til 0 !!! Altid!
Hvis du vælger at bruge sql*loader med direct path, opnår du en meget hurtig insert som ikke genererer redo.
Jeg prøvede at bruge sql*loader med følgende ctl og dat fil:
ctl - fil:
Load Data INFILE \'file=c:\\orant\\bin\\PDV_TYPE_MODELE_CARTE.dat\' INSERT INTO TABLE PDV_TYPE_MODELE_CARTE FIELDS TERMINATED BY \";\" OPTIONALLY ENCLOSED BY \'\"\' (ID_TYPE_CARTE INTEGER, LIBELLE_TYPE_CARTE CHAR)
Hvis det er muligt at tage en kopi af din tabel og tømme orginalen kan du lave en PL/SQL procedure der indsætter 1000 rækker mellem hvert commit på den måde kan du opbygge din snapshot stille og roligt unden at bruge ret meget temp plads
Det Coily siger er til dels rigtigt. Det bruges ved en normal insert.
Men her er det sqlloader, så der gælder lidt andet. Du skal prøve med en anden delimiter. Prøv f.eks. med \'|\' ... det er så sjældent at den indgår i ens data.
Jeg forstår stadig ikke hvorfor du ikke bruger det jeg foreslår længere oppe. Lav din tabel .. Sæt index på. Import dine data med INDEXES=N
På den måde vil dit index ikke kræve så meget temp, da den ikke skal lave en stor sortering, men indsætter efterhånden. At dit index så måske skal rebuildes bagefter... det er en anden sag. Alter index blabla rebuild ;
Det kunne lyde som at pnielsen forslag er mere fornuftigt. Jeg satte i går, ved 14 tiden, serveren i gang med at lave csv-filen og den var ikke færdig her til morgen kl. 4:00. (Kan det være rigtigt at det skal tage så lang tid? - min tabel indeholder godt nok 52 felter og fylder ca. 16 gigabytes - men alligevel?)
Når jeg laver min eksport hvor meget skal jeg så eksportere?
· Grants · Indexes · Rows · Constraints
Ved overførslen skal data til afledte felter genereres, til hvilket jeg har lavet triggers som fungerer. Jeg ved godt jeg har spurgt før, men er der nogen af jer der med sikkerhed ved om de vil fyre ved en import?
Min \"gamle\" tabel ligger på en anden databaseserver. Min nye tabel skal være en tro kopi, blot med afledte felter. Tabellen hedder \"PDV_ABONNEMENT_CARTE\" og jeg har lavet et databaselink til den \"gamle\" som hedder \"KOPI\". Mit spørgsmål er så om man kan følgende?
create table PDV_ABONNEMENT_CARTE as select * from PDV_ABONNEMENT_CARTE@KOPI where 1=0; - Hvad betyder det?
Create index.. - Er det indexet på min nye tabel?
- Er det nedenstående dataoverførslen i form af eksport - jeg bruger Oracles eksportværktøj (Datamanager) insert /*+ APPEND */ into PDV_ABONNEMENT_CARTE select /*+ FULL(old) */ * from PDV_ABONNEMENT_CARTE old; commit;
En anden løsning er at lave din nye tabel og en PL/SQL procedure
declare antal number; cursor c1 is select * from PDV_ABONNEMENT_CARTE@KOPI; begin for rec in c1 loop insert into PDV_ABONNEMENT_CARTE values rec.col1, rec.col2........; antal=antal+1; if (mod(antal,10000) then commit; end if; end loop; end; /
insert /*+ APPEND */ into PDV_ABONNEMENT_CARTE select /*+ FULL(kopi) * from PDV_ABONNEMENT_CARTE@KOPI kopi;
Dette virker fint hvis tabelstrukturen på tabellen jeg SELECT\'er fra og tabellen jeg INSERT\'er i, er ens. Tabellen jeg INSERT\'er i har flere felter som INSERT\'es med en trigger.
Jeg får følgende fejl:
ORA-00947: not enough values
fordi SELECT og INSERT INTO ikke har lige mange felter. På metalink er jeg kommet frem til at det umiddelbart skulle kunne lade sig gøre, hvis man blot angiver hvert felt. Jeg har prøvet det, men kan ikke få det at at funke.
Ja det vil virke hvis du angiver alle felter, men når man bruger APPEND som er Direct patch write vil din trigger ikke blive brugt, så er der kun den langsomme vej tilbage, det er den med procedure der vil hver række blive indsat og triggeren fyret, men også her skal du angive alle felterne evt. kan du disable triggeren mens du indsætter og der efter selv lave det samme som triggeren gør
Jeg har fået strikket min INSERT INTO (..) SELECT ... til at virke. Der var et enkelt felt jeg havde overset. Jeg fik overført ca. 1,5 mill rækker på en god time. Mine afledte felter blev også opdateret.
Tak for hjælpen alle sammen!!!
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.