
مقدمه: اوراکل بدون Undo چه شکلی است؟
تصور کنید در یک اتاق شلوغ هستید و دارید روی یک تابلوی بزرگ تغییراتی میدهید. اگر ناگهان تصمیم بگیرید اشتباهتان را اصلاح کنید، باید راهی برای برگرداندن تابلو به حالت قبل داشته باشید.
در دنیای پایگاه داده، این “تابلوی بزرگ” دادههای شماست و “Undo Tablespace” مثل یک دوربین عکاس سریع عمل میکند که قبل از هر تغییری، از وضعیت قبلی عکس میگیرد!
بدون این مکانیزم، اگر شما یک دستور UPDATE را اجرا میکردید و بعد متوجه خطا میشدید، نه راهی برای پس گرفتن دادهها بود و نه خوانندگان میتوانستند همزمان با ویرایشگر شما، اطلاعات قدیمی را ببینند.
در این مقاله آموزش Oracle در بخش آموزش معماری اوراکل ، بدون پیچیدگیهای خستهکننده، قرار است با هم لایهی پنهان اما حیاتی اوراکل را کشف کنیم.
در دنیای پایگاههای داده سازمانی، فقط اینکه بدانیم «چه کسی به دیتابیس وصل شده» کافی نیست.
سؤالهای مهمتر اینها هستند:
- چه کسی اطلاعات حقوق کارکنان را مشاهده کرده؟
- آیا دادهای حساس بدون مجوز دیده شده؟
- چه Queryهایی روی ستونهای حیاتی اجرا شدهاند؟
Oracle برای پاسخ به این نیاز حیاتی، قابلیتی قدرتمند به نام Fine-Grained Auditing (FGA) ارائه کرده که از طریق پکیج DBMS_FGA پیادهسازی میشود.
پیشنهاد می کنم این مقاله زیر رو حتما مطالعه کنی.
در این مقاله شما می خوانید
بخش اول: Undo Tablespace چیست؟
Undo Tablespace یک فضای اختصاصی در دیتابیس اوراکل است که قبل از اینکه هر تغییری در دادههای شما (مثل INSERT, UPDATE, DELETE) اعمال شود، نسخه قدیمی آن داده در آنجا ذخیره میشود.
به زبان ساده:
- شما عدد
۱۰۰را به۸۰تغییر میدهید. - اوراکل قبل از تغییر، عدد
۱۰۰را در Undo Tablespace نگه میدارد. - حالا اگر بگویید “پشیمان شدم” (Rollback) یا دیتابیس خراب شود، اوراکل به این فضا نگاه میکند،
۱۰۰را برمیگرداند و همه چیز به حالت اول برمیگردد.
💡 نکته انسانی: فکر کنید Undo Tablespace مثل دکمه “بازگشت” (Undo) در فتوشاپ است، اما این دکمه همیشه و برای هر تغییری به صورت خودکار و در سطح سرور فعال است.
بخش دوم: چطور Undo باعث Rollback میشود؟ (مکانیزم بازگشت)
بیایید یک سناریوی واقعی را تصور کنیم.
سناریو: خطای انسانی در حین ویرایش
فرض کنید کاربری دستور زیر را اجرا میکند تا موجودی یک حساب را کم کند:
UPDATE accounts SET balance = balance - 50 WHERE account_id = 1001;
لحظهی دقیق تغییر:
- اوراکل به بلوک دادهای میرود که رکورد
۱۰۰۱آنجا است. - مقدار قدیمی (
Balance = 100) را استخراج میکند. - این مقدار قدیمی را در Undo Tablespace ذخیره میکند.
- مقدار جدید (
Balance = 50) را در بلوک اصلی (Buffer Cache) اعمال میکند. - تراکنش هنوز Commit نشده است.
اگر کاربر بگوید ROLLBACK یا خطایی رخ دهد:
- اوراکل به Undo Tablespace میرود.
- مقدار
۱۰۰را از آنجا میخواند. - بلوک اصلی را دوباره بازنویسی میکند تا عدد
۱۰۰برگردد. - نتیجه: انگار هیچ تغییری صورت نگرفته بود!
این قدرت Rollback است. بدون Undo Tablespace، دادههای تغییر یافته در صورت خطا، دیگر قابل بازگشت نبودند و دیتابیس شما ناپایدار میشد.
بخش سوم: چطور Undo باعث Consistency (سازگاری خواندن) میشود؟
اینجاست که جادوی واقعی اوراکل رخ میدهد. به این پدیده MVCC (Multi-Version Concurrency Control) میگوییم.
سوالی که هر توسعهدهندهای پرسیده است:
“وقتی من دیتای یک جدول را تغییر میدهم (اما هنوز Commit نکردهام)، چرا کاربر دیگری نمیتواند آن تغییر را ببیند؟ و چرا دیتای قبلی را میبیند؟”
پاسخ:
وقتی شما یک تغییر انجام میدهید و آن را Commit نمیکنید، آن تغییر فقط برای شما قابل مشاهده است. برای بقیه، آن تغییر هنوز اتفاق نیفتاده است.
مثال واقعی:
- دیتای فعلی: حقوق کارمند (ID: 50) =
۵,۰۰۰,۰۰۰. - شما: دستور
UPDATEرا میزنید:SET salary = 5,500,000.
- اوراکل عدد
۵,۰۰۰,۰۰۰را در Undo ذخیره میکند. - عدد
۵,۵۰۰,۰۰۰در حافظه موقت شماست (اما Commit نشده).
- همکارتان (کاربر B): همزمان دستور
SELECTرا اجرا میکند.
- کاربر B به دیتابیس نگاه میکند.
- اوراکل به شما نگاه میکند. چون شما هنوز Commit نکردهاید، اوراکل به Undo Tablespace میرود.
- نسخهی قدیمی (
۵,۰۰۰,۰۰۰) را از Undo برمیگرداند و به کاربر B نشان میدهد.
- نتیجه: کاربر B عدد قدیمی را میبیند و دیتابیس همیشه سازگار (Consistent) باقی میماند. هیچکس نسخهی ناقص و در حال ویرایش شما را نمیبیند.
اگر بعداً شما دستور COMMIT را بزنید، آن زمان تغییر برای همه اعمال میشود و نسخه قدیمی در Undo دیگر نیاز نیست.
بخش چهارم: خطاهای رایج و مدیریت Undo
با وجود این همه مزیت، اگر مدیریت نشود، میتواند دردسرساز شود.
۱. خطای ORA-01555 (Snapshot Too Old)
این یکی از ترسناکترین خطاها برای دیتابیسهای بزرگ است.
چرا رخ میدهد؟
اگر یک کوئری (Query) خیلی طولانی اجرا شود و در حین آن، Undo Tablespace پر شود، اوراکل مجبور میشود Undoهای قدیمی را پاک کند تا فضا باز کند. اگر کوئری شما به Undo قدیمی برای پیدا کردن نسخه سازگار نیاز داشت و آن نسخه پاک شده باشد، خطای ORA-01555 میگیرید.
راه حل:
تنظیم پارامتر UNDO_RETENTION. این پارامتر به دیتابیس میگوید که حداقل چند ثانیه Undoها را نگه دارد تا کوئریهای طولانی بتوانند کار کنند.
۲. پر شدن Undo Tablespace (ORA-30036)
اگر فضا کافی نباشد و UNDO_RETENTION یا سایز فضا تنظیم نشده باشد، دیتابیس تراکنشهای جدید را مسدود میکند تا فضا آزاد شود.
نتیجهگیری: چرا Undo Tablespace حیاتی است؟
Undo Tablespace قلب تپندهی اطمینان در دیتابیس اوراکل است.
این فضا نه تنها به شما اطمینان میدهد که اگر اشتباه کردید، میتوانید عقب برگردید، بلکه تضمین میکند که هزاران کاربر میتوانند همزمان با دقت و بدون تداخل، از دادههای شما استفاده کنند.
بدون آن، اوراکل دیگر آن دیتابیس قدرتمند، سریع و قابل اعتمادی که امروز میشناسید، نبود.
مدیریت صحیح آن (سایز مناسب و Retention) کلید موفقیت هر پروژهی بزرگی است.
سوالات متداول درباره Undo Tablespace در اوراکل
این خطا زمانی رخ میدهد که یک کوئری طولانی اجرا میشود و در حین کار، دیتابیس برای آزاد کردن فضا، نسخههای قدیمی (Undo) مورد نیاز آن کوئری را پاک کرده است.
اوراکل نمیتواند نسخهای را که پاک شده، بازیابی کند.
این دو مکمل یکدیگرند اما وظایف متضادی دارند:
- Redo Log: برای پایداری (Durability) است. هر تغییری که میکنید (حتی اگر Commit نکنید) در Redo ثبت میشود تا بعد از ریستارت سرور، دادهها از دست نروند. (مسیر به جلو: Undo to Redo)
- Undo Tablespace: برای بازگشت (Rollback) و سازگاری است. نسخه قدیمی داده را نگه میدارد تا بتوانید عقب برگردید یا کاربران قدیمی را ببینند.
برای جلوگیری از پر شدن Undo و خطای ORA-30036، باید این فرمول را رعایت کنید:
Size=UNDO_RETENTION×Avg_Transactions_Per_Second×Avg_Bytes_Per_Transaction
مثال عملی:
- اگر میخواهید Undo ۱ ساعت نگهداری شود (۳۶۰۰ ثانیه).
- و میانگین ۱۰ تراکنش در ثانیه با حجم متوسط ۱۰ کیلوبایت دارید.
- سایز مورد نیاز = ۳۶۰۰ × ۱۰ × ۱۰KB = 360,000KB ≈ ۳۵۰MB.
- نکته مهم: همیشه ۲۰-۳۰٪ فضا را برای نوسانات لحظهای در نظر بگیرید.
خیر، برعکس! استفاده صحیح از Undo باعث افزایش سرعت و کارایی میشود.
به جای اینکه کاربران برای خواندن داده منتظر بمانند تا ویرایشگر کارش را تمام کند (که باعث قفل شدن یا Blocking میشود)، اوراکل با استفاده از MVCC، نسخه قدیمی داده را بدون نیاز به قفل، از Undo برمیگرداند.
- تنها حالت کندی: اگر Undo Tablespace سایز کافی نداشته باشد و مجبور به پاک کردن دادههای قدیمی شود، کوئریهای طولانی با خطا قطع میشوند (که آن هم با تنظیم صحیح رفع میشود).
جمعبندی
در دیتابیسهای مدرن، Auto Manage Undo فعال است، اما برای دیتابیسهای با بار بالا (High Load)، دستی کردن سایز و تنظیم UNDO_RETENTION بر اساس الگوی کارکردی کویریها، یک ضرورت مهندسی است.
امیدوارم این مقاله به شما کمک کرده باشد تا عمق این مفهوم را درک کنید. اگر سوالی در مورد تنظیمات خاص یا دیباگ کردن خطاهای Undo دارید، حتماً بپرسید!
سؤالی درباره این مقاله داری؟
اگر نکتهای در این مقاله برات مبهم بود یا خواستی بیشتر بدونی، همین حالا برام بنویس تا دقیق و صمیمی پاسخت رو بدم — مثل یه گفتوگوی واقعی 💬
برو به صفحه پرسش و پاسخ
دیدگاهتان را بنویسید