MySQL移行計画と落とし穴の実践記録

MySQL移行計画と落とし穴の実践記録

背景

過去のビジネス データは MySQL に保存されるため、操作記録テーブル video_log があります。ユーザーがレコードを作成、更新、または監査人がレコードを確認するたびに、対応する video_log にログが追加されます。このログ テーブルには挿入のみがあります。ご想像のとおり、1 つのビデオは複数のログに対応します。1 日に 100,000 本のビデオがある場合、1 つのビデオに対して平均 5 つのログは、1 日に 500,000 ログ、1 か月に 50 * 30 = 1,500 万レコード、1 年に 1500 * 12 = 1 億 8,000 万レコードを意味します。現在、オンライン上のデータは 2 億件以上あります。ログ自体は C エンド向けではなく、問題を照会するために使用されるため、若干の遅延は許容されます。 しかし、時間が経つにつれて、どうしても速度が遅くなり、効率に影響が出るため、変換のアイデアが提案されました。

解決策1: 古いデータをバックアップする

ログ自体は最も重要なデータではありませんが、高いリアルタイム性能も要求されるため(リアルタイムクエリの問題)、コアとなる基本ストレージは変更せずに、古いデータを移行するというアイデアが当初の考えでした。結局のところ、1年前の操作記録を突然クエリする可能性は非常に低いです。突然確認する必要がある場合は、オフラインにすることができます。設計面では、毎日午前 4 時頃 (ビジネスのオフピーク時間帯) にデータを抽出するスケジュールされたスクリプトのみが必要です。抽出されたデータは、何らかのオフライン ストレージ (一般的に企業には Hive ベースのデータ ウェアハウスなどがある) にレポートできるため、オンラインの video_log データは増加し続けます。

オプション2: テーブルを分割する

テーブルを分割することも解決策の 1 つです。ソリューション 1 と比較すると、すべてのデータをリアルタイムでクエリできるという利点があります。欠点は、コードを変更する必要があることです。

  • まず、シャーディング キーを確認します。video_log はビデオにバインドされているため、シャーディング キーとして video_id を当然選択します。
  • テーブルの分割方法が決まったので、テーブルをいくつに分割するかを確認する必要があります。まずは小さな目標を設定し、それを 3 年間続けましょう。各テーブル内の最大データ量は 1 億です (クエリが単純なため)。上記の統計によると、3 年間でおよそ 3*1.8=5 億 4000 万となり、およそ 5.4/1≈6 個のテーブルが必要になります。

次のステップは、コードを変換し、新しいデータと古いデータの読み取りと書き込みの問題を解決することです。

  • 新しいデータは新しいテーブルに直接挿入されます
  • ログ テーブルには挿入操作のみがあり、更新操作や削除操作はないため、これらのシナリオを考慮する必要はありません。
  • テーブルを分割すると、ビデオのログが 2 つのテーブル (古いテーブルと新しいテーブル) に存在するため、両方のテーブルを一時的にチェックしてから結合します。
  • 古いデータを新しいテーブルに同期する
  • 古いテーブルを読み取るためのオフラインコード

解決策3: tidbに移行する

オプション 2 の欠点は明らかです。3 年後はどうすればよいのでしょうか? メーターの解体を続けるのでしょうか?そこには常に歴史的な負債があるように感じます。そこで私たちは、分散データベースである tidb に目を向けました。tidb に接続すれば、テーブルのシャーディングについて心配する必要はありません。tidb がこれらすべてを実行し、ノードの容量を自動的に拡張します。分散されているため、tidb の主キーは順序付けられておらず、これは非常に重要です。
全体のプロセスは、おおまかに次の 4 つのステップに分けられます。

  1. 最初に二重書き込みを行う (二重書き込みの開始時に MySQL ID を記録します。この ID の前のデータは古いデータである必要があります)
  2. 古いデータを同期する(最初のステップで記録したIDで区別)
  3. カット読み取り(旧データ同期完了)
  4. 二重書き込み

古いデータを同期する際の落とし穴に焦点を当ててみましょう。

tidb への移行は簡単に思えますが、実際にはジョブ スクリプトにいくつかの落とし穴が隠れています。

  • ジョブが途中で中断され、再開しなければならない場合の対処方法も考慮する必要があります。データの再実行にかかる時間コストの他に、再実行時に同期済みのデータが重複してしまうため、重複データの問題も考慮する必要があります。重複データの問題を解決するには、古いテーブルに新しいフィールドを追加して、同期されたかどうかを示します。同期が完了するたびに、フィールドを更新します。デメリット: オンライン データが大きいため、フィールドを追加すると安全ではなく、オンラインの混雑が発生する可能性があります。
  • フィールドを追加するのは得策ではないので、既存の主キー ID を制約として使用し、主キー ID を同期します。この方法では、スクリプトを再起動して最初から実行した場合でも、同じ主キーが挿入されているため、エラーが報告され、スキップされます。完璧に思えますが、tidb は分散されており、主キー ID は連続していないため、このような状況が発生する可能性があります。通常の業務データを tidb に挿入する場合、tidb が割り当てた主キー ID と、mysql と同期した主キー ID が重複します。この場合、誰が挿入しても、最後の 1 つは必ず失敗します。

最終同期スクリプトソリューション

データの重複、ジョブの再開の効率、全体の同期の効率を考慮して、大まかに次のような計画を立てました。

  1. タスクをバッチに分割して効率化: まず、処理能力と完了予定時間に応じて、古いデータをバッチに分割します。バッチは約 10 個あります。10 個のジョブは互いに干渉することなく異なるバッチのデータを実行し、そのたびに 100 項目がバッチで更新されます。
  2. 状態を記録し、再起動後にブレークポイントに自動で復元: 各データ同期後に現在の同期位置を記録します (redis は現在の ID を記録します)。再起動しても、前回の更新位置を redis から取得して更新できます。
  3. 主キーの競合を避ける: 主キー以外のすべてのフィールドを同期します (主キーは同期しません)

最終的に、ソリューション 3 の 4 つの切り替え手順 + 効率的な同期スクリプトにより、データ移行がスムーズに完了しました。

要約する

これで、MySQL 移行ソリューションと落とし穴に関するこの記事は終了です。より関連性の高い MySQL 移行ソリューションと落とし穴については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQLデータベースのデータフォルダを移行するための詳細な手順
  • MySQLデータベースを別のマシンに移行する方法の詳細な説明
  • OracleデータベースをMySQLに移行する方法の概要
  • MySQLデータベースをOracleデータベースに移行する
  • MySQLデータベース移行により、大量のデータを迅速にエクスポートおよびインポートできます
  • MySQL InnoDB テーブルスペースのアンロード、移行、ロードの使用方法
  • MySQLデータ移行の詳しい説明 - データディレクトリ直接置換の注意事項
  • MySQLからClickHouseに移行する5つの方法
  • mysql5.5 データベースデータディレクトリ移行方法の詳細な説明
  • MySQLのバックアップと移行データの同期方法

<<:  Nginx の場所と proxy_pass パスの設定の問題の概要

>>:  シンプルで簡単なJavaScript開発のためのSvelte実装原理の詳細な説明

推薦する

ラジオボタンとチェックボックス効果の純粋な CSS 実装例

ラジオボタンとチェックボックスラジオボタンとチェックボックスの効果を実現するための純粋な CSSラジ...

yum の基本的な使い方と例(推奨)

yumコマンドYum (フルネームは Yellow dog Updater, Modified) ...

mysql zipファイルのインストールチュートリアル

この記事では、参考までにMySQL zipファイルをインストールする具体的な方法を紹介します。具体的...

MySQL 文字セットの文字化けとその解決方法

序文文字セットは、一連のシンボルとエンコード規則です。Oracle データベースでも MySQL デ...

Vue ソング プログレス バーのサンプル コード

なお、これはvue-cliで作成したプロジェクトではありません。vue.jsを参照して記述したHTM...

WeChatアプレットAmapマルチポイントルート計画プロセス例の詳細な説明

電話Amap API を呼び出す方法は? Amap が https://lbs.amap.com/a...

Docker 自動ビルド 自動ビルド実装プロセス図

自動ビルドとは、Docker Hub を使用して、Dockerfile ファイルを含む GitHub...

DockerにJava環境をインストールするための実装手順

この記事は Linux centos8 をベースにして、docker をインストールし、イメージをプ...

ウェブページのドロップダウンリストとdivレイヤーのカバーの問題を選択する

HTML の select 要素に関する質問は、さまざまな場所で提起されています。最近のプロジェクト...

html ページ!--[IE の場合]...![endif]--使用方法の詳細な紹介

コードをコピーコードは次のとおりです。 <!--[IEの場合]><script t...

HTML テーブルタグチュートリアル (44): テーブルヘッダータグ

<br />ソース コード内で表の構造を明確に区別するために、HTML 言語では、表のヘ...

htmlハイパーリンクaのクリックイベントの後、hrefで指定されたアドレスにジャンプします。

場合によっては、ジャンプを完了するために href の代わりにハイパーリンク <a> を...

CentOS7にJDK8をrpmモードでインストールする

CentOS 7が正常にインストールされると、OpenJDKのJREがデフォルトでインストールされて...

背景とリンクとして画像を書き込む方法(背景画像+リンク)

写真を背景にしてリンクを記載します。たとえば、ウェブサイトのロゴ画像などです。例: ポテトのロゴ画像...

k8sとDockerの関係についての簡単な説明

最近、プロジェクトでは kubernetes (以下、k8s と表記、k と s の間には 8 つの...