我正在LAMP堆栈上的自动化系统上工作,遇到几次查询未命中,即查询由PHP执行,但数据库中不存在,也没有错误。
因此,我启用了在mysql中记录所有查询的功能,以查看查询是否完全到达那里,并且确实可以确定查询在那里。现在发生了,因此我将举一个例子进行说明:
(顺便说一句,BTW不会尝试在查询中查找错误。没有。在大多数情况下,相同的查询会执行)
PHP执行:
$saveOrderQ = "INSERT INTO orders (order_id, parent_order, date_created, status, type, phase, ticker, quantity, entry_price, tp1, tp2, strategy, relative_volume, distance_from_close) VALUES ({$order->order_id}, 0, '$now', 'OPEN', 'BUY', 0, '$ticker', $positionsSize, $price, $tp1, $tp2, {$tickerAttr['strategy']}, $relativeVol, $distanceFromClose)";
writeToLog($saveOrderQ); // I get the query in the log. This function's log is seperate from mysql log
$saveOrder = mysqli_query($connect, $saveOrderQ);
if(!$saveOrder){
writeToLog("Failed to insert file 30daybreakout.php Line 59. Error: ".mysqli_error($connect)."\nQuery: $saveOrderQ"); // no error received
}
MySQL大约在同一时间登录
2020-04-13T09:23:02.222315+05:30 127059 Query SELECT order_id FROM orders WHERE ticker = 'NSE:BALMLAWRIE' AND DATE(date_created) = '2020-04-13' AND parent_order = 0 AND phase < 3
2020-04-13T09:23:02.356930+05:30 127059 Query INSERT INTO orders (order_id, parent_order, date_created, status, type, phase, ticker, quantity, entry_price, tp1, tp2, strategy, relative_volume, distance_from_close) VALUES (200413000329794, 0, '2020-04-13 09:23:01', 'OPEN', 'BUY', 0, 'NSE:BALMLAWRIE', 54, 91.3, 94.95, 98.6, 1, 108.87022900763, 6.5966141272621)
该条目根本不存在于订单表中。
我的最佳猜测是,订单表已被锁定,但我不确定。我该如何解决?
答案 0 :(得分:1)
还要检查“警告”。在检查完错误之后并在运行任何其他SQL之前,请执行SHOW WARNINGS LIMIT 11
并打印结果(如果有),以执行此操作。警告并不像错误那样严重,但是警告有时会提示事情与预期不符,从而导致发现真正的错误。
直到最近PHP才从32位版本切换到64位。也就是说,用PHP表示大量数字是不安全的。您正在使用哪个版本的PHP?由于问题是“有时”发生的,可能是因为您舍入了超过31、32(INT大小)或53位(DOUBLE大小)的舍入错误。为了解决这个问题,请提供一些具体的数字,并说明哪些有效,哪些无效。 (200413000329794占用48位,因此,如果它在PHP中通过DOUBLE处理,则不会丢失任何内容。)
在MySQL中用引号引起来没关系:如果WHERE foo = 123
是整数而不是char ,则WHERE foo = "123"
和foo
的工作原理相同。
>
您使用autocommit
的哪个值?我认为OFF
容易出错,因为您必须记住最终要COMMIT
。而且很容易忘记这样做,或者有时选择避免使用COMMIT
的分支。然后,当连接关闭时,该打开的事务将自动ROLLBACKd
。
(更多“未经请求的建议”)评论建议将日期更改为“可更改”。它需要一些扩展:
AND date_created >= '2020-04-13'
AND date_created < '2020-04-13' + INTERVAL 1 DAY
(还有一些“主动提供的建议”),这可能是最佳索引:
INDEX(ticker, parent, date_created)
更多(主要是“像稻草一样钓鱼”)
在数字字段中插入数字常量或在WHERE
子句中进行比较时,数字常量是否被引用都没有关系。
建议打开“常规日志”。尽管您的日志记录机制似乎等效,但也许仍有一些细微之处,一般日志会指出。
在没有autocommit=ON
并且没有显式事务的情况下,我很难想象会发生死锁。请立即SHOW ENGINE INNODB STATUS;
捕获,并且每当您怀疑问题再次发生时。
请提供SHOW CREATE TABLE
和声明缺少该行的查询。搜索非整数时误用FLOAT
会导致舍入问题。
答案 1 :(得分:1)
我认为您必须提供表格结构 或者您可以尝试在MySQL GUI中运行此查询日志,
INSERT INTO orders (order_id, parent_order, date_created, status, type, phase, ticker, quantity, entry_price, tp1, tp2, strategy, relative_volume, distance_from_close) VALUES (200413000329794, 0, '2020-04-13 09:23:01', 'OPEN', 'BUY', 0, 'NSE:BALMLAWRIE', 54, 91.3, 94.95, 98.6, 1, 108.87022900763, 6.5966141272621)
我认为有一些错误,例如您的查询无法满足唯一键表条件或类似条件。
答案 2 :(得分:0)
在这种情况下,问题可能是以下之一:
仅用于测试:尝试使用在重复键更新中插入 ....:而不是仅在SQL中插入。 .. 让我们知道。
答案 3 :(得分:-2)
这不是一个确定的解决方案,但是到目前为止,我已经使用以下代码在系统中建立了一些冗余,希望可以解决该问题。
$saveOrderCount = 0;
do {
$saveOrder = mysqli_query($connect, $saveOrderQ);
$saveOrderCount++;
} while(!mysqli_affected_rows($connect) and $saveOrderCount < 3); //Will retry upto a max of 3 times
if($saveOrderCount >= 3){
writeToLog("Failed to insert in file test.php Line 59. Error: ".mysqli_error($connect)."\nQuery: $saveOrderQ");
}