ERROR: cache lookup failed for type 1075

昨日に引き続き今日もPostgreSQLをダンプするための苦労の話

$ docker exec [container] pg_dumpall -c -U misskey > dump.sql
pg_dump: error: Dumping the contents of table "note" failed: PQgetResult() failed.
pg_dump: detail: Error message from server: ERROR:  cache lookup failed for type 1075
pg_dump: detail: Command was: COPY public.note (id, "replyId", "renoteId", text, name, cw, "userId", "localOnly", "renoteCount", "repliesCount", reactions, visibility, uri, "fileIds", "attachedFileTypes", "visibleUserIds", mentions, "mentionedRemoteUsers", emojis, tags, "hasPoll", "userHost", "replyUserId", "replyUserHost", "renoteUserId", "renoteUserHost", url, "channelId", "threadId", "reactionAcceptance", "clippedCount", "reactionAndUserPairCache") TO stdout;
pg_dumpall: error: pg_dump failed on database "misskey", exiting
$

今回のエラーはERROR: cache lookup failed for type 1075
noteテーブルのダンプ時に発生しています。

ダンプの最後のレコード

前回のものと同じく常に同じ場所で詰まるので、とあるレコードがダメなんでしょう。 idが9satsk2cj6のレコードまでは正常にダンプできています。

次のidを調べたいのですが、いい感じの方法を思いつかなかったのでバカの方法でやります。
idの標準出力をテキストに変換してgrepで探します。なんだかんだこれが一番楽。

$ docker exec [container] psql -c 'SELECT id FROM note;' -U misskey misskey > ids.txt
$ grep -A1 '9satsk2cj6' ids.txt
 9satsk2cj6
 9pq3zca1nj

idが9pq3zca1njなレコードが怪しそうです。

確認

misskey=# SELECT * FROM note WHERE id = '9pq3zca1nj';
ERROR:  cache lookup failed for type 1075
misskey=# SELECT id FROM note WHERE id = '9pq3zca1nj';
     id
------------
 9pq3zca1nj
(1 row)

misskey=# SELECT id,name,text FROM note WHERE id = '9pq3zca1nj';
     id     | name |                       text
------------+------+--------------------------------------------------
 9pq3zca1nj |      | 内容(省略)
(1 row)

misskey=#

全てのカラムはダメそうです。 idやname, textなどは問題ありません。

misskey=# SELECT
"id",
"reactionAndUserPairCache"
FROM note
WHERE id = '9pq3zca1nj';
ERROR:  cache lookup failed for type 1075
misskey=#

reactionAndUserPairCacheの値が悪さしてそうです。

更新

当該noteを調べたところ、現在も運用されているインスタンスの投稿だったため、
削除ではなく初期値を代入するという方法でお茶を濁します。

misskey=# UPDATE note SET "reactionAndUserPairCache" = '{}' WHERE id = '9pq3zca1nj';
UPDATE 1
misskey=# SELECT
"id",
"reactionAndUserPairCache"
FROM note
WHERE id = '9pq3zca1nj';
     id     | reactionAndUserPairCache
------------+--------------------------
 9pq3zca1nj | {}
(1 row)

misskey=#

これで問題なく当該レコードを参照することができるようになりました。

当該テーブルのダンプを取得することができたため、いったんこのエラーは解決ということになります。

おわり

本番環境でSQL文打つのいやすぎる。

今考えたら、数か月前にやらかしたファイルシステムバグった件のせいな気がしてきた。
確かあれ丁度DBが壊れたはず。