@@ -11195,3 +11195,94 @@ func TestBackupRestoreFunctionDependenciesRevisionHistory(t *testing.T) {
1119511195
1119611196 checkFunctions ("test6" )
1119711197}
11198+
11199+ func TestBackupRestoreDatabaseRevisionHistory (t * testing.T ) {
11200+ defer leaktest .AfterTest (t )()
11201+ defer log .Scope (t ).Close (t )
11202+
11203+ dataDir , dirCleanupFunc := testutils .TempDir (t )
11204+ defer dirCleanupFunc ()
11205+
11206+ _ , sqlDB , cleanupFn := backupRestoreTestSetupEmpty (t , singleNode , dataDir , InitManualReplication , base.TestClusterArgs {})
11207+ defer cleanupFn ()
11208+
11209+ // Helper function to check if a database exists.
11210+ checkDatabase := func (dbName string , shouldExist bool ) {
11211+ var count int
11212+ sqlDB .QueryRow (t , `SELECT count(*) FROM system.namespace WHERE name = $1 AND "parentID" = 0` , dbName ).Scan (& count )
11213+ if shouldExist {
11214+ if count != 1 {
11215+ t .Fatalf ("expected database %s to exist, but it doesn't" , dbName )
11216+ }
11217+ } else {
11218+ if count != 0 {
11219+ t .Fatalf ("expected database %s to not exist, but it does" , dbName )
11220+ }
11221+ }
11222+ }
11223+
11224+ sqlDB .Exec (t , `CREATE DATABASE test_db` )
11225+
11226+ // T1: Full cluster backup with revision history.
11227+ backupPath := "nodelocal://1/database_revision_backup"
11228+ sqlDB .Exec (t , `BACKUP INTO $1 WITH revision_history` , backupPath )
11229+
11230+ // T2: Capture timestamp after backup (database exists).
11231+ var t2 string
11232+ sqlDB .QueryRow (t , `SELECT cluster_logical_timestamp()` ).Scan (& t2 )
11233+
11234+ sqlDB .Exec (t , `DROP DATABASE test_db` )
11235+
11236+ checkDatabase ("test_db" , false )
11237+
11238+ // T3: Capture timestamp after dropping database.
11239+ var t3 string
11240+ sqlDB .QueryRow (t , `SELECT cluster_logical_timestamp()` ).Scan (& t3 )
11241+
11242+ sqlDB .Exec (t , `CREATE DATABASE ephemeral` )
11243+
11244+ // T4: Capture timestamp the has the ephemeral database.
11245+ var t4 string
11246+ sqlDB .QueryRow (t , `SELECT cluster_logical_timestamp()` ).Scan (& t4 )
11247+
11248+ sqlDB .Exec (t , `DROP DATABASE ephemeral` )
11249+
11250+ // T5: Capture timestamp after dropping ephemeral database.
11251+ var t5 string
11252+ sqlDB .QueryRow (t , `SELECT cluster_logical_timestamp()` ).Scan (& t5 )
11253+
11254+ sqlDB .Exec (t , `BACKUP INTO LATEST IN $1 WITH revision_history` , backupPath )
11255+
11256+ // Choose one of the 4 restores to run, to reduce test runtime:
11257+ i := rand .Intn (4 )
11258+
11259+ switch i {
11260+ case 0 :
11261+ // Restore AOST t2 -> expect database to exist.
11262+ restoreQuery := fmt .Sprintf (
11263+ "RESTORE FROM LATEST IN $1 AS OF SYSTEM TIME %s" , t2 )
11264+ sqlDB .Exec (t , restoreQuery , backupPath )
11265+ checkDatabase ("test_db" , true )
11266+
11267+ sqlDB .Exec (t , `DROP DATABASE test_db` )
11268+ case 1 :
11269+ // Restore AOST t3 -> expect database to not exist.
11270+ restoreQuery := fmt .Sprintf (
11271+ "RESTORE FROM LATEST IN $1 AS OF SYSTEM TIME %s" , t3 )
11272+ sqlDB .Exec (t , restoreQuery , backupPath )
11273+ checkDatabase ("test_db" , false )
11274+ case 2 :
11275+ // Restore AOST t4 -> ephemeral db exists.
11276+ restoreQuery := fmt .Sprintf (
11277+ "RESTORE FROM LATEST IN $1 AS OF SYSTEM TIME %s" , t4 )
11278+ sqlDB .Exec (t , restoreQuery , backupPath )
11279+ checkDatabase ("ephemeral" , true )
11280+
11281+ sqlDB .Exec (t , `DROP DATABASE ephemeral` )
11282+ case 3 :
11283+ restoreQuery := fmt .Sprintf (
11284+ "RESTORE FROM LATEST IN $1 AS OF SYSTEM TIME %s" , t5 )
11285+ sqlDB .Exec (t , restoreQuery , backupPath )
11286+ checkDatabase ("ephemeral" , false )
11287+ }
11288+ }
0 commit comments