Чи збираються перехідні сміття?


61

Це питання змусило мене думати, що транзиторні RSS-канали у wp_options не видаляються автоматично?

Передбачається, що перехідні періоди закінчуються та видаляються. Однак єдиний спосіб, коли я бачу, що це обробляється - це коли термін тимчасового терміну закінчується і запитується, тоді він видаляється під час запиту.

Що робити, якщо термін минулого закінчився, але після цього його ніколи не просять? З опису в Codex я подумав, що мається на увазі якесь збирання сміття. Зараз я не настільки впевнений і не можу знайти жодного коду, який виконує таке.

Тож він просто назавжди застряже в базі даних?


теоретично їх слід видалити під час запуску
крона

1
@ Амбітна Амеба, так, я якось згадав про це в питанні. Моя думка - тимчасове, що створюється, не передбачає і не гарантує, що його коли-небудь вимагатимуть. Наголошуючи на первісному запитанні - коли і якщо термін дії терміну придатності видаляється, якщо я його ніколи не отримую ?
Рарст

1
Це передбачає, що ви очищаєте дані, що втратили чинність, але так, ви праві, є ситуації, коли вони ніколи не будуть видалені. Як видалення віджета, який використовує перехідні процеси. Ви повинні подати квиток на trac для цього :)
onetrickpony

1
@Rarst - Здається, як ідеальна річ написати патч і подати на trac?
MikeSchinkel

1
Білет, пов’язаний з поїздкою
Стівен Харріс

Відповіді:


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 - не робіть цього. Більш ретельно попрацюйте з змінними / значеннями $ _SERVER, щоб запобігти ін'єкції SQL.
хакре

@hakre hm ... Я вибрав це з презентації щодо продуктивності PHP, яка рекомендувала його над використанням, time()що може спричинити помилки (виконання не миттєве за своєю природою). Час запиту встановлюється самим PHP, не надходить із будь-яких даних, що надаються користувачем. Чому така вразливість?
Рарст

@Rarst: Я не сказав, що ви не повинні використовувати його, ви повинні просто переконатися, що він безпечно закодований для використання всередині запиту SQL. Ви повинні робити це з кожною змінною із зовнішнього джерела. $ _SERVER змінні можуть бути встановлені не так, як очікувалося, а натомість встановлені запитуючим користувачем навіть. Я хотів лише поширити якусь хорошу практику кодування. Як завжди, щоб дізнатися про реальний стан доступності, дивіться документи. Наприклад, для PHP 4 такої змінної не існує, і вона може бути перезаписана користувацькою змінною заголовка чи середовища - php.net/manual/en/reserved.variables.server.php
hakre

@hakre виправлено (я думаю), дякую за нагадування PHP4 btw (я не можу дочекатися, коли WordPress
скасує

Це в моїх очах виглядає набагато краще;). Будемо сподіватися, що не існує жодних проблем із часом () та мінус-цілими числами, які могли б видалити всі або без перехідних випадків, ніж випадково. Ніколи не довіряйте запущеній системі: P
hakre

20

Переміщення деяких коментарів із обговорення у відповідь із переформулюванням та переформатуванням.

В основному, це зводиться до того, що якщо у вас є надзвичайно екстремальний випадок, їх насправді не потрібно "збирати сміттям". Якщо ви ніколи їх не отримуєте, то не має значення, вони там чи ні.

Дивіться, перехідні процеси за замовчуванням зберігаються в таблиці параметрів. У базовій установці в таблиці параметрів буде, можливо, 100 записів. Кожен перехідний додає ще два записи, але навіть якщо у вас їх тисячі, вони не впливають на швидкість сайту, оскільки вони не завантажуються автоматично.

При запуску WordPress завантажує параметри в пам'ять, але він завантажує лише параметри, у яких увімкнено прапор автозавантаження. Тимчасові не отримують цього, і тому не завантажуються в пам'ять. Тільки тимчасові, які фактично використовуються пізніше, понесуть витрати.

З точки зору бази даних, таблиця параметрів містить індекси як Id параметра, так і імені параметра. Перехідні файли завжди завантажуються на основі імені (ключа), і тому пошуки для них завжди прості, вибираються на одному унікальному значенні ключа. Таким чином, пошук є O (log (n)) і надшвидкий. З Big-O журналу (n) вам доведеться потрапляти в мільйони і мільйони рядків, перш ніж це стане помітним. Відверто кажучи, накладні витрати в налаштуванні та вилученні запиту, а також фактична передача даних, значно довші. Сам запит працює порівняно з нульовим часом порівняно. Тому просто наявність зайвих невикористаних рядків не впливає ні на що, крім використання додаткового місця на диску.

Індексація в базах даних - одна з тих глибоко читаних ідей, які не мають сенсу людям, які насправді не розуміють, що відбувається за лаштунками. Бази даних розроблені для швидкого пошуку даних з нуля і можуть обробляти подібні речі без проблем. Це досить вдале прочитання: http://en.wikipedia.org/wiki/Index_(database )

Тепер очищення найбільш очевидним способом (виклик SQL DELETE на них) насправді не видаляє їх із бази даних. Він просто видаляє їх з індексу і позначає рядок як "видалено". Знову ж таки, саме так працюють бази даних. Щоб фактично очистити простір на диску, вам слід продовжити і робити ОПТИМІЗАЦІЮ ТАБЛИЦІ після цього, і це не швидка операція. На це потрібен час. Напевно, більше часу, ніж варто. Це, мабуть, недостатньо, щоб загалом заощадити час процесора.

Якщо у вас є певний випадок, який спричиняє постійне введення нових перехідних процесів, які не використовуються, тоді вам потрібно знайти основну проблему. Що вставляє ці перехідні? Чи використовують клавішу, що змінюється або мутує? Якщо так, то плагін або код, що викликає це, слід виправити, в основному, не робити цього. Це буде корисніше, тому що, ймовірно, код, який не створює їх належним чином, також не отримує їх, і, таким чином, виконує більше роботи, ніж це доводиться робити.

З іншого боку, може бути випадок, коли створюються перехідні періоди для чогось подібного до кожної посади. Це дійсно може бути цілком прийнятним. Я роблю це сам у SFC, щоб зберігати вхідні коментарі з Facebook. Кожна публікація пов'язана з потенційним перехідним періодом, що означає два додаткових рядки на посаду. Якщо у вас є 10 000 повідомлень, у таблиці параметрів (зрештою) у вас буде 20k рядків. Це не погано чи повільно, оскільки, знову ж таки, різниця між 100 рядками та 20 000 рядками є дуже малою, що стосується баз даних насправді. Це все індексовано. Це швидко, як чорт. Суб-мілісекунди.

Коли ви почнете збиратися в мільйони рядків, то я б хвилювався. Коли розмір таблиці параметрів збільшується вище сотень мегабайт, то я буду досить стурбований, щоб детальніше ознайомитися. Але взагалі це не проблема, окрім крайніх випадків. Це, звичайно, не проблема для чогось меншого, ніж щось на зразок великого сайту новин із сотнями тисяч публікацій. І для будь-якого сайту, достатньо великого, щоб це могло бути проблемою, ви повинні використовувати зовнішній кеш об'єктів, і в цьому випадку перехідні процеси автоматично зберігаються там, а не в базі даних.


1
NB: перехідні процеси , які не мають закінчення терміну дії цього отримати autloaded, і немає терміну придатності є по замовчуванням , так що, коли додаток / плагін створює безліч перехідних і не встановлюючи термін дії вони будуть використовувати фрагменти пам'яті на кожній сторінці / після завантаження.
webaware

Немає жодних причин використовувати "перехідний період без закінчення терміну дії", оскільки це в основному ідентично звичайній "опції".
Отто

1
Звичайно, але це за замовчуванням . Таким чином, багато авторів плагінів додають перехідні періоди, що не закінчуються.
webaware

1
Ну, рішення тут просте: не використовуйте ці плагіни. Вони роблять неправильно. Перехідні процеси не повинні використовуватися як сеанси, ви не повинні використовувати їх без значущого закінчення, і вони не повинні мутувати або змінювати клавіші.
Отто

2
Скажімо, 7 днів. Якщо автор плагіна / теми хоче щось більше або менше, вони вказатимуть його. Якщо вони хочуть автозавантажувати, вони не повинні вказувати 0 для закінчення терміну дії (= нескінченність), але це те, що вони отримали в даний момент, коли параметр закінчення виконує подвійний обов'язок як параметр автозавантаження так / ні. Так чи інакше, термін закінчення за замовчуванням також не повинен призводити до автоматичного завантаження = так, як за замовчуванням; це просто прохання про неприємності.
webaware

18

Отто - я більше не могла погодитися з вами. Проблема полягає в тому, що врешті-решт із усіма цими перехідними періодами розмір столу стає смішним. Не потрібно мільйони рядків, щоб збити. Зараз я маю справу з таблицею варіантів, яка має понад 130 тис. Рядків і регулярно висить. Оскільки поле значення є великим текстовим типом, навіть пошук лише рядків "автозавантаження" стає кошмаром продуктивності. Ці поля значень зберігаються окремо від решти даних рядків. Незважаючи на те, що це логічно є частиною тієї ж таблиці, приєднання має відбуватися для того, щоб витягнути потрібні рядки. Приєднання, яке зараз триває назавжди, оскільки потрібні вам дані розповсюджуються по всьому місцю на диску. Профілювання (використання реактивного профілю для mysql) підтвердило це.

Додавання автоматичного завантаження в кластерний ключ може допомогти вирішити цю проблему. Кластеризація на автоматичному завантаженні Desc, ID ASC, наприклад, дозволить усім рядкам автоматичного завантаження спочатку з'єднатись на диску. Навіть все-таки я думаю, що ти дивишся на величезну напругу з точки зору БД.

Особисто я вважаю, що дизайн цієї системи пробуксований. Таблиця параметрів, здається, перетворилася на загальний підсумок для багатьох речей. Це добре, якщо поле значення є досить малим, щоб його можна було включити на ту ж сторінку, що й решта даних рядка, і його можна ефективно індексувати. На жаль, це не так. Хто б це не спроектував, потрібно повернутися до класу DB101.


5
правда, але врахуйте, що коли розпочалася розробка WordPress, ніхто не думав, що досягнуть тисячі плагінів, використовуючи таблицю параметрів у якості зберігання даних :)
onetrickpony

@onetrickpony, тому важливо завжди витрачати свій час і робити все правильно, чи очікуєте ви, що це буде величезний день чи ні :)
Махмуд Аль-Кудсі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.