MySQLのトランザクションDDLワークフロー


25

私は少しはDDL文(ことを発見して驚いたalter tablecreate indexなど)が暗黙のMySQLで現在のトランザクションをコミットします。MS SQL Serverから来て、トランザクションでデータベースの変更をローカルで行う機能(その後ロールバックされた機能)は、ワークフローの重要な部分でした。継続的な統合では、何らかの理由で移行が中断した場合にロールバックが使用されたため、少なくともデータベースが半分移行された状態のままになりませんでした。

MySQLを移行と継続的インテグレーションで使用する場合、これら2つの問題をどのように解決しますか?


SOからのクロス投稿。 stackoverflow.com/q/28197013/614523そこまで多くの愛を得ることができませんでした。
セネット

1
継続的インテグレーションの場合、既知の状態にある環境全体を非常に迅速に作成する方法として、LVMスナップショットを検討してください。
リックジェームズ

5
いつでもPostgresにアップグレードできます-トランザクションDDL(SCNR)をサポートします。
a_horse_with_no_name

3
@a_horse_with_no_nameに同意します。これがあなたのワークフローである場合、他の多くの優れた機能とともにトランザクションDDLを備えたPosgreSQLの使用を真剣に検討してください。
レンゾ・

回答:


9

多くの人にとって、MySQL Achillesのかかとは暗黙のコミットです。

本の 418ページのパラグラフ3によると

MySQL 5.0認定スタディガイド

次のコマンドは、トランザクションを中断する可能性があります。

  • ALTER TABLE
  • BEGIN
  • CREATE INDEX
  • DROP DATABASE
  • DROP INDEX
  • DROP TABLE
  • RENAME TABLE
  • TRUNCATE TABLE
  • LOCK TABLES
  • UNLOCK TABLES
  • SET AUTOCOMMIT = 1
  • START TRANSACTION

提案

MySQLの場合、構築するContinuousIntegration(CI)/ SelfServiceジョブは、常にトランザクションジョブとDDLスクリプトを相互に排他的にする必要があります。

これにより、次のようなパラダイムを作成できます。

  • START TRANSACTION/COMMITブロックで適切に分離されたトランザクションをサポートする
  • DDLを自分でスクリプト化し、そのようなDDLをコンストラクターまたはデストラクターとして実行することによるDDLの制御
    • コンストラクター:新しいデザインのテーブルを作成するDDL
    • デストラクタ:テーブルを以前のデザインに戻すDDL
  • これらの操作を1つのジョブにまとめないでください

警告:これにMyISAMを使用している場合、おそらく暗黙的なコミットの観点ではなく、データの一貫性の観点から、トランザクションを中断する可能性のあるもののリストにMyISAMを追加することができます。必要です。

なぜLVMではないのですか?

LVMスナップショットは優れており、重いSQL処理を実行せずにデータベースのインスタンス全体を復元することが理想的です。ただし、MySQLに関しては、InnoDBとMyISAMの2つのストレージエンジンを考慮する必要があります。

All-InnoDBデータベース

InnoDBのアーキテクチャを見てください(写真はPercona CTOのVadim Tkachenkoの好意による)

InnoDB配管

InnoDBには多くの可動部分があります

  • システム表領域
    • データ辞書
    • ダブルライトバッファ(データの一貫性をサポート。クラッシュリカバリに使用)
    • バッファーの挿入(セカンダリーの非一意索引へのバッファーの変更)
    • ロールバックセグメント
    • スペースを元に戻す(最も制御できない成長が発生する可能性のある場所)
  • InnoDBバッファープール
    • ダーティデータページ
    • 汚れたインデックスページ
    • 非ユニークインデックスの変更
  • その他の重要なメモリキャッシュ

コミットされていない変更がバッファプールとメモリキャッシュに浮かんでいるすべてのInnoDBデータベースのLVMスナップショットを取得すると、LUNが復元されmysqldが起動するとInnoDBクラッシュリカバリが必要なデータセットが生成されます。

ALL-InnoDBの提案

スナップショットを撮る前にMySQLをシャットダウンできる場合

    1. 走る SET GLOBAL innodb_fast_shutdown = 0;
    1. 走る SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 走る SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirtyが0または可能な限り0に近づくまで、手順3を繰り返します。
    1. service mysql stop
    1. LVMスナップショットを撮る
    1. service mysql stop

シャットダウンできないがMySQL Liveでスナップショットを撮る場合

    1. 走る SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 走る SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirtyが0または可能な限り0に近づくまで、手順2を繰り返します。
    1. LVMスナップショットを撮る
    1. 走る SET GLOBAL innodb_max_dirty_pages_pct = 75;

All-MyISAMデータベースまたはInnoDB / MyISAM Mix

MyISAMは、アクセスされると、それに対する開いているファイルハンドルの数を維持します。MySQLがクラッシュすると、開いているファイルハンドルカウントが0を超えるMyISAMテーブルは、クラッシュとしてマークされ、修復が必要です(データに問題がない場合でも)。

使用中のMyISAMテーブルがあるデータベースのLVMスナップショットを取得すると、スナップショットが復元されmysqldが開始されたときに修復が必要な1つ以上のMyISAMテーブルがあります。

All-MyISAMまたはInnoDB / MyISAM Mixの提案

スナップショットを撮る前にMySQLをシャットダウンできる場合

    1. 走る SET GLOBAL innodb_fast_shutdown = 0;
    1. 走る SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 走る SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirtyが0または可能な限り0に近づくまで、手順3を繰り返します。
    1. service mysql stop
    1. LVMスナップショットを撮る
    1. service mysql stop

シャットダウンできないがMySQL Liveでスナップショットを撮る場合

特定のInnoDBテーブルのフラッシュを強制できます

    1. 走る SET GLOBAL innodb_max_dirty_pages_pct = 0;
    1. 走る SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
    1. Innodb_buffer_pool_pages_dirtyが0または可能な限り0に近づくまで、手順2を繰り返します。
    1. FLUSH TABLES innodb_tbl1,... FOR EXPORT;重要なInnoDBテーブルで実行する
    1. 走る FLUSH TABLES WITH READ LOCK;
    1. LVMスナップショットを撮る
    1. 走る UNLOCK TABLES;
    1. 走る SET GLOBAL innodb_max_dirty_pages_pct = 75;

MySQL Replicationは役立ちますか?

1つのLVMスナップショットを2つのサーバーに復元し、MySQL Master / Slave Replicationをセットアップすることもできますが、スナップショットを復元する際のハウスクリーニングの追加ソースになります。

CIジョブをマスターで実行し、それらのジョブが小さい場合、特定の状況下で複製が時間の節約になる可能性があります。STOP SLAVE;スレーブで実行し、マスターでCIジョブを開始しSTART SLAVE;、マスターのデータが認証されたらスレーブで実行できます。

CIジョブが大量のデータを警告する場合、LVMスナップショットを復元し、レプリケーションをゼロからセットアップできます。頻繁にこれを行うことに気付いた場合は、おそらくMySQLレプリケーションのセットアップを行うことができます。

最終的な考え

  • 複数のDBサーバー(3つ以上)を使用して、復元と回帰テストを実行することをお勧めします。
  • テーブルがMyISAMのままである必要がない場合、残りのMyISAMテーブルをInnoDBに変換します。
  • データコンテンツが機密である場合は、テストを開始する前にスナップショットを復元した後、CIジョブを実行してデータをスクラブする必要があります。別の方法として、データを既にスクラブしたMySQLのスナップショットを作成することもできます。

4

継続的インテグレーションについて話す場合、それは開発環境だと思います。その場合、構造的な変更を行う人は、一般的なライブラリを更新するのと同じように、他の人に物事を壊さないようにテストする必要があります:そのような変更をコミットする前に自分のサンドボックスでテストします。

運用展開プロセスでは、通常、コードの変更と同じ方法で、開発、QA、または運用前環境を経て変更をテストします。

これはMySQL固有ではないことに注意してください。Oracleデータベースは、「alter table」などを発行するときに暗黙的にCOMMITを実行します。

自分自身を保護したい場合は、当然、事前にバックアップを行うか、システムがそれを実行できる場合はLVMまたはファイルシステムのスナップショットを行うことができます。また、機密操作の前にセキュリティとして遅延/停止できるスレーブがある場合もあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.