فصل ۱۸ – بایگانی و پشتیبان‌گیری

هرچه بیشتر با سیستم خود کار کنیم، فایل‌های بیشتری جمع می‌کنیم.
این فایل‌ها ممکن است شامل سندهای مهم، پروژه‌های نرم‌افزاری، عکس‌های خانوادگی یا فایل‌های تنظیمات گوناگون باشند.
همهٔ این‌ها نتیجهٔ ساعت‌ها (و شاید سال‌ها) تلاش ما هستند؛ بنابراین طبیعی است که بخواهیم در برابر خطاهای سخت‌افزاری، بدافزارها یا اشتباه‌های خودمان از آن‌ها محافظت کنیم.
از طرف دیگر، گاهی لازم داریم مجموعه‌ای از فایل‌ها را به سیستم دیگری منتقل کنیم و دوست داریم این کار را به شکل مرتب و مطمئن انجام دهیم.

در این فصل به سراغ ابزارهایی می‌رویم که برای «جمع کردن» فایل‌ها و «فشرده‌سازی» آن‌ها استفاده می‌شوند تا بتوانیم به سادگی از داده‌ها نسخهٔ پشتیبان بگیریم یا آن‌ها را منتقل کنیم.
شناخت این ابزارها برای هر کاربر لینوکس ضروری است، چون در دنیای یونیکس از همان روزهای نخست چنین ابزارهایی وجود داشته و هنوز هم بخش جدایی‌ناپذیر کار روزمرهٔ ما هستند.

پس از مطالعهٔ این فصل می‌توانیم:


آرشیو چیست؟

در فرهنگ لینوکس و یونیکس، «آرشیو» به فایلی گفته می‌شود که چند فایل و دایرکتوری را در خود جمع می‌کند.
مهم‌ترین مزیت آرشیو این است که مجموعه‌ای از فایل‌ها را می‌توان به صورت یک فایل منفرد ذخیره کرد یا انتقال داد.
اغلب برای آسان‌تر کردن انتقال، آرشیو را فشرده می‌کنند تا حجم کمتری اشغال کند.

دو روند معمول داریم:

  1. فشرده‌سازی تک‌فایلی: یک فایل منفرد را کوچک می‌کنیم؛ مانند فشرده کردن یک لاگ حجیم.
  2. ایجاد آرشیو: چند فایل را در قالب یک بسته جمع می‌کنیم (ممکن است هم‌زمان فشرده‌سازی هم انجام شود).

در ادامه ابتدا با ابزارهای فشرده‌سازی کار می‌کنیم و سپس سراغ آرشیوکنندهٔ کلاسیک یونیکس یعنی tar می‌رویم.


gzip، gunzip و دوستانشان

قدیمی‌ترین (و شاید رایج‌ترین) برنامهٔ فشرده‌سازی در دنیای لینوکس gzip است.
این برنامه فایل‌های ورودی را با الگوریتم DEFLATE فشرده و نتیجه را به‌صورت فایلی با پسوند .gz ذخیره می‌کند.
برنامهٔ مکمل آن gunzip نام دارد که فایل‌های .gz را از حالت فشرده خارج می‌کند.

استفادهٔ پایه‌ای از آن‌ها بسیار ساده است:

[me@linuxbox ~]$ gzip foo.txt

با اجرای این دستور، فایل اصلی حذف شده و نسخهٔ فشردهٔ آن (foo.txt.gz) جایگزین می‌شود.
برای بازگرداندن فایل می‌نویسیم:

[me@linuxbox ~]$ gunzip foo.txt.gz

نکته: برنامهٔ gzip هم گزینه‌ای برای برگرداندن فایل دارد. اجرای gzip -d foo.txt.gz دقیقاً معادل gunzip foo.txt.gz است.

برنامه‌های دیگری هم هستند که می‌توانند محتوای فشرده را بدون استخراج کامل بخوانند.
به‌عنوان مثال دستور zcat فایل فشردهٔ متنی را روی خروجی استاندارد می‌نویسد تا بتوانیم آن را مشاهده یا با ابزارهایی مثل less بررسی کنیم:

[me@linuxbox ~]$ zcat foo.txt.gz | less

از آن‌جا که gzip فایل اصلی را حذف می‌کند، اگر می‌خواهید نسخهٔ فشرده و نسخهٔ اصلی را هم‌زمان نگه دارید، از گزینهٔ -k (یا --keep) استفاده کنید:

[me@linuxbox ~]$ gzip -k foo.txt

گزینهٔ -r باعث می‌شود gzip به‌صورت بازگشتی تمام فایل‌های موجود در یک دایرکتوری را فشرده کند.
همچنین با -l می‌توانیم دربارهٔ درصد فشرده‌سازی و اندازهٔ فایل‌ها گزارش بگیریم:

[me@linuxbox ~]$ gzip -l foo.txt.gz
         compressed        uncompressed  ratio uncompressed_name
              12345                67890  81.8% foo.txt

در مثال بالا ستون «ratio» نشان می‌دهد که حجم فایل حدود ۸۲٪ کاهش یافته است.


bzip2 و xz – فشرده‌سازی با راندمان بالاتر

در بسیاری از توزیع‌ها، علاوه بر gzip ابزارهای دیگری نیز وجود دارد که فایل‌ها را با الگوریتم‌هایی کارآمدتر فشرده می‌کنند.
دو مورد مهم عبارت‌اند از bzip2 و xz.

bzip2 فایل‌ها را با الگوریتم بوروز–ویلر فشرده می‌کند و معمولاً فایل خروجی کوچک‌تری نسبت به gzip تولید می‌کند، هرچند ممکن است کمی کندتر باشد.
نحوهٔ استفادهٔ آن تقریباً با gzip یکسان است:

[me@linuxbox ~]$ bzip2 foo.txt
[me@linuxbox ~]$ bunzip2 foo.txt.bz2

در کنار bunzip2، ابزارهایی مثل bzcat، bzless و bzgrep نیز وجود دارند که به ترتیب برای نمایش محتوا، مرور در محیط less و جست‌وجو داخل فایل فشرده به کار می‌روند.

ابزار جدیدتر xz فشرده‌سازی را با الگوریتم LZMA انجام می‌دهد و در بسیاری از سناریوها بهترین نسبت فشرده‌سازی را ارائه می‌کند.
فرمان‌های پایه‌ای آن مشابه است:

[me@linuxbox ~]$ xz foo.txt
[me@linuxbox ~]$ unxz foo.txt.xz

همانند خانوادهٔ gzip، در این‌جا هم برنامه‌هایی مانند xzcat، xzless و xzgrep ارائه شده‌اند.

نکته: هر سه خانواده (gzip، bzip2 و xz) فایل اصلی را پس از فشرده‌سازی حذف می‌کنند، مگر این‌که گزینهٔ -k را اضافه کنید.
بنابراین اگر می‌خواهید نسخهٔ اصلی باقی بماند، همیشه -k را فراموش نکنید.


zip و unzip – برای سازگاری با دنیای دیگر

در سیستم‌های یونیکس‌مانند معمولاً از tar برای بایگانی استفاده می‌شود؛ اما در دنیای ویندوز و macOS فرمت رایج‌تر zip است.
برای همین لینوکس هم از سال‌ها پیش ابزارهایی برای کار با این فرمت دارد.

برای ساخت یک فایل zip کافی است بنویسیم:

[me@linuxbox ~]$ zip archive.zip file1 file2 dir1

با این دستور، همهٔ فایل‌ها و دایرکتوری‌های مورد نظر در یک بستهٔ فشرده به نام archive.zip قرار می‌گیرند.
به‌طور پیش‌فرض zip ساختار دایرکتوری‌ها را حفظ می‌کند و اگر دایرکتوری را وارد کنید، محتویات آن به صورت بازگشتی اضافه می‌شود.

برای استخراج فایل zip می‌نویسیم:

[me@linuxbox ~]$ unzip archive.zip

با گزینهٔ -l می‌توانیم فهرست محتوا را بدون استخراج مشاهده کنیم:

[me@linuxbox ~]$ unzip -l archive.zip

برنامهٔ zip گزینه‌های زیادی برای رمزنگاری، حذف فایل‌ها از آرشیو، یا به‌روزرسانی آرشیو موجود دارد.
برای جزئیات بیشتر صفحهٔ راهنمای آن (man zip) را بخوانید.


tar – آرشیوساز کلاسیک

مهم‌ترین ابزار این فصل tar است که نام آن مخفف Tape ARchive می‌باشد.
در روزگاری که داده‌ها روی نوارهای مغناطیسی ذخیره می‌شدند، tar وظیفهٔ بسته‌بندی و کپی‌کردن فایل‌ها روی نوار را داشت.
امروزه هم تقریباً در هر توزیع لینوکس حضور دارد و همچنان گزینهٔ اصلی برای ساخت آرشیو محسوب می‌شود.

بر خلاف برنامه‌های فشرده‌سازی که فقط روی یک فایل کار می‌کنند، tar می‌تواند مجموعه‌ای از فایل‌ها و دایرکتوری‌ها را در قالب یک فایل منفرد ذخیره کند.
این فایل معمولاً «آرشیو tar» یا به اختصار «تاربال» نامیده می‌شود و معمولاً پسوند .tar دارد.
اغلب تاربال‌ها به کمک gzip یا bzip2 یا xz فشرده می‌شوند که در این صورت پسوندهایی مانند .tar.gz، .tar.bz2 یا .tar.xz به خود می‌گیرند.

گزینه‌های اصلی tar

tar گزینه‌های زیادی دارد، اما چند گزینهٔ کلیدی را باید همیشه به یاد داشته باشیم:

ترکیب گزینه‌ها معمولاً بدون خط تیرهٔ اضافی انجام می‌شود.
به‌عنوان مثال tar -czf معادل tar -c -z -f است.

ساخت یک تاربال ساده

فرض کنید دایرکتوری‌ای به نام playground داریم و می‌خواهیم از آن آرشیو بگیریم.
دستور زیر تاربال playground.tar را می‌سازد:

[me@linuxbox ~]$ tar -cf playground.tar playground

اگر بخواهیم در حین ساخت آرشیو نام فایل‌ها را ببینیم، گزینهٔ -v را اضافه می‌کنیم:

[me@linuxbox ~]$ tar -cvf playground.tar playground

هشدار: فراموش کردن گزینهٔ -f خطای رایجی است؛ چون در این حالت tar سعی می‌کند خروجی را روی نوار مغناطیسی بنویسد! همیشه مطمئن شوید آخرین گزینه قبل از نام فایل -f باشد.

فشرده‌سازی و آرشیو در یک مرحله

در عمل معمولاً می‌خواهیم آرشیوی بسازیم که هم‌زمان فشرده هم باشد.
برای این کار از گزینه‌های -z، -j یا -J استفاده می‌کنیم:

[me@linuxbox ~]$ tar -czf playground.tar.gz playground
[me@linuxbox ~]$ tar -cjf playground.tar.bz2 playground
[me@linuxbox ~]$ tar -cJf playground.tar.xz playground

با اجرای این دستورات، آرشیو tar ایجاد و بلافاصله با الگوریتم مربوط فشرده می‌شود.
به همین ترتیب هنگام استخراج باید همان گزینه‌ها را به کار ببریم تا آرشیو به‌درستی باز شود:

[me@linuxbox ~]$ tar -xzf playground.tar.gz
[me@linuxbox ~]$ tar -xjf playground.tar.bz2
[me@linuxbox ~]$ tar -xJf playground.tar.xz

اگر می‌خواهیم قبل از استخراج، محتویات آرشیو را ببینیم، از گزینهٔ -t استفاده می‌کنیم:

[me@linuxbox ~]$ tar -tzf playground.tar.gz

این دستور فهرست فایل‌های داخل آرشیو را نمایش می‌دهد بدون آن‌که چیزی استخراج شود.

تغییر دایرکتوری مقصد

به‌طور پیش‌فرض tar آرشیو را در محل جاری ایجاد یا استخراج می‌کند.
برای تغییر این رفتار می‌توانیم از گزینهٔ -C استفاده کنیم تا در حین استخراج، ابتدا به دایرکتوری مشخص‌شده برویم و بعد عملیات انجام شود:

[me@linuxbox ~]$ tar -xzf playground.tar.gz -C /tmp

به همین ترتیب، هنگام ساخت آرشیو می‌توانیم ابتدا با -C به یک دایرکتوری برویم و سپس فایل‌ها را از آن‌جا جمع‌آوری کنیم.
این کار کمک می‌کند مسیرهای داخل آرشیو تمیز و قابل پیش‌بینی باشند.

نگهداری مجوزها و مالکیت

tar به‌طور پیش‌فرض مجوزهای فایل‌ها، زمان و مالکیت را حفظ می‌کند.
اگر آرشیو را با دسترسی کاربر عادی بسازید و بعد آن را روی سیستمی دیگر به عنوان کاربر ریشه استخراج کنید، مالکیت فایل‌ها به کاربر ریشه تغییر خواهد کرد.
برای حفظ مالکیت اصلی باید آرشیو را با کاربری که مالک فایل‌هاست استخراج کنید یا از گزینهٔ --same-owner استفاده کنید (در صورتی که مجوز لازم را داشته باشید).

انتقال از طریق شبکه

یکی از ویژگی‌های قدرتمند tar این است که می‌تواند روی ورودی و خروجی استاندارد کار کند.
این یعنی می‌توانیم آرشیو را از طریق لوله‌ها (pipes) به فرمان‌های دیگر بدهیم.
یک نمونهٔ مشهور استفادهٔ ترکیبی از ssh برای ارسال آرشیو به سیستم دیگر است:

[me@linuxbox ~]$ tar -czf - project | ssh remote.example.com "tar -xzf - -C backups"

در این مثال آرشیو ساخته می‌شود اما روی دیسک محلی ذخیره نمی‌گردد؛ بلکه از طریق شبکه به سیستم مقصد فرستاده شده و همان‌جا استخراج می‌شود.

آرشیوهای افزایشی (Incremental)

در نسخه‌های جدید tar می‌توان آرشیوهای افزایشی ساخت؛ یعنی فقط فایل‌هایی را که از آخرین نسخهٔ پشتیبان تغییر کرده‌اند ذخیره کنیم.
برای این کار از گزینهٔ --listed-incremental همراه با یک فایل وضعیت استفاده می‌شود.
این فایل وضعیت مشخص می‌کند آخرین بار چه فایل‌هایی ذخیره شده‌اند.

[me@linuxbox ~]$ tar -czf backup-full.tar.gz --listed-incremental=tar.snar home/me

دستور بالا یک پشتیبان کامل می‌سازد و اطلاعات وضعیت را در فایل tar.snar ذخیره می‌کند.
وقتی بعداً دستور مشابهی اجرا کنیم، فقط فایل‌هایی که تغییر کرده‌اند در آرشیو جدید قرار می‌گیرند:

[me@linuxbox ~]$ tar -czf backup-inc-01.tar.gz --listed-incremental=tar.snar home/me

برای بازگرداندن چنین پشتیبانی باید ابتدا نسخهٔ کامل و سپس به ترتیب نسخه‌های افزایشی را استخراج کنیم.


همگام‌سازی دایرکتوری‌ها با rsync

آرشیو گرفتن همیشه تنها گزینهٔ پشتیبان‌گیری نیست؛ گاهی می‌خواهیم یک دایرکتوری را دقیقاً همان‌گونه که هست در جایی دیگر «آینه» کنیم.
ابزار rsync برای چنین کاری طراحی شده و با حداقل انتقال داده، دو شاخهٔ فایل را یکسان نگه می‌دارد.

[me@linuxbox ~]$ rsync -av Documents/ /media/backup/Documents/

در این مثال:

اگر مقصد روی سیستم دیگری باشد، rsync به صورت پیش‌فرض از ssh برای انتقال امن استفاده می‌کند:

[me@linuxbox ~]$ rsync -avz project/ alice@server.example.com:~/project/

گزینهٔ -z داده‌ها را در حین انتقال فشرده می‌کند. برای آزمایش دستور بدون اعمال تغییر، گزینهٔ --dry-run مفید است و تنها پیش‌نمایش انتقال را نشان می‌دهد.

وقتی می‌خواهیم مقصد دقیقاً تصویر منبع باشد (یعنی فایل‌هایی که در مقصد وجود دارند اما در منبع حذف شده‌اند پاک شوند)، از گزینهٔ --delete استفاده می‌کنیم:

[me@linuxbox ~]$ rsync -av --delete photos/ backup/photos/

می‌توان با --exclude یا --exclude-from فهرستی از فایل‌ها و دایرکتوری‌هایی را که نباید منتقل شوند مشخص کرد. افزون بر این، گزینهٔ --progress هنگام انتقال‌های طولانی نمایشگر میزان پیشرفت است.

rsync به دلیل انتقال افزایشی‌اش محبوب است؛ تنها بخش‌هایی از فایل که تغییر کرده‌اند جابه‌جا می‌شوند، بنابراین برای پشتیبان‌گیری‌های دوره‌ای یا همگام‌سازی از طریق شبکهٔ کند بسیار کارآمد است.


طرح کلی یک استراتژی پشتیبان‌گیری

همان‌طور که می‌بینیم ابزارهای زیادی وجود دارد، اما سؤال مهم این است که «چه برنامه‌ای برای پشتیبان‌گیری داشته باشیم؟»
پاسخ این سؤال به نیازها، حجم داده‌ها، زمان در دسترس و منابع سخت‌افزاری بستگی دارد.
با این حال چند اصل کلی همیشه درست است:

  1. از داده‌های مهم دست‌کم در دو محل جداگانه نسخهٔ پشتیبان داشته باشید.
    یکی از این نسخه‌ها بهتر است خارج از سیستم اصلی (مثلاً روی هارد اکسترنال یا سرویس ابری) باشد.
  2. پشتیبان‌گیری را به کار روزمره تبدیل کنید.
    اگر اجرای آن سخت یا وقت‌گیر باشد، احتمالاً فراموش می‌شود.
    استفاده از اسکریپت‌ها و ابزارهایی مثل cron برای زمان‌بندی خودکار بسیار مفید است.
  3. بازگردانی را تمرین کنید.
    داشتن پشتیبان بدون اطمینان از امکان بازیابی ارزش چندانی ندارد.
    هر چند وقت یک‌بار سعی کنید داده‌ای را از نسخهٔ پشتیبان برگردانید تا مطمئن شوید همه چیز درست کار می‌کند.

ابزارهایی مانند rsync برای همگام‌سازی دایرکتوری‌ها، یا برنامه‌های اختصاصی پشتیبان‌گیری که در توزیع‌ها ارائه می‌شوند، همگی بر پایهٔ همین مفاهیم کار می‌کنند.
rsync مخصوصاً برای انتقال مؤثر فایل‌ها به سیستم‌های دیگر محبوب است؛ زیرا فقط قسمت‌های تغییر کرده را می‌فرستد.

در نهایت باید توجه داشت که هیچ ابزاری جایگزین یک برنامهٔ منظم و آزموده‌شده نمی‌شود.
ابزارهایی که در این فصل یاد گرفتیم قطعات سازندهٔ چنین برنامه‌ای هستند؛ بقیهٔ کار بستگی به ما دارد که چگونه آن‌ها را کنار هم قرار دهیم.


جمع‌بندی


تمرین

  1. یک دایرکتوری آزمایشی بسازید و با استفاده از tar هم نسخهٔ کامل و هم نسخهٔ افزایشی از آن تهیه کنید. سپس بازگردانی را تمرین کنید.
  2. یک اسکریپت ساده بنویسید که هر شب از پوشهٔ «Documents» شما یک تاربال فشرده بسازد و آن را در دایرکتوری دیگری ذخیره کند.
  3. با rsync یک همگام‌سازی یک‌طرفه بین دو دایرکتوری انجام دهید و اثر گزینه‌های --dry-run، --delete و --exclude را بررسی کنید.

مطالعهٔ بیشتر