3行で
- テーブル名を変更したくない人はこの記事。変更しても大丈夫な人は作り直しでおk
- サーバレス環境だが、パイプラインの途中止めていい感じにメンテするということができなかった
- 間違えるな(めんどくさいから)
概要
- Stream Firestore to BigQueryという便利なFirebase Extentionsがある
- Firestoreの対象のコレクションの書き込みをトリガー → Eventarc → Cloud Functions(Cloud Run) → BigQuery
- 上記流れでパイプラインをほぼ自動で用意してくれる便利なやつ
- プロジェクト初期に導入した。当時何も考えずインストールしたので、パーティションを年で設定した
- データパイプラインのタスクが増えていく中で、クエリの課金量なんか高くない??って思って内訳みたら、上の設定したことを思い出した
- じゃあ、パーティション設定しなおそうね(沖縄風)って腰をあげて作業したのがことの始まり
調査開始
パーティションの分割基準をあとから変更することはできる?
できない
END
愚直なやり方を思いつく
- CTEを使って移行元のテーブルのデータから新規でテーブルを作る
- 移行元のテーブルを
_bk
とかつけてRENAMEする - 移行先のテーブルを移行元のテーブル名にRENAMEする
CREATE TABLE `project-id.dataset-id.collection_name_raw_changelog_移行先`
PARTITION BY
DATE(timestamp) -- timestamp列の日付部分でパーティション分割
OPTIONS (
description = 'collection_name table partitioned by day'
-- 必要に応じて他のオプション (ラベルなど) を追加
) AS
SELECT
timestamp,
event_id,
document_name,
operation,
data,
old_data,
document_id
FROM
`project-id.dataset-id.collection_name_raw_changelog`;
-- (推奨) 古いテーブルをバックアップとしてリネーム
ALTER TABLE `project-id.dataset-id.collection_name_raw_changelog`
RENAME TO `collection_name_raw_changelog_bk`;
-- 新しい日次パーティションテーブルを元のテーブル名にリネーム
ALTER TABLE `project-id.dataset-id.collection_name_raw_changelog_移行先`
RENAME TO `collection_name_raw_changelog`;
完璧だ!!!!
だめでした
Cannot rename A:B.C because it has streaming data.
みたいなエラーがでる
調べてみたら、ストリーミングバッファにデータが書き込まれている状態でrenameはできないとのこと。そうか
ストリーミングバッファを空にする方法を探す
強制的にはできないとのこと
ストリーミングバッファが空になるタイミングを見極める
日中はトリガーされまくなので深夜帯じゃないと不可能
ストリーミングするCloud Run(Firebase Extentions)を止められないか考える
- 無効化ができない(削除のみ)
- Eventarcよくわからない(PubSubを拡張したなにかと思って無効化できないか探したけどよくわからない)
- Cloud Runのソースコード無理やり書き換えてエラー出力するようにしたがストリーミングバッファが空になるタイミングが最大90分らしいので待てない
辛い
次なる手
同じテーブル名を使いまわしたいだけなので、そもそもテーブル名変更すればどうとでもなるんですが、参照するコードが多かったので避けたかった。というわけでこうしました
-
Stream Firestore to BigQuery
をアンインストール - CTEを使って移行元のテーブルのデータから新規でテーブルを作る
- 移行元テーブルを削除
- 2のテーブルをRENAME
- 拡張機能インストール
- 移行作業中のFirestoreのドキュメントをPythonスクリプトで取得して更新(updated_atを上書きするなどで)
- 再度トリガーが走るのでBigQuery側へSyncされる
結果は?
これでいけました
雑感
まちがえないで