我正在从附录中连接到Google Cloud SQL,并且我遇到了似乎部分成功的大批次删除的问题。我有三张相关的表格 - A存储B,B,B存储C的子对象C。我们称它们为宠物,人和城市 - 每个人往往有大约一个宠物,但可能有几个宠物或可能没有。每个城市都有很多人。我正在努力扩展到大城市 - 最终我想获得数百万人。最多可容纳1000人,但是当我有大约5000人时,我对删除有一些奇怪的行为。
这是我删除城市时要做的:
我的宠物是指外钥匙ID的人,因此我必须先删除宠物。我的查询看起来像:
DELETE FROM Pets WHERE person_id IN (SELECT person_id FROM People WHERE city_id=?)
代码看起来像:
PreparedStatement stat = connection.prepareStatement(<above statement>);
stat.setString(1, city_id);
return stat.executeUpdate();
那么,如果成功(返回> 0是我正在使用的条件(,我会以以下查询删除所有的人(人们用外国密钥ID参考城市(
DELETE FROM People WHERE city_id=?
和与宠物类似的代码。
这是很奇怪的地方。我对宠物的删除仅返回〜2000(一次是1405,另一个时间2803(,中断了预期的5000删除。我没有例外。另一个〜3000宠物仍在数据库中 - 我可以手动检查它并查看它们:
MySQL [adam1]> select count(*) from People ppl inner join Pets pts on ppl.person_id=pts.person_id where ppl.city="some city id here";
+----------+
| count(*) |
+----------+
| 2197 |
+----------+
1 row in set (0.16 sec)
当然,由于违反外国密钥的限制,我对人的删除失败了。我在这些点上对我的数据库没有任何奇怪的看法 - CPU利用率从未超过70%,内存利用率相当低,同时没有更新。我确实看到了很多消息,例如"与db的中止连接:''user:'host:'cloudsqlproxy〜'(有一个错误读取通信数据包(",但是这些都是始终发生的(每秒很多,当数据库的使用严重(,似乎与此问题没有相关。
这是否期望删除部分成功?我是否有办法发现它除了尝试并未删除参考人员之外,它仅部分成功了吗?
项目ID是Adam-Dev-193118,数据库ADAM1。宠物,人和城市桌是跑步,批处理和项目。示例日志是在2018-02-07 17:43:16.107 EST。很高兴提供其他信息。
*编辑:我的原始查询开始花费很长时间。我发誓这并不总是这样做,但我无法证明这一点。无论如何,我切换到连接而不是子选择(现在需要〜1s而不是〜45s(,但我仍然有完全相同的问题。查询现在就像:
DELETE a FROM People b INNER JOIN Pets a ON a.person_id=b.person_id WHERE b.city_id=?;
叹气,应该很明显。准备施加或CloudSQL没有任何问题(当然,如预期的那样(。这是我自己的问题,与"中止连接"错误无关。
对于任何有兴趣的人来说,我并没有意识到,每当有人添加到人时,我的系统中的一个异步运行的一部分都在添加宠物。添加人们曾经如此慢,以至于添加宠物几乎总是保持不变。此外,通常您希望人们坚持一段时间,以便您可以与他们一起做些事情,从而给宠物 - 培养服务更多的时间来赶上。我一直在努力使人们更快地添加,所以它变得更快了,而且我正在通过质量插件进行骑自行车以测试这一点,因此人们的人很短。
tl; dr:宠物没有删除,因为它们还没有。但是,由于它们很快添加,所以当我设法在控制台中进行双重检查时,它们就在那里。