日. 6月 26th, 2022

はじめに

redashの内部のDBはpostgresだが、version upを繰り返すうちにDB構成がバグってしまった。具体的には外部キーや、Indexなのが外れてしまった。

根本対応としては再度イチからredashを作り、そこにデータを一個一個転送することになるとおもうが、なかなかその対応にたどり着けず、一時対応でとりあえず問題を先送りしている。

ちなみにusersテーブルの場合、以下の部分がごっそり無くなっていた

Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "users_api_key_key" UNIQUE CONSTRAINT, btree (api_key)
    "users_org_id_email" UNIQUE, btree (org_id, email)
Foreign-key constraints:
    "users_org_id_fkey" FOREIGN KEY (org_id) REFERENCES organizations(id)
Referenced by:
    TABLE "access_permissions" CONSTRAINT "access_permissions_grantee_id_fkey" FOREIGN KEY (grantee_id) REFERENCES users(id)
    TABLE "access_permissions" CONSTRAINT "access_permissions_grantor_id_fkey" FOREIGN KEY (grantor_id) REFERENCES users(id)
    TABLE "alert_subscriptions" CONSTRAINT "alert_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "alerts" CONSTRAINT "alerts_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "api_keys" CONSTRAINT "api_keys_created_by_id_fkey" FOREIGN KEY (created_by_id) REFERENCES users(id)
    TABLE "changes" CONSTRAINT "changes_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "dashboards" CONSTRAINT "dashboards_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "events" CONSTRAINT "events_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "favorites" CONSTRAINT "favorites_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "notification_destinations" CONSTRAINT "notification_destinations_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "queries" CONSTRAINT "queries_last_modified_by_id_fkey" FOREIGN KEY (last_modified_by_id) REFERENCES users(id)
    TABLE "queries" CONSTRAINT "queries_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "query_snippets" CONSTRAINT "query_snippets_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)

その結果、Edit Visualizationで保存ができなくなった。

コンテナのログを見たら、本来1つしかないはずが2つ以上ヒットするよ。とエラーになっているのが原因だとわかった。

シーケンスで指している数字が、すでにレコードとして存在していたのが問題だ。

今回はシーケンスを変更することで対処した。

Postgresのシーケンス一覧を表示する

“` SELECT c.relname FROM pg_class c LEFT join pg_user u ON c.relowner = u.usesysid WHERE c.relkind = ‘S’; relname  “` で表示できる。

redashに限らず、どのPostgresでも対応可能。

postgres=# SELECT c.relname FROM pg_class c LEFT join pg_user u ON c.relowner = u.usesysid WHERE c.relkind = 'S';
             relname              
----------------------------------
 access_permissions_id_seq
 alert_subscriptions_id_seq
 alerts_id_seq
 api_keys_id_seq
 changes_id_seq
 dashboards_id_seq
 data_source_groups_id_seq
 data_sources_id_seq
 events_id_seq
 favorites_id_seq
 groups_id_seq
 notification_destinations_id_seq
 organizations_id_seq
 queries_id_seq
 query_results_id_seq
 query_snippets_id_seq
 users_id_seq
 visualizations_id_seq
 widgets_id_seq
(19 rows)

postgres=#

シーケンスの値を確認する

postgres=# select nextval('visualizations_id_seq');                                                                                                                                                                  nextval 
---------
      56
(1 row)

56ということがわかる

シーケンスの値を変更する

ALTER SEQUENCEコマンドで変更が可能

postgres=# ALTER SEQUENCE visualizations_id_seq RESTART WITH 251;
ALTER SEQUENCE

 

結果、redashが正常に動くようになった。

おそらくversion upを繰り返しているうちに、どこかでDBスキーマが壊れてしまった可能性がある。

 

関連記事

https://tsukada.sumito.jp/2018/10/11/redash_all-queries_loading/

redash を専門に扱っている唯一の本