http://www.mysqlkorea.co.kr
Çѱ۸Ŵº¾ó 5.0 , Çѱ۸Ŵº¾ó 5.1 , MySQL 5.1 HA , »ç¿ëÀڸŴº¾ó
Advanced Knowle...  
¿£Áö´Ï¾î ³ëÆ®  
ºí·Î±×Á¸  
±Û·Î¹ú MySQL  
MySQL 5.5 GA  
MySQL 5.6 Developer  
ÃֽűÛ
foreign key ¼³Á¤¡¦
ÀÎÅØ½º Ãß°¡ µî¿¡¡¦
mysql master - s¡¦
´Ù´ë´Ù °ü°è¿¡¼­ ¡¦
mysql myÆÄÀϰú ¡¦
 
¹ÙÀ̳ʸ® ·Î±× API¿Í ¸®Çø®ÄÉÀÌ¼Ç ¸®½º³Ê
±Û¾´ÀÌ : taeguni   ³¯Â¥ : 11-10-11 14:54   Á¶È¸¼ö : 8135

¹ÙÀ̳ʸ® ·Î±× API¿Í ¸®Çø®ÄÉÀÌ¼Ç ¸®½º³Ê

ÀÌ ºí·Î±×´Â MySQL ¸®Çø®ÄÉÀÌ¼Ç ¸®½º³Ê ÆÐŰÁö¿¡ ÀÖ´Â ¹ÙÀ̳ʸ® ·Î±× API¿¡ ´ëÇÑ °ÍÀÔ´Ï´Ù. ¹ÙÀ̳ʸ® ·Î±× API¿Í ¸®Çø®ÄÉÀÌ¼Ç ¸®½º³Ê°¡ MySQL µ¥ÀÌÅͺ£À̽ºÀÇ Á÷°üÀûÀÎ °Ë»ö°ú ¹«½¼ »ó°üÀÌ ÀÖ´ÂÁö ÀǾÆÇմϱî? Change-Data-Capture(CDC)¶ó°í ºÒ¸®´Â ±â¼úÀ» ÀÌ¿ëÇÏ¿©, ¾î¶² ¿ÜºÎÀ妽º¿¡ ¾÷µ¥ÀÌÆ®¸¦ ÇÒ ¶§, ´ç½ÅÀº ¹ÙÀ̳ʸ® ·Î±×¸¦ »ç¿ëÇÒ ¼ö Àֱ⠶§¹®ÀÔ´Ï´Ù.
ÀÌ ºí·Î±×¸¦ Àаí ÀÖ´Â µ¶ÀÚ°¡ Àý´ë·Î Ãʺ¸ÀÚ°¡ ¾Æ´Ï¶ó°í °¡Á¤ÇÕ´Ï´Ù. MySQL ¸®Çø®ÄÉÀ̼ǿ¡ ´ëÇÏ¿© ÀÌÇØÇϰí, ¾à°£ÀÇ C++¿¡ ´ëÇÑ Áö½ÄÀÌ ÇÊ¿äÇÕ´Ï´Ù.
´ÙÀ½ µ¿¿µ»óÀ» º¸¸é, ¹ÙÀ̳ʸ® ·Î±× APIÀÇ ¹Ýº¹ÀûÀÎ ¾÷µ¥ÀÌÆ®¸¦ »ç¿ëÇÏ¿© MySQLÀÇ Å×ÀÌºí¿¡ Å×½ºÆ® Çʵ带 ãÀ» ¼ö ÀÖ´Â ÀαâÀÖ´Â ¿£ÅÍÇÁ¶óÀÌÁî °Ë»ö ÇÁ·Î±×·¥ÀÎ 'SOLR'·Î ¸¸µé¾îÁø °£´ÜÇÑ ÀÀ¿ëÇÁ·Î±×·¥ÀÇ °³³äÀ» º¸¿©ÁÙ °ÍÀÔ´Ï´Ù.
µ¿¿µ»óÀÇ ¿¹Á¦´Â Çà±â¹ÝÀÇ º¹Á¦(¸®Çø®ÄÉÀ̼Ç) À̺¥Æ®¸¦ »ç¿ëÇÕ´Ï´Ù. Çà±â¹Ý º¹Á¦´Â ÀϹÝÀûÀ¸·Î Ưº°ÇÑ ¿ëµµÀÇ µ¥ÀÌÅÍ ÀúÀå°ú ÇÔ²² MySQLÀ» ÅëÇÕÇϴ°ÍÀ» ½±°Ô ¸¸µé¾îÁÝ´Ï´Ù. ³ª´Â ¹ÙÀ̳ʸ® ·Î±×ÀÇ À̺¥Æ®°¡ ¹ß»ýÇÒ ¶§, ĸÃÄÇÏ°í ºÐ¼®ÇÏ´Â °ÍÀÌ ½±°Ô ¹ÙÀ̳ʸ® ·Î±× API·Î Á¢¸ñµÉ ¼ö ÀÖ´Ù°í »ý°¢Çß½À´Ï´Ù. ¾ÆÁ÷ ´õ Áö¿øÇؾßÇϰí, º¹Á¦ ¹× µ¥ÀÌÅÍ ÅëÇÕÀÇ »ç¿ë »ç·Ê´Â ¸¹Áö¸¸ ¾Æ¸¶µµ ¾ÆÁ÷ À̰ÍÀÌ ¹Ù¸¥ 뱡ÇâÀ» ã¾Æ°¡±â¿¡´Â À̸¥ ´Ü°èÀÏ ¼ö ÀÖ½À´Ï´Ù.

ÀüÁ¦Á¶°Ç

µ¥¸ð¸¦ º¹»çÇϱâ Àü¿¡, ½Ã½ºÅÛ ±¸¼ºÀ» ¾Ë¾Æ º¾½Ã´Ù.
  • ÃֽЏ®Çø®ÄÉÀÌ¼Ç ¸®½º³Ê¸¦ º¹»çÇÕ´Ï´Ù. MySQL Labs ¶Ç´Â º¹Á¦ ¼Ò½º·Î ºÎÅÍ ¹ÙÀ̳ʸ® ÆÄÀÏÀ» ´Ù¿î·Îµå ÇÕ´Ï´Ù.
  • ÃֽŠg++ (4.4 /4.5°¡ ÁÁ½À´Ï´Ù.)¿Í Boost 1.45 ¶Ç´Â ±× ÀÌ»ó ¹öÀü
  • OpenSSL
  • Cmake
  • Netbeans (¼±ÅûçÇ×)
  • Clucence
  • SOLR
  • Linux (¼±ÅûçÇ×)
  • MySQL 5.6
  • ´ë´ãÇÑ ÇØÄ¿ÀÇ ¸¶À½°¡Áü!

±âº» ¿¹Á¦

binlog API¸¦ »ç¿ëÇÏ·Á¸é Çì´õÆÄÀÏ¿¡ "binlog_api.h"¿Í, "libreplication" ¶óÀ̺귯¸®ÀÇ ¸µÅ©¸¦ Æ÷ÇÔÇØ¾ß ÇÕ´Ï´Ù.
API´Â ³×Æ®¿öÅ© ¶Ç´Â ÆÄÀÏ ½Ã½ºÅÛ ÅëÇØ¼­ ¹ÙÀ̳ʸ® ·Î±×¿¡ ¿¬°áÇÕ´Ï´Ù. CDCÀÇ ±¸ÇöÀ» À§Çؼ­, ³×Æ®¿öÅ©¸¦ ÅëÇØ¼­ ¼­¹ö¿¡ Á÷Á¢¿¬°áÇϸé, Á¤Àû ÆÄÀÏÀ» Àд °Íº¸´Ù ÈξÀ ´õ Àç¹ÌÀÖ´Â °ÍÀÌ µÇµµ·Ï ½ÃÀÛÇÒ ¼ö ÀÖ½À´Ï´Ù.
¾Æ·¡ ¿¹Á¦´Â ´Ü¼øÈ÷ ÁöÁ¤µÈ À§Ä¡¿¡¼­ ¹ÙÀ̳ʸ® ·Î±×¿¡ ¿¬°áÇÏ´Â ÇÁ·Î±×·¥ À强 ¹æ¹ýÀ» º¸¿©ÁÝ´Ï´Ù.
/* example1.cpp */
#include 
#include "binlog_api.h"
int main(int argc, char** argv){
  if (argc != 2)  {
    fprintf(stderr,"Usage:\n\treplaybinlog URL\n\nExample:\n\treplaybinlog mysql://root:mypasswd@127.0.0.1:3306\n\n");
    return (EXIT_FAILURE);
  }
  Binary_log binlog(system::create_transport(argv[1]));
  if (binlog.connect())
  {
    fprintf(stderr,"Can't connect to the master.\n");
    return (EXIT_FAILURE);
  }
  if (binlog.set_position(4) != ERR_OK)
  {
    fprintf(stderr,"Can't reposition the binary log reader.\n");
    return (EXIT_FAILURE);
  }
return EXIT_SUCCESS;
}
ÄÄÆÄÀÏ ÄÚµå »ç¿ë
% g++ example1.cpp -I/path/to/mysql-replication-listener/include/ -L/path/to/mysql-replication-listener/include/ -lreplication -lboost_system -o example1 
create_transport() helper ÇÔ¼ö´Â URLÀ» Àμö·Î ÇÏ¿©, Binary_log_driver °´Ã¼¸¦ ¹ÝȯÇÕ´Ï´Ù. À̰ÍÀº ³ªÁß¿¡ ¹ÙÀ̳ʸ® ·Î±×¿¡ ¿¬°áÇÒ ¼ö ÀÖ´Â Binary_log °´Ã¼¿¡¼­ »ç¿ëµË´Ï´Ù. ¿Â¶óÀÎ ³×Æ®¿öÅ© ¿¬°áÀ» À§Çؼ­ "mysql://username:pass@localhost:3365"°ú °°Àº °ÍÀ» ÀÔ·ÂÇϰí, Á¤Àû ÆÄÀÏÀ» ¿­¶÷Çϱâ À§Çؼ­ "file:///tmp/binlog.000001"°ú °°Àº Çü½ÄÀ» ÀÔ·ÂÇÕ´Ï´Ù.
´ÙÀ½À» ÀνÄÇÏ´Â µÎ °¡Áö Áß¿äÇÑ °³³äÀÌ ÀÖ½À´Ï´Ù.
  • À̺¥Æ® ·çÇÁ.
  • ÄÜÅÙÃ÷ Çڵ鷯 ÆÄÀÌÇÁ¶óÀÎ.
À̺¥Æ® ·çÇÁ´Â ´Ü¼øÈ÷ ÀϹÝÀûÀÎ GUI À̺¥Æ® ·çÇÁ¿Í °°ÀÌ ¸ðµç ÇÁ·Î±×·¡¸Ó¿¡°Ô »ó´çÈ÷ Ç¥ÁØÈ­ µÇ¾î¾ßÇÕ´Ï´Ù. »õ·Î¿î À̺¥Æ®°¡ °Ô½ÃµÇ¾î ÀÖ´ÂÁö È®ÀÎÇÏ°í ±×°ÍÀ» ½ÇÇàÇÏ¿© À̺¥Æ® ´ë±â¿­(Å¥)¿¡¼­ ¹Ð¾î³À´Ï´Ù.
¸¸¾à¿¡ ¿À¸¥ÂÊÀ¸·Î ¹Ð¾î³»´Â ÇÔ¼ö°¡ ÀÖ°í ±× ÇÔ¼öÀÌ ½ÇÇàµÇ¾úÀ»¶§, ²ø¾î³»±â(Pulling)´Â Ç×»ó Æí¸®ÇÑ °³¹ß ÆÐÅÏÀ̳ª ´õ ÁÁÀº ¹æ¹ýÀÌ µÉ ¼ö ¾ø½À´Ï´Ù. À̺¥Æ® Áß½ÉÀÇ (¶Ç´Â ºñµ¿±â½Ä) API³ª ÄÜÆ°Ã÷ Çڵ巯 ÆÄÀÌÇÁ¶óÀÎÀÇ ¶óÀ̺귯¸® ¾È¿¡¼­ ½ÇÇöµÇ´Â ÇÁ·Î±×·¥ ¹æ¹ý·ÐÀº Á¾Á¾ ¾ð±ÞµË´Ï´Ù.
°¢°¢ÀÇ ÄÜÅÙÃ÷ Çڵ鷯´Â ½ºÅÿ¡ ¹Ð¾î ³Ö°í ÇϳªÀÇ Çڵ鷯°¡ ÀçÀÛ¼º ÇÏ´Â °ÍÀ» °¡´ÉÇÏ°Ô Çϰųª, ¶Ç´Â ½ºÅÿ¡¼­ Çڵ鷯¸¦ ó¸® Çϱâ À§ÇØ ÇൿÇÏ´Â »õ·Î¿î À̺¥Æ®¸¦ ¸¸µì´Ï´Ù.
¾Æ·¡ÀÇ µ¿¿µ»ó ¿¹Á¦¿¡¼­ Äõ¸® ºÐ¼®À» À§ÇÑ ÄÜÅÙÃ÷ Çڵ鷯 À̺¥Æ®°¡ ½ºÅÿ¡ ¹Ð¾î ³Ö½À´Ï´Ù. ±¸¹® ±â¹Ý º¹Á¦¿¡ ´ëÇÑ Äõ¸®À̺¥Æ®°¡ »ç¿ëµÇ°í, ¼­¹ö¿Í ´Ù¸¥°Í »çÀÌ¿¡¼­ ½ÇÇàµÈ ½ÃÁ¦±¸¹®ÀÌ ÆäÀ̷ε忡 Æ÷ÇԵǾî ÀÖ½À´Ï´Ù.
´ÙÀ½ ¿¹Á¦¿¡¼­´Â SOLR ¿£ÅÍÇÁ¶óÀÌÁî °Ë»ö ¿£Áø¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸°Ú½À´Ï´Ù. ¿©±â¼­´Â ÀǵµÀûÀ¸·Î ¼¼¼¼ÇÑ ³»¿ëÀ» Á¦¿ÜÇϰÚÁö¸¸, ÁÖ ¸ñÀûÀº APIÀÇ ÀϹÝÀûÀÎ °³³ä°ú ±â´ÉÀ» ½Å¼ÓÇÏ°Ô Á¦°øÇÏ´Â °ÍÀÔ´Ï´Ù.

°í±Þ¿¹Á¦

´ÙÀ½ ¿¹Á¦¿¡¼­´Â SOLR ¿£ÅÍÇÁ¶óÀÌÁî °Ë»ö ¿£Áø¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸°Ú½À´Ï´Ù.
Çà ±â¹Ý º¹Á¦¿¡ ´ëÇÑ ¿É¼Ç°ú ÇÔ²² MySQL ¼­¹ö°¡ ½ÃÀ۵ǰí, clucene ¶óÀ̺귯¸®´Â MySQL ¼­¹ö¿¡¼­ ½Ç½Ã°£À¸·Î µ¥ÀÌÅ͸¦ ·ç¾À À妽º¿¡ ¾÷µ¥ÀÌÆ® ÇϱâÀ§Çؼ­ »ç¿ëµË´Ï´Ù.
³ª´Â clucene »ç¿ë¹æ¹ý¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀ» Æ÷ÇÔÇÏÁö´Â ¾ÊÁö¸¸, ¼Ò½º¿¡ °ü½ÉÀÌ ÀÖ´Ù¸é, ÀúÀå¼Ò¿¡ ÀÖ´Â ¿¹Á¦ ÆÄÀÏÀÇ ÀϺθ¦ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.
¾Æ·¡ÀÇ ÇÁ·Î±×·¥ ±¸Á¶´Â ¾Õ¿¡¼­ ¼³¸íÇÑ ÆÐÅÏÀ» µû¸¨´Ï´Ù: binlog °´Ã¼°¡ ÀÖ°í, À̺¥Æ® ·çÇÁ°¡ ÀÖ°í, ¾î¶² ¼±ÅÂµÈ À̺¥Æ®¿¡ ´ëÇÑ Æ®¸®°Å¸¦ °¡Áø ÄÜÅÙÃ÷ Çڵ鷯°¡ ÀÖ½À´Ï´Ù.
#include <stdlib.h>
#include <boost/foreach.hpp>
#include "binlog_api.h"
#include "table_update.h"
#include "table_delete.h"
#include "table_insert.h"
#include "table_index.h"
using mysql::system::create_transport;
using mysql::Binary_log;
std::string cl_index_file;
class Incident_handler : public mysql::Content_handler
{
public:
 Incident_handler() : mysql::Content_handler() {}
 Binary_log_event *process_event(mysql::Incident_event *incident)
 {
   std::cout << "Event type: "
             << mysql::system::get_event_type_str(incident->get_event_type())
             << " length: " << incident->header()->event_length
             << " next pos: " << incident->header()->next_position
             << std::endl;
   std::cout << "type= "
             << (unsigned)incident->type
             << " message= "
             << incident->message
             <<  std::endl
             <<  std::endl;
   /* Consume the event */
   delete incident;
   return 0;
 }
};
class Applier : public mysql::Content_handler
{
public:
 Applier(Table_index *index)
 {
   m_table_index= index;
 }
 mysql::Binary_log_event *process_event(mysql::Row_event *rev)
 {
   boost::uint64_t table_id= rev->table_id;
   Int2event_map::iterator ti_it= m_table_index->find(table_id);
   if (ti_it == m_table_index->end ())
   {
     std::cout << "Table id "
               << table_id
               << " was not registered by any preceding table map event."
               << std::endl;
     return rev;
   }
   /*
    Each row event contains multiple rows and fields. The Row_iterator
    allows us to iterate one row at a time.
   */
   mysql::Row_event_set rows(rev, ti_it->second);
   /*
    Create a fuly qualified table name
   */
   std::ostringstream os;
   os << ti_it->second->db_name << '.' << ti_it->second->table_name;
   mysql::Row_event_set::iterator it= rows.begin();
   do {
     mysql::Row_of_fields fields= *it;
     if (rev->get_event_type() == mysql::WRITE_ROWS_EVENT)
       table_insert(os.str(),fields);
     if (rev->get_event_type() == mysql::UPDATE_ROWS_EVENT)
     {
       ++it;
       mysql::Row_of_fields fields2= *it;
       table_update(os.str(),fields,fields2);
     }
     if (rev->get_event_type() == mysql::DELETE_ROWS_EVENT)
       table_delete(os.str(),fields);
     } while (++it != rows.end());
     /* Consume the event */
     delete rev;
     return 0;
  }
private:
  Table_index *m_table_index;
};
int main(int argc, char** argv)
{
  if (argc != 3)
  {
    fprintf(stderr,"Usage:\n\nmysql2lucene URL\n\nExample:\n\nmysql2lucene mysql://root@127.0.0.1:3306 myindexfile\n\n");
    return (EXIT_FAILURE);
  }
  Binary_log binlog(create_transport(argv[1]));

  cl_index_file.append (argv[2]);
  /*
    Attach a custom event content handlers
  */
  Incident_handler incident_hndlr;
  Table_index table_event_hdlr;
  Applier replay_hndlr(&table_event_hdlr);
  binlog.content_handler_pipeline()->push_back(&table_event_hdlr);
  binlog.content_handler_pipeline()->push_back(&incident_hndlr);
  binlog.content_handler_pipeline()->push_back(&replay_hndlr);
  if (binlog.connect())
  {
    fprintf(stderr,"Can't connect to the master.\n");
    return (EXIT_FAILURE);
  }
  binlog.set_position("searchbin.000001", 4);
  bool quit= false;
  while(!quit)
  {
    /*
     Pull events from the master. This is the heart beat of the event listener.
    */
    Binary_log_event  *event;
    binlog.wait_for_next_event(&event);
    /*
     Print the event
    */
    std::cout << "Event type: "
              << mysql::system::get_event_type_str(event->get_event_type())
              << " length: " << event->header()->event_length
              << " next pos: " << event->header()->next_position
              << std::endl;
    /*
     Perform a special action based on event type
    */
    switch(event->header()->type_code)
    {
    case mysql::QUERY_EVENT:
      {
        const mysql::Query_event *qev= static_cast(event);
        std::cout << "query= "
                  << qev->query
                  << " db= "
                  << qev->db_name
                  <<  std::endl
                  <<  std::endl;
        if (qev->query.find("DROP TABLE REPLICATION_LISTENER") != std::string::npos)
        {
          quit= true;
        }
      }
      break;
    case mysql::ROTATE_EVENT:
      {
        mysql::Rotate_event *rot= static_cast(event);
        std::cout << "filename= "
                  << rot->binlog_file.c_str()
                  << " pos= "
                  << rot->binlog_pos
                  << std::endl
                  << std::endl;
      }
      break;
    } // end switch
    delete event;
  } // end loop
  return (EXIT_SUCCESS);
}
ÀÌ Äڵ带 À¯¿ëÇÏ°Ô »ç¿ëÇÒ·Á¸é, SOLR À¥ ¼­ºñ½º¿Í MySQL 5.6¼­¹ö¿Í µ¥ÀÌÅͺ£À̽º¿¡ ÀÔ·ÂÀ» °ø±ÞÇÏ´Â ¸î¸î MySQL clientÀ» ½ÇÇàÇØ¾ß ÇÕ´Ï´Ù. ¶ÇÇÑ lucene À妽º¸¦ ÀúÀåÇÒ À§Ä¡¸¦ ÁöÁ¤ÇÏ¾ß ÇÕ´Ï´Ù.
Çà±â¹Ý ¸®Çø®ÄÉÀ̼Ç(--binlog_format=row)°ú "searchbin"°ú °°Àº ¹ÙÀ̳ʸ® ·Î±×ÀÇ ±âº»¸í(--log_bin=searchbin)À» »ç¿ëÇÏ¿© MySQL ¼­¹ö¸¦ ½ÇÇàÇÒ ¼ö ÀÖ´ÂÁö È®ÀÎÇØ¾ßÇÕ´Ï´Ù. MySQL 5.6 ¼Ò½ºÄڵ带 ´Ù¿î·Îµå ÇÏ¿´À» °æ¿ì¿¡´Â mysql-test µð·ºÅ丮¿¡ ÀÖ´Â Å×½ºÆ® µµ±¸ÀÎ 'MTR'À» »ç¿ëÇÏ¿© ½±°Ô ¾Ë ¼ö ÀÖ½À´Ï´Ù. ´Ü¼øÇÑ À¯Çü:
% ./mtr --start alias --mysqld=--log_bin=searchbin --mysqld=--binary_log=row
ÄÝ¼Ö ½ÇÇàÁß¿¡¼­ SOLR Ç÷§ÆûÀ» ¾òÀ»·Á¸é, SOLR ¸Å´º¾óÀ̳ª ¼Ò½ºÆÐŰÁöÀÇ ¿¹Á¦µð·ºÅ丮¿¡¼­ À̰ÍÀ» ½ÇÇàÇÕ´Ï´Ù.
% java -jar start.jar
¶ÇÇÑ clucene À妽ºÀÇ À§Ä¡¸¦ ÁöÁ¤ÇÏ´Â °ÍÀ» ÀÖÁö ¸»¾Æ¾ß ÇÕ´Ï´Ù.
Applier Ŭ·¡½º´Â ¸î°¡Áö Ãß°¡ ¼³¸íÀÌ ÇÊ¿äÇÕ´Ï´Ù. Çà ±â¹ÝÀ¸·Î À̺¥Æ®¸¦ ±¸¹® ºÐ¼®Çϴ ŪÈ÷ ÀÌ ºÎºÐÀÌ´Ù. ±× ¾Æ·¡ ´õ ¸¹Àº °Íµé:

¿­ ±â¹Ý À̺¥Æ® ºÐ¼®

¸®Çø®ÄÉÀÌ¼Ç ½ºÆ®¸²À¸·Î ºÎÅÍ µ¥ÀÌÅ͸¦ ¹Þ¾Æ¿Ã ¶§, µ¥À̺í À̸§, Çõå Çü½Ä ¹× À¯¿ëÇÑ ÇüÅ×ÀÇ ½ÇÁ¦ µ¥ÀÌÅÍ¿Í °°Àº °ÍµéÀº ¾î¶»°Ô ÃàÃâÇմϱî?
¹ÙÀ̳ʸ® ·Î±× ÇÁ·ÎÅäÄÝ¿¡ ´ëÇÑ ¼³¸íÀº MySQL forge¿¡ À§Ä¡Çϰí ÀÖ½À´Ï´Ù. ¼¼ºÎ»çÇ׿¡ ´ëÇÏ¿© ÀÚ¼¼È÷ ¾Ë°í ½Í´Ù¸é, MySQL forge´Â Á¤º¸ÀÇ ¿øÃµÀÏ °ÍÀÔ´Ï´Ù.
¿©±â¼­´Â ¼¼ºÎ»çÇ×À» »ý·«Çϰí, MySQLÀÇ ¼¼Á¾·ùÀÇ Çà±â¹Ý À̺¥Æ® ¾Ë¾Æ º¼ °ÍÀÔ´Ï´Ù.
  • UPDATE_ROWS_EVENT
  • DELETE_ROWS_EVENT
  • INSERT_ROWS_EVENT
°¢°¢ÀÇ ·¹À̾ƿôÀº ¸Å¿ì À¯»çÇÕ´Ï´Ù. ¿ì¼± ¸ðµç À̺¥Æ®¿¡¼­ µ¿ÀÏÇÑ Ç¥ÁØ Çì´õ°¡ ÀÖ½À´Ï´Ù.
class Log_event_header
{
public:
uint8_t reserved;
uint32_t timestamp;
uint8_t type_code;
uint32_t server_id;
uint32_t event_length;
uint32_t next_position;
uint16_t flags;
};
ÇàÀÇ Æ¯Á¤ÇÑ µ¥ÀÌÅÍ´Â ´ÙÀ½°ú °°½À´Ï´Ù.
class Row_event: public Binary_log_event
{
public:
uint64_t table_id;
uint16_t flags;
uint64_t columns_len;
uint32_t null_bits_len;
vector used_columns;
vector row;
[..]
};
¾Ë°íÀÖµíÀÌ, 'row' ¹éÅÍ·Î ºÎÅÍ ½ÇÁ¦ µ¥ÀÌÅ͸¦ °¡Áö°í ¿À´Â °ÍÀº ±×¸® Æò¹üÇÏÁö ¾Ê½À´Ï´Ù. ¿ì¸®ÀÇ ÇÁ·Î±×·¥ÀÌ »ç¿ëÇÒ ¼ö À־ ¹«¾ð°¡·Î °ªÀ» ÃàÃâÇÒ ¼ö ÀÖ´Â ÆÄ¼­¿Í °°Àº °ÍÀÌ ÇÊ¿äÇÕ´Ï´Ù.
¸®Çø®ÄÉÀ̼ǿ¡ »ç¿ëµÇ´Â µ¥ÀÌÅ͸ðµ¨Àº °¡º­¿î °ª °´Ã¼ ÁÖÀ§¿¡ ±¸ÃàµÇ°í, ¾î¶² °ªÀº Row_of_fields·Î º¤ÅÍ Ä÷º¼Ç¿¡ ÀúÀåµË´Ï´Ù. °¢°¢ÀÇ Row_of_fields´Â Row_event_setÀÇ ÀϺÎÀÔ´Ï´Ù.
´Ù½ÃÇѹø óÀ½ºÎÅÍ »ìÆìº¸°Ú½À´Ï´Ù.
°¢°¢ÀÇ ÇàÀº Row_event_setÀ̶ó°í ºÒ¸®´Â ¿©·¯ Çà°ú Çʵå·Î ±¸¼ºµÇ¾î ÀÖ½À´Ï´Ù. Row_iterator´Â ¿ì¸®¿¡°Ô Çѹø¿¡ Çϳª¾¿ °¢°¢ÀÇ ÇàÀ» ¹Ýº¹ÇÏ´Â °ÍÀ» °¡´ÉÇÏ°Ô ÇÕ´Ï´Ù.
if (row_event->header()->type_code= UPDATE_ROWS_EVENT)
{
[..]
  Row_event_set rows(row_event, table_map_event);
  Row_event_set::iterator it= rows.begin();
Àá±ñ! table_map_eventÀº ¹«¾ùÀԴϱî? ±×°ÍÀº, °¢°¢ÀÇ Æ®·£Á§¼Ç°ú ¸ðµç Row event Àü¿¡ ¼­¹ö¿¡ »ç¿ëµÇ´Â Å×ÀÌºí¿¡ ´ëÇÑ Á¤º¸¸¦ ¼±¾ðÇÑ descript-xor events¸¦ Àü´ÞÇÕ´Ï´Ù. ÀÌÁ¦ Å×ÀÌºí ´ë½Å Å×À̺í À̸§, µ¥ÀÌÅͺ£À̽º, ¸ðµç ´ÜÀÏ row event¿¡ ÀÖ´Â Àüü Çʵ尡 À妽º·Î ÂüÁ¶µÉ ¼ö Àֱ⶧¹®¿¡ ÁÁ½À´Ï´Ù. ¹°·Ð ¿ì¸®´Â ¸ÕÀú À妽º¸¦ ±¸ÃàÇØ¾ß ÇÕ´Ï´Ù. ¹°·Ð ¸ÕÀú À妽º¸¦ ±¸ÃàÇØ¾ßÇÕ´Ï´Ù. ¿À·¡ °É¸®Áö ¾ÊÀ»Å×´Ï Àá½Ã ±â´Þ·Á ÁÖ¼¼¿ä.

table mapÀ¸·Î ºÎÅÍÀÇ À妽º ±¸Ãà

¸ÕÀú map content ÄÜÅÙÃ÷ Çڵ鷯¸¦ µî·ÏÇϰí, ±×°ÍÀ» ½ºÅØ¿¡ ÀúÀåÇÕ´Ï´Ù. table map À̺¥Æ®¿¡ table_id¸¦ Ç¥ÁØ STL Áöµµ·Î »ç¿ëÇÕ´Ï´Ù.
class Table_map_handler : public Content_handler
{
  public:
  Binary_log_event *process_event(Table_map_event *event)
  {
    m_table_map.insert(Event_index_element(event->table_id,tm));
    /*
      Eat this event instead of passing it
      on to the next handler.
    */
    return NULL;
  }
  std::map m_table_map;
}
[..]
/* create an instance of the handler */
Table_map_handler table_index;
/* push content handler to stack */
binlog.content_handler_pipeline()->push_back(&table_index);
[..]
°¢°¢ÀÇ row event´Â ´ÙÀ½ º¯°æ Å×ÀÌºí¿¡ ´ëÇÑ À妽º¸¦ Æ÷ÇÔÇÕ´Ï´Ù:
[..]
/* get table id from the recently captured row event */
boost::uint64_t table_id= row_event->table_id;
Table_map_event *table_map_event=
table_index.m_table_map[table_id];
[..]
ÀÌÁ¦ Çà ¹Ýº¹À» Çϱâ À§ÇØ ÇÊ¿äÇÑ table map À̺¥Æ®°¡ »ý°å½À´Ï´Ù!
basic_transaction_parser.cpp ÆÄÀÏÀº ¾î¶² Æ®·£Á§¼Ç ±â°£ µ¿¾ÈÀÇ Áý°è table map ÄÜÅÙÃ÷ Çڵ鷯°¡ Æ÷ÇԵǾî ÀÖ½À´Ï´Ù. ´õ À¯¿ëÇÑ Å×À̺íÀε¦¼­¸¦ ±¸ÃàÇϱâ À§Çؼ­ ÀÌ¿Í °°Àº ¿¹Á¦¸¦ »ç¿ëÇÕ´Ï´Ù.

¹Ýº¹ÀÇ ¸¶Áö¸· Çà

ÀÏ´Ü ¸ðµç ÇàÀ» ¹Ýº¹ÇÏ´Â °ÍÀÌ °¡´ÉÇÑ Row_iterator¸¦ ¸¸µé¾ú½À´Ï´Ù.
Row_event_set rows(row_event, table_map_event);
do {
  Row_of_fields fields= *it;
  if (event->get_event_type() == UPDATE_ROWS_EVENT)
  {
    ++it;
    Row_of_fields fields2= *it;
    table_update(os.str(),fields,fields2);
  }
[..]
} while (++it != rows.end());
Row_of_fields Ŭ·¡½º´Â ¿ì¸®¿¡°Ô Çѹø¿¡ ÇϳªÀÇ Çʵ带 ¹Ýº¹ÇÏ´Â °ÍÀ» °¡´ÉÇÏ°Ô ÇÕ´Ï´Ù.
void table_update (const string& table_name,
Row_of_fields &old_fields,
Row_of_fields &new_fields
{
  int field_id= 0, string str;
  Row_of_fields::iterator
  field_it= new_fields.begin();
  Converter converter;
  do {
    converter.to(str, *field_it);
    cout << field_id << "= " << str;"
    ++field_it; ++field_id;
  } while(field_it != new_fields.end());
}
Row_of_fieldsÀº ¾î¶² ÇÊ¿ä·Î ÇÏ´Â °ª¿¡ µû¶ó¼­ ´Ù¸¥ Çü½ÄÀ¸·Î º¯È¯ ÇÒ ¼ö ÀÖ´Â °ª °´Ã¼¸¦ Æ÷ÇÔÇϰí ÀÖ½À´Ï´Ù. À§ÀÇ ¿¹Á¦¿¡¼­´Â ÇÊµå °ªÀ» ÅØ½ºÆ®·Î º¯È¯ÇÏ¿© È­¸éÀ¸·Î Àμâ ÇÒ ¼ö Àִ ǥÁØ º¯È¯ °´Ã¼°¡ »ç¿ëµË´Ï´Ù.
¿ì¸®ÀÇ µ¥ÀÌÅÍ ¸ðµ¨Àº ¾Æ·¡¼­ À§·Î³ª À§¿¡¼­ ¾Æ·¡·Î Àо´Â °ÍÀÌ´Ù.

°ü·Ã ¸µÅ©

ÀÌÀü±Û
´ÙÀ½±Û Multi-threaded Slave¿¡ ´ëÇÑ ¾÷µ¥ÀÌÆ® 
MySQL Korea »çÀÌÆ®ÀÇ ÄÁÅÙÃ÷ ¼ÒÀ¯±ÇÀº (ÁÖ)»ó»óÀ̺ñÁî¿¡ ÀÖÀ¸¹Ç·Î ¹«´ÜÀüÀ縦 ±ÝÇÕ´Ï´Ù.
Copyright ¨Ï ssebiz All Rights Reserved.