0
0
DbmsConceptBeginner · 4 min read

Shadow Paging in DBMS: How It Works and When to Use

In shadow paging, the database keeps two copies of data pages: the current page and a shadow page. Updates are made to the current page while the shadow page remains unchanged, ensuring that if a failure occurs, the system can revert to the shadow page to maintain data integrity.
⚙️

How It Works

Shadow paging works by maintaining two versions of each data page: the original (shadow) page and the updated (current) page. When a transaction starts, the system keeps the shadow pages unchanged as a safe backup. Any changes are made only to the current pages.

Think of it like writing on a copy of a document instead of the original. If you finish and everything is correct, you replace the original with the updated copy. But if something goes wrong, you just keep the original safe and discard the copy. This way, the database can always recover to a consistent state without complex undo operations.

💻

Example

This simple example simulates shadow paging by copying data before updating and committing changes only after successful updates.
python
class ShadowPagingDB:
    def __init__(self):
        self.shadow_pages = {'page1': 'data1', 'page2': 'data2'}
        self.current_pages = self.shadow_pages.copy()

    def update_page(self, page, new_data):
        print(f"Updating {page}...")
        self.current_pages[page] = new_data

    def commit(self):
        print("Committing changes...")
        self.shadow_pages = self.current_pages.copy()

    def rollback(self):
        print("Rollback: Reverting to shadow pages...")
        self.current_pages = self.shadow_pages.copy()

    def show_pages(self):
        print("Current Pages:", self.current_pages)
        print("Shadow Pages:", self.shadow_pages)

# Usage
 db = ShadowPagingDB()
 db.show_pages()
 db.update_page('page1', 'new_data1')
 db.show_pages()
 db.rollback()  # Simulate failure
 db.show_pages()
 db.update_page('page2', 'new_data2')
 db.commit()  # Successful commit
 db.show_pages()
Output
Current Pages: {'page1': 'data1', 'page2': 'data2'} Shadow Pages: {'page1': 'data1', 'page2': 'data2'} Updating page1... Current Pages: {'page1': 'new_data1', 'page2': 'data2'} Shadow Pages: {'page1': 'data1', 'page2': 'data2'} Rollback: Reverting to shadow pages... Current Pages: {'page1': 'data1', 'page2': 'data2'} Shadow Pages: {'page1': 'data1', 'page2': 'data2'} Updating page2... Committing changes... Current Pages: {'page1': 'data1', 'page2': 'new_data2'} Shadow Pages: {'page1': 'data1', 'page2': 'new_data2'}
🎯

When to Use

Shadow paging is useful when you want a simple and reliable way to ensure database consistency without complex logging or undo operations. It is often used in systems where transactions are short and the overhead of maintaining shadow pages is acceptable.

Real-world use cases include embedded databases, systems with limited resources, or applications where quick recovery from crashes is critical. However, it may not be ideal for very large databases or highly concurrent systems due to the cost of copying pages.

Key Points

  • Shadow paging keeps a backup copy of data pages to ensure safe recovery.
  • Updates are made on current pages, leaving shadow pages unchanged until commit.
  • On failure, the system reverts to shadow pages to maintain consistency.
  • It avoids complex undo logging but may have overhead due to copying pages.

Key Takeaways

Shadow paging maintains two copies of data pages to ensure safe recovery after failures.
Updates happen on current pages while shadow pages remain unchanged until commit.
Rollback simply restores shadow pages, avoiding complex undo operations.
Best suited for systems with short transactions and limited concurrency.
May not scale well for very large or highly concurrent databases.