MySQL 복제-슬레이브가 지속적으로 마스터보다 뒤 떨어지고 있음


12

마스터-슬레이브 복제 설정과 함께 MySQL-5.1.50을 사용하고 있습니다.

대부분의 경우 노예가 주인보다 뒤쳐져 있습니다.

을 실행하면 show processlist;시간이 오래 걸리는 쿼리가 없습니다. 나는 또한 가능하게 slow_log했다. 그러나 느리게 실행되는 쿼리는 찾지 않습니다.

슬레이브는 복제가 마스터보다 몇 초 뒤에 있다는 경고를 지속적으로 제공합니다. 때때로 지연 시간이 증가합니다.

문제의 원인을 어떻게 진단합니까?

이 문제가 지난 20 일 동안 지속되었으므로 긴급한 도움이 필요합니다.


답변:


20

Seconds_Behind_Master는 실제로 시간 여행을 통해 과거를 보는 것과 같습니다.

이런 식으로 생각하십시오 :

  • 태양은 지구에서 93,000,000 마일 떨어져 있습니다.
  • 빛의 속도는 186,000 마일 / 초입니다
  • 간단한 구분은 태양의 빛이 지구에 도달하는 데 약 500 초 (8 분 20 초)가 걸린다는 것을 보여줍니다
  • 태양을 보면 실제로 태양이 보이지 않습니다. 8 분 20 초 전의 위치를 ​​봅니다.

마찬가지로 마스터가 많은 쿼리를 동시에 처리하는 것 같습니다.

당신은 슬레이브를 되돌아보고 달리고 SHOW SLAVE STATUS\G200을 말합니다 Seconds_Behind_Master. 그 숫자는 어떻게 계산됩니까? 슬레이브 클럭 시간 (UNIX_TIMESTAMP (NOW ())-쿼리가 완료되어 마스터 이진 로그에 기록 된 쿼리의 TIMESTAMP입니다.

게다가 볼 또 다른 메트릭이 있습니다 Seconds_Behind_Master. 이 측정 항목을이라고 Relay_Log_Space합니다. 이는 슬레이브의 모든 릴레이 파일에 대한 모든 바이트의 합계를 나타냅니다. 기본적으로 가장 큰 단일 릴레이 로그는 1GB로 제한됩니다. 경우 Relay_Log_Space1GB 미만보다이 많은 장기 실행 쿼리 병렬 마스터에서 실행을 나타냅니다. 불행하게도, 단일 스레드 특성 Replication의 SQL 스레드로 인해 쿼리가 서로 뒤에서 실행됩니다.

예를 들어, 마스터에 다음 시나리오가 있다고 가정하십시오.

  • 느린 쿼리 로그가 활성화되었습니다
  • 마스터에서 병렬로 실행 된 20 개의 쿼리
  • 각 쿼리는 3 초가 걸렸습니다
  • 각 쿼리는 동일한 타임 스탬프를 사용하여 마스터 이진 로그에 기록됩니다.

슬레이브가 릴레이 로그에서 해당 쿼리를 읽고 하나씩 처리 할 때

  • 노예의 시계가 움직일 것입니다
  • 20 개의 쿼리 각각에 대한 TIMESTAMP는 동일합니다.
  • 차이는 3 초 증가 쿼리 완료됩니다
  • 결과는 60 초입니다. Seconds_Behind_Master

느린 로그와 관련하여 long_query_time 의 기본값 은 10 초입니다. 릴레이 로그의 모든 쿼리가 10 초 미만이면 느린 쿼리 로그에서 아무 것도 포착하지 않습니다.

마스터 및 슬레이브 서버 모두에 대해 다음 권장 사항이 있습니다.

추가 문제 해결

반복 지연을 일으키는 쿼리를 보려면 다음을 수행하십시오.

  • SHOW SLAVE STATUS\G
  • 에서 릴레이 로그 이름 가져 오기 Relay_Log_File
  • STOP SLAVE;
  • START SLAVE;
  • OS cd /var/lib/mysql또는 릴레이 로그가 작성되는 곳
  • 릴레이 로그를 텍스트 파일로 덤프

예를 들어 SHOW SLAVE STATUS\G

               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.64.51.149
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000009
          Read_Master_Log_Pos: 1024035856
               Relay_Log_File: relay-bin.000030
                Relay_Log_Pos: 794732078
        Relay_Master_Log_File: mysql-bin.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: search_cache
           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: 1024035856
              Relay_Log_Space: 794732271
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 106451149

를 실행 STOP SLAVE; START SLAVE;하면 릴레이 로그가 닫히고 새 로그가 열립니다. 그러나 당신은 원합니다 relay-bin.000030.

다음과 같이 내용을 덤프하십시오.

cd /var/lib/mysql
mysqlbinlog relay-bin.000030 > /root/RelayLogQueries.txt
less /root/RelayLogQueries.txt

이제 슬레이브가 현재 처리하려고하는 쿼리를 볼 수 있습니다. 이러한 쿼리를 튜닝의 시작점으로 사용할 수 있습니다.


v5.7부터 MySQL은 멀티 스레드 방식으로 변경 사항을 슬레이브에 적용 할 수 있습니다. 관련 문서는 여기에서 찾을 수 있습니다 : dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html
에디 구

2

어떤 바이너리 로그 형식을 사용하고 있습니까? ROW 또는 STATEMENT를 사용하고 있습니까?
" SHOW GLOBAL VARIABLES LIKE 'binlog_format';"

ROW를 binlog 형식으로 사용하는 경우 모든 테이블에 기본 또는 고유 키가 있는지 확인하십시오.
SELECT t.table_schema,t.table_name,engine FROM information_schema.tables t INNER JOIN information_schema .columns c on t.table_schema=c.table_schema and t.table_name=c.table_name and t.table_schema not in ('performance_schema','information_schema','mysql') GROUP BY t.table_schema,t.table_name HAVING sum(if(column_key in ('PRI','UNI'), 1,0)) =0;

PK 또는 고유 키가없는 테이블에서 백만 개의 레코드를 삭제하기 위해 마스터에서 하나의 delete 문을 실행하는 경우 마스터 측에서는 하나의 전체 테이블 스캔 만 수행되며 이는 슬레이브의 경우가 아닙니다.
ROW binlog_format을 사용하는 경우 MySQL은 행 변경 사항을 STATEMENT binlog_format과 같은 명령문이 아닌 2 진 로그에 기록하며 해당 변경 사항이 슬레이브의 행에 적용됩니다. 즉, 1 백만 개의 전체 테이블 스캔이 수행됩니다. 슬레이브에서 마스터에 하나의 delete 문만 반영하면 슬레이브 지연 문제가 발생합니다.


0

SHOW SLAVE STATUS의 seconds_behind_master 값은 이벤트가 원래 실행되어 바이너리 로그에 기록 될 때 저장된 마스터의 시스템 시간과 이벤트가 실행될 때 슬레이브의 시스템 시간 간의 차이입니다.

두 시스템의 클럭이 동기화되지 않은 경우 마스터 뒤의 초는 잘못된 값을 제공합니다.


MySQL 5.5 및 이전 버전에서는 복제 이벤트 실행이 슬레이브 측에서 단일 스레드입니다. "시스템 사용자"로 실행중인 "SHOW FULL PROCESSLIST"에는 두 개의 스레드가 있어야합니다. 하나는 마스터로부터 이벤트를 받고 있고 다른 하나는 쿼리를 실행하고 있습니다. 슬레이브가 지연되는 경우 해당 스레드는 현재 실행중인 쿼리를 표시해야합니다. 이를 살펴보고 디스크 / 메모리 / CPU 통계에서 리소스 부족을 확인하십시오.
Michael-sqlbot
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.