首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

各位大佬们 征求意见

  •  
  •   JustinJie · 27 天前 · 1793 次点击
    1. 菜鸡一枚, 接到一个数据迁移的需求
    2. 新功能重构上线, 要把老库里面的表数据迁移到新库的表里, 两张表字段大体上一样也有一些区别, 表里面大概 40 个字段
    3. 数据库是 mysql, 老库的数据量大概在 400 多万条的亚子
    4. 现在正在考虑方案, 奈何之前没接触过类似的功能, 找 v2 大佬请教, 用什么样的方式比较好, 是用代码实现, 还是直接脚本之类的 ? 如果可以的话可以说的稍微具体点
    31 回复  |  直到 2019-10-21 13:28:11 +08:00
        1
    JustinJie   27 天前
    求大佬临幸 ~
        2
    JustinJie   27 天前
    我订
        3
    dswyzx   27 天前
    才 400w 啊.用代码的话只要别一条一条处理也不怕
        4
    JustinJie   27 天前
    @dswyzx # 3 不一条一条处理 ? 代码不就 for 循环吗 ? 还有什么方法 ?
        5
    zgzhang   27 天前   ♥ 1
    我能想到的步骤如下:
    1. 新老表双写,读老表
    2. 数据迁移,400W 条数据迁移应该很快
    3. 抽样对比数据,看下是否 OK
    4. 灰度读数据到新表
    5. 老表下线
        6
    telami   27 天前   ♥ 2
    一般来说三种方式:
    1、sql 脚本,能用 sql 处理的,一定用 sql,成本最低。看你的数据是不是经过大的处理,如果是要用到外部一些数据,这种就不推荐了。
    2、python 脚本,好处是想咋写咋写,400 万数据也不多,用完一次就扔掉,不用重复上线。
    3、代码,代码的话看场景,设计多个表,甚至需要一些外部 api 数据处理,这就只能用代码了,但是同步数据得上线,上完线还得删,就比较麻烦。
        7
    CoCoMcRee   27 天前   ♥ 1
    这么点数据量, 找个 NaviCat 之类的工具 同步下就行了吧
        8
    taotaodaddy   27 天前 via Android   ♥ 1
    如果数据处理规则很简单就用 sql
    如果比较复杂就 python 走一波,用完即扔
        9
    taogen   27 天前   ♥ 1
    用脚本或者代码,对比两个库,生成最终的 SQL 文件。新库中,清空对应的表,执行 SQL 文件。
        10
    xxdd   27 天前   ♥ 1
    写 sql 脚本吧 这个迁移应该不涉及数据比对
        11
    JustinJie   27 天前
    @zgzhang # 5
    1. 新功能上线貌似就没有使用老表了, 新功能没有向之前表插入
    2. 数据迁移 怎么弄 ? 我主要就是想问下这个怎么实现 之前没有弄过
    3. 抽样对比数据 到时候肯定是要测的
    4. 灰度是个啥意思 ? 我研究下
    @telami # 6
    1. 我暂时只想到了一个用程序读取老表然后插入新表的办法, sql 脚本暂时还不知道如何去写
    2. python 脚本 不怎么会 没怎么研究过 我这边是弄 Java 的
    3. 是的 我也是这么想的 代码比较麻烦 而且我只想到循环处理 肯定耗时性能也不好
    @CoCoMcRee # 7
    好的 我研究下同步工具 但是我两个表的字段 名称不一样 还有些字段不同 不知道能不能处理
    @taotaodaddy # 8
    好的 感谢
    @taogen # 9
    你的意思是用代码 生成 对应 sql 语句 然后去执行 ? 我也有这么考虑的
    @xxdd # 10
    嗯 都比较推荐 sql 脚本 我向下 数据比对 这个是什么意思 ?
        12
    JustinJie   27 天前
    我顶 !
    再次召唤大佬~
        13
    JustinJie   27 天前
    再顶 !
        14
    JustinJie   27 天前
    大佬们, 周五已经下班了吗~
        15
    wuwukai007   27 天前   ♥ 1
    pandas read_sql

    pandas to_sql
    注意缺失值处理一下,应该蛮快的。
        16
    JustinJie   27 天前
    @wuwukai007 # 15 Python ? 我先看下
        17
    markgor   27 天前   ♥ 1
    表有區別就不能跑同步了,
    就算是 dump 出來,你也 source 不了進去。
    所以老老實實寫腳本。
    具體點就是:
    1、寫腳本,建測試庫
    2、測試腳本用測試庫的資源。
    3、和後端商議個時間做切換。
    4、鎖庫腳本同步數據
    5、後端切換數據
    6、測試下
    7、休息
        18
    JustinJie   27 天前
    @markgor # 17 大佬懂我
    不过我还有点疑问就是 我一条语句写一个 insert into 这样的行吗 ?
    还是有更好的什么写法和形式吗 ?
        19
    lazyfighter   27 天前   ♥ 1
    kettle
        20
    JustinJie   27 天前
    @lazyfighter # 19 好的 我看下
        21
    MorpheusAnchor   27 天前   ♥ 1
    做过类似的 几十个表吧 逻辑处理比较复杂 用 python 一条一条写的,但是可复用,因为是公司的产品,部署出去的
        22
    zgzhang   27 天前   ♥ 1
    @JustinJie 你的服务如果在迁移期间可以停止服务,那同步数据用脚本还是 sql 都可以。但是你确定迁移期间没有数据修改的问题吗?
        23
    markgor   27 天前   ♥ 1
    @JustinJie 沒時間要求就一條條,有時間要求就嘗試讀 N 條,插入 N 條 異步操作。
        24
    JustinJie   26 天前
    @zgzhang # 22
    服务在晚上发布, 一般都没有什么用户的了, 应该是没有问题的

    @markgor # 23
    OK 我懂了 应该没有时间要求
    那我是不是就 Java 代码 读取数据, 拼接成 sql 生成脚本这样 ? 还是有好的方式呢 ?
        25
    markgor   26 天前   ♥ 1
    @JustinJie java 不清楚,我是直接 PHP 跑腳本
    主進程讀 1K 條就 fork 個子線程出來跑插入,
    然後插入失敗就寫個 log (完整的 SQL 語句),
    最後在跑一次失敗 log 裡面的記錄。

    因為是一年前的事,大概就這些,
    你的環境我不清楚,我當時是異地的,數據量不算大,好像幾十萬筆記錄,

    注意下網絡超時和新數據庫的格式就可以了( mysqlmax_allowed_packet,還有 MYSQL 特性是否一致)。
    對了,mysql 還有個 max_connections。

    實話實說,你不缺時間的就一條條跑,失敗的記錄起來,然後打牌的打牌,喝酒的喝酒,跳舞的跳舞,每個一會看看有沒出錯就可以了。最後跑完就看看失敗的 log 裡面有沒 SQL 語句記錄,數量不多直接就在新數據庫裡運行裡面的語句。

    good luck
        26
    lufeng08   26 天前   ♥ 1
    做过类似的,一个论坛重构,几千万条帖子,几亿个回复,跨服务器迁移,写接口实现,然后写 shell 脚本请求接口,每页多少条数据可以配置,先每页 100 条执行,根据测试结果慢慢往上加,比如加到 2000,400 万条数据,每次迁移 2000 条,也就 2000 秒执行完毕。
        27
    zpfhbyx   26 天前   ♥ 1
    先双写啊,新库带老库的主键 id 插入到新库,然后查新库最小 id, 然后 while(true) 老库主键作位移,一次 1000 ,然后新库, insert 批量插入, 保你 5kw 数据没问题
        28
    CoooooolFrog   26 天前   ♥ 1
    如果允许服务短时间不可用,简单点直接 mysqldump。
    如果不允许服务不可用,双写表,数据同步完以后清理旧表,全部迁移新表。
        29
    lufeng08   26 天前   ♥ 1
    有句话不知当讲不当讲,我们做了一个提升新手生产力的脚手架,也开发了好多应用上架了,都免费了,你可以参观下,可以拿来二次开发
    https://www.gepardshop.com/appstore
        30
    JustinJie   24 天前
    @markgor # 25
    好的 我考虑的是直接拼接成 sql 脚本 给 dba 执行, 程序跑, 记录失败 log 也很有必要的样子

    @lufeng08 # 26
    大佬, 膜拜 ! 我去研究下

    @zpfhbyx # 27
    关键我两张表 好些字段不一样 , 不只是名称, 这样也有用的吗 ?

    @CoooooolFrog # 28
    好的 接收到了 大佬 ~

    @lufeng08 # 29
    再次感谢 ~
        31
    zpfhbyx   24 天前   ♥ 1
    @JustinJie 自己逻辑映射啊,最后数据批量插入,没问题的,实际跑过,线上直接 rename 完事了如果不同实例,停双写或者反向双写,然后直接上代码就可以了,验证数据没问题,直接停双写
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4108 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 26ms · UTC 08:45 · PVG 16:45 · LAX 00:45 · JFK 03:45
    ♥ Do have faith in what you're doing.