מגבלת זיכרון בפונקציית רג'קס בmysql
-
@chagold אני לא חושב שיש קשר לגודל ההודעה, אני יותר חושב שהRegex שלך לא תקין.
לפי השגיאה, נראה שהרגקס מבצע יותר מידי פעולות, שחורגות מהמגבלה לרקורסיה (בSql המגבלה היא 100 כעיקרון).
רקורסיה פירושו כל פעם שפונקציה קוראת לעצמה, בדרך כלל עם קלט אחר שמועבר לפונקציית הילד. זה קורא לעצמו שוב ושוב עד שמגיעים למצב יציאה, ואז מעביר את התוצאות בחזרה לLIFO.
הבעיה העיקרית עם הרקורסיה היא שהיא יכולה להשתמש בקריאה לפונקציה מקוננת עבור כל אלמנט מעובד. זה מביא להרבה יותר צריכת משאבים, מכיוון שכל קריאת פונקציה צריכה קבוצה משלה של משתנים ופרמטרים מקומיים. וזה ייקח זמן עיבוד נוסף בהשוואה לללולאות.
בגדול אפשר לשנות את מגבלת הרקורסיה בSql באמצעות האפשרות MAXRECURSION, רק קח בחשבון שאתה חשוף ללולאה אין סופית שתצרוך משאבים גדולים מאוד.
ההנחת יסוד שלי היא שהתחביר של הרגקס לא תקין, ההמלצה שלי היא שתעלה אותו כאן לבדיקה, לפני שתשנה את מגבלת הרקורסיה. -
@Elhanan כתב במגבלת זיכרון בפונקציית רג'קס בmysql:
@chagold אני לא חושב שיש קשר לגודל ההודעה, אני יותר חושב שהRegex שלך לא תקין.
לפי השגיאה, נראה שהרגקס מבצע יותר מידי פעולות, שחורגות מהמגבלה לרקורסיה (בSql המגבלה היא 100 כעיקרון).
רקורסיה פירושו כל פעם שפונקציה קוראת לעצמה, בדרך כלל עם קלט אחר שמועבר לפונקציית הילד. זה קורא לעצמו שוב ושוב עד שמגיעים למצב יציאה, ואז מעביר את התוצאות בחזרה לLIFO.
הבעיה העיקרית עם הרקורסיה היא שהיא יכולה להשתמש בקריאה לפונקציה מקוננת עבור כל אלמנט מעובד. זה מביא להרבה יותר צריכת משאבים, מכיוון שכל קריאת פונקציה צריכה קבוצה משלה של משתנים ופרמטרים מקומיים. וזה ייקח זמן עיבוד נוסף בהשוואה לללולאות.
בגדול אפשר לשנות את מגבלת הרקורסיה בSql באמצעות האפשרות MAXRECURSION, רק קח בחשבון שאתה חשוף ללולאה אין סופית שתצרוך משאבים גדולים מאוד.
ההנחת יסוד שלי היא שהתחביר של הרגקס לא תקין, ההמלצה שלי היא שתעלה אותו כאן לבדיקה, לפני שתשנה את מגבלת הרקורסיה.א. יש רשומות שזה מחזיר תקין.
ב.UPDATE phpbb_posts set post_text = REPLACE( post_text, REGEXP_SUBSTR(post_text, "\\[align=right\\](((?R)|.)*?)\\[\\/align\\]"), CONCAT( '[right]', REGEXP_REPLACE ( REGEXP_SUBSTR(post_text, "\\[align=right\\](((?R)|.)*?)\\[\\/align\\]"),"^\\[align=right\\](((?R)|.)*?)\\[\\/align\\]", "\\2"), '[/right]' ) )
-
@chagold הבעיה נובעת מה?R שבעצם מורה לרג'קס לבדוק בלולאה את קיום הביטוי כולו שוב ושוב במיקום ההוא (אני לא לגמרי מבין למה זה נדרש).
בקלט מסויים, יכול להיות בגלל אי תקינות, זה עובר את מגבלת הריקורסיה המוגדרת. כפי שאמר @Elhanan הגדלה של המגבלה לא בהכרח תעזור, יכול להיות שעבור קלט מסויים הביטוי הזה נכשל - כלומר עובד יותר מידי הרבה פעמים עד שהשאילתה תיתקע למשך שנתיים.אני לא מבין למה צריך את הביטוי הזה, הוא אמנם מכסה מקרה של קינון, אבל הוא מוצא רק את החיצוניים ביותר להבנתי, זה עוזר לך? אני הייתי מחפש את הפנימיים ביותר ופשוט מחפש שוב ושוב עד שלא נשאר (ע"י בדיקה של הwhere בשאילתה).
-
יש לי עכשיו שגיאה נוספת.
הקוד
UPDATE phpbb_posts set post_text = REPLACE( post_text, REGEXP_SUBSTR(post_text, '\\<ALIGN align="(.*?)"(.*?)\\>(.*?)\\<\\/ALIGN\\>'), REGEXP_REPLACE ( REGEXP_SUBSTR(post_text, '\\<ALIGN align="(.*?)"(.*?)\\>(.*?)\\<\\/ALIGN\\>'),'^\\<ALIGN align="(.*?)"(.*?)\\>(.*?)\\<\\/ALIGN\\>', '\\2') )
השגיאה -
Warning: #1139 Regex error 'match limit exceeded'
(ג"כ רק בחלק מהרשומות).
תודה
-
@chagold לפי הבנתי, השגיאה נובעת שוב מתחביר שגוי.
לדעתי השגיאה נובעת מהגדרות ברירת מחדל של הספריה PCRE שנועדו ע"מ להגביל את השימוש בזיכרון או את זמן החישוב.
PCRE משתמש בפונקצייה match() וקורא לה בצורה רקורסיבית, ע"מ שלא תרוץ רקורסיה אין סופית, קבעו את הגבול match_limit שמגבילה את מספר הקריאות של הפונקציה. כמו את מגבלת הרקורסיה, גם כאן ניתן לשנות את המגבלה. כברירת מחדל הוא מוגבל ל10 מיליון קריאות וניתן לשנות אותה באמצעות הפונקצייה pcre_exec().
אבל כמו שכתבתי קודם, לשנות את המגבלה זה לא פיתרון, מגבלות הברירת מחדל לא קיימות סתם. אני מציע לבדוק שוב את התחביר ע"מ לאתר את שורש הבעיה.
יתכן שהבעיה קיימת מסיבות אחרות, ולאו דווקא בגלל הPCRE, אבל הבעיה זהה..