こんにちは、なかわけです。
今日はPostgresのpg_lo_exportの話です。
仕事で大量のラージオブジェクトLarge Objectをファイルに書き出す処理をしました。大量にあったので全部できるか心配だったのですが、無事全部書き出すことができました。めでたしめでたし。
・・・ではありませでした。
(さらに…)
こんにちは、なかわけです。
今日はPostgresのpg_lo_exportの話です。
仕事で大量のラージオブジェクトLarge Objectをファイルに書き出す処理をしました。大量にあったので全部できるか心配だったのですが、無事全部書き出すことができました。めでたしめでたし。
・・・ではありませでした。
(さらに…)
こんにちは、なかわけです。
珍しくPostgresの話です。
管理しているとあるデータベースで、LargeObjectが大量に保存されてました。大量すぎて大変になってきたので、一部のLO管理を止めてファイル管理にするように移行しました。移行後に削除したLO分の容量を解放すべくフルバキュームを行ったのですが、強制終了やほかのプロセスにより中断されましたという謎のエラーでフルバキュームが完了しませんでした。
(さらに…)
こんにちは、なかわけです。
いまpostgresのlargeobjectを大量にコピーする作業をしています。
元のデータベースに3000万行くらいあってそれをまるっとそっくりコピーのデータベースに流し込みます。
INSERT INTO pg_largeobject SELECT * FROM dblink('dbname=元データベース', SELECT * FROM pg_largeobject') AS t1 (loid oid, pageno integer, data bytea);
最初一回でコピーしようとしたらメモリエラーで失敗しました。そりゃそうですよねw
それで3000万行を10万行ずつに分割して書いたクエリのテキストファイルを読み込ませて
データを流し込むことにしました。たとえば、以下はその中のひとつのクエリ。
INSERT INTO pg_largeobject SELECT * FROM dblink( 'dbname=元データベース', 'SELECT * FROM pg_largeobject ORDER BY loid, pageno LIMIT 100000 OFFSET 200000') AS t1(loid oid,pageno integer,data bytea);
始めの方は10万行を挿入するのに1、2分程度で処理されていましたが、だんだん処理が遅くなり、
1000万行を挿入し終わったあたりでは10万行挿入するのに15分程度かかるようになってしまいました。
時間がかかってしょうがないです。どうしたものか。
ところが、とあるところからいい方法を教えてもらいました。
INSERT INTO pg_largeobject SELECT * FROM dblink( 'dbname=元データベース', 'SELECT * FROM pg_largeobject WHERE loid BETWEEN n AND m') AS t1(loid oid,pageno integer,data bytea);
ORDERしてLIMIT、OFFSETするのではなく、BETWEENを使うんですね!
確かにこっちの方が処理が少ない分早そうだし、実際めちゃ早かったです。
あーよかったよかった!