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











実践
取得したいデータをもう少しはっきり定義していたら手前のシェルでもう少しデータ加工できそう。