Les passagers en transit sont-ils ramassés?

58

Cette question m'a fait réfléchir Flux RSS transitoires dans wp_options n'est pas automatiquement supprimé?

Les transitoires sont supposés expirer et être supprimés. Cependant, la seule façon de voir cela est de gérer le moment où le transitoire est expiré et demandé, puis il est supprimé lors de la demande.

Que se passe-t-il si le transitoire a expiré mais n'est jamais demandé par la suite? D'après la description du Codex, je pensais qu'une sorte de ramasse-miettes est implicite. Maintenant, je ne suis pas si sûr et je ne trouve aucun code qui exécute une telle chose.

Alors, sera-t-il simplement bloqué dans la base de données pour toujours?

    
posée Rarst 09.01.2011 - 01:20
la source

3 réponses

42

Ils sont maintenant

À partir de WordPress 3.7, les transitoires arrivés à expiration sont supprimés lors de la mise à niveau de la base de données, voir # 20316

.

Ancienne réponse

Si quelqu'un ne peut pas me montrer le contraire, il semble que les passagers ne soient pas ramassés après tout. Ce qui aggrave la situation, c'est que contrairement aux options, leur stockage dans la base de données n'est pas garanti. Il n’existe donc aucun moyen fiable d’extraire la liste de tous les transitoires afin de vérifier leur expiration.

Quelques codes de fortune pour la récupération de place si la base de données est utilisée pour le stockage:

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);
    }
}
    
réponse donnée Rarst 10.01.2011 - 10:55
la source
20

Déplacement de certains commentaires de la discussion dans une réponse, avec reformulation et reformatage.

En gros, le problème est que, sauf dans les cas extrêmes, ils n’ont pas vraiment besoin d’être "ramassés". Si vous ne les récupérez jamais, peu importe qu'ils soient là ou non.

Voir, les transitoires sont stockés dans le tableau des options par défaut. Dans une installation de base, la table d'options contiendra peut-être 100 entrées. Chaque transitoire ajoute deux entrées supplémentaires, mais même si vous en avez des milliers, elles n’affectent pas la vitesse du site, car elles ne sont pas chargées automatiquement.

Au démarrage, WordPress charge les options en mémoire, mais il ne charge que les options dont l'indicateur de chargement automatique est activé. Les passagers ne comprennent pas cela et ne sont donc pas chargés en mémoire. Seuls les transitoires effectivement utilisés plus tard entraîneront des coûts.

Du point de vue de la base de données, la table des options contient des index sur l’option Id et sur le nom de l’option. Les transitoires sont toujours chargés en fonction du nom (clé). Par conséquent, leurs recherches sont toujours simples et se font sur une seule valeur de clé. Ainsi, la recherche est O (log (n)) et est super rapide. Avec un Big-O de log (n), il faudrait entrer dans les millions et les millions de lignes avant que cela devienne perceptible. Franchement, le temps système nécessaire à la configuration et à la suppression de la requête, ainsi que le transfert des données, est beaucoup plus long. La requête elle-même s'exécute pratiquement à zéro heure par comparaison. Donc, simplement avoir des rangées inutilisées en plus n'affecte que l'utilisation de l'espace disque supplémentaire.

L'indexation dans les bases de données est l'une de ces idées profondes qui n'a aucun sens pour les personnes qui n'ont pas encore compris ce qui se passe en coulisse. Les bases de données sont conçues pour une récupération rapide des données, à partir de la base, et peuvent gérer ce genre de choses sans problème. C'est une très bonne lecture: enlace )

Désormais, le nettoyage de la manière la plus évidente (appeler SQL DELETE sur eux) ne les supprime pas réellement de la base de données. Il les supprime simplement de l'index et marque la ligne comme "supprimée". Encore une fois, c’est ainsi que fonctionnent les bases de données. Pour réellement libérer de l’espace disque, vous devez continuer et exécuter ensuite une table OPTIMIZE TABLE. Il ne s’agit pas d’une opération rapide. Ça prend du temps. Probablement plus de temps que ça vaut le coup. Ce n’est probablement pas suffisant pour vous permettre d’économiser au total du temps processeur.

Si certains cas entraînent une insertion continue de nouveaux transitoires non utilisés, vous devez alors rechercher le problème sous-jacent. Qu'est-ce que l'insertion de ces transitoires? Utilisent-ils une clé changeante ou en mutation? Si tel est le cas, le plug-in ou le code à l'origine de ce problème doit être corrigé pour ne pas le faire. Ce sera plus utile, car il est probable que le code qui ne les crée pas correctement ne les récupère pas non plus, ce qui représente plus de travail que nécessaire.

D’autre part, il peut arriver que des transitoires soient créés pour quelque chose comme toutes les publications. Cela peut en effet être parfaitement acceptable. Je le fais moi-même dans SFC, pour stocker les commentaires entrants de Facebook. Chaque publication est associée à un transitoire potentiel, ce qui signifie deux lignes supplémentaires par publication. Si vous avez 10k postes, vous aurez 20k lignes dans la table d'options (éventuellement). Ce n'est ni mauvais ni lent, car encore une fois, il y a très peu de différence entre 100 lignes et 20 000 lignes dans la mesure où les bases de données sont importantes. Tout est indexé. C'est rapide comme bonjour. Sous-sous-millisecondes.

Si vous commencez à vous retrouver dans des millions de rangées, je suis inquiet. Lorsque la taille de la table d'options dépasse plusieurs centaines de mégaoctets, je serais alors suffisamment préoccupée pour examiner de plus près. Mais d’une manière générale, ce n’est pas un problème, sauf dans les cas extrêmes. Ce n’est certainement pas un problème pour des projets plus petits qu’un site comme un grand site d’informations, avec des centaines de milliers de messages. Et pour tout site suffisamment grand pour poser problème, vous devez utiliser un cache d’objets externe, et dans ce cas , les éléments transitoires sont automatiquement stockés là-bas plutôt que dans la base de données.

    
réponse donnée Otto 12.09.2011 - 20:09
la source
17

Otto - Je ne pourrais pas être plus en désaccord avec vous. Le problème est que finalement avec tous ces transitoires, la taille de la table devient ridicule. Il ne faut pas des millions de lignes pour s'enliser. Je traite actuellement avec une table d'options comportant plus de 130 000 lignes et qui se bloque régulièrement. Étant donné que le champ de valeur est un type de texte volumineux, même rechercher uniquement les lignes de "chargement automatique" devient un cauchemar de performances. Ces champs de valeur sont stockés séparément du reste des données de la ligne. Même si cela fait logiquement partie de la même table, des jointures doivent avoir lieu pour afficher les lignes souhaitées. Les jointures prennent maintenant une éternité, car les données dont vous avez besoin sont réparties sur le disque. Le profilage (en utilisant jet profiler pour mysql) l'a prouvé.

L'ajout du chargement automatique à la clé en cluster peut aider à résoudre ce problème. Le regroupement sur Autoload Desc, ID ASC par exemple, permettrait à toutes les lignes de chargement automatique de se regrouper en premier sur le disque. Même quand même, je pense que vous envisagez une énorme tension du point de vue de la DB.

Personnellement, je pense que la conception de ce système est géniale. Le tableau des options semble s'être transformé en un fourre-tout général pour beaucoup de choses. C'est bien si le champ de valeur est suffisamment petit pour être inclus sur la même page que le reste du rowdata et qu'il peut être indexé efficacement. Malheureusement ce n'est pas le cas. Celui qui a conçu cela doit revenir à la classe DB101.

    
réponse donnée myke 02.12.2011 - 20:43
la source

Lire d'autres questions sur les étiquettes