Avatar billede pimpf202 Nybegynder
03. december 2004 - 22:59 Der er 14 kommentarer

backup af database i emergency mode

Dette er et desperart sidste forsøg i håb om der er en eller anden der ligger inde med et guldkorn..
Jeg har en database som er i emergencymode. Denne database har jeg nu brug for at få en backup af, så jeg kan restore så meget som muligt i en anden database. Jeg har postet en del spørgsmål omkring dette emne her i forumet (den database med 22.000 filer, og samlet ca. 30 gb data). Der er ingen måde jeg kan få, dts, eller script funktionen i EM til at virke, de hænger , dør mm. (dette sker på alle sql installationer jeg har prøvet, samt det kraftigste hardware IBM kan levere) Hvis jeg ændre status på databasen (til 0), marker sql serveren den suspect, og vil ikke tage en backup af den. Ændre jeg dens status til 32768 (emergency mode), så kan jeg forsprøge i alle tabellerne, men jeg kan stadigvæk ikke tage en backup (dette understøtter sql serveren åbenbart ikke..) Jeg har lavet et script der har bcp'et alle 22.000 tabeller ud i 22.000 filer, men problemet er bare at jeg ikke kan bruge det til en skid, når jeg ikke kan få relatioerne mellem tabellerne med, og jeg ligeledes ikke har nogen mulighed for at få views samt stored procedures med.
Hvis der er nogen der har en eller anden underlig ide til hvordan jeg kan få data'en ud (jeg kan jo se dem når jeg sætter den i emergency mode), så ville det rede mere en dagen for mig.
Avatar billede trer Nybegynder
05. december 2004 - 15:11 #1
Jeg er bange for at du ikke har de store chancer for at gøre det nemt - men først:

Luk SQL Serveren ned og tag en fuld backup af filsystemet (hvis du ikke allerede har det) - du må IKKE detactche databasen, at få den på igen kan være stort set umuligt!

Så kan du "lege" uden at få problemer - smadrer du noget kan du genskabe serveren.

Jeg checkede lige min formodning på MS premier support - eneste anbefaling MS har er, at du anvender BCP eller SELECT til at få dine data over i en anden database.

Min anbefaling - rå sql via Query Analyser til at flytte over i en ny database:

Først bygger du en ny db med de rigtige brugere etc, og så flytter du dine tabeller med et script a la dette:

declare @tbl sysname, @sql varchar(8000)

declare crsr local fast_forward for
  select '['+su.name+'].['+so.name+']' as tbl
  from faileddb.dbo.sysobjects so inner join faileddb.dbo.sysusers su
  on so.uid = su.uid
  where so.xtype='U'

open crsr
fetch next from crsr
into @tbl

while @@fetch_status=00 begin
  set @sql = 'SELECT * INTO [newdb].'+@tbl+' FROM [faileddb].'+@tbl+';'
  exec (@sql)
  fetch next from crsr
  into @tbl
end
close crsr
deallocate crsr
go

Ovenstående burde snuppe tabel metadata samt data og lave en rå kopi af databasen med de rigtige tabel-ejere.

Dine indeks og dine fremmednøgler kan du hive ud fra sysindekses og sysconstraints mv - jeg vil lige checke om jeg ikke allerede har et script liggende til at genererer dem i "rå" SQL.
Avatar billede trer Nybegynder
05. december 2004 - 16:09 #2
Migrering af indeks (danner script til afvikling i ny database).  Jeg har lige tilrettet det fra dets originale brug - så jeg garenterer ikke at det virker 100% - men... check det selv efter :-)

Jeg skal lige lede videre i mine gemmer for et fremmednøgle-script...

print '/*'
print ' Index script '
print '*/'

declare @idxname sysname, @tblname sysname,
    @keyno int, @colname sysname,
    @ColDir varchar(5), @fill int, @type varchar(13), @opt varchar(7), @man int
declare @sql varchar(8000)
declare @idx sysname, @tbl sysname
declare idxcrsr cursor local fast_forward for
    select    '['+si.name+']' as idx,
        '['+su.name+'].['+so1.name+']' as tbl,
        cast(sik.keyno as int) as keyno,
        '['+index_col(so1.name,si.indid,sik.keyno)+']' as colname,
        case when indexkey_property(so1.id, si.indid, sik.keyno,'IsDescending')=1 then 'desc' else 'asc' end as ColDir,
        indexproperty(so1.id,si.name,'IndexFillFactor') as IdxFill,
        case when indexproperty(so1.id,si.name,'IsClustered')=1 then 'clustered ' else 'nonclustered ' end as IdxType,
        case when indexproperty(so1.id,si.name,'IsUnique')=1 then 'unique ' else '' end as IdxOpt,
        case when (select count(1) from dbo.sysindexes subsi where subsi.id = si.id and si.indid=1)=0 then 1 else 0 end as MoveTbl
    from    dbo.sysindexes si right outer join dbo.sysobjects so1 on si.id=so1.id
    inner join dbo.sysindexkeys sik on sik.id=si.id and sik.indid = si.indid
    inner join dbo.sysfilegroups sfg on si.groupid = sfg.groupid
    inner join dbo.sysusers su on so1.uid = su.uid
    where si.indid between 1 and 254
    and objectproperty(so1.id,'IsMsShipped')=0
    order by si.name, si.id, sik.keyno
open idxcrsr
fetch next from idxcrsr
into @idxname, @tblname, @keyno, @colname, @coldir, @fill, @type, @opt, @man

select @idx=@idxname, @tbl=@tblname

-- opbyg index script
set @sql = 'create '+@opt+@type+'index '+@idxname+' on '+@tblname+'('

while @@fetch_status=0 begin
  -- check om vi er nået til næste index
  if @tbl<>@tblname and @idx<>@idxname begin
    -- sikr at valgt fillfactor anvendes når kolonner tilføjes index script
    if @fill<>0 begin
        set @sql = left(@sql,len(@sql)-1)+') with fillfactor='+cast(@fill as varchar)+', '
    end else begin
        set @sql = left(@sql,len(@sql)-1)+') '
    end
    -- sæt ny filgruppe til target
    print @sql
    select @idx=@idxname, @tbl=@tblname
    -- opbyg index
    set @sql = 'create '+@opt+@type+'index '+@idxname+' on '+@tblname+'('
  end
  -- opbyg kolonneliste
  set @sql=@sql+@colname+' '+@coldir+','
  fetch next from idxcrsr
  into @idxname, @tblname, @keyno, @colname, @coldir, @fill, @type, @opt, @man
end
-- her færdiggøres sidste index
if @fill<>0 begin
    set @sql = left(@sql,len(@sql)-1)+') with fillfactor='+cast(@fill as varchar)+', '
end else begin
    set @sql = left(@sql,len(@sql)-1)+')  '
end
print @sql
close idxcrsr
deallocate idxcrsr
print '/*'
print ' Scripting done '
print '*/'
go
Avatar billede trer Nybegynder
05. december 2004 - 16:37 #3
Og så var der et script til oprettelse af fremmednøgler (genererer script, ikke andet - og kan ikke håndtere casade update/delete, men du kan ret nemt joine cursor-selecten med INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS for at få casade delen på).

declare @old sysname, @const sysname, @fktbl sysname, @fkcol sysname, @pktbl sysname, @pkcol sysname
declare @sql1 varchar(6000), @sql2 varchar(2000)
declare crsr cursor local fast_forward for
    select '['+so.name+']','['+su1.name+'].['+so1.name+']', '['+sc1.name+']', '['+su2.name+'].['+so2.name+']', '['+sc2.name+']'
    from sysforeignkeys sfk
    inner join sysobjects so on sfk.constid = so.id
    inner join sysobjects so1 on sfk.fkeyid = so1.id  -- fk table
    inner join sysusers su1 on so1.uid = su1.uid
    inner join syscolumns sc1 on so1.id = sc1.id and sfk.fkey = sc1.colid
    inner join sysobjects so2 on sfk.rkeyid = so2.id  -- pk table
    inner join sysusers su2 on so2.uid = su2.uid
    inner join syscolumns sc2 on so2.id = sc2.id and sfk.rkey = sc2.colid
    order by sfk.keyno
open crsr
fetch next from crsr
into @const, @fktbl, @fkcol, @pktbl, @pkcol

set @old = @const
set @sql1 = 'ALTER TABLE '+@fktbl+' WITH NOCHECK ADD CONSTRAINT '+@const+' FOREIGN KEY ('
set @sql2 = ') REFERENCES '+@pktbl+' ('
while @@fetch_status=00 begin
  if @old = @const begin
    set @sql1 = @sql1 + @fkcol+','
    set @sql2 = @sql2 + @pkcol+','
  end else begin
    set @sql1 = left(@sql1,len(@sql1)-1)
    set @sql2 = left(@sql2,len(@sql2)-1)
    set @sql1 = @sql1+@sql2+')'
    print @sql1
    set @sql1 = 'ALTER TABLE '+@fktbl+' WITH NOCHECK ADD CONSTRAINT '+@const+' FOREIGN KEY ('
    set @sql2 = ') REFERENCES '+@pktbl+' ('
  end
  fetch next from crsr
  into @const, @fktbl, @fkcol, @pktbl, @pkcol
end
close crsr
deallocate crsr
go


Hvad angår views, stored procedures etc og rettigheder - så burde du kunne scripte disse uden de store problemer blot du nøjes med at scripte de objekter alene.
Avatar billede pimpf202 Nybegynder
05. december 2004 - 17:11 #4
Hej trer.. Mange tak for din hjælp indtil videre. Jeg har selv prøvet at lave en løsning i t-sql, men uden held. Jeg er helt sikkert heller ikke så erfaren som dig, så derfor er jeg nød til at tage dine scripts en af gangen. Jeg har lidt problemer med det første script.. Først får jeg en fejl på at declare cursoren local.. Derfor ændrede jeg linien : "declare crsr local fast_forward for" til "declare crsr cursor for" bare for at se om jeg kunne få det til at køre. Så får jeg en "Cannot run SELECT INTO in this database. The database owner must run sp_dboption to enable this option." Denne er jeg lidt i tvivl om hvorfor jeg får, og hvad jeg skal gøre ved den?
Avatar billede pimpf202 Nybegynder
05. december 2004 - 17:40 #5
Jeg må have været lidt for sent oppe i går, så jeg sidder vidst og sover lidt.. Jeg har kørt sp_dboption, så den har mulighed for bulk_insert. Men nu sker der det meget mærkelige at når jeg kører dit script, så kommer den ud og siger : Invalid object name 'defekt_db.dbo.A013' (og det samme på alle de andre tabeller). Men hvis jeg laver en "select * from defekt_db.dbo.A013", så får jeg resultatet fint tilbage ?? Det forstår jeg ikke, da det for mig at se er det samme du gør i cursoren ?
Avatar billede pimpf202 Nybegynder
05. december 2004 - 17:57 #6
og så fandt jeg også lige den trykfejl, der gjorde at det ikke virkede... Jeg beklager, og takker meget for din hjælp og tåldmodighed indtil videre.. Jeg vil gå videre med eksperimentet, og se  hvad det bliver til.
Avatar billede trer Nybegynder
05. december 2004 - 21:27 #7
Jep - der er trykfejl i mit første script. Det burde have heddet "declare crsr cursor local fast_forward" - men godt at du har fået startet på det.

Giv lyd hvis der er mere.
Avatar billede trer Nybegynder
05. december 2004 - 21:28 #8
I øvrigt - views og sp'er ligger i syscomments, du kan scripte dem derfra.
Avatar billede pimpf202 Nybegynder
08. december 2004 - 13:10 #9
Hej trer. SÅ har det lykkes mig at få mine tabeller over i den nye database. Nu har jeg desværre nogle små problemer med det 2 script, som flytter indexes. Jeg har en lille smule svært ved at overskue det, og derfor ville jeg høre om du kunne hjælpe mig lidt. Når jeg eksekvere det (fra den nye database(?)), så får jeg følgende fejl: "'indexkey_property' is not a recognized function name". Da jeg heller ikke kan finde en funktion med det navn, kan jeg ikke lige gennemskue hvad der så skulle stå i stedet ? Den anden fejl jeg får er i den 3 case linie i cursoren, får jeg at vide at der er en syntax fejl nær = Jeg synes sådanne set at den ser meget rigtig ud, (og ligner de andre case linier, så her er jeg ligeledes i tvivl om hvad der så skal stå..
Avatar billede trer Nybegynder
08. december 2004 - 13:51 #10
Jeg skal prøve at kigge på det med casen - men mht Indexkey_property - det er en standard sql server 2000 funktion.  Hvad version kører du (print @@version) ?
Avatar billede pimpf202 Nybegynder
08. december 2004 - 20:10 #11
Jeg kører sql 7.0 sp4..
Avatar billede pimpf202 Nybegynder
08. december 2004 - 21:12 #12
Hej trer.. Jeg er meget glad for det stykke vi er kommet ind til videre. Det vigtigste for mig er at få data'en med mig, så jeg synes at vi skal glemme det med index'ne for nu. Jeg kan jo altid bygge nogle nye index efterfølgende.  Jeg har kørt dit script til foreign keys, og det svare bare tilbage at det er completet ok.. Men det betyder vel ikke at jeg har fået defineret mine foreign keys ??  angående mine views og stored procedures, som jeg meget gerne vil have med over i den nye db, forsøger jeg mig en sidste gang med EM til at scripte dem ud, ellers kan jeg så bare kopiere hele syscomments over fra den gamle db ??
Avatar billede trer Nybegynder
08. december 2004 - 21:41 #13
Ok vi glemmer indeks - mht foreign keys - jeg aner faktisk ikke hvordan mit script opfører sig på 7.0 - det er lavet på 2000 og der er forskelle i metadata mellem de to versioner.

Mht at kopiere syscomments - det er no go. Du vil smadre din nye database hvis du forsøger! Det du kan er, at du kan lave en select fra syscomments

select text from syscomments
order by id, X

Så får du SQL'en ud for sp'er i basen.  En detalje er, at en enkelt SP kan fylde flere rækker så der er en kolonne der fortæller række indeks pr SP - jeg kan ikke huske hvad den hedder, så jeg har ovenfor angivet den som X.

Mht views - mener at du kan få dem ud af ovenstående også.
Avatar billede pimpf202 Nybegynder
17. december 2004 - 08:44 #14
Jeg har kastet håndklædet i ringen... Lige meget hvordan jeg vender og drejer det, så ender jeg op med meddelelser som :
“Table Corrupt: Database ID 7, object ID 410197703, index ID 0. Chain linkage mismatch. (3:2055025)->next = (1:2074288), "

Jeg er dog stadigvæk meget taknemlig for din hjælp, da det et kort øjeblik så ud til at fungere, og derfor må du godt post et svar så jeg kan give dig point..
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester