0

私たちは PHP で書かれたシステムを持っていますが、これは何年にもわたってかなり大きくなっています。データベースは MySQL (InnoDB テーブル) で、現在 12GB を超えるデータがあり、何百ものテーブルがあり、その多くには 1200 万を超えるレコードがあります!

問題は、多くのテーブル/列 (すべてではない) が latin1 にあり、(明らかに) 外国語の文字を保存する際に問題が発生していることです。

可能な限り短いダウンタイムで、すべてのテーブル/テキスト列を UTF8 に変換する最善の方法は何ですか?

このシステムは何百人もの人々が 24 時間年中無休で使用しているため、長時間のダウンタイムは許されません。

大量のダウンタイムなしでこれを成功させる方法はありますか?また、注意が必要な明らかな点はありますか?

アプリケーションで utf-8 を使用するには、次の設定が必要になることはわかっています。

  • <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  • ini_set('default_charset', 'utf-8');
  • SET NAMES utf8
  • ファイルをアップロードする前に、IDE で UTF8 にエンコードされたファイル

私は他のさまざまな投稿を読みましたが、誰もがさまざまな方法を提案しているようで、完全なデータベースのダンプ/復元が必要だと言う人もいます...これは、何時間ものダウンタイムを意味します.

では、これを行う最善の方法は何ですか?

4

1 に答える 1

0

可能であるが、非常に難しく、リスクもある何かをしたいと思っています。賢いことはあきらめてください。これを簡単にする魔法のようなものは何もありません。一方ではダウンタイムと人件費、他方ではデータ損失のリスクをトレードオフしています。人件費は、15 時間のダウンタイムを取った場合よりもおそらく 10 倍高くなります。

SELECT特定の日付/時刻以降に追加または変更されたすべての行を取得することが保証されているすべてのテーブルのクエリを作成し、すばやく実行することは可能ですか? その場合は、すべてのテーブルに対してこのクエリを作成し、手元に置いておいてください。そうでない場合、この方法は使用できません。

これはテーブルごとに行うことができます。

小さなテーブルはそれほど手間がかかりません。おそらく、アプリケーションがオフピーク時間に稼働している間に実行できます。列を変換するだけです。

大きなテーブルを更新したことがない場合は、問題の列に必要な文字セットとデフォルトの照合を使用して、それらのテーブルのコピーを作成できます。でデータをコピーできますINSERT ... SELECT。( http://dev.mysql.com/doc/refman/5.1/en/insert-select.html ) 最後に、しばらくダウンタイムをとって、本番テーブルの名前を変更し、新しいテーブルに本番テーブル名を付けることができます。InnoDB のトランザクション整合性システムがサーバーの RAM を使い果たすのを防ぐために、これを数千行のチャンクで行う必要がある場合があります。

最後に、大きく変化するテーブルに対処する必要があります。INSERT ... SELECTもう一度、 InnoDB トランザクションがアプリケーションの操作を中断したり、RAM を吹き飛ばしたりしないように、 を使用してテーブルをコピーします。ここでの意図は、特定の日付/時刻の時点でのテーブルのスナップショットを取得することです。

次に、生産を停止します。便利なクエリを使用して、開始時刻以降に挿入および変更されたすべての行を選択し、それらをターゲット テーブルに挿入/更新します。次に、本番テーブルの名前を変更し、ターゲット テーブルに本番テーブルの名前を付けて、本番を再開します。これはかなり迅速に実行できるはずです。

私があなただったら、本番データベースのステージング コピーを作成し、本番で実行する前にこの手順のすべてのステップをリハーサルします。たとえば、InnoDB の外部キー制約で問題が発生します。それらを慎重に処理できる必要があります。

実際、私があなただったら、これをやろうとはしません。飛行機が飛んでいる間に飛行機のエンジンを交換するようなものです。何が問題になる可能性がありますか?:-) 代わりに、この変換を完了するためにスケジュールされた Web アプリケーションのダウンタイムが発生します。その場合でも、ライブに移行する前にステージング サーバーですべてを試す必要があります。

于 2013-06-10T11:42:45.373 に答える