SSD Nodes Learn 🎉 VPS $5.50/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor

rm -rf দিয়ে মুছে ফেলা ফাইল পুনরুদ্ধার করার উপায়

rm -rf কমান্ডের মাধ্যমে ভুলবশত ফাইল মুছে ফেলেছেন? ডিস্কে নতুন ডেটা লেখা অবিলম্বে বন্ধ করুন। ext4 ফাইলসিস্টেম থেকে ফাইল পুনরুদ্ধারের কার্যকর ধাপগুলো এই নির্দেশিকায় জানুন।

প্রথম ষাট সেকেন্ডে যা করণীয়

rm -rf দিয়ে মুছে ফেলা ফাইল পুনরুদ্ধার করা যাবে কি না, তা দুটি বিষয়ের ওপর নির্ভর করে এবং এই দুটি কাজই আপনাকে সার্চ ইঞ্জিন খোলার আগে করতে হবে। প্রথমত, সেই ফাইলসিস্টেমে কোনো কিছু লেখা বন্ধ করুন। এরপর সেটিকে unmount করে অথবা read-only মোডে remount করে ব্যবহারের বাইরে নিয়ে আসুন।

rm কোনো কিছু মুছে ফেলে না। এটি শুধু ডিরেক্টরি এন্ট্রি সরিয়ে দেয় এবং inode ও ফাইলের ডেটা ব্লকগুলোকে খালি হিসেবে চিহ্নিত করে। বাইটগুলো ডিভাইসেই থেকে যায়। যতক্ষণ না ব্লক অ্যালোকেটর সেই ব্লকগুলোকে অন্য কোনো কাজের জন্য বরাদ্দ করে এবং অন্য কোনো কিছু সেখানে নতুন ডেটা লেখে, ততক্ষণ সেগুলো সেখানেই থাকে। ফাইলসিস্টেমটি মাউন্ট করা এবং সচল থাকলে প্রতি সেকেন্ডে কোনো না কোনো ডেমোন লগ ফাইল লেখে অথবা ডেটাবেস কোনো পেজ ফ্ল্যাশ করে। এই ধরনের যেকোনো রাইট অপারেশন আপনার প্রয়োজনীয় ব্লকের ওপর ডেটা লিখে দিতে পারে।

তাই প্রথম কমান্ডগুলো হওয়া উচিত রাইট অপারেশন বন্ধ করার জন্য, ফাইল পুনরুদ্ধারের জন্য নয়।

sudo systemctl stop nginx postgresql
sudo umount /mnt/data

যদি umount কমান্ডটি umount: /mnt/data: target is busy. আউটপুট দেয়, তবে খুঁজে বের করুন কোন প্রসেসটি ফাইলসিস্টেমটিকে সচল বা ওপেন করে রেখেছে।

sudo fuser -vm /mnt/data
sudo lsof +D /mnt/data

যদি আপনি এটিকে মুক্ত করতে না পারেন, তবে সেটিকে read-only মোডে remount করুন। একটি read-only মাউন্ট নতুন কোনো অ্যালোকেশন হতে দেয় না, যা আপনার প্রয়োজনের বেশিরভাগই পূরণ করে।

sudo mount -o remount,ro /mnt/data

যদি মুছে ফেলা ফাইলটি রুট ফাইলসিস্টেমে থাকে, তবে এটি করা কঠিন। sudo mount -o remount,ro / সাধারণত mount: /: cannot remount /dev/vda1 read-only. এর কারণে ব্যর্থ হবে, কারণ চলমান প্রসেসগুলো ফাইলগুলোকে রাইট মোডে ওপেন করে রাখে এবং কার্নেল সেগুলোকে জোরপূর্বক বন্ধ করবে না। একটি VPS-এর ক্ষেত্রে বাস্তবসম্মত সমাধান হলো আপনার প্রোভাইডারের rescue বা recovery মোড ব্যবহার করা: এটি একটি আলাদা live system বুট করে যেখানে আপনার ডিস্কটি মাউন্ট না করা অবস্থায় সংযুক্ত থাকে। এরপর নিচের প্রতিটি কমান্ড এমন একটি ডিভাইসে চালানো হয় যেখানে কেউ কিছু লিখছে না।

এই গাইডের পুরো সময় একটি নিয়মই প্রযোজ্য। পুনরুদ্ধার করা ফাইল, ডিস্ক ইমেজ বা নতুন ইনস্টল করা কোনো টুল কখনোই সেই ফাইলসিস্টেমে লিখবেন না যেখান থেকে আপনি ডেটা পুনরুদ্ধার করছেন। একটি দ্বিতীয় ভলিউম সংযুক্ত করুন অথবা SSH-এর মাধ্যমে আউটপুট অন্য কোনো মেশিনে পাঠান।

কেন ext4-এ rm -rf করার পর ফাইল পুনরুদ্ধার করা প্রায় অসম্ভব

কিছু ইনস্টল করার আগেই আপনার প্রত্যাশা ঠিক করে নিন। আপনি কোন ফাইলসিস্টেম ব্যবহার করছেন তা নিশ্চিত করুন:

lsblk -f

প্রায় প্রতিটি VPS ইমেজে ডিফল্ট হিসেবে থাকা ext4 ফাইলসিস্টেমে, ফাইলের ডেটা লোকেশন তার ইনোডে (inode) একটি এক্সটেন্ট ট্রি (extent tree) হিসেবে থাকে। একটি এক্সটেন্ট হলো এমন একটি রেকর্ড যা বলে যে, এই ফাইলের লজিক্যাল ব্লক N, ফিজিক্যাল ব্লক M থেকে শুরু হয়েছে এবং L ব্লক পর্যন্ত বিস্তৃত। ছোট ফাইলগুলো এই রেকর্ডের চারটি পর্যন্ত ইনোডের ভেতরেই রাখে। বড় ফাইলগুলো অতিরিক্ত ব্লকের দিকে নির্দেশ করে, যেখানে ট্রির বাকি অংশ থাকে।

যখন কোনো ফাইলের শেষ লিঙ্কটি মুছে ফেলা হয়, ext4 সেই ট্রি ধরে এগিয়ে যায়, প্রতিটি এক্সটেন্টকে ব্লক অ্যালোকেটরে ফেরত পাঠায় এবং ইনোড থেকে ট্রিটি মুছে ফেলে। এরপর ইনোডটিকে খালি হিসেবে চিহ্নিত করা হয় এবং তাতে মুছে ফেলার সময় (deletion time) স্ট্যাম্প দেওয়া হয়। ডেটা নিজে অক্ষত থাকে, কিন্তু সেই ডেটা কোথায় ছিল তার একমাত্র রেকর্ডটি মুছে ফেলা হয়েছে।

এটি ext3 থেকে ভিন্ন, যেখানে একটি মুছে ফেলা ইনোড ext3grep-এর মতো টুলের কাজ করার জন্য যথেষ্ট তথ্য রেখে দিত। ext4-এ আপনি এখনও মুছে ফেলা ইনোডগুলোর তালিকা দেখতে পারেন:

sudo debugfs -R lsdel /dev/vdb1

debugfs ডিভাইসটিকে রিড-অনলি মোডে খোলে, যদি না আপনি -w ফ্ল্যাগ ব্যবহার করেন। তাই আনমাউন্ট করা ডিভাইসে এটি চালানো নিরাপদ এবং এতে কোনো ক্ষতি নেই। ইনোডগুলোর তালিকা দেখা যাবে। কিন্তু একটি ইনোড ডাম্প করার পর সেখানেই কাজ শেষ হয়ে যায়, কারণ ইনোডটি আগে যে ব্লক ম্যাপ ব্যবহার করত তা মুছে ফেলা হয়েছে, তাই dump-এর অনুসরণ করার মতো আর কিছু থাকে না।

দুটি টুল জার্নাল (journal) পড়ার মাধ্যমে এই সীমাবদ্ধতা কাটানোর চেষ্টা করে। জার্নাল হলো একটি নির্দিষ্ট আকারের রিং, যা ext4 ক্র্যাশের সময় মেটাডেটা সামঞ্জস্যপূর্ণ রাখতে ব্যবহার করে। এতে মুছে ফেলার আগের ইনোডের একটি পুরনো কপি থাকতে পারে। extundelete এবং ext4magic উভয়ই এটি অনুসন্ধান করে। আপনার জার্নালের আকার কত তা পরীক্ষা করুন:

sudo dumpe2fs -h /dev/vdb1 | grep -i journal

জার্নাল শুধুমাত্র মেটাডেটা ধরে রাখে এবং এটি আকারে ছোট, তাই সাধারণ রাইট অ্যাক্টিভিটি দ্রুত এর মধ্য দিয়ে চলে যায়। একটি চলমান সার্ভারে মুছে ফেলার আগের ইনোডটি টিকে থাকার সময়কাল মাত্র কয়েক মিনিট। টুলগুলোর কোনোটিই বর্তমানে সক্রিয়ভাবে রক্ষণাবেক্ষণ করা হয় না এবং কোনোটিই সব ডিস্ট্রিবিউশনে প্যাকেজ হিসেবে থাকে না। উভয়কেই একটি ক্ষীণ সম্ভাবনা হিসেবে ধরুন, এগুলোকে আনমাউন্ট করা ডিভাইস বা ডিস্ক ইমেজের ওপর চালান এবং ফলাফল না পেলে অবাক হবেন না।

যদি lsblk -f রিপোর্ট করে xfs, তবে পরিস্থিতির কোনো উন্নতি নেই, কারণ XFS-এর জন্যও কোনো সমর্থিত আনডিলিট (undelete) ব্যবস্থা নেই। নিচের বিকল্পগুলোর ক্রম এতে কোনো পরিবর্তন আনে না।

ফাইলটি কি কোনো চলমান প্রসেসে ওপেন করা আছে?

এই পৃষ্ঠায় বর্ণিত পদ্ধতিগুলোর মধ্যে এটিই সফল হওয়ার সম্ভাবনা সবচেয়ে বেশি। এই কারণেই যে সার্ভিসটি ফাইলটি ব্যবহার করছিল, সেটি রিস্টার্ট করা উচিত নয়।

একটি ফাইল তখনই পুরোপুরি মুছে যায় যখন দুটি কাউন্ট শূন্যে পৌঁছায়: ফাইলটির inode-এর দিকে নির্দেশকারী ডিরেক্টরি এন্ট্রির সংখ্যা এবং ওপেন থাকা ফাইল ডেসক্রিপ্টরের সংখ্যা। rm কমান্ডটি প্রথম কাউন্টটিকে শূন্যে নামিয়ে আনে। যদি কোনো প্রসেস ফাইলটিকে ওপেন করে রাখে, তবে দ্বিতীয় কাউন্টটি শূন্য হয় না। ফলে inode এবং এর ব্লকগুলো তখনও বরাদ্দ থাকে এবং ডেটা পড়া সম্ভব হয়।

যেসব ওপেন ফাইলের লিঙ্ক কাউন্ট শূন্যে নেমে গেছে সেগুলো খুঁজে বের করুন:

sudo lsof +L1

+L1 মানে হলো এমন সব ওপেন ফাইল তালিকাভুক্ত করা যার লিঙ্ক কাউন্ট 1-এর নিচে। প্রতিটি ফলাফলে প্রসেস, ফাইল ডেসক্রিপ্টর নম্বর, NLINK-এর একটি 0 এবং (deleted) দিয়ে শেষ হওয়া একটি পাথ দেখা যাবে। PID এবং ডেসক্রিপ্টর নম্বরটি নিয়ে /proc-এ যান:

sudo ls -l /proc/1234/fd

একটি এন্ট্রি দেখতে 3 -> /var/log/app/events.log (deleted)-এর মতো হবে। সেই লিঙ্কটি এখনও ডেটা পর্যন্ত পৌঁছাতে পারে। এটিকে অন্য একটি ফাইলসিস্টেমে কপি করুন:

sudo cp /proc/1234/fd/3 /mnt/rescue/events.log

mv ব্যবহার না করে cp ব্যবহার করুন। /proc/1234/fd/3 ওপেন করলে আপনি একই inode-এর ওপর নতুন একটি হ্যান্ডেল পাবেন যা শূন্য অফসেট থেকে শুরু হয়। ফলে রাইটারের বর্তমান অবস্থানের পরের অংশটুকু পাওয়ার পরিবর্তে আপনি পুরো ফাইলটিই পাবেন।

দুটি সীমাবদ্ধতা জেনে রাখা ভালো। মুছে ফেলা ডিরেক্টরি ট্রি এভাবে ফিরে পাওয়া যায় না, কারণ শুধুমাত্র প্রসেসের ওপেন থাকা ফাইলগুলোই সংরক্ষিত থাকে। এছাড়া ডাটাবেস ইঞ্জিন যখন লিখছে এমন অবস্থায় কপি করা ফাইলটি একটি ক্র্যাশ-কনসিস্টেন্ট কপি হিসেবে গণ্য হয়। তাই সেটিকে ক্লিন ফাইল হিসেবে বিবেচনা না করে ডাটাবেস ইঞ্জিনের নিজস্ব রিকভারি টুল ব্যবহার করার পরিকল্পনা করুন। lsof কমান্ডের আউটপুটে যেসব এন্ট্রিতে ডেসক্রিপ্টর নম্বরের জায়গায় mem থাকে, সেগুলো মেমোরি ম্যাপ করা থাকে। সেগুলোর ক্ষেত্রে কপি করার জন্য কোনো /proc/<pid>/fd এন্ট্রি থাকে না।

আপনার কি btrfs, ZFS বা LVM-এ কোনো snapshot আছে?

যদি ফাইলসিস্টেম snapshot নিতে পারে, তবে মুছে ফেলা ফাইলগুলো অপরিবর্তিত অবস্থায় তার ভেতরেই রয়ে গেছে। এটি কেবল তখনই কাজে দেয় যদি মুছে ফেলার আগে কোনো snapshot তৈরি করা থাকে। এখন আপনি নতুন যা কিছু তৈরি করবেন তা অতীতে কার্যকর হবে না।

btrfs snapshot-গুলোকে subvolume হিসেবে রাখে:

sudo btrfs subvolume list /

snapshot ব্রাউজ করুন এবং cp -a ব্যবহার করে প্রয়োজনীয় পাথগুলো কপি করে নিন। পুরো subvolume রোলব্যাক করার চেয়ে নির্দিষ্ট পাথ কপি করা ভালো, কারণ রোলব্যাক করলে snapshot নেওয়ার পর থেকে লেখা সমস্ত ডেটা মুছে যায়।

ZFS প্রতিটি snapshot-কে একটি read-only ডিরেক্টরি হিসেবে প্রদর্শন করে:

zfs list -t snapshot
ls /tank/data/.zfs/snapshot/

.zfs ডিরেক্টরিটি লুকানো থাকে এবং ডেটাসেটের রুটে সাধারণ ls কমান্ড দিলে তা দেখা যায় না, তবে আপনি নাম ধরে সরাসরি সেখানে প্রবেশ করতে পারেন। সেখান থেকে ফাইলগুলো কপি করে নিন। zfs rollback পুরো ডেটাসেটকে আগের অবস্থায় ফিরিয়ে নেয় এবং আপনার দেওয়া নামের পরের সমস্ত snapshot ধ্বংস করে ফেলে, তাই এটিকে শেষ উপায় হিসেবে রাখুন।

LVM snapshot হলো নির্দিষ্ট আকারের copy-on-write ভলিউম:

sudo lvs
sudo mount -o ro /dev/vg0/data-snap /mnt/snap

এটিকে read-only মোডে মাউন্ট করুন এবং ফাইল কপি করে নিন। বিশ্বাস করার আগে lvs চেক করে নিন, কারণ LVM snapshot-এর জন্য বরাদ্দকৃত জায়গা পূর্ণ হয়ে গেলে কার্নেল সেটিকে অকার্যকর করে দেয় এবং একবার এমনটি ঘটলে এর ভেতরের বিষয়বস্তু হারিয়ে যায়।

snapshot কোনো ব্যাকআপ নয়। এটি মূল ডেটার মতোই একই ডিস্ক বা একই পুলে থাকে, তাই মূল ডেটার যেকোনো ব্যর্থতা এতেও প্রভাব ফেলে। দুই মিনিট আগে করা কোনো ভুল সংশোধনের জন্য এটি অত্যন্ত কার্যকর, যা এই পরিস্থিতির জন্য একদম উপযুক্ত।

PhotoRec দিয়ে ফাইল কার্ভিং, সরাসরি ডিস্কে নয় বরং ইমেজ ফাইলে কাজ করুন

যদি উপরের কোনো পদ্ধতিই কাজ না করে, তবে শেষ উপায় হলো কার্ভিং: র (raw) ডিভাইসে এমন সব বাইট প্যাটার্ন স্ক্যান করা যা কোনো পরিচিত ফাইল টাইপের শুরু নির্দেশ করে, এবং এরপর যা পাওয়া যায় তা লিখে ফেলা। কার্ভিং শুধুমাত্র ফাইলের ডেটা পড়ে। ফাইলের নাম, ডিরেক্টরি স্ট্রাকচার, টাইমস্ট্যাম্প এবং মালিকানা—এসবই হলো ফাইলসিস্টেম মেটাডেটা, আর এই মেটাডেটাই rm ধ্বংস করে ফেলেছে, তাই এর কিছুই ফিরে পাওয়া সম্ভব নয়। আপনি একটি নাম্বারিং করা আউটপুট ডিরেক্টরিতে f0384512.jpg নামের ফাইলগুলো পাবেন এবং আপনাকে সেগুলো হাতে বাছাই করতে হবে।

এই পদ্ধতিটি কাজ করবে কি না তা দুটি নিয়মের ওপর নির্ভর করে।

প্রথমত, অন্য কোনো টুল ব্যবহার করার আগেই ডিভাইসটির একটি ইমেজ তৈরি করুন। Debian এবং Ubuntu-তে প্যাকেজটির নাম gddrescue এবং এটি যে বাইনারি ইনস্টল করে তা হলো ddrescue

sudo apt update && sudo apt install -y gddrescue testdisk
sudo ddrescue -n /dev/vdb1 /mnt/rescue/vdb1.img /mnt/rescue/vdb1.map

/mnt/rescue অবশ্যই একটি ভিন্ন ডিভাইসে থাকতে হবে, যেখানে পার্টিশনের সমান বা তার চেয়ে বেশি খালি জায়গা আছে। lsblk -b বাইট এককে সঠিক আকার প্রদর্শন করে। ম্যাপ ফাইলটি থাকলে কোনো কারণে কপি বাধাগ্রস্ত হলে তা শুরু থেকে না করে মাঝখান থেকে পুনরায় শুরু করা যায়। একবার ইমেজ তৈরি হয়ে গেলে আপনি পরবর্তীতে একই বাইটগুলোর ওপর অন্য কোনো টুল ব্যবহার করে দেখতে পারবেন, যা প্রথম টুলটি সরাসরি ডিস্কে লিখে ফেললে সম্ভব হতো না।

দ্বিতীয়ত, রিকভারি টুলটিকে ইমেজ ফাইলের দিকে নির্দেশ করুন।

sudo photorec /d /mnt/rescue/recup /mnt/rescue/vdb1.img

photorec একটি টেক্সট মেনু খোলে। পার্টিশন নির্বাচন করুন, এরপর ফাইলসিস্টেম টাইপ, তারপর যে ফাইল সিগনেচারগুলো খুঁজতে চান তা নির্বাচন করুন এবং সবশেষে গন্তব্য ডিরেক্টরি ঠিক করুন। শুরু করার আগে সিগনেচারের তালিকাটি শুধুমাত্র আপনার হারানো ফাইল টাইপগুলোর মধ্যে সীমাবদ্ধ রাখুন, কারণ ডিফল্ট তালিকায় সবকিছুই থাকে এবং এটি আপনাকে হাজার হাজার টুকরো ফাইল দেবে যা বাছাই করা কঠিন।

একই প্যাকেজের testdisk-এর নিজস্ব আনডিলিট ফাংশন রয়েছে, যা শুধুমাত্র FAT, exFAT, NTFS এবং ext2 সাপোর্ট করে। ext4-এর ক্ষেত্রে শুধুমাত্র photorec ব্যবহার করা যায়।

টুকরো হয়ে যাওয়া ফাইলগুলো ভাঙা অবস্থায় ফিরে আসার সম্ভাবনা থাকে। কার্ভিং ধরে নেয় যে একটি ফাইলের ব্লকগুলো পর্যায়ক্রমে (contiguous) সাজানো থাকে, তাই অ্যালোকেটর যদি ফাইলটিকে ডিস্কের বিভিন্ন জায়গায় ছড়িয়ে রাখে, তবে সেটি হয় ভুলভাবে জোড়া লাগবে অথবা একেবারেই পাওয়া যাবে না। মিডিয়া ফাইলগুলো কার্ভিংয়ে মোটামুটি ভালো পাওয়া যায় কারণ সেগুলোর শক্তিশালী হেডার থাকে। সাধারণ টেক্সট, কনফিগারেশন এবং সোর্স কোড কার্ভিংয়ে খুব খারাপ ফলাফল দেয়, কারণ কোনো শেল স্ক্রিপ্টের শুরু নির্দেশ করার মতো নির্দিষ্ট কোনো বাইট সিগনেচার নেই।

অতিরিক্ত স্পেস: ভুল পাথ যেভাবে ডিলিট হয়ে যায়

প্রায় প্রতিটি rm -rf দুর্ঘটনা একটি শেল সমস্যা। rm পাথগুলোর একটি তালিকা পায় এবং পর্যায়ক্রমে প্রতিটি ডিলিট করে। আপনি কী বোঝাতে চেয়েছেন তা এটি কখনোই বুঝতে পারে না।

সবচেয়ে পরিচিত সমস্যাটি হলো একটি অতিরিক্ত স্পেস:

rm -rf /home/deploy/app /old
rm -rf /home/deploy/app/old

প্রথম লাইনটি দুটি আর্গুমেন্ট হিসেবে কাজ করে। এটি প্রথমে অ্যাপ্লিকেশনটি ডিলিট করে, তারপর /old ডিলিট করে। যদি /old বিদ্যমান না থাকে, তবে rm কিছুই প্রিন্ট করে না, কারণ -f ফাইল না পাওয়ার এরর মেসেজটি চেপে রাখে। নীরবতা মানেই নিশ্চিতকরণ নয়।

দ্বিতীয় ধরণটি হলো একটি আনকোট করা ভেরিয়েবল, যার মধ্যে একটি স্পেস রয়েছে:

dir="/srv/my app"
rm -rf $dir

শেল হোয়াইটস্পেসের ভিত্তিতে ভ্যালুটিকে আলাদা করে ফেলে, তাই rm দুটি আলাদা পাথ হিসেবে /srv/my এবং app গ্রহণ করে। rm -rf "$dir" হিসেবে লিখলে এটি একটি পাথ হিসেবে গণ্য হতো।

তৃতীয়টি হলো একটি খালি ভেরিয়েবল, সাধারণত এটি ঘটে কারণ যে কমান্ডটি এটি পূরণ করার কথা ছিল তা ব্যর্থ হয়েছে:

rm -rf "$TARGET"/*

TARGET সেট করা না থাকলে, এটি প্রসারিত হয়ে rm -rf /* এ পরিণত হয়। GNU rm এই খালি ফরমটি গ্রহণ করতে অস্বীকার করে: rm -rf / প্রিন্ট করে rm: it is dangerous to operate recursively on '/' এবং কাজ বন্ধ করে দেয়। গ্লোব (glob) ফরমটি এই সুরক্ষা পায় না, কারণ rm রান করার আগেই শেল /* কে প্রকৃত টপ-লেভেল পাথগুলোর একটি তালিকা দিয়ে প্রতিস্থাপন করে। যেহেতু / সেগুলোর মধ্যে নেই, তাই গার্ডটি কখনোই কাজ করে না।

পরবর্তী বিপর্যয় এড়ানোর অভ্যাসসমূহ

  • পাথ হিসেবে ব্যবহৃত প্রতিটি ভেরিয়েবলকে কোটেশনের ভেতরে রাখুন। প্রতিবার "$dir" ব্যবহার করুন, এমনকি টেস্ট এবং লুপের ভেতরেও।
  • খালি থাকলে ব্যর্থ হোন। যখনই TARGET আনসেট বা খালি থাকে, তখন rm শুরু হওয়ার আগেই rm -rf "${TARGET:?TARGET is not set}"/* শেলটিকে আপনার মেসেজসহ থামিয়ে দেয়। ডিলিট করে এমন যেকোনো স্ক্রিপ্টের শুরুতে set -euo pipefail যুক্ত করুন।
  • --one-file-system যোগ করুন। এটি rm-কে নির্দেশ দেয় যে, আপনার দেওয়া আর্গুমেন্ট থেকে ভিন্ন কোনো ফাইলসিস্টেমে থাকা ডিরেক্টরি যেন এড়িয়ে যাওয়া হয়। ফলে রিকার্সিভ ডিলিট কোনো মাউন্ট করা ব্যাকআপ ভলিউম বা বাইন্ড মাউন্টের ভেতরে প্রবেশ করতে পারে না।
  • রুট হিসেবে ডিলিট করবেন না। একটি সার্ভিস অ্যাকাউন্ট কেবল তার মালিকানাধীন ফাইলগুলোই ধ্বংস করতে পারে, যা প্রতিটি সার্ভিসকে আলাদা আনপ্রিভিলেজড ইউজার হিসেবে চালানোর মূল যুক্তি। কোনো নির্দিষ্ট অ্যাকাউন্টের অ্যাক্সেস কতদূর, তা নিশ্চিত না হলে ls লিস্টিংয়ের পারমিশন বিট পড়া একটি কমান্ডেই তার উত্তর দেয়।
  • কাজ করার আগে তালিকাটি প্রিন্ট করুন। স্ক্রিপ্টের ক্ষেত্রে, পাথগুলো তৈরি করুন, সেগুলোকে printf '%s\n' করুন, আউটপুট পড়ুন, তারপর দ্বিতীয় ধাপে ডিলিট করুন।
  • হাতের কাছে একটি ট্র্যাশ কমান্ড রাখুন। sudo apt install trash-cli আপনাকে trash-put, trash-list, trash-restore এবং trash-empty ব্যবহারের সুবিধা দেয়। ডিলিট করা ফাইলগুলো ~/.local/share/Trash-এ চলে যায় এবং trash-empty 30 ত্রিশ দিনের বেশি পুরনো যেকোনো ফাইল মুছে ফেলে।

rm-কে trash-put হিসেবে অ্যালিয়াস করাকে পরবর্তী যৌক্তিক পদক্ষেপ মনে হতে পারে, কিন্তু এটি একটি ফাঁদ। এই অ্যালিয়াস এমন একটি অভ্যাসের জন্ম দেয় যা অন্য কোনো সার্ভারে কাজ করে না, আর স্ক্রিপ্টের ভেতরে অ্যালিয়াস কাজ করে না—যেখানে বড় ধরনের ভুলগুলো হওয়ার সম্ভাবনা থাকে। বরং সচেতনভাবে trash-put টাইপ করুন।

একমাত্র পুনরুদ্ধার পদ্ধতি যা সবসময় কাজ করে

উপরের সবকিছুই একটি সুযোগ মাত্র। কিন্তু ব্যাকআপ কোনো সুযোগের বিষয় নয়।

দুটি বিষয় একটি ব্যাকআপকে প্রকৃত ব্যাকআপ করে তোলে। প্রথমত, এটি আপনার মনে রাখা ছাড়াই নিয়মিত শিডিউল অনুযায়ী চলে। দ্বিতীয়ত, আপনি অন্তত একবার এটি থেকে ডেটা পুনরুদ্ধার করেছেন। যে রিপোজিটরি থেকে কেউ কখনো ডেটা পুনরুদ্ধার করেনি, তা কেবল একটি বিশ্বাস মাত্র। কারণ, ব্যাকআপ অকেজো হওয়ার কারণগুলো (যেমন: ইনক্লুড লিস্টে ভুল পাথ থাকা বা রিপোজিটরির পাসওয়ার্ড হারিয়ে ফেলা) কেবল সেই দিনই ধরা পড়ে, যেদিন আপনার ব্যাকআপটি সবচেয়ে বেশি প্রয়োজন হয়।

restic-এর ক্ষেত্রে, পুনরুদ্ধার করার জন্য মাত্র দুটি কমান্ড প্রয়োজন।

restic -r /srv/restic-repo snapshots
restic -r /srv/restic-repo restore latest --target /mnt/rescue --include /srv/appdata

লাইভ পাথের ওপর সরাসরি ডেটা পুনরুদ্ধার না করে একটি খালি ডিরেক্টরিতে করুন। এতে কোনো কিছু প্রতিস্থাপনের আগে আপনি দুটি ডিরেক্টরির মধ্যে তুলনা করতে পারবেন। VPS-এ restic ব্যাকআপ সেটআপ করা অংশে রিপোজিটরি সেটআপ এবং এটি চালানোর জন্য systemd টাইমার সম্পর্কে আলোচনা করা হয়েছে।

Borg-এর ক্ষেত্রে:

borg list /srv/borg-repo
borg extract /srv/borg-repo::daily-2026-08-08 srv/appdata

Borg আর্কাইভের ভেতরের পাথগুলো শুরুর স্ল্যাশ (/) ছাড়াই সংরক্ষিত থাকে, তাই srv/appdata কাজ করে কিন্তু /srv/appdata কোনো কিছু খুঁজে পায় না। borg extract বর্তমান ওয়ার্কিং ডিরেক্টরিতে ডেটা লেখে, তাই প্রথমে cd ব্যবহার করে একটি স্ক্র্যাচ ডিরেক্টরিতে পুনরুদ্ধার করুন।

আপনি যদি এখনো দুটির মধ্যে কোনোটি বেছে না নিয়ে থাকেন, তবে restic এবং Borg-এর তুলনা অংশে ডিডুপ্লিকেশন (deduplication) এবং অ্যাপেন্ড-অনলি (append-only) রিপোজিটরি সম্পর্কে জানতে পারবেন। অ্যাপেন্ড-অনলি রিপোজিটরি এমন একটি বৈশিষ্ট্য যা একটি আক্রান্ত সার্ভারকে তার নিজের ব্যাকআপ হিস্ট্রি মুছে ফেলা থেকে বিরত রাখে। যেকোনো একটি টুল ব্যবহার করলেই চলবে। ভুল সিদ্ধান্ত হলো কোনোটিই ব্যবহার না করা।

নতুন সার্ভার সেটআপ করার সময়টিই এটি করার সবচেয়ে উপযুক্ত মুহূর্ত, কারণ তখনো সেখানে হারানোর মতো গুরুত্বপূর্ণ কিছু থাকে না। নতুন VPS-এ প্রথম দশ মিনিট অংশে SSH এবং ফায়ারওয়াল সেটআপের পাশাপাশি এই কাজটি করার পরামর্শ দেওয়া হয়েছে।

এরপর আপনার ক্যালেন্ডারে একটি পুনরাবৃত্তিমূলক এন্ট্রি রাখুন: প্রতি মাসে রিপোজিটরি থেকে একটি ডিরেক্টরি /tmp-এ পুনরুদ্ধার করুন এবং ফাইলগুলো যাচাই করুন। এই একটি অভ্যাস এই পৃষ্ঠার সব টুলের চেয়েও বেশি কার্যকর।

FAQ

আমি কি ext4-এ কোনো ডিলিট করা ফাইল উদ্ধার করতে পারি?

সাধারণত না। যখন কোনো ফাইলের শেষ লিঙ্কটি মুছে ফেলা হয়, তখন ext4 ইনোড (inode) থেকে এক্সটেন্ট ট্রি (extent tree) মুছে ফেলে। ফলে ডিস্কের কোথাও সেই ডেটা কোথায় ছিল তার কোনো রেকর্ড থাকে না। extundelete এবং ext4magic টুলগুলো ext4 জার্নাল থেকে ইনোডের পুরোনো কপি খোঁজার চেষ্টা করে। এটি কেবল তখনই কাজ করে যদি ফাইলটি কয়েক মিনিট আগে ডিলিট করা হয়ে থাকে এবং ফাইলসিস্টেমটি এরপর থেকে নিষ্ক্রিয় থাকে। এই প্রজেক্টগুলোর কোনোটিই বর্তমানে রক্ষণাবেক্ষণ করা হয় না। যেকোনো একটি টুল চালানোর সময় অবশ্যই আনমাউন্ট করা ডিভাইস বা ডিস্ক ইমেজের ওপর চালান, কখনোই মাউন্ট করা ফাইলসিস্টেমে চালাবেন না। কাজ শুরু করার আগে sudo dumpe2fs -h /dev/vdb1 | grep -i journal ব্যবহার করে নিশ্চিত হয়ে নিন আপনি কোন ডিভাইসে কাজ করছেন।

একটি সার্ভিস এখনো ডিলিট করা ফাইলটি ওপেন করে রেখেছে। আমি কি এটি ফেরত পেতে পারি?

হ্যাঁ, এটিই সবচেয়ে ভালো পরিস্থিতি। যতক্ষণ কোনো প্রসেস ফাইলটিকে ওপেন করে রাখে, ততক্ষণ এর ইনোড এবং ডেটা ব্লকগুলো বরাদ্দ থাকে, তাই ডেটা পড়া সম্ভব। সার্ভিসটি রিস্টার্ট করবেন না, কারণ শেষ ডেসক্রিপটরটি বন্ধ হয়ে গেলে ডিলিট প্রক্রিয়া সম্পন্ন হয়ে যায়। sudo lsof +L1 চালিয়ে দেখুন কোন ওপেন ফাইলগুলোর লিঙ্ক কাউন্ট 0। এরপর PID এবং ফাইল ডেসক্রিপটর নম্বরটি নোট করুন এবং sudo cp /proc/1234/fd/3 /mnt/rescue/events.log ব্যবহার করে /proc-এর মাধ্যমে কপি করুন। কপিটি অন্য কোনো ফাইলসিস্টেমে সেভ করুন। যেসব এন্ট্রিতে ডেসক্রিপটর নম্বরের পরিবর্তে mem দেখানো হয়, সেগুলো মেমোরি ম্যাপ করা থাকে এবং কপি করার জন্য কোনো /proc/<pid>/fd পাথ থাকে না।

রিকভারি টুল সরাসরি ডিস্কে না চালিয়ে ইমেজ তৈরি করা উচিত কেন?

কারণ প্রতিটি টুলকে তার আউটপুট কোথাও না কোথাও লিখতে হয়। আপনি যে ফাইলসিস্টেম থেকে ডেটা উদ্ধার করছেন, সেখানে কিছু লিখলে তা সেই ফ্রি ব্লকের ওপর পড়তে পারে যেখানে আপনার ডেটা এখনো সংরক্ষিত আছে। প্রথমে sudo ddrescue -n /dev/vdb1 /mnt/rescue/vdb1.img /mnt/rescue/vdb1.map ব্যবহার করে পার্টিশনটিকে অন্য কোনো ডিভাইসে কপি করুন, তারপর ইমেজ ফাইলটির ওপর photorec চালান। ইমেজ ফাইল থাকলে আপনি পরবর্তীতে একই বাইটের ওপর অন্য কোনো টুল দিয়ে চেষ্টা করতে পারবেন, যা অরিজিনাল ডিস্কে কিছু লিখে ফেলার পর আর সম্ভব নয়।

rm -rf / কমান্ড কি এখনো লিনাক্স সিস্টেম ধ্বংস করে?

শুধুমাত্র এই কমান্ডটি তা করে না। GNU rm এটি প্রত্যাখ্যান করে এবং rm: it is dangerous to operate recursively on '/' প্রিন্ট করে। বিপদজনক রূপগুলো আসে অন্য পথ দিয়ে। TARGET আনসেট থাকা অবস্থায় rm -rf "$TARGET"/* কমান্ডটি rm -rf /*-এ প্রসারিত হয়। শেল তখন rm-কে টপ-লেভেল ডিরেক্টরিগুলোর একটি তালিকা দেয়, যার কোনোটিই / নয়, তাই নিরাপত্তা ব্যবস্থাটি আর কাজ করে না। এর পরিবর্তে "${TARGET:?TARGET is not set}" লিখুন, তাহলে rm রান করার আগেই শেল থামিয়ে দেবে।

ফাইলসিস্টেম স্ন্যাপশট কি ব্যাকআপ?

না। btrfs বা ZFS স্ন্যাপশট যে ডেটা রক্ষা করে, সেটি একই পুলে থাকে। তাই ডিস্ক নষ্ট হলে বা পুল ধ্বংস হয়ে গেলে উভয়ই একসাথে হারিয়ে যায়। LVM স্ন্যাপশটের ক্ষেত্রে নির্দিষ্ট সাইজের একটি সমস্যা আছে: এটি পূর্ণ হয়ে গেলে কার্নেল এটিকে অকার্যকর করে দেয় এবং এর ভেতরের সব ডেটা মুছে যায়। স্ন্যাপশট দুই মিনিট আগের কোনো ডিলিট করা ফাইল উদ্ধারের জন্য চমৎকার। তবে অন্য সবকিছুর জন্য আলাদা হার্ডওয়্যারে একটি রিপোজিটরি রাখুন।

#linux#rm#data-recovery#backups#ext4