מחיקת קובצי גיבוי ישנים שלא באמצעות Maintenance Plan


הכל התחיל כאשר יום אחד נכשלו מספר גיבויים. בדיקה מהירה של הסיבות לכישלון הראתה שאין מקום בדיסק. בדיקה טיפה יותר יסודית הראתה שלמרבה ההפתעה, למרות שבג'וב הגיבוי מוגדר למחוק קבצי גיבוי ישנים, בפועל הללו שרדו על הדיסק והגיעו לגיל מופלג. חשוב לציין שבכל אותן פעמים שהג'וב לא ביצע את שלב המחיקה, הוא דיווח על סיום מוצלח שלו, ולנו, צוות ה- DBA לא היתה סיבה לחשוד שמשהו אינו כשורה. השורה התחתונה היא, שכאשר מדובר במחיקת קבצי גיבוי ישנים, ה- maintenance plan התגלה ככלי שאמינותו בעייתית. נוצר צורך למצוא דרך אחרת למחוק את קבצי הגיבוי הישנים, מבלי להסתמך על ה-maintenance plan.

לאחר חיפוש מהיר בתיעוד של מערכת ההפעלה שלנו (Windows Server 2008) מצאנו את פקודת forfiles, המאפשרת למחוק קבצים לפי גילם. על הפקודה הזאת, התבסס הפתרון שלנו.

סינטקס הפקודה פשוט למדי:

forfiles [/p <Path>] [/m <SearchMask>] [/s] [/c "<Command>"] [/d [{+|-}][{<Date>|<Days>}]]

לאחר הפרמטר /p מפרטים את ה- path בו נמצאים קבצי הגיבוי.

/m מפרט תבניות בשם של הקבצים. לדוגמא, אפשר להגדיר /m *.bak, ואז הפקודה תחול אך ורק על קבצים שהסיומת שלהם היא bak. אם לא משתמשים באופציה הנ"ל, הפקודה תחול על כל הקבצים, ללא קשר לשמם או לסיומת שלהם.

/s – כאשר מוסיפים את האופציה /s, הפקודה תרוץ גם על תתי הספריות מתחת ל- path המצוין. כאשר הוא לא מופיע בפקודה, הפקודה תרוץ אך ורק על המחיצה המופיעה ב- path ולא תרד לתתי הספריות מתחתיה.

/c – הפקודה שאנחנו רוצים להריץ על הקבצים ש- forfiles ימצא. במקרה שלנו מדובר כמובן על פקודת מחיקה – del. הפקודה תופיע תמיד בתוך מרכאות, ולרוב היא תשתמש במשתנים שונים. המשתנה הנפוץ ביותר שבו היא תשתמש הוא @file, שמכיל את השמות המלאים (שם + סיומת של הקצבים שנמצאו על ידיforfiles).

הפרמטר האחרון – /d מתייחס לגיל הקובץ. ניתן להגדיר גיל ביחס לתאריך (לפני או אחרי תאריך מסוים) או בימים. לעניינו רלוונטי גיל בימים.

פקודת המחיקה המלאה למחיקת קבצים בני מעל 5 ימים תראה כך:

forfiles /P D:\sql\Backup /s /d -5 /C "cmd /c del @file "

הפקודה תמחק את כל הקבצים שגילם מעל חמישה ימים הנמצאים תחת מחיצת D:\sql\Backup או תתי המחיצות שמתחתיה.

עד כאן, הכל טוב ויפה, אבל אנחנו מדברים על פקודה של מערכת ההפעלה, לא פקודת T-SQL. על מנת להשתמש בפקודה בסקריפט שיריץ sql server יש צורך לעטוף אותה בפקודת :xp_cmdshell

EXEC xp_cmdshell 'forfiles /P D:\sql\Backup /s /d -5 /C "cmd /c del @file "'

פקודת xp_cmdshell היא פירצה בטיחותית, ולא כל בסיס נתונים מאפשר להריץ אותה. על מנת לאפשר להריץ אותה יש לשנות את הפרמטר xp_cmdshell ב-sp_configure ל- 1 (וכמובן לבצע reconfigure).

להלן סקריפט מלא, שמוודא שהערך של xp_cmdshell שווה ל-1, מבצע את המחיקה תוך כדי שימוש בפקודת forfiles, ומחזיר את הערך המקורי של xp_cmdshell. לצורך הפשטות הסקריפט המצורף הוא הסקריפט הבסיסי ביותר, ללא שימוש בפרמטרים או טיפול בשגיאות.

DECLARE @configData table

(name sysname, minimum int, maximum int, config_value int, run_value int)

DECLARE @config_value INT

INSERT INTO @configData

EXEC sp_configure 'xp_cmdshell'

SELECT @config_value = config_value

FROM @configData

IF @config_value !=1

BEGIN

EXEC sp_configure 'xp_cmdshell', 1

RECONFIGURE

END

EXEC xp_cmdshell 'forfiles /P D:\sql\Backup /s /d -5 /C "cmd /c del @file "'

EXEC sp_configure 'xp_cmdshell', @config_value

RECONFIGURE

#ShmulikCohn #שמו #MaintenancePlan #SQLServer #ITPRO #DEV #SQLServerAgent #SSMS #xpcmdshell

Featured Posts
Posts are coming soon
Stay tuned...
Recent Posts