Für viele Menschen ist die MySQL-Achillesferse ein implizites Commit.
Gemäß Absatz 3 des Buches
Die folgenden Befehle können und werden eine Transaktion abbrechen
ALTER TABLE
BEGIN
CREATE INDEX
DROP DATABASE
DROP INDEX
DROP TABLE
RENAME TABLE
TRUNCATE TABLE
LOCK TABLES
UNLOCK TABLES
SET AUTOCOMMIT = 1
START TRANSACTION
VORSCHLAG
Wenn Sie in MySQL ContinuousIntegration (CI) / SelfService-Jobs erstellen, sollten sich Transaktionsjobs und DDL-Skripten immer gegenseitig ausschließen.
Dies gibt Ihnen die Möglichkeit, Paradigmen zu schaffen, die dies tun würden
- unterstützen Transaktionen, die ordnungsgemäß mit
START TRANSACTION/COMMIT
Blöcken isoliert sind
- Steuerung der DDL durch Erstellen eines Skripts für die DDL selbst, wobei die DDL entweder als Konstruktor oder als Destruktor ausgeführt wird
- Konstruktor: DDL zum Erstellen von Tabellen mit einem neuen Design
- Destruktor: DDL, um Tabellen auf den vorherigen Entwurf zurückzusetzen
- Kombinieren Sie diese Vorgänge niemals unter einem Job
WARNUNG: Wenn Sie hierfür MyISAM verwenden, können Sie MyISAM (un) freundlich zu der Liste der Dinge hinzufügen, die eine Transaktion unterbrechen können, möglicherweise nicht in Bezug auf das implizite Festschreiben, aber definitiv in Bezug auf die Datenkonsistenz, falls es jemals zu einem Rollback kommen sollte erforderlich.
WARUM NICHT LVM?
LVM-Snapshots eignen sich hervorragend, und die Wiederherstellung ganzer Instanzen von Datenbanken ohne umfangreiche SQL-Verarbeitung ist ideal. Bei MySQL müssen Sie jedoch zwei Speicher-Engines berücksichtigen: InnoDB und MyISAM.
All-InnoDB-Datenbank
Schauen Sie sich die Architektur von InnoDB an (Foto mit freundlicher Genehmigung von Percona CTO Vadim Tkachenko)
InnoDB hat viele bewegliche Teile
- System Tablespace
- Datenwörterbuch
- Double Write Buffer (unterstützt Datenkonsistenz; wird für Crash Recovery verwendet)
- Puffer einfügen (Pufferänderungen an sekundären nicht eindeutigen Indizes)
- Rollback-Segmente
- Undo Space (wo das unkontrollierteste Wachstum passieren kann)
- InnoDB-Pufferpool
- Schmutzige Datenseiten
- Verschmutzte Indexseiten
- Änderungen an nicht eindeutigen Indizes
- Andere wichtige Speicher-Caches
Das Erstellen eines LVM-Snapshots einer InnoDB-Datenbank mit nicht festgeschriebenen Änderungen im Pufferpool und im Speichercache würde zu einem Dataset führen, das eine Wiederherstellung nach dem Absturz von InnoDB erfordert, sobald die LUN wiederhergestellt und mysqld gestartet wurde.
VORSCHLAG FÜR ALL-InnoDB
Wenn Sie MySQL herunterfahren können, bevor Sie einen Schnappschuss machen
- Lauf
SET GLOBAL innodb_fast_shutdown = 0;
- Lauf
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Lauf
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Wiederholen Sie Schritt 3, bis Innodb_buffer_pool_pages_dirty 0 oder so nahe wie möglich bei 0 liegt
service mysql stop
- Machen Sie einen LVM-Schnappschuss
service mysql stop
Wenn Sie nicht herunterfahren können, sondern einen Schnappschuss mit MySQL Live machen
- Lauf
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Lauf
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Wiederholen Sie Schritt 2, bis Innodb_buffer_pool_pages_dirty 0 oder so nahe wie möglich bei 0 liegt
- Machen Sie einen LVM-Schnappschuss
- Lauf
SET GLOBAL innodb_max_dirty_pages_pct = 75;
All-MyISAM-Datenbank oder InnoDB / MyISAM-Mix
Wenn auf MyISAM zugegriffen wird, werden die Anzahl der geöffneten Dateizugriffsnummern beibehalten. Wenn MySQL abstürzt, wird jede MyISAM-Tabelle mit einer Anzahl offener Datei-Handles> 0 als Absturz markiert und muss repariert werden (auch wenn mit den Daten nichts falsch ist).
Wenn Sie einen LVM-Snapshot einer Datenbank erstellen, in der MyISAM-Tabellen verwendet werden, müssen eine oder mehrere MyISAM-Tabellen repariert werden, wenn der Snapshot wiederhergestellt und mysqld gestartet wird.
EMPFEHLUNG FÜR All-MyISAM oder InnoDB / MyISAM Mix
Wenn Sie MySQL herunterfahren können, bevor Sie einen Schnappschuss machen
- Lauf
SET GLOBAL innodb_fast_shutdown = 0;
- Lauf
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Lauf
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Wiederholen Sie Schritt 3, bis Innodb_buffer_pool_pages_dirty 0 oder so nahe wie möglich bei 0 liegt
service mysql stop
- Machen Sie einen LVM-Schnappschuss
service mysql stop
Wenn Sie nicht herunterfahren können, sondern einen Schnappschuss mit MySQL Live machen
Sie können ein Leeren bestimmter InnoDB-Tabellen erzwingen
- Lauf
SET GLOBAL innodb_max_dirty_pages_pct = 0;
- Lauf
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
- Wiederholen Sie Schritt 2, bis Innodb_buffer_pool_pages_dirty 0 oder so nahe wie möglich bei 0 liegt
- Führen Sie
FLUSH TABLES innodb_tbl1,... FOR EXPORT;
auf kritische InnoDB - Tabellen
- Lauf
FLUSH TABLES WITH READ LOCK;
- Machen Sie einen LVM-Schnappschuss
- Lauf
UNLOCK TABLES;
- Lauf
SET GLOBAL innodb_max_dirty_pages_pct = 75;
Könnte MySQL Replication helfen?
Sie können zwar einen LVM-Snapshot auf zwei Servern wiederherstellen und MySQL Master / Slave Replication einrichten, dies wird jedoch zu einer zusätzlichen Quelle für die Hausreinigung beim Wiederherstellen von Snapshots.
Wenn Sie CI-Jobs auf einem Master ausführen und diese Jobs klein sind, kann die Replikation unter bestimmten Umständen zu einer Zeitersparnis führen. Sie könnten einfach STOP SLAVE;
auf dem Slave laufen , die CI-Jobs auf dem Master starten und START SLAVE;
auf dem Slave laufen, wenn die Daten des Masters zertifiziert sind.
Wenn die CI-Jobs zu viele Daten melden, können Sie den LVM-Snapshot wiederherstellen und die Replikation von Grund auf einrichten. Wenn Sie dies häufig tun, können Sie möglicherweise MySQL Replication einrichten.
ABSCHLIESSENDE GEDANKEN
- Verwenden Sie am besten mehrere DB-Server (3 oder mehr), um Wiederherstellungen und Regressionstests durchzuführen.
- Konvertieren Sie verbleibende MyISAM-Tabellen in InnoDB, wenn diese Tabellen nicht MyISAM bleiben müssen.
- Wenn Ihr Dateninhalt vertraulich ist, sollten Sie nach dem Wiederherstellen eines Snapshots einen CI-Job ausführen, um die Daten zu bereinigen, bevor Sie Tests starten. Alternativ können Sie Snapshots von MySQL mit den bereits bereinigten Daten erstellen.