PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Datenbank sichern ab einem gewissen Zeilensatz weg



byron1778
31-01-2006, 11:52
Hallo Forum,

ich muss die Datenbank in meiner Firma sichern und dann nach einem Abgleich mit der Zweitdatenbank, wieder zurück spielen, dabei sollen aber keine Dubletten entstehen, bzw. vorhandene Dubletten sollen gelöscht werden.
Die Zweitdatenbank ist ein haargenauer Mitschnitt der ersten Datenbank, leider kam es aber zu Fehlern in den Datenbanken, nun soll ein Dump einer Datenbank erstellt werden, aber ab einem gewisse Datum. Dieses Dump soll dann mit der Zweitdatenbank geprüft werden.

Ich habe mir hierzu mysqldump angesehen, jedoch kann ich darin keine Option feststellen, mit der man zum Beispiel ab dem Datum 1.1.2006 bis 4.1.2006 ein Dump erstellen (möglich wäre natürlich auch ein Dump ab der Stelle 10.000.000 bis 15.000.000)kann.

Als Hinweis: Wir verwenden Winmysql!

Weiss jemand vielleicht, wie ich ein Dump ab einer gewissen Stelle vornehmen kann und dann Dubletten löschen kann? (Die Datenbank hat insgesamt nämlich über 25.000.000 Einträge, und da wird ein gesamtes Dump und dann ein Abgleich mit der anderen Datenbank eine halbe Ewigkeit dauern).

Danke für jede Hilfe schon einmal.

Mfg
Byron

elrond
31-01-2006, 12:43
was du dir vorstellst kann nicht gehen, da

1. mysql nicht selbständig irgendwelche infos über versionsständer der daten speichert.
und seshalb
2. mysqldump auch keinen snapshot von einem bestimmten zeitpunkt ausgeben kann.

Das kann man nur mit einem guten sicherunghskonzept umgehen...

ergeo:

du musst den abgleich wohl oder übel tabelle für tabelle per hand machen...

mwanaheri
31-01-2006, 13:22
Naja, wenn du ein autoincrement als Schlüssel hast, kannst du eventuell ab da händisch in eine csv exportieren, aber besseres fällt mir auch nicht ein.

byron1778
31-01-2006, 21:19
Danke für eure Hilfe.

Eine letzte Frage:

Wäre es vielleicht möglich über eine Select - Abfrage die Daten einzugrenzen und dann in eine externe Datenbank diese Abfrage zu transportieren (die Ergebnise)?

Ca. in dieser Form:

select datum from backup where datum = '1.1.2006' and where datum < '5.1.2006' >> backupzweitedatenbank

Wobei ich hier noch rausfinden müsste, wie man Datensätze genau eingrenzt.

Mfg
Byron

elrond
01-02-2006, 06:58
ich benutze dafür ein kurzes perl-script:


#!/usr/bin/perl -w
use DBI;

$dbcstring="DBI:mysql";
$dbname="hl"; #std-db
$dbuser="<dbuser>"; #dbusername
$dbpasswd="<dbpassword>"; #passwd
$table="default";
$sql="default";
foreach(@ARGV) {
$arg=$_;

if ($arg=~/db=/) {
@elm=split("=",$arg);
$dbname=$elm[1];
}
if ($arg=~/tbl=/) {
@elm=split("=",$arg);
$table=$elm[1];
}
if ($arg=~/sql=/) {
@elm=split("=",$arg);
$sql=$elm[1];
}
}

mkconnect();
if ($sql eq "default") { $sql="select * from $table";}

my $sth=$dbh->prepare($sql);
die "Prepare-Fehler: $DBI::errstr\n" if $DBI::err;

$sth->execute();
die "Execute-Fehler: $DBI::errstr\n" if $DBI::err;

while(@fields = $sth->fetchrow_array()) {
for (my $i=0 ;$i<@fields;$i++) {$fields[$i]=~ s/\;//g;$fields[$i]=~ s/\s{3,}//g;$fields[$i]=~ s/\n/ /g ;}
my $bcpln= substr(join(";",@fields),0,254);

print $bcpln."\r\n";
}


$sth->finish();
mkdisconnect();
#***************Datenbankfunktionen*************** *****************
sub mkconnect {

$dbh=DBI->connect($dbcstring.":".$dbname,$dbuser,$dbpasswd);
die "Fehler $DBI::errstr\n" unless $dbh;
}
#************************************************* ******************
sub mkdisconnect {
$dbh->disconnect();
die "Fehler $DBI::errstr\n" unless $dbh;
}
#************************************************* ******************


das ding liefert mir eine datei in der alle felder der abfrage mit ";" getrennt drinstehen. das ist dann leicht wieder einzulesen

aufruf entweder:
mysql2bcp db=test sql='select * from testtabelle where id<1000'

oder:
mysql2bcp db=jub tbl=testtabelle

kannst ja versuchen, ob es dir was bringt

byron1778
01-02-2006, 07:33
Danke Dir vielmals.

Werde mir das Script genauer ansehen.
Schön einen so tollen Support zu bekommen, wenn man nicht mehr weiter weiß.

Mfg
Byron

mwanaheri
01-02-2006, 07:48
Ich werde hier demnächst vor einem ähnlichen Problem stehen, denn ich muss dann zwei Datenbanken synchronisieren, die zwar die gleiche Struktur haben, in deren Nutzertabellen aber unabhängig voneinander Daten eingegeben werden. Ich weiß zwar, bis wohin der Datenbestand gleich ist, aber die Querbezüge zwischen den Tabellen mit den (unvermeidlichen) serial-Feldern sind natürlich ein Problem. Muss ich wirklich ein Progrämmchen schreiben, dass die neuen Einträge in eine Objektstruktur umsetzt, die ich dann in die jeweils andere Datenbank schiebe?

byron1778
01-02-2006, 14:45
Hallo,

ich habe eines meiner Probleme im Moment so gelöst.

Erstelle eine Datenbank, bei der die ausgelesenen Werte der einen Datenbank in die andere neue transportiert werden.

Dann muss ich schauen, wie ich die beiden abgleiche, das konnte ich noch nicht eruieren, wie ich da auf Dubletten eventuell überprüfe.

Hier mein Code:

<html>
<body>

<?php

$database = "dbase";
$user = "root";
$pass = "";
$linker = @mysql_connect ("localhost", $user, $pass);

if (! $linker) {

die ("Cannot connect to Database: ".mysql_error());

}

@mysql_select_db($database) or die("Cannot open Database: ".mysql_error());

$sql = 'select id from dbase where id between 5 and 1000';

$result = mysql_query($sql);
while($a_row = mysql_fetch_row($result)){
foreach($a_row as $field){

$database = "anderedbase";
$user = "root";
$pass = "";
$link = @mysql_connect ("localhost", $user, $pass);

if (! $link) {

die ("Cannot connect to Database: ".mysql_error());

}

@mysql_select_db($database) or die("Cannot open Database: ".mysql_error());

$sql = "insert into anderedbase (test) values('$field')";

mysql_query($sql);

mysql_close($link);

print "<p>$field</p>";}}

mysql_close($linker);

?>
</body>
</html>

Turbohummel
01-02-2006, 15:46
Seht euch mal IBMs DB2 an. Dort ist ein Data-Warehouse-Manager enthalten, der ziemlich genau diese Sync-Probleme lösen dürfte.

elrond
02-02-2006, 07:28
was du da tust kannst du mit nem sql-statement deutlich einfacher haben:


insert into newdb.testtab select * from testtab where id<1000

mwanaheri
02-02-2006, 08:15
@byron
Mindestens solltest du aufpassen, dass du nicht in der Schleife eine Datenbankverbindung herstellst. Das frisst unglaublich viele Resourcen.
Stelle also die Verbindung zu beiden Datenbanken außerhalb der schleife her und nimm in der Schleife nur die Einfügeoperation vor.
Problematisch kann es auch werden, wenn du in deiner Tabelle Bezüge zu einer anderen dynamischen Tabelle hast, weil du dann diese Bezüge nachbauen musst, die kannst du nicht kopieren.
Das dürfte das Besondere an der DB2-Sache sein, denke ich. Der liegt allerdings bei 11000 €, außerhalb meines Budgets also.

byron1778
02-02-2006, 08:19
Ok, danke, der Befehl funktioniert toll.

Gibt es noch einen Zusatz, mit dem man dann beide Datenbanken überprüfen kann, ob da Dubletten vorhanden sind.

Also Datenbank 1 soll mit Datenbank 2 abgeglichen werden, ob Dubletten vorhanden sind, wenn ja, dann sollen Dubletten gelöscht werden?

Mfg
Byron

elrond
02-02-2006, 08:49
was sind für dich dubletten?

byron1778
02-02-2006, 09:34
Also bei unserer Datenbank ist es so, dass Telefongespräche aufgezeichnet werden. Die Telefongespräche werden dabei in 2 Datenbanken geschrieben (beide sind voneinander unabhängig, also keine Master - Slave Beziehung).

Jetzt haben wir aber festgestellt, dass eine Datenbank vermutlich bestimmte Datensätze nicht aufgezeichnet hat und genau diese wollen wir nun finden.

Und sollten wir diese gefunden haben, dann wollen wir die Datenbank updaten, bei der die Gespräche fehlen.

So würde es aussehen:

Dbase 1 Dbase 2
Gespräch 1 Gespräch 1 vorhanden
Gespräch 2 Gespräch 3
Gespräch 3 ----------- Gespräch 2 nicht vorhanden, also soll es upgedatet werden

Folgende Operationen wollen wir also durchführen:

Vergleichen einen bestimmten Datensatz, und wenn möglich dann updaten.

Turbohummel
02-02-2006, 11:54
Stichwort: "REPLACE INTO"

Aber haltet ihr es nicht für unsauber, das ganze Zeugs in 2 Datenbanken zu kloppen? Einen Zweck sehe ich darin jedenfalls nicht.

byron1778
02-02-2006, 13:03
Naja, wir müssen eventuell diesen Auszug aus der Datenbank an die vermeintlichen Ursacher weiterschicken.
Wir selber haben die Datenbank an sich nicht erstellt, wurde von einer Firma gemacht, nur die sträuben sich jetzt überhaupt was zu machen und setzen auf Zeit.
Somit versuchen wir einmal die gröbsten Fehler zu finden.
Wobei die Hauptdatenbanken nicht angegriffen werden sollen.
Die müssen 7 Jahre bestehen bleiben und wenn wir da einen Fehler machen, ist vielleicht alles weg, deswegen lieber vielleicht umständlich aber dann mit Erfolg.

Danke für Deinen Tipp.

elrond
02-02-2006, 14:38
wenn ihr in dfer lage seid gespräche eindeutig zu identifizieren, ist der abgleich eigentlich nicht schwehr...einfacher left join