› 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
getlost
V2EX  ›  MySQL

请教,遇到一个 MySQL 问题

  •  
  •   getlost · Oct 30, 2019 · 7172 views
    This topic created in 2526 days ago, the information mentioned may be changed or developed.

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

    22 replies  •  2019-11-22 20:08:53 +08:00
    taogen
        1
    taogen  
       Oct 31, 2019 via Android
    什么叫 “从 A 表存入 B 表的数据再也无法读取”?

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

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