Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 锁的总数超过了锁表的大小_Mysql_Sql - Fatal编程技术网

Mysql 锁的总数超过了锁表的大小

Mysql 锁的总数超过了锁表的大小,mysql,sql,Mysql,Sql,我正在MySQL中运行一个报告。其中一个查询涉及在临时表中插入大量行。当我尝试运行它时,会出现以下错误: 错误代码1206:锁的数量超过了锁表的大小 有关问题包括: create temporary table SkusBought( customerNum int(11), sku int(11), typedesc char(25), key `customerNum` (customerNum) )ENGINE=InnoDB DEFAULT CHARSET=latin1; insert i

我正在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。我在查询中更改了它,但没有在这里更改。

来自(如我所见,您已经阅读了):

1206(ER\U锁\U桌满)

锁的总数超过了锁表的大小。要避免此错误,请增加innodb_buffer_pool_size的值。在单个应用程序中,解决方法可能是将大型操作分解为较小的部分例如,如果大插入发生错误,请执行几个较小的插入操作。


如果增加innodb\u buffer\u pool\u大小没有帮助,那么只需按照粗体部分的指示将插入内容拆分为3。跳过联合并进行3次插入,每个插入都与topThreetransit表连接。

我找到了另一种解决方法-使用表锁。当然,它可能不适合您的应用程序—若您需要同时更新表的话

见: 尝试使用
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;
杰伊·派普斯,
Community Relations Manager,北美,MySQL Inc.

如果您已经正确地构造了表,使每个表都包含相对唯一的值,那么执行此操作的不太密集的方法是执行3个单独的insert into语句,每个表1个,每个insert都有连接筛选器-

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表名即可。 **如果试图防止SKUSBUY表中出现重复条目,可以在WHERE子句之前的每个部分中添加以下联接代码

LEFT OUTER JOIN SkusBought AS T3
ON  t1.customer = t3.customer
AND t1.sku = t3.sku
-然后是WHERE子句的最后一行-

AND t3.customer IS NULL

您的初始代码使用了许多子查询,UNION语句可能会很昂贵,因为它首先创建自己的临时表来填充来自三个独立源的数据,然后再插入到所需的表中,同时运行另一个子查询来过滤结果。

可以通过为MySQL变量设置更高的值来解决此问题
innodb\u缓冲区\u池\u大小
innodb\u buffer\u pool\u size
的默认值为
8388608

要更改
innodb\u buffer\u pool\u size
的设置值,请参阅下面的设置

  • 从服务器上找到文件
    my.cnf
    。对于Linux服务器,这将主要位于
    /etc/my.cnf
  • 将行
    innodb\u buffer\u pool\u size=64MB
    添加到此文件
  • 重新启动MySQL服务器
  • 要重新启动MySQL服务器,您可以使用以下两个选项中的任何一个:

  • 服务mysqld重启
  • /etc/init.d/mysqld重新启动

  • 在windows中参考:如果您有mysql workbench。转到服务器状态。查找正在运行的服务器文件的位置(在我的示例中是):

    C:\ProgramData\MySQL\MySQL Server 5.7
    
    打开my.ini文件并找到缓冲池大小。将该值设置为高。默认值为8M。
    这就是我如何解决这个问题的方法

    值得一提的是,用于此设置的数字是以字节为单位的-找到了困难的方法

    我正在使用MySQL工作台运行MySQL windows。 转到服务器>服务器状态 顶部显示配置文件:“path”(
    C:\ProgramData\MySQL\…\my.ini

    然后在文件“my.ini”中按control+F并查找
    缓冲池大小
    。
    将该值设置得更高,我建议使用64MB(默认值为8MB)

    通过转到实例>启动/关闭>停止服务器(然后稍后再次启动服务器)重新启动服务器


    在我的例子中,我无法从表中删除条目。

    首先,可以使用sql命令
    显示全局变量,如'innodb_buffer%'
    检查缓冲区大小

    解决方案是找到您的
    my.cnf
    文件并添加

    [mysqld]
    innodb_buffer_pool_size=1G取决于您的数据和机器
    下面的答案并不直接回答OP的问题。然而, 我在这里添加这个答案是因为这个页面是 您可以通过谷歌搜索“锁的总数超过了锁表的大小”。


    如果正在运行的查询正在分析跨越数百万行的整个表,则可以尝试while循环,而不是更改配置中的限制

    while外观会将其分解成碎片。下面是一个在DATETIME索引列上循环的示例

    #放下
    删除表(如果存在)
    新表;
    #创建(稍后我们将添加键)
    创建表
    新表
    (
    数值INT(11),
    行id VARCHAR(255),
    行值VARCHAR(255),
    行日期时间
    );
    #换药
    分隔符//
    #创建过程
    创建过程do_repeat(当前循环中的日期时间)
    开始
    #每周循环一次直到现在()。如果仍然出现锁定错误,请将“周”更改为“天”等较短的时间。
    当前循环日期=当前循环日期和
    行日期<当前循环日期
    
    key_buffer_size=64M
    read_buffer_size=64M
    read_rnd_buffer_size=128M
    innodb_log_buffer_size=10M
    innodb_buffer_pool_size=256M
    query_cache_type=2
    max_allowed_packet=16M