일시적인 가비지가 수집됩니까?


61

이 질문은 wp_options의 Transient RSS 피드가 자동으로 제거되지 않는다고 생각했습니다 .

과도는 만료되어 삭제되어야합니다. 그러나 내가 처리하는 것을 볼 수있는 유일한 방법은 일시적이 만료되고 요청 된 다음 요청하는 동안 삭제됩니다.

과도기가 만료되었지만 그 이후에 요청되지 않으면 어떻게됩니까? Codex의 설명에서 일종의 가비지 수집이 암시되어 있다고 생각했습니다. 이제 확실하지 않아서 그러한 코드를 수행하는 코드를 찾을 수 없습니다.

그렇다면 데이터베이스에 영원히 갇혀 있습니까?


이론적으로 cron을 실행할 때 제거해야합니다 (만료 된 경우)
onetrickpony

1
@Ambitious Amoeba 그래, 나는 그 문제에 대해 언급했다. 내 요점은-일시적인 생성이 요청 될 것이라고 가정하거나 보장하지는 않습니다. 원래의 질문을 강조 - 나는 결코 경우 만료 과도은 삭제됩니다 때 경우에 얻을 그것을?
Rarst

1
만료 된 데이터를 정리한다고 가정하지만 그렇습니다. 삭제되지 않는 상황이 있습니다. 과도를 사용하는 위젯을 제거하는 것과 같습니다. trac에 대한 티켓을 제출해야합니다 :)
onetrickpony

1
@Rarst-패치를 작성하고 trac에 제출하기에 완벽한 것 같습니까?
MikeSchinkel

답변:


45

그들은 지금

데이터베이스 업그레이드시 WordPress 3.7부터 만료 된 임시 항목이 삭제됩니다 ( # 20316 참조) .


이전 답변

누군가 나에게 달리 보여줄 수 없다면, 일시적으로 과도 현상이 가비지 수집되지 않는 것 같습니다. 더 나쁜 것은 옵션과 달리 데이터베이스에 저장되지 않는다는 것입니다. 따라서 모든 과도 목록을 가져 와서 만료 여부를 확인할 수있는 확실한 방법은 없습니다.

데이터베이스가 스토리지에 사용되는 경우 가비지 콜렉션을 수행하는 임시 임시 코드 :

add_action( 'wp_scheduled_delete', 'delete_expired_db_transients' );

function delete_expired_db_transients() {

    global $wpdb, $_wp_using_ext_object_cache;

    if( $_wp_using_ext_object_cache )
        return;

    $time = isset ( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time() ;
    $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};" );

    foreach( $expired as $transient ) {

        $key = str_replace('_transient_timeout_', '', $transient);
        delete_transient($key);
    }
}

$ time = $ _SERVER [ 'REQUEST_TIME']; 그런 다음 SQL 쿼리에서 $ time을 사용하십시오. SQL 주입을 방지하기 위해 $ _SERVER 변수 / 값을보다 신중하게 다루십시오.
hakre

@hakre hm ... PHP 성능에 대한 프레젠테이션에서 time()버그를 유발할 수있는 사용을 권장합니다 (실행은 본질적으로 즉각적이지 않습니다). 요청 시간은 PHP 자체에서 설정하고 있으며 사용자가 제공 한 데이터는 아닙니다. 왜이 취약점이 있습니까?
Rarst

@Rarst : 나는 그것을 사용해서는 안된다고 말하지 않았고 SQL 쿼리 내부에서 사용되도록 안전하게 인코딩되어야합니다. 외부 소스의 모든 변수에 대해이 작업을 수행해야합니다. $ _SERVER 변수가 예상대로 설정되지 않고 요청하는 사용자도 설정 될 수 있습니다. 좋은 코딩 방법을 전파하고 싶었습니다. 항상 그렇듯이 실제 가용성 상태에 대해 알아 보려면 문서를 참조하십시오. 예를 들어 PHP 4의 경우 그러한 변수가 존재하지 않고 사용자 정의 헤더 또는 환경 변수로 덮어 쓸 수 있습니다 -php.net/manual/en/reserved.variables.server.php
hakre

@hakre 고정 (생각합니다), PHP4 알림 btw 감사합니다 (WordPress가 지원을 중단 할 때까지 기다릴 수 없습니다)
Rarst

그것은 내 눈에 훨씬 좋아 보인다;). 우연히 만 과도기를 전부 또는 전혀 삭제할 수없는 time () 및 음의 정수에 문제가 없기를 바랍니다. P : 실행중인 시스템을 신뢰하지 마십시오
hakre

20

다시 말하고 다시 서식을 지정하여 토론의 일부 의견을 답변으로 옮깁니다.

기본적으로, 극단적 인 경우가 아니라면 실제로 "쓰레기 수거"일 필요는 없습니다. 당신이 그들을 가져 오지 않으면, 그들이 있는지 여부는 중요하지 않습니다.

과도는 기본적으로 옵션 테이블에 저장되어 있습니다. 기본 설치에서 옵션 테이블에는 100 개의 항목이있을 수 있습니다. 각 과도는 항목을 두 개 더 추가하지만 수천 개가 있어도 자동로드되지 않기 때문에 사이트 속도에 영향을 미치지 않습니다.

시작할 때 WordPress는 옵션을 메모리에로드하지만 자동로드 플래그가 설정된 옵션 만로드합니다. 과도는 이것을 얻지 못하므로 메모리에로드되지 않습니다. 나중에 실제로 사용되는 과도 전류 만 비용이 발생합니다.

데이터베이스의 관점에서 옵션 테이블에는 옵션 ID와 옵션 이름 모두에 대한 인덱스가 있습니다. 과도는 항상 이름 (키)을 기준으로로드되므로 단일 고유 키 값에서 항상 간단한 선택을 수행합니다. 따라서 조회는 O (log (n))이며 매우 빠릅니다. log (n)의 Big-O를 사용하면 눈에 띄기 전에 수백만 행과 수백만 행에 들어가야합니다. 솔직히, 실제 데이터 전송과 함께 쿼리 설정 및 해제의 오버 헤드가 더 길어집니다. 쿼리 자체는 본질적으로 제로 시간으로 실행됩니다. 따라서 사용하지 않는 행 추가하면 추가 디스크 공간을 사용하는 것 외에는 아무런 영향을 미치지 않습니다.

데이터베이스에서 인덱싱은이면에서 무슨 일이 일어나고 있는지 실제로 이해하지 못하는 사람들에게는 이해가되지 않는 심도있는 아이디어 중 하나입니다. 데이터베이스는 처음부터 빠른 데이터 검색을 위해 설계되었으며 문제없이 이러한 종류의 작업을 처리 할 수 ​​있습니다. 이것은 꽤 잘 읽습니다 : http://en.wikipedia.org/wiki/Index_(database )

이제 가장 명확한 방법으로 정리 (SQL DELETE 호출)해도 실제로 데이터베이스에서 삭제되지는 않습니다. 색인에서 그것들을 제거하고 행을 "삭제됨"으로 표시합니다. 다시, 이것은 데이터베이스 작동 방식입니다. 실제로 디스크 공간을 정리하려면 나중에 계속해서 OPTIMIZE TABLE을 수행해야하며 이는 빠른 조작이 아닙니다. 시간이 걸린다. 아마 가치보다 더 많은 시간. 전체 CPU 시간을 절약하기에 충분하지 않을 수 있습니다.

사용하지 않는 새로운 과도 현상을 지속적으로 삽입하는 경우가 있지만 대신 근본적인 문제를 찾아야합니다. 이 과도를 삽입하는 것은 무엇입니까? 변경 또는 변경 키를 사용하고 있습니까? 그렇다면 플러그인 또는 코드를 일으키는 코드는 기본적으로 수정되어서는 안됩니다. 코드를 올바르게 작성하지 않는 코드도 검색하지 않으므로 필요한 것보다 많은 작업을 수행 할 가능성이 높기 때문에 더 유용합니다.

반면에 모든 게시물과 같은 것을 위해 과도 현상이 발생하는 경우가 있습니다. 이것은 실제로 완벽하게 수용 가능할 수 있습니다. Facebook에서 들어오는 의견을 저장하기 위해 SFC에서 직접이 작업을 수행합니다. 각 게시물에는 이와 관련된 잠재적 인 과도 현상이 있으며 이는 게시물 당 두 개의 추가 행을 의미합니다. 게시물이 10k 인 경우 옵션 테이블에 결과적으로 20k 개의 행이 있습니다. 데이터베이스가 실제로 관리하는 한 100 행과 20,000 행 사이에는 거의 차이가 없기 때문에 이것은 나쁘거나 느리지 않습니다. 모두 색인화되었습니다. 도대체 빠릅니다. 서브-밀리 밀리 초

당신이 수백만 행에 들어가기 시작할 때 , 나는 걱정할 것입니다. 옵션 테이블 크기가 수백 메가 바이트 이상으로 증가하면 자세히 살펴볼 정도로 충분히 걱정할 것입니다. 그러나 일반적으로 말하자면 극단적 인 경우를 제외하고는 문제가되지 않습니다. 수십만 개의 게시물이있는 대형 뉴스 사이트보다 작은 것에는 문제가되지 않습니다. 그리고 문제가되기에 충분한 사이트라면 어떤 종류의 외부 객체 캐시를 사용해야합니다. 경우 일시적인 데이터는 데이터베이스 대신 자동으로 저장됩니다.


1
NB : 만료 없는 과도 상태 가 자동으로로드되고 만료가 기본값 이 없으므로 응용 프로그램 / 플러그인이 많은 과도 현상을 생성하고 만료를 설정하지 않는 경우 모든 페이지 / 포스트로드에서 메모리 청크를 사용합니다.
웹웨어

"만료없는 일시적인"을 사용할 이유는 없습니다. 기본적으로 일반 "옵션"과 동일하기 때문입니다.
Otto

1
물론 입니다. 기본값 입니다. 따라서 많은 플러그인 작성자는 만료되지 않는 과도기를 추가하고 있습니다.
웹웨어

1
글쎄, 여기의 해결책은 간단합니다. 해당 플러그인을 사용하지 마십시오. 그들은 잘못하고 있습니다. 과도는 세션으로 사용되지 않으며 의미있는 만료없이 사용해서는 안되며 키를 변경하거나 변경하지 않아야합니다.
Otto

2
7 일 말해봐 플러그인 / 테마 작성자가 더 크거나 작은 것을 원하면 지정합니다. 자동로드를 원한다면 만료 (= 무한대)에 0을 지정하지 않아도되지만, 현재는 만료 매개 변수가 예 / 아니요 자동로드 매개 변수로 이중 듀티를 수행하는 것입니다. 어느 쪽이든, 기본 만료는 autoload = yes로 기본 설정되지 않아야합니다. 그것은 단지 문제를 요구하는 것입니다.
webaware

18

오토-나는 당신에 더 동의하지 못했습니다. 문제는 결국 모든 과도 상태에서 테이블 크기가 어리 석다는 것입니다. 수백만 줄이 걸리지 않습니다. 현재 130k 개가 넘는 행이 있고 정기적으로 중단되는 옵션 테이블을 처리하고 있습니다. 값 필드는 큰 텍스트 유형이므로 "자동로드"행만 찾으더라도 성능이 악몽이됩니다. 이러한 값 필드는 나머지 행 데이터와 별도로 저장됩니다. 논리적으로 동일한 테이블의 일부이지만 원하는 행을 가져 오려면 조인이 발생해야합니다. 필요한 데이터가 디스크의 모든 곳에 퍼져 있기 때문에 이제 영원히 걸리는 조인. 프로파일 링 (mysql 용 jet profiler 사용)이 이것을 입증했습니다.

클러스터 된 키에 자동로드를 추가하면이 문제를 해결하는 데 도움이 될 수 있습니다. 예를 들어, ID ASC 인 Autoload Desc에서의 클러스터링은 모든 자동로드 행이 디스크에서 먼저 묶일 수 있도록합니다. 그럼에도 불구하고 DB 관점에서 큰 부담을보고 있다고 생각합니다.

개인적으로 저는이 시스템의 디자인이 문제라고 생각합니다. 옵션 테이블은 많은 것들에 대한 일반적인 포괄으로 바뀌 었습니다. 값 필드가 나머지 행 데이터와 동일한 페이지에 포함되기에 충분히 작고 효과적으로 색인을 생성 할 수 있으면 좋습니다. 불행히도 그렇지 않습니다. 이것을 설계 한 사람은 DB101 클래스로 돌아 가야합니다.


5
사실, 그러나 WordPress 개발이 시작되었을 때 아무도 옵션 테이블을 데이터 스토리지로 사용하는 수천 개의 플러그인을 가질 것이라고 생각하지 않았습니다. :
onetrickpony

그것은 항상 당신의 시간을 가지고 일을 잘 할 중요한 이유 @onetrickpony 그것은 당신이 거대한 언젠가 여부 될 것으로 기대 여부입니다 :)
마흐무드 알 - Qudsi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.