PDO ATTR_PERSINT에 대한 완전한 이해
질문:.
PDO를 사용할 때 지속적인 연결 관리 뒤에 있는 규칙/논리는 무엇입니까?
환경:
웹 서버
- Windows 7 x64
- 16GB RAM이 있는 듀얼 코어
- Apache 2.2.17
- PHP 5.3.5
- IP 주소, 포트, 서비스 이름 등을 사용하여 DSN 문자열을 통해 연결하는 중...
- DB conn에 대한 ODBC 없음(지금 2시간 동안 DB conn을 생성하려고 했습니다. Oracle 감사합니다!)
DB 서버
- 리눅스 기반 Oracle 10g
- 4GB RAM이 있는 멀티 코어
- 내 웹 앱을 위해 특별히 만들어진 사용자 이름(예, 가짜입니다)
- 사용자: 웹 사용자
내가 이해한 바/의견:
비영구 연결
<?php
// Open a new connection
// Session created in Oracle
$dbh = new PDO('DSN', 'webuser', 'password');
// webuser is active in v$session with a SID=1
$dbh = NULL;
// webuser removed from v$session
// Manually calling $dbh = NULL; will remove the session from v$session
// OR
// Wait for script EOL so a kill-session command is sent to Oracle?
?>
- 프레임워크 오버헤드 등을 사용하여 스크립트를 안정적으로 실행하는 데 약 0.09초가 소요됩니다.
영구 연결
<?php
// Open a new connection and make it persistent
// Session created in Oracle
// Is Apache maintaining some sort of keep-alive with Oracle here?
// because I thought php.exe is only alive for the duration of the script
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));
// webuser is active in v$session with a SID=1
$dbh = NULL;
// webuser is still active in v$session with a SID=1
$dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE));
// webuser is still active in v$session with a SID=1
// Manually calling $dbh = NULL; does not kill session
// OR
// Script EOL does not kill session
// ^^ this is good, just as expected
?>
- 프레임워크 오버헤드 등으로 초기 방문 시 스크립트를 실행하는 데 최대 0.12초 소요...
- 후속 실행 take ~.04
문제:
는 그 하고 는나페를방고하문이지,▁and고▁the▁i▁page,webuser
을 SID=1
그하고 내동가페방문고하를지이료,▁and고▁the▁my하▁visits▁page방,webuser
추정를얻습다니보를 가져옵니다.SID=2
이새헹굼, 및 <->
새로운 방문자가 다시 사용해야 하지 않나요?SID=1
?
모든 답변, 제안, 대체 테스트 요청, 읽기 자료 링크를 환영합니다.
은 미미한 RTFM만을 했습니다.Advantages of Persistent vs. Non-persistent
블로그
아파치 관점
Apache에는 상위 프로세스가 하나 있습니다.이 프로세스는 웹 서버로 오는 모든 요청을 처리하는 하위 프로세스를 만듭니다.될 때 은 " " " 에 됩니다.StartServers
는 파일 이름으로 제공됩니다.에 따라 합니다.ServerLimit
도달했습니다.
PHP 및 영구 연결
PHP(스크립트 실행 종료 시 CGI가 해제되므로 mod_php로 실행)가 요청에 대한 데이터베이스와의 지속적인 연결을 설정하라는 메시지가 표시되면 스크립트가 완료된 후에도 이 연결은 유지됩니다.현재 보류 중인 연결은 요청이 처리된 Apache 자식 프로세스와 데이터베이스 서버 간의 연결이며 이 정확한 자식 프로세스에 의해 처리되는 모든 요청에 의해 재사용될 수 있습니다.
어떤 이유로(정확하게 이유를 묻지 않음) 하위 프로세스가 실제 요청보다 오래 사용되고 있고 다른 요청이 들어오면 상위 아파치 프로세스는 이 요청을 (새) 하위 프로세스로 리디렉션하여 현재까지 데이터베이스에 대한 연결을 설정하지 않았을 수 있습니다.스크립트를 실행하는 동안 SID를 올려야 하는 경우 관찰한 대로 SID를 높입니다.이제 아파치의 두 가지 자식 프로세스에 의해 두 개의 연결이 유지됩니다.
명심하세요...
이것은 또한 많은 문제를 일으킬 수 있다는 것을 알아야 합니다.스크립트 실행 중에 무한 루프가 발생하거나 트랜잭션이 중단되거나 일부 오류가 발생할 수 있는 경우 연결이 차단되어 다시 사용할 수 없습니다.또한 데이터베이스의 사용 가능한 모든 연결이 사용되지만 데이터베이스에 액세스하려는 Apache 서버의 다른 하위 프로세스가 있을 수 있습니다.데이터베이스 또는 Apache에 의해 연결이 해제될 때까지(시간 초과 또는 종료에 의해 자발적으로) 이 프로세스는 당분간 차단됩니다.이 항목에 대한 자세한 내용은 다음 페이지를 참조하십시오. http://www.php.net/manual/en/features.persistent-connections.php
저는 우리가 댓글 대화에서 논의한 모든 것을 정확하게 요약하고, 잊은 것이 없기를 바랍니다.그렇다면 힌트를 남겨주시면 추가하겠습니다 :)
편집:
저는 방금 이 댓글에 언급된 @MonkeyZeus 기사를 다 읽었습니다.위에서 요약한 프로세스에 대해 설명하고 영구 연결과 함께 더 잘 작동하도록 Apache 서버를 최적화하는 방법에 대한 유용한 정보를 제공합니다.그러나 오라클 데이터베이스 백엔드와 함께 또는 없이 사용할 수 있습니다.당신은 다음을 살펴봐야 합니다:
이점
영구 연결은 스크립트 실행이 종료될 때 닫히지 않는 링크입니다.영구 연결이 요청되면 PHP는 동일한 영구 연결이 이미 있는지 확인합니다(이전부터 열려 있음). 그리고 연결이 존재하는 경우 해당 연결을 사용합니다.존재하지 않는 경우 링크가 생성됩니다.
영구 연결을 사용하는 이유는 물론 비용이 많이 드는 연결 수를 줄이기 때문입니다. MySQL은 대부분의 다른 데이터베이스보다 훨씬 빠르지만 말입니다.
문제들
영구 연결을 사용하는 동안 테이블 잠금에 몇 가지 문제가 있습니다.
어떤 이유로든 스크립트가 잠금을 해제할 수 없는 경우 동일한 연결을 사용하는 후속 스크립트는 무기한 차단되며 httpd 서버 또는 데이터베이스 서버를 재시작해야 할 수 있습니다.
또 하나는 mysql commit에 의한 트랜잭션을 사용할 때입니다.
트랜잭션 블록은 또한 스크립트 실행이 트랜잭션 블록보다 먼저 종료되는 경우 해당 연결을 사용하는 다음 스크립트로 전달됩니다.두 경우 모두 register_shutdown_function()을 사용하여 간단한 정리 함수를 등록하여 테이블 잠금을 해제하거나 트랜잭션을 롤백할 수 있습니다.
지속적인 연결의 단점에 대한 이 질문을 읽는 것이 좋습니다.
PDO는 그런 식으로 좀 재미있습니다.동일한 사용자/방문자라도 두 번째 또는 세 번째 인스턴스를 생성할 수 있습니다.DB 쿼리의 성능을 테스트하는 동안 로컬 컴퓨터에서 동일한 현상이 발생했습니다.
이러한 인스턴스는 조만간 시간 초과되므로 정확한 시간 초과는 서버 구성에 따라 달라집니다.
왜 그런 일이 일어날까요?현재 인스턴스가 사용 중이면 새 인스턴스가 생성되고 오래된 인스턴스가 조만간 시간 초과됩니다.적어도 그것은 나에게 논리적으로 보입니다.
최근에 당신과 비슷한 문제를 겪었기 때문에 다음과 같이 관찰했습니다.MySQL 서버는 계속해서 새로운 연결을 열었고 사용할 수 있는 유휴 연결이 많음에도 불구하고 MySQL 서버에 대한 동시 연결 수를 초과했습니다.
설정PDO::ATTR_PERSISTENT => true
사용 가능한 유휴 연결을 재사용합니다.MySQL 프로세스를 모니터링하려고 하면 보고서가 다시 전송되는 시간 동안 유휴 연결이 다른 프로세스에 의해 활성화되었을 수 있기 때문에 얼핏 보기에는 이렇게 보이지 않을 수 있습니다.
전체적으로 영구 연결을 사용하지 않는 대신 유휴 연결 수가 감소합니다.테이블 잠금 문제와 관련하여 MyISAM Storage Engine에서는 테이블 잠금이 아닌 행 수준 잠금을 사용하기 때문에 테이블에 InnoDB Storage Engine을 사용하기로 결정했습니다.
이 InnoDB Storage Engine과 PDO persistent Connection의 조합을 사용할 때 아직 동시성에 문제가 발생한 적이 없습니다.
또한 잘못 실행된 쿼리가 테이블을 잠그는 것을 방지하기 위해 쿼리를 Try-catch Block 내에 유지합니다.
언급URL : https://stackoverflow.com/questions/23432948/fully-understanding-pdo-attr-persistent
'programing' 카테고리의 다른 글
없음 값이란 무엇입니까? (0) | 2023.07.23 |
---|---|
C에서 정적 라이브러리에 링크하는 방법은 무엇입니까? (0) | 2023.07.23 |
PHP에서 call_user_func_array를 사용하여 생성자를 호출하는 방법 (0) | 2023.07.23 |
pip 요구 사항 파일을 사용하여 패키지를 제거하고 설치하려면 어떻게 해야 합니까? (0) | 2023.07.18 |
Android API 버전을 프로그래밍 방식으로 검색하는 중 (0) | 2023.07.18 |