请教,遇到一个 MySQL 问题

2019-10-30 23:02:26 +08:00
 getlost

场景:在数据库中分别建了两张表 A、B,A 用来存储从网上爬取到的 ip 和 port,然后测试,有效就存储在 B 表。现在,我写了一个定时任务,每 60 分钟爬取一次,并存储在 A 表,然后把有效的存在 B 表。针对 B 表也写了一个定时任务,每 1 分钟检查一次是否仍然有效,如果无效就删除,有效就从当前行删除,插入到最后一行,一直这样循环。但是现在遇到一个问题,针对 B 表的定时任务,在检测完 B 中原有的数据,包括从当前行删除并插入到最后一行的数据后,其他从 A 表存入 B 表的数据再也无法读取到,这是因为锁吗?初学数据库,不太了解这个,求助各位。

5757 次点击
所在节点    MySQL
22 条回复
taogen
2019-10-31 00:44:54 +08:00
什么叫 “从 A 表存入 B 表的数据再也无法读取”?

到底是哪个表的操作失败?是读操作,还是写操作失败?
sumarker
2019-10-31 01:43:14 +08:00
```
如果无效就删除,有效就从当前行删除,插入到最后一行,一直这样循环
```

没看懂这个操作是啥意思 orz
z7356995
2019-10-31 06:53:31 +08:00
为什么不用一张表,A 表一张就够了,有效无效只要一个标记位就行
aaa5838769
2019-10-31 07:37:43 +08:00
你应该加个字段就解决了,还干嘛弄个表
sansanhehe
2019-10-31 07:42:08 +08:00
没有用事务包裹整个过程吗? MySQL 的默认隔离级别解决了不可重复读和幻读问题
fortunezhang
2019-10-31 08:05:46 +08:00
我读了好 5、6 遍才明白你的操作。
从 B 表中的操作,每次都是 select * from table_b order by id asc limit 1。这样就能够保证每次都能拿到了。还有一个复杂的方法,就是你保留上一次被删除的 id,select * from table_b where id=(last_deleted_id +1 ) 这样也行。
native
2019-10-31 08:40:08 +08:00
锁一般在多线程高并发时候会用到,仔细检查代码。
laminux29
2019-10-31 08:54:46 +08:00
楼主要小心网监,毕竟牢饭不好吃。
chengcanmm77
2019-10-31 08:56:07 +08:00
应该是定时任务开了事务
Yano
2019-10-31 09:41:22 +08:00
我觉得吧,你一个 A 表就足够了。A 表增加一个字段,标识是否有效;最多再加一个字段,标识是否扫描标记过。
ShangAliyun
2019-10-31 11:12:09 +08:00
你这个用途要注意安全,扫公网端口,大多目的都不是“合法”的,甚至及时合法都得放着,容易被误解甚至利用
getlost
2019-10-31 12:22:01 +08:00
@taogen 比如 B 表中原有 5 条记录,一段时间后都失效了,定时任务查出后将 5 条记录都从 B 表中删除,但是 B 表中新存进去的记录查询不到(是从 A 表中取出后新插入的),但是我用 Navicat 看了 B 表的记录,新的记录已经存进去了,就是取不到。
getlost
2019-10-31 12:29:14 +08:00
@sumarker 因为我发现每次取一条记录,都只能取到第一条,如果这一条不删除,后面的都取不到。我考虑过用 id+1 这个,但是因为有删除操作,所以 id 不是连续的,然后我就想到这个了,把当前记录删除并插入到最后,这样我就可以一直取到新的记录了。囧,刚学,还不太会用。
getlost
2019-10-31 12:31:39 +08:00
@z7356995 但是这样就存在一个问题啊,大多 ip 都无效,无效的记录越来越多,所以我就给删了
getlost
2019-10-31 12:33:38 +08:00
@aaa5838769 没想到这个,但是如果加个字段,这里面大多都是无效的,能用的 ip 很少,所以干脆删了
getlost
2019-10-31 12:37:49 +08:00
@sansanhehe 还不会这个,我现在只会用类似 SELCTE INSERT 这种,我去查查你说的这个,谢谢啊
sumarker
2019-10-31 12:42:58 +08:00
@getlost 其实比较简单的是你先处理,然后 把处理中的放内存里(如果太大可能导致内存堆满,但是可以分片),然后 再去操作数据库不是更好吗?
getlost
2019-10-31 19:41:22 +08:00
@fortunezhang 我试了一下,这样不行,B 中的记录删除完之后,新加入的记录还是取不到。
getlost
2019-10-31 19:45:15 +08:00
@native 我开了两个进程,一个执行爬取任务,并存在 A 表,然后测试 ip,有效存入 B 表,无效删除。另一个一直循环检测 B 表 ip 是否还能用,无效就删除。但是问题出现了,B 表原有的 ip 过段时间都会失效,全部删除,从第一个进程存入 B 表的记录,第二个进程就拿不到数据了。
getlost
2019-10-31 19:45:57 +08:00
@laminux29 自己玩一下,都是从代理网站上爬的,没有干其他的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/614639

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX