【问题标题】:How to migrate data in batches via rake task in postgres?如何通过postgres中的rake任务批量迁移数据?
【发布时间】:2021-01-14 21:48:44
【问题描述】:

我有以下 rake 任务:

namespace :backfill do
 desc "backfill device id data"
 task device_ids: :environment do
   user_count = User.where.not(device_id: nil).count

   puts "Begin device_id backfill for #{user_count} users"

   batch_size, offset = 2000, 0
   begin
     puts "Beginning backfill batch from rows #{offset} to #{offset + batch_size} out of #{user_count} rows"

    ActiveRecord::Base.connection.execute <<-SQL
      INSERT INTO user_device_infos (user_id, user_device_id, last_login_at, created_at, updated_at)
      SELECT users.id, users.device_id, users.last_sign_in_at, current_timestamp, current_timestamp
      FROM users
      LEFT JOIN user_device_infos
      ON users.id = user_device_infos.user_id
      AND users.device_id = user_device_infos.user_device_id
      WHERE users.device_id IS NOT NULL
      AND user_device_infos.user_id IS NULL
      ORDER BY users.created_at DESC
      LIMIT #{batch_size}
      OFFSET #{offset}
    SQL
    offset += batch_size
  end until offset > user_count

  puts "backfill complete"
end

结束

此作业将数据从用户头表复制到设备信息子表中。它在生产数据库上运行,因此使用小批量来防止锁定。它有一些问题。

  1. 它神秘地丢弃了记录,在没有复制所有需要的数据的情况下完成。不知道为什么。
  2. 非常慢。它正在运行大约 200 万条记录,需要一个多小时,我需要加快速度。
  3. 它需要是幂等的。

我该怎么做

  1. 确保它仅在尚未迁移的记录上运行
  2. 合理地加快速度(增加批量大小,或者可能对小批量使用限制/偏移之外的其他东西)
  3. 验证是否已成功完成

【问题讨论】:

    标签: ruby-on-rails postgresql rake


    【解决方案1】:

    问题是我不需要 sql 子句中的偏移量,因为左连接已经过滤掉了新记录。删除偏移量既加快了工作速度又修复了工作。

    将 sql 输出保存到变量并打印 puts result.cmd_status 有助于验证每个批次是否已成功完成。

    【讨论】:

      猜你喜欢
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 2011-12-01
      • 2015-10-05
      • 1970-01-01
      • 2022-08-24
      • 1970-01-01
      相关资源
      最近更新 更多