MyISAMからInnoDBへの変換の高速化


15

私は4GBを占有する約450のテーブルのデータベースを持つmysql 5.1サーバーを持っています。これらのテーブルの大部分(2つを除くすべて)はMyIsamです。ほとんどの場合これで問題ありません(トランザクションは必要ありません)が、アプリケーションはトラフィックを獲得しており、更新時のテーブルロックにより特定のテーブルが影響を受けています。これが、テーブルの2つがInnoDBになった理由です。

小さなテーブル(10万行)での変換にはまったく時間がかからず、ダウンタイムが最小限に抑えられます。ただし、追跡テーブルのいくつかは5,000万行に近づいています。ALTER TABLE...ENGINE InnoDB大きなテーブルでを高速化する方法はありますか?そうでない場合、これらの書き込みが多いテーブルでダウンタイムを最小限に抑える変換方法はありますか?


1
覚えておくべきこと:1つの投稿に複数の質問があると、質問の1つに回答できる人が回答を投稿することを思いとどまらせる傾向があります。
BenV

これは答えるのがかなり複雑なので、私はVtCです。いくつかの質問として個別に開く必要があります。
jcolebrand

私は喜んでそれを単一の質問にするアドバイスをしますが、この質問を削除して新しい質問を開くことをお勧めしますか?書き直しは主に2番目の2つの弾丸を削除し、最初の2つの弾丸を変更することです(どのストレージエンジンを反映するようにタイトルも更新しました)
デレクダウニー

どちらでも構いません。通常、他の2つの質問を書いて削除する方が簡単です。ただし、これを「参照」用にそのままにして、他の2人に「これは私の全体的な目標です」という質問として参照させることができます。
jcolebrand

これを1つの箇条書きに編集してから、追加の質問を投稿してください。
ブライアンボールサンスタントン

回答:


10

まず、ALTERが嫌いだと言ってみましょう。それは悪です、私見。

たとえば、これは現在のテーブルスキーマです-

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

私がお勧めするパスは次のとおりです-

古いテーブルオブジェクトを置き換える新しいテーブルオブジェクトを作成します。

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

古いテーブルのすべての行を名前で新しいテーブルに挿入します。

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

移行の煙テスト:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

ロールバックする必要がある場合に備えてバックアップを維持できるように、テーブル名を交換します。

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

回帰テストに進みます。

このアプローチは、複数のインデックスと数百万行のテーブルでますます望ましいものになります。

考え?


1
同意します...ただし、トランザクションが非常に多い場合は、これを行っている間にデータベースを停止する必要があるかもしれません。(ただし、別のテーブルを使用すると、ダウンタイムが長くなる可能性が高くなります)
ジョー

ええ、よりアクティブなテーブルにはダウンタイムが必要だと思いました。いくつかのテストを実行する必要がありますが、なぜ5,000万行ALTER TABLEよりも時間がかかるのでしょうINSERT INTO...SELECTか?
デレクダウニー

しません。基本的に、MySQLはこのポスターが示唆したとおりに内部的に実行します。定義のコピーを作成し、コピーにロードをトリクルします。
モーガントッカー

この方法は、「tmpへのコピー」部分をスキップするため、大きなテーブルでは時間がかかることがあるため、この方法が気に入っています。
ハルク

MySQL 5.7では、ALTERの方がはるかに高速で簡単に対処できることを付け加えます。
-randomx

7

1)損失保護はパラノイアの機能です。常にバックアップを作成してください。本当に妄想している場合は、バックアップを作成してからバックアップから復元します。

2)このページ MySQLマニュアルのは、テーブルタイプを変換する手順が記載されています。

テーブルをInnoDBに変更する最も速い方法は、InnoDBテーブルに直接挿入することです。つまり、ALTER TABLE ... ENGINE = INNODBを使用するか、同じ定義で空のInnoDBテーブルを作成し、INSERT INTO ... SELECT * FROM ...で行を挿入します。

3)PostgreSQLは全文検索を行いますがSphinxエンジンはMySQLに対してそれを行うようです


スフィンクスについては最近聞いたばかりなので、間違いなく調べます。
デレクダウニー

3

エンジンを1つしか使用していない場合、サーバー全体(メモリ構成、キャッシュ、インデックス)を最適化するのはX倍簡単です。大規模なデータベースでmyisamとinnodbを混在させると、両方のエンジンが正常に機能するための妥協によって強制された時点で常にスタックします(ただし、優秀ではありません:)

sphinx、lucene(solr)のような専用の全文検索エンジンに興味を持ち、データベース層からそれを取り除くことをお勧めします。

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