2012-10-16 3 views
4

이 유형의 질문은 몇 번 게시되었지만 다음과 같은 경우에는 제공되는 솔루션이 이상적이지 않습니다. 첫 번째 쿼리에서이 첫 번째 쿼리가 실행될 때 내가 알고있는 테이블 이름을 선택합니다. 그런 다음 반복하면서 선택한 테이블의 레코드 수를 쿼리하려고하지만 여전히 존재하는 경우에만 쿼리를 실행합니다. 문제는 루프 중에 테이블의 일부가 다른 스크립트에 의해 삭제된다는 것입니다. 예를 들어 :mysql이 아닌 고유, 테이블이 존재하는 경우에만 선택

SELECT tablename FROM table 
-- returns say 100 tables 

while (%tables){ 
    SELECT COUNT(*) FROM $table 
    -- by the time it gets to the umpteenth table, it's been dropped 
    -- so the SELECT COUNT(*) fails 
} 

그리고, 그것은 크론에 의해 실행 있기 때문에 내 생각, 그것은 fataly 실패하고 나는 그것이 실패라는 크론에서 이메일을 전송받을.

DBD :: mysql을 :: 일 실행에 실패했습니다 테이블 'XXX'는 /usr/local/lib/perl/5.10.1/Mysql.pm 라인에 존재하지 않는 175

스크립트는 더 이상 사용되지 않는 Mysql.pm perl 모듈을 사용하고 있습니다.

+0

예외 처리 ??? – Khaleel

+0

새로운 사용자 팁 : 유용하다고 판단되면 upvote/accept를 사용할 수 있습니다. 그리고 아마도 당신의 질문과 관련된 mysql 엔진 버전을 포함해야한다. –

+1

거래를 사용해 보셨습니까? –

답변

1

분명히 쿼리를 실행하기 전에 삭제되지 않도록 테이블을 보호해야합니다. 일종의 테이블 잠금으로 시작하면 가능한 드롭을 피하기 위해 다른 곳에서 발행 된 DROP TABLE 쿼리가 잠금 오류와 함께 실패하거나 SELECT가 끝날 때까지 기다릴 것임을 명심하십시오. 테이블을 삭제하는 것은 실제로 자주 사용되는 작업이 아니므로 대부분의 경우 서버 작업 중에 스키마 디자인이 지속됩니다. 관찰하는 것은 매우 드문 동작입니다. 일반적으로, 다른 쿼리 중에 테이블이 삭제되는 것을 막을 수는 없지만, 아래 문서에 대한 설명에서이를 달성하기 위해 세마포 테이블을 사용하는 트릭을 발견 할 수 있습니다.

http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html

"A 테이블 잠금은 읽기 부적절 방지 또는 다른 세션에 의해 기록합니다. 세션은 DROP 테이블과 테이블 수준의 작업을 수행 할 수 있습니다, 심지어 읽기 잠금, 잠금을 보유. 작업이 없습니다 잘라 내기 트랜잭션이 안전하므로 세션이 활성 트랜잭션 또는 테이블 잠금을 유지하는 동안 세션을 시도하면 오류가 발생합니다. "

"읽기 또는 쓰기 잠금 (테이블 삭제 또는 잘라내 기와 같은)에서 정상적으로 지원되지 않는 테이블을 사용해야하는 경우 협조 할 수 있습니다. 세마포 테이블을 사용하여 첫 번째 세션에서 세마포어 테이블에 대한 읽기 또는 쓰기 잠금을 적절하게 가져옵니다. 두 번째 세션에서는 다른 모든 테이블과 관련된 모든 작업을 수행하십시오. "

+0

그게 정확히 내가 필요로하는 것 같은데. 스토리지 엔진 MyISAM, MySQL 버전입니다 : 5.0.95. 초기 쿼리에서 어떻게 잠그고 완료되면 잠금을 해제합니까? 나는 지금 그것에 대해 조사를 할 것이다. 감사. – user1749141

+0

은 원시 SQL 코드에서만 작동합니다. 나는 MySQL 펄 모듈을 사용하고있다. – user1749141

1

당신은 perl 코드를 eval 블록에 넣음으로써 실패로부터 보호 할 수 있어야합니다. 뭐 그런 :

eval { 
    # try doing something with DBD::mysql 
}; 
if ([email protected]) { 
    # oops, mysql code failed. 
    # probably need to try it again 
} 

심지어는에 넣고

것은 당신이 포스트 그레스와 같은 더 나은 서버를 사용하는 경우 루프 "하면서"최적의 솔루션 트랜잭션에 모든 것을 묶어야하는 것입니다. 그러나, MySQL에서 테이블을 떨어 뜨리는 것은 트랜잭션에 의해 보호되지 않습니다.

+0

루프가 반복되는 동안 (각 반복에는 2 ~ 2 초 걸림) while 루프에 문제가 있습니다. 다른 스크립트에 의해 테이블이 삭제됩니다. Innodb 엔진을 사용하는 최신 버전의 mysql도 트랜잭션을 지원한다. 내가 잠에서 깨면 평가판을 시험해 볼거야. 일반적으로 다음과 같은 것을 사용합니다 : if ($ dbh-> execute)는 에러를 트랩하지만 cron 버전은 죽어 가고 있습니다. – user1749141

+0

Eval도이를 잡지 못했습니다. 아직도 cron notifs를 얻는 중입니다. Cron 명령은 다음과 같습니다. */1 * * * * /x.cgi 2> & 1>/dev/null – user1749141

+0

테이블 이름이있는 원본 select의 결과를 배열 또는 해시에 저장할 수 있어야합니다. 그런 다음 해당 목표 테이블 목록을 순환하여 "SELECT count (*) from tableN"을 수행하십시오. 그러나, 그 진술을 할 때, 그것을 eval 블록에 넣으십시오. 이것은 확실히 작동해야합니다 - cron 또는 아닙니다. 디버깅을 위해 수동으로 목표 테이블 목록에 정크 이름을 넣을 수 있습니다. – mvp

관련 문제