Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 748a8e3

Browse files
dvdplmAndronik Ordian
andauthored
Don't delete old db after migration (#11662)
* Don't delete old db after migration Fixes unwanted shuffling&deletion of the old database after a migration that merely deletes data in one of the existing database columns. * Update util/migration-rocksdb/src/lib.rs Co-Authored-By: Andronik Ordian <[email protected]> Co-authored-by: Andronik Ordian <[email protected]>
1 parent cb9800f commit 748a8e3

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

parity/db/rocksdb/migration.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ fn migrate_database(version: u32, db_path: &Path, mut migrations: MigrationManag
186186

187187
// completely in-place migration leads to the paths being equal.
188188
// in that case, no need to shuffle directories.
189-
if temp_path == db_path { return Ok(()) }
189+
if temp_path == db_path {
190+
trace!(target: "migrate", "In-place migration ran; leaving old database in place.");
191+
return Ok(())
192+
}
190193

191194
// create backup
192195
fs::rename(&db_path, &backup_path)?;

util/migration-rocksdb/src/lib.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::path::{Path, PathBuf};
2121
use std::sync::Arc;
2222
use std::{fs, io, error};
2323

24-
use log::{info, trace};
24+
use log::{info, trace, warn};
2525
use kvdb::DBTransaction;
2626
use kvdb_rocksdb::{CompactionProfile, Database, DatabaseConfig};
2727

@@ -97,10 +97,12 @@ pub trait Migration {
9797
/// Whether this migration alters any existing columns.
9898
/// if not, then column families will simply be added and `migrate` will never be called.
9999
fn alters_existing(&self) -> bool { true }
100+
/// Whether this migration deletes data in any of the existing columns.
101+
fn deletes_existing(&self) -> bool { false }
100102
/// Version of the database after the migration.
101103
fn version(&self) -> u32;
102104
/// Migrate a source to a destination.
103-
fn migrate(&mut self, source: Arc<Database>, config: &Config, destination: &mut Database, col: u32) -> io::Result<()>;
105+
fn migrate(&mut self, source: Arc<Database>, config: &Config, destination: Option<&mut Database>, col: u32) -> io::Result<()>;
104106
}
105107

106108
/// A simple migration over key-value pairs of a single column.
@@ -123,8 +125,15 @@ impl<T: SimpleMigration> Migration for T {
123125

124126
fn version(&self) -> u32 { SimpleMigration::version(self) }
125127

126-
fn migrate(&mut self, source: Arc<Database>, config: &Config, dest: &mut Database, col: u32) -> io::Result<()> {
128+
fn migrate(&mut self, source: Arc<Database>, config: &Config, dest: Option<&mut Database>, col: u32) -> io::Result<()> {
127129
let migration_needed = col == SimpleMigration::migrated_column_index(self);
130+
let dest = match dest {
131+
None => {
132+
warn!(target: "migration", "No destination db provided. No changes made.");
133+
return Ok(());
134+
}
135+
Some(dest) => dest,
136+
};
128137
let mut batch = Batch::new(config, col);
129138

130139
for (key, value) in source.iter(col) {
@@ -156,7 +165,7 @@ impl Migration for ChangeColumns {
156165
fn columns(&self) -> u32 { self.post_columns }
157166
fn alters_existing(&self) -> bool { false }
158167
fn version(&self) -> u32 { self.version }
159-
fn migrate(&mut self, _: Arc<Database>, _: &Config, _: &mut Database, _: u32) -> io::Result<()> {
168+
fn migrate(&mut self, _: Arc<Database>, _: &Config, _: Option<&mut Database>, _: u32) -> io::Result<()> {
160169
Ok(())
161170
}
162171
}
@@ -170,10 +179,11 @@ pub struct VacuumAccountsBloom {
170179
impl Migration for VacuumAccountsBloom {
171180
fn pre_columns(&self) -> u32 { self.columns }
172181
fn columns(&self) -> u32 { self.columns }
173-
fn alters_existing(&self) -> bool { true }
182+
fn alters_existing(&self) -> bool { false }
183+
fn deletes_existing(&self) -> bool { true }
174184
fn version(&self) -> u32 { self.version }
175185

176-
fn migrate(&mut self, db: Arc<Database>, _config: &Config, _dest: &mut Database, col: u32) -> io::Result<()> {
186+
fn migrate(&mut self, db: Arc<Database>, _config: &Config, _dest: Option<&mut Database>, col: u32) -> io::Result<()> {
177187
if col != self.column_to_vacuum {
178188
return Ok(())
179189
}
@@ -300,7 +310,7 @@ impl Manager {
300310
let mut new_db = Database::open(&db_config, temp_path_str)?;
301311

302312
for col in 0..current_columns {
303-
migration.migrate(cur_db.clone(), &config, &mut new_db, col)?
313+
migration.migrate(cur_db.clone(), &config, Some(&mut new_db), col)?
304314
}
305315

306316
// next iteration, we will migrate from this db into the other temp.
@@ -309,6 +319,11 @@ impl Manager {
309319

310320
// remove the other temporary migration database.
311321
let _ = fs::remove_dir_all(temp_idx.path(&db_root));
322+
} else if migration.deletes_existing() {
323+
// Migration deletes data in an existing column.
324+
for col in 0..db_config.columns {
325+
migration.migrate(cur_db.clone(), &config, None, col)?
326+
}
312327
} else {
313328
// migrations which simply add or remove column families.
314329
// we can do this in-place.
@@ -322,6 +337,8 @@ impl Manager {
322337
}
323338
}
324339
}
340+
// If `temp_path` is different from `old_path` we will shuffle database
341+
// directories and delete the old paths.
325342
Ok(temp_path)
326343
}
327344

util/migration-rocksdb/tests/tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ impl Migration for AddsColumn {
9090
fn pre_columns(&self) -> u32 { 1 }
9191
fn columns(&self) -> u32 { 1 }
9292
fn version(&self) -> u32 { 1 }
93-
fn migrate(&mut self, source: Arc<Database>, config: &Config, dest: &mut Database, col: u32) -> io::Result<()> {
93+
fn migrate(&mut self, source: Arc<Database>, config: &Config, dest: Option<&mut Database>, col: u32) -> io::Result<()> {
94+
let dest = dest.expect("migrate is called with a database");
9495
let mut batch = Batch::new(config, col);
9596

9697
for (key, value) in source.iter(col) {

0 commit comments

Comments
 (0)