2012-03-23 5 views
1

MySQL 테이블에서 증분 업데이트를 추출하고 싶습니다. 해당 테이블에는 자동 증분 ID 필드와 모든 변경 (INSERT/UPDATE)시 현재 타임 스탬프로 업데이트되는 updated_at 필드가 있습니다. 레코드는이 테이블에서 삭제되지 않습니다.MySQL 테이블에서 증분 업데이트 추출

스크립트의 마지막 실행 이후이 테이블에서 새로 생성되고 업데이트 된 모든 레코드를 추출하고 싶습니다. 마지막 실행에서 가장 높은 updated_at 값을 알고 있습니다. 따라서 레코드를 추출하는 주요 쿼리는 다음과 같습니다.

SELECT * FROM table WHERE updated_at >= :last_seen_updated_at 

가장 좋은 방법은 무엇입니까? 모든 새롭고 업데이트 된 기록을 추출 할 수 있는지 100 % 확신해야합니다. 몇 가지 질문 및 염려 사항 :

  • 여러 초 기록이 업데이트 될 수 있으며 그 중 일부는 이전 추출 실행에 포함될 수 있으며 그 중 일부는 업데이트되지 않을 수 있습니다. (예 : 추출기가 초의 첫 번째 절반에서 실행되는 반면 레코드는 초의 두 번째 절반에서 업데이트 될 수 있습니다.)
  • 하나의 큰 SELECT 쿼리를 사용해야합니까? 아니면 여러 쿼리를 사용하여 X 레코드의 배치를 추출해야합니까? ? 추출 할 데이터 양이 클 수 있습니다. 일괄 처리를 사용하는 경우 다른 쿼리간에 레코드가 업데이트 될 수 있습니다.
  • 중복 레코드를 추출하지 않아야하지만 큰 문제는 아닙니다. (예를 들어 updated_at >= :last_seen_updated_at - INTERVAL 1 MINUTE) 내가? REPEATABLE READ 이러한 쿼리를 실행해야합니까 격리 모드
  • ? SERIALIZABLE?
  • MySQL의 D? "안전을 위해", 마지막으로 본 갱신하기 전에 시간의 X 금액을 시작하는 의미가 atabase는 복제 된 슬레이브이며 마스터 DB보다 다소 뒤떨어져 있습니다. 이것은 행이 포함되거나 포함되지 않을 때 어떤 영향을 미칠 수 있습니까?

답변

1

이것은 완전한 대답은 아니지만 중복을 피하는 확실한 방법입니다. 첫째, 업데이트 스크립트를 실행할 때 현재 스크립트를 실행하지 마십시오. 5 초가 넘는 모든 작업에서 실행하십시오. 그렇게하면 주어진 초에 대해 하나의 레코드가 있다면 그 초에 대한 모든 레코드가 있음을 알 수 있습니다. 이렇게하면 updated_at > :last_seen_updated_at을 사용할 수 있고 업데이트주기간에 중복을 피할 수 있습니다.

그 시점에서 배치 또는 하나의 큰 쿼리에서 자유롭게 추출해야합니다. 적어도 테이블을 설명했듯이 추출 할 데이터는 거의 정적 일 것입니다. 테이블에 다른 항목이 추가 될 수도 있지만 모두 임의적으로 처리됩니다. 최근 컷 - 오프 초, 그래서 귀하의 쿼리의 일부가되지 않습니다.

슬레이브/마스터 문제와 관련하여 약간 우려 될 수 있지만 마스터가 이전 레코드를 먼저 업데이트하는 한 여전히 해결하기가 쉽습니다. 업데이트 컷오프를 설정할 때 로컬 레코드에서 가장 최근의 시간대를 찾아 1 초를 뺍니다.

주목하고있는 시간 영역에서 추가되거나 업데이트 된 항목이 추출 중에 다시 업데이트 될 수 있다는 우려가 있습니다. 이를 막기위한 유일한 방법은 추출하는 동안 서버에서 연결을 끊고 변경 사항을 버퍼하는 것입니다.하지만 추가 및 수정이 상대적으로 적은 경우 스크립트를 다시 실행하여 발생률을 크게 줄일 수 있습니다 큰 그룹을 추출하는 동안 발생했습니다. 편집증 영장을 느끼는 것처럼 반복 할 수 있습니다. 또는 추출 전 행 수를 계산하고 추출한 수를 계산할 수 있습니다. 차이가있는 경우 이전과 이후에 같은 번호가 나타날 때까지 프로세스를 다시 실행할 수 있습니다.