티스토리 뷰

문제점

XE에서 MySQL Replication 구성하여 Master, Slave 두개의 디비를 사용할 경우, 쓰기는 Master를, 읽기는 Slave를 사용하도록 돼 있다. 하지만 MySQL Replication에서는 Master와 Slave 간에 비동기 방식으로 데이터를 동기화하기 때문에 데이터가 동일하다고 보장할 수 없다. 그로 인해 문제가 발생한다.

예를 들어 어떤 글 'A'에 댓글을 하나 달았다고 생각해보자.

  1. 댓글 등록을 요청받는다.
  2. 요청된 댓글을 master db에 쓰기(insert)
  3. <master -> slave sync>
  4. slave db에 A에 달린 댓글수 질의(select count(*))
  5. 'A'글의 댓글수를 master db에 재기록(update)

위의 과정에서 정상적으로 작동하려면 2번이 실행된 후 4번이 실행되기 전에 master와 slave가 sync가 이루어져 slave에도 댓글이 등록돼야 한다. 하지만 sync가 4번보다 늦게 이루어 질 경우, 4번과정에서 정확한 댓글수를 가져오지 못한다.(실제댓글수-1을 가져온다.)

해결법

읽기 작업시 자동으로 XE가 알아서 master, slave를 구분하도록 하는 것은 불가능하다. 일일이 소스코드를 수정하는 방법이 맘 편하다. 위에서 예로 든 '댓글 작성후 댓글수 갱신'과 같이 쓰기 요청후 곧바로 읽기 요청을 하는 경우, 읽기 요청에서 slave 대신 master db를 사용하도록 직접 소스코드를 수정한다. 수정하는 방법으로는 아래의 방법을 제안한다. 아래와 같이 파일 두 곳(func.inc.php, DB.class.php)에 코드를 작성/수정한다.

     /* config/func.inc.php에 아래코드 추가 */

    function useMasterDB($use=true)
    {
    	$GLOBALS['use_master_db'] = $use;
    }
        
    function isMasterDBUsed()
    {
    	return $GLOBALS['use_master_db']===true?true:false;
    }
        /* class/db/DB.class.php의 _getConnection method */

        function _getConnection($type = 'master', $indx = NULL){
            if($type == 'master' || isMasterDBUsed()){ // 이 라인만 수정
                if(!$this->master_db['is_connected'])
                        $this->_connect($type);
                $this->connection = 'Master ' . $this->master_db['db_hostname'];
                return $this->master_db["resource"];
            }

            if($indx === NULL)
                $indx = $this->_getSlaveConnectionStringIndex($type);

            if(!$this->slave_db[$indx]['is_connected'])
                    $this->_connect($type, $indx);

            $this->connection = 'Slave ' . $this->slave_db[$indx]['db_hostname'];
            return $this->slave_db[$indx]["resource"];
        }

slave db 대신 master db에서 읽기를 수행해야 하는 소스코드가 있을 경우, 아래와 같이 useMasterDB(); useMasterDB(false);로 감싼다.  

	useMasterDB();
	$document = $oDocumentModel->getDocument($obj->document_srl, false, true, $columnList);
	useMasterDB(false);

코어를 수정해야 하고, 번거롭긴 하지만 어차피 코어가 수정되지 않는 한 해결할 수 없는 문제라고 판단된다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함