From 5c9c0e58c44b861e6c372357241db09883e31b09 Mon Sep 17 00:00:00 2001 From: dimitr Date: Thu, 8 Feb 2007 14:32:07 +0000 Subject: [PATCH] Fixed possibly trashed memory plus small cleanup. --- src/jrd/nbak.cpp | 50 +++++++++++++++++++++++------------------------- src/jrd/nbak.h | 1 - 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/jrd/nbak.cpp b/src/jrd/nbak.cpp index 237dd953ea..aa9b845707 100644 --- a/src/jrd/nbak.cpp +++ b/src/jrd/nbak.cpp @@ -399,7 +399,7 @@ int BackupManager::backup_state_ast(void *ast_object) throw() tdbb->tdbb_transaction = NULL; NBAK_TRACE_AST("NBAK, backup_state_ast"); - + if (new_dbb->dbb_backup_manager->flags & NBAK_state_in_use) new_dbb->dbb_backup_manager->ast_flags |= NBAK_state_blocking; else { @@ -503,7 +503,7 @@ int BackupManager::backup_database_ast(void *ast_object) throw() tdbb->tdbb_status_vector = ast_status; NBAK_TRACE_AST("NBAK, backup_database_ast"); - + if (new_dbb->dbb_backup_manager->database_use_count) { new_dbb->dbb_backup_manager->ast_flags |= NBAK_database_blocking; ast_status[1] = 0; @@ -618,7 +618,7 @@ void BackupManager::begin_backup(thread_db* tdbb) header_locked = false; CCH_RELEASE(tdbb, &window); tdbb->tdbb_flags &= ~TDBB_set_backup_state; - + backup_state = newState; current_scn = adjusted_scn; // This is essential for SuperServer to prevent multi-threading issues @@ -723,10 +723,9 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover) CCH_RELEASE(tdbb, &window); throw; } - - + // Here comes the dirty work. We need to reapply all changes from difference file to database - + // Release write state lock and get read lock. // Merge process should not inhibit normal operations. tdbb->tdbb_flags &= ~TDBB_set_backup_state; @@ -746,9 +745,9 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover) ERR_punt(); NBAK_TRACE(("Allocation table %p is current.", alloc_table)); AllocItemTree::Accessor all(alloc_table); - + tdbb->tdbb_flags |= TDBB_set_backup_state | TDBB_backup_merge; - + if (all.getFirst()) { do { WIN window2(DB_PAGE_SPACE, all.current().db_page); //vlad ?? @@ -763,14 +762,14 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover) tdbb->tdbb_flags &= ~(TDBB_set_backup_state | TDBB_backup_merge); unlock_state(tdbb); - + } catch (const Firebird::Exception&) { tdbb->tdbb_flags &= ~(TDBB_set_backup_state | TDBB_backup_merge); unlock_state(tdbb); throw; } - + // We finished. We need to reflect it in our database header page window.win_page = HEADER_PAGE_NUMBER; window.win_flags = 0; @@ -800,12 +799,12 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover) header_locked = false; CCH_RELEASE(tdbb, &window); tdbb->tdbb_flags &= ~TDBB_set_backup_state; - + // Page allocation table cache is no longer valid delete alloc_table; alloc_table = NULL; last_allocated_page = 0; - + if (diff_file) { #ifndef SUPERSERVER diff_generation++; @@ -814,7 +813,7 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover) diff_file = NULL; } unlink(diff_name.c_str()); - + unlock_state_write(tdbb); NBAK_TRACE(("backup ended")); } @@ -829,7 +828,7 @@ void BackupManager::end_backup(thread_db* tdbb, bool recover) } return; } - + bool BackupManager::actualize_alloc(thread_db* tdbb) throw() { if (alloc_table @@ -850,12 +849,12 @@ bool BackupManager::actualize_alloc(thread_db* tdbb) throw() // Difference file pointer pages have one ULONG as number of pages allocated on the page and // then go physical numbers of pages from main database file. Offsets of numbers correspond // to difference file pages. - + // Get offset of pointer page. We can do so because page sizes are powers of 2 temp_bdb.bdb_page = last_allocated_page & ~(database->dbb_page_size / sizeof(ULONG) - 1); temp_bdb.bdb_dbb = database; temp_bdb.bdb_buffer = reinterpret_cast(alloc_buffer); - + if (!PIO_read(diff_file, &temp_bdb, temp_bdb.bdb_buffer, status_vector)) return false; for (ULONG i = last_allocated_page - temp_bdb.bdb_page.getPageNum(); @@ -924,7 +923,7 @@ ULONG BackupManager::allocate_difference_page(thread_db* tdbb, ULONG db_page) th temp_bdb.bdb_buffer = reinterpret_cast(empty_buffer); if (!PIO_write(diff_file, &temp_bdb, (Ods::pag*)empty_buffer, status_vector)) return 0; - + const bool alloc_page_full = alloc_buffer[0] == database->dbb_page_size / sizeof(ULONG) - 2; if (alloc_page_full) { // Pointer page is full. Its time to create new one. @@ -961,7 +960,7 @@ ULONG BackupManager::allocate_difference_page(thread_db* tdbb, ULONG db_page) th memset(alloc_buffer, 0, database->dbb_page_size); return last_allocated_page - 1; } - + return last_allocated_page; } @@ -975,7 +974,7 @@ bool BackupManager::write_difference(ISC_STATUS* status, ULONG diff_page, Ods::p return false; return true; } - + bool BackupManager::read_difference(thread_db* tdbb, ULONG diff_page, Ods::pag* page) throw() { BufferDesc temp_bdb; @@ -986,7 +985,7 @@ bool BackupManager::read_difference(thread_db* tdbb, ULONG diff_page, Ods::pag* return false; return true; } - + BackupManager::BackupManager(thread_db* tdbb, Database* _database, int ini_state) : database(_database), diff_file(NULL), alloc_table(NULL), backup_state(ini_state), last_allocated_page(0), @@ -998,12 +997,11 @@ BackupManager::BackupManager(thread_db* tdbb, Database* _database, int ini_state BYTE *temp_buffers = reinterpret_cast( FB_ALIGN(reinterpret_cast(temp_buffers_space), MIN_PAGE_SIZE)); memset(temp_buffers, 0, database->dbb_page_size * 3); - + empty_buffer = reinterpret_cast(temp_buffers); spare_buffer = reinterpret_cast(temp_buffers + database->dbb_page_size); - alloc_buffer = reinterpret_cast(temp_buffers + database->dbb_page_size + 2); + alloc_buffer = reinterpret_cast(temp_buffers + database->dbb_page_size * 2); - #ifdef SUPERSERVER alloc_lock = FB_NEW(*_database->dbb_permanent) Firebird::RWLock(); state_lock = FB_NEW(*_database->dbb_permanent) Firebird::RWLock(); @@ -1015,7 +1013,7 @@ BackupManager::BackupManager(thread_db* tdbb, Database* _database, int ini_state database_use_count = 0; diff_use_count = 0; diff_generation = 0; - + state_lock = FB_NEW_RPT(*database->dbb_permanent, 0) Lock(); state_lock->lck_type = LCK_backup_state; state_lock->lck_owner_handle = LCK_get_owner_handle(tdbb, state_lock->lck_type); @@ -1096,9 +1094,9 @@ bool BackupManager::actualize_state(thread_db* tdbb) throw() // State is unknown. We need to read it from the disk. // We cannot use CCH for this because of likely recursion. NBAK_TRACE(("actualize_state")); - + ISC_STATUS *status = tdbb->tdbb_status_vector; - + // Read original page from database file or shadows. SSHORT retryCount = 0; Ods::header_page* header = reinterpret_cast(spare_buffer); diff --git a/src/jrd/nbak.h b/src/jrd/nbak.h index 4e303b5591..e551462a76 100644 --- a/src/jrd/nbak.h +++ b/src/jrd/nbak.h @@ -63,7 +63,6 @@ class AllocItem { public: ULONG db_page; // Page number in the main database file ULONG diff_page; // Page number in the difference file - Record* rec_data; static const ULONG& generate(const void *sender, const AllocItem& item) { return item.db_page; }