<?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>Lieber Linux &#187; Synchronisation</title>
	<atom:link href="http://www.lieber-linux.de/tag/synchronisation/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lieber-linux.de</link>
	<description>Linux und Open Source Software im Blog</description>
	<lastBuildDate>Thu, 26 Jan 2012 17:58:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>MySQL mit Two-Way-Synchronization ohne Replikation</title>
		<link>http://www.lieber-linux.de/2009/12/mysql-mit-two-way-synchronization-ohne-replikation/</link>
		<comments>http://www.lieber-linux.de/2009/12/mysql-mit-two-way-synchronization-ohne-replikation/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 22:14:38 +0000</pubDate>
		<dc:creator>Nudge</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tipp]]></category>
		<category><![CDATA[Primary Key]]></category>
		<category><![CDATA[Synchronisation]]></category>

		<guid isPermaLink="false">http://www.lieber-linux.de/?p=677</guid>
		<description><![CDATA[Anbei eine kleine Idee für alle, die verteilte Datenhaltung haben, und dazu eine architektonisch recht einfache Synchronisation brauchen. Manchmal kommt aus diversen Gründen ein Replikationsmechanismus nicht in Frage. Dafür nun die folgende Idee. Wir nutzen dabei aus, dass MySQL bei zusammengesetzten Indizes einen AUTO_INCREMENT-Wert pro distinktem Schlüsselpräfix zählt. Das heißt ganz konkret: Wir legen einen [...]]]></description>
			<content:encoded><![CDATA[<p>Anbei eine kleine Idee für alle, die verteilte Datenhaltung haben, und dazu eine architektonisch recht einfache <strong>Synchronisation</strong> brauchen. Manchmal kommt aus diversen Gründen ein Replikationsmechanismus nicht in Frage. Dafür nun die folgende Idee. Wir nutzen dabei aus, dass <strong>MySQL</strong> bei zusammengesetzten <strong>Indizes</strong> einen <strong>AUTO_INCREMENT</strong>-Wert pro distinktem Schlüsselpräfix zählt.</p>
<p><span id="more-677"></span></p>
<p>Das heißt ganz konkret: Wir legen einen Primär-Schlüssel aus zwei Spalten zusammen. In der ersten Spalte verwenden wir einen sehr kleinen Wert, der die Quelle der Daten kennzeichnet: <em>Source tinyint unsigned NOT NULL;</em> Den zweiten Teil legen wir als einfache <em>ID int unsigned NOT NULL AUTO_INCREMENT</em> an. Und ein <em>Timestamp</em>-Wert bietet sich für das Triggern der Updates an. Unsere Tabellen haben dann mindestens folgende Form:</p>
<pre>CREATE TABLE `&lt;table_name&gt;` (
  `Source` tinyint unsigned NOT NULL,
  `ID` int unsigned NOT NULL AUTO_INCREMENT,
  `Timestamp` timestamp,
  PRIMARY KEY (`Source`, `ID`)
);</pre>
<p>MySQL wird also die Spalte <em>`ID`</em> pro distinktem Wert der Spalte <em>`Source`</em> inkrementieren. So können wir nun den jeweiligen Applikationen eine eindeutige Source-Kennung zuweisen, z.B. eine Filial-Nummer oder eine Server-Nummerierung. Der Synchronisationsalgorithmus kann dann die jeweiligen Datenbanken zusammentragen, ohne dass es zu Konflikten in den Schlüsseln kommen kann.</p>
<p>Im speziellen Fall &#8220;<strong>Two-Way-Synchronization</strong>&#8220;, der zum Beispiel offline- und online-Datenerfassungen abbilden könnte, werden geänderte und neue Datensätze von jeweils einer zur anderen <strong>Datenbank</strong> geschrieben. In beiden Fällen läuft die Synchronisation mit der jeweiligen Source-Kennung, sodass auch gelöschte Sätze in der Zieldatenbank gefunden und ebenfalls gelöscht werden kann, ohne dass es zu Doppeldeutigkeiten kommt.</p>
<p>Ich wünsche Euch viel Erfolg damit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lieber-linux.de/2009/12/mysql-mit-two-way-synchronization-ohne-replikation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Sequence oder integer-Timestamp</title>
		<link>http://www.lieber-linux.de/2009/04/mysql-sequence-oder-integer-timestamp/</link>
		<comments>http://www.lieber-linux.de/2009/04/mysql-sequence-oder-integer-timestamp/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 20:34:40 +0000</pubDate>
		<dc:creator>Nudge</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[MSSQL]]></category>
		<category><![CDATA[Postgresql]]></category>
		<category><![CDATA[Replikation]]></category>
		<category><![CDATA[Routine]]></category>
		<category><![CDATA[Sequenz]]></category>
		<category><![CDATA[Synchronisation]]></category>
		<category><![CDATA[Timestamp]]></category>
		<category><![CDATA[Trigger]]></category>
		<category><![CDATA[Update]]></category>

		<guid isPermaLink="false">http://www.lieber-linux.de/?p=382</guid>
		<description><![CDATA[Ich suche seit einiger Zeit nach einer bequemen Möglichkeit, einen MSSQL-ähnlichen Timestamp in MySQL zu integrieren. Im Unterschied zu MySQL benutzt MSSQL nämlich nicht das aktuelle Datum, sondern einen (binär codierten) integer-Wert. Dieser wird kontinuierlich im Laufe des MSSQL-Lebenszyklus hochgezählt. Das sieht erst einmal nicht so schön aus &#8211; man weiß also nicht, wann der [...]]]></description>
			<content:encoded><![CDATA[<p>Ich suche seit einiger Zeit nach einer bequemen Möglichkeit, einen <strong>MSSQL</strong>-ähnlichen <strong>Timestamp</strong> in <strong>MySQL</strong> zu integrieren.</p>
<p>Im Unterschied zu <strong>MySQL</strong> benutzt <strong>MSSQL</strong> nämlich nicht das aktuelle Datum, sondern einen (binär codierten) <strong>integer</strong>-Wert. Dieser wird kontinuierlich im Laufe des <strong>MSSQL</strong>-Lebenszyklus hochgezählt. Das sieht erst einmal nicht so schön aus &#8211; man weiß also nicht, wann der Datensatz zuletzt angefasst wurde. Dennoch bringt er einen kleinen Vorteil mit: Für einfache Synchronisationsaufgaben braucht man sich nur den letzten abgerufenen Wert zu merken. Erst alle höheren Timestamps müssen neu übertragen werden. Bei <strong>MySQL</strong> muss man alle Datensätze der letzten Sekunde wieder übertragen, denn eine Sekunde ist im Leben einer Datenbank eine Ewigkeit, da kann viel passieren.</p>
<p><span id="more-382"></span></p>
<h3>Warum sollte man denn überhaupt über Zeitstempel synchronisieren?</h3>
<p>Nun, das Leben bietet mehr als eine Datenbank, und ab und zu muss man einen Datensatz über mehrere Datenbanken synchron halten. Da die verfügbaren Mechanismen der <strong>Replikation</strong> sich allesamt auf das jeweilige Datenbank-Produkt beziehen, hat man keine andere Chance. Man könnte natürlich auch Spalten für Geändert/Gelöscht in den Tabellen pflegen. Doch man benötigte dazu Rechte, das Tabellenschema zu ändern und die Applikation zu modifizieren. Und es müsste ausnahmslos und sauber programmiert sein. Ein Datenbank-Zeitstempel dagegen befreit von diesen Zwängen, arbeitet vollkommen automatisch und transparent für den Benutzer. Und mit einem Zeitstempel à la <strong>Timestamp</strong> hat man schon fast alles, was man zur <strong>Synchronisation</strong> braucht.</p>
<h3>Alternativen zum Timestamp mit gleichem Mechanismus</h3>
<p>Die erste offensichtliche Möglichkeit habe ich in einer Sequenz gesehen. Diese ist wiederum nicht ganz so einfach abzubilden wie in <strong>Postgres</strong>, was ja bekannt dafür ist. Sondern man programmiert sich eine per <strong>CREATE FUNCTION</strong> eine Routine, die wiederum in einer eigenen Tabelle einen Wert inkrementiert, optimalerweise gleich einen <strong>BIGINT</strong>, denn es soll ja mehr als 3 Tage funktionieren.</p>
<p>Für jede Tabelle, die man mit der Sequence ausstatten möchte, muss man zwei <strong>Trigger</strong> anlegen, einmal <strong>BEFORE INSERT</strong> und einen <strong>BEFORE UPDATE</strong>. Sie setzen dann jeweils per <strong>NEW.Timestamp = f_getSeq()</strong> einen neuen Sequence-Wert ein. Es kann dabei durchaus passieren, dass zwei Datensätze denselben Sequence-Wert bekommen, da die <strong>Routine</strong> nicht-atomar ist. Da aber <strong>MyISAM</strong> <strong>Locking</strong> nur auf Tabellen-Ebene betreibt, können diese nur auf zwei unterschiedlichen Tabellen landen &#8211; folglich ist diese Einschränkung für die Synchronisationsaufgabe nicht entscheidend. Doch spätestens, wenn man 200 oder mehr Tabellen im Einsatz hat, wird die Sache mit den Triggern extrem unübersichtlich.</p>
<h3>Ausweg zwei: Genauere Zeitstempel mit Microsekunden</h3>
<p>Angeblich kann <strong>MySQL</strong> ja Timestamps mit Microseconds ausgeben. Bei mir kommt dort immer .000000 raus. Kann natürlich auch an einer zu schwachen CPU oder an den zu langen Prozess-Zyklen des <strong>Kernel</strong> liegen. Wenn man davon ausgehen kann, dass dies funktioniert, wäre es an sich eine gute Sache: Lesbar und totzdem extrem genau. Es muss dann auf jeden Fall sichergestellt sein, dass pro Satz in einem Update ein neuer Wert erzeugt wird, und man sollte davon ausgehen, dass innerhalb einer Microsekunde nicht zu viel passiert. Für Hochlastserver also nix.</p>
<p><strong>Postgres</strong> hat meines Wissens die Microsekunden standardmäßig im Zeitstempel drin. Auf den Chemnitzer Linux-Tagen habe ich mal mit einem der <strong>Postgres</strong>-Leute über diese Variante von <strong>Synchronisation</strong> gesprochen. Er meinte aber, dass dies nicht <strong>Locking</strong>-safe sei. Es könnte also passieren, dass ein <strong>Update</strong> erst später geschrieben als sein Zeitstempel erzeugt wird, denn die Zieltabelle könnte in diesem Moment gesperrt sein. So könnten sich zwei <strong>Updates</strong> überlagern und der letzte trotzdem einen früheren Zeitstempel erhalten. Synchronisiert man aber nicht zu oft, sollte das kein Problem darstellen.</p>
<p>Naja, vielleicht sollte man mal einen Feature Request für <strong>MySQL 6</strong>.x stellen? Aber bevor das in den <strong>Server-Distributionen</strong> dann drin wäre, bin ich Rentner. Bis dahin müssen halt noch ein paar Datensätze doppelt übertragen werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lieber-linux.de/2009/04/mysql-sequence-oder-integer-timestamp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

