首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
V2EX  ›  MySQL

请教,遇到一个 MySQL 问题

  •  
  •   getlost · 37 天前 · 3390 次点击
    这是一个创建于 37 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    22 回复  |  直到 2019-11-22 20:08:53 +08:00
        1
    taogen   37 天前 via Android
    什么叫 “从 A 表存入 B 表的数据再也无法读取”?

    到底是哪个表的操作失败?是读操作,还是写操作失败?
        2
    sumarker   37 天前
    ```
    如果无效就删除,有效就从当前行删除,插入到最后一行,一直这样循环
    ```

    没看懂这个操作是啥意思 orz
        3
    z7356995   36 天前 via Android
    为什么不用一张表,A 表一张就够了,有效无效只要一个标记位就行
        4
    aaa5838769   36 天前 via iPhone
    你应该加个字段就解决了,还干嘛弄个表
        5
    sansanhehe   36 天前 via Android
    没有用事务包裹整个过程吗? MySQL 的默认隔离级别解决了不可重复读和幻读问题
        6
    fortunezhang   36 天前
    我读了好 5、6 遍才明白你的操作。
    从 B 表中的操作,每次都是 select * from table_b order by id asc limit 1。这样就能够保证每次都能拿到了。还有一个复杂的方法,就是你保留上一次被删除的 id,select * from table_b where id=(last_deleted_id +1 ) 这样也行。
        7
    native   36 天前 via Android
    锁一般在多线程高并发时候会用到,仔细检查代码。
        8
    laminux29   36 天前
    楼主要小心网监,毕竟牢饭不好吃。
        9
    chengcanmm77   36 天前
    应该是定时任务开了事务
        10
    Yano   36 天前
    我觉得吧,你一个 A 表就足够了。A 表增加一个字段,标识是否有效;最多再加一个字段,标识是否扫描标记过。
        11
    ShangAliyun   36 天前
    你这个用途要注意安全,扫公网端口,大多目的都不是“合法”的,甚至及时合法都得放着,容易被误解甚至利用
        12
    getlost   36 天前 via iPhone
    @taogen 比如 B 表中原有 5 条记录,一段时间后都失效了,定时任务查出后将 5 条记录都从 B 表中删除,但是 B 表中新存进去的记录查询不到(是从 A 表中取出后新插入的),但是我用 Navicat 看了 B 表的记录,新的记录已经存进去了,就是取不到。
        13
    getlost   36 天前 via iPhone
    @sumarker 因为我发现每次取一条记录,都只能取到第一条,如果这一条不删除,后面的都取不到。我考虑过用 id+1 这个,但是因为有删除操作,所以 id 不是连续的,然后我就想到这个了,把当前记录删除并插入到最后,这样我就可以一直取到新的记录了。囧,刚学,还不太会用。
        14
    getlost   36 天前 via iPhone
    @z7356995 但是这样就存在一个问题啊,大多 ip 都无效,无效的记录越来越多,所以我就给删了
        15
    getlost   36 天前 via iPhone
    @aaa5838769 没想到这个,但是如果加个字段,这里面大多都是无效的,能用的 ip 很少,所以干脆删了
        16
    getlost   36 天前 via iPhone
    @sansanhehe 还不会这个,我现在只会用类似 SELCTE INSERT 这种,我去查查你说的这个,谢谢啊
        17
    sumarker   36 天前
    @getlost 其实比较简单的是你先处理,然后 把处理中的放内存里(如果太大可能导致内存堆满,但是可以分片),然后 再去操作数据库不是更好吗?
        18
    getlost   36 天前
    @fortunezhang 我试了一下,这样不行,B 中的记录删除完之后,新加入的记录还是取不到。
        19
    getlost   36 天前
    @native 我开了两个进程,一个执行爬取任务,并存在 A 表,然后测试 ip,有效存入 B 表,无效删除。另一个一直循环检测 B 表 ip 是否还能用,无效就删除。但是问题出现了,B 表原有的 ip 过段时间都会失效,全部删除,从第一个进程存入 B 表的记录,第二个进程就拿不到数据了。
        20
    getlost   36 天前
    @laminux29 自己玩一下,都是从代理网站上爬的,没有干其他的
        21
    z7356995   36 天前 via Android
    @getlost MySQL 几百万 上千万数据也不会卡, 同一个表里也可以几天删一次呀,反正有标记位
        22
    getlost   14 天前
    @z7356995 刚开始玩,还不太会这个,我在试试啊。上面的问题已经解决了,删除之后需要 commit 才行。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   925 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 22:07 · PVG 06:07 · LAX 14:07 · JFK 17:07
    ♥ Do have faith in what you're doing.