web-dev-qa-db-ja.com

Linuxで大きなMySQLデータベースをバックアップする方法

約200GBのMySQLデータベースをバックアップしたい。どうすればいいですか?

Mysqldumpの使用-継続的な書き込みが行われている200GBのデータベースをバックアップしているように感じます。それは良い考えですか?データベースの挿入を停止できません。だから私は一種のホットバックアップを取りたいです。 myisamテーブルのみをバックアップするmysqlhotcopy ..について知っています。そして私はInnodbにテーブルを持っています。

どうすればいいのか、考えやコメントをお願いします。

4
MySQL DBA

MySQL docs で説明されているいくつかの可能なバックアップ方法があります。あなたの場合、「ファイルシステムスナップショットを使用したバックアップの作成」セクションで説明されている方法を明確にお勧めします。この方法では、読み取りロック付きのフラッシュテーブルを発行し、ファイルシステムスナップショット(LVMまたはその他)を作成し、テーブルのロックを解除します。その後、データベースファイルをバックアップメディアにコピーするだけです。

他のオプションは明らかに劣っています。 Mysqldumpは、特に非常に大きなテーブルで、長い間INSERTを防ぐ長いロードスパイクとテーブルロックを作成します。

MySQLにはレプリカセットが同一であることを保証するメカニズムがないため、レプリケーションはさらに洗練されていないソリューションです。これが当てはまると期待する必要がありますが、実際にはバックアップに必要なものではありません。

4
the-wabbit

mysqldumpを使用したバックアップの実行に関する洞察

私見バックアップを行うことは、それにアプローチする方法を知っていれば、より芸術的な形になりました

オプションがあります

オプション1:mysqlインスタンス全体をmysqldumpします

これは最も簡単なもので、簡単です!!!

mysqldump -h... -u... -p... --routines --triggers --all-databases | gzip > MySQLData.sql.gz

テーブル構造、インデックス、トリガー、ストアドプロシージャ、ユーザー、暗号化されたパスワードなど、すべてが1つのファイルに書き込まれます。他のmysqldumpオプションも、さまざまなスタイルのINSERTコマンド、ログファイルと位置座標をバイナリログ、データベース作成オプション、部分データ(--whereオプション)などからエクスポートできます。

オプション2:mysqldumpの個別のデータベースを個別のデータファイルに

データベースのリストを作成することから始めます(これを行うための2つの手法)

テクニック1

mysql -h... -u... -p... -A --skip-column-names -e"SELECT schema_name FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql')" > ListOfDatabases.txt

テクニック2

mysql -h... -u... -p... -A --skip-column-names -e"SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfDatabases.txt

テクニック1が最速の方法です。テクニック2は最も確実で安全です。場合によっては、ユーザーがデータベースに関連しない/ var/lib/mysql(datadir)に汎用のフォルダーを作成するため、テクニック2の方が優れています。 information_schemaは、このフォルダーをデータベースとしてinformation_schema.schemataテーブルに登録します。テクニック2は、mysqlデータを含まないフォルダーをバイパスします。

データベースのリストをコンパイルしたら、必要に応じて並行して、リストをループしてmysqldumpすることができます。

for DB in `cat ListOfDatabases.txt`
do
    mysqldump -h... -u... -p... --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
done
wait

一度に起動するにはデータベースが多すぎる場合は、一度に10個ずつ並列ダンプします。

COMMIT_COUNT=0
COMMIT_LIMIT=10
for DB in `cat ListOfDatabases.txt`
do
    mysqldump -h... -u... -p... --routines --triggers ${DB} | gzip > ${DB}.sql.gz &
    (( COMMIT_COUNT++ ))
    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
    then
        COMMIT_COUNT=0
        wait
    fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
    wait
fi

オプション3:mysqldumpの個別のテーブルを個別のデータファイルに

テーブルのリストを作成することから始めます

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql')" > ListOfTables.txt

次に、すべてのテーブルを10個のグループにダンプします

COMMIT_COUNT=0
COMMIT_LIMIT=10
for DBTB in `cat ListOfTables.txt`
do
    DB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $1}'`
    TB=`echo ${DBTB} | sed 's/\./ /g' | awk '{print $2}'`
    mysqldump -h... -u... -p... --triggers ${DB} ${TB} | gzip > ${DB}_${TB}.sql.gz &
    (( COMMIT_COUNT++ ))
    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]
    then
        COMMIT_COUNT=0
        wait
    fi
done
if [ ${COMMIT_COUNT} -gt 0 ]
then
    wait
fi

オプション4:あなたの想像力を使う

前述のオプションのバリエーションに加えて、クリーンなスナップショットの手法を試してください

  1. テーブルのリストを、各テーブルのサイズの昇順または降順で並べ替えます。
  2. 別のプロセスを使用して、mysqldumpsを起動する前に、「FLUSH TABLES WITH READ LOCK; SELECTSLEEP(86400)」を実行します。 mysqldumpsが完了した後、このプロセスを強制終了します。
  3. Mysqldumpsを古いフォルダーに保存し、古いバックアップフォルダーをローテーションします。
  4. インスタンス全体のmysqldumpをスタンドアロンサーバーにロードします。

[〜#〜]警告[〜#〜]

オプション1だけがすべてをもたらします。欠点は、この方法で作成されたmysqldumpは、mysqldumpが生成されたのと同じmajotリリースバージョンのmysqlにしか再ロードできないことです。つまり、MySQL5.0データベースのmysqldumpを5.1または5.5でロードすることはできません。理由 ? mysqlスキーマは、メジャーリリース間でまったく異なります。

オプション2と3には、ユーザー名とパスワードの保存は含まれていません。

これは、読みやすく、より移植性の高いユーザー向けのSQLGrantsをダンプする一般的な方法です。

mysql -h... -u... -p... --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',Host,''';') FROM mysql.user WHERE user<>''" | mysql -h... -u... -p... --skip-column-names -A | sed 's/$/;/g' > MySQLGrants.sql

オプション3はストアドプロシージャを保存しないため、次の操作を実行できます。

mysqldump -h... -u... -p... --no-data --no-create-info --routines > MySQLStoredProcedures.sql &

注意すべきもう1つのポイントは、InnoDBに関するものです。 InnoDBバッファープールが大きい場合は、バックアップを実行する前に、できる限りフラッシュすることをお勧めします。それ以外の場合、MySQLはバッファプールからダーティページが残っているテーブルをフラッシュすることに時間を費やします。これが私が提案するものです:

バックアップを実行する約1時間前に、このSQLコマンドを実行します

SET GLOBAL innodb_max_dirty_pages_pct = 0;

MySQL 5.5では、デフォルトのinnodb_max_dirty_pages_pctは75です。MySQL5.1以降では、デフォルトのinnodb_max_dirty_pages_pctは90です。innodb_max_dirty_pages_pctを0に設定すると、ダーティページのディスクへのフラッシュが速くなります。これにより、InnoDBテーブルに対してmysqldumpを実行する前に、InnoDBデータの不完全な2フェーズコミットをクリーンアップする影響を防止または少なくとも軽減できます。

mysqldumpの最終ワード

ほとんどの人は他のツールを支持してmysqldumpを敬遠し、それらのツールは確かに優れています。

そのようなツールには次のものが含まれます

  1. MAATKIT(並列 ダンプ / 復元 スクリプト、Perconaから[非推奨ですが素晴らしい])
  2. XtraBackup (PerconaからのTopNotchスナップショットバックアップ)
  3. CDP R1SoftMySQLモジュールオプション ポイントインタイムスナップショットを取得します)
  4. MySQL Enterprise Backup (以前のInnoDB Hot Backups [商用])

真のMySQL DBAの精神を持っている場合は、mysqldumpを採用して、それを完全に習得することができます。すべてのバックアップがMySQLDBAとしてのスキルを反映している可能性があります。

1
RolandoMySQLDBA

最善の選択は、別のMySQLサーバーを作成し、それらをマスター/マスターモードで構成することです。これにより、リアルタイムのバックアップソリューションだけでなく、フェイルオーバーも提供されます。

1
Jim Ekleberry

すべてのテーブルがInnoDBの場合は、オンラインバックアップを提供する Xtrabackup を使用する必要があります。 LVMスナップショットを作成することもできますが、LVMスナップショットのパフォーマンスの問題から、Xtrabackupが推奨されるソリューションであることがわかります。

乾杯

0
HTTP500