2013-01-08 3 views
9

가끔 모든 필드를 업데이트하고 때로는 하나만 제외하고 모든 필드를 업데이트하는 mySQL 업데이트 쿼리가 있습니다.업데이트 쿼리가 때때로 데이터베이스의 필드를 업데이트하지 않습니다.

통화 중 약 10 %가 실패합니다.

내 테이블은 다음과 같습니다

CREATE TABLE IF NOT EXISTS `grades` ( 
`id` int(11) NOT NULL AUTO_INCREMENT, 
`state` int(1) NOT NULL, 
`result` varchar(255) NOT NULL, 
`date_synced` datetime NOT NULL, 
`updated_at` datetime NOT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4395 ; 

내 쿼리는 다음과 같습니다

$sqlstr = "UPDATE grades SET result = '$result', state = 2, date_synced = '$date', updated_at = '$date' WHERE id = $id"; 

실패

은 결과, date_synced 및 updated_at이 업데이트되지만 상태가 변경되지 않습니다.

상태 필드 만 업데이트하고 간헐적으로 실패하는 쿼리가 있습니다.

테스트 환경에서 문제를 재현하지 못했습니다. 프로덕션 mySQL 데이터베이스 또는 잠금 충돌과 같은 문제가있을 수 있습니까?


자세한 정보가 있습니다. 나는 mysqli를 사용하고있다. 상태를 업데이트하는 다른 쿼리는 mysql을 사용합니다. 그게 문제가 되겠습니까?

나는 InnoDB가 행에 의해 잠겨 있다고 생각했다. 부분 행 업데이트를 허용하지 않습니다.


의견을 언급하는 또 다른 업데이트.

내 코드 흐름은 꽤 선형입니다.

The row is created with state=0. 
<flash stuff here> and the row is updated with state=1 
A cron job pulls all state=1 and sends an api call 
if api call is successful, the row is updated with state=2, result, date_synced, and updated_at 
if api call is error, the row is updated with state=3, result, and updated_at 

상태 필드는 0 (플래시 후) 또는 1 (API 호출 후)으로 설정되지 않습니다. date _synced와 result가 설정되었지만 (때로는) 상태가 여전히 1이므로 상태 필드에 대한 업데이트가 삭제되는 것과 같습니다.

업데이트 트리거를 추가하고 추가 정보가 있는지 확인합니다.

+3

디버깅을 위해 ID, 세션 ID 및 현재 사용자와 함께 이전 값과 새 값을 저장하는 업데이트 트리거와 로그 테이블을 추가해야합니다. 어쩌면 변경 사항이 통과되었지만 또 다른 문장으로 덮어 씌어졌습니다. –

+1

저는 Rufo 경의 의견이 귀하의 상황에 매우 도움이 될 수 있다고 생각합니다. 일이 일어나는 순서와 여러 개의 쿼리 결과가 나오는 더 복잡한 시나리오를 결정하는 데 도움이되기 때문입니다. 당신이보고있는 그림에서. – DWright

+1

"[..] 또는 같은 종류의 잠금 충돌 [..] 일종의 다른 필드가 업데이트되었으므로 잠금 문제가 없습니다. innodb이 잠글 수있는 가장 작은 것은 행입니다. 나는 하나의 필드를 잠글 수 없다. – scones

답변

1

"{n} 행이 영향을 받습니까?"

또한 반복 가능합니다. 정확히 동일한 데이터에서 동일한 쿼리를 실행할 수 있으며 다른 작업을 수행 할 수 있습니까?

그렇다면 손상된 설치 또는 손상된 데이터베이스가있을 수 있습니다.

테이블에서 & 최적화를 시도 했습니까? 그것은 도움이 될 수 있습니다. 사슴 사냥 용 총알 답변 죄송

:

SET sql_mode = 'TRADITIONAL'; 

및 PHP없이 콘솔에서 삽입을 시도 : P

0

는 기존에 MySQL의에서 "엄격"을 조정합니다. 그런 다음 설명 할 수있는 오류가 있는지 확인하십시오.

는로를 "용서"엄격 재설정 :
SET sql_mode = ''; 

또는

하여 데이터베이스에 연결이 같은 뭔가 다시 PHP를 통해 오류를 얻을 수있는 PDO 개체를 사용하는 경우 :

try { 
    $sqlstr = "UPDATE grades SET result = '$result', state = 2, date_synced = '$date',updated_at = '$date' WHERE id = $id"; 
$s = $pdo->exec($sqlstr); 
} 
catch (PDOException $e) { 
    $error = $e->getMessage(); 
    echo $error; 
} 

기본적으로, 무슨 일이 일어나고 있는지에 대한 오류 메시지를 얻는 데 필요한 모든 것을하십시오. SQL이 오류를 보낼 가능성이 가장 높지만 PHP가 스크립트에 오류를 표시하도록 설정되어 있지 않습니다.

+0

실제로, INT (1)이 잘 리거나 잘못 되었기 때문에 MySQL이 경고를 생성 할 가능성이 큽니다. 따라서 PHP는 경고를 무시하고 계속 진행할 수 있습니다. –

+1

FWIW, INT (1) 및 INT (1000000)는 저장 및 지원되는 값의 범위에 대해 정확히 동일합니다. 인수는 길이 제한이 아니며 표시 힌트입니다. MySQL의 INT는 항상 32 비트 데이터 유형입니다. –

0

'state'에서 'state_num'과 같은 다른 이름으로 필드의 이름을 변경해보십시오. MySQL의 예약어로 나열되어 있지는 않지만 이름이 문제를 일으킬 수 있습니다.

0

"상태"및 기타 필드를 설정하는 쿼리는 두 번 실행되며 때로는 작업 중 하나가 다른 작업보다 빠르게 완료됩니다. 모든 필드를 업데이트하고 해당 작업을 호출 한 스크립트는 "상태"필드를 업데이트하는 MySQL 쿼리도 실행합니다.

예를 들어, exec()를 통해 백그라운드에서 쉘 명령 "tar"을 실행하고 완료 후 DB에 "state"를 설정하는 PHP 스크립트가 있습니다. PHP 코드의 다음 문자열은 데이터베이스의 "상태"를 업데이트합니다. 하지만 가끔 bash 명령을 호출하면 PHP 스크립트가 MySQL 업데이트를 호출하는 것보다 빠르게 실행됩니다 (bash 명령이 백그라운드 모드로 실행되는 경우).

첫 번째 단계 : 날짜를 완료, 업데이트, 다른 필드 후 "상태가"= 3 (추가 처리를 기다립니다) 설정 PHP에서 실행 bash는 스크립트 등

다음 단계 : 간부 인 후 당신의 PHP()는 설정에서 "상태"= 2 (진행 중). 이 경우 백그라운드에서 bash 스크립트가 MySQL 업데이트 쿼리를 실행하는 것보다 빠르게 작업을 수행하면 업데이트 된 날짜 값과 "state"= 2 (하지만 1 초 전의 값 = 3)가 표시됩니다.

이 문제가 발생했습니다.

관련 문제