我也在dba.stackexchange上发布了这个问题,但我也把它放在这里,希望得到更多答案。
我们的服务器在AWS EC2实例上运行10.0.30-MariaDB。我们有一个存储过程,它创建多个临时表,它们之间的连接,最终产生最终结果。当我们第一次调用此过程时(在新连接中),我们总是得到一个结果。如果我们再次调用此过程,但使用不同的参数,则该连接的结果集始终为空。如果我们启动一个新连接并再次进行第二次调用,那么此调用将返回正确的结果,但第一次调用将为空。请参阅下面的简化方案:
Connection 1:
call my_procedure("a"); > 1 row returned
call my_procedure("b"); > 0 rows returned
call my_procedure("a"); > 1 row returned
Connection 2:
call my_procedure("b"); > 1 row returned
call my_procedure("a"); > 0 rows returned
call my_procedure("b"); > 1 row returned
我们总能以这种方式重现这种行为。
此外,当我们更改过程时(即使只添加注释),下一个调用就像在新连接上调用一样。因此,如果我们首先打电话给" a",我们会得到结果,但是" b"永远不会工作,反之亦然。
我们的程序是有效的sql并返回正确的数据,临时表被正确清除,......但由于某种原因在某些情况下不返回数据。
我们得到的印象是我们遇到了一些内部限制'或者。我们已经尝试了各种各样的东西,但我们已经没有选择在哪里查看或如何调试。
欢迎任何有关如何调试此类情况的建议。
请参阅下面的程序。我把它简化了一下。在dba.stackexchange帖子上,您可以看到另一个完整版本:
PROCEDURE `select_products`(IN arg_uuid VARCHAR(36),
IN arg_application VARCHAR(36),
IN arg_app_version VARCHAR(20),
IN arg_installation VARCHAR(50),
IN arg_user VARCHAR(36),
IN arg_product VARCHAR(36),
IN arg_license VARCHAR(36),
IN arg_type VARCHAR(10),
IN arg_code VARCHAR(255),
IN arg_group VARCHAR(100))
BEGIN
DECLARE var_b_user INT DEFAULT NULL;
SET var_b_user = (select bu.id from b_user bu JOIN user u on u.id = bu.user where u.`key` = arg_user limit 1);
/********************* PLTA **********************/
DROP TEMPORARY TABLE IF EXISTS plta;
CREATE TEMPORARY TABLE plta (product_id INT, license_id INT, token_id INT, activation_id INT, INDEX(product_id, license_id))
SELECT
l.product as product_id, l.id as license_id, lt.token as token_id, null as activation_id
FROM
license l,
license_token lt,
activation a,
`user` u
WHERE
a.current = TRUE
AND l.id = lt.license
AND a.`user` = u.id
AND a.installation = arg_installation
AND u.`key` = arg_user
AND lt.token = a.token
group by product_id, license_id, token_id;
UPDATE plta, activation a, `user` u
SET activation_id = a.id
WHERE
u.id = a.user
and a.current = TRUE
AND u.`key` = arg_user
AND a.installation = arg_installation
AND a.license = plta.license_id
AND a.token = plta.token_id;
/********************* TMP_PP **********************/
DROP TEMPORARY TABLE IF EXISTS tmp_pp;
CREATE TEMPORARY TABLE tmp_pp (product INT,INDEX(product))
SELECT DISTINCT
p.id AS product
FROM
product p
JOIN
application n
ON
p.application = n.id
AND n.`key` = arg_application
LEFT JOIN
(
SELECT
gp.product
FROM
product_group__product gp,
product_group g
WHERE
gp.enabled = TRUE
AND gp.product_group = g.id
AND g.`key` = arg_group
) g
ON
p.id = g.product
WHERE
( p.`key` = arg_product
OR ( arg_product IS NULL
AND p.enabled = TRUE))
AND ( g.product IS NOT NULL
OR arg_group IS NULL)
AND ( p.app_version IS NULL
OR arg_app_version IS NULL
OR (INET_ATON(p.app_version) <= INET_ATON(arg_app_version)));
select * from tmp_pp;
/********************* TMP_LT **********************/
DROP TEMPORARY TABLE IF EXISTS tmp_lt;
CREATE TEMPORARY TABLE tmp_lt (license INT,token INT,INDEX(license),INDEX(token))
SELECT
lt.license,
t.id as token
FROM
license_token lt,
token t
WHERE
lt.token = t.id
AND t.`type` = arg_type
AND ( ( arg_code IS NOT NULL
AND t.code = arg_code)
OR arg_type = 'free');
select * from tmp_lt;
/********************* PLT_PROD **********************/
SELECT
p.id AS product,
l.id AS license,
tmp_lt.token,
NULL AS activation,
FALSE AS license_auto_activation
FROM
product p
JOIN
tmp_pp
ON
p.id = tmp_pp.product
JOIN
license l
ON
( l.`key` = arg_license
OR arg_license IS NULL)
AND l.enabled = TRUE
AND l.product = p.id
AND ( l.app_version IS NULL
OR arg_app_version IS NULL
OR (INET_ATON(l.app_version) <= INET_ATON(arg_app_version)))
LEFT JOIN
tmp_lt
ON
l.id = tmp_lt.license
WHERE
( arg_type IS NULL
OR arg_type = 'auto'
OR tmp_lt.token IS NOT NULL);
END
另外&#39;有趣&#39;需要注意的是,如果我们将最后一个WHERE更改为WHERE arg_type = 'auto';
,则不会发生这种问题(尽管结果当然不一样)。