복원 실패: `entity2char already exists' RDS Postgres 13.7

"Discourse 2.9.0.beta10 - https://github.com/discourse/discourse version 8d3fe3ddc5d38ab02a8f5c6aed7ebf7a6bcfbfec">에서 생성된 데이터베이스를 복원하려고 시도하고 있으며, 대상은 Discourse 2.9.0.beta12 - https://github.com/discourse/discourse version d4371a9ffcc6c727105a880b4b70c715ed0283cb">입니다. 양쪽 모두 RDS Postgres 13.7을 사용하고 있습니다. 압축되지 않은 데이터베이스 크기는 126GB로, 30GB인 압축 데이터베이스를 복원하려면 200GB 디스크가 필요하다고 생각하며 며칠을 보낸 끝에 다음과 같은 오류가 발생했습니다:

...
SET
CREATE TYPE
ERROR:  function "entity2char" already exists with same argument types
EXCEPTION: psql failed: ERROR:  function "entity2char" already exists with same argument types
/var/www/discourse/lib/backup_restore/database_restorer.rb:92:in `restore_dump'
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in `restore'
/var/www/discourse/lib/backup_restore/restorer.rb:51:in `run'
...

"entity2char" already exists를 검색해도 아무 결과가 없으며, 코어나 플러그인 어디에서도 entity2char를 찾을 수 없습니다. retort에서도 찾지 못했는데, 이쪽을 원인으로 의심했지만 제거해도 문제가 해결되지 않았습니다.

현재 사용 중인 플러그인은 다음과 같습니다:

         - git clone https://github.com/discourse/discourse-adplugin.git
         - git clone https://github.com/discourse/discourse-affiliate.git
         - git clone https://github.com/discourse/discourse-bbcode.git
         - git clone https://github.com/discourse/discourse-canned-replies.git
         - git clone https://github.com/discourse/discourse-data-explorer.git
         - git clone https://github.com/discourse/discourse-prometheus.git
         - git clone https://github.com/discourse/discourse-push-notifications.git
         - git clone https://github.com/discourse/discourse-signatures.git
         - git clone https://github.com/discourse/discourse-user-notes.git
         - git clone https://github.com/discourse/discourse-spoiler-alert.git
         - git clone https://github.com/discourse/discourse-cakeday.git
         - git clone https://github.com/discourse/discourse-checklist.git
         - git clone https://github.com/discourse/discourse-calendar.git
         - git clone https://github.com/discourse/discourse-reactions.git

백업을 만든 데이터베이스에서 entity2char 함수를 찾아보려 했지만 찾을 수 없었습니다.

이 포럼의 역사는 어떻게 되나요? 어떤 PostgreSQL 버전과 Discourse 버전으로 시작했나요? Bitnami나 그런 불안정한 호스팅 업체를 사용했던 적이 있나요?

어떤 이유인지 모르겠지만 데이터베이스 덤프에 entity2char 함수에 대한 참조가 포함된 것으로 보입니다. 덤프에 다른 문제가 있는 경우를 제외하고는 이를 제거하면 작동할 것입니다.

기존 데이터베이스에서 이를 제거하는 방법에 대한 힌트가 있을까요? 구글에서 찾은 첫 번째 해결책은 효과가 없었습니다.

데이터베이스에서 삭제하지 말고, 백업에서 삭제하세요.

데이터베이스에서 삭제할 뻔했습니다. SQL에 함수를 삭제하는 방법이 훨씬 쉬워 보였거든요.

   drop function entity2char;

\df 명령으로 목록을 확인했습니다.

데이터베이스에서 삭제하면 무언가 깨질까요?

잠깐. . . . 이 연습의 목적은 최신 Discourse를 설치하고 데이터베이스를 마이그레이션할 때 기존 프로덕션 데이터베이스와 Discourse가 정상적으로 동작하는지 확인하는 것입니다. 따라서 스테이징에 복원하기 위해 데이터베이스를 수정하는 것은 의미가 없습니다.

네, 정확히 이 부분입니다.

그리고 이 부분도 :wink:

아마 작동할 수 있는 방법은, 복원 직전에 대상 데이터베이스 인스턴스에서 함수 이름을 변경해 보는 것입니다. 하지만 저는 이를 테스트해 보지 않았습니다.

즉 (대상 DB에서)

  • ALTER FUNCTION entity2char RENAME TO e2c_outoftheway
  • 복원
  • ALTER FUNCTION entity2char RENAME TO e2c_from_backup
  • ALTER FUNCTION e2c_outoftheway RENAME TO entity2char

아! 그래서 문제는 스테이징 데이터베이스에 이미 그 함수가 있고, 백업에도 그 함수가 있어서 동일한 함수라는 점을 인식하지 못하는 거군요.

스테이징/대상 사이트에서 데이터베이스를 삭제하고 새로 만드는 것이 더 나을까요?

하지만 당신의 아이디어가 좀 더 쉬운 것 같습니다.

수정: 알겠습니다. 함수 이름을 변경하고 이제 복원을 진행 중입니다. 약 1시간 후에 성공했는지 확인할 수 있을 것입니다.

그리고 우려되는 점은 백업에 함께 들어가는 entity2char 함수가 기존 데이터베이스와 함께 제대로 작동하지 않을까 하는 것입니다. 그냥 새 데이터베이스를 만들고 거기에 복원하는 것이 좋을까요? 어차피 xx-discourse-database-5라는 이름도 별로 마음에 들지 않습니다.

수정: 글쎄요, 좀 더 많은 문제를 해결해야 할 것 같습니다.

ERROR:  function "replace_mentions" already exists with same argument types

아마 새 데이터베이스로 시작하는 것이 최선의 방법일 것 같습니다.

해결 방법은 복구 전에 데이터베이스를 삭제(drop), 생성(create) 및 마이그레이션(migrate)하는 것이었습니다. 마이그레이션 단계를 건너뛰는 것을 시도해 보았어야 했습니다.

도움을 주셔서 감사합니다, @RGJ님, @gerhard님. 여러분이 제시한 단서 덕분에 이 문제를 해결할 수 있었습니다.

데이터베이스를 항상 먼저 삭제하면 안 되는 이유는, 실패했을 때 되돌릴 수 없기 때문인 것 같습니다.