From 96179bfc8f7ad764efc7da1c4100c23f1f0ada38 Mon Sep 17 00:00:00 2001 From: richardjcai Date: Mon, 6 Dec 2021 19:02:20 -0500 Subject: [PATCH] sql: insert missing public schema namespace entry When restoring a database, a namespace entry for the public schema was not created. Release note: None --- .../settings/settings-for-tenants.txt | 2 +- docs/generated/settings/settings.html | 2 +- pkg/ccl/backupccl/BUILD.bazel | 1 + ...lic_schema_namespace_entry_restore_test.go | 85 ++++++++++++++++++ .../v21.1.1/716846481902174209.sst | Bin 0 -> 1014 bytes .../v21.1.1/716846481902206977.sst | Bin 0 -> 1140 bytes .../v21.1.1/716846481902239745.sst | Bin 0 -> 1310 bytes .../v21.1.1/716846482369970177.sst | Bin 0 -> 1072 bytes .../v21.1.1/716846482426396673.sst | Bin 0 -> 1144 bytes .../v21.1.1/716846482479906817.sst | Bin 0 -> 991 bytes .../v21.1.1/716846484028981249.sst | Bin 0 -> 953 bytes .../v21.1.1/716846484029112321.sst | Bin 0 -> 953 bytes ...KUP-CHECKPOINT-716846479146844161-CHECKSUM | 1 + .../v21.1.1/BACKUP-CHECKPOINT-CHECKSUM | 1 + .../v21.1.1/BACKUP-STATISTICS | 0 .../v21.1.1/BACKUP_MANIFEST | Bin 0 -> 2504 bytes .../v21.1.1/BACKUP_MANIFEST-CHECKSUM | 1 + pkg/clusterversion/cockroach_versions.go | 13 ++- pkg/clusterversion/key_string.go | 7 +- pkg/migration/migrations/BUILD.bazel | 1 + ...t_missing_public_schema_namespace_entry.go | 82 +++++++++++++++++ pkg/migration/migrations/migrations.go | 6 ++ 22 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 pkg/ccl/backupccl/insert_missing_public_schema_namespace_entry_restore_test.go create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846481902174209.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846481902206977.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846481902239745.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846482369970177.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846482426396673.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846482479906817.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846484028981249.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846484029112321.sst create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-716846479146844161-CHECKSUM create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-CHECKSUM create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-STATISTICS create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP_MANIFEST create mode 100644 pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP_MANIFEST-CHECKSUM create mode 100644 pkg/migration/migrations/insert_missing_public_schema_namespace_entry.go diff --git a/docs/generated/settings/settings-for-tenants.txt b/docs/generated/settings/settings-for-tenants.txt index 91e20abc851c..cf3a3fa6da7d 100644 --- a/docs/generated/settings/settings-for-tenants.txt +++ b/docs/generated/settings/settings-for-tenants.txt @@ -168,4 +168,4 @@ trace.debug.enable boolean false if set, traces for recent requests can be seen trace.jaeger.agent string the address of a Jaeger agent to receive traces using the Jaeger UDP Thrift protocol, as :. If no port is specified, 6381 will be used. trace.opentelemetry.collector string address of an OpenTelemetry trace collector to receive traces using the otel gRPC protocol, as :. If no port is specified, 4317 will be used. trace.zipkin.collector string the address of a Zipkin instance to receive traces, as :. If no port is specified, 9411 will be used. -version version 21.2-28 set the active cluster version in the format '.' +version version 21.2-30 set the active cluster version in the format '.' diff --git a/docs/generated/settings/settings.html b/docs/generated/settings/settings.html index aca61f0835ac..c3824af16304 100644 --- a/docs/generated/settings/settings.html +++ b/docs/generated/settings/settings.html @@ -173,6 +173,6 @@ trace.jaeger.agentstringthe address of a Jaeger agent to receive traces using the Jaeger UDP Thrift protocol, as :. If no port is specified, 6381 will be used. trace.opentelemetry.collectorstringaddress of an OpenTelemetry trace collector to receive traces using the otel gRPC protocol, as :. If no port is specified, 4317 will be used. trace.zipkin.collectorstringthe address of a Zipkin instance to receive traces, as :. If no port is specified, 9411 will be used. -versionversion21.2-28set the active cluster version in the format '.' +versionversion21.2-30set the active cluster version in the format '.' diff --git a/pkg/ccl/backupccl/BUILD.bazel b/pkg/ccl/backupccl/BUILD.bazel index 6dfc23b8fea8..814301af3322 100644 --- a/pkg/ccl/backupccl/BUILD.bazel +++ b/pkg/ccl/backupccl/BUILD.bazel @@ -141,6 +141,7 @@ go_test( "full_cluster_backup_restore_test.go", "helpers_test.go", "import_spans_test.go", + "insert_missing_public_schema_namespace_entry_restore_test.go", "key_rewriter_test.go", "main_test.go", "partitioned_backup_test.go", diff --git a/pkg/ccl/backupccl/insert_missing_public_schema_namespace_entry_restore_test.go b/pkg/ccl/backupccl/insert_missing_public_schema_namespace_entry_restore_test.go new file mode 100644 index 000000000000..13a2d9556a49 --- /dev/null +++ b/pkg/ccl/backupccl/insert_missing_public_schema_namespace_entry_restore_test.go @@ -0,0 +1,85 @@ +// Copyright 2021 The Cockroach Authors. +// +// Licensed as a CockroachDB Enterprise file under the Cockroach Community +// License (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt + +package backupccl_test + +import ( + "context" + "fmt" + "testing" + + "github.com/cockroachdb/cockroach/pkg/base" + "github.com/cockroachdb/cockroach/pkg/clusterversion" + "github.com/cockroachdb/cockroach/pkg/server" + "github.com/cockroachdb/cockroach/pkg/testutils" + "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" + "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" + "github.com/cockroachdb/cockroach/pkg/util/leaktest" +) + +func TestPublicSchemaMigration(t *testing.T) { + defer leaktest.AfterTest(t)() + ctx := context.Background() + dir, cleanup := testutils.TempDir(t) + defer cleanup() + tc := testcluster.StartTestCluster(t, 3, base.TestClusterArgs{ + ServerArgs: base.TestServerArgs{ + ExternalIODir: dir, + Knobs: base.TestingKnobs{ + Server: &server.TestingKnobs{ + DisableAutomaticVersionUpgrade: 1, + BinaryVersionOverride: clusterversion.ByKey(clusterversion.InsertPublicSchemaNamespaceEntryOnRestore - 1), + }, + }, + }, + }) + defer tc.Stopper().Stop(ctx) + + db := tc.ServerConn(0) + defer db.Close() + sqlDB := sqlutils.MakeSQLRunner(tc.Conns[0]) + + // Mimic a restore where the public schema system.namespace entries are + // missing. + sqlDB.Exec(t, `CREATE DATABASE db1`) + sqlDB.Exec(t, `CREATE TABLE db1.t()`) + sqlDB.Exec(t, `CREATE SCHEMA db1.s`) + sqlDB.Exec(t, `CREATE DATABASE db2`) + sqlDB.Exec(t, `CREATE TABLE db2.t(x INT)`) + sqlDB.Exec(t, `INSERT INTO db2.t VALUES (1), (2)`) + sqlDB.Exec(t, `CREATE SCHEMA db2.s`) + sqlDB.Exec(t, `CREATE TABLE db2.s.t(x INT)`) + sqlDB.Exec(t, `INSERT INTO db2.s.t VALUES (1), (2)`) + + // Give root the ability to delete from system.namespace. + sqlDB.Exec(t, `INSERT INTO system.users VALUES ('node', '', false);`) + sqlDB.Exec(t, `GRANT node TO root`) + + var db1ID, db2ID int + row := sqlDB.QueryRow(t, `SELECT id FROM system.namespace WHERE name = 'db1'`) + row.Scan(&db1ID) + row = sqlDB.QueryRow(t, `SELECT id FROM system.namespace WHERE name = 'db2'`) + row.Scan(&db2ID) + + // Remove public schema namespace entries from system.namespace. + sqlDB.Exec(t, fmt.Sprintf(`DELETE FROM system.namespace WHERE name='public' AND id=29 AND "parentID"=%d`, db1ID)) + sqlDB.Exec(t, fmt.Sprintf(`DELETE FROM system.namespace WHERE name='public' AND id=29 AND "parentID"=%d`, db2ID)) + + // Verify that there are no system.namespace entries for the public schema for + // the two databases. + sqlDB.CheckQueryResults(t, fmt.Sprintf(`SELECT id FROM system.namespace WHERE name = 'public' AND "parentID"=%d`, db1ID), [][]string{}) + sqlDB.CheckQueryResults(t, fmt.Sprintf(`SELECT id FROM system.namespace WHERE name = 'public' AND "parentID"=%d`, db2ID), [][]string{}) + + // Kick off migration by upgrading to the new version. + _ = sqlDB.Exec(t, `SET CLUSTER SETTING version = $1`, + clusterversion.ByKey(clusterversion.InsertPublicSchemaNamespaceEntryOnRestore).String()) + + sqlDB.CheckQueryResults(t, fmt.Sprintf(`SELECT id FROM system.namespace WHERE name = 'public' AND "parentID"=%d`, db1ID), [][]string{{"29"}}) + sqlDB.CheckQueryResults(t, fmt.Sprintf(`SELECT id FROM system.namespace WHERE name = 'public' AND "parentID"=%d`, db2ID), [][]string{{"29"}}) + +} diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846481902174209.sst b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846481902174209.sst new file mode 100644 index 0000000000000000000000000000000000000000..1455e1cf978ac3110affe90ca2c52b331497ecd9 GIT binary patch literal 1014 zcmah|zfTlF6rMRaZf`jc4h~cTdKyZYAQCAE1^%G0@fQ|i%w}%)aknx%v&_uFEd>_D z1W+3jjnTx?5)&IcV`FVaW25m;ASNcpL}&I6v@yP7Gw;oN@B7~OX5ZrgjbtBg_t78< zIl^0L@ZFVL?&*4*$0(0SKX2|nb=`7yXM27aRpuU-iydyc>%rw=G;!_T)J>e}IG&Y4 z=+a^#`(*#iz~ZqV?B%ALFP9c4hf#U#?#aE5{D3`A?T)-67+JGljJEcNkehjgO21l$ zl7leoGA9K;H_E(uD7g5TgYj+1`J^F*wTuht9~vF24nt!Bs1OwCjntOA=oJ2`!B zdZwbZ=?S%Dc4DStCiQ~Q*IqTzploDa>Atq&_)Sh1`Pw0TD4s$^(V^J90*K-e4@&(&@px5s`GnbnOZkau~RlA*ilG4>mP5 z7&kp3RUerG!2(b^U35#Lfn57J7&RpIO?Sd+1Z@bnbjf1tgqWAWz+S7{3r5@XqQQfO zD!VF0eBt0~KCMs2E~Y|Xx9I;!x#JWvlCGsZtO&1h!ELKx-HH`H{YA+5haJ>+__|{Q nXXu#up5vd{!>muw_I}_OxlnO)xx6 literal 0 HcmV?d00001 diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846481902206977.sst b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846481902206977.sst new file mode 100644 index 0000000000000000000000000000000000000000..66d936bd044ad7fef45e25fcadab45ecb5ebfefc GIT binary patch literal 1140 zcmaiz-D^}w6u@V)iF@~E8)IUY7;L*m$&)+8WJz2?z-qPhsipP7qH>vg@5yFx?##{1 zY_gjtUj%)z^iBKd|DaL|)jvQep?^S2OQEGL_}~Zlfu6a$+4e=8hs!-@&gbu(A@i*p z*QXNMu?`HgkQi`;UL&<1KmWS+=*-CqCH=E`=-Z#e`J>H+xY=4xnvGT~Inih?EhUW> z=g?>^#w*KwJ#C(dmuFvIeezxP${%-sDAlMfEgnh*Z!2w`NGvmuYvY7!Gf+I1kPfn) z|C|0&A7;CxE^dVLqt0|-_PLMt;PI`yV>KF=4u7}>#tN&t?Wt@Tphg`5tOM(vq=pq2c zWn`_35C^cf)UlUgQ)y4jpSkkrV9p~b1>>|2u82y)3EJ&PWD-={ZIH@)RGW-DwznL? z4DFA=(-oF=EUq{HlZjF4D|>&UMz^@^;G`@|L1Mw65}o2c1`{*`(*~w|net#CkcQz2 zMrVp=Fh~&|IOB7>9>Z0T;IHk4a|rj8?x^%!EWa>1KfQN#w(##A`=kKYiJx*6ux(6A2XXtx@mU98cZA?#DM7~jhhFAs7aa-e8x0Lt2Wzt+-%0q&P?at zNwN_!VlCOI&>zxP5oxUyd{6|@R*{g>Kca{&zWt$4AE1y;G}TgU)q7_X^^YDHxaZvS z_|A9EomZlhpeZ<1x+4FwB%VGy2j@Zk;yw3It-SW041o++AGy5v)ia4^nFNM`v5C#h z{Qh5`QG&)4rvWCPFCsO98UPxG-uRi(b1tzrC?^;_L-M-T(4C;X#kJWV?k?a0J4tRJv5+NIIVa*=OHvS`e!Nn7cLk z;gM6(TQWMRN;NE$qOHmN&iQV+_SD=b##_sY$6`q>di{>;Ub^kexjViKddW&poe;}R zMIQVbR4*&XpMU6!bcaHk$FCY%2FU|QA76>hmO-Rly}JxRd%7&Gef(|obw%BG_@}6> zFf?8LWzhaKP!8@su2+|(lcgW!j>fWb==}r3>9>{B)BPXZR|ZL#jV^5NSZo6@bxAvM zbl;`eqr1DEi?DTV+nEtDtwuXnCx>Cncsp!)@!=hVBD^N~BmnTn@gX7k{hQ~07IzIv zQYJY*3Y1T;v(bFwkA923tVTJ$ha+mM8wk0-1dG-25k`)sgn z4RvsO(q*oDaPePeDH%0fJ1974LMvEy5m_cj7*9y40^0?Ry1v1R`L1S6<_vekro>}D zCd6``?T+So#X2dMb3Mv*GR?5K(>dLuq<72KY>#T=DQx%N+}_pM)uR&1a^ifkx2;EI zo#sr-pgFxrG2xb3Ld_gEGcU{e$BrG|rO91n1^Srns_P(X6)=!wfiEi})+|0I%2g2C zm@-~in*>Nr5}siMIGUX!gyt9>80BqO=Q`f&xSTC64e`hn_IW=7)1)d`Auh}c5;bt9 zk`dY1$1O){990I6`K#r`jrXEgdcEBb@kcn*u7(0f` z-XV}`U;+Dij9d@RXs3lueMunk=1IHZG z?GfMg1~#sS!uVqAwvgyiUj08@c1eohYttbPPQrOXNeC4dxVpxv4&Mi8yz}zCfd5Y_ r`|YuM3=eB?N&F-Fx7X+AMnrfAWQ literal 0 HcmV?d00001 diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846482369970177.sst b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846482369970177.sst new file mode 100644 index 0000000000000000000000000000000000000000..8514c0f483dda83237c51be23da4f4bb9a418ad6 GIT binary patch literal 1072 zcmaJ=PiPcZ7=Leew>!HT=MgQib(rDolnIUcJ z4GgcXPuGb*Ts?NaPDrV*UL5*%T9Duu`oq2PItdE?%|iz#io@ScPmtj67vGGGPms#y z!3FXorUh3YpZc|n`lE=b+9slEzdal}Rwx}WJ+2XNpmt|^lmyq${B)mG2~SH<&dn8r(q4 zEN=*4iHxDmY$pR(cCbb>4RcAG%_YKuPGs}sU_V`&R|s8z&i}%GtrRKIN+p})X(Bo- ziQRbp?zp00g{W*7#kuTz?woeoDbKea%?#p zEEg9+yL~+L{2tmRF0V?ey|mq}$OOoyohOxDROyskwv|Nu0os+ov6~pyGN9cEq_;@j zWJA6C=pq*_RLZaz1P%-`QZdBD@1-f|CNPzO<}x;VI@_ BOML(U literal 0 HcmV?d00001 diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846482426396673.sst b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846482426396673.sst new file mode 100644 index 0000000000000000000000000000000000000000..86706842041e8d33e7ee4e958eac5f30c83d6592 GIT binary patch literal 1144 zcmaJ>U1%It6ux(wb!Rryq`S$6vLROQ?45#_5uPb{KPnOOT2;zu{ru+$H55Ytn)ALp14?OIQ27M z%sv0QcL0^0`swX&%wPEKQRG%9Q(5zYD?! z;QXn*pX26%v-p$4otdk1$cP>U;q<4^uA#!V_fhe`fuMhkJ$ppqg)5iPuBTX!jTP%~$oL zUJ&}qYxNaKV>u~R;2E>_3i&NNa5H6KTpSk*pr#U0VFbu_tbi&?WOx!bu``T;fzr6> zF(tBh+0fGfaLPO>m8anV(q?hX=4t&(aR33bM{oq9 z4MZP;pgfRhY+GK#&Qrz`CG1hm(}-jm5XS)dOp zV|sv5Ilr|J8Vx~xot0lP$ zf9S~!=x0s!JGi`LyOyBctPcaiFW4~TZbaTHG^HUH?5BRQiJ!kmI fT#JX^spAcM_a@$HY2vYVF@gRCTo2h*&Hn8T8TiHal#MRO66p=YKtJEW(3?C#C( zYzd-QnP4F)m@FHmUKB5<~U|_1cs=lwj>VAoL(QNMd{wNLN zh$B2Ih0qA^p~;WeZX8!;e^Z$(kC`9hQ3V0f)MG#*9zdJuGy&Uos*Do}8&R8VL`;K>cvzbn!>xue zshg1g6?V!wU$AD($p(!hmXav21oK5_JWi;jT1el3NkRRF>x+J@ls_gxsYvi!oF+*+ z=D4m%wDDETa1kxni?mvrJAa{GWv~ToX<>fx;$pq3wCM?9x>T!I&7^J+`P%hT4a!Eg zl@44RHdzt>69;am3~WlFge6dmM06Abatb)0ni3UlLs%HZz(5;W%#;c_ryOXT`8j2- zQrb0Y0127!tPl6Nuwq%8%4fGg+Ho?*a|Ur&w@y=39LDW#N5X)Ix`7HqSjd=a(knvF z1nzFYiW@1?R3I${G@Qkj*!1uu-lD8&7Ntl4%oiIDI&P-{SgEte5 ze}?~p2{!}r<^|6lF!3KSK@&}gKW4TqdNI6YlYMXA``-7yH?z`0Gv5BopQYpd;-h1P zchS__hfiJ|z27KdRKi#GPCl%cYXyJG`?^|3w|;zi{;^yuB5T-vN95OQR4yE#iQhd# zcLrzZ-63nBQ9n{~NQ@>4?Vdsxd?p4Cx?EH;+R`>FxQ`k)0r9MlUwzZYgk(&RF9K0FiBiREnCD{g~w;}optkK&$gIVdVu zakqy^IEbccq0%`lRYDEv7a@NV_cq|fWty}#C`SQRi`WsnRGq@xl(+4oG>L&*z91qQ zLyY_?PCzw*$P^S6u|~Ba&#ErkoTo0LUE_*}K^VnA7b;`e)-<7EF(FqU z*#gO9&?aAWPohb$e;uqEibfWl2%12@MS0@B>uoY(ZvqE*tk>79ws&P)#A_j6Q8HZ~ z96iYEv#a-Vp;uk^|D-(i?W$-e=ix-ST`BiPa9-8v?%oDkYRnCx^FxEno!V}ejU6vI f89q&_Z5+J8pGNA-7hUKKb4&bw`0d5s(&ybj3$HSN literal 0 HcmV?d00001 diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846484029112321.sst b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/716846484029112321.sst new file mode 100644 index 0000000000000000000000000000000000000000..a892eeb33bb5c8665e2d5350706b06686a008b56 GIT binary patch literal 953 zcmah|&ubJh6i&9=&g^#Gwyv#Or0&6kh>i6JwovPjR=rwkK~Tz=nR(p}%_L)z?e6p> zf>?;6X%_*{*! z6ddg2C{7iuvkqBj+<;=DF*8}i?WVM;8<71K_D2UJ$yoj3JBP@0Vy|TY2NvWbn zs>n7|l19xSlKoi48&aS(lj5qNX`0piAdsoCzHVDCvK@rX=!NOyr{?P%Hi0jkJTZHE zcD}BS#e_z-Ff(7blLj%1Ob})Uw2N$M69+DAvzYi32jQlST}r8f6;RiS7?uF?OE{*6 z63wb`jA8rZh#Bw(26*ob-aSGP+hjCZ8 z92AwSxYI=>97Mx3QE3;JDxrq-ijY5!yBl!gGEG_$w$oBu5rb~AdF(53zZRUYZ@?Z zF(FqU*#gO9&?aAWSE6yRcO9%6ibfWl2%12zMS1L!>uoY(ZvqE*tZ%GZZ5L%r#H%4+ zRx(}cA6?Gtv!fStp;uh@f26GWc2%^U^Kc@Zsg!#nIIrq-cW(pT+kUu)b`SI~cWS#? lHg>$=`{3`S+RdFO`2A3QX|D_Y$J`RXz5ROk*@X|=zW|{?FA4wv literal 0 HcmV?d00001 diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-716846479146844161-CHECKSUM b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-716846479146844161-CHECKSUM new file mode 100644 index 000000000000..0df5cffc6595 --- /dev/null +++ b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-716846479146844161-CHECKSUM @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-CHECKSUM b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-CHECKSUM new file mode 100644 index 000000000000..a4f55c5ebc07 --- /dev/null +++ b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-CHECKPOINT-CHECKSUM @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-STATISTICS b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP-STATISTICS new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP_MANIFEST b/pkg/ccl/backupccl/testdata/restore_old_versions/missing-public-schema-namespace/v21.1.1/BACKUP_MANIFEST new file mode 100644 index 0000000000000000000000000000000000000000..0a6787b0c953bd42e725cc2857566354cb602b51 GIT binary patch literal 2504 zcmV;(2{-m1iwFP!00000|Lj;@Y#dh=zW2`T?(FqX#+$m?OevWR#ND{IGyCKHgBHhD zAwL8x$F0DXn9S~sok`X^+nw3i?o(b6*^ovdR83SAH6TDuQK3pfvLdylQ4mojB!q-O zNT@|X6)8duJRsl+&7IlVnO*NXwo#sV^7!t#_nh;6=bU@a#UO&2J0E@g=a27w`-4Y0 zhC}D-0y=lr`g*A@pqI$k`MQA4ldo6m0(ymfU8)P{(mCtvN?kx#$l7al0lh}nuGR%~ zm8@N>3+Nj8db2K|H@|6py;B#^J7n!6;xlC%Dh=-W((kzP7>(IJm#bl>0~aQ&Lo}lzmC`d5g)@YW?u13E+?k5 zaoe0A^EDPmZEp!SHeyZrl$glovhhT!fz1%>k+xCwN$2A6L^2WgOAkL4`3w#kD~72q zvXFZmhjBnw7PT@fVg}PyT{l@VLYH+#jY0u47k>TA+h?tiiNOhQ2n^q*@Ou;v)C{$1 zL}?zzVBRA%`2=RHpUU#0%0jM}39%pwL@>Sc7~p{jj)MwV2B#sI9L4>|W#hQ2Ov{F` zq*oOdalH)Vhz}eCJoJi>;GkyA=p~h72kcx&$&2rfW$8G`S@AOj*G3SNicIs`W$IEGH_ z!ngs~eF}#iyzWyCz)nMW22z);9Xp#A0M6CV!x*>@NAM%_@}iWG+8}5Fg-0=T9ex7$ zTH;B`g}?!Wr()D9q;ElR7lMC4+A{cG5S&KfA_A`>4>8vfSViC_di)LoA0jaPD}>)i zIPjugR*h(&jmF&=X$m0_vJ(XAM_LKogM&rAJg+TuCGG$wx2m1@|hXHi73~DEuc1GlpuKT6w{U2HPP06sFhDicjOfDY;Zr38o#Tp2j^T z*)X52D6*+4EXDOP0Y~-^3`vQBvc44Co6qNG4<32u=wB&JJYPtb9Vj5@T$9Vzbn%?q|M?A&TF|Z2ZCTPA& z;VTqIH7(lTMzDaXlj_O_`0ZHio?MS#f35qHpCZeOhsV$(-VC!;+bPE39y`Sv?%ICa z^=t?a*!9fsrPt}rSGGG0{sn{S6MDgjZfheczII_7?yr@#7iy|h)t59Swzs9w8K!L3 zjP6O9$Dv|X-CRNr;ZQ|hDe1C8($O0jJ{?bBrc%`xs;XhIfo>5rhPOG!NQD*2v=SuP zCC?{EaGytBQ`k@oLO$tzm@SrMZBa5*!_f4ywSnnoj)({B4O-bS<#JKAc7(gAIDr4h z*T!50@32BbvZ<6B-fGG+i=seqC>9zVib$lgZ~|;W<7J44h{_fwBp=em0xAlGR>A~7 zBg2k`Vo(fqHmrgkD8uQEWVnuZ*)>>GTG49+ExB7c$3m`wA=e0MuGKfr?^~lP^Fcmj z7msF`L(cu?1F^t$n8E=PODy8rqL6D3GoInYR<+;ErT#4%pQmxSq!(pV)5}J5u&tg9 z;~wkhl4h{4ViRA@bl

a zATXo()5>eT;5Sc%BHBs z<3G~4x2l&^X;ED)SYyzRwVFLkqI*2-!9n|k?tw6bLz=OlfY>(s_#1)eTY5Fi1i{g< zRW|1&Jm_^=BL6hXCs8HBEZTyCBHrOsVE=XNW5W-W-AZq>p~|<*+uINqImZesimXcY zN!-_%%o+?e$l81dbC<$@r7%;}7Z=sCX+)!Ig%`QgyAEhE9M%gb)S_u!wrHJE&ZreE zF{+!`5DqyuwG9m|Mdn0HAd>s6X^r5hvtm-Dtf<^lm3h*~D8|7`tx(d6EZ?2o5g)tc zT56ieIVRfW!b5dRYGTlUgQsKkDhzCb>T?vXQ%*I}EA}O`d-IPfdvMS`rF%tjrx2>! z>_^W?9Uf5xN6W*#Ax74GP~jX~8Uu#S7qz+K{@W1#O$hfJ#p9|{E2)Y^rieXlgyeBg zLq^)@I5C3z+`WX+u2g;2KUIVsxvOEKW_#OIF+0~nw7yhUt6lTe>NLvgvME(-Wj4^N z1hzcdxwc!)o;_7`d9-V~sxDWmWUA;mgY3hsE3K%etd)%JQ^g4GQKV1UEz?QBzY9k4i#R1}z)kS%n z<6L977PfiF2l${>43}|0H;=1T7IOY*ZZ`jR$Gp*o<>DGwqLa`;Z5VaL}o&cX!bfgO7TPx~-ar>-6TX%dIr$g)Ebb zKqHzKx*IU;!C3V1lVCIJ^K<9w8}DB8^OJMyj`#L;STEY59Dh>7?5 zGjb|fkW&dIs}u`Lp{S1M=5umtxNoW?mlycBI3|vXe4(e;SD&*(2;@3{ZogZogO_pyMOlJ z(b= Key(len(_Key_index)-1) { diff --git a/pkg/migration/migrations/BUILD.bazel b/pkg/migration/migrations/BUILD.bazel index f2bedaf27cfd..d227bbf91a09 100644 --- a/pkg/migration/migrations/BUILD.bazel +++ b/pkg/migration/migrations/BUILD.bazel @@ -10,6 +10,7 @@ go_library( "delete_deprecated_namespace_tabledesc.go", "ensure_no_draining_names.go", "fix_descriptor_migration.go", + "insert_missing_public_schema_namespace_entry.go", "join_tokens.go", "migrations.go", "records_based_registry.go", diff --git a/pkg/migration/migrations/insert_missing_public_schema_namespace_entry.go b/pkg/migration/migrations/insert_missing_public_schema_namespace_entry.go new file mode 100644 index 000000000000..28bf9b8ed635 --- /dev/null +++ b/pkg/migration/migrations/insert_missing_public_schema_namespace_entry.go @@ -0,0 +1,82 @@ +// Copyright 2021 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package migrations + +import ( + "context" + + "github.com/cockroachdb/cockroach/pkg/clusterversion" + "github.com/cockroachdb/cockroach/pkg/jobs" + "github.com/cockroachdb/cockroach/pkg/keys" + "github.com/cockroachdb/cockroach/pkg/kv" + "github.com/cockroachdb/cockroach/pkg/migration" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/catalogkeys" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descs" + "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" +) + +// insertMissingPublicSchemaNamespaceEntry creates a system.namespace entries +// for public schemas that are missing a system.namespace entry. +// This arises from restore where we mistakenly did not create system.namespace +// entries for public schemas when restoring databases. +func insertMissingPublicSchemaNamespaceEntry( + ctx context.Context, _ clusterversion.ClusterVersion, d migration.TenantDeps, _ *jobs.Job, +) error { + // Get the ID of all databases where we're missing a public schema namespace + // entry for. + query := ` + SELECT id + FROM system.namespace + WHERE id + NOT IN ( + SELECT ns_db.id + FROM system.namespace AS ns_db + INNER JOIN system.namespace + AS ns_sc ON ( + ns_db.id + = ns_sc."parentID" + ) + WHERE ns_db."parentSchemaID" = 0 + AND ns_db."parentID" = 0 + AND ns_sc."parentSchemaID" = 0 + AND ns_sc.name = 'public' + AND ns_sc.id = 29 + ) + AND "parentID" = 0 +ORDER BY id ASC; +` + rows, err := d.InternalExecutor.QueryIterator( + ctx, "get_databases_without_public_schema_namespace_entry", nil /* txn */, query, + ) + if err != nil { + return err + } + var databaseIDs []descpb.ID + for ok, err := rows.Next(ctx); ok; ok, err = rows.Next(ctx) { + if err != nil { + return err + } + id := descpb.ID(tree.MustBeDInt(rows.Cur()[0])) + databaseIDs = append(databaseIDs, id) + } + + return d.CollectionFactory.Txn(ctx, d.InternalExecutor, d.DB, func( + ctx context.Context, txn *kv.Txn, descriptors *descs.Collection, + ) error { + b := txn.NewBatch() + for _, dbID := range databaseIDs { + publicSchemaKey := catalogkeys.MakeSchemaNameKey(d.Codec, dbID, tree.PublicSchema) + b.Put(publicSchemaKey, keys.PublicSchemaID) + } + return txn.Run(ctx, b) + }) +} diff --git a/pkg/migration/migrations/migrations.go b/pkg/migration/migrations/migrations.go index 38e73105f5a5..6f27cb2c9d9c 100644 --- a/pkg/migration/migrations/migrations.go +++ b/pkg/migration/migrations/migrations.go @@ -142,6 +142,12 @@ var migrations = []migration.Migration{ NoPrecondition, alterSystemStmtDiagReqs, ), + migration.NewTenantMigration( + "insert missing system.namespace entries for public schemas", + toCV(clusterversion.InsertPublicSchemaNamespaceEntryOnRestore), + NoPrecondition, + insertMissingPublicSchemaNamespaceEntry, + ), } func init() {