web-dev-qa-db-ja.com

MySQLでibdata1ファイルを縮小/削除する方法

LocalhostでMySQLをRで統計を実行するための「クエリツール」として使用しています。つまり、Rスクリプトを実行するたびに、新しいデータベースを作成し(A)、新しいテーブルを作成し(B)、データをBにインポートします。 、必要なものを取得するためにクエリを送信し、次にBをドロップしてAをドロップします。

私には問題なく動作していますが、ibdataファイルのサイズが急激に増加していることがわかりました。MySQLには何も保存しませんでしたが、ibdata1ファイルはすでに100 MBを超えています。

セットアップに多かれ少なかれデフォルトのMySQL設定を使用していますが、一定期間後にibdata1ファイルを自動的に縮小/削除する方法はありますか?

530
lokheart

ibdata1が縮小されていないことは、MySQLの特に厄介な機能です。 ibdata1ファイルは、すべてのデータベースを削除し、ファイルを削除してダンプを再ロードしない限り、実際には縮小できません。

しかし、インデックスを含む各テーブルが別々のファイルとして格納されるようにMySQLを設定することができます。そのようにすればibdata1はそれほど大きくならないでしょう。 Bill Karwinのコメントによれば これはMySQLのバージョン5.6.6からデフォルトで有効になっています。

それはしばらく前でした。ただし、テーブルごとに別々のファイルを使用するようにサーバーを設定するには、これを有効にするためにmy.cnfを変更する必要があります。

[mysqld]
innodb_file_per_table=1

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

ibdata1からスペースを取り戻したいのであれば、実際にファイルを削除する必要があります。

  1. すべてのデータベース、プロシージャ、トリガなどのmysqldumpを実行します mysqlおよびperformance_schemaデータベースを除く
  2. すべてのデータベースを削除 上記の2つのデータベースを除く
  3. MySQLを停止します。
  4. ibdata1ib_logファイルを削除する
  5. Mysqlを起動します
  6. ダンプから復元

手順5でMySQLを起動すると、ibdata1およびib_logファイルが再作成されます。

今、あなたは行くのに適しています。分析用に新しいデータベースを作成すると、テーブルはibd*ではなく、別々のibdata1ファイルに配置されます。通常すぐにデータベースを削除するので、ibd*ファイルは削除されます。

http://dev.mysql.com/doc/refman/5.1/en/drop-database.html

あなたはおそらくこれを見ました:
http://bugs.mysql.com/bug.php?id=1341

コマンドALTER TABLE <tablename> ENGINE=innodbまたはOPTIMIZE TABLE <tablename>を使用して、ibdata1からデータページとインデックスページを別々のファイルに抽出できます。ただし、上記の手順を実行しない限り、ibdata1は縮小されません。

information_schemaに関しては、削除する必要はなく、不可能でもありません。実際には、テーブルではなく、単に読み取り専用ビューの集まりです。そしてそれらに関連するファイルはなく、データベースディレクトリさえもありません。 informations_schemaはメモリdb-engineを使用しており、mysqldの停止/再起動時に削除され再生成されます。 https://dev.mysql.com/doc/refman/5.7/en/information-schema.html を参照してください。

748
John P

に追加するJohn Pの答え

Linuxシステムの場合、手順1〜6は次のコマンドで実行できます。

  1. mysqldump -u [username] -p[root_password] [database_name] > dumpfilename.sql
  2. DROP DATABASE [database_name];
  3. Sudo /etc/init.d/mysqld stop
  4. Sudo rm /var/lib/mysql/ibdata1
    Sudo rm /var/lib/mysql/ib_logfile(そしてib_logfile0ib_logfile1などと名付けられている可能性のある他のすべてのib_logfileを削除します)
  5. Sudo /etc/init.d/mysqld start
  6. create database [database_name];
  7. mysql -u [username]-p[root_password] [database_name] < dumpfilename.sql

警告:このmysqlインスタンスに他のデータベースがある場合、これらの指示により他のデータベースを失うことになります。保持したいすべてのデータベースをカバーするようにステップ1、2および6、7が変更されていることを確認してください。

42
Vinay Vemula

Innodbテーブルを削除しても、MySQLはibdataファイル内のスペースを解放しないため、増え続けます。これらのファイルはほとんど圧縮されません。

既存のibdataファイルを縮小する方法:

http://dev.mysql.com/doc/refman/5.5/en/innodb-resize-system-tablespace.html

これをスクリプト化して、スクリプトを一定期間後に実行するようにスケジュールすることができますが、上記の設定では、複数の表領域を使用するほうが簡単な方法のようです。

構成オプションinnodb_file_per_tableを使用すると、複数の表領域が作成されます。つまり、MySQLは1つの共有ファイルではなく、テーブルごとに別々のファイルを作成します。これらの別々のファイルはデータベースのディレクトリに格納され、このデータベースを削除すると削除されます。これにより、あなたの場合にibdataファイルを縮小/削除する必要がなくなります。

複数の表領域に関する詳細情報:

http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html

33
titanoboa

MySQLテーブル(の一部)にInnoDBストレージエンジンを使用している場合は、おそらくデフォルトの設定に問題があると思います。 MySQLのデータディレクトリ(Debian/Ubuntu - /var/lib/mysql)に気づいたかもしれませんが、 'ibdata1'というファイルがあります。 MySQLインスタンスのほぼすべてのInnoDBデータ(トランザクションログではありません)を保持しているため、非常に大きくなる可能性があります。デフォルトでは、このファイルの初期サイズは10MBで、自動的に拡張されます。残念ながら、設計上、InnoDBデータファイルは縮小できません。これが、DELETE、TRUNCATE、DROPなどがファイルによって使用されているスペースを取り戻さない理由です。

私はあなたがそこに良い説明と解決策を見つけることができると思います:

http://vdachev.net/2007/02/22/mysql-reducing-ibdata1/ /

14
Vik

受け入れられた回答の手順を手早くbashで記述しました。

#!/usr/bin/env bash
DATABASES="$(mysql -e 'show databases \G' | grep "^Database" | grep -v '^Database: mysql$\|^Database: binlog$\|^Database: performance_schema\|^Database: information_schema' | sed 's/^Database: //g')"
mysqldump --databases $DATABASES -r alldatabases.sql && echo "$DATABASES" | while read -r DB; do
    mysql -e "drop database \`$DB\`"
done && \
    /etc/init.d/mysql stop && \
    find /var/lib/mysql -maxdepth 1 -type f \( -name 'ibdata1' -or -name 'ib_logfile*' \) -delete && \
    /etc/init.d/mysql start && \
    mysql < alldatabases.sql && \
    rm -f alldatabases.sql

purge_binlogs.shとして保存し、rootとして実行します。

mysqlinformation_schemaperformance_schema(およびbinlogディレクトリ)を除外します。

/root/.my.cnfに管理者資格情報があり、データベースがデフォルトの/var/lib/mysqlディレクトリにあるとします。

このスクリプトを実行した後にバイナリログを消去して、次のコマンドでディスク容量を増やすこともできます。

PURGE BINARY LOGS BEFORE CURRENT_TIMESTAMP;

MySQLの空き容量を監視することが目的であり、MySQLを停止してibdataファイルを縮小できない場合は、テーブルステータスコマンドを使用して取得します。例:

MySQL> 5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $20}'

MySQL <5.1.24:

mysqlshow --status myInnodbDatabase myTable | awk '{print $35}'

次に、この値をibdataファイルと比較してください。

du -b ibdata1

ソース: http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html

6
Cyno

上記のmysql-serverレシピの新しいバージョンでは、 "mysql"データベースがクラッシュします。旧バージョンでは動作します。新しいテーブルの中には、テーブルタイプINNODBに切り替わるものがあります。最も簡単な方法は、あなたのデータベースをすべてダンプし、mysql-serverをアンインストールし、残りのmy.cnfを追加することです。

[mysqld]
innodb_file_per_table=1


erase all in /var/lib/mysql
install mysql-server
restore users and databases
4

すでに述べたように、ibdata1を縮小することはできません(そのためにはダンプして再構築する必要があります)が、実際には必要ないこともよくあります。

自動拡張(おそらく最も一般的なサイズ設定)を使用すると、ibdata1はストレージを事前割り振りし、それがいっぱいになるたびに大きくなります。スペースがすでに割り当てられているので、書き込みが速くなります。

データを削除してもデータは縮小されませんが、ファイル内のスペースは未使用としてマークされます。新しいデータを挿入すると、ファイルをさらに大きくする前にファイル内の空きスペースを再利用します。

ですから、実際にそのデータが必要な場合に限り、増え続けるでしょう。実際に他のアプリケーション用のスペースが必要でない限り、それを縮小する理由はおそらくないでしょう。

0
steveayre