1. 程式人生 > >MySQL插入大批量資料是報錯“The total number of locks exceeds the lock table size”的解決辦法

MySQL插入大批量資料是報錯“The total number of locks exceeds the lock table size”的解決辦法

事情的原因是:我執行了一個load into語句的SQL將一個很大的檔案匯入到我的MySQL資料庫中,執行了一段時間後報錯“The total number of locks exceeds the lock table size”。

首先使用命令 show variables like '%storage_engine%' 檢視MySQL的儲存引擎:

mysql> show variables like '%storage_engine%';
+----------------------------------+--------+
| Variable_name                    | Value  |
+----------------------------------+--------+
| default_storage_engine           | InnoDB |
| default_tmp_storage_engine       | InnoDB |
| disabled_storage_engines         |        |
| internal_tmp_disk_storage_engine | InnoDB |
+----------------------------------+--------+
4 rows in set, 1 warning (0.00 sec)

可以看到InnoDB是MySQL的預設引擎。

報錯“The total number of locks exceeds the lock table size”說明MySQL的預設配置已經無法滿足你的需求了,
InnoDB表執行大批量資料的更新,插入,刪除操作時會出現這個問題,
需要調整InnoDB全域性的innodb_buffer_pool_size的值來解決這個問題,並且重啟mysql服務。

首先我們通過命令 show variables like "%_buffer_pool_size%" 檢視MySQL快取池的大小:

mysql> show variables like "%_buffer_pool_size%";
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| innodb_buffer_pool_size | 8388608 |
+-------------------------+---------+
1 row in set, 1 warning (0.00 sec)

可以看到,預設的快取池大小是 8388608 = 8 * 1024 * 1024 = 8 MB。我們需要把它改大一點。
那麼到底是多少呢,就是說你剩多少記憶體,用多少記憶體咯,我估計我有個3個G的記憶體可以用,
那麼我可以將innodb_buffer_pool_size的值設成310241024*1024=3221225472。

然後我們配置一下``檔案(MySQL Installer安裝的話,這個是配置檔案的預設位置),將

innodb_buffer_pool_size=8M

修改為:

innodb_buffer_pool_size=3G

對於這個值的配置,其實在配置檔案中也給了說明:

# InnoDB, unlike MyISAM, uses a buffer pool to cache both indexes and
# row data. The bigger you set this the less disk I/O is needed to
# access data in tables. On a dedicated database server you may set this
# parameter up to 80% of the machine physical memory size. Do not set it
# too large, though, because competition of the physical memory may
# cause paging in the operating system.  Note that on 32bit systems you
# might be limited to 2-3.5G of user level memory per process, so do not
# set it too high.

然後重啟mysqld服務。(可通過命令列執行services.msc進入服務視窗)
然後在命令列執行命令檢視此時的快取池大小:

mysql> show variables like "%_buffer_pool_size%";
+-------------------------+------------+
| Variable_name           | Value      |
+-------------------------+------------+
| innodb_buffer_pool_size | 3221225472 |
+-------------------------+------------+
1 row in set, 1 warning (0.00 sec)

可以看到這個值已經修改成了我們想要的大小 —— 3GB。

再次執行我的匯入檔案的SQL,發現可以了,而且還很快呢。

但是記憶體也是有些吃緊的。