程序目的: 比对新旧两套数据库的同名表记录条数是否一致。预先已将需比对的表名写入 diff_log 表中,添加了两个字段new_count和 old_count用于保存表的记录条数。
- require 'celluloid'
- require 'dbi'
- class MyWorker
- # 定义一个 actor
- include Celluloid
- # 析构函数,当主 actor 退出时,所有的子 actor 将调用析构函数并退出
- finalizer :my_finalizer
-
- # 构造函数:连接新旧两套数据库
- def initialize
- @newdb = DBI.connect('dbi:OCI8:db_new','new_user','new_pass') or exit
- @olddb = DBI.connect('dbi:OCI8:db_old','old_user','old_pass') or exit
- end
-
- # 统计记录条数,写入 diff_log
- def calc(table_name)
- new_count = @newdb.select_one("select count(1) c from #{table_name}").by_field("C");
- old_count = @olddb.select_one("select count(1) c from #{table_name}").by_field("C");
-
- sql = sprintf "update diff_log set new_count = %d,old_count = %d where table_name = '%s'",
- new_count,old_count,table_name
- puts sql
-
- @newdb.execute(sql)
- @newdb.commit
- end
-
- def my_finalizer
- @newdb.disconnect if @newdb
- @olddb.disconnect if @olddb
- end
- end
- # 开启一个进程池,可以同时运行 20 个 actor
- pool = MyWorker.pool(size: 20)
- dbh = DBI.connect('dbi:OCI8:db_new','new_user','new_pass') or exit
- # 主循环
- dbh.select_all("select table_name from diff_log where new_count is null") do |row|
- table_name = row.by_field "TABLE_NAME"
- # 异步调用
- pool.async.calc(table_name)
- end
- dbh.disconnect if dbh
- # 休眠主进程。否则主进程将直接退出,所有子 actor 也将被 kill 掉。
- # 终止程序只有按 ctrl+c
- sleep