我正在MySQL中运行报告。其中一个查询涉及将大量行插入临时表。当我尝试运行它时,我收到此错误:
错误代码1206:锁的数量超过了锁表大小。
有问题的查询是:
create temporary table SkusBought(
customerNum int(11),
sku int(11),
typedesc char(25),
key `customerNum` (customerNum)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into skusBought
select t1.* from
(select customer, sku, typedesc from transactiondatatransit
where (cat = 150 or cat = 151)
AND daysfrom07jan1 > 731
group by customer, sku
union
select customer, sku, typedesc from transactiondatadelaware
where (cat = 150 or cat = 151)
AND daysfrom07jan1 > 731
group by customer, sku
union
select customer, sku, typedesc from transactiondataprestige
where (cat = 150 or cat = 151)
AND daysfrom07jan1 > 731
group by customer, sku) t1
join
(select customernum from topThreetransit group by customernum) t2
on t1.customer = t2.customernum;
我已经读过,更改配置文件以增加缓冲池大小会有所帮助,但这没有任何作用。解决这个问题的方法是临时解决方法还是永久解决方法?
编辑:更改了部分查询。不应该影响它,但我做了一个发现 - 替换所有,并没有意识到它搞砸了。不影响这个问题。
编辑2:将typedesc添加到t1。我在查询中更改了它但不在此处。
答案 0 :(得分:49)
可以通过设置MySQL变量innodb_buffer_pool_size
的较高值来解决此问题。 innodb_buffer_pool_size
的默认值为8,388,608
。
要更改innodb_buffer_pool_size
的设置值,请参阅以下设置。
my.cnf
。对于Linux服务器,这主要是/etc/my.cnf
innodb_buffer_pool_size=64MB
添加到此文件要重启MySQL服务器,您可以使用以下两个选项中的任何一个:
答案 1 :(得分:21)
我找到了解决它的另一种方法 - 使用Table Lock。当然,如果您需要同时更新表格,它可能不适合您的应用程序。
请参阅:
尝试使用LOCK TABLES
来锁定整个表,而不是InnoDB的MVCC行级锁定的默认操作。如果我没有弄错的话,“锁定表”指的是InnoDB内部结构,它存储了MVCC实现的行和版本标识符,其中一位标识正在语句中修改行,并且具有6000万行的表,可能超过分配给它的内存。 LOCK TABLES
命令应该通过设置表级锁而不是行级来缓解此问题:
SET @@AUTOCOMMIT=0;
LOCK TABLES avgvol WRITE, volume READ;
INSERT INTO avgvol(date,vol)
SELECT date,avg(vol) FROM volume
GROUP BY date;
UNLOCK TABLES;
Jay Pipes,
北美社区关系经理,MySQL Inc.
答案 2 :(得分:13)
来自MySQL documentation(您已经阅读过的内容):
1206(ER_LOCK_TABLE_FULL)
锁的总数超过了锁表大小。要避免此错误,请增加innodb_buffer_pool_size的值。在单个应用程序中,解决方法可能是将大型操作分解为更小的部分。 例如,如果大型INSERT发生错误,请执行几个较小的INSERT操作。
如果增加 innodb_buffer_pool_size 没有帮助,那么只需按照粗体部分上的指示并将你的INSERT拆分为3.跳过UNION并制作3个INSERT,每个INSERT都加入 topThreetransit 表。
答案 3 :(得分:2)
如果你已经正确地构建了表,以便每个表包含相对唯一的值,那么执行此操作的方法不那么强烈,就是执行3个单独的insert-into语句,每个表1个,并使用join-filter每个插入 -
INSERT INTO SkusBought...
SELECT t1.customer, t1.SKU, t1.TypeDesc
FROM transactiondatatransit AS T1
LEFT OUTER JOIN topThreetransit AS T2
ON t1.customer = t2.customernum
WHERE T2.customernum IS NOT NULL
对其他两个表重复此操作 - 复制/粘贴是一个很好的方法,只需更改FROM表名即可。 **如果您试图阻止SkusBought表中的重复条目,您可以在WHERE子句之前的每个部分中添加以下连接代码。
LEFT OUTER JOIN SkusBought AS T3
ON t1.customer = t3.customer
AND t1.sku = t3.sku
- 然后是WHERE子句的最后一行 -
AND t3.customer IS NULL
您的初始代码使用了许多子查询,并且UNION语句可能很昂贵,因为它会首先创建自己的临时表来填充来自三个单独源的数据,然后插入到您希望ALONG运行的表中另一个用于过滤结果的子查询。
答案 4 :(得分:2)
:如果你有mysql工作台。转到服务器状态。在我的情况下找到运行服务器文件的位置:
C:\ProgramData\MySQL\MySQL Server 5.7
打开my.ini文件并找到buffer_pool_size。将值设置为高。默认值为8M。 这就是我解决这个问题的方法
答案 5 :(得分:1)
我正在使用MySql工作台运行MySQL窗口。
转到服务器>服务器状态
在顶部,它说配置文件:“path”(C:\ProgramData\MySQL\...\my.ini
)
然后在文件“my.ini”中按控制+ F并找到buffer_pool_size
。
设置值更高,我建议64MB(默认为8MB)。
转到Instance> Startup / Shutdown>重新启动sruver。停止服务器(然后再次启动服务器)
在我的情况下,我无法删除表格中的条目。
答案 6 :(得分:1)
首先,您可以使用sql命令show global variables like 'innodb_buffer%';
来检查缓冲区大小。
解决方案是找到您的my.cnf
文件并添加,
[mysqld]
innodb_buffer_pool_size=1G # depends on your data and machine
请勿忘记添加[mysqld]
,否则将无法正常工作。
就我而言, ubuntu 16.04 ,my.cnf
位于文件夹/etc/mysql/
下。
答案 7 :(得分:1)
修复错误代码1206:锁的数量超过了锁表的大小。
就我而言,我使用在Windows上使用WampServer 2.5运行的MySQL Workbench(5.6.17)。
对于Windows / WampServer,您必须编辑my.ini文件(而不是my.cnf文件)
要找到此文件,请转到菜单服务器/服务器状态(在MySQL Workbench中),然后在服务器目录/基本目录
下查找在my.ini文件中,为不同的设置定义了部分,查找[mysqld]部分(如果不存在则创建该部分)并添加命令: innodb_buffer_pool_size = 4G
[mysqld]
innodb_buffer_pool_size = 4G
buffer_pool文件的大小取决于您的特定计算机,在大多数情况下,2G或4G将解决此问题。
请记住重新启动服务器,以便采用新配置,它为我解决了该问题。
希望有帮助!
答案 8 :(得分:1)
同一问题,我在运行sql脚本时进入了 MYSQL ,请查看下图。 Error code 1206: The number of locks exceeds the lock table size Picture
这是Mysql配置问题,因此我在<div class="block-editor">
<!-- editor control -->
<div class="block-editor-control">
<ul>
<li data-action="bold"> B </li>
</ul>
</div>
<!-- editor content's -->
<div class="block-editor-content">
<div class="block-editor-block" contenteditable="true" role="group">
Voldemort is back
</div>
</div>
</div>
中进行了一些更改
并且它正在我的系统上工作并且问题已解决。
我们需要对let arr = [
[
['firstName', 'Joe'],
['age', 42],
['gender', 'male'],
],
[
['firstName', 'Mary'],
['lastName', 'Jenkins'],
['age', 36],
['gender', 'female'],
],
[
['lastName', 'Kim'],
['age', 40],
['gender', 'female'],
],
];
进行一些更改,这些更改可在以下路径上找到:- function test5(arr) {
let result =[]
arr.map(function(ele){
for(let i=0; i < ele.length; i++){
if(ele[i][0]==='firstName'||ele[i][0]==='lastName'){
result.push(ele[i][1])
}
if(ele[i][0]==='age'){
result.push(ele[i][1])
}
}
})
return result
}
并请在%dw 2.0
output application/json
---
{ result: payload mapObject (
(lower ('$$')): $
)
}
配置文件字段中更新以下更改:-
my.ini
完成所有上述更改后,请重新启动 MYSQL服务。 请参考图片:-Microsoft MYSQL Service Picture
答案 9 :(得分:0)
值得一提的是,用于此设置的数字是在BYTES中 - 找到了困难的方法!
答案 10 :(得分:0)
下面的答案不能直接回答OP的问题。然而, 我在此处添加此答案,因为此页面是 您的Google“锁总数超过了锁表的大小”。
如果您正在运行的查询正在分析跨越数百万行的整个表,则可以尝试使用while循环,而不用更改配置中的限制。
一会儿看起来会把它弄成碎片。下面是循环遍历DATETIME的索引列的示例。
# Drop
DROP TABLE IF EXISTS
new_table;
# Create (we will add keys later)
CREATE TABLE
new_table
(
num INT(11),
row_id VARCHAR(255),
row_value VARCHAR(255),
row_date DATETIME
);
# Change the delimimter
DELIMITER //
# Create procedure
CREATE PROCEDURE do_repeat(IN current_loop_date DATETIME)
BEGIN
# Loops WEEK by WEEK until NOW(). Change WEEK to something shorter like DAY if you still get the lock errors like.
WHILE current_loop_date <= NOW() DO
# Do something
INSERT INTO
user_behavior_search_tagged_keyword_statistics_with_type
(
num,
row_id,
row_value,
row_date
)
SELECT
# Do something interesting here
num,
row_id,
row_value,
row_date
FROM
old_table
WHERE
row_date >= current_loop_date AND
row_date < current_loop_date + INTERVAL 1 WEEK;
# Increment
SET current_loop_date = current_loop_date + INTERVAL 1 WEEK;
END WHILE;
END//
# Run
CALL do_repeat('2017-01-01');
# Cleanup
DROP PROCEDURE IF EXISTS do_repeat//
# Change the delimimter back
DELIMITER ;
# Add keys
ALTER TABLE
new_table
MODIFY COLUMN
num int(11) NOT NULL,
ADD PRIMARY KEY
(num),
ADD KEY
row_id (row_id) USING BTREE,
ADD KEY
row_date (row_date) USING BTREE;
如果您的表不使用日期,您也可以对其进行调整以遍历“ num”列。
希望这对某人有帮助!