Mittwoch, 5. November 2014

#1690 - BIGINT UNSIGNED value is out of range

#1690 - BIGINT UNSIGNED value is out of range

Kann bei einer MySQL - Abfrage erscheinen, wenn man innerhalb der Abfrage mit UNSIGNED Integer - Spalten rechnet und das Ergebnis ein negativer Wert ist.

Also beispielsweise die Tabellenspalte "time" ist eine unsigned Integer Spalte. Unsigned bedeutet übrigens, dass der Wert nicht negativ werden kann, aber dafür erhöht sich der gültige Wertebereich im postiven Bereich um 100%.

Nehmen wir an die Spalte "time" hat einen UNIX TIMESTAMP wert in der Vergangenheit und wir haben folgende Abfrage:

SELECT * FROM tabelle WHERE time - UNIX_TIMESTAMP() < 5

Hier würde entweder die Fehlermeldung von oben erscheinen oder ein sehr hoher Wert errechnet werden.

Die Lösung:

1. entweder die Spalte "time" zum normalen Integer umwandeln (ALTER TABLE `tabelle` CHANGE `time` `time` INT(10) NOT NULL DEFAULT '0';)

2. Oder MySQL im 'no_unsigned_subtraction' - Modus starten.
Dazu einfach in der my.cnf "sql_mode = 'no_unsigned_subtraction'" eintragen, bzw. "no_unsigned_subtraction" in der entsprechenden Zeile ergänzen.


Mittwoch, 29. Oktober 2014

strict_trans_tables deaktivieren. Möglicher fix.

Ich musste wegen eines Projekts die irgendwann neu eingeführte Direktive "strict_trans_tables" in mysql deaktivieren, da sie dazu führte, dass einige MySQL-Queries nicht ausgeführt wurden.

Normalerweise geht man in die /etc/my.cnf , sucht nach "sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES" und kommentiert diese Zeile aus.

Hat aber nicht gereicht. Nach etwas Recherche suchte ich my.cnf die im /usr Verzeichnis sein sollte. Und tatsächlich, sie existierte. Dort gab es auch nur die Zeile "sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES", welche auskommentiert werden musste.


MySQL Datenbank von einem Server zum anderen kopieren mittels ssh und mysqldump

Um eine Datenbank per SSH zu einem anderen Server zu kopieren kann man folgenden Befehl verwenden:

mysqldump -uuser -ppassword db1 | mysql -h desthost -uuser -ppassword destdb

Ja: nach -u und -p kommt KEIN Leerzeichen. Hier ein Beispiel, wenn
User gleich root
Passwort gleich 123sonnenschein
Datenbank gleich MyDB
Ziel-Host: 192.168.2.1

mysqldump -uroot -p123sonnenschein MyDB | mysql -h 192.168.2.1 -uroot -p123sonnenschein MyDB

Es sollte beachtet werden, dass auf dem Zielhost entsprechende Rechte des Users vorhanden sind. Also, dass er auch außerhalb von localhost auf den Server verbinden kann.
Zudem sollte die Datenbank (in diesem Fall MyDB) bereits angelegt worden sein.

Das Beispiel geht davon aus, dass User und Passwort auf beiden Servern gleich ist (was keine gute Idee ist).

Dienstag, 7. Oktober 2014

[linux] SSH-Befehl im Hintergrund ausführen bzw. nicht beenden, wenn die Verbindung abbricht.

Manchmal möchte man im Remote - SSH einen Befehl eingeben, dessen Ausführung ziemlich lange dauern kann. zum Beispiel das Packen vieler Dateien oder weiß der Fuchs was.

Diese Aktion wird Standardmäßig abgebrochen, wenn die SSH Verbindung beendet wird. Das kann zum Beispiel durch den 24h - Reconnect des Providers sein oder irgendeinen anderen Grund haben. In jedem Fall ist das dann sehr ärgerlich.

Man kann das Ganze aber auch im Hintergrund ausführen - mit "screen".

Um genau das Problem zu lösen benutzt man folgenden Befehl:

screen -dmSL myscreen

"myscreen" ist dabei einfach eine Bezeichnung für den geöffneten neuen Screen.

Beendet man nun die Verbindung zum Server, werden die Befehle weiterhin ausgeführt.

[linux] rsync Performance verbessern. Mehr CPU Kerne.

Ich stand vor dem Problem viele kleine (3 Millionen) Bilddateien von einem Server zum anderen kopieren zu müssen, da der Bildauslagerungsserver gewechselt werden sollte.

Das Packen und Archivieren mit tar und gzip war leider unbefriedigend langsam.

Auch die Alternative mit pigz (gzip mit Mehrkern-Unterstützung) brachte keine großartige Besserung.


Syntax für pigz:

 tar -cv –use-compress-program=pigz -f meinarchiv.tar /srv/www/img

Was ich noch nicht probiert habe, ist tar mit einer Erweiterung zu versehen, die mehrere Threads zum Schreiben verwenden kann.

Das gibts hier: http://www.maier-komor.de/mtwrite.html


Syntax für Nutzung mit mtwrite:

mttar xf mytarfile.tar


Ich habe mich dann aber erstmal für die Nutzung von rsync entschieden. Vorteile: Ich muss den laufenden Betrieb (Bildupload) nicht stoppen; Abgebrochene Aktionen können wieder aufgenommen werden; Ich habe nur eine Aktion auszuführen, denn die Daten werden direkt via ssh übertragen.

Leider dauert dieser Vorgang wegen der vielen kleinen Dateien auch ziemlich lange. Nach 24 Stunden waren knapp 70GB übertragen.

Nun gibt es noch einige Dinge die ich demnächst ausprobieren möchte. Und damit ich Sie nicht vergesse gibt es diesen Post :)

Zum Beispiel lässt sich der CPU - Kern den rsync verwendet auf den Maximalwert hochtakten.
Das kann man so machen:

for i in 0 ; do
echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor
done

Mehr dazu auf http://lwn.net/Articles/400489/

Noch etwas mehr verspreche ich mir jedoch von mehreren parallel laufenden rsync- Prozessen.
Mit Hilfe eines Scripts werden die Dateien auf die Prozesse verteilt.

Das Script gibts dort: https://wiki.ncsa.illinois.edu/display/~wglick/Parallel+Rsync

Falls der Link irgendwann mal down sein sollte, hier zum Kopieren:

/bin/bash
# SETUP OPTIONS
export SRCDIR="/folder/path"
export DESTDIR="/folder2/path"
export THREADS="8"
# RSYNC TOP LEVEL FILES AND DIRECTORY STRUCTURE
rsync -lptgoDzd $SRCDIR/ /$DESTDIR/
# FIND ALL FILES AND PASS THEM TO MULTIPLE RSYNC PROCESSES
cd $SRCDIR; find . -type f | xargs -n1 -P$THREADS -I% rsync -az % /$DESTDIR/%
# IF YOU WANT TO LIMIT THE IO PRIORITY, 
# PREPEND THE FOLLOWING TO THE rsync & cd/find COMMANDS ABOVE:
#   ionice -c2

Nachteil hierbei: Bei diesem Script werden alle Dateien des Hauptverzeichnisses mit nur einem Prozess übertragen. In den Kommentaren gab es eine alternative Lösung:

#!/bin/bash
 
# SETUP OPTIONS
export SRCDIR="/Storage/data1"
export DESTDIR="/Storage/data2"
export THREADS="32"
 
# FIND ALL FILES AND PASS THEM TO MULTIPLE RSYNC PROCESSES
cd $SRCDIR
if [[ $? -eq 0 ]]; then
        find . -type d | xargs -I% mkdir -p /$DESTDIR/%
        find . -type f | xargs -n1 -P$THREADS -I% rsync -a % /$DESTDIR/%
fi

Für beide Fälle gilt: Soll per ssh übertragen werden - also von Server zu Server - müssen die rsync Befehle abgeändert werden:

rsync -lptgoDzd -e 'ssh -c arcfour' $SRCDIR/ remotehost:/$DESTDIR/
cd $SRCDIR; find . -type f | xargs -n1 -P$THREADS -I% rsync -az -e 'ssh -c arcfour' % remotehost:/$DESTDIR/%

Und noch ein wichtiger Parameter: Soll das Verzeichnis lediglich geupdated werden und nicht alle Dateien überschrieben werden, unbedingt die Option "-u"verwenden.

Quellen:

http://www.maier-komor.de/mtwrite.html
http://lwn.net/Articles/400489/
https://wiki.ncsa.illinois.edu/display/~wglick/Parallel+Rsync
http://wiki.ubuntuusers.de/rsync


Montag, 19. Mai 2014

Android. App in den Hintergrund, anstatt zu beenden.

statt

finish();

folgenden Code verwenden:

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(startMain);
 

Samstag, 17. Mai 2014

Android Webview App. Beim Aufrufen der App bei Klick auf Push Notification wird eine neue Activity erstellt. Fix.

Szenario:

Man hat eine App bzw. in meinem Fall eine Webview App. Per Push erhält man eine Nachricht, dass eine neue Nachricht eingegangen ist. Man klickt nun auf die Push-Notification und anstatt die eventuell vorhandene Activity zu öffnen, wird eine neue Activity gestartet. Das wollte ich gern vermeiden.

Nach echt langer Recherche bin ich dann auf diesen Link gestoßen: http://www.helloandroid.com/tutorials/communicating-between-running-activities

Relevanter Inhalt:

In der Main-Activity:

protected void onNewIntent(Intent intent) {
     super.onNewIntent(intent);
     setIntent(intent);//must store the new intent unless getIntent() will return the old one
       intent = getIntent();
        WebView myWebView = (WebView) findViewById(R.id.webview);
          myWebView.loadUrl(url);
    }

In der Notifiaction Sende Klasse:

Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("tag", tag);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);