복제 슬레이브 지연 문제를 해결하는 방법

Henry Hwang -

복제 슬레이브 지연

복제를 사용하면 때때로 슬레이브 지연을 경험하게 됩니다. 슬레이브 지연은 마스터에서 원래 실행했을 때보다 몇초 느리게 슬레이브가 이벤트를 처리하는 지점을 말합니다. 대개, 슬레이브가 마스터를 따라 잡겠지만, 그렇지 못한 경우나 무엇이 지연을 유발했는지 알고 싶은 경우 다음이 슬레이브 지연 문제를 해결하는데 도움이 됩니다.

슬레이브 지연의 일반적인 원인

복제 지연의 일반적인 원인은 다음과 같습니다.

  • CPU 로드: 클러스터가 적시에 복제 이벤트를 처리하느라 바쁩니다.
  • 누락된 인덱스: 업데이트 중인 테이블에 기본키가 없거나 적적할 인덱스가 없는 SBR인 경우.
  • 잠금 대기 시간초과(lock wait timeouts): 슬레이브에서 커밋되지 않은 트랜잭션으로 인해 발생하는 잠금 대기 시간초과.
  • 일반적인 쓰기 양: 사이트 트래픽 증가나 대량 삭제 또는 업데이트를 동반한 데이터 마이그레이션으로 인한 쓰기 양 증가. 
  • 데이터 일관성: 데이터 일관성 문제(duplicate keys 또는 row not found)로 인해 슬레이브가 빈번히 중지 또는 시작.
  • 오래 실행되는 집계 쿼리(SBR): SBR에서 처리 대기중인 쿼리의 증가를 유발하는 오래 걸리는 집계 쿼리.
  • 데이터 분포: 모든 노드에 고르게 분산되지 않은 대상 테이블.
  • 네트워크 이슈

슬레이브 지연의 다른 원인을 살펴보기 전에 어느 정도 기대치를 설정하고 몇 가지 복제의 기본 사항을 검토해야 합니다.

기대

마스터에서 쓰기 쿼리가 병렬로 처리되는 것과 달리 복제는 싱글 스레드 프로세스이기 때문에 쓰기 이벤트 처리는 마스터에서 보다 슬레이브에서 더 느립니다.

대부분의 고객은 단일 binlog가 고객의 복제 필요성에 좀더 부합되지만, 쓰기가 많은 환경에서는 여러 binlog 사용을 고려할 수 있습니다.

Configuring Replication 문서를 참조하십시오.

복제 유형

다음과 같은 두 가지 유형의 복제가 있습니다.

  • SBR (Statement-based replication): 일괄(bulk) 쓰기에 적합, 문제 해결하기 더 쉬움.
  • RBR (Row-based replication): 쿼리를 처리하는 대신에 슬레이브가 행 변경을 처리하는 작은 쓰기에 적합, 일반적으로 좀 더 효율적임.

마스터 클러스터가 실행중인 복제 유형을 확인하려면 다음을 실행하십시오.

show binlogs\G

format의 값은 특정 binlog에 대해 실행중인 복제 유형을 알려줍니다

mysql> show binlogs\G
*************************** 1. row ***************************
   log_name: test
       head: 6257570335613048834
log_all_dbs: 1
     format: row
    version: 2
   segments: 1
      bytes: 524288
1 row in set (0.08 sec)

각 복제 유형과 연관된 테이블 및 통계가 서로 다르기 때문에 복제 유형을 아는 것이 유용합니다(나중에 다룸). 또한, RBR을 실행중인 경우 쓰기를 발생시킨 쿼리는 슬레이브의 쿼리 로그에 로깅되지 않으므로 문제가 있는 쿼리를 식별하려면 마스터를 조사해야 합니다.

쿼리 로그

쿼리 및 clustrix 로그 항목을 검토하는 것이 슬레이브가 왜 지연되는지 파악하는데 중요합니다. 로그 항목을 추출하려면 쿼리 로그를 읽는 방법의 단계를 따라야 합니다.

슬레이브 지연 문제를 해결할 때 읽기 쿼리는 binlog에 기록되지 않고 슬레이브로 복제되기 때문에 일반적으로 오래 실행되는 SELECT 문은 무시할 수 있습니다. 그러나, 마스터 또는 슬레이브가 성능이 떨어지는 SELECT 쿼리로 인해 큰 영향을 받을 수 있다는 것을 명심하십시오. SELECT 쿼리를 원인에서 자동으로 제거하지 마십시오. 일반적으로 RBR의 경우 슬레이브 지연의 잠재적 원인으로 오래 실행되는 쓰기 쿼리나 마스터에서 다수의 행에 영향을 주는 쓰기 쿼리를 찾고 싶을 것입니다.

SBR의 경우 어떤 SLOW 쓰기가 오는지 확인하기 위해 슬레이브 클러스터에서 쿼리 로그를 확인해야 합니다.

Clustrix 로그

슬레이브 문제는 슬레이브 프로세스가 실행중인 노드의 clustrix 로그에 로깅됩니다. 다음 쿼리를 사용하여 슬레이브가 어디에서 실행중인지 찾을 수 있습니다.

SELECT slave_name,
       master_host,
       nodeid
FROM system.mysql_repconfig;

슬레이브 프로세스는 그룹 변경 후에 슬레이브 프로세스가 이동할 수 있는 노드와 동일한 노드에 항상 바인딩되지는 않습니다.

로그 항목은 슬레이브가 중지되었을 때와 마지막으로 성공한 로그 위치 및 읽은 로그 파일과 함께 중지된 이유를 기록합니다. 클러스터는 슬레이브가 재시작되었을 때와 요청한 로그 위치를 기록합니다.

여기 몇 가지 샘플 clustrix.log (v5 이하에서 sprout.log) 항목이 있습니다.

Aug 6 16:46:54.164643 UTC 2014 clxnode002 real: ALERT SLAVE_STOP WARNING Stopped mysql slave clxslave (10.0.1.10:3306) on non-transient error: Duplicate key in container: test.__idx_email__PRIMARY (support@clustrix.com). Statement: COMMIT, Database: (master_log.015688, position 89420179)

Aug 6 16:47:02.750361 UTC 2014 clxnode002 real: INFO mysql/replication/slave_driver.ct:112 mysql_slave_sig_migrated(): User stopping mysql slave "clxslave"

Aug 6 16:47:04.096524 UTC 2014 clxnode002 real: INFO mysql/replication/slave_driver.ct:105 mysql_slave_sig_migrated(): User starting mysql slave "clxslave"

Aug 6 16:47:04.128394 UTC 2014 clxnode002 real: INFO mysql/replication/slave.ct:804 mysql_slave_initialized(): mysql slave "clxslave" writing to binlogs per system.mysql_slave_log_updates

Aug 6 16:47:04.128844 UTC 2014 clxnode002 real: INFO mysql/replication/slave.ct:723 mysql_slave_session(): mysql slave "clxslave" connecting to 10.0.1.10:3306

Aug 6 16:47:04.128884 UTC 2014 clxnode002 real: INFO mysql/replication/slave.ct:690 mysql_slave_connected(): mysql slave "clxslave" opened relay log for 10.0.1.10:3306 (requesting "master_log.015688, position 89419912")

Aug 6 16:47:04.549432 UTC 2014 chndb002 real: INFO mysql/replication/slave_trx.c:129 check_skip_evt(): slave clxslave (10.0.1.10:3306) (master_log.015688, position 89420179) skipped transaction (remaining 0): t_mysql_query

clustrix 로그 항목을 읽는 방법을 익히기 위해 위의 예제 로그 항목에서 몇 가지 세부 항목을 이해해보고자 합니다.

  • test 테이블에서 중복키 때문에 슬레이브가 중지되었습니다. 즉, "support@clustrix.com" 값을 가진 "test" 테이블의 기본키에 중복키가 있습니다.
  • 읽었던 binlog 파일은 master_log.015688이고 복제 이벤트에 대한 마지막으로 성공한 로그 위치는 89420179입니다.
  • 그런 다음, 슬레이브 프로세스가 자동으로 중지하고 하나의 이벤트를 건너뛰고 난 후에 재시작합니다.

슬레이브 건너뛰기 동작은 설정 가능함에 주의하십시오. Controlling Slave Behavior on Errors 문서를 참조하십시오.

복제 스트림에 무엇이 오는지 식별하려면 binlog 세부 정보를 추출하기 위한 시작점으로 로그 위치 및 binlog 이름이 필요합니다. binlog 이벤트를 추출하는 방법은 FAQ에서 문제 해결을 위한 binlog 데이터 추출을 참조하십시오.

슬레이브 상태

먼저 확인해야 할 점은 복제 스트림에서 슬레이브가 이벤트를 처리하는지 여부를 확인하는 것입니다. 다음과 같이 슬레이브 상태를 얻을 수 있습니다.

show slave status\G

중요한 점은 로그 위치가 "이동 중"인지 여부와 릴레이 로그가 증가하는지 여부입니다. 그렇다면, 슬레이브가 복제 스트림을 처리하고 마스터에서 이벤트를 가져오고 있다는 것을 알 수 있습니다.

또한 last error에 주목하십시오. duplicate key 또는 lock wait timeout로 표시되면 문제는 분명하며 아래 관련 섹션으로 이동합니다. 그렇지 않으면 몇 가지 추가 문제 해결을 수행애햐 합니다.

CPU Load

클러스터가 마스터 또는 슬레이브 중 하나에서 사용율이 높으면 복제에 영향을 줄 수 있습니다.

부하가 높은 마스터는 충분히 빠르게 슬레이브에 전달할 수 없으며 부하가 높은 슬레이브(master-master 구성)는 적시에 복제된 이벤트를 처리하지 못할 것입니다. 로드 및 로드 추위를 확인하려면 클러스터에서 다음 명령을 실행할 수 있습니다.

mysql> show load;
+--------------+------+
| facility     | LOAD |
+--------------+------+
| bm_miss_rate |    0 |
| cpu          |  0.4 |
| disk_util    |  2.8 |
+--------------+------+
3 rows in set (0.19 sec)
mysql> SELECT * FROM clustrix_statd.statd_history NATURAL JOIN clustrix_statd.statd_metadata WHERE name='clustrix.cpu.load_avg' ORDER BY TIMESTAMP DESC LIMIT 10;
+-----+---------------------+----------+-----------------------+
| id  | timestamp           | value    | name                  |
+-----+---------------------+----------+-----------------------+
| 643 | 2016-03-01 21:40:00 |   0.1207 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:35:00 | 0.124875 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:30:00 | 0.117828 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:25:00 | 0.106306 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:20:00 | 0.124611 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:15:01 | 0.104327 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:10:00 | 0.113514 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:05:00 | 0.115097 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 21:00:00 | 0.107797 | clustrix.cpu.load_avg |
| 643 | 2016-03-01 20:55:00 | 0.113899 | clustrix.cpu.load_avg |
+-----+---------------------+----------+-----------------------+
10 rows in set (0.00 sec)

CPU load 평균이 정상보다 높으면 부하가 많이 발생하는 원인을 파악해야 합니다. 그 원인은 다음과 같습니다.

  • 쿼리의 양
  • 오래 실행되는 쿼리(아마도 분석 또는 많은 쓰기를 발생하는 쿼리)
  • 제대로 최적화 되지 않은 쿼리(올바른 인덱스를 사용하지 못하거나 테이블에 인덱스가 누락된 쿼리).

마스터에서는 적시에 처리되는 빠른 쓰기가 있을 수 있지만 쓰기의 양 때문에 슬레이브가 지연되기 시작합니다. 쿼리 자체는 실행 시간이 슬로우 로깅 임계치(slow logging threshold)를 넘지 않아 쿼리 로그에 기록되지 않을 수 있습니다. 그러나, clustrix_statd.qpc_history 테이블을 쿼리하여 마스터에서 updates, deletes 또는 inserts가 얼마나 자주 실행되는지 다음 쿼리로 확인할 수 있습니다(timestamp 및 statement는 적절히 수정하십시오).

SELECT TIMESTAMP,
       STATEMENT,
       sum(exec_count),
       avg(avg_exec_ms)
FROM clustrix_statd.qpc_history
WHERE rank < 10
  AND TIMESTAMP > '2014-10-10 12:40:00'
  AND STATEMENT LIKE 'update%'
GROUP BY query_key
ORDER BY TIMESTAMP ASC LIMIT 3 \G

통계 기간 동안 많은 업데이트가 표시되면 문제가 될 가능성이 큽니다. 예를 들어, 15분 동안 단순 업데이트 쿼리가 200,000회 실행되도 쿼리 로그에 기록되지 않지만, qpc_history를 보고 이를 파악할 수 있어야 합니다. 

또한 마스터의 쿼리 로그 항목을 사용하여 슬레이브 지연을 유발하는 일괄 쓰기(bulk write)를 식별할 수 있습니다. 비록 130000 행 업데이트가 많은 것 처럼 들리지는 않지만 아주 짧은 시간에 30번의 업데이트가 있다면 슬레이브를 느리게 만들 수 있습니다.

Aug 4 21:22:35.449849 UTC 2014 clxmaster003 real: INSTR SLOW SID:3780625411 db=test user=user1@10.100.0.20 ac=Y xid=53e0fd9420ba4006 sql="UPDATE bigtable SET TIME_UPDATED=now(),DELETED=0 WHERE ID=371" [Ok: 138756 rows updated] time 27487.7ms; reads: 277513; inserts: 416268; deletes: 0; updates: 277512; counts: 138756; rows_read: 416268; forwards: 832543; rows_output: 2; semaphore_matches: 0; runtime: 3735902785; attempts: 1

대괄호에서 "rows updated" 수에 유의하십시오.

잠재적으로 오래 실행되는 쿼리의 경우 일반적으로 다음 쿼리(clustrix 버전에 따라 다름)를 사용하여 쿼리를 찾고 쿼리가 그 상태로 얼마나 있었는지 확인할 수 있습니다.


SELECT *
FROM system.sessions
WHERE statement_state='executing'
AND time_in_state_s>1
ORDER BY time_in_state_s DESC LIMIT 10 \G

동일한 유형의 쿼리가 여러 번 표시되고 처리하는데 오랜 시간이 걸리면 누락된 인덱스 또는 잠금 대기 시간 초과를 나타낼 수 있습니다(후자는 쿼리 로그에 표시됨).

인덱싱

쿼리에 인덱스가 누락되어 있는지 여부를 확인하고 이 문제를 해결하는 방법은 완전히 다른 주제이지만 간단히 살펴보겠습니다.

하나의 RBR 시나리오는 슬레이브 지연이 지속적으로 증가하고 릴레이 로그 위치가 변경되지만 로그 위치가 이동하지 않는 경우입니다. 이는 해당 인덱스가 있더라도 대상 테이블에 기본 키가 없는 일괄 삭제 또는 업데이트로 인해 발생할 수 있습니다. 슬레이브에서 쓰여지고 있는 해당 테이블의 create table 정의를 반드시 체크하고 기본기가 있는지 여부를 확인할 필요가 있습니다.

예를 들어, 이 쿼리가 마스터에서 처리되고 백만개의 행을 삭제한 경우:

delete from foo where start_date<'2014-01-01'

이 테이블의 DDL은 다음과 같습니다.

mysql> show create table foo \G
*************************** 1. row ***************************
       Table: foo
Create Table: CREATE TABLE `foo` (
  `id` bigint(16),
  `bar` bigint(16),
  `start_date` date,
  `end_date` date,
  KEY `start_date` (`start_date`) /*$ DISTRIBUTE=1 */
) CHARACTER SET utf8 /*$ REPLICAS=2 SLICES=1 */

여기서 해결책은 테이블에 기본키가 있어야할 뿐 아니라 복제가 기본적으로 RBR인 경우 명령문 기반 쿼리를 복제할 쿼리를 지정하는 것입니다. 여기서 한가지 더 할 일은 쓰기 로드를 줄이기 위해 제한을 포함해야할 수 있습니다.

alter table foo add primary key (id);
set session binlog_format='statement'
delete from foo where statt_date<'2014-01-01' limit 100000;
### 모든 행이 삭제될 때까지 반복하십시오 ###

SBR을 실행중인 경우, 처리중인 쿼리가 제대로 최적화되지 않았거나 테이블에 올바른 인덱스가 없을 수 있습니다. 마스터에서 쿼리 로그 또는 qpc_history를 보고 마스터에서 문제가 있는 쓰기를 식별하고 실행 속도가 느린 쓰기를 찾을 수 있는지 확인해야 합니다.

그런 다음 실제 쿼리를 보고 쿼리가 테이블 정의에 있는 인덱스를 사용하는 올바른 검색 인자를 가지고 있는지 여부를 볼 수 있습니다.

잠금 대기 시간 초과(Lock Wait Timeouts)

sprout 또는 clustrix 로그에서 슬레이브 프로세스에 대해 다음과 같은 "lock wait timeout exceeded" 오류를 발견할 수 있습니다.

Jul 17 18:07:38.393608 UTC 2014 clxnode002 real: INFO mysql/replication/slave_state.c:175 mysql_slave_state_reconnect(): Stopped mysql slave clxslave (10.1.0.10:3306) on transient error, scheduling retry: Lock wait timeout exceeded: . Statement: COMMIT, Database: (master_log.014723, position 5397030)

또는 다음과 같이 slave status 명령을 실행할 때 Last_Error 필드에서 "Lock wait timeout exceeded"를 볼 수 있습니다.

mysql> show slave status \G
*************************** 1. row ***************************
           Slave_Name: clxslave
         Slave_Status: Reconnecting
          Master_Host: 10.1.0.10
          Master_Port: 3306
          Master_User: replication
      Master_Log_File: master_log
        Slave_Enabled: Enabled
         Log_File_Seq: 14723
         Log_File_Pos: 5397030
           Last_Error: Lock wait timeout exceeded: . Statement: COMMIT, Database:
    Connection_Status: Disconnected
 Relay_Log_Bytes_Read: 0
Relay_Log_Current_Size: 0
Seconds_Behind_Master: NULL
1 row in set (0.00 sec)

이것은 슬레이브 이벤트가 커밋되지 않은 다른 프로세스에 의해 현재 잠겨있는 행이나 테이블을 업데이트하기 위해 잠금을 획득하려 하기 때문에 발생합니다. 5분(기본값) 후에 잠금을을 얻지 못하면 이 오류가 발생합니다.

여전히 커밋되지 않은 트랜잭션을 찾을 수 있어야 합니다.

SELECT *
FROM system.sessions
WHERE xid IN
    (SELECT holder
     FROM system.lockman
     ORDER BY holder ASC LIMIT 1)\G

다음은 출력 샘플입니다.

mysql> select * from system.sessions where xid in (select holder from system.lockman order by holder asc limit 1) \G*************************** 1. row ***************************           nodeid: 5       session_id: 1977584645
        source_ip: 10.1.1.100
      source_port: 13574
         local_ip: 10.1.0.10
       local_port: 3306
             user: 5711972934625828866
         database: prod
        trx_state: open
  statement_state: executing
              xid: 6037483960283521034
        isolation: REPEATABLE-READ
   last_statement: UPDATE foo set bar=1
    time_in_state: 34
          created: 2014-07-17 10:27:48
          trx_age: 1517
         trx_mode: explicit
trx_counter_select: 3
trx_counter_insert: 0
trx_counter_update: 42
trx_counter_delete: 0
    trx_is_writer: 1
1 row in set (0.07 sec)

이 예제에서 trx_mode는 명시적이며 이 트랜잭션이 자동 커밋으로 설정되어 있지 않음을 알려줍니다. 그런 다음 사용자에게 트랜잭션을 커밋하도록 알리거나 세션을 종료할 수 있습니다.

슬레이브 프로세스 교착

드문 경우지만, 오류로 인해 슬레이브가 중지된 지점에 슬레이브 프로세스가 교착 상태에 빠질 수 있고 재시작되었을 때 이전 슬레이브가 아직도 중지되지 않았습니다. 

이것은 다음과 같은 증상과 함께 슬레이브 클러스터에서 나타납니다.

  • 슬레이브 지연 증가
  • bigc 증가
  • 언두 스페이스(undo space) 증가
  • 릴레이 로그(relay log)가 증가하지 않습니다
  • 슬레이브의 XID에 대한 system.transactions 테이블의 통계가 증가하지 않습니다
  • 슬레이브 프로세스가 가장 오래된 트랜잭션입니다
select * from system.sessions where xid in (select xid from system.transactions order by xid asc limit 1 \G  # check to see if user=4100 which would be the slave process.

이것은 슬레이브가 교착 상태인 것으로 확인되면 세션을 종료할 수 있는지 확인하십시오. 그래도 문제가 해결되지 않으면 지원팀에 문의하십시오.


마스터에서 문제

슬레이브에서 CPU 로드가 낮고 슬레이브에서 오래 실행되는 쿼리가 없으며 인덱싱 이슈가 없는 경우 마스터 클러스터를 확인하는 것이 좋습니다.

  • 마스터 로그의 모든 오류(clustrix.log)?
  • 마스터에서 CPU 로그가 높습니까?
  • 복제중인 많은 쓰기 이벤트가 있습니까?
  • 다수의 작은 쓰기(수십만의 작은 updates, deletes 또는 inserts)가 있습니까?


쓰기 양

정상보다 더 많은 binlog 파일이 생성되고 있습니까? 아마도 마이그레이션 작업이 있고 마이그레이션의 일부로 데이터가 복제되고 있거나 전반적으로 쓰기가 늘어나고 있고 여러 개의 binlog를 계획해야할 수도 있습니까? 이것은 RBR에서 보다 쉽게 알 수 있지만 쓰기 명령문이 상당히 증가하면 SBR 환경에서도 나타날 수 있습니다.

다음과 같이 통계 테이블을 쿼리하여 binlog 크기의 차이를 보고 차트를 만들어 일정 시간 동안 binlog가 얼마나 증가했는지 확인할 수 있습니다.

SELECT (max(value) - min(value))/1024/1024/1024 AS Binlog_Growth_GB
FROM clustrix_statd.statd_history
NATURAL JOIN clustrix_statd.statd_metadata
WHERE TIMESTAMP BETWEEN timestampadd(DAY,-1,now()) AND now()
  AND name = 'clustrix.capacity.disks.binlog.size_bytes';

RBR의 경우 특정 시간(예: 하루) 동안 생성된 binlog 수를 세고 지연이 binlog의 증가와 일치하는지 확인할 수 있습니다.

tee binlogfiles.todaysdate;
show all binlog files;

SBR의 경우 쓰기 명령(deletes, updates, inserts)이 증가했는지 여부를 확인하고 이전 기간과 비교해 볼 수 있습니다.

mysql> select name, timestamp, max(value) - min(value) as Exec_count from clustrix_statd.statd_history natural join clustrix_statd.statd_metadata where timestamp between timestampadd(day,-1,now()) and now() and name in ('clustrix.stats.Com_delete','clustrix.stats.Com_update','clustrix.stats.Com_insert') group by name limit 10;
>+---------------------------+---------------------+------------+
| name                      | timestamp           | Exec_count |
+---------------------------+---------------------+------------+
| clustrix.stats.Com_update | 2014-08-05 15:15:00 |     196959 |
| clustrix.stats.Com_insert | 2014-08-05 15:10:00 |   17493971 |
| clustrix.stats.Com_delete | 2014-08-05 14:20:01 |       5494 |
+---------------------------+---------------------+------------+
3 rows in set (0.00 sec)

결과를 도표로 만들면 증가된 binlog 쓰기를 쉽게 시각화하고 식별할 수 있습니다(첨부된 이미지 참조).

데이티 일관성

duplicate keys 또는 row not found로 인한 빈번한 슬레이브 중지는 해당 이벤트를 건너뛰도록 구성된 경우 슬레이브가 재시작하는데 최대 10초가 걸릴 수 있기 때문에 추가적인 슬레이브 지연을 초래합니다. 이상적으로는 이것은 데이터 일관성 문제를 나타낼 수 있기 때문에 이런 상황에 있으면 안됩니다. 그러나, 이는 주로 애플리케이션이 두 클러스터에 실수로 동일한 데이터를 기록하는 master-master 구성에서 발생합니다. 또한 개발팀이 부주의로 슬레이브에 기록한 master-slave 구성에서도 발생합니다.


오래 실행되는 분석 쿼리

복제는 단일 스레이드로 실행되기 때문에 SBR에서 처리하는데 오랜 시간이 걸리는 복잡한 쓰기 쿼리가 있는 경우 이것과 대기중인 모든 쿼리가 처리가 완료될 때까지 슬레이브는 지연됩니다.

데이터 분산

예를 들어 클러스터에서 노드 수보다 슬라이스 수가 적은 테이블이 제대로 분산되어 있지 않는 경우 모든 가용한 자원을 활용하지 못합니다. 쓰기가 모든 노드에서 더 균등하게 분산되고 있지 않으므로 이 테이블은 "hot" 할 것입니다. 다음과 같이 hotness_history(괄호 안의 값 수정)을 보고 사용율이 높은 테이블을 찾을 수 있습니다.

select * from clustrix_statd.hotness_history where write_rank <20 and database not in ('system','clustrix_statd','_replication') and total_replicas < [### 2 * number_of_nodes###] order by timestamp desc, write_rank asc limit 50;

또는 현 시점에 어떤 테이블의 사용율이 높은지 보려면 hotness 도구(https://support.clustrix.com/entries/23261163-Hotness)를 사용할 수 있습니다.

네트워크 문제

네트워크 모니터링 시스템이나 NOC는 복제에 영향을 미치는 네트워크 문제가 있는 경우 알려야 합니다. 그렇지 않은 경우, 슬레이브 지연이 0에서 높은 값으로 급격하게 증가하는 것을 알 수 있습니다.

mysql> select * from clustrix_statd.statd_metadata natural join clustrix_statd.statd_history where name like '%seconds_behind%' order by timestamp desc limit 200;
+------+-----------------------------------------------------------+---------------------+-------+
| id   | name                                                      | timestamp           | value |
+------+-----------------------------------------------------------+---------------------+-------+
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:55:05 |  1486 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:51:06 |  2095 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:45:24 |  NULL |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:40:05 |  3676 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:35:06 |  NULL |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:32:13 |  5575 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:25:03 |  NULL |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:20:07 |  6569 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:15:28 |  6438 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:10:07 |  6671 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:04:49 |  6864 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-21 00:00:24 |  NULL |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-20 23:56:25 |  7155 |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-20 23:50:04 |  NULL |
| 1327 | clustrix.replication.slave.seconds_behind_master.clxslave | 2014-11-20 23:44:49 |     0 |

슬레이브가 실행되는 노드에서 sprout 또는 clustrix 로그가 다음과 같은 로그를 남겼습니다.

Nov 20 23:49:08.216590 UTC 2014 clxnode001 real: INFO mysql/replication/slave_state.c:175 mysql_slave_state_reconnect(): Stopped mysql slave clx-slave (10.0.0.100:3306) on transient error, scheduling retry: Could not connect to master (Connection reset by peer)


몇 개의 Binlog

어떤 경우에는 하나의 binlog가 처리하기에 너무 많은 쓰기가 있을 수 있습니다. 이는 사이트의 성장이나 휴가 기간 동안과 같은 시즌에 따른 수요 때문일 수 있습니다. 문제 해결방법은 비의존적 쓰기가 자신의 binlog에 쓰일 수 있는 다수의 binlog를 갖도록 하는 것입니다. 예를 들어, 사용자 테이블에 쓰고 메시지 테이블에 쓸 수 있습니다. 이들이 서로 다른 스키마에 있고 서로 의존성을 갖고 있지 않은 경우 스키마 마다 하나의 binlog를 구성한다면 하나의 스키마에 대한 복제 이벤트가 다른 스키마에 대한 쓰기 뒤로 대기하지 않습니다.

이를 수행하는 벙법에 대한 자세한 내용은 지원부서에 문의하십시오.


Binlog 이벤트 추출

이 FAQ(How To Extract Binlog Events)는 binlog에서 이벤트를 추출하는 방법을 설명합니다.

통계

RBR의 경우 이 테이블은 RBR 통계(슬레이브가 다시 시작될 때마다 재설정되는 다음 두 테이블의 통계)에 대한 통찰을 제공합니다.

  • system.slave_row_stats: select * from system.slave_row_stats order by event_bytes desc limit 10;    # 슬레이브가 시작된 이후 쓰여지는 상위 10개의 테이블을 보여줍니다.
  • system.mysql_slave_stats: select * from system.mysql_slave_stats;                                                 # bytes_per_sec 및 events_per_sec을 찾고 배치값이 증가하는지 여부를 확인합니다.

위의 통계는 어떤 테이블이 "hot"한지 알려주며 해당 테이블에 대한 쓰기 쿼리를 찾는데 도움을 줍니다.

SBR의 경우 슬레이브에서 이 통계는 복제되는 문의 양을 식별하는데 도움을 줍니다.

  • clustrix.stats.Com_delete
  • clustrix.stats.Com_update
  • clustrix.stats.Com_insert

통계와 쿼리 로그 항목과 함께 사용되는 경우

  • clustrix_statd.qpc_history


모범 사례

  • 여러 개의 슬레이브 프로세스가 있는 경우 VIP 호스트 보다는 마스터 노드에서 다른 노드를 보도록 지정하십시오.
  • 일반적으로 RBR이 좀 더 효율적이지만 슬레이브가 쓰기 작업으로 넘쳐나지 않도록 하려면 일괄 쓰기를 문기반(set session binlog_format='statement')으로 설정할 필요가 있습니다.
  • 하나의 binlog에 대해 쓰기 양이 너무 많은 경우 쓰기가 의존적이지 않다면 binlog 쓰기를 다른 binlog로 분리하십시오.
또 다른 질문이 있으십니까? 문의 등록

0 댓글

댓글을 남기려면 로그인하세요.
Zendesk 제공