MySQL 4.0x에서 5.0으로 마이그레이션하기
웹 서버를 또 바꾸었다. 새 서버에는 MySQL 5.0이 설치되어 있었다. 덕분에 그동안 미뤄왔던 마이그레이션 작업을 해야 했다. 블로그 엔진 ExpressionEngine1과 웹 기반 RSS 리더 Gregarius2부터 마이그레이션해 봤다. 작업 과정을 간단히 정리해본다.
공통 작업
기존 MySQL 데이터를 내려 받아서 새 데이터베이스로 옮겨야 한다.
-
덤프 파일 내려받기
mysqldump -u{username} -p{password} {dbname} --default-character-set latin1 > {dump}.sql -
내려받은 덤프 파일의 텍스트 인코딩 변환하기
Iconv 같은 변환 도구를 사용하기도 하지만, 파일이 아주 크지는 않아서 텍스트 편집기를 사용했다. Notepad++3로 덤프 파일을 열어서 UTF-8로 다시 인코딩했다. -
덤프 파일 수정하기
우선 덤프 파일 첫 줄에 SET character set utf8;을 추가했다. 그리고 CREATE TABLE 구문 끝을 TYPE=MyISAM에서 TYPE=MyISAM DEFAULT CHARSET=utf8;로 바꾸었다. -
옮기기
mysql -u{username} -p{password} {dbname} < {dump}.sql
ExpressionEngine
키워드 모듈 수정하기
웹 브라우저에 다음과 같은 메시지가 출력됐다.
- MySQL ERROR:
- Error Number: 1054
- Description: Unknown column wt.weblog_id in on clause
- Query: SELECT DISTINCT wt.entry_id, SUM(if(keyword=test,1,0)) as threshold, title, url_title, ?? AS category_id FROM exp_weblog_titles wt, exp_keyword k LEFT JOIN exp_weblogs w ON wt.weblog_id = w.weblog_id LEFT JOIN exp_weblog_data wd ON wt.entry_id = wd.entry_id LEFT JOIN exp_members m ON m.member_id = wt.author_id LEFT JOIN exp_member_data md ON md.member_id = m.member_id LEFT JOIN exp_keyword_layers l ON l.layer_id = k.layer_id WHERE wt.entry_id=k.entry_id /* begin _build_where_query */ AND wt.entry_date < 1136085621 AND (wt.expiration_date = 0 || wt.expiration_date > 1136085621) AND w.is_user_blog = ?n? AND wt.status = ?open? /* end _build_where_query */ GROUP BY wt.entry_id HAVING threshold >= 1
MySQL ERROR: Error Number: 1054 Description: Unknown column wt.weblog_id in on clause Query: SELECT DISTINCT wt.entry_id, SUM(if(keyword=test,1,0)) as threshold, title, url_title, ?? AS category_id FROM exp_weblog_titles wt, exp_keyword k LEFT JOIN exp_weblogs w ON wt.weblog_id = w.weblog_id LEFT JOIN exp_weblog_data wd ON wt.entry_id = wd.entry_id LEFT JOIN exp_members m ON m.member_id = wt.author_id LEFT JOIN exp_member_data md ON md.member_id = m.member_id LEFT JOIN exp_keyword_layers l ON l.layer_id = k.layer_id WHERE wt.entry_id=k.entry_id /* begin _build_where_query */ AND wt.entry_date < 1136085621 AND (wt.expiration_date = 0 || wt.expiration_date > 1136085621) AND w.is_user_blog = ?n? AND wt.status = ?open? /* end _build_where_query */ GROUP BY wt.entry_id HAVING threshold >= 1
원인과 해결책은 Keyword Module progress5에 잘 나와있다. MySQL 5.0에서는 FROM exp_weblog_titles wt, exp_keyword k과 같이 비명시적으로 조인하는 것을 허용하지 않으니 FROM exp_weblog_titles wt INNER JOIN exp_keyword k과 같이 수정해야 한다. {EE system dir}/{modules}/{keyword}/mod.keyword.php 파일을 열어서 위와 같이 코딩된 부분을 전부 바꿔주면 된다.
???로 표시되는 웹 페이지
한글이 모두 깨져서 보였다. 이 문제도 역시 소스 코드를 수정해야만 해결된다. {EE dir}/db/db.mysql.php 파일을 연다.
- // Execute the query
- if ( ! $this->query_id = mysql_query($sql, $this->conn_id))
- {
- if ($this->debug)
- {
- return $this->db_error("MySQL ERROR:", $this->conn_id, $sql);
- }
- return FALSE;
- }
// Execute the query if ( ! $this->query_id = mysql_query($sql, $this->conn_id)) { if ($this->debug) { return $this->db_error("MySQL ERROR:", $this->conn_id, $sql); } return FALSE; }
위의 코드에 한 줄만 추가하면 된다.
- mysql_query('SET NAMES utf8');
- // Execute the query
- if ( ! $this->query_id = mysql_query($sql, $this->conn_id))
- {
- if ($this->debug)
- {
- return $this->db_error("MySQL ERROR:", $this->conn_id, $sql);
- }
- return FALSE;
- }
mysql_query('SET NAMES utf8'); // Execute the query if ( ! $this->query_id = mysql_query($sql, $this->conn_id)) { if ($this->debug) { return $this->db_error("MySQL ERROR:", $this->conn_id, $sql); } return FALSE; }
Gregarius 이전하기
ExpressionEngine과 마찬가지로 한글이 ???로 표시됐다. 마찬가지로 소스 코드를 수정했다. {gregarius dir}/cls/db/db.mysql.php 파일을 열어서 mysql_query('SET NAMES utf8'); 한 줄을 추가하면 끝이다.
- function rss_query ($query, $dieOnError=true, $preventRecursion=false) {
- mysql_query('SET NAMES utf8');
- $ret = mysql_query($query);
- if ($error = $this -> rss_sql_error()) {
- $errorString = $this -> rss_sql_error_message();
- }
function rss_query ($query, $dieOnError=true, $preventRecursion=false) { mysql_query('SET NAMES utf8'); $ret = mysql_query($query); if ($error = $this -> rss_sql_error()) { $errorString = $this -> rss_sql_error_message(); }
참고 문헌
Links
- http://www.pmachine.com/
- http://gregarius.net/
- http://notepad-plus.sourceforge.net/
- http://kaistizen.net/EE/index.php/weblog/comments/migrate_mysql_40x_to_50/#
- http://www.pmachine.com/forums/viewthread/27030/P108/
- http://www.abcseo.com/papers/utf8-expression-engine.htm