web-dev-qa-db-fra.com

MySQL manque de mémoire lors de l'importation de la base de données InnoDB

J'ai un petit VPS avec 512MB RAM et aucun échange (ne peut avoir aucune).

J'importe une base de données InnoDB de 1,5 Go avec

mysql -u -p <base de données.sql

Avant que l'opération puisse finir, il dit: Connexion perdue au serveur MySQL. En effet, le mysqld s'est écrasé en essayant d'obtenir plus de 480 Mo de RAM.

C'est mon 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

Plus d'informations:
[.____] * Il y a beaucoup de tables: tables de 30k
[.____] * J'exécute MySQL 5.5 sur Ubuntu 12.04
[.____] * J'ai lu beaucoup de choses sur MySQL InnoDB Memory Usage ... Je dois manquer quelque chose parce que la formule qu'ils présentes ne fonctionnent pas

Ce script

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"
}'

Et c'est la sortie

+------------------------------------------+--------------------+
|                          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 |
+------------------------------------------+--------------------+

Cependant, en haut, je peux voir l'utilisation de la mémoire mysqld aller à 481m, puis MySQL Crash.

Quelle configuration est manquante pour limiter l'utilisation de la mémoire ?! Merci

4
Lazik

Vous pouvez essayer ma solution à ce problème - mysqldumpsplitter . Il faut un fichier de décharge et le divise dans des tables individuelles que vous pourriez trouver pratiques. Mon email est qu'il ne devrait pas être conforme à vos besoins - je pourrais examiner les problèmes que vous pourriez avoir dans le but de rendre l'outil meilleur.

Disclaimer: Je l'ai écrit et, comme vous le verrez auprès du README, cela ne fonctionne que dans des conditions spécifiques. Utiliser à votre propre discrétion.

1
Vérace

Solution de contournement

BigDump http://www.ozerov.de/bigdump/

Il n'existe qu'une petite partie de l'énorme décharge et redémarre lui-même. La session suivante commence où le dernier a été arrêté pour vous empêcher de courir dans les limites de votre serveur. Les instructions d'utilisation sont sur le site Web de BigDump. Fondamentalement, vous placez votre fichier SQL dans un dossier de votre serveur, ainsi que le fichier BigDump.php. Vous modifiez ce fichier avec vos informations de base de données, puis visitez la page sur votre serveur et définissez l'importation pour aller. C'est un processus assez rapide et vous fera gagner beaucoup de temps.

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

Créez les scissions, puis téléchargez-les sur un répertoire de votre serveur.

Si vous souhaitez restaurer le décharge, vous devez d'abord exécuter le fichier YourDatabase_DaStructure.SQL car il contient la structure des tableaux. Après cela, vous pouvez exécuter les autres fichiers .sql car ils contiennent les données des tables maintenant existantes. Utilisation de SSH, CD sur votre répertoire à nouveau et assurez-vous d'envoyer ceci en premier:

mysql -u db_user -p db_name < yourbackup_DataStructure.sql

Ensuite, vos divisions:

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

Source: http://www.ontwerps.nl/Methods-importing-large-sql-files

1
nmad

Certaines personnes me disent de myDumper. Je ne l'ai pas utilisé avant mais c'est très espoir. À propos de 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

Essayez de le faire en 2 étapes

mysql -u username -p db_name

Une fois que vous êtes dans, utilisez la commande "Source"

> source database.sql
0
Unmesh
  • Il y a beaucoup de tables: tables 30k

C'est vraiment mauvais, même si vous avez une quantité moderne de RAM (au lieu de 0,5 Go). Le système d'exploitation a besoin d'espace pour eux; MySQL a besoin d'espace; InnoDB a également besoin d'espace.

Je ne peux pas le prouver, mais je pense que c'est le problème principal.

0
Rick James

Pas votre problème, mais j'ai eu ce même problème et mon problème était que innodb_buffer_pool_size était trop grand. Je l'exécutais à l'intérieur de Docker et je l'avais fixé à 16g, ce qui est de savoir comment il est placé en production, mais Docker le tuait tôt parce qu'il demandait trop de mémoire. Abaissement de ce paramètre à 6g fixe le problème.

Si vous exécutez ceci dans Docker, veillez également à augmenter la mémoire que vous autorisez Docker d'allouer à partir de la valeur par défaut 2. J'ai une mine définie à 8 Go. J'espère que cela aide quelqu'un.

0
Hassan