そのDDLステートメント(alter table
、create index
etc)MySQLで現在のトランザクションを暗黙的にコミットします。 MS SQL Serverから来て、トランザクションでデータベースの変更をローカルで行う(それはその後ロールバックされる)機能は、私のワークフローの重要な部分でした。継続的な統合では、何らかの理由で移行が中断した場合にロールバックが使用されたため、少なくともデータベースが半分移行された状態のままになることはありませんでした。
MySQLを移行と継続的インテグレーションで使用する場合、人々はこれら2つの問題をどのように解決しますか?
多くの人にとって、MySQLアキレス腱は暗黙のコミットです。
The Book の418ページ3項によると
次のコマンドは、トランザクションを中断できます。
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
ブロックで適切に分離されたトランザクションをサポートする警告:これにMyISAMを使用している場合は、トランザクションを中断させる可能性のあるもののリストにMyISAMを(無)親切に追加できます。暗黙のコミットに関しては、データの一貫性に関しては、ロールバックが必要になる場合があります。
LVMスナップショットは優れており、大量のSQL処理を実行せずにデータベースのインスタンス全体を復元するのが理想的です。ただし、MySQLに関しては、InnoDBとMyISAMの2つのストレージエンジンを考慮する必要があります。
InnoDBのアーキテクチャを見てください(写真はPercona CTO Vadim Tkachenkoの厚意による)
InnoDBには多くの可動部分があります
コミットされていない変更がバッファープールとメモリキャッシュに浮かんでいるすべてのInnoDBデータベースのLVMスナップショットを取得すると、LUNが復元されてmysqldが起動すると、InnoDBクラッシュリカバリが必要なデータセットが生成されます。
SET GLOBAL innodb_fast_shutdown = 0;
を実行しますSET GLOBAL innodb_max_dirty_pages_pct = 0;
を実行しますSHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
を実行しますservice mysql stop
service mysql stop
SET GLOBAL innodb_max_dirty_pages_pct = 0;
を実行しますSHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
を実行しますSET GLOBAL innodb_max_dirty_pages_pct = 75;
を実行しますMyISAMは、アクセスされると、それに対するオープンファイルハンドルの数を維持します。 MySQLがクラッシュした場合、開いているファイルハンドル数が0より大きいMyISAMテーブルは、クラッシュとマークされ、修復が必要です(データに何も問題がなくても)。
MyISAMテーブルが使用されているデータベースのLVMスナップショットを作成すると、スナップショットが復元されてmysqldが起動したときに、修復が必要な1つ以上のMyISAMテーブルが作成されます。
SET GLOBAL innodb_fast_shutdown = 0;
を実行しますSET GLOBAL innodb_max_dirty_pages_pct = 0;
を実行しますSHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
を実行しますservice mysql stop
service mysql stop
特定のInnoDBテーブルのフラッシュを強制できます
SET GLOBAL innodb_max_dirty_pages_pct = 0;
を実行しますSHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_dirty';
を実行しますFLUSH TABLES innodb_tbl1,... FOR EXPORT;
を実行しますFLUSH TABLES WITH READ LOCK;
を実行しますUNLOCK TABLES;
を実行しますSET GLOBAL innodb_max_dirty_pages_pct = 75;
を実行します1つのLVMスナップショットを2つのサーバーに復元し、MySQLマスター/スレーブレプリケーションをセットアップすることもできますが、スナップショットを復元するときに、ハウスクリーニングの追加のソースになります。
マスターでCIジョブを実行し、それらのジョブが小さい場合、特定の状況下でレプリケーションが時間の節約になる可能性があります。スレーブでSTOP SLAVE;
を実行し、マスターでCIジョブを開始し、マスターのデータが認証されたらスレーブでSTART SLAVE;
を実行するだけです。
CIジョブが警告するデータが多すぎる場合は、LVMスナップショットを復元し、レプリケーションを最初からセットアップできます。これを頻繁に実行している場合は、MySQLレプリケーションの設定でおそらく実行できます。
継続的インテグレーションといえば、開発環境だと思います。その場合、構造的な変更を行う人は、他の人が物事を壊さないことを確認するために、それらをテストする必要があると言います。誰かが共通ライブラリを更新するのと同じように、そのような変更をコミットする前に独自のサンドボックスでテストします。
運用展開プロセスでは、通常、コードの変更と同じように、開発環境、QA環境、または運用前環境で変更をテストします。
これはMySQL固有ではないことに注意してください。Oracleデータベースは、「alter table」などを発行するときに暗黙的にCOMMITを実行します。
自分を保護したい場合は、もちろん事前にバックアップを行ってください。または、システムで可能であればLVMまたはファイルシステムのスナップショットを作成してください。機密性の高い操作の前にセキュリティとして遅延/停止できるスレーブがある場合もあります。