<< | Index | IndikationsSuche >>
Probleme mit der ODBA
Nach dem Schreiben eines Snapshots
- clean_objects_connection method in storage.rb takes too long to execute
- system object gets extended with a new instance variable. how shall we store it in the odba without writing a new snapshot (odba_take_snapshot) eg atc_chooser, after rebuilding the atc_chooser
- DB mit einem grossen Snapshot füllen dauert sehr lange (>1 Woche) Einstellungen: Leere ATC Klassen werden berücksichtig, Transaktion auskommentiert, Maeges Interaktionscode integriert. Was kann optimieren?
- das erste was mir aufgefallen ist, ist dass die verschiedenen Instanzen mehrmals gespeichert werden. Konkret: die ersten paar zeilen Output von rebuild_odba in RebuildOdbaLog1 => es wird zu ca 50% das Objekt mit der odba_id 1 gespeichert!
- Erklärung: ScalarCache wird jedesmal gespeichert, wenn z.B. ein Hash auch gespeichert wird.
- Es sollten alle Skalarwerte eines ODBA::Persistables gesammelt und erst später gespeichert werden.
- Es bietet sich z.B. als Möglichkeit, am Ende von Persistable#odba_store oder am Ende von Storage#transaction den ScalarCache zu speichern (Aktiv am 10.08.2004: in ODBA#transaction)
- die Konstante ODBA_CACHE_METHODS hatte für alle Persistable zwei Default-Einträge -> das führt dann für die allermeisten Persistable für eine Iteration mit 2 überflüssigen respond_to? abfragen. Theoretisch könnte das auch für String gesetzt werden, aber ich denke nicht, dass das irgend einen Vorteil hätte. Im Moment (10.08.2004) also nur für Array und Hash gesetzt.
- vom gleichen Durchgang gibts auch einen ProfileOutput1
- Noch ein Durchgang, diesmal mit obigen Änderungen und deaktivierter Transaktion (DeactivateDbTransaction): ProfileOutput2
- Weiter fällt mir auf, dass Storage#add_object_connection eine sehr hohe Ausführungszeit hat (total ms/call), bedingt dadurch, dass für jede der sehr vielen object_connections mindestens eine Abfrage auf die grösste Tabelle (im Moment ca 4 rows pro Objekt) gemacht werden muss. Dies ist offensichtlich trotz korrektem Index (
»object_connection_pkey« Primärschlüssel, btree (origin_id, target_id)
) ein Problem:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
2.21 1383.85 58.63 10253 5.72 226.96 ODBA::Storage#add_object_connection
bzw.
1.07 482.67 2.58 879 2.94 240.40 ODBA::Storage#add_object_connection
- Lösungsvorschlag: ev. ist es möglich, mit einer stored-procedure etwas zeit gutzumachen, da der ganze Ruby-DBI overhead vermieden werden kann. (Versuchsweise Umgesetzt am 11.8.2004: ensure_object_connection.sql, dasselbe für store_object in update_object.sql)
anhand von ProfileOutput3 lässt sich vermuten, dass das was genützt hat.
- Andere Möglichkeit: während dem Snapshot object_connections ignorieren, und in einer separaten Struktur speichern und erst später komplett in die DB schreiben.
- 11.8.2004 15:00: im Moment ist gemäss
top
die DB das Bottleneck: ca 1.4% CPU für ruby und 98.6% CPU für postmaster.
- Ev. müssen wir in zwei schritten Arbeiten: ein flatfile anlegen, das von Ruby gefüllt wird, dann
COPY FROM
in postgres.
- Der erste Schritt ist nach etwas mehr als 24h erledigt:
25.7334209925 h to save OddbPrevalence and all its unsaved neighbors
- nächster Schritt aufsplitten mit
split -l10000 object_connection.csv object_connection/conn_part_
bzw. split -l5000 object.csv object/obj_part_
-> hier ist definitiv die Festplatte das Bottleneck
- In die DB reinladen:
hwyss@oldie:/var/www/oddb.org$ for file in $(ls data/odba-csv/object/); do
> echo "loading $file";
> psql -U postgres --command "COPY object FROM '/var/www/oddb.org/data/odba-csv/object/$file'" odba;
> done;
hwyss@oldie:/var/www/oddb.org$ for file in $(ls data/odba-csv/object_connection/); do
> echo "loading $file";
> psql -U postgres --command "COPY object_connection FROM '/var/www/oddb.org/data/odba-csv/object_connection/$file'" odba;
> done;
- Probleme damit: Duplikat-Eintrag für odba_id 4, ausserdem eine selbe Fehlermeldung für odba_id 25000, wobei diese nicht verifiziert werden konnte. Es fehlen auch genau die 5000 Objekte vom ersten File (das mit odba_id 4). Ebenso einige Duplikate für object_connections. Es ist im Moment nicht klar, wieviel Daten deswegen nicht geladen werden konnten...
sort object_connection.csv | uniq > unique_object_connection.csv
-> unique_object_connection.csv hat noch 509734 zeilen, im Gegensatz zu den 518736 Zeilen von object_connection.csv
- javoll, das seint so tsu klappen!
- Festplatte auf Oldie ist voll, Snapshot über Nacht ab (27.07-28.07). Bevor jemand also wieder einen Snapshot schreiben möchte, muss unbedingt die Festplatte gereinigt werden.
- Das problem ist offenbar hier die Transaktion, die nicht ausgeschaltet war. Im Zusammenhang mit der
COPY FROM
-Idee bin ich auf einen Mailing-List Beitrag gestossen, der dazu auch eine Lösung bietet: man teilt den COPY
in mehrere Files auf, die alle maximal 10'000 Zeilen haben. So bleibt das Transaktionslog schön klein.
- OK
- Den Updater haben wir gestarten auf dem Lehrling, es gab einen Segmenation Error im Swissmedicjournal. Updater funktionierte aber bei Maege.
- Also. Nach langem suchen, und viel Output bin ich auf folgenden UpdaterLog1 gekommen: Das Problem scheint zu entstehen, wenn ein Objekt gelöscht wird, aufgrund von zirkulären Referenzen aber noch mal geladen werden soll... Darüber denk ich heute nacht zu Hause nach...
- Anscheinend haben wir das Problem genau dann, wenn die allererste sequenz gelöscht werden soll.
- Das Problem konnten wir lösen, indem wir überprüfen ob ein connected_object noch geladen werden konnte, oder obs bereits gelöscht war.
- Ein weiteres Problem scheint jetzt zu sein, dass in der Iteration über alle Sequenzen einer Registration nach dem Löschen ein Eintrag des Scalar-Cache im Iterations-Block landet!! Ich vermute, dass das irgendwie mit dem Speichern oder Löschen zu tun hat, (z.B. wenn beim Speichern dieser Eintrag returned würde, anstelle des Objektes)
- Workaround hier ist, vor der Iteration eine kopie der collection zu machen.
- Package, Sequence, Registrationen können erstellt und gändert werden.
- Wirkstoffe ändern gibt wieder einen pointer for nil Fehler. (Maege bitte anschauen)
- Galenik Form ändern funktioniert.
- Atc browser wird beim Starten jeweils neu erstellt. Beim ersten Gebrauch dauert es lange. Danach werden die ATC Klassen schnell dargestellt. Das Problem ist hier anscheinend nicht gleich wie bei der Hauptseite (Aufruf auf length Methode), obwohl viele arrays geladen werden. Die Methode empty? wird aufgerufen. Wir haben die Methode in den scalar_cache aufgenommen, der ATC Browser lädt jetzt normal schnell.
- Exporter haben wir laufen gelassen. Gab keine Probleme damit.
- Eingabe eines | Zeichens provoziert einen Syntaxfehler auf DBI Ebene, obwohl das SQL Statement eigentlich via DBI escaped werden sollte. Die Seite stürzt nich ab, man landet aber im vorherigen State. Könnte dies für eine böswillige SQL-Injection missbraucht werden?
- Mit einer Regex werden Sonderzeichen jetzt gefiltert. Das | Zeichen wird als Operator im TSearch Modul benutzt (|| für OR Suche).
- Funktionieren die Direktvergleiche noch? Im Moment siehts so aus, als ob nein (vergleich zw. Online und Oldie: Erstes Ponstan-Produkt hat online 4 Direktvergleiche, lokal keine)
- Problem beim vergleichen der Medikamente. Klickt man auf ein Medikament sollte es eine Ausgabe der Medis mit gleichen Wirkstoffen und gleicher Dosis erzeugen. Das Problem ist unserer Meinung nach im Comparable Modul. Die Methode <=> scheint nicht richtig zu funktionieren. Es könnte ein ähnliches Problem sein, wie bei der include? Methode der Klasse Array. Wir versuchten die <=> Methode in der Klasse Array zu überschreiben (im Modul odba) leider funktionierte das nicht, testweise sah das so aus:
def <=>(other)
puts "in <=>"
super(other)
end
- Wenn wir jetzt eine Suche anklickten, dann erschien die puts Ausgabe, es gab aber einen Fehler, obwohl wir die Supermethode aufgerufen haben. Man müsste wohl in der <=> Methode die Stubs des Arrays durch die Richtigen Elemente ersetzen.
- Ruby Referenz zu <=> der Klasse Array: Thus, two arrays are ``equal'' according to Array#<=> if and only if they have the same length and the value of each element is equal to the value of the corresponding element in the other array
Maege hat festgestellt, falls man diese Zeile:
#&& seq.galenic_form.equivalent_to?(@galenic_form) \
Im File model/sequence in der Methode comparables? auskommentiert.
Jetzt wird das Resultat richtig angezeigt bei der Suche nach Ponstan. Sucht man aber nach "Panad", wird ersichtlich, dass alle Medis angezeigt werden, also nicht nur solche die die gleiche Galenicform besitzen.
Das heisst man darf diese Zeile NICHT auskommentieren.