1. 소개
프로젝트 주소: https://github.com/seanlook/p...
pt-table은 마스터-슬레이브에서 데이터 일관성 검증에 자주 사용됩니다. -checksum 도구의 원리와 구현 프로세스는 이전에 pt-table-checksum을 사용하여 프로덕션 환경에서 MySQL 데이터 일관성을 확인하는 문서에 작성되었습니다. 그러나 DBA 작업에서는 두 테이블의 일관성에 대한 일부 검사가 있으며 두 테이블 사이에는 마스터-슬레이브 관계가 없습니다. pt 도구는 binlog를 기반으로 마스터 데이터베이스에서 수행되는 검사 작업을 재생합니다. 슬레이브 데이터베이스는 더 이상 적용되지 않습니다.
Alibaba Cloud RDS 인스턴스에서 자체 구축된 mysql 인스턴스로 마이그레이션하는 등의 특별한 요구 사항은 항상 존재합니다. 데이터 전송 서비스 구현 방법은 테이블 기반 배치 데이터 추출과 binlog 구독이지만, 필수 행 모드에서는 pt-table-checksum이 일시적으로 세션을 명령문으로 변경할 수 있는 권한이 없습니다. 또 다른 요구 사항은 전체 라이브러리의 문자 집합을 변환하는 것입니다. 라이브러리 테이블 정의는 모두 utf8이지만 응용 프로그램 연결은 기본 latin1을 사용합니다. 연결 문자 집합과 테이블 문자 집합을 통합하려면 latin1을 통해서만 데이터를 내보낼 수 있습니다. , 그런 다음 UTF8 가져오기를 사용하여 이 경우 데이터 일관성 검사를 수행합니다. binlog 구문 분석 프로그램이 명령문(예: 운하)을 지원하지 않는다는 점은 말할 것도 없고 이전 라이브러리와 새 라이브러리의 내용이 다르며 검사 값은 pt로 계산됩니다. -table-checksum은 다르며 유효하지 않습니다.
그래서 제가 pt-table-checksum을 참조하는 아이디어를 생각해내고 px-table-checksum을 직접 작성했습니다.
2. 구현 방법
전체적인 아이디어는 pt-table-checksum에서 학습하고, 소스 데이터베이스에서 1000행과 같은 데이터 조각을 일괄(즉, 청크)로 꺼내는 것입니다. CRC32 값을 계산하고 대상에서 동일한 문을 사용합니다. 라이브러리가 한 번 실행되고 결과가 다른 라이브러리에 저장됩니다. 마지막으로 해당 번호의 청크 crc 값이 일치하는지 확인합니다. 불일치를 아는 것만으로는 충분하지 않습니다. 따라서 차이점을 빠르고 편리하게 수정할 수 있어야 합니다. 따라서 일관성 없는 청크를 기반으로 일관성 없는 행을 찾기 위해 계속해서 대상 라이브러리와 소스 라이브러리로 이동해야 합니다. 또는 수정? 그런 다음 복구 SQL을 생성합니다. 자동으로 복구할지 여부를 나타냅니다.
그럼 질문은
배치를 결정하는 방법, 즉 다음 청크를 얻는 방법은 무엇입니까? 나는 로드에 따라 청크 크기를 동적으로 조정하거나 활성 스레드 수가 임계값을 초과할 때 검사를 일시 중단할 수 있는 pt-table-checksum 기능을 수행하고 싶지 않았습니다. 현재 매번 계산되는 청크 행 수는 고정되어 있으며 1000, 2000 등으로 구성할 수 있습니다.
따라서 페이징 쿼리를 사용해야 합니다(자동 증가 또는 통합) 기본 키와 고유 인덱스에 따라 각 제한 1000 이후에는 마지막 항목이 오름차순으로 다음 항목의 시작으로 사용됩니다. 일괄. 따라서 테이블의 핵심 상황을 분석하고 쿼리 조건을 조합하는 것이 필요합니다. 현재는 기본 키나 고유 키가 있는 테이블만 확인할 수 있습니다.
소스 라이브러리와 대상 라이브러리가 동일한 SQL을 실행하는지 어떻게 확인하나요? 이전 버전에서는 대상 라이브러리와 소스 라이브러리가 여러 스레드를 사용하여 청크를 개별적으로 계산하고 라이브러리에 저장했습니다. 나중에 심각한 버그를 깨달았습니다. 예를 들어 1000행도 가져오면 대상 라이브러리에 더 적은 행이 있으면 데이터에 따라 다음 청크의 시작점이 달라지므로 비교 결과가 엉망이 됩니다.
따라서 동일한 번호와 시작점을 가진 청크가 동일한지 확인하는 것이 필요하므로 소스 라이브러리에서 실행한 모든 검증 SQL을 큐를 사용하여 저장하려고 생각했습니다. , 그리고 pt 도구를 시뮬레이션하여 대상 라이브러리에서 재생합니다. 여러 스레드가 동시에 여러 테이블을 비교해야 한다는 점을 고려하면 큐가 너무 많은 메모리를 소모할 수 있으므로 Redis 큐를 사용한다.
crc32를 데이터베이스에서 직접 계산할까요, 아니면 데이터를 꺼내 메모리에서 계산할까요? pt-table-checksum의 소스코드를 확인해 보니 데이터베이스에 계산되어 있는 것을 발견했습니다. 그러나 첫 번째 섹션에서 언급했듯이 대상 라이브러리와 소스 라이브러리가 올바른 데이터를 읽기 위해 서로 다른 문자 집합을 사용해야 하는 경우 쿼리하고 비교만 하면 됩니다. 따라서 px-table-checksum은 두 가지를 모두 지원하며 하나의 구성 항목만 지정하면 됩니다.
동시에 여러 테이블을 확인합니다. 원본 데이터베이스 SQL이 실행을 위해 꺼내지면 1초가 지났습니다. 다시 수정하여 대상 데이터베이스에 동기화하면 계산 결과가 일치하지 않지만 실제로는 동일하므로 pt-table-checksum에 비해 처리할 수 없습니다.
그러나 이러한 문제를 최대한 줄이기 위해(예: 마스터-슬레이브 지연도 발생할 수 있음) 여러 개의 Redis 대기열이 특별히 설계되었으며 대상 라이브러리에는 여러 개의 검사 스레드가 있습니다. 동시에 검사하도록 지정하면 소스 라이브러리 검사에는 8개의 스레드가 해당되지만 테이블 작성 상황에 따라 4개의 Redis 대기열(현재 무작위로 대기열에 추가됨)과 10개의 대상 라이브러리 검사 스레드를 구성하여 부정확성 요소를 줄일 수 있습니다. . 하지만 제 생각에는 불일치하는 데이터가 기록될 것입니다. 많지 않으면 수동으로 확인하고, 동일한 데이터가 두 번 불일치하면 뭔가 잘못된 것입니다. .
3. 제한 사항
확인 중에 원본 테이블 데이터가 자주 변경되면 확인 결과가 부정확할 수 있는데, 이것이 위의 4번 문제입니다. 분명히, 이 프로그램이 검사하는 각 트랜잭션은 각 검사 SQL의 트랜잭션 순서를 엄격하게 보장할 수 있는 pt 도구와 달리 별개입니다. 그러나 일치하지 않는 데이터가 있는 경우 다시 확인하면 괜찮습니다. 실제로 제가 온라인에서 사용하는 동안에는 99.9% 정확했습니다.
테이블에 기본 키나 고유 인덱스가 있어야 합니다. 그렇지 않으면 프로그램이 확인하고 종료됩니다.
Varbinay, blob 및 기타 바이너리 필드는 복구를 지원하지 않습니다
사실 완전히 지원되지 않는 것은 아니며 사용 방법에 따라 다릅니다. 개발 중에 문자를 먼저 바이트로 변환한 후 mysql에 저장하는 경우 복구가 지원되지 않습니다. 이를 처리하는 방법이 있습니다. 즉, 소스 라이브러리에서 확인할 때 hex() 함수를 사용하고 SQL에서 unhex()를 복구한 후 다시 작성하는 것입니다.
4. 사용방법
이 Python 프로그램은 2.7을 기반으로 개발되었으며 2.6 및 3.x에서는 테스트되지 않았습니다. 사용하기 전에 MySQLdb 및 hotqueue를 설치해야 합니다:
$ sudo pip install MySQL-python hotqueue
비교할 테이블과 옵션은 완전히 구성되어야 합니다. 명령줄을 지정합니다(명령줄 매개변수를 사용하면 코드 양이 늘어납니다).
4.1 px-table-checksum.py
기본 프로그램, python px-table-checksum.py를 실행하여 일관성 검사를 수행하지만 다음 구성 파일 옵션을 이해해야 합니다.
4.2 settings_checksum.py
구성 옵션
CHUNK_SIZE: 매번 추출되는 청크 행 수
REDIS_INFO: Redis 대기열 주소 사용 지정
REDIS_QUEUE_CNT: Redis 대기열 수입니다. 소비자(대상 라이브러리)에는 대기열을 보호하는 일대일 스레드가 있습니다.
REDIS_POOL_CNT: 생산자(소스 라이브러리) Redis 클라이언트 연결 풀입니다. 이러한 설계는 GIL로 인해 발생하는 문제를 완화하고 큐에 넣는 쪽과 빼는 쪽을 분리하기 위한 것입니다. 테이블이 많으면 핫 큐 경합을 피하기 위해 짧은 시간에 많은 양의 SQL이 큐에 들어갈 수 있기 때문입니다.
CALC_CRC32_DB : True는 db 내부에서 체크섬 값을 계산한다는 뜻이고, False는 청크 데이터를 꺼내서 파이썬으로 계산한다는 뜻이다. 기본값은 연결 문자 집합을 기반으로 합니다.
DO_COMPARE: 동작 모드
0: 계산용 데이터만 추출하고 일관성 비교는 하지 않습니다. 나중에 모드 2: 계산 및 비교에서는
1개만 비교할 수 있습니다. 일반적으로 확인되는 테이블의 마지막 결과는 각 계산 전에 삭제됩니다. 비교 결과는 일치하지 않는 청크 번호만 알려줍니다.
2: 계산하지 않고 t_checkum 결과만 비교합니다. 일반적으로 사용되는 계산은 데이터베이스 리소스를 소비하며 기존 체크섬 계산 결과의 불일치만 비교할 수 있습니다. pt 도구의 --replicate-check-only 옵션과 유사합니다.
GEN_DATAFIX:
DO_COMPARE와 함께 사용되며 True인 경우 일관성 없는 청크에 대해 일관성 없는 특정 행을 찾고 False인 경우 복구 SQL을 생성한다는 의미입니다.
RUN_DATAFIX:
GEN_DATAFIX와 함께 사용되며 True인 경우 생성된 복구 SQL이 대상 라이브러리에서 실행된다는 의미입니다. 주의가 필요합니다. 수리를 설정했다면 완료 후 다시 False로 변경하는 것을 잊지 마세요. 그렇지 않으면 다음에 다른 테이블을 확인할 때 사고가 발생할 수 있으므로 이 옵션에 대한 확인 프롬프트를 특별히 추가했습니다.
DB_CHECKSUM: 체크섬 결과가 저장되는 위치를 지정하는 사전
구성 파일에 예제가 있으며, db_name을 지정해야 하며 테이블이 자동으로 생성됩니다.
4.3 settings_cs_tables.py
위 구성 파일은 프로그램을 제어하는 데 사용된다고 볼 수 있습니다. 이 구성 파일은 검증할 소스 및 대상 라이브러리 정보와 어떤 테이블을 지정할 것인지를 지정합니다. 확인됩니다.
TABLES_CHECK: 일관성을 확인할 테이블을 지정하는 사전입니다. db 이름은 키이고 여러 테이블 이름 목록은 값입니다. 전체 DB 확인은 현재 지원하지 않으며, 동시에 비교하는 테이블 수는 8개를 초과하지 않는 것이 좋습니다.
DB_SOURCE: 사전, 원본 데이터베이스의 연결 정보를 지정
DB_SOURCE: 사전, 대상 데이터베이스 정보의 연결을 지정