Oracle Undo বনাম Redo সহজ ব্যাখ্যা - এবং ORA-01555 আসলেই কীভাবে সারাবেন
দশজন ডেটাবেজ পেশাজীবীকে undo আর redo-র পার্থক্য জিজ্ঞেস করুন - আত্মবিশ্বাসী কিন্তু ভুল উত্তর বেশ কয়েকটা পাবেন, কারণ শব্দ দুটো শুনতে একই রকম আর দুটোই কোনো-না-কোনোভাবে "রিকভারি" জড়িত। অথচ এই দুটি মেকানিজমই Oracle-এর সামঞ্জস্য (consistency) ধরে রাখা আর ক্র্যাশ থেকে বেঁচে ফেরার হৃৎপিণ্ড - আর এগুলো ভুল বোঝার কারণেই ক্লাসিক ORA-01555 "snapshot too old" ত্রুটি যুগের পর যুগ ধরে লম্বা রিপোর্টগুলোকে তাড়া করে বেড়াচ্ছে। এই গাইডে দুটো মেকানিজমই সহজ ভাষায় ব্যাখ্যা করা হয়েছে, দেখানো হয়েছে read consistency আসলে কীভাবে কাজ করে, আর দেওয়া হয়েছে অনুমান-ছাড়া একটি বাস্তব পদ্ধতি - undo সাইজ করে ORA-01555 চিরতরে বিদায় করার।
মূল কথাগুলো
- Redo ডেটাবেজকে ক্ষতি থেকে রক্ষা করে: প্রতিটি পরিবর্তন রেকর্ড করে যাতে ক্র্যাশের পর কমিট হওয়া কাজ রিপ্লে করা যায়। Undo রক্ষা করে ট্রানজ্যাকশন ও পাঠকদের: পরিবর্তন কীভাবে উল্টানো যায় তা রেকর্ড করে এবং ডেটার পুরনো ইমেজ সরবরাহ করে।
- Read consistency-ই undo-র সবচেয়ে গুরুত্বপূর্ণ কাজ - একটি কোয়েরি ডেটাবেজকে ঠিক সেই অবস্থায় দেখে যেমনটি কোয়েরি শুরুর মুহূর্তে ছিল, আর তা পুনর্গঠিত হয় undo থেকে।
- ORA-01555 মানে দীর্ঘ সময় ধরে চলা একটি কোয়েরির এমন পুরনো ডেটা-ইমেজ দরকার ছিল যার undo ইতিমধ্যে ওভাররাইট হয়ে গেছে - এটি undo retention-এর সমস্যা, করাপশন নয়।
- ORA-01555 সারান সাইজিং দিয়ে: দীর্ঘতম কোয়েরি মাপুন, UNDO_RETENTION তার চেয়ে বেশি সেট করুন, এবং তা রক্ষা করার মতো যথেষ্ট জায়গা undo tablespace-কে দিন।
- V$UNDOSTAT আপনাকে সত্যিটা বলে: প্রকৃত undo ব্যবহার, দীর্ঘতম কোয়েরি, আর প্রতি পিরিয়ডে কতগুলো ORA-01555 ঘটেছে।
- RETENTION GUARANTEE জায়গার চাপেও Oracle-কে retention মানতে বাধ্য করে - শক্তিশালী, তবে এটি writer-দের আটকে দিতে পারে, তাই ভেবেচিন্তে ব্যবহার করুন।
১. দুটি ভিন্ন কাজ: অতীত রক্ষা বনাম ভবিষ্যৎ রক্ষা
Undo আর redo গুলিয়ে না ফেলার সবচেয়ে পরিষ্কার উপায় হলো - প্রত্যেকে কোন প্রশ্নের উত্তর দেয় তা মনে রাখা।
Redo-র প্রশ্ন: "ব্যর্থতার পর কমিট হওয়া কাজ আমি আবার কীভাবে করব?" Oracle-এর প্রতিটি পরিবর্তন - টেবিলে, ইনডেক্সে, এমনকি খোদ undo-তেও - redo রেকর্ড তৈরি করে, যা LGWR ধারাবাহিকভাবে online redo log-এ লেখে। সার্ভার মারা গেলে Oracle স্টার্টআপে redo রিপ্লে করে ডেটাফাইলগুলোকে ক্র্যাশের মুহূর্ত পর্যন্ত এগিয়ে আনে। Redo-র অস্তিত্বই এজন্য যে কমিট হওয়া ট্রানজ্যাকশন কখনও হারায় না।
Undo-র প্রশ্ন: "একটি পরিবর্তন কীভাবে উল্টাব, বা ডেটা আগে যেমন ছিল তেমন কীভাবে দেখব?" কোনো row পরিবর্তনের আগে Oracle পুরনো মানগুলো একটি undo segment-এ কপি করে রাখে। সেই পুরনো ইমেজ দুই প্রভুর সেবা করে: রোলব্যাক করা ট্রানজ্যাকশন, এবং - তার চেয়ে অনেক বেশি বার - অন্য সেশনগুলো, যাদের row-টিকে কোনো আনকমিটেড বা সাম্প্রতিক পরিবর্তনের আগের চেহারায় পড়তে হয়।
জুনিয়রদের আমি একটি স্মরণীয় সারাংশ দিই: redo ইতিহাস রিপ্লে করে, undo তা রিওয়াইন্ড করে। Redo লেখা হয় সেই ক্র্যাশের জন্য যা আপনি আশা করেন কখনও ঘটবে না; আর undo ব্যবহৃত হয় অবিরাম, প্রতি সেকেন্ডে, সাধারণ কোয়েরিগুলোর হাতে।
২. Read Consistency: Undo-র আসল নিত্যদিনের কাজ
Oracle-এর মুকুটমণি হলো পাঠকরা কখনও লেখকদের আটকায় না, লেখকরাও কখনও পাঠকদের আটকায় না। এর মেকানিজম হলো multi-version read consistency, আর তা চলে undo-র ওপর।
আপনার কোয়েরি যদি ১০:০০:০০-তে শুরু হয়, Oracle তাকে ঠিক ১০:০০:০০ মুহূর্তের ডেটাবেজের একটি দৃশ্য দেওয়ার প্রতিশ্রুতি দেয়। অন্য একটি সেশন যদি ১০:০০:০৫-এ কোনো row আপডেট করে - এমনকি কমিটও করে দেয় - আপনার কোয়েরি সেই নতুন মান দেখবে না, দেখা চলবেই না। তাই আপনার কোয়েরি যখন সেই ব্লকে পৌঁছায়, Oracle খেয়াল করে ব্লকটি কোয়েরি শুরুর পরে বদলেছে, undo-তে যায়, এবং শুধু আপনার জন্যই ব্লকটির ১০:০০:০০ সংস্করণ পুনর্গঠন করে। একেই বলে consistent read।
এবার সবচেয়ে জরুরি খুঁটিনাটি: undo segment একটি বৃত্তাকার বাফার। ট্রানজ্যাকশন কমিট হয়ে গেলে তার undo আর আবশ্যক থাকে না, এবং জায়গার দরকার পড়লে তা ওভাররাইট হওয়ার যোগ্য হয়ে যায়। Oracle যতক্ষণ পারে তা ধরে রাখে - যা নিয়ন্ত্রিত হয় UNDO_RETENTION দিয়ে - কিন্তু চাপে পড়লে পুরনো undo রিসাইকেল হয়ে যায়।
৩. তাহলে ORA-01555 আসলে ঠিক কী?
দুটি তথ্য পাশাপাশি বসান। দীর্ঘ সময় ধরে চলা একটি কোয়েরির undo থেকে পুরনো ব্লক-ইমেজ দরকার। আর undo সময়ের সঙ্গে রিসাইকেল হয়। আপনার কোয়েরি যদি ৪৫ মিনিট চলে এবং ৪০তম মিনিটে এমন একটি undo রেকর্ড দরকার পড়ে যা ২৫তম মিনিটেই ওভাররাইট হয়ে গেছে - Oracle তার প্রতিশ্রুত সামঞ্জস্যপূর্ণ ছবিটি আর বানাতে পারে না। চুপচাপ ভুল ডেটা দেওয়ার বদলে সে তোলে:
ORA-01555: snapshot too old: rollback segment number ... too small
এই বোঝাপড়া থেকে তিনটি সিদ্ধান্ত আসে। প্রথমত, ORA-01555 করাপশন নয়, বাগও নয় - কোনো কিছুরই ক্ষতি হয়নি। দ্বিতীয়ত, ত্রুটিটা লাগে পাঠকের গায়ে (সাধারণত একটি লম্বা রিপোর্ট বা এক্সপোর্ট), কিন্তু কারণটা হলো পাঠকের সময়কাল আর undo রিসাইকেল করে দেওয়া লেখকদের কার্যক্রম - এই দুইয়ের সমন্বয়। তৃতীয়ত, সমাধানের চাবিকাঠি retention: আপনার দীর্ঘতম পাঠকের জন্য undo যথেষ্টক্ষণ ধরে রাখা।
জেনে রাখার মতো একটি বিশেষ ধরন: delayed block cleanout। বিশাল একটি কমিট হওয়া ট্রানজ্যাকশনের ছোঁয়া লাগা ব্লকে তখনও পুরনো লক-তথ্য থেকে যেতে পারে; পরের পাঠককে কমিট নিশ্চিত করতে undo-তে যেতে হয়, আর সেই undo না থাকলে ORA-01555 দেখা দিতে পারে যদিও "কিছুই তো চলছিল না।" বিরল, কিন্তু ব্যাচ লোডের পরের রহস্যময় কেসগুলোর ব্যাখ্যা এটিই।
৪. V$UNDOSTAT দিয়ে নির্ণয় - সৎ সাক্ষী
যা কিছু জানা দরকার সবই দশ-মিনিটের বাকেটে রেকর্ড করা থাকে V$UNDOSTAT-এ:
-- How much undo is being generated, the longest query, and 1555s per bucket
SELECT TO_CHAR(begin_time,'DD-MON HH24:MI') AS began,
undoblks AS undo_blocks,
txncount AS txns,
maxquerylen AS longest_query_sec,
ssolderrcnt AS ora_1555_count,
nospaceerrcnt AS space_errors,
tuned_undoretention AS auto_tuned_retention
FROM v$undostat
ORDER BY begin_time DESC FETCH FIRST 24 ROWS ONLY;
-- Current settings and undo tablespace size
SHOW PARAMETER undo
SELECT tablespace_name, ROUND(SUM(bytes)/1024/1024/1024,1) AS gb
FROM dba_data_files WHERE tablespace_name LIKE 'UNDO%'
GROUP BY tablespace_name;
দুটি কলামই আপনার সমাধান ঠিক করে দেয়। MAXQUERYLEN হলো Oracle-এর দেখা দীর্ঘতম কোয়েরি (সেকেন্ডে) - আপনার retention অবশ্যই এর চেয়ে বেশি হতে হবে। SSOLDERRCNT প্রকৃত ORA-01555-এর সংখ্যা গোনে, ফলে ঠিক কখন সেগুলো জড়ো হচ্ছে তা দেখতে পান (সাধারণত রাতের ব্যাচ উইন্ডোয়, যখন ভারী write লম্বা রিপোর্টের পায়ের নিচ থেকে undo রিসাইকেল করে নেয়)।
৫. সাইজিং পদ্ধতি (কোনো অনুমান নয়)
Undo সাইজিং পাটিগণিত, শিল্পকলা নয়। প্রয়োজনীয় জায়গা মোটামুটি:
undo space = (undo blocks generated per second) x (retention seconds) x block size
-- Get your real undo generation rate from history:
SELECT ROUND(MAX(undoblks/((end_time-begin_time)*86400))) AS peak_undo_blocks_per_sec,
ROUND(AVG(undoblks/((end_time-begin_time)*86400))) AS avg_undo_blocks_per_sec
FROM v$undostat;
- দীর্ঘতম কোয়েরি খুঁজুন - V$UNDOSTAT থেকে
MAX(MAXQUERYLEN)। ধরুন সেটি ৫,৪০০ সেকেন্ড (৯০ মিনিট)। - Retention তার ওপরে সেট করুন - কিছুটা বাড়তি জায়গাসহ:
ALTER SYSTEM SET undo_retention = 7200;(২ ঘণ্টা)। - তা রক্ষার মতো করে tablespace সাইজ করুন - পিক রেট x retention x block size। যেমন, 300 blocks/sec x 7,200 sec x 8 KB ≈ 17 GB। পাটিগণিত যা দাবি করে undo tablespace তার চেয়ে ছোট হলে retention একটি ইচ্ছা মাত্র, সেটিং নয় - Oracle আগেভাগেই expired undo কেড়ে নেবে আর 1555 চলতেই থাকবে।
UNDO_MANAGEMENT=AUTO থাকলে (গত দুই দশকের ডিফল্ট) জায়গা পেলে Oracle নিজেই retention উপরের দিকে অটো-টিউন করে - TUNED_UNDORETENTION কলামটি দেখায় সে আসলে কতটা অর্জন করেছে। আপনার কাজ মূলত তাকে কাজ করার মতো যথেষ্ট ডিস্ক দেওয়া।
৬. RETENTION GUARANTEE: শক্তিশালী বিকল্প, তবে দাঁতওয়ালা
ডিফল্টভাবে retention একটি লক্ষ্য, প্রতিশ্রুতি নয়: জায়গার চাপে Oracle লেখকদের এগোতে দিতে মেয়াদ-না-ফুরানো undo বিসর্জন দেবে। আপনার ব্যবসা যদি সত্যিই ORA-01555 সহ্য করতে না পারে - যেমন একটি নিয়ন্ত্রিত end-of-day রিপোর্ট - তাহলে retention-কে কঠোর গ্যারান্টি বানাতে পারেন:
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
-- confirm
SELECT tablespace_name, retention FROM dba_tablespaces
WHERE tablespace_name LIKE 'UNDO%';
যে সওদা করলেন তা বুঝে নিন: এখন undo-র জায়গা ফুরালে Oracle পাঠকদের দেওয়া retention-প্রতিশ্রুতি ভাঙার বদলে লেখকদের ব্যর্থ করবে (ORA-30036)। ঠিকমতো সাইজ-না-করা tablespace-এর ওপর গ্যারান্টি রিপোর্টের ত্রুটিকে ট্রানজ্যাকশনের ত্রুটিতে বদলে দেয় - যা সরাসরি আরও খারাপ। গ্যারান্টি দিন কেবল সাইজিংয়ের পাটিগণিত মেনে চলার পরে, আর undo-র খালি জায়গাকে প্রথম শ্রেণির অ্যালার্ট হিসেবে মনিটর করুন।
৭. কোয়েরির দিক থেকে সমাধান
কখনও কখনও সবচেয়ে সস্তা সমাধান আরও undo নয়, বরং এক্সপোজারের সময়টাই কমিয়ে আনা।
- পাঠককে দ্রুত করুন। ৯০ মিনিট থেকে ১২ মিনিটে টিউন করা রিপোর্টের দরকার সাত গুণ কম retention। প্রায়ই দেখা যায় 1555 আসলে ছদ্মবেশে একটি টিউনিং সমস্যা - পারফরম্যান্স টিউনিং গাইডের পদ্ধতি এখানে সরাসরি প্রযোজ্য।
- লেখকদের এড়িয়ে সময়সূচি করুন। লম্বা রিপোর্টটিকে ভারী ব্যাচ উইন্ডোর বাইরে সরান, বা ব্যাচটিকে রিপোর্টিং উইন্ডোর বাইরে। আমার সারানো 1555-গুলোর অর্ধেকই ছিল ক্যালেন্ডার-সমাধান।
- লুপের ভেতরে কমিট করা বন্ধ করুন। পুরনো "fetch across commit" প্যাটার্ন - একটি কার্সর লুপ যা ফেচ চলা অবস্থাতেই প্রতি N row-তে কমিট করে - কার্যত নিজের undo-র বিরুদ্ধেই ORA-01555 উৎপাদন করে। শেষে গিয়ে কমিট করার মতো করে পুনর্গঠন করুন, বা স্বাধীন খণ্ডে খণ্ডে প্রসেস করুন।
- বিশাল এক্সট্র্যাক্টের জন্য ৩-ঘণ্টার খোলা কার্সরের বদলে flashback-consistent পদ্ধতি বা আগেভাগে consistent snapshot নেওয়া Data Pump বিবেচনা করুন - দেখুন Data Pump গাইড।
৮. আর Redo? বাকি অর্ধেক দুই মিনিটে
যেহেতু দুটোরই সংজ্ঞা দিলাম: আপনার redo স্বাস্থ্য-চেকলিস্ট ছোট কিন্তু আপসহীন। Redo log এমনভাবে সাইজ করতে হবে যাতে পিক সময়ে গ্রুপগুলো মোটামুটি প্রতি ১৫-৩০ মিনিটে সুইচ করে (অনবরত সুইচিং মানে ছোট log আর checkpoint-এর চাপ - দেখুন V$LOG_HISTORY)। প্রোডাকশন কখনও ARCHIVELOG mode ছাড়া চালাবেন না, কারণ archived redo-ই point-in-time recovery রিপ্লে করে - যা RMAN গাইডের সবকিছুর ভিত্তি। আর কমিটের সময় log file sync wait সাধারণত মানে ধীর redo স্টোরেজ, নয়তো এমন অ্যাপ্লিকেশন যা মাত্রাতিরিক্ত ঘন ঘন কমিট করছে।
অন্যদিকে undo-ই আবার Flashback Query ও Flashback Table-এর চালিকাশক্তি - উদার undo সাইজিং যে শুধু 1555 মারার বাইরেও নিজের দাম উসুল করে, তার আরেকটি কারণ।
৯. একটি বাস্তব কেস: মাস-শেষের সেই রিপোর্ট যা সবসময় ৯০ মিনিটে মারা যেত
একটি ম্যানুফ্যাকচারিং ক্লায়েন্টের মাস-শেষের কস্টিং রিপোর্ট ঘড়ির কাঁটার মতো নিয়ম করে ORA-01555 দিয়ে ব্যর্থ হতো - তবে কেবল সেই রাতগুলোতে, যখন inventory revaluation ব্যাচও চলত। V$UNDOSTAT এক কোয়েরিতেই পুরো গল্পটা বলে দিল: MAXQUERYLEN প্রায় ৫,৮০০ সেকেন্ড, retention সেট করা ৯০০-তে (পুরনো ডিফল্ট), আর SSOLDERRCNT ঠিক revaluation উইন্ডোতেই লাফাচ্ছে - যখন undo জেনারেশন দশ গুণ বেড়ে কয়েক মিনিটেই সব রিসাইকেল করে ফেলত।
সমাধান ছিল তিন ভাঁজের: retention বাড়িয়ে ৭,২০০; undo tablespace ৪ GB থেকে বাড়িয়ে ২০ GB (পাটিগণিত দাবি করেছিল ১৭); আর রিপোর্টটি revaluation-এর পাশাপাশি নয়, বরং তা শেষ হওয়ার পরে শুরু হওয়ার মতো করে পুনঃসূচিত। ত্রুটিটি আর কখনও ফেরেনি, আর বোনাস হিসেবে বড় undo পুল ব্যবহারযোগ্য Flashback Query উইন্ডোও বাড়িয়ে দিল - যা একই ক্লায়েন্ট পরে একটি ভুল UPDATE থেকে রিস্টোর ছাড়াই সেরে উঠতে ব্যবহার করেছিলেন। এক নির্ণয়ে দুই সমস্যার সমাধান।
সাধারণ জিজ্ঞাসা (FAQ)
Oracle-এ undo আর redo-র পার্থক্য কী?
Redo প্রতিটি পরিবর্তন রেকর্ড করে যাতে ক্র্যাশের পর কমিট হওয়া কাজ আবার রিপ্লে করা যায় - এটি ডেটাবেজকে সামনের দিকে রক্ষা করে। Undo প্রতিটি পরিবর্তনের আগের পুরনো মানগুলো রেকর্ড করে যাতে ট্রানজ্যাকশন রোলব্যাক করতে পারে এবং কোয়েরিগুলো ডেটার সামঞ্জস্যপূর্ণ পুরনো সংস্করণ দেখতে পারে - এটি পেছনে ফেরায়। Redo ইতিহাস রিপ্লে করে; undo ইতিহাস রিওয়াইন্ড করে।
ORA-01555 snapshot too old কেন হয়?
দীর্ঘ সময় ধরে চলা একটি কোয়েরির একটি পরিবর্তিত ব্লকের পুরনো ইমেজ দরকার ছিল, কিন্তু সেই পুরনো ইমেজ ধরে রাখা undo ততক্ষণে ওভাররাইট হয়ে গেছে। সাধারণত এটি ঘটে যখন লম্বা রিপোর্ট ভারী write কার্যক্রমের সঙ্গে একসাথে চলে এবং UNDO_RETENTION বা undo tablespace সেই সমন্বয়ের তুলনায় ছোট। কোনো কিছুই করাপ্ট হয়নি।
ORA-01555 কীভাবে সারাব?
আগে মাপুন: V$UNDOSTAT আপনার দীর্ঘতম কোয়েরি (MAXQUERYLEN) এবং কখন ত্রুটিগুলো ঘটছে (SSOLDERRCNT) দেখায়। তারপর UNDO_RETENTION দীর্ঘতম কোয়েরির চেয়ে বেশি (কিছু বাড়তি জায়গাসহ) সেট করুন, তা রক্ষা করার মতো করে undo tablespace সাইজ করুন (undo rate x retention x block size), এবং সম্ভব হলে কোয়েরিটি ছোট করুন বা ভারী write উইন্ডো থেকে সরিয়ে নিন।
UNDO_RETENTION আসলে কী করে?
এটি সেকেন্ডে প্রকাশিত সেই লক্ষ্য-সময়, যতক্ষণ Oracle কমিট হওয়া undo-কে consistent read ও Flashback-এর জন্য ধরে রাখার চেষ্টা করে। ডিফল্টভাবে এটি একটি লক্ষ্য, প্রতিশ্রুতি নয় - জায়গার চাপে Oracle মেয়াদ-না-ফুরানো undo-ও রিসাইকেল করে। Undo tablespace-এ RETENTION GUARANTEE দিলে এটি কঠোর প্রতিশ্রুতিতে পরিণত হয়, তবে বিনিময়ে জায়গা ফুরালে writer-রা ব্যর্থ হতে পারে।
RETENTION GUARANTEE চালু করা কি উচিত?
কেবল undo tablespace ঠিকমতো সাইজ করার পরেই। Guarantee মানে Oracle retention ভাঙার বদলে নতুন ট্রানজ্যাকশন ব্যর্থ করবে (ORA-30036), তাই ছোট tablespace-এ এটি রিপোর্টের ত্রুটিকে ট্রানজ্যাকশনের ব্যর্থতায় রূপান্তরিত করে। এমন গুরুত্বপূর্ণ দীর্ঘ প্রসেস থাকলে ব্যবহার করুন যা সত্যিই ORA-01555 সহ্য করতে পারে না, এবং undo-র খালি জায়গা নিবিড়ভাবে মনিটর করুন।
📊 ORA-01555 বা ধীর ব্যাচ উইন্ডোর সঙ্গে লড়ছেন?
আমি undo/redo সমস্যা নির্ণয় করি ডেটা দিয়ে, অনুমান দিয়ে নয় - retention সাইজিং, ব্যাচ সময়সূচি ও কোয়েরি টিউনিং, যাতে snapshot-too-old চিরতরে বিদায় নেয়। বাংলাদেশ ও বিশ্বজুড়ে ক্লায়েন্ট।
তথ্যসূত্র ও আরও পড়ুন
- 📄 Oracle Database Administrator's Guide (19c) - Managing Undo
- 📄 Oracle Database Concepts - Data Concurrency and Consistency
এই লেখার পদ্ধতি ও কেস স্টাডিগুলো ম্যানুফ্যাকচারিং, ব্যাংকিং ও ফার্মাসিউটিক্যাল পরিবেশে ১৮+ বছরের Oracle প্রোডাকশন ডেটাবেজ অ্যাডমিনিস্ট্রেশনের অভিজ্ঞতার ভিত্তিতে লেখা।
