<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Willkommen bei der eL Mediaagentur &#187; Datenbanken</title>
	<atom:link href="http://www.el-mediaagentur.com/best-practice/datenbanken/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.el-mediaagentur.com</link>
	<description>die kreative Agentur aus dem Herzen Kölns</description>
	<lastBuildDate>Fri, 02 Apr 2010 19:18:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex,follow" />
		<item>
		<title>PL/SQL Embedded Gateway</title>
		<link>http://www.el-mediaagentur.com/2010/03/19/plsql-embedded-gateway/</link>
		<comments>http://www.el-mediaagentur.com/2010/03/19/plsql-embedded-gateway/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 18:08:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[APEX]]></category>
		<category><![CDATA[apxconf.sql]]></category>
		<category><![CDATA[CREATE_DAD]]></category>
		<category><![CDATA[Embedded]]></category>
		<category><![CDATA[Gateway]]></category>
		<category><![CDATA[GETHTTPPORT]]></category>
		<category><![CDATA[Oracle 11g]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[SETHTTPPORT]]></category>
		<category><![CDATA[SET_DAD_ATTRIBUTE]]></category>

		<guid isPermaLink="false">http://www.el-mediaagentur.com/?p=302</guid>
		<description><![CDATA[Seit Oracle 11g und APEX 3.0.1 hat man die Wahl einen Apache (1.3 oder 2.0) Webserer mit mod_plsql oder dem integrierten PL/SQL Gateway für die Bereitstellung  dynamisch erstellter PL/SQL Inhalte zu nutzen. Wer bsp. PL/SQL Prozeduren online ausführbar machen möchte und auf die Verwendung eines eigenständigen Apache Webservers (Proxy-Server, URL-Rewriting, Filesystem etc.) verzichten kann, [...]]]></description>
			<content:encoded><![CDATA[<p><b>Seit Oracle 11g und APEX 3.0.1 hat man die Wahl einen Apache (1.3 oder 2.0) Webserer mit mod_plsql oder dem integrierten PL/SQL Gateway für die Bereitstellung  dynamisch erstellter PL/SQL Inhalte zu nutzen. Wer bsp. PL/SQL Prozeduren online ausführbar machen möchte und auf die Verwendung eines eigenständigen Apache Webservers (Proxy-Server, URL-Rewriting, Filesystem etc.) verzichten kann, der ist mit dem PL/SQL Embedded Gateway gut beraten. Im Folgenden wird die einfache Installation bzw. Aktivierung des PL/SQL Embedded Gateway beschrieben.</b><span id="more-302"></span></p>
<div id="inline_ad" style="float: left;">
<script type="text/javascript"><!--
google_ad_client = "pub-2821839982812174";
/* Mediaum Rectangle 300x250 (leicht abgr.), Erstellt 27.02.08 */
google_ad_slot = "3929261217";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p>Um den PL/SQL Embedded Gateway zu verwenden, führt man als SYS zuerst das folgende</p>
<pre class="brush: bash;">
SQL&gt; @$ORACLE_HOME/apex/apxconf.sql;
</pre>
<p>Konfigurations-Skript aus. Dieses SQL-Skript fragt nach dem HTTP-Port, über den später PL/SQL per URL angesprochen werden kann. Mit</p>
<pre class="brush: bash;">
SQL&gt; EXEC DBMS_XDB.SETHTTPPORT(8080);
</pre>
<p>kann dieser Port nachträglich verändert werden. Ein Aufruf mit Port 0 </p>
<pre class="brush: bash;">
SQL&gt; EXEC DBMS_XDB.SETHTTPPORT(0);
</pre>
<p>deaktivert den PL/SQL embedded Gateway und mit</p>
<pre class="brush: bash;">
SQL&gt; SELECT DBMS_XDB.GETHTTPPORT FROM DUAL;
</pre>
<p>wird der zur Zeit verwendete Port ausgegeben.<br />
Nach der Konfiguration durch <i>apxconf.sql</i> kann mit dem Listener Status-Kommando</p>
<pre class="brush: bash;">
$ lsnrctl status
</pre>
<p>geprüft werden ob der Port aktiv ist. Es sollte eine Zeile ähnlich der folgenden </p>
<pre class="brush: bash;">
$ (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=...)(PORT=8080))(Presentation=HTTP)(Session=RAW))
</pre>
<p>mit aufgeführt werden.<br />
Um bsp. PL/SQL Prozeduren über den PL/SQL Embedded Gateway zugänglich zu machen, benötigt man außerdem einen freigeschalteten</p>
<pre class="brush: bash;">
SQL&gt; alter user ANONYMOUS account unlock
</pre>
<p>ANONYMOUS Benutzer.<br />
Des Weiteren wird ein Database Access Descriptor (DAD) benötigt. Ein DAD übernimmt in etwa die Arbeit wie mod_plsql für den Apache.<br />
Sozusagen ein Servlet für den XML DB HTTP Listener. Unter <a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28424/adfns_web.htm" target="_blank">http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28424/adfns_web.htm</a> im Abschnitt <i>Table 10-2 Mapping Between mod_plsql and Embedded PL/SQL Gateway DAD Attributes</i> sieht man zum Vergleich eine Gegenüberstellung der DAD und mod_plsql Attribute.<br />
Ein DAD wird später durch einen Teil in der URL repräsentiert bzw. angesprochen.<br />
Mit </p>
<pre class="brush: bash;">
SQL&gt; EXEC DBMS_EPG.CREATE_DAD('PL_SQL', '/plsql/*');
</pre>
<p>erstellt man ein DAD mit der Bezeichnung <i>PL_SQL</i> und dem URL-Teilpfad <i>/plsql/</i>.<br />
Damit der ANONYMOUS Benutzer für das DAD als eine Art &#8220;Schnittstelle&#8221; zwischen der DB und dem DAD zu fungieren kann, stellt man mit</p>
<pre class="brush: bash;">
SQL&gt; EXEC DBMS_EPG.SET_DAD_ATTRIBUTE('PL_SQL', 'database-username', 'ANONYMOUS');
</pre>
<p>den ANONYMOUS Benutzer für das DAD ein.<br />
Ab hier wäre der PL/SQL Embedded Gateway grundlegend konfiguriert. Um nun eine Prozedur eines Benutzers öffentlich über den<br />
PL/SQL Embedded Gateway zur Verfügung zu stellen, muß die Prozedur für PUBLIC per</p>
<pre class="brush: bash;">
SQL&gt; GRANT execute on PROZEDUR_NAME to public;
</pre>
<p>die Ausführbarkeit dieser Prozedur erlaubt werden. Wird in dieser Prozedur auf andere Objekte zugeriffen, müssen auch für diese die entsprechenden<br />
Rechte (bsp. für Tabellen GRANT select on TABELLEN_NAME to public) vergeben werden. Erst anschließend ist nach folgenden URL-Schema</p>
<pre class="brush: bash;">

http://www.domain.de/plsql/objekt_inhaber.objekt_name
</pre>
<p>das Objekt aufrufbar.</p>
<h3>Fazit</h3>
<p>Der PL/SQL Embedded Gateway ist eine einfache Methode um datenbanknah Objekte oder APEX-Applikationen per Browser ausführbar zu machen. Es entfällt<br />
die umfangreiche Konfiguration eines Apache Webservers. Auch sichere Verbindungen per SSL sind möglich. Benötigt man keine Sonderfunktionen á la<br />
URL-Umschreibung (mod_rewrite) oder einen Auslagerung des Webserver (Perormanz-und Sicherheitsaspekte) und Ähnliches, dann reicht ein PL/SQL<br />
Embedded Gateway für die meisten Fälle aus. </p>
<h3>Hinweis</h3>
<p>Diese Anleitung ist ein praktischer Leitfaden ohne Gewähr.</p>
<h3>Weiterführende Literatur</h3>
<p>empfehlenswert sind folgende Bücher:</p>
<ul>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3826655494/elmediaagentu-21/" target="_blank">Oracle APEX und Oracle XE in der Praxis</a> von Dietmar Aust, Jens-Christian Pokolm und Denes Kubicek</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3827326362/elmediaagentu-21/" target="_blank">Oracle 10g für den DBA: Effizient konfigurieren, optimieren und verwalten</a> von Johannes Ahrends, Dierk Lenz, Patrick Schwanke, und Günther Unbescheid</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3772373259/elmediaagentu-21/" target="_blank">Oracle 11g: Das umfassende Handbuch</a> von Lutz Fröhlich</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.el-mediaagentur.com/2010/03/19/plsql-embedded-gateway/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Binary Log Recovery</title>
		<link>http://www.el-mediaagentur.com/2008/03/15/mysql-binary-log-recovery/</link>
		<comments>http://www.el-mediaagentur.com/2008/03/15/mysql-binary-log-recovery/#comments</comments>
		<pubDate>Sat, 15 Mar 2008 17:18:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Binary Log]]></category>
		<category><![CDATA[my.cnf]]></category>
		<category><![CDATA[MySQL Binary Log]]></category>
		<category><![CDATA[mysqlbinlog]]></category>
		<category><![CDATA[punktgenaue Wiederherstellung]]></category>
		<category><![CDATA[Recovery]]></category>
		<category><![CDATA[Wiederherstellung]]></category>

		<guid isPermaLink="false">http://www.el-mediaagentur.com/index.php/archives/mysql-binary-log-recovery</guid>
		<description><![CDATA[Automatisch erzeugte Backups einer MySQL Datenbank helfen nicht in dem Zeitraum zwischen dem letzten und kommenden Backup. Es gibt einige Methoden um auch für diesen Zwischenraum (interim Daten) Datensicherheit zu gewährleisten, eine davon ist das Binary Log Recovery. 






Das Binary Log schreibt zur Laufzeit alle auf dem Server ausgeführten SQL-Transaktionen mit, dies wiederum verbraucht Ressourcen [...]]]></description>
			<content:encoded><![CDATA[<p><b>Automatisch erzeugte Backups einer MySQL Datenbank helfen nicht in dem Zeitraum zwischen dem letzten und kommenden Backup. Es gibt einige Methoden um auch für diesen Zwischenraum (interim Daten) Datensicherheit zu gewährleisten, eine davon ist das Binary Log Recovery. </b><span id="more-38"></span></p>
<div id="inline_ad" style="float: left;">
<script type="text/javascript"><!--
google_ad_client = "pub-2821839982812174";
/* Mediaum Rectangle 300x250 (leicht abgr.), Erstellt 27.02.08 */
google_ad_slot = "3929261217";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p>Das Binary Log schreibt zur Laufzeit alle auf dem Server ausgeführten SQL-Transaktionen mit, dies wiederum verbraucht Ressourcen (je nach Frequentierung >= 1% CPU), weshalb manche Administratoren die Aktivität des binären loggen eingrenzen oder gar ausschalten. Die Vorteile die das Binary Log mitbringt sind aber enorm, insbesondere wenn neue Applikationen fehlerhafte SQL-Anweisungen absetzen.</p>
<h3>Binäres Loggen konfigurieren</h3>
<p>Alle Einstellungen die das Binary Log betreffen werden in der <i>/etc/mysql/my.cnf</i> vorgenommen</p>
<pre class="brush: bash;">
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
</pre>
<p>Durch <i>log_bin</i> wird der Speicherort der Log-Dateien bestimmt. <i>expire_logs_days</i> bestimmt den Zeitraum, in welchen die Logs aufbewahrt werden sollen, in dem Beispiel werden alle Logs die älter sind als 10 Tage entfernt. <i>max_binlog_size</i> gibt die maximal zugelassene Dateigröße für ein Log-File an. Die Angabe von <i>max_binlog_size</i> sollte unter Debian Systemen nie ohne die Einstellung <i>log_bin</i> aufgeführt werden, da hier der Server abstürzen würde. Je nachdem wieviele SQL-Statements erzeugt werden ist abzuwägen welche Größe und welcher Zeitraum berücksichtigt bzw. zugelassen werden soll. Unbedacht erstellte Applikationen können manchmal riesige Mengen an SQL-Anweisungen innerhalb eines Tages erzeugen, wenn diese Anwendung auch noch von mehreren Benutzern gleichzeitig benutzt wird, kann man sich ausmalen, dass die Grenzen eines zu klein gewählten Log-Files schnell erreicht sind und dann wäre der Vorteil dahin. Um Änderungen an der <i>my.cnf</i> wirksam zu machen, muß der MySQL Server neugestartet werden.</p>
<h3>Einfaches Wiederherstellen</h3>
<p>Durch das binäre Loggen in Verbindung mit der Sicherung der binären Log-Dateien ist es möglich ein vollst. Backup-Konzept zu erstellen. Empfehlen würde ich in Hinsicht auf die mitgeführten redundanten Daten nicht. Praktikabler ist das normale tägliche Backup (bsp. per MySQL Dump oder ähnliches) in Kombination mit dem Binary Log.<br />
Ein alltägliches Backup Szenario könnte folgendermaßen aussehen, vorrausgesetzt das tägliche Backup (bsp. immer um 00:00Uhr) und das Binary Log sind aktiv. Angenommen alle Daten gingen aus irgendeinem Grund verloren, dann ist der erste Schritt den Zugriff auf die Datenbank exklusiv für den Administrator zu setzen:</p>
<pre class="brush: bash;">$ mysqld --socket=/tmp/mysql_restore.sock --skip-networking</pre>
<p><i>skip-networking</i> ermöglicht den Zugriff nur über SSH oder direkt an der Server Konsole.<br />
Nach der Einschränkung des Zugriffs von außen, kann das tägliche Backup per Konsole eingespielt werden um so den Datenstand vom Vortag zu erhalten:</p>
<pre class="brush: bash;">$ mysql -u root -ppassword  --socket=/tmp/mysql_restore.sock \
    &lt; /var/backup/20080325.sql
</pre>
<p>Mit diesem Befehl wird das SQL Backup direkt auf den <i>mysql_restore.sock</i> geleitet. Anschliessend müssen noch die interim Daten wiederhergestellt werden, also die Daten die nach 00:00Uhr entstanden sind. Dazu verwendet man das Werkzeug <i>mysqlbinlog</i>. Vor Benutzung des Tools muß herausgefunden werden welche Log Dateien den jetzigen Tag betreffen, ein einfacher <i>ls -la</i> auf der Konsole im Binary Log Verzeichnis wird alle nötigen Informationen liefern. Nun kann von der kleinsten laufenden Nummer auftsteigend zum neuesten Log folgendermaßen vorgegangen werden:</p>
<pre class="brush: bash;">$ mysqlbinlog /var/log/mysql/mysql-bin.000xxx \
   | mysql -u root -ppassword \
           --socket=/tmp/mysql_restore.sock
</pre>
<p>Mit diesem Befehl werden alle Statements die durch das Binary Log in der Log Datei aufgezeichnet wurden direkt auf der MySQL Datenbank abgesetzt und erneut ausgeführt. Wenn man alle Log-Daten so abgearbeitet hat, hat man alle Daten bis zum DB-Crash wiederhergestellt. Ein abschliessender MySQL-DB Neustart wird die Datenbank wieder zur Verfügung stellen.</p>
<h3>Manuelles Wiederherstellen</h3>
<p>Es kann vorkommen, dass man nicht alle Daten wiederherstellen möchte, da nur eine fehlerhafte Anweisung Daten gelöscht hat. Dazu <i>piped</i> (umleiten) man die Ausgabe nicht direkt auf den MySQL Socket um, sondern in ein seperate Textdatei:</p>
<pre class="brush: bash;">$ mysqlbinlog /var/log/mysql/mysql-bin.000xxx \
    &gt; /tmp/tmp_mysql-bin-000xxx..sql
</pre>
<p>Danach kann mit <i>vi</i> oder <i>vim</i> oder einem anderen Texteditor die temporäre erstellte Datei bearbeitet werden, eventuell fehlerhafte Anweisungen entfernt und danach erneut in die DB eingespielt werden.</p>
<h3>Punktgenaues Wiederherstellen (Zeitstempel)</h3>
<p>Ab MySQL Version 4.1.4 sind die Parameter <i>&#8211;start-date</i> und <i>&#8211;stop-date</i> hinzugefügt wurden. Diese ermöglichen punktuelles Recovery. Beispielsweise löschte eine Anweisung die um 12:00Uhr am 23.03.2008 ausgeführt wurde einige Daten. Die Vorgehensweise wäre die gleiche wie die eben beschriebene, man spielt das tägliche Backup zurück und führt anschliessend folgendes Kommando aus:</p>
<pre class="brush: bash;">$ mysqlbinlog --stop-date=&quot;2008-03-23 11:59:59&quot;
      /var/log/mysql/bin.000xxx |
    mysql -u root -ppassword \
          --socket=/tmp/mysql_restore.sock
</pre>
<p>Hiermit werden alle SQL-Statements die bis 11:59:59 aufgelaufen sind neu auf der Datenbank ausgeführt. Wenn man die fehlerverursachende SQL-Anweisung nicht exakt ausfindig machen kann, dann möchte man vielleicht an dieser Stelle alle Anweisungen die nach dem Fehlerzeitraum abgesetzt wurden wiederherstellen:</p>
<pre class="brush: bash;">$ mysqlbinlog --start-date=&quot;2008-03-23 12:00:01&quot;
      /var/log/mysql/bin.000xxx |
    mysql -u root -ppassword \
          --socket=/tmp/mysql_restore.sock
</pre>
<p>Mit diesen beiden Parametern kann man sehr punktuell Daten wiederherstellen und fehlerhafte SQL-Anweisungen zu umgehen.</p>
<h3>Punktgenaues Wiederherstellen (Positionsangabe)</h3>
<p>Nach dem gleichen Prinzip wie <i>start-date</i> und <i>stop-date</i> funktioniert <i>start-position</i> und <i>stop-position</i>. Wenn man eine binäre Log-Datei in eine Textdatei ausgibt, dann erkennt man das jedes SQL-Statement eine eindeutige Log-Positionsangabe mitführt, auf dieser Basis kann man genauso punktuell Daten wiederherstellen. Wann wird diese Vorgehensweise notwendig? Ganz einfach, wenn man den ungefähren Zeitpunkt des Problemfalles nicht kennt, dann führt kein Weg an dieser Methode vorbei.</p>
<h3>Fazit</h3>
<p>Die Nachteile liegen in dem Verbrauch der Ressourcen, SQL-Statement lastige Anwendungen fluten die Logs, es gilt abzuwägen, wieviel Ressourcen man hierfür als notwendig ansieht. Die Vorteile heben sich aber deutlich von den Nachteilen ab. Ich kam selbst in den Genuß eine MySQL Datenbank in 5 Minuten wieder in ordnungsgemäßen Zustand versetzen zu dürfen, seitdem ist für mich ist das Binary Log Recovery unverzichtbar um eine bessere Datensicherheit bzw. geringere Ausfallzeiten zu gewährleisten.</p>
<h3>Hinweis</h3>
<p>Diese Anleitung ist ein praktischer Leitfaden ohne Gewähr.</p>
<h3>Weiterführende Literatur</h3>
<p>empfehlenswert sind folgende Bücher:</p>
<ul>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3827324041/elmediaagentu-21/" target="_blank">Das offizielle MySQL 5-Handbuch</a> von  MySQL MySQL AB</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3827326362/elmediaagentu-21/" target="_blank">MySQL 5. Einführung, Programmierung, Referenz (Open Source Library)</a> von Michael Kofler</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3772373259/elmediaagentu-21/" target="_blank">MySQL 5. Für Professionals</a> von Axel Bornträger</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.el-mediaagentur.com/2008/03/15/mysql-binary-log-recovery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Volltextsuche (engl. Full-Text Search) in 3 Schritten</title>
		<link>http://www.el-mediaagentur.com/2008/01/30/mysql-volltextsuche-engl-full-text-search-in-3-schritten/</link>
		<comments>http://www.el-mediaagentur.com/2008/01/30/mysql-volltextsuche-engl-full-text-search-in-3-schritten/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 15:08:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Full-Text]]></category>
		<category><![CDATA[Full-Text search]]></category>
		<category><![CDATA[Fulltext]]></category>
		<category><![CDATA[Fulltext Index]]></category>
		<category><![CDATA[Linux Backup]]></category>
		<category><![CDATA[Match]]></category>
		<category><![CDATA[Match Against]]></category>
		<category><![CDATA[MySQL Volltextsuche]]></category>
		<category><![CDATA[Relevanzbestimmung]]></category>
		<category><![CDATA[Stopwort]]></category>
		<category><![CDATA[Stopwortliste]]></category>
		<category><![CDATA[Volltextindezierung]]></category>

		<guid isPermaLink="false">http://www.el-mediaagentur.com/index.php/archives/mysql-volltextsuche-engl-full-text-search-in-3-schritten</guid>
		<description><![CDATA[Die Volltextsuche ist ein gutes Werkezeug, um dem Benutzer mehr Komfort bei der Suche auf der eigenen Webseite, durch relevantere Ergebnisse, zu ermöglichen und diese dem Webseiten-Besucher in geeigneter Form zu präsentieren.






Mit Hilfe der Volltextindizierung, bietet MySQL die Funktionalität der Volltextsuche in MyISAM Tabellentypen an. Mit dem Indextyp FULLTEXT versehene CHAR-, VARCHAR- und TEXT-Spalten ermöglichen [...]]]></description>
			<content:encoded><![CDATA[<p><b>Die Volltextsuche ist ein gutes Werkezeug, um dem Benutzer mehr Komfort bei der Suche auf der eigenen Webseite, durch relevantere Ergebnisse, zu ermöglichen und diese dem Webseiten-Besucher in geeigneter Form zu präsentieren.</b><span id="more-30"></span></p>
<div id="inline_ad" style="float: left;">
<script type="text/javascript"><!--
google_ad_client = "pub-2821839982812174";
/* Mediaum Rectangle 300x250 (leicht abgr.), Erstellt 27.02.08 */
google_ad_slot = "3929261217";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p>Mit Hilfe der Volltextindizierung, bietet MySQL die Funktionalität der Volltextsuche in MyISAM Tabellentypen an. Mit dem Indextyp <i>FULLTEXT</i> versehene <i>CHAR</i>-, <i>VARCHAR</i>- und <i>TEXT</i>-Spalten ermöglichen die benutzerfreundliche Suche. Näheres unter <a href="http://dev.mysql.com/doc/refman/5.1/de/fulltext-search.html" target="_blank">http://dev.mysql.com/doc/refman<br />/5.1/de/fulltext-search.html</a> einsehbar.</p>
<h3>1. Schritt &#8211; Volltext Index erstellen</h3>
<p>Es existieren zwei Wege einen Volltextindex zu erstellen, bei der Neuerstellung einer Tabelle oder dem nachträgliche Hinzufügen. Bei der Erstellung einer Tabelle sehe dies auf dem MySQL-Prompt wie folgt aus:</p>
<p class="code">mysql> CREATE TABLE testtabelle (<br />
    ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,<br />
    ->   testspalte1 VARCHAR(200),<br />
    ->   testspalte2 TEXT,<br />
    ->   FULLTEXT (testspalte1,testspalte2)<br />
    -> );</p>
<p>Das nachträgliche Hinzufügen des Fulltextindex ist mit der <i>ALTER</i>-Anweisung möglich:</p>
<p class="code">mysql> ALTER TABLE testtabelle ADD FULLTEXT (testspalte1,testspalte2);</p>
<h3>2. Schritt &#8211; Eigene Stopwortliste</h3>
<p>Eine Stopwortliste ermöglicht bei der Volltextsuche Füllwörter (und, als, der etc.) bei der Relevanzberechnung zu ignorieren. Je nach Kontext der Seite möchte man eine eigene Stopwortliste verwenden um dem Webseiten-Besucher relevantere Ergebnisse zu liefern.<br />
In der <i>my.cnf</i> meldet man die eigene Stopwortliste wie folgt an:</p>
<p class="code">[mysqld]<br />
ft_stopword_file=&#8221;<i>PFAD</i>/stopword_de.c<br />
ft_min_word_len=&#8221;3&#8243;</p>
<p>Mit <i>ft_min_word_len=&#8221;3&#8243;</i> gibt man die Mindestlänge eines Suchbegriffes an, alle Suchbegriffe die kürzer sind werden ignoriert. Wird dieser Wert nicht gesetzt, gilt der <i>default</i>-Wert von vier Zeichen Mindestlänge.<br />
Die Stopwortliste ist eine Anreihung von Begrifflichkeiten mit Komma getrennt:</p>
<p class="code">    &#8220;dann&#8221;,<br />
  &#8220;das&#8221;,<br />
  &#8220;dass&#8221;
</p>
<p>Lesezugriff (644) auf die Stopwortliste ist vollkommen ausreichend.<br />
<h3>DOWNLOAD: Beispiel Stopwortliste für deutschen Sprachraum</h3>
<p><a class="download" href="http://www.el-mediaagentur.com/download.php?id=bc9121b59b6e1b728beeab096eb1cd40" title="stopword_de.c">stopword_de.c</a></p>
<h3>3. Schritt &#8211; Die Such-Query</h3>
<p>Um die Volltextsuche auch benutzen zu können, bedarf es eines abgeänderten <i>SELECT</i>s:</p>
<p class="code">mysql> SELECT id, <u>MATCH (testspalte1,testspalte2) AGAINST (&#8216;<i>Suchwort</i>&#8216;)</u> AS rang<br />
FROM testtabelle<br />
WHERE <u>MATCH (testspalte1,testspalte2) AGAINST (&#8216;<i>Suchwort</i>&#8216;)</u>;</p>
<p>Die unterstrichenen Bereiche der <i>SELECT</i>-Abfrage ermöglichen die Volltextsuche. Der Alias <i>rang</i> wird nach der Abfrage den Wert (0-1, wobei 0 unrelevant wäre und 1 die maximale Relevanz darstellt) für die Relevanzbestimmung annehmen.<br />
Nun kann man (hier mit PHP) dem Benutzer den Relevanzwert etwas schmackhafter servieren, indem man <i>rang</i> als prozentualen Wert umrechnet.</p>
<p class="code">&lt;?<br />
number_format(($ergebnis['rang'] * 100),0).&#8221;%&#8221;;<br />
?&gt;</p>
<p><b>Voila!</b></p>
<h3>Hinweise</h3>
<p>Die Volltextsuche lohnt sich erst bei einer hohen Datendichte. Bei ein, zwei Webseiten in der Datenbank wird die Volltextsuche kaum relevante Ergebnisse liefern, denn MySQL prüft ob der Suchbegriff in mindestens 50 Prozent der Datensätze vorhanden ist und erklärt diesen dann als unrelevant für die Abfrage. Macht ja auch Sinn, wenn man bedenkt, dass das Wort Auto auf einer Automobilhersteller-Webpräsenz ziemlich unnütz für eine Suchanfrage erscheint.</p>
<p>Diese Anleitung ist ein praktischer Leitfaden ohne Gewähr.</p>
<h3>Weiterführende Literatur</h3>
<p>empfehlenswert sind folgende Bücher:</p>
<ul>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3827324041/elmediaagentu-21/" target="_blank">Das offizielle MySQL 5-Handbuch</a> von  MySQL MySQL AB</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3827326362/elmediaagentu-21/" target="_blank">MySQL 5. Einführung, Programmierung, Referenz (Open Source Library)</a> von Michael Kofler</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3772373259/elmediaagentu-21/" target="_blank">MySQL 5. Für Professionals</a> von Axel Bornträger</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.el-mediaagentur.com/2008/01/30/mysql-volltextsuche-engl-full-text-search-in-3-schritten/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Replikation / Master und Slave in 4 Schritten</title>
		<link>http://www.el-mediaagentur.com/2008/01/27/mysql-replizierung-master-und-slave/</link>
		<comments>http://www.el-mediaagentur.com/2008/01/27/mysql-replizierung-master-und-slave/#comments</comments>
		<pubDate>Sun, 27 Jan 2008 14:20:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[asynchrone]]></category>
		<category><![CDATA[Master]]></category>
		<category><![CDATA[Master und Slave]]></category>
		<category><![CDATA[MySQL Replikation]]></category>
		<category><![CDATA[Replikation]]></category>
		<category><![CDATA[Replizierung]]></category>
		<category><![CDATA[Slave]]></category>
		<category><![CDATA[unidirektionale]]></category>

		<guid isPermaLink="false">http://www.el-mediaagentur.com/index.php/archives/mysql-replizierung-master-und-slave</guid>
		<description><![CDATA[MySQL bietet von Haus aus einige Lösungsansätze um die Datensicherheit zu gewährleisten. Eine davon ist die unidirektionale, asynchrone Replikation (seit v3.23.15) einer Master Datenbank auf einen oder mehreren Slave Datenbanken. Im folgenden beschreibe ich Schritt für Schritt die Einrichtung solch eines DB-Verbunds.






Die Replikation ermöglicht eine exakte Kopie der Master Datenbank als redundante Sicherung. Man sollte [...]]]></description>
			<content:encoded><![CDATA[<p><b>MySQL bietet von Haus aus einige Lösungsansätze um die Datensicherheit zu gewährleisten. Eine davon ist die unidirektionale, asynchrone Replikation (seit v3.23.15) einer Master Datenbank auf einen oder mehreren Slave Datenbanken. Im folgenden beschreibe ich Schritt für Schritt die Einrichtung solch eines DB-Verbunds.</b><span id="more-25"></span></p>
<div id="inline_ad" style="float: left;">
<script type="text/javascript"><!--
google_ad_client = "pub-2821839982812174";
/* Mediaum Rectangle 300x250 (leicht abgr.), Erstellt 27.02.08 */
google_ad_slot = "3929261217";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<p>Die Replikation ermöglicht eine exakte Kopie der Master Datenbank als redundante Sicherung. Man sollte sich bewusst darüber sein, dass alle SQL-Befehle die beim Master abgesetzt werden 1 zu 1 auf dem Slave übernommen werden.<br />Vor einer fehlerhaften Anwendung, die bsp. Datensätze korrumpiert, ist die Replikation nicht gefeit. Nichtdestotrotz eröffnet die Replikation Wege in Bezug Ausfallsicherheit oder Lastverteilung.<br />Ich empfehle bei der Replikation gleiche MySQL Versionen von Master und Slave zu benutzen. Unter <a href="http://mysql2.mirrors-r-us.net/doc/refman/5.1/de/replication-compatibility.html" target="_blank">http://mysql2.mirrors-r-us.net/doc/refman/5.1/de/replication-compatibility.html</a> kann man Details zur Kompatiblität erfahren.</p>
<h3>1. Schritt &#8211; Master Datenbank vorbereiten</h3>
<p>Zuerst muss ein Benutzer auf der Master-DB mit Replikations-Berechtigung erzeugt werden. Dieser Benutzer-Account dient später zur Replizierung der Daten. Auf der Kommadozeile in MySQL sähe das folgendermaßen aus:</p>
<p class="code">mysql> GRANT REPLICATION SLAVE ON *.* TO slave@&#8217;%.ihredomain.de&#8217; IDENTIFIED BY &#8216;ihrPasswort&#8217;;</p>
<p>Wenn man später mit LOAD DATA FROM MASTER agieren möchte dann benötigt dieser Account ein paar Rechte mehr (SELECT, RELOAD, SUPER, REPLICATION SLAVE).<br />
Als nächstes muss die <i>my.cnf</i> des Master editiert werden  </p>
<p class="code">[mysqld]<br />log-bin<br />server-id=1</p>
<p>Hiermit aktivieren wir das binäre loggen des Masters, welches notwenig für die Replikation ist. Des weiteren geben wir dem Master eine eindeutige ID.</p>
<h3>2. Schritt &#8211; Master Datenbank sichern</h3>
<p><i>Diesen Schritt kann man sich auch sparen, wenn der Master keine oder nur wenige Daten zu diesem Zeitpunkt führt. Dann setzt man einfach nach Schritt 4 folgendes Kommando auf dem MySQL-Prompt ab:</i></p>
<p class="code">mysql> LOAD DATA FROM MASTER;</p>
<p><i>Wie bereits erwähnt benötigt der Replikations-Account hierfür weitere Rechte (RELOAD,SUPER).<br />
Mit dem Kommando holt sich der Slave alle Daten vom Master, aber Vorsicht er blockiert hiermit den Master über den Zeitraum des Ladeprozesses, bei vielen Daten ist dieses Vorgehen nicht zu empfehlen.</i></p>
<p>Nun müssen wir den IST-Zustand der Master-DB-Daten erfassen und dem Slave später als Ausgangspunkt zur Verfügung stellen. Als erste Handlung hierbei, muss man die Master-Tabellen sperren, das erfolgt am MySQL-Prompt mit:</p>
<p class="code">mysql> FLUSH TABLES WITH READ LOCK;</p>
<p>Jetzt erfolgt ein Full-Backup der Master DB aus der Kommandozeile mit (bsp. in /var/lib/mysql/):</p>
<p class="code">tar -cvf /tmp/master-backup.tar</p>
<p>Zur Sicherheit legt man eine Kopie von diesem Backup zurück, um eventuell später weitere Slaves mit diesem Datenbestand zu initialisieren.<br />
Als nächstes benötigen wir noch die Binary Log Position um den Slave später den Anfangspunkt der Replizierung mitzuteilen. Auf dem MySQL-Prompt geschieht das mit:</p>
<p class="code">mysql> SHOW MASTER STATUS;</p>
<p>Diesen Wert notieren wir. Nun haben wir alle nötigen Daten des Masters und können dessen Tabellen entsperren:</p>
<p class="code">mysql> UNLOCK TABLES;</p>
<h3>3. Schritt &#8211; Ausgangs-Backup in Slave einspielen</h3>
<p>Im Slave Datenverzeichnis entpacken wir das eben angelegte Backup mit</p>
<p class="code">tar -xvf master-backup.tar</p>
<p>Dieses Backup dient dem Slave als Ausgangspunkt für das spätere unidirektionale, asynchrone replizieren.</p>
<h3>4. Schritt &#8211; Slave Datenbank vorbereiten</h3>
<p>Der Slave benötigt nun auch eine eindeutige ID, diese tragen wir in die Slave <i>my.cnf</i> folgendes ein:</p>
<p class="code">[mysqld]<br />server-id=2</p>
<p>Jetzt füttern wir den Slave mit den notwenigen Daten des Masters auf dem MySQL-Prompt:</p>
<p class="code">mysql> CHANGE MASTER TO<br />
 -> MASTER_HOST=<i>MASTER-IP</i>,<br />
 -> MASTER_USER=<i>Name des Replikation Account</i>,<br />
 -> MASTER_PASSWORD=<i>Passwort des Replikations-Accounts</i>,<br />
 -> MASTER_LOG_FILE=<i>Name des Binary-Logs aus dem Snapshot</i>,<br />
 -> MASTER_LOG_POS=<i>Binary Log Position</i>;
</p>
<p>Anschliessend muss der Slave nur noch seinen Dienst aufnehmen mit:</p>
<p class="code">mysql> START SLAVE;</p>
<p>Nach absetzen des Befehls nimmt der Slave sofort Kontakt mit dem Master auf und orientiert sich am Binary Log um die Replizierung durchzuführen.</p>
<p><b>Voila!</b></p>
<p>Mit</p>
<p class="code">mysql> SHOW MASTER STATUS;</p>
<p>und</p>
<p class="code">mysql> SHOW SLAVE STATUS;</p>
<p>kann man nun Master und Slave kontrollieren. Hierbei ist darauf zu achten, dass auf dem Slave die Stati <i> Slave_IO_Running</i> und <i>Slave_SQL_Running</i> auf <i>YES</i> stehen.<br /> <br />
Unter <a href="http://mysql2.mirrors-r-us.net/doc/refman/5.1/de/replication.html" target="_blank">http://mysql2.mirrors-r-us.net/doc/refman/5.1/de/replication.html</a> findet man weiterführende Informationen und Hilfestellungen. Aus meiner Erfahrung heraus sind bei Master-Slave Gefügen auftretenden Probleme oft bei der Berechtigung des Replikations-Accounts und/oder des Verbindungsaufbaues zu suchen.</p>
<h3>Hinweise</h3>
<p>Man sollte sicherstellen, dass der Master Verbindungen von ausserhalb zulässt, sofern der Replikant nicht im selben Netz (localhost) integriert ist, aber Vorsicht dies ist ein Sicherheitsmanko. Auch diese Einstellung nimmt man in der <i>my.cnf</i> vor, in dem man die Zeile</p>
<p class="code">#skip-networking</p>
<p>mit # auskommentiert. Taucht diese Zeile</p>
<p class="code">#bind-address           = 127.0.0.1</p>
<p>in der my.cnf auf, muss auch diese auskommentiert werden. Sie bedeutet nichts anderes als das nur von <i>localhost</i> verbunden werden darf.</p>
<p>Diese Anleitung ist ein praktischer Leitfaden ohne Gewähr.</p>
<h3>Weiterführende Literatur</h3>
<p>empfehlenswert sind folgende Bücher:</p>
<ul>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3897213885/elmediaagentu-21/" target="_blank">High Performance MySQL. Optimierung, Datensicherung, Replikation &amp; Lastverteilung</a> von Jeremy D. Zawodny und Derek J. Balling</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3827324041/elmediaagentu-21/" target="_blank">Das offizielle MySQL 5-Handbuch</a> von  MySQL MySQL AB</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3827326362/elmediaagentu-21/" target="_blank">MySQL 5. Einführung, Programmierung, Referenz (Open Source Library)</a> von Michael Kofler</li>
<li><a href="http://www.amazon.de/exec/obidos/ASIN/3772373259/elmediaagentu-21/" target="_blank">MySQL 5. Für Professionals</a> von Axel Bornträger</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.el-mediaagentur.com/2008/01/27/mysql-replizierung-master-und-slave/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

