Skip to content

Commit c5a5b37

Browse files
authored
Merge pull request #154398 from jeffswenson/backport25.2-154397
release-25.2: backup: restore must skip temporary tables
2 parents 03dcb4b + 936e143 commit c5a5b37

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

pkg/backup/restore_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package backup
77

88
import (
99
"context"
10+
gosql "database/sql"
1011
"testing"
1112
"time"
1213

@@ -85,3 +86,49 @@ func TestFailAfterCleanupSystemTables(t *testing.T) {
8586
sqlDB.Exec(t, "CANCEL JOB $1", jobID)
8687
jobutils.WaitForJobToCancel(t, sqlDB, jobID)
8788
}
89+
90+
func TestRestoreDuplicateTempTables(t *testing.T) {
91+
defer leaktest.AfterTest(t)()
92+
defer log.Scope(t).Close(t)
93+
94+
// This is a regression test for #153722. It verifies that restoring a backup
95+
// that contains two temporary tables with the same name does not cause the
96+
// restore to fail with an error of the form: "restoring 17 TableDescriptors
97+
// from 4 databases: restoring table desc and namespace entries: table
98+
// already exists"
99+
100+
clusterSize := 1
101+
tc, sqlDB, _, cleanupFn := backuptestutils.StartBackupRestoreTestCluster(t, clusterSize)
102+
defer cleanupFn()
103+
104+
sqlDB.Exec(t, `SET experimental_enable_temp_tables=true`)
105+
sqlDB.Exec(t, `CREATE DATABASE test_db`)
106+
sqlDB.Exec(t, `USE test_db`)
107+
sqlDB.Exec(t, `CREATE TABLE permanent_table (id INT PRIMARY KEY, name TEXT)`)
108+
109+
sessions := make([]*gosql.DB, 2)
110+
for i := range sessions {
111+
sessions[i] = tc.Servers[0].SQLConn(t)
112+
sql := sqlutils.MakeSQLRunner(sessions[i])
113+
sql.Exec(t, `SET experimental_enable_temp_tables=true`)
114+
sql.Exec(t, `USE test_db`)
115+
sql.Exec(t, `CREATE TEMP TABLE duplicate_temp (id INT PRIMARY KEY, value TEXT)`)
116+
sql.Exec(t, `INSERT INTO duplicate_temp VALUES (1, 'value')`)
117+
}
118+
119+
sqlDB.Exec(t, `BACKUP INTO 'nodelocal://1/duplicate_temp_backup'`)
120+
121+
for _, session := range sessions {
122+
require.NoError(t, session.Close())
123+
}
124+
125+
// The cluster must be empty for a full cluster restore.
126+
sqlDB.Exec(t, `DROP DATABASE test_db CASCADE`)
127+
sqlDB.Exec(t, `RESTORE FROM LATEST IN 'nodelocal://1/duplicate_temp_backup'`)
128+
129+
sqlDB.Exec(t, `DROP DATABASE test_db CASCADE`)
130+
sqlDB.Exec(t, `RESTORE DATABASE test_db FROM LATEST IN 'nodelocal://1/duplicate_temp_backup'`)
131+
132+
result := sqlDB.QueryStr(t, `SELECT table_name FROM [SHOW TABLES] ORDER BY table_name`)
133+
require.Equal(t, [][]string{{"permanent_table"}}, result)
134+
}

pkg/backup/targets.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,10 @@ func fullClusterTargetsRestore(
305305
var filteredDescs []catalog.Descriptor
306306
var filteredDBs []catalog.DatabaseDescriptor
307307
for _, desc := range fullClusterDescs {
308+
if table, ok := desc.(catalog.TableDescriptor); ok && table.IsTemporary() {
309+
// TODO(jeffswenson): We should move this filtering into backup.
310+
continue
311+
}
308312
if desc.GetID() != keys.SystemDatabaseID {
309313
filteredDescs = append(filteredDescs, desc)
310314
}
@@ -381,7 +385,6 @@ func selectTargets(
381385
}
382386

383387
if descriptorCoverage == tree.AllDescriptors {
384-
385388
tables, dbs, patterns, err := fullClusterTargetsRestore(ctx, allDescs, lastBackupManifest)
386389
return tables, dbs, patterns, nil, err
387390
}

0 commit comments

Comments
 (0)