본문으로 이동
주 메뉴
주 메뉴
사이드바로 이동
숨기기
둘러보기
연구 메모리
검색
새 메모
메모 목록
최근 변경
도움말
사용 안내
메모 작성법
문제 해결
연구실
S3@YONSEI 웹사이트
운영
시스템 버전
사용자 관리
S3 연구 메모리
검색
검색
외관
로그인
개인 도구
로그인
도움말:S3 연구 메모리/백업과 복원 문서 원본 보기
도움말
토론
한국어
읽기
원본 보기
역사 보기
도구
도구
사이드바로 이동
숨기기
작업
읽기
원본 보기
역사 보기
새로 고침
일반
여기를 가리키는 문서
가리키는 글의 최근 바뀜
특수 문서 목록
문서 정보
외관
사이드바로 이동
숨기기
←
도움말:S3 연구 메모리/백업과 복원
문서 편집 작업을 수행할 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 작업은 다음 중 하나의 권한을 가진 사용자에게 제한됩니다:
사용자
,
연구 메모리 에이전트
.
문서의 원본을 보거나 복사할 수 있습니다.
<!-- S3RM managed repository document; edit the Markdown source, not this page. --> ''이 페이지는 저장소 문서에서 자동으로 동기화됩니다. 위키에서 직접 편집하지 마세요.'' Semantic MediaWiki가 유일한 Lesson 저장소입니다. 복구 지점에는 같은 시점의 MariaDB 덤프, 업로드 파일, 생성된 위키 설정이 모두 있어야 합니다. 공용 <code><nowiki>mcp-http</nowiki></code>는 상태를 저장하지 않는 전송·검증 어댑터입니다. Lesson 볼륨, 토큰 DB, 별도 기준 데이터가 없으므로 백업하지 않습니다. 이미지와 설정은 저장소와 <code><nowiki>.env</nowiki></code>에서 다시 만듭니다. Caddy는 [https://s3wiki.yonsei.ac.kr/]와 [https://s3wiki.yonsei.ac.kr/mcp]의 HTTPS 진입점이며 지식을 저장하지 않습니다. 복구 스크립트는 Bash 4 이상, GNU coreutils(<code><nowiki>stat</nowiki></code>, <code><nowiki>sha256sum</nowiki></code>), GNU tar, gzip이 있는 GNU/Linux Docker 호스트에서 지원합니다. 필요한 명령이 없으면 바로 실패합니다. macOS와 Windows Docker Desktop에서는 이 Compose 프로젝트를 소유한 Linux VM 또는 Linux 호스트에서 실행하세요. BSD 명령 옵션이 같다고 가정하지 마세요. === 영구 데이터 === {| class="wikitable" ! Compose 볼륨 !! 내용 !! 복구 때 역할 |- | <code><nowiki>db_data</nowiki></code> || MediaWiki 페이지, 의미 데이터, 사용자, 변경 이력, 로그, 호환 필드 || 기준 데이터베이스 |- | <code><nowiki>db_binlogs</nowiki></code> || MariaDB ROW binary log와 index || 기준 덤프 이후 시간점 복구(PITR). 기본 14일 보존 |- | <code><nowiki>mediawiki_images</nowiki></code> || 업로드한 근거 파일과 MediaWiki 업로드 메타데이터 || DB 덤프와 같은 시점이어야 함 |- | <code><nowiki>mediawiki_config</nowiki></code> || 생성된 <code><nowiki>LocalSettings.php</nowiki></code>와 MediaWiki 비밀 키 || 위키 식별·설정 보존에 필요 |- | <code><nowiki>caddy_data</nowiki></code> || 발급된 TLS 인증서, 개인 키, Caddy 실행 상태 || 평소 보존하되 Lesson 기준 데이터는 아님 |- | <code><nowiki>caddy_config</nowiki></code> || Caddy 실행 설정 || 저장소와 공개 hostname으로 다시 생성 가능 |- | <code><nowiki>embedding_models</nowiki></code> || SHA-256으로 확인한 번들 GGUF || 다시 받을 수 있는 파생 캐시. Lesson 복구 세트가 아님 |} 일반 백업 스크립트는 DB 덤프, 설정, 업로드와 함께 <code><nowiki>db_binlogs</nowiki></code>의 캡처 시점 구간과 덤프에 내장된 replay 시작 file·position을 저장합니다. 이 항목이 Lesson 복구 세트입니다. 새 <code><nowiki>db_binlogs</nowiki></code> 볼륨은 one-shot <code><nowiki>db-binlog-init</nowiki></code>이 MariaDB 계정만 쓸 수 있도록 소유권과 mode를 맞춘 뒤 DB가 시작합니다. 이 서비스가 실패하면 DB를 시작하지 않으며, 볼륨 권한을 넓혀 우회하지 않습니다. <code><nowiki>caddy_data</nowiki></code>와 <code><nowiki>caddy_config</nowiki></code>는 평소 재시작 때 남겨 두되, 버전이 있는 위키 백업에 섞지 않습니다. 이 볼륨이 없어지면 DNS와 외부 80/443이 정상일 때 Caddy가 인증서를 다시 받을 수 있습니다. 일반 운영에서는 <code><nowiki>docker compose down --volumes</nowiki></code>를 쓰지 마세요. <code><nowiki>embedding_models</nowiki></code>에는 Lesson, 검색 query나 벡터가 없습니다. 백업·복원 스크립트는 이 볼륨을 포함하지 않으며, 의미 검색을 다시 켤 때 고정된 원본과 SHA-256으로 재구성합니다. 평소에는 재다운로드와 서비스 중단을 피하도록 볼륨을 남겨 둡니다. 저장소에는 다시 만들 수 있는 코드, 템플릿, 양식이 있습니다. 자격 증명이 든 <code><nowiki>.env</nowiki></code>는 추적하지 않으며 일반 백업 아카이브에도 넣지 않습니다. 서버 담당자가 복구용 사본을 따로 보관하되 Git이나 공개 아카이브에는 넣지 마세요. 복구 세트의 <code><nowiki>runtime-images.txt</nowiki></code>는 Compose에 설정한 image reference와 실제 컨테이너 image ID를 함께 기록합니다. <code><nowiki>repository-tracked.patch.gz</nowiki></code>는 현재 HEAD 기준의 '''추적된 파일''' 차이만 담습니다. <code><nowiki>.env</nowiki></code>, untracked dump, upload, 자격 증명은 구조적으로 제외됩니다. untracked 파일이 있었다면 metadata에 <code><nowiki>present_not_archived</nowiki></code>만 남고 내용과 이름은 보관하지 않습니다. 서버 <code><nowiki>.env</nowiki></code>에는 MCP 쓰기 토큰의 해시만 있습니다. 전달용 원문 토큰이 든 mode <code><nowiki>0600</nowiki></code> <code><nowiki>~/.config/s3-research-memory/client.env</nowiki></code>도 최소 한 곳에 보관하세요. 원문 토큰을 모두 잃었다면 <code><nowiki>./scripts/configure-mcp-token.sh --rotate</nowiki></code>로 새 토큰을 만들고 쓰기 클라이언트에 다시 전달합니다. 이 작업 중에도 공개 조회는 계속됩니다. === 백업 === 저장소 밖의 절대 경로를 사용합니다. 가능하면 Docker 호스트와 다른 디스크를 선택하고, 서버 담당자만 읽고 쓸 수 있게 만듭니다. <pre><nowiki> install -d -m 0700 /srv/s3rm-backups docker compose stop mcp-http ./scripts/backup.sh /srv/s3rm-backups docker compose up -d mcp-http </nowiki></pre> 먼저 <code><nowiki>mcp-http</nowiki></code>를 멈추면 에이전트 변경 경로가 닫힙니다. 백업 스크립트는 DB를 기다린 뒤 <code><nowiki>mediawiki-jobs</nowiki></code>, <code><nowiki>mediawiki</nowiki></code>와 실행 중인 <code><nowiki>bootstrap</nowiki></code>을 멈춰 브라우저와 job 변경도 막습니다. MariaDB binary log를 교체해 file·position을 고정한 뒤 <code><nowiki>--master-data=2</nowiki></code> 논리 덤프, binary-log 구간, 업로드·설정 볼륨을 묶습니다. 실패해도 exit trap이 스크립트가 관리한 서비스를 백업 전 상태로 돌립니다. <code><nowiki>mcp-http</nowiki></code>는 명시적으로 멈췄으므로 성공하거나 원인을 확인한 실패 뒤에도 마지막 <code><nowiki>up</nowiki></code> 명령을 실행해야 합니다. 모든 파일의 형식과 checksum을 확인한 뒤에만 시각이 붙은 최종 디렉터리를 공개합니다. 덤프나 근거 아카이브를 저장소에 넣지 않습니다. 끝에 출력되는 복구 디렉터리의 정확한 경로를 기록하세요. ==== binary log를 처음 켜는 서버 ==== 이 설정을 배포하기 전부터 실행 중인 DB는 컨테이너를 다시 만들기 전까지 <code><nowiki>log_bin=OFF</nowiki></code>일 수 있습니다. 이 상태에서 일반 백업은 중단되며, 최초 이전 전에만 다음 명시적 기준 백업을 사용합니다. <pre><nowiki> ./scripts/backup.sh --legacy-base /srv/s3rm-backups </nowiki></pre> <code><nowiki>--legacy-base</nowiki></code>는 <code><nowiki>log_bin=OFF</nowiki></code>인 DB에서만 실행됩니다. <code><nowiki>database.sql.gz</nowiki></code>, 두 볼륨 아카이브, <code><nowiki>metadata.txt</nowiki></code>, <code><nowiki>SHA256SUMS</nowiki></code>로 이루어진 복원 가능한 format 1 기준 백업이며 PITR 보조 파일은 '''하나도''' 생성하지 않습니다. 나중에 별도 <code><nowiki>database-binlogs.tar.gz</nowiki></code>나 <code><nowiki>AUXILIARY-SHA256SUMS</nowiki></code>를 더해 일반 백업처럼 만들지 마세요. 보조 파일이 일부만 있는 세트는 복원과 격리 검증이 거부합니다. 체크섬을 확인하고 완성된 디렉터리를 원격 저장소에 복사한 뒤에만 DB를 재생성합니다. <code><nowiki>db_data</nowiki></code>는 지우지 않고 새 <code><nowiki>db_binlogs</nowiki></code> 볼륨을 연결합니다. <pre><nowiki> docker compose stop mediawiki-jobs mcp-http bootstrap mediawiki docker compose up -d --force-recreate --wait db docker compose exec -T db sh -eu -c ' MYSQL_PWD="$MARIADB_ROOT_PASSWORD" mariadb \ --host=127.0.0.1 --user=root --batch \ --execute="SHOW VARIABLES LIKE '\''log_bin'\''; SHOW MASTER STATUS;" ' make domain-up ./scripts/backup.sh /srv/s3rm-backups </nowiki></pre> 출력에 <code><nowiki>log_bin\tON</nowiki></code>과 <code><nowiki>mariadb-bin.NNNNNN</nowiki></code> 행이 모두 있어야 합니다. 마지막 일반 백업은 PITR 보조 체인까지 갖춘 새 기준입니다. 이후에는 <code><nowiki>--legacy-base</nowiki></code>를 사용하지 마세요. 복구 디렉터리는 다음 파일을 한 세트로 가집니다. {| class="wikitable" ! 파일 !! 내용 |- | <code><nowiki>database.sql.gz</nowiki></code> || 설정된 MediaWiki DB 전체 논리 덤프 |- | <code><nowiki>database-binlogs.tar.gz</nowiki></code> || 일반 백업만: 캡처 시점까지 보존된 MariaDB ROW binary log·index 보조 아카이브 |- | <code><nowiki>pitr-manifest.txt</nowiki></code> || 일반 백업만: 기준 dump 뒤 replay를 시작할 binary-log file·position·GTID, archive 목록·digest |- | <code><nowiki>mediawiki-images.tar.gz</nowiki></code> || 업로드·근거 볼륨의 numeric-owner 아카이브 |- | <code><nowiki>mediawiki-config.tar.gz</nowiki></code> || 생성된 설정과 위키 키의 numeric-owner 아카이브 |- | <code><nowiki>runtime-images.txt</nowiki></code> || 일반 백업만: 설정 reference와 실제 실행 컨테이너 image ID |- | <code><nowiki>repository-tracked.patch.gz</nowiki></code> || 일반 백업만: HEAD에 적용할 추적 소스 binary patch. untracked·ignored 파일 제외 |- | <code><nowiki>repository-tracked-manifest.txt</nowiki></code> || 일반 백업만: 추적 파일별 SHA-256과 소스 상태 |- | <code><nowiki>metadata.txt</nowiki></code> || 형식 버전, DB 이름, 페이지·revision 수, 소스 revision, 이미지 참조, Compose 해시. 일반 백업은 PITR position도 포함 |- | <code><nowiki>SHA256SUMS</nowiki></code> || 앞의 네 payload checksum |- | <code><nowiki>AUXILIARY-SHA256SUMS</nowiki></code> || 일반 백업만: PITR·image·tracked-source 보조 파일 checksum. 이 파일 digest는 <code><nowiki>metadata.txt</nowiki></code>를 통해 기본 manifest와 결합 |} 기본 대상, 각 복구 디렉터리, 모든 파일의 권한은 <code><nowiki>0700</nowiki></code> 또는 <code><nowiki>0600</nowiki></code>입니다. 기존 대상에 group/other 접근 비트가 하나라도 있으면 스크립트가 거부하며 권한을 임의로 바꾸지 않습니다. 백업할 때 <code><nowiki>db</nowiki></code>는 실행 중이어야 합니다. 위키가 원래 정지 상태였다면 그대로 두고, 실행 중이었다면 API가 다시 healthy가 될 때까지 기다린 뒤 성공을 알립니다. 복원도 소스 디렉터리에 같은 권한 검사를 합니다. 기본 로컬 대상에 저장하려면 경로를 생략합니다. <pre><nowiki> docker compose stop mcp-http ./scripts/backup.sh docker compose up -d mcp-http </nowiki></pre> 기본 로컬 경로만 장기 보관에 사용하지 마세요. 완료된 디렉터리 전체를 접근이 제한된 외부 저장소에 복사합니다. 공개 메모가 주 내용이더라도 백업에는 사용자 정보, 삭제·이전 revision, 생성된 비밀 키가 있으므로 공개하지 않습니다. ==== 백업 확인 ==== 스크립트가 실패하면 그 백업은 사용할 수 없습니다. 성공한 뒤에도 다음을 확인합니다. # DB 덤프, 설정·이미지 아카이브, 메타데이터, <code><nowiki>SHA256SUMS</nowiki></code>가 있는지 확인합니다. 일반 백업은 binary-log·PITR 보조 파일 전체와 <code><nowiki>AUXILIARY-SHA256SUMS</nowiki></code>도 있어야 합니다. 최초 <code><nowiki>--legacy-base</nowiki></code>는 보조 파일이 하나도 없어야 합니다. # 스크립트가 출력한 checksum 명령을 실행합니다. ```bash (cd /ABS/PATH/TO/BACKUP-DIRECTORY && \ sha256sum --check --strict SHA256SUMS) # 일반 PITR 백업에서만 추가 확인 (cd /ABS/PATH/TO/BACKUP-DIRECTORY && \ sha256sum --check --strict AUXILIARY-SHA256SUMS) ``` # 빈 파일이 없는지, 시각과 소스 버전이 맞는지 확인합니다. # 디렉터리 전체를 한 단위로 복사합니다. 서로 다른 시각의 파일을 섞지 마세요. # 아래의 격리 복원 시험을 정기적으로 실행합니다. checksum은 전송 무결성만 확인하며 실제 복원 가능성을 보장하지 않습니다. MediaWiki [https://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki 백업 안내]도 DB와 파일을 함께 보관하도록 안내합니다. XML 페이지 내보내기는 보조 이동본으로 쓸 수 있지만 사용자 계정, 모든 로그, 업로드 메타데이터, 사이트 전체 상태를 담지 않으므로 이 복구 세트를 대신할 수 없습니다. ==== MariaDB PITR 경계 ==== <code><nowiki>database.sql.gz</nowiki></code>는 완전 기준 백업입니다. <code><nowiki>pitr-manifest.txt</nowiki></code>의 <code><nowiki>binlog_file</nowiki></code>·<code><nowiki>binlog_position</nowiki></code>은 그 덤프가 이미 포함한 마지막 경계이자 replay 시작 좌표입니다. 이 좌표 이전 event를 다시 적용하면 중복 변경이 생깁니다. 이후 시각으로 이동하려면 기준 좌표 '''이후'''의 연속된 binary log가 전부 있어야 합니다. 백업 당시 archive에는 아직 생기지 않은 미래 event가 들어 있을 수 없으므로, 더 늦게 만든 복구 세트의 <code><nowiki>database-binlogs.tar.gz</nowiki></code>나 별도 연속 보관본이 필요합니다. 로컬 <code><nowiki>db_binlogs</nowiki></code>는 기본 14일 후 자동 만료되므로 원격 백업과 복원 시험이 이 기간 안에 성공해야 합니다. PITR은 운영 DB에 바로 재생하지 마세요. 격리 복원을 먼저 완료한 뒤, <code><nowiki>mariadb-binlog --start-position</nowiki></code>에는 manifest의 좌표 다음 event부터 적용되도록 경계를 확인하고, <code><nowiki>--stop-datetime</nowiki></code> 또는 <code><nowiki>--stop-position</nowiki></code>을 명시하여 SQL을 만듭니다. 재생 전에 시작·종료 file, position, target UTC, 예상 event 수를 작업 기록에 남기고, Lesson·revision 개수와 대표 페이지를 확인합니다. binary log가 하나라도 빠졌거나 기준 position보다 이전 백업과 섞였다면 PITR를 계속하지 말고 다음 완전 백업으로 복원합니다. ==== 권장 주기 ==== 파일럿에서는 다음 주기로 시작합니다. * 매일 백업, 14일 보관 * 매주 백업, 8주 보관 * 이미지·의존성 업데이트나 자격 증명 변경 전 백업 * 분기마다 격리 복원 시험 실제 복구 시점 목표는 운영 상황에 맞게 정합니다. 스케줄러 종료 상태와 디스크 여유 공간을 확인하세요. 오류 알림이 없는 예약 명령만으로는 충분하지 않습니다. 새 복원을 확인하기 전에 가장 최근의 정상 백업을 지우지 마세요. ==== Cloudflare R2 자동 백업 ==== 이 서버는 다음 비공개 R2 bucket의 <code><nowiki>restic</nowiki></code> prefix를 원격 백업 저장소로 사용합니다. <pre><nowiki> https://96f01030a087d07d906bff299d260155.r2.cloudflarestorage.com/s3rm-backups </nowiki></pre> 백업 데이터는 <code><nowiki>restic</nowiki></code>이 서버에서 먼저 암호화한 뒤 전송합니다. R2 Access Key, Secret Key와 restic 암호는 Git이나 프로젝트 <code><nowiki>.env</nowiki></code>에 넣지 않습니다. 서버에 <code><nowiki>restic</nowiki></code>을 설치한 뒤 root 권한으로 설정 파일을 준비합니다. <pre><nowiki> sudo install -d -m 0700 /etc/s3-research-memory /srv/s3rm-backups sudo install -m 0600 config/remote-backup.env.example \ /etc/s3-research-memory/remote-backup.env sudo sh -c 'umask 077; openssl rand -base64 48 > /etc/s3-research-memory/restic-password' sudoedit /etc/s3-research-memory/remote-backup.env </nowiki></pre> R2에서 <code><nowiki>s3rm-backups</nowiki></code> bucket에만 목록 조회·읽기·쓰기·삭제가 가능한 S3 API 자격 증명을 만들고 설정 파일의 두 placeholder를 바꿉니다. 삭제 권한은 오래된 restic snapshot과 pack을 보존 정책에 맞게 정리할 때 필요합니다. restic 암호 파일은 서버 장애 때도 찾을 수 있도록 서버 밖의 비밀번호 관리자에 따로 보관합니다. 이 암호를 잃으면 R2의 백업을 복구할 수 없습니다. 현재 live restic repository의 자격 증명은 <code><nowiki>forget</nowiki></code>·<code><nowiki>prune</nowiki></code>를 위해 삭제 권한도 가집니다. 따라서 '''R2 자격 증명 탈취와 오작동으로부터의 불변 백업은 현재 저장소 하나만으로 달성되지 않습니다.''' 이 제한은 복원 시험 기록에 항상 남깁니다. R2의 lock·retention을 live restic prefix에 바로 적용하면 임시 lock 제거와 <code><nowiki>forget</nowiki></code>·<code><nowiki>prune</nowiki></code>가 실패할 수 있습니다. 삭제 방어는 다음과 같이 '''별도 보호 복사본'''으로 구성합니다. # live <code><nowiki>restic</nowiki></code> prefix는 현재 보존 정책으로 검증·정리합니다. # 검증한 복구 세트 또는 restic repository 세대를 별도 bucket·account의 보호 prefix로 복사합니다. 복사 writer와 retention 변경 권한을 분리합니다. # 보호 복사본은 일간 운영 키로 삭제할 수 없게 만들고, 예외 해제 권한은 다른 계정에 보관합니다. # Cloudflare 계정 MFA, bucket 범위 API token, 삭제·retention 변경 알림, 분기별 보호 복사본 복원 시험을 함께 적용합니다. 별도 bucket/retention/API token은 Cloudflare 외부 설정이므로 이 저장소의 Compose나 systemd 파일만으로는 활성화할 수 없습니다. 이 설정이 완료되기 전에는 live R2를 유일한 삭제 방어 본으로 간주하지 마세요. 원격 저장소는 한 번만 초기화합니다. <pre><nowiki> sudo bash -c ' set -a source /etc/s3-research-memory/remote-backup.env set +a exec /home/mrcha033/Projects/s3wiki/scripts/init-remote-backup.sh ' </nowiki></pre> systemd 단위를 설치하고 첫 백업을 수동으로 확인합니다. <pre><nowiki> sudo install -m 0644 deploy/systemd/s3rm-remote-backup.service \ /etc/systemd/system/s3rm-remote-backup.service sudo install -m 0644 deploy/systemd/s3rm-remote-backup.timer \ /etc/systemd/system/s3rm-remote-backup.timer sudo systemctl daemon-reload sudo systemctl start s3rm-remote-backup.service sudo systemctl status s3rm-remote-backup.service sudo systemctl enable --now s3rm-remote-backup.timer systemctl list-timers s3rm-remote-backup.timer </nowiki></pre> 작업은 매일 서울 시각 03:15 이후 45분 안에 실행합니다. 성공한 원격 snapshot은 일간 14개와 주간 8개를 보존하고, 원격 pack 정리는 일요일에 실행합니다. 전송이나 검증이 실패하면 로컬 복구 세트를 지우지 않습니다. 성공하면 R2에 이미 암호화된 snapshot을 확인한 뒤 <code><nowiki>/srv/s3rm-backups</nowiki></code>의 해당 임시 세트를 정리합니다. 상태와 최근 로그를 정기적으로 확인합니다. <pre><nowiki> systemctl status s3rm-remote-backup.timer sudo journalctl -u s3rm-remote-backup.service --since '2 days ago' </nowiki></pre> 원격 snapshot을 복구할 때는 빈 root 전용 디렉터리에 먼저 내려받고 기존 복원 스크립트로 넘깁니다. <pre><nowiki> sudo install -d -m 0700 /srv/s3rm-remote-restore sudo bash -c ' set -a source /etc/s3-research-memory/remote-backup.env set +a restic snapshots --tag s3rm-recovery-set restic restore latest --tag s3rm-recovery-set --target /srv/s3rm-remote-restore ' sudo find /srv/s3rm-remote-restore -maxdepth 2 -type f -name SHA256SUMS -print </nowiki></pre> 출력된 <code><nowiki>SHA256SUMS</nowiki></code>의 상위 디렉터리가 한 개이고 원하는 시각의 복구 세트인지 확인한 뒤 <code><nowiki>scripts/restore.sh <그 디렉터리> --yes</nowiki></code>를 사용합니다. 운영 서버를 덮어쓰기 전에 격리 복원 시험을 먼저 수행합니다. === Lesson 내용 정기 감사 === 읽기 전용 감사 작업은 매주 운영 위키의 안정된 Lesson을 중앙 <code><nowiki>mcp-http</nowiki></code>에서 읽습니다. 실행 전 30분 안에 바뀐 Lesson은 다음 감사로 미룹니다. 별도 Lesson 저장소나 기준 파일을 만들지 않습니다. 쓰기 토큰도 사용하지 않습니다. 외부 근거 URL을 열거나 Lesson을 자동으로 수정하지 않습니다. 감사 작업은 다음 항목을 확인합니다. * 구조화된 근거가 없는 Lesson * <code><nowiki>high</nowiki></code> confidence인데 확인 범위가 약한 근거만 있는 Lesson * 확인 범위가 <code><nowiki>not_recorded</nowiki></code>인 근거 * 서로 같은 관찰·해석 또는 재사용 내용·적용 조건 * 대상이 없는 relation과 중복 relation * 365일 이상 바뀌지 않은 검토 후보 * 비밀 키나 토큰 형식으로 보이는 문자열 발견 결과에는 Lesson ID, revision ID와 <code><nowiki>codes</nowiki></code> 배열만 남깁니다. Lesson 본문, 인용과 relation note는 journal에 남기지 않습니다. 같은 Lesson의 발견 코드는 한 줄로 묶습니다. 오래된 Lesson이라는 이유만으로 틀렸다고 판정하지 않으며 <code><nowiki>stale_review_candidate</nowiki></code>로만 표시합니다. systemd 단위를 설치하고 첫 감사를 수동으로 실행합니다. <pre><nowiki> sudo install -D -m 0755 scripts/audit-lessons.py \ /usr/local/libexec/s3rm-content-audit sudo install -m 0644 deploy/systemd/s3rm-content-audit.service \ /etc/systemd/system/s3rm-content-audit.service sudo install -m 0644 deploy/systemd/s3rm-content-audit.timer \ /etc/systemd/system/s3rm-content-audit.timer sudo systemctl daemon-reload sudo systemctl start s3rm-content-audit.service sudo systemctl status s3rm-content-audit.service sudo journalctl -u s3rm-content-audit.service --since today sudo systemctl enable --now s3rm-content-audit.timer systemctl list-timers s3rm-content-audit.timer </nowiki></pre> 작업은 일요일 서울 시각 04:30 이후 30분 안에 실행합니다. 놓친 실행은 서버가 다시 켜졌을 때 실행합니다. 기본값은 서버의 기본 scan limit과 같은 200개 Lesson이며, 설정 가능한 절대 상한은 1000개입니다. Lesson당 근거·relation은 각각 최대 200개를 읽습니다. 서버의 <code><nowiki>scan_limit</nowiki></code>에서 목록이 잘리거나 감사 중 revision과 Lesson 목록이 바뀌면 완료로 기록하지 않습니다. 연결 오류나 동시 변경으로 끝나면 5분 간격으로 최대 세 번 시도합니다. 발견 사항을 뜻하는 종료 코드 <code><nowiki>2</nowiki></code>는 다시 시도하지 않습니다. 종료 코드는 다음과 같습니다. {| class="wikitable" ! 코드 !! 뜻 !! 다음 작업 |- | <code><nowiki>0</nowiki></code> || 감사를 완료했고 발견 사항이 없음 || 다음 예약 실행을 기다립니다. |- | <code><nowiki>1</nowiki></code> || 연결, 출력 한도 또는 동시 변경으로 감사를 완료하지 못함 || journal의 마지막 오류를 확인하고 다시 실행합니다. |- | <code><nowiki>2</nowiki></code> || 감사를 완료했고 확인할 항목이 있음 || 발견된 Lesson을 읽고 근거를 확인합니다. |} <code><nowiki>systemd</nowiki></code> 서비스는 임시 계정으로 실행합니다. 홈 디렉터리, <code><nowiki>.env</nowiki></code>, Docker 소켓과 <code><nowiki>/etc/s3-research-memory</nowiki></code>를 읽을 수 없습니다. 발견 사항이 있으면 실패 상태로 표시합니다. 이 상태는 Lesson을 바꾸지 않으며 다음 예약 실행도 막지 않습니다. 문제를 고칠 때는 근거를 먼저 붙인 뒤 같은 Lesson ID에 현재 revision을 기준으로 새 revision을 추가합니다. <code><nowiki>supersedes</nowiki></code>나 근거 note를 기존 주장 수정 수단으로 쓰지 않습니다. 예약과 무관하게 현재 상태를 확인할 때는 다음 명령을 사용합니다. 발견 사항이 있어도 수동 명령은 감사 완료 뒤 코드 <code><nowiki>0</nowiki></code>을 반환합니다. 자동 점검과 같은 종료 코드가 필요하면 <code><nowiki>--fail-on-findings</nowiki></code>를 추가합니다. <pre><nowiki> make audit-lessons </nowiki></pre> === 복원 전 주의 === <code><nowiki>scripts/restore.sh</nowiki></code>는 현재 DB, 업로드, 생성된 위키 설정을 교체합니다. 명시적인 <code><nowiki>--yes</nowiki></code>가 필요하며, 공지한 점검 시간에만 실행합니다. 병합이나 페이지 가져오기 도구가 아닙니다. 복원 전에 다음을 확인합니다. * 정확한 백업 디렉터리를 정하고 모든 checksum을 확인합니다. * 백업의 MediaWiki·애플리케이션 버전이 현재 checkout과 호환되는지 확인합니다. 새 DB를 더 오래된 코드에 복원할 수 없습니다. * 점검 시간을 알리고 <code><nowiki>mcp-http</nowiki></code>를 멈춘 뒤 브라우저 편집도 중단합니다. * 현재 상태를 읽을 수 있으면 복원 직전 백업을 하나 더 만듭니다. * <code><nowiki>.env</nowiki></code>에 복원할 인스턴스와 맞는 자격 증명이 있는지 확인합니다. * 복원을 결정한 사람과 이유를 기록합니다. === 현재 서버 복원 === 백업을 만든 것과 같은 저장소 버전에서 실행합니다. <pre><nowiki> docker compose stop mcp-http ./scripts/restore.sh /ABS/PATH/TO/BACKUP-DIRECTORY --yes </nowiki></pre> 스크립트는 checksum manifest, 백업 형식 버전, 압축 stream, 모든 아카이브 member의 경로와 종류를 먼저 확인합니다. 보조 파일이 있는 형식은 auxiliary manifest digest와 binary-log·source artifact도 모두 확인합니다. 백업의 DB 이름과 <code><nowiki>MARIADB_DATABASE</nowiki></code>도 같아야 합니다. 다르면 덤프를 편집하지 말고 복구용 <code><nowiki>.env</nowiki></code>를 맞춥니다. 이 검증과 이미지 빌드 사전 확인이 모두 끝난 뒤에만 애플리케이션을 멈추고 기준 DB·설정·업로드를 교체합니다. 기준 dump import는 <code><nowiki>sql_log_bin=0</nowiki></code> 세션에서 실행합니다. 이어서 DB를 멈추고 기존 <code><nowiki>db_binlogs</nowiki></code>의 '''더 새로운 운영 timeline을 비운 뒤''' 새 local timeline으로 시작합니다. 따라서 과거 DB에 미래 binlog가 이어지는 일은 없지만, backup의 archived binlog를 자동 replay하지도 않습니다. PITR이 필요하면 운영 복원 전에 별도 격리 환경에서 목표 UTC·종료 position을 정해 검증한 절차로만 적용합니다. <code><nowiki>mediawiki</nowiki></code> 시작 때 MediaWiki·확장 기능 마이그레이션을 적용하고, 이어서 반복 실행이 가능한 <code><nowiki>bootstrap</nowiki></code>과 bounded <code><nowiki>mediawiki-jobs</nowiki></code>를 차례로 시작해 worker health까지 확인합니다. 교체 경고가 나온 뒤에는 중단하지 마세요. 오류가 나오면 클라이언트를 멈춘 상태로 로그와 소스 백업을 보존합니다. 실패한 상태 위에 부분 SQL이나 일부 볼륨을 임의로 덮어쓰지 마세요. 완료 뒤 상태를 확인합니다. <pre><nowiki> docker compose ps -a docker compose logs mediawiki bootstrap mediawiki-jobs </nowiki></pre> 아래 MediaWiki 복구 확인을 마칠 때까지 <code><nowiki>mcp-http</nowiki></code>를 멈춰 둡니다. 확인 뒤 현재 설정으로 공용 어댑터를 다시 만들고, 공개 조회와 토큰 기반 변경을 모두 시험합니다. <pre><nowiki> docker compose up -d --force-recreate mcp-http docker compose ps mediawiki-jobs mcp-http docker compose logs --tail=100 mcp-http </nowiki></pre> === 격리 복원 시험 === 실제 서버를 덮어쓰지 말고 별도 Compose 프로젝트와 사용하지 않는 포트에서 시험합니다. 별도 checkout을 사용하고, 복구 디렉터리는 이동하지 말고 복사합니다. Compose 프로젝트와 볼륨 이름을 고유하게 지정하세요. 최상위 이름은 <code><nowiki>COMPOSE_PROJECT_NAME</nowiki></code>으로 바꿀 수 있으며 두 스크립트가 이 값을 사용합니다. <code><nowiki>COMPOSE</nowiki></code> 환경 변수에는 <code><nowiki>docker compose --ansi never</nowiki></code>처럼 고정 접두사를 넣을 수 있습니다. 설치, 백업, 복원에 같은 값을 사용하세요. 권장 경로는 전용 검증 스크립트입니다. 운영 <code><nowiki>.env</nowiki></code>가 아닌 mode <code><nowiki>0600</nowiki></code> 일회용 env에 사용하지 않는 loopback 포트, 일회용 DB·wiki 비밀번호, <code><nowiki>MW_SERVER_URL=http://127.0.0.1:18080</nowiki></code>과 <code><nowiki>S3RM_WIKI_BIND_ADDRESS=127.0.0.1</nowiki></code>, <code><nowiki>S3RM_HTTP_PORT=18080</nowiki></code>을 넣습니다. 복원용 <code><nowiki>S3RM_WIKI_BOT_PASSWORD</nowiki></code>도 <code><nowiki>openssl rand -hex 16</nowiki></code>으로 따로 만들고, 운영 BotPassword와 primary 위키 비밀번호를 재사용하지 않습니다. <pre><nowiki> chmod 0600 /srv/s3rm-restore-test.env ./scripts/verify-restore-isolated.sh /ABS/PATH/TO/BACKUP-DIRECTORY \ --env-file /srv/s3rm-restore-test.env \ --project-name s3rm-restore-2026q3 </nowiki></pre> 스크립트는 project 접두사, 새 project에 기존 컨테이너·볼륨이 없는지, loopback 주소, 기본 checksum과, 있는 경우 PITR 보조 checksum 체인을 '''변경 전''' 확인합니다. 격리 project 이름으로 전용 MediaWiki image tag를 만들어 운영 image tag를 동시에 다시 빌드하지 않습니다. 복원 후 Lesson 개수는 정확히 일치해야 하고, revision은 bootstrap이 관리 페이지 변경을 추가할 수 있으므로 백업 기록 '''이상'''이어야 합니다. MediaWiki API, bootstrap, bounded <code><nowiki>mediawiki-jobs</nowiki></code> health도 확인합니다. 성공하면 격리 볼륨을 지우고, 실패하면 진단을 위해 보존합니다. <code><nowiki>--keep</nowiki></code>을 사용하면 성공한 환경도 보존합니다. 이 검증은 스키마·개수·시작 경계를 자동 확인하지만, 아래의 사람이 열어 보는 대표 Lesson·업로드·검색 확인을 대신하지 않습니다. Docker가 설치된 일회용 VM에서는 다음 순서가 안전합니다. # 백업과 정확히 같은 저장소 revision, 복구 디렉터리, 복구용 <code><nowiki>.env</nowiki></code>를 VM에 복사합니다. # <code><nowiki>COMPOSE_PROFILES=</nowiki></code>로 실제 hostname과 80/443을 사용하지 않게 합니다. 겹치지 않는 <code><nowiki>S3RM_HTTP_PORT</nowiki></code>와 맞는 로컬 <code><nowiki>MW_SERVER_URL</nowiki></code>을 설정합니다. 별도 loopback <code><nowiki>S3RM_MCP_HTTP_PORT</nowiki></code>·<code><nowiki>S3RM_MCP_PUBLIC_URL</nowiki></code>과 일회용 MCP 토큰도 사용합니다. 실제 MCP URL이나 토큰을 복원 시험에 쓰지 마세요. # VM에서 <code><nowiki>scripts/restore.sh <backup-directory> --yes</nowiki></code>를 실행합니다. # 아래 복구 확인을 모두 수행합니다. # 결과를 기록한 뒤 VM을 지웁니다. 원본 복구 세트는 그대로 둡니다. <code><nowiki>docker compose config</nowiki></code>와 <code><nowiki>docker volume ls</nowiki></code>에서 볼륨 이름이 다른지 보기 전에는 <code><nowiki>COMPOSE_PROJECT_NAME</nowiki></code>만 바꿨다고 격리된 것으로 보지 마세요. === 복구 완료 확인 === 다음 항목을 모두 통과해야 복원이 끝납니다. # <code><nowiki>db</nowiki></code>, <code><nowiki>mediawiki</nowiki></code>, <code><nowiki>mediawiki-jobs</nowiki></code>가 healthy이고 <code><nowiki>mediawiki-install</nowiki></code>과 <code><nowiki>bootstrap</nowiki></code>이 코드 0으로 종료되었습니다. # <code><nowiki>Special:Version</nowiki></code>에 예상한 MediaWiki, Semantic MediaWiki, Page Forms, S3 Research Memory 버전이 표시됩니다. # Lesson 페이지 수와 최근 revision 수가 백업 기록과 맞습니다. # 복원된 Lesson의 필드, 근거, 관계, 출처, 호환 필드, 시간이 정상 표시됩니다. # '''역사 보기'''에서 이전 revision 하나 이상이 열립니다. # 업로드한 근거가 열리고, 외부 checksum을 기록했다면 값이 맞습니다. # 전문 검색이 알려진 제목과 본문 단어를 찾습니다. # 격리한 복원 시험 환경에서만 일반 브라우저 계정으로 Lesson 양식을 열고 복구 확인용 메모를 저장합니다. 바로 검색되는지 본 뒤 격리 환경과 함께 폐기합니다. # 다시 만든 <code><nowiki>mcp-http</nowiki></code>가 healthy입니다. 토큰 없이 초기화·도구 목록· <code><nowiki>search_lessons</nowiki></code>를 실행하면 짧은 인용 결과가 나옵니다. 쓰기 토큰을 넣은 클라이언트는 같은 격리 환경에 확인용 메모를 만들 수 있습니다. 운영 위키에는 확인용 데이터를 만들지 않습니다. # 따로 설정한 두 번째 클라이언트가 같은 Lesson을 조회합니다. 두 클라이언트가 로컬 데이터가 아닌 복원된 위키 하나를 보고 있어야 합니다. # MCP 계정은 여전히 삭제, 이동, 보호, 관리 기능을 사용할 수 없습니다. 복구 디렉터리, 소요 시간, 애플리케이션 revision, 결과, 실행자, 필요했던 조치를 기록합니다. 하나라도 실패하면 점검 상태를 유지합니다. === 평소 상태 확인 === 상태와 제한된 길이의 로그를 확인합니다. <pre><nowiki> docker compose ps -a docker compose logs --tail=200 db mediawiki-install mediawiki bootstrap \ mediawiki-jobs mcp-http caddy </nowiki></pre> 로컬 프로세스 경로와 두 공개 경로를 차례로 확인합니다. 로컬 확인만으로 다른 PC의 HTTPS 접속을 대신할 수 없습니다. <pre><nowiki> curl --fail --silent --show-error \ 'http://localhost:8080/api.php?action=query&meta=siteinfo&format=json' \ >/dev/null curl --fail --silent --show-error \ 'http://127.0.0.1:8765/healthz' \ | jq --exit-status \ '.canonical_store == "ok" and .write_admission.active >= 0 and .write_admission.waiting >= 0' \ >/dev/null curl --fail --silent --show-error \ 'https://s3wiki.yonsei.ac.kr/api.php?action=query&meta=siteinfo&format=json' \ >/dev/null </nowiki></pre> [[Help:S3 연구 메모리/설치와 검증#클라이언트를 연결하기 전 공용 MCP 확인|<code><nowiki>setup.md</nowiki></code>]]의 토큰 없는 MCP 초기화도 <code><nowiki>https://s3wiki.yonsei.ac.kr/mcp</nowiki></code>에서 실행합니다. 단순 <code><nowiki>GET /mcp</nowiki></code>는 streaming 연결을 계속 열어 둘 수 있으므로 상태 확인이 아닙니다. 같은 서버에서 위 확인을 한 번에 실행하려면 <code><nowiki>make verify-domain</nowiki></code>을 사용합니다. 이 결과만으로 학교 밖 인바운드 경로까지 확인되지는 않습니다. <code><nowiki>/healthz</nowiki></code>의 <code><nowiki>write_admission</nowiki></code>에는 비밀값 없이 현재 active·waiting·principal 수와 동시 실행·queue 상한이 나옵니다. 기본은 전체 동시 쓰기 8개, queue 64개·2초, principal별 지속 600회/분·burst 120입니다. <code><nowiki>open</nowiki></code> 모드에서는 client IP가 principal이므로 인증 모드를 바꾸지 않아도 사용자별 admission이 적용됩니다. 지표가 계속 상한에 붙거나 <code><nowiki>server_busy</nowiki></code>가 반복되면 DB latency와 실패 요청을 먼저 확인하고, 변경한 상한은 <code><nowiki>mcp-http</nowiki></code>를 다시 만들어 적용합니다. 이 queue는 재시작 뒤 작업을 복구하는 durable queue가 아닙니다. 전달된 IP는 Caddy와 MCP의 <code><nowiki>S3RM_MCP_PROXY_SECRET</nowiki></code>이 맞을 때만 신뢰합니다. 이 값을 교체할 때는 둘을 같은 Compose 재생성에서 함께 전환합니다. MediaWiki job queue는 전용 <code><nowiki>mediawiki-jobs</nowiki></code> 서비스가 기본 25건·20초, 1 process로 처리합니다. 상태 파일은 비밀 값이 없고 현재 queue 깊이, 마지막 성공 시각, 연속 실패 수를 담습니다. <pre><nowiki> docker compose ps mediawiki-jobs docker compose exec mediawiki-jobs cat /run/s3rm-jobs/status.env docker compose exec mediawiki-jobs /usr/local/bin/s3-mediawiki-jobs-health docker compose exec mediawiki \ php maintenance/run.php showJobs --group </nowiki></pre> runner가 실패하면 15초에서 시작해 최대 5분까지 지수 backoff합니다. 마지막 성공이 기본 120초보다 오래되면 health가 실패합니다. queue를 빠르게 비우기 위해 <code><nowiki>--nothrottle</nowiki></code>이나 다중 process를 임의로 사용하지 마세요. 먼저 실패 job 종류와 DB·디스크 상태를 확인하고, 필요한 처리량만 <code><nowiki>.env</nowiki></code>에서 조정합니다. Compose는 각 주요 서비스의 json-file 로그를 파일당 10MB, 최대 5개로 회전하고, PID·메모리·CPU 상한을 둡니다. 평소 사용량과 OOM·재시작 여부를 함께 확인합니다. <pre><nowiki> docker stats --no-stream docker inspect --format \ '{{.Name}} oom={{.State.OOMKilled}} restarts={{.RestartCount}}' \ $(docker compose ps -q) docker system df </nowiki></pre> 상한 도달은 health check 성공만으로 보이지 않을 수 있습니다. OOM이나 PID 부족을 확인한 뒤 queue·동시성·실패 loop 원인을 먼저 고치고, 측정한 정상 peak와 호스트 여유를 근거로 상한을 조정합니다. 로그 회전 파일은 장기 감사 자료가 아니므로 필요한 운영 event는 별도 제한된 저장소에 보관합니다. <code><nowiki>Special:RecentChanges</nowiki></code>, 계정 그룹, 로그인 실패, MCP 쓰기 인증 실패와 403/421, 디스크 여유 공간, 백업 시각, 복원 시험 상태를 확인합니다. <code><nowiki>bootstrap</nowiki></code>이 관리하는 스키마·양식 페이지가 반복해서 달라지면 원인을 찾으세요. 일반 Lesson revision은 <code><nowiki>bootstrap</nowiki></code>이 바꾸지 않습니다. === 공용 MCP 운영 === <code><nowiki>mcp-http</nowiki></code>에는 영구 지식이 없습니다. 정지하거나 다시 만들면 진행 중인 도구 호출이 끊기고 클라이언트가 재연결해야 하지만 Lesson이나 revision은 없어지지 않습니다. <pre><nowiki> docker compose stop mcp-http docker compose up -d mcp-http docker compose up -d --force-recreate mcp-http docker compose ps mcp-http </nowiki></pre> 일시적인 프로세스 오류에는 <code><nowiki>restart</nowiki></code>를 사용합니다. 토큰 해시, 공개 URL, bind·port, allowlist, 위키 자격 증명, 이미지를 바꿨다면 <code><nowiki>--force-recreate</nowiki></code>를 사용합니다. 공개 <code><nowiki>mcp-http</nowiki></code> 복제본을 여러 개 띄우지 마세요. 현재 서비스에는 load balancer나 session 공유 설계가 없습니다. 읽기 요청은 재연결 뒤 다시 시도해도 됩니다. 시간이 초과된 변경 요청은 결과를 먼저 확인한 뒤 다시 보내세요. === 공개 HTTPS === Caddy는 Compose <code><nowiki>domain</nowiki></code> 프로필에서 실행하며 공개 포트를 사용합니다. <pre><nowiki> docker compose ps caddy docker compose logs --tail=200 caddy docker compose up -d --force-recreate caddy make verify-domain </nowiki></pre> <code><nowiki>S3RM_PUBLIC_HOST</nowiki></code>나 저장소의 Caddyfile을 바꾼 뒤 Caddy를 다시 만듭니다. 인증서 발급을 다시 시도하려고 <code><nowiki>caddy_data</nowiki></code>를 지우지 마세요. 먼저 <code><nowiki>s3wiki.yonsei.ac.kr</nowiki></code>이 <code><nowiki>165.132.118.220</nowiki></code>을 가리키는지, 다른 프로세스가 80/443을 쓰는지, 두 포트가 외부에서 서버까지 들어오는지 확인합니다. Caddy는 원래 Host 헤더를 보존하며 MCP는 이를 <code><nowiki>S3RM_MCP_PUBLIC_URL=https://s3wiki.yonsei.ac.kr/mcp</nowiki></code>와 대조합니다. 학교 밖 네트워크의 브라우저 확인도 별도로 해야 합니다. ==== 공용 MCP 토큰 교체 ==== 이 파일럿은 토큰 해시 하나만 받으므로 교체 시 모든 쓰기 클라이언트의 기존 토큰이 한 번에 무효가 됩니다. 공개 조회는 계속됩니다. 변경이 잠시 끊긴다고 알리고 새 서비스 확인이 끝날 때까지 기존 <code><nowiki>client.env</nowiki></code>를 보관하세요. # 원문을 출력하지 않고 새 토큰과 해시를 만듭니다. ```bash ./scripts/configure-mcp-token.sh --rotate ``` 스크립트는 <code><nowiki>.env</nowiki></code>의 해시만 바꾸고, 원문 토큰과 URL은 mode <code><nowiki>0600</nowiki></code> <code><nowiki>~/.config/s3-research-memory/client.env</nowiki></code>에 씁니다. <code><nowiki>--rotate</nowiki></code>가 없으면 기존 토큰과 해시가 맞는지 확인하고 그대로 둡니다. # 공용 어댑터만 다시 만듭니다. ```bash docker compose up -d --force-recreate mcp-http docker compose ps mcp-http docker compose logs --tail=100 mcp-http ``` # 토큰 없이 초기화, 도구 목록, <code><nowiki>search_lessons(limit=1)</nowiki></code>을 확인합니다. 이어서 신뢰하는 셸에서 새 비공개 파일을 불러오고 [[Help:S3 연구 메모리/설치와 검증|<code><nowiki>setup.md</nowiki></code>]]의 쓰기 확인을 실행합니다. # 새 원문 토큰 또는 클라이언트 환경을 쓰기 클라이언트에 전달하고 재연결합니다. 공개 조회 클라이언트는 바꿀 것이 없습니다. DB·위키 비밀번호와 쓸 수 없는 토큰 해시가 든 서버 <code><nowiki>.env</nowiki></code>는 전달하지 마세요. 새 서비스를 확인하기 전에 문제가 생겼다면 이전 해시와 그에 맞는 비공개 토큰을 복구하고 <code><nowiki>mcp-http</nowiki></code>를 다시 만듭니다. 변경 인증을 끄는 방식으로 되돌리지 마세요. === 애플리케이션 업데이트와 되돌리기 === 업데이트 전에 이름을 붙인 백업을 만들고 복원을 시험합니다. 새 이미지를 빌드하고 DB 마이그레이션과 <code><nowiki>bootstrap</nowiki></code>을 완료한 뒤 복구 완료 항목을 확인합니다. 새 release가 DB를 마이그레이션했다면 이미지만 낮춰서는 안 됩니다. 이전 저장소 revision과 함께 업데이트 전 DB, 업로드, 설정을 한 세트로 복원해야 합니다. 기본 제약은 MediaWiki [https://www.mediawiki.org/wiki/Manual:Restoring_a_wiki_from_backup 복원 안내]와 [https://www.mediawiki.org/wiki/Manual:Upgrading 업그레이드 안내]를 참고하세요.
도움말:S3 연구 메모리/백업과 복원
문서로 돌아갑니다.