עוד על גיבויים

אמנם כתבתי על זה בעבר, אבל אפילו אני פאקיונר לא קטן, השבוע גסס לי דיסק, והצלתי ממנו מידע בעור שיני (מה זה אומר לעזאזל? אין לי עור על השיניים!). הבעיה נפתרה אחרי הרבה העתקה איטית וזהירה תחת עינו הפקוחה של מזגן ובסוף כל המידע הועתק יפה מהדיסק למעט קובץ אחד שיש לי מקור אחר בשבילו. במקביל אני קורא כי רק לפני יומיים הלכו הפורומים של אובונטו ישראל בגלל שדרוג חסר אחריות, וצוות האתר לא מבין שיש לו מחויבות לשחזר. וואטסאפ הפליגו עם כותרת מאוד צהובה וכבר הכריזו "מותה של קהילה". אני לא הייתי באמת נשאר אצל צוות הנהלה שיורק בקשת (איזראל סטייל) על מה שכתבו משתתפים בפורום ועונים להם בחוצפה כשהם מבקשים את החומר חזרה באתר. למרות ששם זה נראה שזה נעשה מתוך הובריס ילדותי מכוון ולא בשל תקלה.

לבסוף לפני שעתיים כתבה לי טליה בבהלה שהיא מחקה לעצמה בטעות את הבלוג. אחרי שנרגעה טיפה ושיחזרה את הרוב (עזרתי עם איזה קובצון או שניים), החלטתי להתיישב ולכתוב howto פשוט, איך לגבות שרת גנו או יוניקס מרוחק בלי לגעת בו. אני מביא כאן את הסקריפט שאיתו אני מגבה את השרת שלי ועושה התאמות לגיבוי של ספרית בית של משתמש שאין לו גישת root, אנא בדקו אחרי שלא פישלתי בכלום, כי אחרי כל השינויים אני לא מתכוון להעביר את זה QA:

1. צרו סקריפט שיגבה את כל ספרית הבית שלכם, וכל טבלה דרושה ממסד הנתונים:

#!/bin/bash

# a generic hack to make a backup tarball of a homedir on a server
# and back it up to a home machine.
# This hack is public domain, and may not be useful to YOU if you don't
# customize it to the bone.

# The design is simple - stick everything in a single directory and rsync it out.
# We keep three days of material back, you still need to
# use rsync to take it home.

mkdir -p ~/backup ; cd ~/backup

mkdir -p current back.1 back.2 # add as necessary!

## first, rotate the directories

mv back.1/* back.2
mv current/* back.1

## set up dates for the backup filenames

TODAY=$(date +%Y-%m-%d)
THISMONTH=$(date --date="$TODAY -1 days" +%Y-%m)
ARCHSINCE=$(date --date="$TODAY -1 days" +%Y-%m-1)

## now dump MySQL, you must edit this to reflect YOUR db names!

for db in db1 db2 ${USER}_db ; do
nice mysqldump -e --add-drop-table --add-locks \
--user=USERNAME --password=PASS --single-transaction -q $db | \
nice gzip -c --rsyncable > current/$(hostname)_sql_$db.gz
done

## Did you notice? I always use gzip --rsyncable so the tarballs are, well, rsync-able!

## Latest web logs - only incremental of this month
( tar --newer-mtime ${ARCHSINCE} -cf - ~/weblogs | nice gzip -c --rsyncable \
> current/$(hostname)-weblogs-${THISMONTH}.tgz ) 2> /dev/null

## I run several sites
for site in ~/sites/* ; do
sitename=$(basename ${site})
( tar -C ~/sites/ -cf - ${sitename} | nice gzip -c --rsyncable \
> current/${USER}-${sitename}.tgz ) 2> /dev/null
done

## Backup all the rest of the homedir:
( tar --exclude=weblogs --exclude=sites --exclude=backup -cf - ~/. | nice gzip -c --rsyncable \
> current/$(hostname)-${USER}home.tgz ) 2> /dev/null

## AGAIN: this script makes a lot of assumptions, many not right for your setup.
## go over it, understand what it does and edit it to YOUR needs with
## YOUR directory names.

2. הריצו אותו כל לילה בשעות הכי פנויות בcron

crontab -e
(this opens an editor and you add in a line to run your script)
MAILTO=yourmail@yourdomain.com
30 3 * * * ~/bin/nightly-backup

3. במחשב הביתי שלכם, בנו סקריפט קטן שימשוך את הדלתא של העדכון. אם אתן לא מריצות גנו/לינוקס או מאק, אתן יכולות להתקין cygwin כי אני לא מכיר דרך יותר נוחה להשתמש בrsync מחלונות (הקוראות מוזמנות להאיר את עיני)

while ! nice rsync -av SERVER:backup/current/ ~/backups/SERVER/ ; do sleep 1 ; done

4. הכניסו גם אותו לcron. כאן אני מניח שלא יקח יותר משעה לגבות את כל האמור לעיל, אבל אם אצלכם זה שונה, שנו את המספרים לשעה יותר מאוחרת.

crontab -e
(this opens an editor and you add in a line to run your script)
MAILTO=yourmail@yourdomain.com
30 4 * * * ~/bin/rsync-nightly-backup | tail -2

אני לא דואג לפרט כאן איך למשוך RSYNC משרת רחוק בלי לשבת ליד המקלדת ולהכניס סיסמא כל פעם, אבל אם תהיה מספיק דרישה אני אוסיף עוד howto קטן בנושא. בינתיים רמז: SSH עם מפתח פרטי וציבורי, כאשר אין passphrase או שאתם דואגים לssh-agent רץ וזמין לפעולת הcron.

ושוב כאמור, כתבתי את כל הנ"ל חפיף, נא לתקן אותי אם שכחתי או פישלתי במשהו.

20 Replies to “עוד על גיבויים”

  1. וצוות וואטסאפ לא ממתן או מנסח מחדש דברים כשנראה לו? אין למישהו שליטה מנהלתית ומודרציה? אני מודה שאני לא יודע איך דברים עובדים שם, אבל אם זה פורסם בוואטסאפ, אז מבחינת קהל הקוראים (ואני בינהם) זה בוואטסאפ, וזהו בערך…

  2. ממתן ומשנה (גם הידיעה הזו נערכה קלות). עם זאת האתר גם נועד לתת במה, ופורסמו (ואני בטוח שיפורסמו בעתיד) דעות וידיעות שנויות במחלוקת אשר נוגדות את דעתינו (בעלי האתר).

  3. אתר whatsup בהחלט לא אחראי לכותרת הסנצציונית הזאת, אלא רק אני.

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

    בכל מיקרה, הבעייה היא לא גיבוי, אלא זה שאין מה לעשות עם הגיבוי. דולב כתב שם בפורום שיש לו גיבוי, אבל הוא בגודל של שניים או שלושה ג'יגה. עכשיו לפי מה שאני זוכר שהוא אמר לי פעם זה שרב הנתונים שיש בבסיס נתונים הן תמונות שמשתמשים העלו לוויקי שלהם והפורומים … אני בספק אם המידע של שוקל יותר מ־100 מ"ב. אבל נניח זה שוקל 50 מ"ב: איך אתה מעלה את זה מהבית שלך לשרת? איך אתה משחזר באופן פיזי את הנתונים?

    לך בתור איש מקצוע קל להגיע למקום שבו השרת מתארח, וזאת גם העבודה שלך. אבל מה איתם? הם חובבים (והם מוכיחים את זה כל פעם מחדש) שלא מקדישים את כל יומם לשרת ולא תמיד הם יכולים להפסיד יום עבודה כדי לתקן את השרת.

    זה עדיין לא מכסה על החובבנות שבה המהלך הזה נעשה: לא נעשתה בדיקה על יבש, והאתר שהעלו במקום זה פריסה פשוטה של phpbb שבה שינו פרמטרים בודדים. זה נראה כמו עבודה חובבית שנעשתה כלאחר יד.

  4. יעקב, זה בדיוק מה שכתבתי – נראה לפי התגובות שזה הובריס ילדותי ולא טעות. במקרה הזה אולי אני צריך להדגיש – צריך לא רק דיבוי של המידע אלא גם מוצג בפורמט זמין לגוגל ושאר המנועים כדי שהידע לא ילך לאיבוד. במקרה שלהם הם לא קולטים שהידע זה הדבר היחידי שחשוב בתוכנה חופשית והם זורקים אותו בלי מחשבה שניה לפח. הם אכן אדיוטים, ומגיע להם שתמות להם הקהילה עם היחס הזה.

  5. אין דבר כזה "ידיעה של ווטסאפ"
    כל ידיעה בווטסאפ מופיעה תחת שם השולח או "אנונימי" אם השולח לא טרח להוסיף את שמו (ואזי אני משער שהחופש של העורכים גדול יותר).
    ידיעות שמפרסמים מאיר, יהודה ושות' אינן שונות מאלו שמפרסם דיאגו.

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

  6. ההבדל הוא שחושבים שזו מדיניות האתר ומאשימים אותנו, וזה לא בהכרח מדוייק. אז אפשר לומר ש"המדיניות היא שיפורסמו גם דבר שלא בהכרח עולים בקו אחד עם המדיניות" (אח, רקורסיה לשעות צהריים)

  7. שמתי לב שלפקודת mysqldump בסקריפט הגיבויים שלך יש אופציות שאינני משתמש בהן בסקריפט הגיבוי שאני משתמש בו.
    לכן ישבתי על man mysqldump ועברתי על כל האופציות הלא מוכרות לי כדי לעמוד על משמעותן.
    ואכן פיענחתי את כולן, עם החריג היחיד של a-.
    לפי man mysqldump, אין אופציה כזו (לפחות לא בגירסא 5.0.32), אם כי יש אופציה A-.
    ליתר בטחון, בדקתי ש-mysqldump רגיש ל-case של אופציותיו ע"י השוואת התנהגות של
    mysqldump –help
    להתנהגות של
    mysqldump –HELP
    וכן ההתנהגות של v- עם זו של V-.

    אי לכך אבקש להאיר את עיני באשר למשמעות האופציה a- שהשתמשת בה בסקריפט.

  8. לא הצלחתי להבין מהתיאור שלו מה הוא עושה בדיוק – מוציא לוג של בקשות איטיות? הרי השרת בעצמו עושה את זה. אולי הוא רק עובר על הלוג הזה ומסכם לך אותו?

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

  9. זה עושה בדיוק את מה ש-mysqldump עושה, אבל יותר לאט. הרעיון הוא לא לקרוע את המחשב בזמן הגיבוי, אלא לבצע את הגיבוי בזמן ארוך יותר אבל עם פגיעה מינימאלית בביצוע של ה-dump.

  10. קרא את המאנפייג', נראה לי שאתה טועה. אם אתה רוצה "לא לקרוע את השרת" אתה משתמש בnice שזה מה שעשיתי פה. בזמן שאתה עושה דאמפ, השרת מעכב כתיבות לדיסק (כלומר, כותר רק לג'ורנל בצד או משהו) כדי שכל הקריאות שלך מהטבלאות יהיו מתואמות. למעשה אם אתה עושה דאמפ מלא של כל השרת (עם -A) אז תראה שהמידע שיתקבל בטבלא האחרונה שנפלטת בגיבוי הוא זה שהיה שם כשהגיבוי התחיל ולאו דווקא הנוכחי, כמה דקות מאוחר יותר. המשמעות היא שגם לא כדאי להקפיא במצב הזה את השרת זמן רב מדי.

    בקיצור, קרא את הקובץ, הוא סקריפט בפרל, והנה התחלתו:

    #!/usr/bin/perl
    # mysqldumpslow – parse and summarize the MySQL slow query log
  11. הרסת לי חצי ניסיון שיש לי עם mysql… מוזר ללמוד כמה אתה בור בנושא מסויים… תודה :)

    אם אתה רוצה כאב ראש אמיתי, תפעיל screen, תתחבר לשרת מרוחק ב־ssh ואז בשרת השני תעשה screen -r, לחלופין, תפעיל minicom ב־screen ושלח פקודות sysrq. אני לא יכול לעשות את האחרון, וראיתי מישהו עושה את זה פעם… וזה היה מצחיק להסתכל עליו עושה את החישובים "ממממ… אני נמצא פה, אז כדי לשלוח את זה אני צריך ללחוץ על צירוף הזה כדי לצאת מ־screen ואז…"
    :)

  12. אני חושב שיש לך באג

    את מיצר ספרית current

    mkdir -p current back.1 back.2 # add as necessary!
    (מיותר ליצר back.2)

    אחר כך אתה משנה לה את השם ל back.1

    mv current/* back.1

    אחר כך אתה מנסה להשתמש בספריה current אבל היא לא קיימת עוד

    nice gzip -c –rsyncable > current/$(hostname)_sql_$db.gz

    מכיוון שאתה לא מוחק את הספריות back.1 ו back.2 עדיף להשתמש ב mv -f

  13. אני לא משנה את השם, אני מעביר את התוכן. תריץ ותראה שאחרי יום או יומיים הספריות האלו מתמלאות והתוכן עובר מהאחת לשניה עד ש"נתקע" באחרונה.

    שים לב להבדל:
    mv current back.1
    לעומת
    mv current/* back.1
    עושות דברים מאוד שונים.

    היה 4 בבוקר. אני סולח לך :-)

Leave a Reply