awkでデータの絞り込み
やりたかったこと
- 本番RDSから割と大きめのデータをエクスポート
- 負荷がかからないローカルDBでそのデータをこねくる
- 割とデータ量が多いのである程度はawkなどを駆使してデータを絞る
実践
[必要なデータを本番DBからexport]
mysql -u hoge_user -P 9000 -h 127.0.0.1 -D hoge_db -pxxxxx N --batch -e "SELECT * FROM hoges PARTITION (p201704);" > hoges.tsv
[uniqu_data作成]
sudo cat hoges.tsv | cut -f1-16 | tr " " _ | gawk '{volume[sprintf("%s_%s", $3,$4)]=$6};END{for (key in volume) {print sprintf("%s_%s", key, volume[key])}}' > uniqu_log.tsv
[bulk insert用のimport file作成]
cat uniqu_log.text | gawk 'BEGIN{ FS="_"; OFS="," } {print (NR) == 1 ? sprintf("insert into user_summary values(\"%s\", %s, %s)", $1, $2, $3 ) : sprintf(",(\"%s\", %s, %s)", $1, $2, $3 ) } END{print ";"}' > insert.sql
[LocalDBにimport]
mysql -u hoge_user -phoge -D hoge < insert.sql
[error]
ERROR 2006 (HY000) at line 1: MySQL server has gone away
[予想原因]
クライアントからサーバに送ることができるパケットの最大数が小さい
[対策]
max_allowed_packet を増やす
でもできなかった......
他にもタイムアウト系伸ばしたけど、無理
なのでbulkを分割して対応することに
cat uniqu_log.text | gawk 'BEGIN{ FS="_"; OFS="," } {print (NR%100) == 1 ? (NR) == 1 ? sprintf("insert into user_summary values(\"%s\", %s, %s)", $1, $2, $3 ) : sprintf(";insert into user_summary values(\"%s\", %s, %s)", $1, $2, $3 ) : sprintf(",(\"%s\", %s, %s)", $1, $2, $3 ) } END{print ";"}' > insert.sql
[再度import]
mysql -u hoge_user -phoge -D hoge < insert.sql
実践
取得したいデータをもう少しはっきり定義していたら手前のシェルでもう少しデータ加工できそう。