transients שפגו ב-DB: ניקוי, אופטימיזציה והיגיינה שוטפת

transients שפגו לא נמחקים אוטומטית. כך מנקים אלפי שורות מתות מ-wp_options ושומרים על DB רזה.

Transients הם cache פנימי של וורדפרס - ערך קטן שמאוחסן ב-DB עם תאריך תפוגה. הם נהדרים לאגירה זמנית של תוצאות שאילתות יקרות, אבל המנגנון של וורדפרס לפינוי שלהם הוא עצלן: רק כשמישהו מנסה לקרוא transient שפג, הוא מוחק אותו. transients שאף פעם לא נקראים שוב נשארים תקועים לנצח.

למה זה משנה

באתר ותיק עם הרבה תוספים, טבלת wp_options יכולה להגיע לעשרות אלפי שורות שמרבית התוכן בהן הוא transients מתים. ההשלכות הקונקרטיות:

  • גודל DB: גיבויים נמשכים יותר זמן, ה-table file גדל ב-InnoDB גם כשהשורות נמחקות (יש OPTIMIZE TABLE כדי לדחוס).
  • שאילתות איטיות: כל פעם שוורדפרס טוען autoload options - וזה קורה בכל בקשה - הוא חייב לסרוק את הטבלה. שורות מיותרות מאטות את הסריקה.
  • החשד הסטטיסטי: אתר עם 50,000+ transients תקועים כמעט תמיד מציין תוסף שיוצר transients חדשים בכל בקשה ולא מנקה - בעיה ארכיטקטונית שכדאי לתקן.

זה לא קריטי לביצוע מיידי, אבל היגיינה תקופתית חשובה ולא דורשת הרבה זמן.

איך לזהות

ספור transients שפגו דרך SQL ב-phpMyAdmin:

SELECT COUNT(*) FROM wp_options
WHERE option_name LIKE '\_transient\_timeout\_%'
AND option_value < UNIX_TIMESTAMP();

חלופה ב-WP-CLI:

wp transient list --expired --format=count

RankPlus סופר את אותם רישומים ומסמן אם המספר עובר את ה-threshold (לרוב 1,000+).

איך לתקן

  1. הדרך הפשוטה: wp transient delete --expired. זה מוחק רק את אלה שפגו, בלי לגעת ב-transients תקפים.
  2. חלופה דרך תוסף UI: WP-Optimize או Transients Manager מציעים כפתור Delete Expired ויכולים לתזמן ניקוי שבועי.
  3. חלופה ידנית ב-SQL:
    DELETE FROM wp_options WHERE option_name LIKE '\_transient\_timeout\_%' AND option_value < UNIX_TIMESTAMP();
    DELETE FROM wp_options WHERE option_name LIKE '\_transient\_%' AND option_name NOT LIKE '\_transient\_timeout\_%' AND NOT EXISTS (SELECT 1 FROM (SELECT option_name FROM wp_options) b WHERE b.option_name = CONCAT('_transient_timeout_', SUBSTRING(option_name, 12)));
  4. אחרי הניקוי, דחוס את הקובץ של InnoDB: OPTIMIZE TABLE wp_options;. זה משחרר מקום שכבר "נמחק" אבל עדיין תופס ב-tablespace.
  5. הגדר ניקוי אוטומטי: WP-Optimize יודע לתזמן ניקוי שבועי דרך WP-Cron. או הוסף משימת shell ל-cron של השרת:
    0 3 * * 0 cd /var/www/html && wp transient delete --expired --allow-root
  6. אם הבעיה חוזרת מהר, אתר את התוסף: wp transient list | head -20 ולפי שם ה-transient מזוהה התוסף - לרוב analytics או cache לא מנוהל היטב.

טעויות נפוצות

  • מחיקה גורפת של כל transients (--all): גם תקפים יימחקו, ויש לוורדפרס לחזור ולחשב מחדש - מה שעלול להאיט את האתר זמנית. השתמש רק ב---expired.
  • אי שימוש ב-OPTIMIZE TABLE: השורות נמחקו לוגית אבל הקובץ ב-InnoDB עדיין באותו גודל. הרצת OPTIMIZE משחררת מקום בפועל.
  • פתרון חוזרני בלי לאתר את התוסף שאומר את הבעיה. ייצור 50,000 transients תוך שבוע יחזור.
  • ניקוי באתר עם object cache (Redis/Memcached): transients שם מאוחסנים בזיכרון ולא ב-DB, אז הניקוי ב-SQL לא רלוונטי. השתמש ב-wp transient delete --expired שיודע איזה backend פעיל.

בדיקה לאחר תיקון

הרץ שוב את ה-COUNT של expired transients - צריך להיות 0 או קרוב. בדוק את גודל wp_options: SHOW TABLE STATUS LIKE 'wp_options'; ובחן את Data_length. ב-RankPlus הסטטוס יחזור לירוק. הוסף ניקוי אוטומטי כדי שלא תצטרך לחזור על זה ידנית.

טיפ: אם אתה משתמש ב-Redis Object Cache (תוסף Redis Object Cache או W3 Total Cache), transients יישמרו ב-Redis ולא ב-DB - מה שפותר את הבעיה לחלוטין. שווה את ההגדרה אם האתר שלך פעיל מאוד.