MySQL導入innodb數據庫時記憶體不足
我有一個 512MB RAM 的小型 VPS,沒有交換(不能有任何交換)。
我正在導入一個 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 崩潰。
我缺少什麼配置來限制記憶體使用?!謝謝
解決方法
BigDump http://www.ozerov.de/bigdump/
它只執行大轉儲的一小部分並自行重新啟動。下一個會話從上次停止的地方開始,以防止您遇到伺服器的限制。BigDump 網站上提供了使用說明。基本上,您將 SQL 文件與 bigdump.php 文件一起放在伺服器上的文件夾中。您使用數據庫資訊編輯該文件,然後訪問伺服器上的頁面並將導入設置為進行。這是一個相當快的過程,可以為您節省大量時間。
SQLDumpSpliter http://www.rusiczki.net/2007/01/24/sql-dump-file-splitter/
創建拆分,然後將它們上傳到伺服器上的目錄。
如果要恢復轉儲,必須先執行 yourdatabase_DataStructure.sql,因為它包含 Tables 結構。之後,您可以執行其他 .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
我認為 Rick James 是在正確的軌道上,許多 30k 表句柄正在干擾記憶體。
在 MySQL 5.5 中,InnoDB 使用系統表空間,它將所有表數據放在單個 OS 文件中。這意味著單個內部表數據分配以及句柄管理髮生在 MySQL 內部(也就是說,完全在 RAM 中,因為您沒有交換空間),沒有主機作業系統(Ubuntu 12)的幫助。
我會嘗試啟用
innodb_file_per_table
:https://dev.mysql.com/doc/refman/5.5/en/tablespace-enabling.html
innodb_file_per_table 選項從 MySQL 5.6.6 開始預設啟用,因此您必須在 5.5 伺服器上啟用它:
[mysqld] innodb_file_per_table ...
(請注意,設置沒有給出值,鍵的存在啟用了該功能)
這允許 MySQL InnoDB 使用更多的作業系統和磁碟資源進行表管理,有望減少堆使用和記憶體管理抖動。
您可能希望從全新安裝開始(沒有預先存在的表數據),或者至少關閉 MySQL 並刪除 datadir 中的 ibdata* 和 ib_log* 文件,因為 MySQL 不會將現有表轉換為每個文件格式。MySQL 將在啟動時重建失去的 ib* 文件,預計會看到相關的錯誤消息。
使用
innodb_file_per_table
,MySQL 將單獨的表文件(.fmt 和 .ibd)儲存在 datadir 的子目錄中,其中每個目錄是一個 mysql table_schema。如果您將所有 30k 表放入一個模式/文件夾中,您可能會在作業系統級別遇到同樣的問題,因為 Ubuntu 會嘗試將整個目錄索引載入到記憶體中。如果可能的話,將你的表組織成幾個單獨的模式/文件夾,我會盡量保持每個模式的表數不超過 1000。