Replikation und Lock-Timeout

Replikation und Lock-Timeout

am 09.09.2006 12:29:02 von Ilja Weis

Moin,

ein Slave ist mir kaputtgegangen mit:

Last_Error: Query caused different errors on master and slave. Error on
master: 'Lock wait timeout exceeded; try restarting transaction' (1205),
Error on slave: 'Duplicate entry '....' for key 1' (1062).

MySQL-Version ist 4.1.11 (Debian Sarg), die betroffene Tabelle eine
temporäre MyISAM-Tabelle. Der Slave war danach auch nicht mehr manuell
zu reparieren und musste neu aufgesetzt werden.

Warum landet ein fehlgeschlagenes Statement im binlog? Ist das ein
Bug? Oder sind das Effekte, die man sich einhandelt, wenn man
MyISAM-Tabellen verwendet?

Hätte es hier geholfen, konsequent nur InnoDB-Tabellen zu verwenden?
Was geschieht dann auf dem Slave, wenn eine Transaktion auf dem Master
durch den timeout abgebrochen wird? Es ist ja eher unwahrscheinlich,
dass es den gleichen Timeout auch auf dem Slave gibt.

Re: Replikation und Lock-Timeout

am 09.09.2006 14:19:28 von Axel Schwenke

Ilja Weis wrote:

> ein Slave ist mir kaputtgegangen mit:
>
> Last_Error: Query caused different errors on master and slave. Error on
> master: 'Lock wait timeout exceeded; try restarting transaction' (1205),
> Error on slave: 'Duplicate entry '....' for key 1' (1062).
>
> MySQL-Version ist 4.1.11 (Debian Sarg), die betroffene Tabelle eine
> temporäre MyISAM-Tabelle. Der Slave war danach auch nicht mehr manuell
> zu reparieren und musste neu aufgesetzt werden.

1. Frage: müssen die Änderungen an der temporären Tabelle tatsächlich
zum Slave repliziert werden? Wenn ja, hilft ein passendes
replicate-ignore-table[-wild] in my.cnf. Wenn ja: versuch das anders zu
lösen. Replikation undd temporäre Tabellen ist ein bisschen kitzlig.

> Warum landet ein fehlgeschlagenes Statement im binlog? Ist das ein
> Bug? Oder sind das Effekte, die man sich einhandelt, wenn man
> MyISAM-Tabellen verwendet?

Im Prinzip letzteres. Da die MyISAM-Engine keine Transaktionen kann,
können bestimmte Statements bei einem Fehler partiell ausgeführt
werden. Beispiel: ein Multi-Value-INSERT, bei dem das zweite Tupel
ein Constraint verletzt. Transaktionsorientierte Engines rollen das
Statement zurück, MyISAM kann das nicht. Deswegen werden solche
Statements trotzdem ins Binlog geschrieben und es wird geprüft, ob
Master und Slave den selben Fehler bekommen. Wenn ja, sind beide
danach noch synchron.

> Hätte es hier geholfen, konsequent nur InnoDB-Tabellen zu verwenden?

Vermutlich ja.

> Was geschieht dann auf dem Slave, wenn eine Transaktion auf dem Master
> durch den timeout abgebrochen wird? Es ist ja eher unwahrscheinlich,
> dass es den gleichen Timeout auch auf dem Slave gibt.

Kommt mir ohnehin komisch vor. Was war das für ein Statement?


XL

Re: Replikation und Lock-Timeout

am 09.09.2006 16:56:04 von Ilja Weis

Axel Schwenke writes:

> Ilja Weis wrote:

>> Last_Error: Query caused different errors on master and slave. Error on
>> master: 'Lock wait timeout exceeded; try restarting transaction' (1205),
>> Error on slave: 'Duplicate entry '....' for key 1' (1062).

> 1. Frage: müssen die Änderungen an der temporären Tabelle tatsächlich
> zum Slave repliziert werden? Wenn ja, hilft ein passendes
> replicate-ignore-table[-wild] in my.cnf. Wenn ja: versuch das anders zu
> lösen. Replikation undd temporäre Tabellen ist ein bisschen kitzlig.

Die Inhalte der Datenbank liegen nicht in meiner Verantwortung, aber
ich kann sicherlich Vorschläge zur Verbesserung machen. ;-)

Im Prinzip werden Daten aus anderen Tabellen in die temporären
Tabellen zusammengefasst und Daten daraus in wieder andere, permanente
Tabellen kopiert. In der jetzigen Form wird das auf jeden Fall
mitrepliziert werden müssen.

>> Warum landet ein fehlgeschlagenes Statement im binlog? Ist das ein
>> Bug? Oder sind das Effekte, die man sich einhandelt, wenn man
>> MyISAM-Tabellen verwendet?
>
> Im Prinzip letzteres. Da die MyISAM-Engine keine Transaktionen kann,
> können bestimmte Statements bei einem Fehler partiell ausgeführt
> werden. Beispiel: ein Multi-Value-INSERT, bei dem das zweite Tupel
> ein Constraint verletzt. Transaktionsorientierte Engines rollen das
> Statement zurück, MyISAM kann das nicht. Deswegen werden solche
> Statements trotzdem ins Binlog geschrieben und es wird geprüft, ob
> Master und Slave den selben Fehler bekommen. Wenn ja, sind beide
> danach noch synchron.

Ja, das passt zum Effekt. Danke für die Erklärung.

>> Hätte es hier geholfen, konsequent nur InnoDB-Tabellen zu verwenden?
>
> Vermutlich ja.

Dann werden wir das versuchen umzustellen...

>> Was geschieht dann auf dem Slave, wenn eine Transaktion auf dem Master
>> durch den timeout abgebrochen wird? Es ist ja eher unwahrscheinlich,
>> dass es den gleichen Timeout auch auf dem Slave gibt.
>
> Kommt mir ohnehin komisch vor. Was war das für ein Statement?

Vereinfacht:

INSERT INTO temp_table ( SELECT ... FROM a LEFT JOIN b WHERE ...)

Re: Replikation und Lock-Timeout

am 10.09.2006 23:20:56 von Axel Schwenke

Ilja Weis wrote:
> Axel Schwenke writes:
>
>> 1. Frage: müssen die Änderungen an der temporären Tabelle tatsächlich
>> zum Slave repliziert werden? Wenn ja, hilft ein passendes
>> replicate-ignore-table[-wild] in my.cnf. Wenn ja: versuch das anders zu
>> lösen. Replikation undd temporäre Tabellen ist ein bisschen kitzlig.
>
> Die Inhalte der Datenbank liegen nicht in meiner Verantwortung, aber
> ich kann sicherlich Vorschläge zur Verbesserung machen. ;-)
>
> Im Prinzip werden Daten aus anderen Tabellen in die temporären
> Tabellen zusammengefasst und Daten daraus in wieder andere, permanente
> Tabellen kopiert. In der jetzigen Form wird das auf jeden Fall
> mitrepliziert werden müssen.

Ja, das ist dann einer der Fälle, wo du die temporären Tabellen
replizieren mußt. Zum Problem wird das z.B. dann, wenn der Slave mal
runtergefahren wird (auch regulär, kein Crash). Dabei verliert er alle
temp. Tables. Bei schlechtem Timing ist dann der Slave futsch :-/

Ein Workaround ist im Manual beschrieben. Der kann aber beliebig weit
schief gehen. M.a.W. es ist nicht gesichert, daß der Algorithmus des
Workarounds terminiert :-)

>>> Was geschieht dann auf dem Slave, wenn eine Transaktion auf dem Master
>>> durch den timeout abgebrochen wird? Es ist ja eher unwahrscheinlich,
>>> dass es den gleichen Timeout auch auf dem Slave gibt.
>>
>> Kommt mir ohnehin komisch vor. Was war das für ein Statement?
>
> Vereinfacht:
>
> INSERT INTO temp_table ( SELECT ... FROM a LEFT JOIN b WHERE ...)

Das ist dann wohl eine Variante von Multi-Value-INSERT. Aber ja, mit
InnoDB wäre das entweder als Ganzes durchgegangen oder als Ganzes
fehlgeschlagen.

Das LOCK war dann auf a oder b - ich hatte mich gewundert, woher
ein LOCK timeout auf eine temp. Table kommen soll. Die gehört ja
per Definition der Verbindung.


XL

Re: Replikation und Lock-Timeout

am 12.09.2006 10:29:47 von Ilja Weis

Moin,

Axel Schwenke writes:

> Ja, das ist dann einer der Fälle, wo du die temporären Tabellen
> replizieren mußt. Zum Problem wird das z.B. dann, wenn der Slave mal
> runtergefahren wird (auch regulär, kein Crash). Dabei verliert er alle
> temp. Tables. Bei schlechtem Timing ist dann der Slave futsch :-/
>
> Ein Workaround ist im Manual beschrieben. Der kann aber beliebig weit
> schief gehen. M.a.W. es ist nicht gesichert, daß der Algorithmus des
> Workarounds terminiert :-)

Das klingt nicht nach etwas, auf das man sich verlassen möchte. ;-)

Da "stop slave" aber laufende Transaktionen komplett abschliesst (oder
gar nicht), sollte es auch mit temporären Dateien gehen, wenn man
diese nur innerhalb einer Transaktion verwendet. Dann sollte man
eigentlich auch vor einem Crash sicher sein, denn dann wird die
"Exec_Master_Log_Pos" vor der Transaktion bleiben und die angefangene
zurückgerollt. (Sah zumindest bei einem schnellen Test so aus, als
würde das auch funktionieren.)

>> INSERT INTO temp_table ( SELECT ... FROM a LEFT JOIN b WHERE ...)
>
> Das ist dann wohl eine Variante von Multi-Value-INSERT. Aber ja, mit
> InnoDB wäre das entweder als Ganzes durchgegangen oder als Ganzes
> fehlgeschlagen.
>
> Das LOCK war dann auf a oder b - ich hatte mich gewundert, woher
> ein LOCK timeout auf eine temp. Table kommen soll. Die gehört ja
> per Definition der Verbindung.

Gut, ich werde vorschlagen, dass alles auf InnoDB umgestellt
wird. Danke für die Hilfe.