Migrate a phpBB3 forum to Discourse

실제로는 3.3 버전이므로, 해당 phpBB 버전과 스크립트가 호환되도록 PR이 들어오는 것을 기다리며 사전 작업을 진행 중입니다. 아니면 이전에 제안해 주신 버전 체크 수정 사항을 현재 스크립트에 적용해 보려 합니다.

그러면 xml_to_markdown.rb 파일을 작업해야 하나요?

2개의 좋아요

phpBB 3.3.x 포럼으로 테스트 가져오기를 시도해 보았지만 큰 실패로 끝났습니다. 자세한 내용은 나중에 이야기하겠습니다.

시도하는 과정에서 많은 것을 배웠고, 다른 가져오기 작업이나 phpBB 3.3용 가져오기 스크립트가 업데이트될 때 도움이 될 수 있을 것 같아 배운 내용을 공유하고자 합니다.

버전 확인을 우회하기 위해 /script/import_scripts/phpbb3/database/database.rb를 편집하거나, 사용자 정의 BBCode를 추가하기 위해 /script/import_scripts/phpbb3/support/bbcode/xml_to_markdown.rb를 편집해야 한다면, 다음 명령어로 가져오기를 시작한 후에야 편집해야 합니다:

/var/discourse/launcher enter import

이 시점에서 nano를 사용하여 파일을 편집할 수 있습니다.

phpBB 3.3 포럼에서 가져오기를 실행하려는 시도가 실패했기 때문에, 제 사용자 정의 BBCode 변경 사항이 실제로 효과가 있었을지는 확신할 수 없습니다. 하지만 phpBB 3.2+의 경우 위에서 언급한 대로 다음 파일을 편집하기만 하면 되는 것으로 보입니다:

/script/import_scripts/phpbb3/support/bbcode/xml_to_markdown.rb

그리고 다음과 같은 형식으로 정의를 추가하면 됩니다:

def visit_<대소문자를 구분하는 사용자 정의 BBCode를 여기에 입력>(xml_node, md_node)
  # 처리할 코드가 여기에 들어갑니다
end

다시 한번 말씀드리지만, 아직 이 부분을 테스트해 보지는 못했지만, 제가 가진 xml_to_markdown.rb 버전에는 없지만 phpBB에서 매우 흔한 사용자 정의 BBCode 중 하나는 다음과 같습니다:

[YouTube]{식별자}[/YouTube]

여기서 {식별자}는 YouTube URL의 쿼리 문자열에서 “v” 값입니다.

따라서 Ruby 초보자로서 xml_to_markdown.rb에 해당 코드를 추가하려는 제 시도는 다음과 같습니다:

def visit_YouTube(xml_node, md_node)
      content = xml_node.content
      url = "https://www.youtube.com/watch?v=" + content
      md_node.text = "#{url}"
      md_node.prefix_linebreaks = md_node.postfix_linebreaks = 2
      md_node.prefix_linebreak_type = LINEBREAK_HTML
end

마지막으로, 가져오기 스크립트를 실행했을 때 데이터베이스 로드 단계까지만 진행되었고, 다음과 같은 오류가 발생했습니다:

ERROR 1071 (42000) at line 1233035: Specified key was too long; max key length is 1000 bytes

이것이 DB 엔진 문제(원본은 InnoDB 사용)인지 아니면 다른 문제인지는 확실하지 않지만, phpBB 3.3 버전의 스크립트에서 이 문제가 해결될 것으로 추정합니다.

2개의 좋아요

음, 결국 이 문제를 그냥 둘 수 없었습니다.

수입(import) 스크립트로 이 에러를 처리할 수도 있겠지만, 제 생각에는 phpBB3의 데이터베이스 구조와 제 데이터베이스 정렬(Collation)이 UTF8라는 사실에서 비롯된 문제인 것 같습니다. 수입 스크립트를 실행할 때 다음과 같은 에러가 발생했습니다:

ERROR 1071 (42000) at line 1233035: Specified key was too long; max key length is 1000 bytes

phpbb_mysql.sql 파일의 1233035번째 줄을 확인해 보았을 때(로컬에 데이터 덤프 사본을 사용 중입니다), 다음과 같은 내용이 있었습니다:

ALTER TABLE `phpbb_config`
  ADD PRIMARY KEY (`config_name`),
  ADD KEY `is_dynamic` (`is_dynamic`);

phpbb_config 테이블의 config_name 컬럼을 살펴보니 VARCHAR(255)로 설정되어 있었습니다.

Stackoverflow의 이 게시물 덕분에 키 길이를 줄이기 위해 "접두사 인덱스(prefix index)"를 사용할 수 있다는 사실을 알게 되었습니다. 테스트해 보니 잘 작동했습니다.

제 phpBB 3.3.8 데이터베이스에서는 실제로 네 개의 테이블이 영향을 받았습니다:

  • phpbb_config
  • phpbb_config_text
  • phpbb_migrations
  • phpbb_oauth_accounts

다른 분들도 시도해 보고 싶으시다면, phpbb_config 테이블에 대한 단계는 아래와 같습니다. 나머지 테이블에 대한 쿼리는 문서末尾에 포함해 두었습니다.

다음 쿼리를 사용하여 접두사 인덱스의 최적 길이를 계산합니다:

SELECT
 ROUND(SUM(LENGTH(`config_name`)<10)*100/COUNT(`config_name`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`config_name`)<20)*100/COUNT(`config_name`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`config_name`)<50)*100/COUNT(`config_name`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`config_name`)<100)*100/COUNT(`config_name`),2) AS pct_length_100
FROM `phpbb_config`;

제 경우를 보면, 100%의 행이 50자 미만을 사용한다고 나타났으므로 데이터 덤프 파일을 편집했습니다:

nano /var/discourse/shared/standalone/import/data/phpbb_mysql.sql

그리고 Ctrl+W로 다음 문자열을 검색했습니다:

ALTER TABLE `phpbb_config`

그 다음, 이 부분을:

ALTER TABLE `phpbb_config`
  ADD PRIMARY KEY (`config_name`),
  ADD KEY `is_dynamic` (`is_dynamic`);

아래처럼 변경했습니다:

ALTER TABLE `phpbb_config`
  ADD PRIMARY KEY (`config_name`(50)),
  ADD KEY `is_dynamic` (`is_dynamic`);

여기서 (50)은 접두사 인덱스의 길이입니다.

제 경우, 나머지 세 테이블에 대해서도 최적의 접두사 키 길이를 얻기 위해 다음 쿼리를 사용하여 동일한 과정을 반복해야 했습니다:

SELECT
 ROUND(SUM(LENGTH(`config_name`)<10)*100/COUNT(`config_name`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`config_name`)<20)*100/COUNT(`config_name`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`config_name`)<50)*100/COUNT(`config_name`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`config_name`)<100)*100/COUNT(`config_name`),2) AS pct_length_100
FROM `phpbb_config_text`;

SELECT
 ROUND(SUM(LENGTH(`migration_name`)<10)*100/COUNT(`migration_name`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`migration_name`)<20)*100/COUNT(`migration_name`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`migration_name`)<50)*100/COUNT(`migration_name`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`migration_name`)<100)*100/COUNT(`migration_name`),2) AS pct_length_100
FROM `phpbb_migrations`;

SELECT
 ROUND(SUM(LENGTH(`provider`)<10)*100/COUNT(`provider`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`provider`)<20)*100/COUNT(`provider`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`provider`)<50)*100/COUNT(`provider`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`provider`)<100)*100/COUNT(`provider`),2) AS pct_length_100
FROM `phpbb_oauth_accounts`;

시간을 절약해 드리기 위해 나머지 테이블에 대한 검색 문자열도 아래에 제시합니다:

ALTER TABLE `phpbb_config_text`
ALTER TABLE `phpbb_migrations`
ALTER TABLE `phpbb_oauth_accounts`

완전히 해결되었다고 단언하긴 어렵지만, 위의 방법으로 초기 데이터베이스 에러는 해결되었고, 현재 수입 과정이 진행 중입니다:

#import_phpbb3.sh
The phpBB3 import is starting...

Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...

importing from phpBB 3.3.8

creating users
      722 / 5014 ( 14.4%)  [58 items/min]

업데이트:

수입 스크립트는 9시간 28분 만에 완료되었습니다. Screen이 참 고마웠습니다. 이 스크립트는 정말 훌륭합니다!

현재 후처리(Post-processing)가 진행 중입니다.

어딘가에 수입 스크립트의 출력 로그가 있는지, 아니면 제가 파일로 파이프(pipe)해야 하는 건가요?

3개의 좋아요

WSL에서 Docker 컨테이너로 discourse_dev를 실행할 때 phpbb3 가져오기에 어떤 절차를 사용해야 합니까?

저는 절차 1(Docker 컨테이너를 사용하여 가져오기)과 절차 2(개발 환경을 사용하여 가져오기)을 모두 시도해 보았습니다. 절차 1에서는 스크립트가 끝까지 실행되긴 했지만, 중간에 수많은 쿼리가 성공한 것처럼 보였음에도 불구하고 실제로 데이터가 포럼 데이터베이스에 저장되지 않았습니다. 가져오기가 discourse_dev 컨테이너와 별도로 자체 컨테이너에서 실행되기 때문에, 다른 데이터베이스에 데이터가 저장되고 있는 것은 아닐까요?

절차 2의 경우, 빌드 실행 자체가 불가능하며 "An error occurred while installing tiny_tds (2.1.5), and Bundler cannot continue."라는 오류 메시지와 함께 실패합니다.

WSL에서 ‘표준 설치’(Docker 미사용, 개발 환경 미사용)를 먼저 수행한 뒤 Docker 기반 가져오기를 진행해 볼까요?

1개의 좋아요

제가 추천하는 방법입니다. 더 이상 개발 환경에서 마이그레이션을 거의 수행하지 않습니다.

또한, mysql/mariadb 대신 mssql을 사용하지 않는 한 tiny_tds는 필요하지 않습니다.

1개의 좋아요

제이, 정말 감사드립니다. 튜토리얼이 딱 필요할 때 정확히 도움되는 내용이라 정말 감사해요.

2개의 좋아요

새 VPS에서 표준 Docker 설치 과정을 사용하여 Discourse를 성공적으로 설치했습니다. 이후 해당 설명에 따라 가져오기(import) 과정을 실행했고, 스크립트는 문제 없이 완료되었습니다. 컨테이너를 종료한 후 stop import를 실행하니 다음과 같은 메시지가 나타났습니다:

''디스크 /var/lib/docker가 위치한 디스크의 여유 공간이 5GB 미만입니다. 계속 진행하려면 더 많은 공간이 필요합니다.
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 24G 20G 2.7G 89% /

시스템의 docker 이미지와 컨테이너를 정리하여 공간을 확보해 보시겠습니까? (y/N)‘’

공간을 복구해도 추가적인 공간이 확보되지 않았습니다. 이제 어떻게 진행해야 할까요? /data에 업로드한 모든 이미지 파일을 안전하게 삭제할 수 있을까요? 여전히 필요한지 확실하지 않습니다.

감사합니다.

1개의 좋아요

가져오기가 끝난 것 같고, 가져와야 할 이미지들에 대해 이야기하고 있다면 문제없을 것입니다. 하지만 백업을 만들기에 공간이 부족할 가능성이 큽니다. 더 많은 공간을 확보하도록 드롭렛을 업그레이드하는 것이 좋습니다. 하루 요금은 큰 문제가 되지 않을 것입니다.

1개의 좋아요

이 조언을 주셔서 감사합니다, Jay.

이 세부 정보가 다른 분들께 도움이 될 수 있으므로, 이미지 파일(오직 그것만)을 제거했는데, 이로 인해 약 3.4GB가 해제되어 총 6.1GB의 사용 가능 공간이 확보되었습니다. 이후 Sidekiq가 후처리(post-processing)를 성공적으로 완료했습니다. 이후 디스크 공간은 추가로 20GB가 증설되었습니다.

기록을 위해 말씀드리면, 이번 임포트는 phpBB 버전 3.3.0 메시지 보드였으며, 약 8,000개 이상의 주제(topic)에 약 73,000개 이상의 게시글과 약 1,300명 이상의 사용자가 포함되어 있었습니다.

현재까지 발견한 유일한 문제는 일부 사용자 이름이 처리하기 까다롭다는 점이지만, 이는 앞서 논의된 사항이며 치명적인 문제가 아닙니다.

이번 임포트와 소스 phpBB 포럼의 폐쇄 사이에 간격이 있을 예정입니다. 임포트용 Docker 컨테이너를 그대로 유지해 두고, 이후 이 컨테이너를 사용하여 이번 임포트 이후에 작성된 게시글을 증분 백업(incremental backup) 방식으로 마이그레이션할 수 있을까요?

1개의 좋아요

저는 phpBB 3.3.x 마이그레이션을 수행할 때, 최종 가져오기를 위해 phpBB 사이트를 '유지보수 모드’로 전환하고 rsync를 사용해 첨부 파일, 아바타, 이모티콘을 업데이트한 뒤 새로운 데이터 덤프를 가져왔습니다. 그리고 가져오기 스크립트의 최종 실행을 위해 가져오기를 다시 구성해야 했으나, 그 전에 이미 가져오기를 종료해 둔 상태였습니다.

@DonH 님, phpBB 비밀번호를 가져와서 ‘Migrate Passwords’ 플러그인과 함께 정상적으로 작동하도록 설정하셨나요?

2개의 좋아요

몇 가지 이유로 phpBB 비밀번호를 가져오지 않았습니다. 플러그인과의 잠재적인 충돌을 원치 않았고, 사람들이 비밀번호를 업그레이드하도록 강제하고 싶었습니다. 이번 마이그레이션은 이를 위한 좋은 방법(그리고 좋은 핑계)으로 보였습니다. phpBB 웹 호스트의 보안은 호스팅 회사가 담당했지만, 새로운 VPS에는 그런 특권이 없습니다.

정리하자면, 데이터베이스 전체를 마지막으로 한 번만 다시 가져왔고, 증분 업데이트는 하지 않은 것이 맞습니까?

1개의 좋아요

제 이해와 경험에 따르면, phpBB 포럼의 데이터 덤프를(예: phpMyAdmin에서) 수행하여 파일을 /var/discourse/shared/standalone/import/data 디렉터리에 업로드하고, 가져오기를 다시 빌드한 다음 가져오기 명령을 다시 실행하면, 마이그레이션 스크립트는 이미 가져온 사용자 계정, 게시물 등에는 영향을 주지 않고 이전에 가져오지 않은 데이터베이스 항목에만 적용됩니다.

결론적으로 이는 일종의 증분 업데이트를 수행하지만 기존 항목에는 영향을 미치지 않으므로 일부 데이터가 손실될 수 있습니다. 예를 들어, 사용자가 이미 가져온 게시물을 수정했거나 이메일 주소를 변경한 경우 등이 해당됩니다.

1개의 좋아요

플러그인 설정인 migratepassword_allow_insecure_passwords를 체크하지 않으면, migratepassword 플러그인은 Discourse에서 안전하지 않다고 판단된 비밀번호의 마이그레이션을 허용하지 않습니다. 이는 최소 길이 및 고유 문자 수와 같은 모든 복잡성 설정을 준수합니다.

어떤 종류의 플러그인 충돌을 말씀하시는 지 정확히 알 수 없습니다.

2개의 좋아요

@RGJ migratepassword 플러그인이 phpBB 3.3에서 작동하나요?

지금 phpBB 3.3.8 포럼에서 가져오기를 진행 중인데, 비밀번호를 가져와서 테스트해 보고 있습니다.

1개의 좋아요

myBB에서 어떻게 마이그레이션을 할 수 있을까요?

1개의 좋아요

myBB와 태그 #migration::tag를 검색해 보면 #howto를 찾을 수 있을지도 모릅니다.

2개의 좋아요

네, 정보 감사합니다!

1개의 좋아요

Richard, 설명해 주셔서 감사합니다. 특정 충돌을 언급한 것이 아니라, 낯선 환경에서 예상치 못한 일이 발생할 수 있는 가능성을 말한 것입니다. 플러그인을 추가하기 전에 의도적으로 가져오기를 수행했습니다. 하지만 무엇보다도 회원들이 비밀번호를 업그레이드하도록 유도하는 것이 목적입니다.

이번 마이그레이션은 정말 문제없이 잘 진행되었으니, 잘 다듬어진 스크립트를 만들어 주신 Gerhard와 모든 관련자에게 감사드립니다. 새로운 게시판에 맞게 조정하는 작업을 기대하고 있습니다.

2개의 좋아요

네, 호환됩니다. 최근 해당 플러그인에 Argon2 지원을 추가했습니다.

4개의 좋아요

Richard는 자신의 호스팅에서 해당 플러그인을 지원합니다. 플러그인으로 인해 문제가 발생했다는 이야기를 들어본 적이 없습니다. 많은 가져오기 도구가 비밀번호를 가져오며, 그냥 작동합니다. 제가 작성한 다른 무작위 포럼용 가져오기 스크립트에서도 작동하도록 한 적이 있습니다.

1개의 좋아요