운영하는 시스템에서 replication 지연현상이 발생하여 원인 분석 했던 사례 공유드립니다.

포인트는  replication 지연이 발생하는 부분을 찾고 문제되는 쿼리와 그 원인 파악 입니다.

 

--1. 지연 현상 발생 시점의 Replication 상태

MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: TEST2
                  Master_User: repliUser
                  Master_Port: 3312
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000038
          Read_Master_Log_Pos: 250526084
               Relay_Log_File: relay-log.000038
                Relay_Log_Pos: 393111930
        Relay_Master_Log_File: mysql-bin.000029
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 393111642
              Relay_Log_Space: 6388283173
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 161990

 

-. Master_Log_File : I/O thread는 Master 노드의 mysql-bin.000038를 읽고있음.

-. Relay_Master_Log_file : SQL-thread는 Master  노드의  mysql-bin.000029 를 반영 중.

-. Exec_Master_log_pos : mysql-bin.000029 의 393111642 Pos를 반영중이고 161990 초가 넘도록 반영중인 것으로 보아 이 부분이 병목현상의 원인으로 파악됨.

-. Seconds_Behind_Master : I/O thread와 SQL Thread의 반영 차이를 초(sec) 로 나타냄.

 

 

--2. 병목 부분 확인

 mysql-bin.000029 를 확인해보면

# at 393111642
#171115 13:59:24 server id 2 end_log_pos 393111680 GTID 0-2-9707043
/*!100001 SET @@session.gtid_seq_no=9707043*//*!*/;
BEGIN
/*!*/;
# at 393111680
# at 393111799
# at 393112809
# at 393113819
# at 393114831
# at 393115841
.
.
.
.
.
  # at 1651532355
  # at 1651533367
  # at 1651534379
  # at 1651535395
  # at 1651536405
  #171115 13:58:48 server id 2  end_log_pos 393111799     Table_map: `test`.`si_test` mapped to number 93
  #171115 13:58:48 server id 2  end_log_pos 393112809     Update_rows: table id 93
  #171115 13:58:48 server id 2  end_log_pos 393113819     Update_rows: table id 93
  .
  .
   #171115 13:58:48 server id 2  end_log_pos 1651536931    Update_rows: table id 93 flags: STMT_END_F
 

 

 

-. 지연되는 Update 쿼리의 대상 테이블 생성구문

CREATE TABLE "si_test" ( 
"DIV_CD" varchar(3) COLLATE utf8_bin DEFAULT NULL COMMENT '사업부',   "PART_NO" varchar(40) COLLATE utf8_bin DEFAULT NULL COMMENT 'PARTNO', "STOCK_QTY" double DEFAULT NULL COMMENT '사업부재고수량', "WORK_YN" varchar(1) COLLATE utf8_bin DEFAULT NULL COMMENT '작업여부',
  "WORK_DATE" datetime DEFAULT NULL COMMENT '인터페이스일시',
  "BAM_SEQUENCE_ID" double DEFAULT NULL COMMENT '통합 모니터링 관련 컬럼',
  "OLD_GLOBAL_UNIQUE_ID" varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '통합 모니터링 관련 컬럼',
  "STEP_CODE" varchar(30) COLLATE utf8_bin DEFAULT NULL COMMENT 'step for B2B Server',
  "STEP_STATUS_CODE" varchar(30) COLLATE utf8_bin DEFAULT NULL COMMENT 'step status for B2B Server',
  "EDI_INTERFACE_DATE" datetime DEFAULT NULL COMMENT 'edi interface date for B2B Server',
  "GLOBAL_UNIQUE_ID" varchar(100) COLLATE utf8_bin DEFAULT NULL COMMENT '통합 모니터링 관련 컬럼',
  "HIM_WORK_YN" varchar(1) COLLATE utf8_bin DEFAULT 'N' COMMENT 'HIM 작업 여부',
  "HIM_WORK_DATE" datetime DEFAULT NULL COMMENT 'HIM 작업 일자',
  "ATTRIBUTE1" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE2" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE3" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE4" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE5" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE6" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE7" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE8" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE9" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  "ATTRIBUTE10" varchar(150) COLLATE utf8_bin DEFAULT NULL,
  KEY "si_test_IX02" ("HIM_WORK_YN")
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='사업부재고정보(I/F)'
 
=>  Primary key 없으며 KEY "si_test_IX02" ("HIM_WORK_YN") 인덱스 존재
 

-.  해당 테이블의 인덱스 생성 구문 및 효율성

 MariaDB [(none)]> show index from test.si_test\G;
*************************** 1. row ***************************
        Table: si_test
   Non_unique: 1
     Key_name: si_test_IX02
 Seq_in_index: 1
  Column_name: HIM_WORK_YN
    Collation: A
  Cardinality: 166
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment:
1 row in set (0.00 sec)
 

 

=> table rows 수는 190296711 인데 비하여   cardinality 가 166인 비효율적인 인덱스밖에 없어서 update 시 full scan 발생

->  update 속도 문제 및 Slave로의 복제 시  성능 이슈 유발

 

 

-. 병목 유발 쿼리 확인

 60079824 ### UPDATE `test`.`si_test`  60079825 ### WHERE 60079826 ###   @1='DMZ'
 60079827 ###   @2='AHA73673401'
 60079828 ###   @3=3
 60079829 ###   @4='N'
 60079830 ###   @5='2017-11-12 09:15:03'
 60079831 ###   @6=1015
 60079832 ###   @7=NULL
 60079833 ###   @8=NULL
 60079834 ###   @9=NULL
 60079835 ###   @10=NULL
 60079836 ###   @11='5DAE334C460B04B2E053A5F4EF879EA3'
 60079837 ###   @12='N'
 60079838 ###   @13=NULL
 60079839 ###   @14='3'
 60079840 ###   @15=NULL
 60079841 ###   @16=NULL
 60079842 ###   @17=NULL
 60079843 ###   @18=NULL
 60079844 ###   @19=NULL
 60079845 ###   @20=NULL
 60079846 ###   @21=NULL
 60079847 ###   @22=NULL
 60079848 ###   @23=NULL
 60079849 ### SET
 60079850 ###   @1='DMZ'
 60079851 ###   @2='AHA73673401'
 60079852 ###   @3=3
 60079853 ###   @4='X'
 60079854 ###   @5='2017-11-12 09:15:03'
 60079855 ###   @6=1015
 60079856 ###   @7=NULL
 60079857 ###   @8=NULL
 60079858 ###   @9=NULL
 60079859 ###   @10=NULL
 60079860 ###   @11='5DAE334C460B04B2E053A5F4EF879EA3'
 60079861 ###   @12='N'
 60079862 ###   @13=NULL
 60079863 ###   @14='3'
 60079864 ###   @15=NULL
 60079865 ###   @16=NULL
 60079866 ###   @17=NULL
 60079867 ###   @18=NULL
 60079868 ###   @19=NULL
 60079869 ###   @20=NULL
 60079870 ###   @21=NULL
 60079871 ###   @22=NULL
 60079872 ###   @23=NULL
 

 

--3. 해결 방법

 

MariaDB [(none)]> show index from lghirunp.si_divstock\G;
*************************** 1. row ***************************
        Table: si_divstock
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: INTERFACE_ID
    Collation: A
  Cardinality: 190296711
     Sub_part: NULL
       Packed: NULL
         Null:
   Index_type: BTREE
      Comment:
Index_comment:
 

=> Primary key 추가하여 update 성능향상