【发布时间】: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
结束
此作业将数据从用户头表复制到设备信息子表中。它在生产数据库上运行,因此使用小批量来防止锁定。它有一些问题。
- 它神秘地丢弃了记录,在没有复制所有需要的数据的情况下完成。不知道为什么。
- 非常慢。它正在运行大约 200 万条记录,需要一个多小时,我需要加快速度。
- 它需要是幂等的。
我该怎么做
- 确保它仅在尚未迁移的记录上运行
- 合理地加快速度(增加批量大小,或者可能对小批量使用限制/偏移之外的其他东西)
- 验证是否已成功完成
【问题讨论】:
标签: ruby-on-rails postgresql rake