MyISAMからInnoDBへのオンライン変換後に行が失われる


16

MyISAMからInnoDBに変換したいかなり小さなデータベースがあります。データベース初心者であるため、サイトをダウンさせることなく変換(alter tableを使用)しました。

変換が完了したので、多くの断続的な行が欠落しているようです。これは、おそらく変換中の操作によるものですか?または、問題はどこか別の場所ですか?


どのテーブルに行がありませんか?変換したものまたは他のテーブル?
ロングネック

回答:


20

ALTERを実行してストレージエンジンを変更しても、行が消えることはありません。しかし、あなたはあなたがあなたの質問で「データベース初心者」だと言ったので、いくつかのアドバイスをさせてください。

既存のスキーマを変更したり、データに影響を与える可能性のあることを行ったりする場合、基本的なアドバイスを次に示します。

  1. 最初にバックアップを作成します。
  2. 変更計画を立ててください。
  3. オフラインホストで計画をテストします。
  4. データの前後で比較するテスト計画を立てます。
  5. ダウンタイムをスケジュールしてください。
  6. ダウンタイムが有効になり、トラフィックが停止したことを確認したら、すぐにバックアップとスナップショットを作成します。
  7. MYISAMを実行している場合、ALTERする前に、「CHECK TABLE」を使用して、何を扱っているかを評価します。
  8. 念のため、バックアップに加えてテーブルをローカルにコピーします。
  9. 注意して進め、「-show warnings」およびその他の出力を有効にして、変更の全体像を把握します。
  10. データが重要な場合は、DBAを雇ってください。移行中に相談するだけでも、ベテランのベテランを味方につけることができます。

おそらくもっと多くのことができるでしょうが、上記は何かがうまくいかないときにオプションを提供します。

不足しているデータ/行に関しては、「前/後」のスナップショットを比較して知る方法はありません。最新のバックアップと比較して、少なくともその程度を確認できます。


これを読みました。良いDR計画。進行中の計画に加えて、私が質問よりも敏感だったため、あなたの答えは+1されます。
RolandoMySQLDBA

1
@randyあなたの良い答えのためにこれをお気に入りの質問としてマークしました
-techExplorer

8

多くのダウンタイムなしでMyISAMをInnoDBに変換する最良の方法の1つは、レプリケーションスレーブを使用するという1つの前提条件のみです。

これがその計画の鳥瞰図です

  1. レプリケーションマスター/スレーブセットアップの作成
  2. スレーブ上のすべてのMyISAMテーブルをInnoDBに変換します
  3. アプリをスレーブに向ける

簡単に聞こえますか?この背後には多くの詳細があります。

レプリケーションマスター/スレーブセットアップの作成

マスターに大きな混乱を与えることなくスレーブを作成する洗練された方法があります。私は2つの投稿を書きました:

rsyncの使用方法を詳しく説明するのではなく、これら2つの投稿を読んでください。

スレーブ上のすべてのMyISAMテーブルをInnoDBに変換します

DBスレーブでは、次のSQLステートメントを実行できます。

MySQL 5.5の場合:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

MySQL 5.5より前のMySQLのバージョン

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

クエリからの出力を使用して、スレーブ用の変換スクリプトを作成します。

次の2行をスクリプトの先頭に配置する必要があります。

SET SQL_LOG_BIN = 0;
STOP SLAVE;

スクリプトは、最初にバイナリロギングを無効にし(スレーブにバイナリログを設定した場合)、レプリケーションを停止し、各MyISAMテーブルをInnoDBに変換します。

そのスクリプトを作成して実行する方法は次のとおりです。

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

アプリをスレーブに向ける

スレーブからSELECTクエリを実行します。スレーブ上のデータコンテンツに満足している場合は、次のようにアプリをスレーブに向けてください。

  1. スレーブで、SHOW SLAVE STATUS\GSeconds_Behind_Masterが0であることを確認して実行します
  2. スレーブで、mysqldump -h(スレーブのIP)-u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql(バックアップが適切でしょう今について)
  3. マスターで、実行service mysql stop(ダウンタイム開始)
  4. ステップ1を繰り返します
  5. アプリをスレーブに向ける(ダウンタイムはアプリの最初の接続で終了します)

これまで無傷でおめでとうございます、おめでとうございます!!!

追加ボーナス:マスター/スレーブの代わりにマスター/マスターレプリケーション(別名循環レプリケーション)をセットアップする場合、代わりにこれを行うことができます:

  1. スレーブで、SHOW SLAVE STATUS\GSeconds_Behind_Masterが0であることを確認して実行します
  2. スレーブで、mysqldump -h(スレーブのIP)-u ... -p ... --single-transaction --routines --triggers --all-databases> MySQLBackup.sql(バックアップが適切でしょう今について)
  3. アプリをスレーブに向ける(ダウンタイムはアプリの最初の接続で開始および終了します)
  4. 新しいマスターで、実行します STOP SLAVE;
  5. 新しいマスターで、実行します CHANGE MASTER TO MASTER_HOST='';

あなたが今持っているのは、逆のマスター/スレーブです。新しいマスターにはInnoDBデータがあり、古いマスターはMyISAMデータを持つスレーブになりました。読み取りと書き込みを分割すると、読み取りはスレーブから行われ(読み取りはMyISAMからInnoDBより高速になります)、書き込みはマスターに送られます(InnoDBのトランザクションサポート)。ハンナ・モンタナが歌うように、あなたは(はい、私はショーを愛する2人の娘を持っている)の両方の長所を取得します

別の追加ボーナス:マスターがInnoDBになったため、ダウンタイムやトランザクションを妨げることなく、マスターからmysqldumpを実行できます。唯一の欠点は、CPUとディスクI / Oの増加です。したがって、マスター(InnoDB)のみのテーブル構造のmysqldumpおよびスレーブのみのデータのmysqldump(このようなダンプはInnoDBまたはMyISAMへの参照を持ちません。データのみになります)とmysqldumpのスレーブがMyISAMレイアウトを持つためのテーブル構造。

この新しいセットアップにより、可能性が広がります...

更新2011-08-27 19:50 EDT

謝罪いたします。私は質問を完全には読みませんでした。あなたはすでに会話をしました

既にバイナリロギングを有効にしていて、以前にバックアップを行っている場合のみ、

  • / var / lib / mysql2のような別の場所に/ var / lib / mysqlを復元します
  • 走る service mysql stop
  • 走る service mysql start --datadir=/var/lib/mysql2
  • そのバックアップから/root/olddata.sqlにデータベースをmysqldump
  • /root/changes.sqlへの最後のバックアップ以降の特定の時点から/ var / lib / mysql(/ var / lib / mysql2ではない)内のすべてのバイナリログに対してmysqlbinlogを実行します。
  • changes.sqlをmysqlにロードします(まだ/ var / lib / mysql2を指しているため)

これにより、記録されたすべてが捕捉され、変換が開始されるはずです。繰り返しますが、これはすべて、前回のバックアップの前に既にバイナリロギングをオンにしてい場合に発生します。そうでなければ、私の哀dolの意。

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