web-dev-qa-db-ja.com

MySQLがinnodbデータベースをインポートするとメモリ不足になる

512MBの小さなVPSがありますRAMでスワップはありません(何もありません)。

1.5GBのinnodbデータベースをインポートしています

mysql -u -p <データベース.sql

操作が完了する前に、「MySQLサーバーへの接続が失われました」と表示されます。これは、mysqldが480MBを超えるRAMを取得しようとしてクラッシュしたためです。

これは私のmy.cnfです

[client]
port            = 3306
socket          = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket          = /var/run/mysqld/mysqld.sock
Nice            = 0

[mysqld]
#
# * Basic Settings
#
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = 3306
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address            = 127.0.0.1
#
# * Fine Tuning
#
key_buffer              = 16M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover         = BACKUP
max_connections        = 4
#table_cache            = 64
#thread_concurrency     = 10
#
# * Query Cache Configuration
#
query_cache_limit       = 1M
query_cache_size        = 16M
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file        = /var/log/mysql/mysql.log
#general_log             = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Here you can see queries with especially long duration
#log_slow_queries       = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
#server-id              = 1
#log_bin                        = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
#binlog_do_db           = include_database_name
#binlog_ignore_db       = include_database_name
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
#
innodb_buffer_pool_size=80M
innodb_additional_mem_pool_size=20M

innodb_flush_log_at_trx_commit=0
innodb_log_buffer_size = 8M

[mysqldump]
quick
quote-names
max_allowed_packet      = 16M

[mysql]
#no-auto-rehash # faster start of mysql but no tab completition

[isamchk]
key_buffer              = 16M

より詳しい情報:
*テーブルがたくさんあります:30kテーブル
* ubuntu 12.04でmysql 5.5を実行しています
* mysqlのinnodbのメモリ使用量について多くのことを読みました...存在する数式が機能しないため、何か不足しているはずです

このスクリプト

mysql -u admin -p -e "show variables; show status" | awk '
{
VAR[$1]=$2
}
END {
MAX_CONN = VAR["max_connections"]
MAX_USED_CONN = VAR["Max_used_connections"]
BASE_MEM=VAR["key_buffer_size"] + VAR["query_cache_size"] + VAR["innodb_buffer_pool_size"] + VAR["innodb_additional_mem_pool_size"] + VAR["innodb_log_buffer_size"]
MEM_PER_CONN=VAR["read_buffer_size"] + VAR["read_rnd_buffer_size"] + VAR["sort_buffer_size"] + VAR["join_buffer_size"] + VAR["binlog_cache_size"] + VAR["thread_stack"] + VAR["tmp_table_size"]
MEM_TOTAL_MIN=BASE_MEM + MEM_PER_CONN*MAX_USED_CONN
MEM_TOTAL_MAX=BASE_MEM + MEM_PER_CONN*MAX_CONN

printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %15.3f MB |\n", "key_buffer_size", VAR["key_buffer_size"]/1048576
printf "| %40s | %15.3f MB |\n", "query_cache_size", VAR["query_cache_size"]/1048576
printf "| %40s | %15.3f MB |\n", "innodb_buffer_pool_size", VAR["innodb_buffer_pool_size"]/1048576
printf "| %40s | %15.3f MB |\n", "innodb_additional_mem_pool_size", VAR["innodb_additional_mem_pool_size"]/1048576
printf "| %40s | %15.3f MB |\n", "innodb_log_buffer_size", VAR["innodb_log_buffer_size"]/1048576
printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %15.3f MB |\n", "BASE MEMORY", BASE_MEM/1048576
printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %15.3f MB |\n", "sort_buffer_size", VAR["sort_buffer_size"]/1048576
printf "| %40s | %15.3f MB |\n", "read_buffer_size", VAR["read_buffer_size"]/1048576
printf "| %40s | %15.3f MB |\n", "read_rnd_buffer_size", VAR["read_rnd_buffer_size"]/1048576
printf "| %40s | %15.3f MB |\n", "join_buffer_size", VAR["join_buffer_size"]/1048576
printf "| %40s | %15.3f MB |\n", "thread_stack", VAR["thread_stack"]/1048576
printf "| %40s | %15.3f MB |\n", "binlog_cache_size", VAR["binlog_cache_size"]/1048576
printf "| %40s | %15.3f MB |\n", "tmp_table_size", VAR["tmp_table_size"]/1048576
printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %15.3f MB |\n", "MEMORY PER CONNECTION", MEM_PER_CONN/1048576
printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %18d |\n", "Max_used_connections", MAX_USED_CONN
printf "| %40s | %18d |\n", "max_connections", MAX_CONN
printf "+------------------------------------------+--------------------+\n"
printf "| %40s | %15.3f MB |\n", "TOTAL (MIN)", MEM_TOTAL_MIN/1048576
printf "| %40s | %15.3f MB |\n", "TOTAL (MAX)", MEM_TOTAL_MAX/1048576
printf "+------------------------------------------+--------------------+\n"
}'

そして、これは出力です

+------------------------------------------+--------------------+
|                          key_buffer_size |          16.000 MB |
|                         query_cache_size |          16.000 MB |
|                  innodb_buffer_pool_size |          80.000 MB |
|          innodb_additional_mem_pool_size |          20.000 MB |
|                   innodb_log_buffer_size |           8.000 MB |
+------------------------------------------+--------------------+
|                              BASE MEMORY |         140.000 MB |
+------------------------------------------+--------------------+
|                         sort_buffer_size |           2.000 MB |
|                         read_buffer_size |           0.125 MB |
|                     read_rnd_buffer_size |           0.250 MB |
|                         join_buffer_size |           0.125 MB |
|                             thread_stack |           0.188 MB |
|                        binlog_cache_size |           0.031 MB |
|                           tmp_table_size |          16.000 MB |
+------------------------------------------+--------------------+
|                    MEMORY PER CONNECTION |          18.719 MB |
+------------------------------------------+--------------------+
|                     Max_used_connections |                  1 |
|                          max_connections |                  4 |
+------------------------------------------+--------------------+
|                              TOTAL (MIN) |         158.719 MB |
|                              TOTAL (MAX) |         214.875 MB |
+------------------------------------------+--------------------+

しかし、一番上にはmysqldのメモリ使用量が481mになり、その後mysqlがクラッシュすることがわかります。

メモリ使用量を制限するためにどの構成が欠けていますか?!ありがとう

4
Lazik

リック・ジェームスは正しい方向に進んでいると思います。30kのテーブルハンドルの多くがメモリを妨害しています。

MySQL 5.5では、InnoDBはシステムテーブルスペースを使用します。これにより、すべてのテーブルデータが単一のOSファイルに配置されます。これは、個々の内部テーブルデータの割り当てとハンドル管理がMySQL内で発生することを意味します(つまり、完全にRAMスワップスペースがないため))。ホストからの支援はありません。 OS(Ubuntu 12)。

innodb_file_per_tableを有効にしてみます。

https://dev.mysql.com/doc/refman/5.5/en/tablespace-enabling.html

MySQL 5.6.6以降、innodb_file_per_tableオプションはデフォルトで有効になっているため、5.5サーバーで有効にする必要があります。

[mysqld]
innodb_file_per_table
...

(設定に値が指定されていないことに注意してください。キーが存在すると機能が有効になります)

これにより、MySQL InnoDBがより多くのOSおよびディスクリソースをテーブル管理に使用できるようになり、ヒープの使用量とメモリ管理のスラッシュが削減されると期待されます。

MySQLは既存のテーブルをファイルごとに変換しないため、クリーンインストール(既存のテーブルデータがない)で開始するか、少なくともMySQLをシャットダウンして、datadirのibdata *およびib_log *ファイルを削除することができます。フォーマット。 MySQLは起動時に不足しているib *ファイルを再構築します。関連するエラーメッセージが表示されることを期待しています。

MySQLはinnodb_file_per_tableを使用して、個々のテーブルファイル(.fmtおよび.ibd)をdatadirのサブディレクトリに保存します。各ディレクトリはmysql table_schemaです。 30kテーブルのすべてを1つのスキーマ/フォルダーに配置する場合、Ubuntuがディレクトリインデックス全体をメモリにロードしようとするため、OSレベルで同じ問題が発生する可能性があります。可能であれば、テーブルをいくつかの別々のスキーマ/フォルダーに編成し、スキーマあたりのテーブル数を1000以下に保つようにします。

1
dkloke

この問題の私の解決策を試すことができます- MySQLDumpSplitter 。ダンプファイルを受け取り、それを個々のテーブルに分割します。私のメールはあなたのニーズに合わないはずです-ツールをより良くするためにあなたが持っているかもしれないどんな問題も見ることができます。

免責事項:私はそれを書いた、そしてあなたがReadmeからわかるように、それは特定の条件下でのみ機能する。独自の裁量で使用してください。

1
Vérace

回避策

BigDumphttp://www.ozerov.de/bigdump/

巨大なダンプのほんの一部しか実行せず、再起動します。次のセッションは、最後のセッションが停止したところから始まり、サーバーの制限に達しないようにします。使用方法はBigDumpのWebサイトにあります。基本的に、SQLファイルをbigdump.phpファイルと共にサーバー上のフォルダーに配置します。データベース情報を使用してそのファイルを編集し、サーバーのページにアクセスして、インポートを実行するように設定します。これはかなり迅速なプロセスであり、多くの時間を節約します。

SQLDumpSpliterhttp://www.rusiczki.net/2007/01/24/sql-dump-file-splitter/

スプリットを作成し、サーバー上のディレクトリにアップロードします。

ダンプを復元する場合は、テーブル構造が含まれているため、最初にyourdatabase_DataStructure.sqlを実行する必要があります。その後、既存のテーブルのデータが含まれている他の.sqlファイルを実行できます。 SSHを使用して、もう一度CDをディレクトリに移動し、必ず最初にこれを送信してください。

mysql -u db_user -p db_name < yourbackup_DataStructure.sql

次に、あなたの分割:

mysql -u db_user -p db_name < yourbackup_1.sql
mysql -u db_user -p db_name < yourbackup_2.sql

ソース: http://www.ontwerps.nl/methods-importing-large-sql-files

1
nmad

Mydumperについて教えてくれる人もいます。今まで使ったことはありませんが、とても期待しています。 mydumperについて:

http://imagexmedia.com/blog/2014/11/speeding-your-mysql-dumprestores-mydumper
http://www.percona.com/blog/2014/03/10/new-mydumper-0-6-1-release-offers-several-performance-and-usability-features/
0
Luke Nguyen

2ステップで実行してみてください

mysql -u username -p db_name

いったん入ったら、「ソース」コマンドを使用します

> source database.sql
0
Unmesh
  • テーブルがたくさんあります:30kテーブル

RAM(0.5GBの代わりに)の現在の量がある場合でも、それは本当に悪いことです。OSはそれらのためにスペースを確保する必要があり、mysqlはスペースを必要とし、InnoDBもスペースを必要とします。

証明できませんが、それが一番の問題だと思います。

0
Rick James

あなたの問題ではありませんが、これと同じ問題があり、私の問題はinnodb_buffer_pool_sizeが大きすぎます。私はそれをDocker内で実行し、16Gに設定しました。これは、本番環境での設定方法ですが、Dockerはメモリを要求しすぎたため、早期に強制終了していました。この設定を6Gに下げると問題が解決しました。

これをDockerで実行している場合は、Dockerが割り当てることができるメモリもデフォルトの2から増やしてください。私は8 GBに設定しています。これが誰かを助けることを願っています。

0
Hassan