2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

railsのsessionデータ更新でzero-length delimited identifier at or near """"のエラー

Last updated at Posted at 2020-09-06

開発環境である時見慣れぬエラーが出て、もしも本番で発生したらどうすればいいのか途方に暮れそうなので、復旧手順を試行錯誤したメモです。同じエラーが出た場合にヒントになればと思うのですが、同じ状況とは限らないのでご注意。

環境 rails 5.2.4.3 postgresql 12.2 pg 1.2.2 activerecord-session_store 1.1.3

状況
 ログインするサイトで、ブラウザからアクセスした際に以下のエラーが出て、サイトをまったく利用できない。

development.log
ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR:  zero-length delimited identifier at or near """"
LINE 1: ... SET "data" = $1, "updated_at" = $2 WHERE "sessions"."" = $3
: UPDATE "sessions" SET "data" = $1, "updated_at" = $2 WHERE "sessions"."" = $3)
:

activerecord (5.2.4.3) lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `exec_params'
activerecord (5.2.4.3) lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `block (2 levels) in exec_no_cache'
...

ログに羅列されているファイル名には自分が書いたファイルはなく心当たりなし。昨日何やったっけ。とりあえずこの状態のDBをダンプして保存。

セッションの情報はactiverecord-session_storeでactiverecordに記録していて、ユーザがアクセスするとこの情報を更新する。その際にこのエラーが出ている。
正常に動いている本番データと比べると、whereのところは本来は
WHERE "sessions"."id" = $3 のはずであることがわかった。

activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/database_statements.rb
までは追っかけて、発行するsqlを生成する関数の入力値arelでname="id"であるところが、エラーが出るパターンではname=""になっていたところまではわかったが、そこから遡るのは断念。

pg_dumpしてpsqlでloadしても同じエラー。そこで、pg_dumpをデータだけにして、dbは一度初期化、migrateしてデータを流し込んだら復旧できた。復旧後改めてpg_dumpして比較すると、

ALTER TABLE ONLY public.sessions
    ADD CONSTRAINT sessions_pkey PRIMARY KEY (id);

が欠けていた。どこで/何をしてこれが消えたのか、心当たりなし。

sessionsのテーブルだけであれば、邪道っぽいけど、以下のようにactiverecord-session_store適用でやったのと同じmigrationを一時的に用意し、

class ResetSessionTable < ActiveRecord::Migration[5.2]
  def up
    drop_table :sessions
    create_table :sessions do |t|
      t.string :session_id, :null => false
      t.text :data
      t.timestamps
    end

    add_index :sessions, :session_id, :unique => true
    add_index :sessions, :updated_at
  end
  def down
  end
end
# pg_dump -b DB名 --data-only --table sessions >sessions_bak.sql
# ここで上記をdb:migrateしてすぐにdb:rollbackしてファイルを削除
# cat sessions_bak.sql  |/usr/local/pgsql/bin/psql -e DB名

こんな感じで停止もそこそこで復旧できる見通しはついた。もっと良い対応があるかもしれない。

結局発生の原因はわかっていないが、開発環境は初期化とかデータロードを頻繁に行っているため、そこで何らかエラーがあった可能性が高いけど、pgのバージョンの制約とか、他のgemとかの影響の可能性もなくはないので、情報共有で投稿してみました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?