2021-01-22 20:16:22.015 UTC [4055] discourse@discourse LOG: duration: 75335.241 ms statement: UPDATE notifications SET processed = true
2021-01-22 20:16:23.792 UTC [4055] discourse@discourse LOG: duration: 1776.591 ms statement: ALTER TABLE "notifications" ALTER COLUMN "processed" SET NOT NULL
2021-01-22 20:16:25.198 UTC [4055] discourse@discourse LOG: duration: 1323.298 ms statement: CREATE INDEX "index_notifications_on_processed" ON "notifications" ("processed")
2021-01-22 20:16:25.458 UTC [4055] discourse@discourse LOG: duration: 241.063 ms statement: CREATE TABLE "user_notification_schedules" ("id" bigserial primary key, "user_id" integer NOT NULL, "enabled" boolean DEFAULT FALSE NOT NULL, "day_0_start_time" integer NOT NULL, "day_0_end_time" integer NOT NULL, "day_1_start_time" integer NOT NULL, "day_1_end_time" integer NOT NULL, "day_2_start_time" integer NOT NULL, "day_2_end_time" integer NOT NULL, "day_3_start_time" integer NOT NULL, "day_3_end_time" integer NOT NULL, "day_4_start_time" integer NOT NULL, "day_4_end_time" integer NOT NULL, "day_5_start_time" integer NOT NULL, "day_5_end_time" integer NOT NULL, "day_6_start_time" integer NOT NULL, "day_6_end_time" integer NOT NULL)
2021-01-22 20:16:25.560 UTC [4055] discourse@discourse LOG: duration: 100.868 ms statement: CREATE INDEX "index_user_notification_schedules_on_user_id" ON "user_notification_schedules" ("user_id")
2021-01-22 20:16:25.782 UTC [4055] discourse@discourse LOG: duration: 142.180 ms statement: CREATE INDEX "index_do_not_disturb_timings_on_scheduled" ON "do_not_disturb_timings" ("scheduled")
2021-01-22 20:16:26.414 UTC [4055] discourse@discourse LOG: duration: 361.514 ms statement: UPDATE users
SET locale = 'en_GB'
WHERE locale = 'en'
2021-01-22 20:16:26.656 UTC [4055] discourse@discourse LOG: duration: 132.778 ms statement: UPDATE theme_translation_overrides
SET locale = 'en_GB'
WHERE locale = 'en'
2021-01-22 20:16:42.745 UTC [4055] discourse@discourse ERROR: duplicate key value violates unique constraint "index_users_on_username"
2021-01-22 20:16:42.745 UTC [4055] discourse@discourse DETAIL: Key (username)=(DaveW) already exists.
2021-01-22 20:16:42.745 UTC [4055] discourse@discourse STATEMENT: UPDATE users
SET locale = 'en'
WHERE locale = 'en_US'
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_username"
DETAIL: Key (username)=(DaveW) already exists.
그리고 출력의 마지막 부분에는 다음과 같은 내용이 표시됩니다:
I, [2021-01-22T20:16:42.805286 #1] INFO -- : Terminating async processes
I, [2021-01-22T20:16:42.805333 #1] INFO -- : Sending INT to HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main pid: 49
I, [2021-01-22T20:16:42.805381 #1] INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 166
166:signal-handler (1611346602) Received SIGTERM scheduling shutdown...
2021-01-22 20:16:42.805 UTC [49] LOG: received fast shutdown request
2021-01-22 20:16:42.835 UTC [49] LOG: aborting any active transactions
2021-01-22 20:16:42.857 UTC [49] LOG: background worker "logical replication launcher" (PID 58) exited with exit code 1
166:M 22 Jan 2021 20:16:42.876 # User requested shutdown...
166:M 22 Jan 2021 20:16:42.876 * Saving the final RDB snapshot before exiting.
166:M 22 Jan 2021 20:16:44.758 * DB saved on disk
166:M 22 Jan 2021 20:16:44.758 # Redis is now ready to exit, bye bye...
2021-01-22 20:16:45.563 UTC [53] LOG: shutting down
I, [2021-01-22T20:16:52.806177 #1] INFO -- : HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main pid:49 did not terminate cleanly, forcing termination!
FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate' failed with return #<Process::Status: pid 4032 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:112:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"db_migrate", "cmd"=>["su discourse -c 'bundle exec rake db:migrate'"]}
d627ad17d1f22d839a7dc8099878e6272eb3ea1772539f6628e2a23dd830aca2
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
말씀하신 내용을 이해했습니다. GUI에서 검색을 하면 실제로 두 개가 보이긴 합니다. 하지만 관리자로 로그인하여 두 항목 모두를 클릭해서 상세 페이지를 불러오면, 두 계정이 동일한 사용자로 보입니다. 두 계정 사이에 다른 단 하나의 세부 정보도 찾을 수 없습니다. 기본적으로 그중 어느 것을 클릭하든, 전체 이름이 입력된 두 번째 계정의 데이터가 표시됩니다.
해당 사용자는 이전에 게시물을 작성한 적이 없고 한동안 접속하지 않았기 때문에, GUI에서 해당 계정을 삭제했습니다.
흥미롭게도, 여전히 목록에서 첫 번째에 있는, 전체 이름이 없는 다른 계정은 남아 있습니다. 하지만 이제 그 사용자를 클릭하면 아무 일도 일어나지 않습니다. 대화상자가 열리려다 즉시 닫히는 것을 볼 수 있습니다.
데이터베이스에서 중복 항목을 스캔할 방법이 있을까요? 사용자뿐만 아니라 업그레이드 중 이 오류를 유발할 수 있는 모든 테이블에 대해요.
다시 시도하기 전에 모두 찾아서 수정하고 싶습니다.
또한 이것이 업그레이드 과정의 일부가 되는 것이 좋겠습니다. 먼저 스캔을 실행한 후, 어떤 변경 사항도 적용되기 전에 프로세스를 중단하는 방식이죠. 사용자에게 경고를 하고, 중복 항목 목록과 함께 메타(meta)에 있는 수정 방법 안내 페이지로 연결되는 링크를 제공하는 것이 어떨까요?
저는 데이터베이스 전문가가 아니기 때문에 그게 좀 무섭게 느껴집니다. 그리고 제가 올바르게 이해했다면, 그렇게 하면 중복된 인덱스가 생겨서 수동으로 삭제해야 한다는 뜻인가요?
게다가 여기가 이상한 부분입니다. 이전 중복 항목에서 제 사이트에서 발견했던 것과 마찬가지로, 이번에는 GUI에서 중복된 사용자 RobS를 발견했습니다. 하지만, 이전과 마찬가지로 그중 어느 것을 클릭하든 결국 둘 중 하나(사용자 #2)의 프로필 페이지로 이동했습니다. 즉:
GUI에서 RobS라는 이름의 사용자를 나열합니다. 두 명을 찾습니다. 둘 다 다른 통계를 가지고 있음을 확인합니다.
사용자 #1을 클릭합니다. 사용자 #2에 속하는 프로필과 통계를 확인합니다.
사용자 #2를 클릭합니다. 사용자 #2에 속하는 프로필과 통계를 확인합니다.
select * from users WHERE username_lower = 'robs';
1행 반환: 사용자 #2처럼 보이는 것(날짜가 일치합니다).
select * from users WHERE username = 'RobS';
역시 1행만 반환: 사용자 #1처럼 보이는 것(다시, 날짜가 일치합니다). 이 사용자는 다른 사용자와 ID가 다릅니다.
출력 결과를 판단하면, 둘 다 같은 username과 username_lower를 가지고 있었음에도 불구하고 각 SELECT 문에서 1행만 반환되었습니다. 제 데이터베이스가 심각한 상태인가요?
네, 가능하다고 생각합니다. 그리고 더 나은 방법이 있는지 저도 잘 모르겠습니다. 제 테스트 인스턴스에서는 아무 출력 없이 실행만 되었습니다. 프로덕션 사이트를 업데이트했을 때 중복된 항목이 하나뿐이었기 때문에, 제 경험은 여러분의 상황에 좋은 예시가 아닐 수 있습니다. 어쨌든 데이터베이스 작업을 하기 전에 반드시 백업하세요—보통 DigitalOcean에서 스냅샷을 만들어 두면 문제가 생겼을 때 복구가 빠르고 쉽습니다.