Posts mit dem Label MySQL werden angezeigt. Alle Posts anzeigen
Posts mit dem Label MySQL werden angezeigt. Alle Posts anzeigen

8.12.17

MySQL - Schnellere Inserts

1. Je mehr Indizes, desto langsamer die Inserts!

Bei 20000 Einträgen dauert das Befüllen auf herkömmlichem Wege auf einem RPI3 ca. 140 Sekunden. Optimiert dauert es ca. 1.5 Sekunden!!!

Code, um Zeitaufwand für Inserts zu vergleichen.

function my_autoloader($class)
{
    include 'include/' . $class . '.php';
}
$cache=5000;
$usecache = true;
$inserts=10000;
spl_autoload_register('my_autoloader');
$db = new \PDO('mysql:dbname=newdb;host=localhost', 'DB', 'PASSWORD'');
for ($i = 1; $i <= $inserts; $i++)
{
    $data[] = ["id" => 1, "zip" => "30159", "name" => "Hannover", "citizens" => 50000];
}

$beginn = microtime(true);
$sql = 'INSERT IGNORE INTO testdaten (id, zip, name, citizens) VALUES ';
if ($usecache)
{
    $dbCache = new dbcache($db, $sql, $cache, true);

    foreach ($data as $entry)
    {
        $dbCache->add('(null,' . $db->quote($entry['zip']) . ',' . $db->quote($entry['name']) . ',' . ((int) $entry['citizens']) . ')');
    }
    $dbCache->flush();
}
 else
{
     $cache=0;
     foreach ($data as $entry)
     {
         $sql2= $sql . " ('null','" . $entry['zip'] . "','". $entry['name'] . "','" . $entry['citizens'] . "')";
         //echo "debug: $sql"; die;
         $db->query($sql2);
     }
}
$dauer = microtime(true) - $beginn;
echo "Verarbeitung des Skripts: $dauer Sek.<br>";
$sql = "SELECT count(*) from testdaten";
$result = $db->query($sql);
echo "Anzahl der Datensätze: " . $result->fetchColumn() . "<br>";
$db->query("TRUNCATE table testdaten");
$db->query("INSERT INTO performance (inserts, zeit, cache) VALUES"
        . "('$inserts','$dauer','$cache')");
DBCache Klasse, gefunden hier.

class dbcache
{
    public $lastQuery;

    private $db, $limit, $sql, $cache = [], $auto;

    /**
     * @param \PDO   $db
     * @param string $sqlPrefix
     * @param int    $limit
     * @param bool   $autoFlush
     */
    public function __construct(\PDO $db, $sqlPrefix, $limit, $autoFlush = false)
    {
        $this->db    = $db;
        $this->limit = $limit;
        $this->auto  = $autoFlush;
        $this->sql   = $sqlPrefix;
    }

    /**
     * @param string $query
     */
    public function add($query)
    {
        $this->cache[] = $query;

        if ($this->auto) {
            $this->softFlush();
        }
    }

    /**
     * Flush cache and query database.
     */
    public function flush()
    {
        if (empty($this->cache)) {
            return;
        }

        // save query for logging, if something goes wrong
        $this->lastQuery = $this->sql.implode(',', $this->cache);

        $this->db->query($this->lastQuery);
        $this->cache = [];
    }

    /**
     * Flush cache if limit is reached.
     */
    public function softFlush()
    {
        if (count($this->cache) >= $this->limit) {
            $this->flush();
        }
    }
}

29.6.17

Ergebnisse aus NMAP in eine MySQL Datenbank schreiben

Es gibt bei Nmap die Möglichkeit die Ergebnisse von Netzwerkscans in eine XML-Datei zu schreiben. Die Weiterverarbeitung mit Linux-Bordmitteln ist jedoch nicht ganz trivial. Jedenfalls habe ich es mit xmlstartlet nicht so richtig hinbekommen.
Nmap wird z.B. gestartet mit

nmap -Pn 192.168.0178.0/24 -oX output/ZIELDATEI.xml

Mit einem Einzeiler, wie

xmlstarlet sel -t -m '/nmaprun/host' -v 'address[@addrtype="ipv4"]/@addr' -o ":" -v 'ports/port/@portid' -n /var/www/html/netzinfo/output/ZIELDATEI.xml

bekomme ich zwar alle Ports nacheinander angezeigt, doch die Zuordnung von IP Adressen zu den offenen Ports muss noch erfolgen.

Da ich das Ergebnis sowieso noch einmal durchgehen muss und alles in eine MySQL Datenbank eintragen will, habe ich mir das Ganze etwas vereinfacht und eine Sprache genommen, die ich etwas besser beherrsche: PHP.

Die Ausgabedatei habe ich testweise so eingeladen und ausgegeben:

$xml = file_get_contents("output/ZIELDATEI.xml");
$p = \xml_parser_create();
\xml_parse_into_struct($p, $xml, $data, $values);
\xml_parser_free($p);
echo "Index array <br><pre>";
print_r($values);
echo "data array <br><pre>";
print_r($data);
Ausgabe (auszugsweise):
260] => Array
        (
            [tag] => ADDRESS
            [type] => complete
            [level] => 3
            [attributes] => Array
                (
                    [ADDR] => 192.168.178.150
                    [ADDRTYPE] => ipv4
                )

        )

    [261] => Array
        (
            [tag] => HOST
            [value] => 

            [type] => cdata
            [level] => 2
        )

    [262] => Array
        (
            [tag] => ADDRESS
            [type] => complete
            [level] => 3
            [attributes] => Array
                (
                    [ADDR] => 74:75:48:A4:48:A8
                    [ADDRTYPE] => mac
                    [VENDOR] => Amazon Technologies
                )

        )
Auch hier ist es nicht so einfach, eine einwandfrei Zuordnung, von z.B. IP - Adressen zu offenen Ports und Mac-Adressen zu treffen.
Geholfen haben mir die Beispiele auf php.net und zwar die Funktion von efredericksen.

<?php class XmlElement {
  var
$name;
  var
$attributes;
  var
$content;
  var
$children;
};

function
xml_to_object($xml) {
 
$parser = xml_parser_create();
 
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
 
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
 
xml_parse_into_struct($parser, $xml, $tags);
 
xml_parser_free($parser);

 
$elements = array();  // the currently filling [child] XmlElement array
 
$stack = array();
  foreach (
$tags as $tag) {
   
$index = count($elements);
    if (
$tag['type'] == "complete" || $tag['type'] == "open") {
     
$elements[$index] = new XmlElement;
     
$elements[$index]->name = $tag['tag'];
     
$elements[$index]->attributes = $tag['attributes'];
     
$elements[$index]->content = $tag['value'];
      if (
$tag['type'] == "open") {  // push
       
$elements[$index]->children = array();
       
$stack[count($stack)] = &$elements;
       
$elements = &$elements[$index]->children;
      }
    }
    if (
$tag['type'] == "close") {  // pop
     
$elements = &$stack[count($stack) - 1];
      unset(
$stack[count($stack) - 1]);
    }
  }
  return
$elements[0];  // the single top-level element}
Die Ausgabe ist so, dass ich dann durch alle Ergebnisse der Nmap Ausgabe interieren kann.
Das PHP Script sieht so aus (quick and dirty):


$xml=file_get_contents("output/ZIELDATEI.xml");
$object = \xml_to_object($xml)->children;
// Gehe alle Objekte durch:
$anzahl = count($object);
for($i=0; $i<$anzahl; $i++)
{
    // IP Adresse
    $ip = $object[$i]->children[1]->attributes['addr'];
    if(strlen($ip)<1) continue;
    echo "Adresse: $ip<br>";
    // Rechnername
    $name=$object[$i]->children[3]->children[0]->attributes['name'];
    echo "Name: $name <br>";
    // MAC Adresse
    $mac=$object[$i]->children[2]->attributes['addr'];
    echo "MAC Adresse: $mac <br>";
    $vendor=$object[$i]->children[2]->attributes['vendor'];
    echo "Hersteller: $vendor <br>";
    // Offene Ports
    $anzahlports=count($object[$i]->children[4]->children);
    $port=""; $ports="";
    for($a=0;$a<$anzahlports; $a++)
    {
        $port=$object[$i]->children[4]->children[$a]->attributes['portid'];
        if(strlen($port)>0)
        {
            $ports.= $port . ";";
        }
    }
    echo "Offene Ports: $ports <br>";
}

Mit diesen Daten kann ich nun weiterarbeiten und sie z.B. in eine MySQL Datenbank schreiben.
Vielleicht hat jemand einfachere Lösungen??



12.1.17

Postfixadmin

apt-get install postfixadmin

Fix:
1. /etc/postfixadmin/dbconfig.inc.php
$dbtype=mysqli

2. Fehler:bei https://gehrdener.de/postfixadmin/setup.php?debug=1
DEBUG INFORMATION:
Invalid query: Invalid default value for 'created'


Fix:
Strict Mode off:

Erstelle
/etc/mysql/conf.d/disable_strict_mode.cnf
 
Inhalt:
sql_mode=IGNORE_SPACE,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 
service mysql restart
 
 
Alias definieren in /etc/main.cf
 virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_alias_maps.cf

Inhalt:
hosts = localhost
user = [DBUSER]
password = [PASSWORD]
dbname = [DBNAME]
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
 
Virtuelle Domänen
Main.cf: 
virtual_alias_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf

 
In der mysql-virtual_domains.cf  
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'

27.10.16

Joomla - Inhalte per Script auf neue Version übertragen

Ich stand vor dem Problem, die Inhalte einer ziemlich alten Joomla Version (V 1.5) auf eine neue Joomla Installation zu übertragen.

Hier ein schnell dahin gehacktes Script. Dieses muss noch mit den Zugangsdaten der alten und neuen Datenbank angepasst werden. Dann noch die Startwerte von  $rgt und $lft anpassen. Ich habe keine Ahnung, wozu sie sind. Auf jeden Fall müssen sie hochgezählt werden. Einfach mal in die Tabelle assets nach den entsprechenden Spalten gucken und die letzten Werte +1 übernehmen in das Script.

<?php


$prefix = "c27gy_";
$rgt = 36;
$lft = 35;

class mydatabase
{

    var $database = "";
    var $prefix = "c27gy_"; // Prefix der Joomla Tabellen

   
    function db_connect($database)
    {
       
        $user = "[user]";
        $pw = "[PASSWORD]";

        $mysqli = new mysqli("localhost", $user, $pw, $database);
        /* check connection */
        if (mysqli_connect_errno())
        {
            $error = "Connect failed: " . mysqli_connect_error();
            //$this->errorReport($error, true);
            exit();
        }
        $mysqli->query("SET NAMES 'utf8'");
        return $mysqli;
    }


    function getAssetID($title, $lft, $rgt, $name)
    {
       
        $sql_asset = "INSERT INTO " . $this->prefix . "assets
    (level,name,title, lft, rgt, parent_id, rules)
    VALUES
    ('3', '$name','$title', '$lft', '$rgt', '27','{\"core.admin\":{\"7\":1},\"core.manage\":{\"6\":1},\"core.create\":{\"3\":1},\"core.delete\":[],\"core.edit\":{\"4\":1},\"core.edit.state\":{\"5\":1},\"core.edit.own\":[]}')";
        $link=$this->db_connect("[DATABASE]");
        $link->query($sql_asset);
        //echo "DEBUG $sql_asset <br>";
        return $link->insert_id;
    }

    function truncateTables()
    {
        $link=$this->db_connect($this->db_new);
        // Die u.a. id anpassen!!! Nicht, dass existente Datensätze gelöscht werden
        $link->query("DELETE FROM " . $this->prefix . "assets WHERE id > 65");
        $link->query("TRUNCATE TABLE " . $this->prefix . "content");
        $link->query("TRUNCATE TABLE " . $this->prefix . "content_frontpage");
       
    }
}

$db = new \mydatabase();
// ACHTUNG: NICHT UNBEDINGT NÖTIG!!
//$db->truncateTables(); // Tabellen leeren bzw. Einträge löschen

// Mit den Datenbanken verbinden
$link = $db->db_connect("[DATABASE]");
$link1 = $db->db_connect("[DATABASE_OLD]");
// Daten aus der alten Tabelle holen
$sql_abfrage = "SELECT * FROM jos_content where state=1 ORDER by created DESC";
$result = $link1->query($sql_abfrage);
$zaehler = 0;
while ($row = $result->fetch_array())
{
    $zaehler++;

    echo $zaehler . " " . $row['alias'] . "<br>";
    $title = $row['title'];
    $alias = $row['alias'];
    $introtext = $row['introtext'];
    $fulltext = $link->real_escape_string($row['fulltext']);
    $created = $row['created'];
    $old_id=$row['id'];
    $id = $db->getAssetID($title, $lft, $rgt, "com_content.article." . $old_id);
    $rgt+=2;
    $lft+=2;
    $sql_insert = "INSERT INTO ${prefix}content (
                asset_id,
                title,
                alias,
                state,
                catid,
                introtext,
                `fulltext`,
                language,
                created, publish_up,
                featured,
                version,
                access)
VALUES('$id', '$title',
        '$alias',
        1,
        2,
         '$introtext',
         '$fulltext',
         '*',
        '$created', '$created',
         1,
         2,
         1)";
    if(!$link->query($sql_insert))
    {
        echo "Fehler! " . $link->error . "<br>$sql_insert";
    }
    $content_id=$link->insert_id;
   
    $sql_frontpage="INSERT INTO ${prefix}content_frontpage (content_id, ordering)
    VALUES ('$content_id', '$zaehler')";
    if(!$link->query($sql_frontpage))
    {
        echo "Fehler! " . $link->error . "<br>$sql_frontpage";
    }
}

23.7.13

PHP und JS Schnipsel - Datumsfunktionen

Datum aus einer MySQL-Datenbank formatieren:


$datum_de = date("d.m.Y ", strToTime($datum));



Datumspicker mit jquery einbinden:

  1. Framework und CSS einbinden 
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"</script>
    <script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js">
    </script> <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" type="text/css" />
  2. Funktion definieren (geht auch ohne PHP :))
function datepicker($fieldId)
{
    ?>
    <script type="text/javascript">

        jQuery(function($){
            $.datepicker.regional['de'] = {clearText: 'enternen', clearStatus: 'Auswahl löschen',
                closeText: 'schließen', closeStatus: 'Änderungen nicht übernehmen',
                prevText: 'vorheriger Monat', prevStatus: 'vorheriger Monat',
                nextText: 'nächster Monat', nextStatus: 'nächster Monat',
                currentText: 'heute', currentStatus: '',
                monthNames: ['Januar','Februar','März','April','Mai','Juni',
                    'Juli','August','September','Oktober','November','Dezember'],
                monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
                    'Jul','Aug','Sep','Okt','Nov','Dez'],
                monthStatus: 'anderer Monat', yearStatus: 'anderes Jahr',
                weekHeader: 'Wo', weekStatus: 'Woche des Monats',
                dayNames:
                    ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
                dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
                dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
                dayStatus: 'Setze DD als ersten Wochentag', dateStatus: 'Wähle D, M d',
                dateFormat: 'yy-mm-dd', firstDay: 1,
                changeMonth: true,
                changeYear: true,
                initStatus: 'Bitte wählen Sie ein Datum', isRTL: false};
            $.datepicker.setDefaults($.datepicker.regional['de']);
        });
        $(function() {
            <?php echo "\$(\"#" . $fieldId . "\").datepicker();";
            ?>
        });

    </script>
    <?php
}

29.4.13

Verschlüsselte Verbindung mit MySQL Server

Diese Anleitung ist sehr gut, jedoch gab es bei immer noch folgende Fehlermeldung, obwohl die Rechte zu den Pfaden mit chown mysql:mysql entsprechend angepasst wurden:

SSL error: Unable to get certificate from '/etc/ssl/mysql/server.cert'
130429 13:09:59 [Warning] Failed to setup SSL
130429 13:09:59 [Warning] SSL error: Unable to get certificate

Erst dieser Fund hat die Lösung gebracht.

Und wieder war Apparmor mein Problem :(

Auch diese Anleitung ist ganz gut gemacht :)


29.10.12

XML Ausgabe mit MySQL

Eher durch Zufall bin ich auf eine Funktion in MySQL gestoßen, mit der man Daten als XML ausgeben kann.

Dazu kann man sich in der Konsole einloggen mit:

mysql -uroot -p --xml;

Jetzt erfolgen alle Ausgaben auf Selects, showdatabases etc. im XML-Format:

show databases;

<?xml version="1.0"?>

<resultset statement="show databases;" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <row>
        <field name="Database">information_schema</field>
  </row>
  <row>
        <field name="Database">mysql</field>
  </row>

  <row>
        <field name="Database">performance_schema</field>
  </row>
</resultset>

14.8.12

Wenn MySQL mal nicht funktioniert

Fehlermeldung:

 Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)



Einstellungen in Apparmor überprüfen:


/etc/apparmor.d/usr.sbin.mysqld


Openhab und Ecoflow Max - API Anbindung

 Ich wollte die neu erworbene Powerstation in Openhab einbinden, um den aktuellen Status (Ladestand etc.) über Openhab auswerten zu können. ...