וורדפרס משתמש ב-transient בשם doing_cron כמנגנון נעילה (mutex) פשוט שמונע משני תהליכי cron לרוץ במקביל. כשתהליך מתחיל הוא קובע אותו לזמן הנוכחי, וכשהוא מסיים מוחק אותו. אם הוא נכשל באמצע - הנעילה נשארת תקועה והכל קופא.
למה זה משנה
קוד ה-cron של וורדפרס בודק לפני כל הרצה אם doing_cron קיים. אם כן והערך שלו צעיר מ-WP_CRON_LOCK_TIMEOUT שניות (60 ברירת מחדל), הוא מניח שעבודה אחרת רצה כרגע ומדלג. במצב תקין זה תקין; אבל אם תהליך cron נחתך באמצע (PHP fatal, OOM, timeout של PHP, restart של PHP-FPM), ה-transient עלול להישאר תקוע עם option_value שלא יוסר. כל בקשת cron עתידית תחשוב שעבודה רצה ותדלג. תוצאה: גיבויים, סנכרונים, פרסום פוסטים מתוזמנים, מיילים ועוד - הכל פשוט מפסיק. וזה לא תמיד גלוי - אין שגיאה במסך, פשוט שום דבר לא קורה ברקע.
איך לזהות
בדוק את התוכן של ה-transient דרך WP-CLI:
wp transient get doing_cronאם הוא מחזיר ערך timestamp שגדול בהרבה מ-60 שניות בעבר (למשל לפני שעה או יום), הוא תקוע. חלופה דרך phpMyAdmin:
SELECT option_name, option_value FROM wp_options WHERE option_name LIKE '%doing_cron%';גם wp cron event list שמראה next_run_relative שלילי בכל ה-hooks הוא סימן עקיף.
איך לתקן
- הדרך המומלצת:
wp transient delete doing_cron. זה ינקה גם את ה-timeout שלו. - חלופה דרך phpMyAdmin:
DELETE FROM wp_options WHERE option_name IN ('_transient_doing_cron', '_transient_timeout_doing_cron'); - חלופה ויזואלית: התקן את Transients Manager (חינמי), חפש
doing_cron, ולחץ Delete. - אחרי המחיקה, הפעל
WP_DEBUGו-WP_DEBUG_LOGב-wp-config.phpוחכה. הסיבה השורש - ה-fatal שגרם לנעילה - תופיע ב-debug.log. - תקן את הקוד הבעייתי או הסר את התוסף. אם זה תוסף תורם, פתח issue אצל המפתח.
- אם הבעיה חוזרת תכופות, עבור ל-system cron (ראה wp_cron_status) - זה מבטל את התלות בלוקים hashtag-נשכחים.
טעויות נפוצות
- פתרון חוזרני: מחיקת ה-transient כל פעם בלי לחקור את השורש. הבעיה תחזור.
- שינוי WP_CRON_LOCK_TIMEOUT לערך נמוך מדי: זה גורם לשני תהליכים לרוץ בו זמנית ולנסות לבצע אותה משימה. ברירת המחדל (60) טובה.
- חשד שווא ל-cron בעוד שהבעיה ב-PHP-FPM: לפעמים שגיאות OOM מקילות לחשוד ב-WP-Cron, אבל הסיבה היא שזיכרון PHP נמוך מדי. הגדל
memory_limitב-wp-config.php. - אי בדיקה אחרי המחיקה: ייתכן שהמחיקה הצליחה אך הסיבה השורש מחזירה אותו תוך 5 דקות. בדוק שוב.
בדיקה לאחר תיקון
הרץ wp cron event run --due-now - הוא צריך להריץ משימות שעבר זמנן. הרץ wp transient get doing_cron - אמור להחזיר ריק או ערך טרי. חכה 10-30 דקות וודא שגיבוי, מיילים או פוסט מתוזמן יוצאים בזמן הצפוי. ב-RankPlus הסטטוס יחזור לירוק.
doing_cron נתקע מספר פעמים בשבוע, זה כמעט תמיד Action Scheduler של WooCommerce שנופל באמצע. הסר תהליכים תקועים עם wp action-scheduler clean והגדל memory_limit ל-512M לפחות. שווה גם להגדיר WP_MEMORY_LIMIT ו-WP_MAX_MEMORY_LIMIT בנפרד ב-wp-config.php; הראשון לבקשות frontend והשני לאדמין ולעיבוד רקע. אם הבעיה ממשיכה גם אחרי הגדלת זיכרון, שקול לעבור מ-WP-Cron הפנימי ל-system cron (ראה wp_cron_status) - זה גם פותר את התלות בלוקים שלא משתחררים, וגם מבטל את ה-overhead של loopback HTTP שיכול לכשול בפני עצמו על שרתים עם DNS פנימי איטי או חוקי firewall שחוסמים בקשות יוצאות לאותו host.