osmosis replication Task

Hallo,

ich habe versucht mir eine lokale Postgresdatenbank nach folgendem Beispiel aufzubauen: https://docs.google.com/document/pub?id=1paaYsOakgJEYP380R70s4SGYq8ME3ASl-mweVi1DlQ4

Das ganze scheint auch ganz gut zu funktionieren. Bis auf den Cronjob am Ende des Beispiels.
Ich habe zwar die .sh Datei so angelegt, wie es dort beschrieben wurde, aber es funktioniert nicht.

Schon die Erste Zeile des Scripts scheint fehlerhaft zu sein. Da dieses Script nie richtig ausgeführt wird. Da die ersten beiden Zeilen einen Administrator enthalten, habe ich diesen durch den Benutzer osm (ist der angemeldete Testbenutzer) ersetzt. Allerdings ohne Erfolg.

Die Zeilen habe ich dann mit # auskommentiert um wenigstens den Rest zu testen. Aber hier kommt es zu schwerwiegenden Fehlern:


02.05.2011 18:52:31 org.openstreetmap.osmosis.core.Osmosis run
INFO: Osmosis Version 0.39
02.05.2011 18:52:32 org.java.plugin.registry.xml.ManifestParser <init>
INFO: got SAX parser factory - org.apache.xerces.jaxp.SAXParserFactoryImpl@192d342
02.05.2011 18:52:32 org.java.plugin.registry.xml.PluginRegistryImpl configure
INFO: configured, stopOnError=false, isValidating=true
02.05.2011 18:52:33 org.java.plugin.registry.xml.PluginRegistryImpl register
INFO: plug-in and fragment descriptors registered - 1
02.05.2011 18:52:33 org.java.plugin.standard.StandardPluginManager activatePlugin
INFO: plug-in started - org.openstreetmap.osmosis.core.plugin.Core@0.39.0
02.05.2011 18:52:33 org.openstreetmap.osmosis.core.Osmosis run
INFO: Preparing pipeline.
02.05.2011 18:52:33 org.openstreetmap.osmosis.core.Osmosis run
INFO: Launching pipeline execution.
02.05.2011 18:52:33 org.openstreetmap.osmosis.core.Osmosis run
INFO: Pipeline executing, waiting for completion.
02.05.2011 18:52:33 org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager waitForCompletion
SCHWERWIEGEND: Thread for task 1-rri failed
org.openstreetmap.osmosis.core.OsmosisRuntimeException: Unable to open lock file ~/osm/planet/replication/download.lock.
    at org.openstreetmap.osmosis.core.util.FileBasedLock.initialize(FileBasedLock.java:53)
    at org.openstreetmap.osmosis.core.util.FileBasedLock.lock(FileBasedLock.java:68)
    at org.openstreetmap.osmosis.replication.v0_6.BaseReplicationDownloader.run(BaseReplicationDownloader.java:343)
    at java.lang.Thread.run(Thread.java:636)

Der Fehlermeldung entnehme ich, dass es Probleme beim schreiben der Datei download.lock. gibt. Warum und wie ich die beheben kann weiß ich jedoch nicht.

Mein script sieht derzeit wie folgt aus:


#!/bin/sh

#n=`ps -ef | grep -v grep | grep /home/osm/osm/osmosis-0.39/ | wc -l`

#if [ $n -le 0 ]

#then

        if [ -s /home/osm/osm/planet/surveillance-new.osm.pbf ]

        then

        mv ~/osm/planet/surveillance-new.osm.pbf ~/osm/planet/surveillance.osm.pbf

fi

~/osm/osmosis-0.39/bin/osmosis --rri workingDirectory=~/osm/planet/replication/ --simc --read-pbf ~/osm/planet/surveillance.osm.pbf --ac --tf accept-nodes man_made=surveillance --tf accept-ways man_made=surveillance --tf reject-relations --write-pbf ~/osm/planet/surveillance-new.osm.pbf

~/osm/osmosis-0.39/bin/osmosis --read-pbf ~/osm/planet/surveillance-new.osm.pbf --read-pbf ~/osm/planet/surveillance.osm.pbf --dc --write-pgsql-change database=osm_cctv user=osm password=osm

fi

Schreibfehler in den Aufrufen von osmosis möchte ich ausschließen, da alle Befehle einzeln nacheinander ins Terminal kopiert ohne Fehlermeldung ausgeführt werden.

hi,

schau dir mal an, ob der unix-user, der den script ausführen soll, rw-rechte auf ~/osm/planet/replication/ hat.

ausserdem würde ich hier immer einen vollen Pfad angeben: z.b. /home/viw/osm/planet/replication/ falls das directory wirklich da liegt.
oder soll es eventuell /osm/planet/replication sein? ohne ~

oder das lock-file exitiert bereits, gehört aber nicht dem aktuellen user?

ist zu 99% ein unix-rechte-problem und hat nix mit dem rest zu tun.

Gruss
Walter

Wie finde ich heraus welcher Benutzer das Skript als Cronjob ausführt?
Der angemeldete und eingerichtete Benutzer ist osm daher liegen die Daten auch in /home/osm/osm/planet/replication/

Auch ein löschen der Datei brachte keinen Erfolg. Was mich nur wundert ist halt, dass die gleichen Zeilen kopiert im Terminal unter dem gleichen User ausgeführt keine Probleme machen.

der cronjob läuft unter der userid, mit der er eingerichtet wurde.

d.h. wenn du als linux-user “osm” eingeloggt bist und “crontab -e” eingibts, rennt das Zeug nachher unter “osm”.

zur frage: ich baue manchmal ein “touch /tmp/xxx” ein und schaue mir nachher an, wer das gemacht hat. “ls -la /tmp/xxx”. Auf /tmp darf ja jeder schreiben.

mich auch :frowning:
eventuell (soooo ein riesen linux-guru bin ich auch nicht): WIE welchselst du zum User “osm”? Richtiges Ausloggen und Einloggen als “osm” in der Gui oder mit “sudo”?
ach ja, welches Linux?

Der Tip mit den ausgeschriebenen Verzeichnisen war schon sehr gut. Jetzt läuft das Skript wenigstens ohne den Fehler.
Allerdings habe ich noch nicht so ganz verstanden was die ersten Zeilen bedeuten. Denn wenn ich diese nicht auskommentiere startet das Skript gar nicht bzw. führt nichts aus.

beim 1. osmosis-call erzeugt er aus surveillance.osm.pbf das file surveillance-new.osm.pbf.

wenn der script ein weiteres mal aufgerufen wird (z.b. per cron) kopiert er surveillance-new.osm.pbf nach surveillance.osm.pbf und jagt da die neuen diff-daten rüber.
Warum er das aber in Abhängigkeit von der zweiten Zeile macht, ist mir schleierhaft. Da checkt der cron-job, in welchem Directoy er sich gerade befindet (?).

egal, es funzt :wink:

ansonsten verstehe ich -noch- nicht, wieso hier osmosis 2x aufgerufen wird. das geht auch in einem einzigen. eventell hat diese methode mir noch verborgene Vorteile. mal sehen.

und wie kann ich sicherstellen, dass der Task nicht ausgeführt wird, wenn der vorherige noch läuft? Ich dachte das mache ich mit der ersten Zeile.

Moin,

wenm man die seite bei dem link anschaut, dann wird die erste zeile klarer: Es wird geschaut ob osmosis noch mit dem catchup zu tun hat und
verschiebe erst dannn wenn er damit fertig ist, da der cronjob alle 5 Minuten aufgerufen wird.

Es sind zwei ineinander geschachtelte if & fi, nur ein if auszukommentieren kommt mir nicht richtig vor.

Ciao,
Frank

wo er recht hat, hat er recht :wink:
gruss
walter

 #!/bin/sh

n=`ps -ef | grep -v grep | grep /home/osm/osm/osmosis-0.39/ | wc -l`

if [ $n -le 0 ]

then

        if [ -s /home/osm/osm/planet/surveillance-new.osm.pbf ]

        then

        mv /home/osm/osm/planet/surveillance-new.osm.pbf /home/osm/osm/planet/surveillance.osm.pbf

    fi

/home/osm/osm/osmosis-0.39/bin/osmosis --rri workingDirectory=/home/osm/osm/planet/replication/ --simc --read-pbf /home/osm/osm/planet/surveillance.osm.pbf --ac --tf accept-nodes man_made=surveillance --tf accept-ways man_made=surveillance --tf reject-relations --write-pbf /home/osm/osm/planet/surveillance-new.osm.pbf

/home/osm/osm/osmosis-0.39/bin/osmosis --read-pbf /home/osm/osm/planet/surveillance-new.osm.pbf --read-pbf /home/osm/osm/planet/surveillance.osm.pbf --dc --write-pgsql-change database=osm_cctv user=osm password=osm

fi

wenn ich das Skript habe, wenn leider nichts ausgeführt. Wenn ich jedoch


#!/bin/sh

#n=`ps -ef | grep -v grep | grep /home/osm/osm/osmosis-0.39/ | wc -l`

#if [ $n -le 0 ]

#then

        if [ -s /home/osm/osm/planet/surveillance-new.osm.pbf ]

        then

        mv /home/osm/osm/planet/surveillance-new.osm.pbf /home/osm/osm/planet/surveillance.osm.pbf

#    fi

/home/osm/osm/osmosis-0.39/bin/osmosis --rri workingDirectory=/home/osm/osm/planet/replication/ --simc --read-pbf /home/osm/osm/planet/surveillance.osm.pbf --ac --tf accept-nodes man_made=surveillance --tf accept-ways man_made=surveillance --tf reject-relations --write-pbf /home/osm/osm/planet/surveillance-new.osm.pbf

/home/osm/osm/osmosis-0.39/bin/osmosis --read-pbf /home/osm/osm/planet/surveillance-new.osm.pbf --read-pbf /home/osm/osm/planet/surveillance.osm.pbf --dc --write-pgsql-change database=osm_cctv user=osm password=osm

fi

verwende funktioniert es.

Warum dies so ist kann ich mir nicht erklären.

Nur mal zur Erklärung:

  1. Zeile: Führe dieses Skript mit dem Programm /bin/sh (Standard-Shell) aus.
  2. Zeile: Setze Variable ‘n’ auf die Ausgabe des rechts stehenden Kommandos
    • “ps -ef” Liste der aktuellen Prozesse
    • “grep -v grep” Gib alle Zeilen aus, die nicht den String “grep” enthalten.
    • “grep /home/osm/osm/osmosis-0.39/” Gib die Zeilen mit “…osmosis-0.39” aus
    • “wc -l” Gib die Zahl der Zeilen aus.
      Die Variable ‘n’ hat als Wert entweder eine Zahl >0 oder 0 je nachdem ob osmosis-0.39 läuft oder nicht.
  3. Zeile: Führe die folgenden Kommandos nur aus, wenn osmosis-0.39 nicht läuft.
    Die innere Bedingung benennt surveillance-new.osm.pbf zu surveillance.osm.pbf um, falls es existiert.

Das ist durchaus erstaunlich, da du das innere “fi” auskommentiert hast, statt des zweiten “fi”, welches eigentlich zu deiner auskommentierten Bedingung gehört. Sprich du hast die Struktur der Abfrage massiv geändert.

Edbert (EvanE)

Danke für die wirklich aufschlussreichen Erklärungen.
Dieses Skript wird quasi immer ausgeführt, wenn die Datei surveillance-new.osm.pbf vorhanden ist. Das sollte sie im Prinzip ja auch, weil ich das erste Mal alles von Hand gemacht habe.
Man könnte also auch alles auskommentieren was mit dem if zu tun hat.
Offenbar lief bei mir noch eine osmosis instanz. Nach einem Neustart funktioniert das Skript bis auf die aller erste Zeile fehlerfrei. Diese ist bei mir jetzt wie in der Vorlage auskommentiert, da sie offenbar nicht gebraucht wird und nur eine Fehlermeldung anzeigt.

Gern geschehen.
Shell-Skripte sind nicht so einfach zu verstehen, wenn man nicht selber bereits einige erstellt hat. Vieles kann sehr knapp formuliert werden. Das spart Schreibarbeit, fördert aber nicht die Lesbarkeit.

Die erste Zeile ist inklusive der ersten beiden Zeichen wichtig.
Das “#!” sagt dem aufrufenden Programm (in der Regel eine Shell), dass dieses Skript nach den Regeln des anschließenden Programms (hier “/bin/sh”, die Standard-Shell) formuliert ist und entsprechend mit diesem Programm ausgeführt werden soll.

Da es bei Unix/Linux mehr als eine Shell (Kommando-Interpreter) mit sehr unterschiedlicher Syntax gibt, wurde diese Konvention eingeführt, um sicherzustellen, dass ein Skript im richtigen Kontext ausgeführt wird.
Wenn man so ein Skript in /bin/sh aufruft, ändert sich nichts. Ruft man es jedoch in einer anderen Shell auf, so wird eine Instanz von /bin/sh erzeugt und dieser der restliche Text als Input übergeben. ==> Alles klappt wie vorgesehen.

Edbert (EvanE)

Also eine Frage hätte ich da noch. Hier wird die Replication in zwei Schritten gemacht. Aber wäre es nicht viel einfacher, wenn ich die Daten direkt in die Datenbank speichern würde ohne den Umweg über ein pbf? Oder spielen hier Sicherheitserwägungen eine Rolle, wenn es zu Fehlern kommt?

Ja, ja diese Anleitung.

Erst nennt er das script
replicate-cctv.sh
als cronjob wird plötzlich ein
replicate-surveillance.sh
draus :wink:

Ciao,
Frank

Solche offensichtlichen Probleme konnte ich ja recht schnell lösen. Es geht mir einfach darum, dass ich an BEispielen die ganzen Möglichkeiten einmal nachvollziehen kann. Da fand ich die Anleitung sehr schön, auch wenn noch andere Stolpersteine drin sind. Eine hstore.sql Beispielsweise, statt hastore-new.sql. Auch wird die nur in contrib abgelegt wenn man ein bestimmtes PAket installiert. Es reicht also nicht Postgis1.5 wie er schreibt. Aber mit Eurer Hilfe war es dennoch möglich eine Datenbank zuerstellen, welche sich jetzt selbst aktuelle hält.

Gratuliere,

das das in einem Rutsch gehen muss/geht hab ich ja gestern schon angemerk :slight_smile:

hier der Kern meines Scripts:


osmosis  \
        --read-replication-interval  \
        --simc \
        --write-pgsql-change host= ...zensiert...

hier noch mein configuration.txt


baseUrl=http://planet.openstreetmap.org/minute-replicate
changeFileBeginFormat=yyyyMMddHH
changeFileEndFormat=yyyyMMddHH

maxDownloadCount = 20
maxInterval=3600

Ich starte den cron-job alle 2 Minuten.

Normalerweise holt er sich alle Daten der letzten Minuten und pflegt die ein.
Sollte der Rechner mal längere Zeit offline gewesen sein, holt er sich MAXIMAL die Daten einer Stunde (3600 secs) und verarbeitet diese.
Sollten mehr als die Daten einer Stunde fehlen, holt der nächste Chron-Job den nächten Block im nächsten Durchgang.
Nach einigen Durchgängen ist der Spuk vorbei und der selbe Job backt dann “Kleine Brötchen”.

Vorteil nicht zu grosser “Brötchen”:
Die Datenblöcke sind relativ klein und ich kann den Rechner jederzeit runterfahren - auch während des aktuellen Updates- ohne allzuviele Daten zu verlieren.
Keine Angst: postgresql merkt das, macht einen Rollback der zuletzt noch nicht vollständig geladenen Daten; der nächste Cronjob am nächten Tag wiederholt den abgebrochenen und alles ist ok.
Zeitverlust: ca 10 Minuten als Mittelwert, da das Verarbeiten eines “Grossen Brötchens” bei meinem Rechner ca 20 Minuten Real-Time dauert.
Datenverlust: NULL

Noch ein paar Fragen/Tips:

a) Plattenplatz: ist der gross genug?
b) was ist surveillance.osm.pbf
c) brauchst du/willst du den ganzen planet?
d) jetzt der Hammer: solltest du nur einen bestimmten Teil de Welt brauchen wird dir osmosis dennoch alle neuen oder geänderten Objekte weltweit in deine DB schreiben.
Brett (der Autor von osmosis) hat es noch nicht geschafft, ein bbox- oder poly-filter beim Verarbeiten der Diff-Files einzubauen. Die ganze Sache ist nicht trivial.
Resultat: die DB wird riesig 1TB (?) Tendenz steigend.
Workaround: die DB alle 3-4 Wochen neu aufsetzen :frowning:
e) vergiss um Himmelswillen nicht, autovacuum im postgresql.cfg zu aktivieren

Gruss
Walter

Nein also ich habe kein Interesse an surveillance, welches nur die Überwachungskammeras speichert. Und ja ich möchte eigentlich lieber einen Teil des Planeten. Besonders weil das TB an Platz nicht zur Verfügung steht und mich manche Teile der Welt auch nicht interessieren. Außerdem läuft die Sache nur auf einem Win32 Bit in einer virtuellen Maschiene.
Zu d) wäre also der Umweg über das neue File durchaus der bessere Weg, da man so dann recht schnell beim einlesen der Diffs in die Datenbank noch die bbox oder das Poly drüberjagen könnte.

kannst du auf jeden Fall erst mal so lassen; auf die paar Minuten Overhead kommt es ja nicht an.

Wenn das aber soooo einfach wäre mit den diffs und dem clipping, stände das schon längst in den osmosis-foren drin. Davon träumen nämlich viele.
Brett selber schreibt irgendwo, dass es nicht geht und nennt auch die Gründe dafür. link könnte ich nachreichen.

Eins sei klargestellt: wenn du mit osmosis den Replication-Mechanismus verwendest, sind die Optionen --bb und --bp nicht erlaubt. → Fehlermeldung

mit den dataset-tasks --dbb und --dd hab ich auch Schiffbruch erlitten.

Probier einfach mal aus; ich würde mich riesig freuen, wenn du einen Weg findest.

Gruss
Walter

p.s kannst du ja auch mal etwas zurückstellen aber irgendwann in einigenWochen wirst du dich drum kümmern müssen.

Das Blöde bei den riesigen Daten ausserhalb deines “Gebietes” ist, dass du die noch nicht einmal verwenden kannst, da dort ja “nur” die neuen Objekte drin sind aber nicht der Altbestand. Das ginge nur beim ganzen Planeten.

Ohne das jetzt probiert zu haben, aber wäre es denkbar, wenn das Gebiet als Geometrie in der Datenbank enthalten ist, dann einfach mit der Abfrage ist nicht in die Sachen zu löschen? Ok man muss dann noch auf die Abhängigkeiten achten, aber im Prinzip scheint mir das einfacher als die Datenbank neu zu füllen.
Postgis ist später noch eine andere Herausforderung. Jetzt versuche ich erstmal pgsql zum laufen zu bewegen. Danach wollte ich schauen das ich daraus Karten und/oder andere nützliche Dinge mache. Ich denke dabei werde ich früher oder später nicht um Postgis herumkommen. Gerade was die ganzen Trigger angeht habe ich ja schon interessante Dinge bei dir gelesen. Eventuell wäre auch das noch eine Lösung einfach einen Trigger anschalten wenn Daten außerhalb eingelesen werden. bzw die Löschabfrage im Skript hinterher schieben.