@@ -64,13 +64,18 @@ func (s *topLevelServer) newTenantServer(
64
64
portStartHint int ,
65
65
testArgs base.TestSharedProcessTenantArgs ,
66
66
) (onDemandServer , error ) {
67
- tenantID , err := s .getTenantID (ctx , tenantNameContainer .Get ())
67
+ tenantID , tenantReadOnly , err := s .getTenantID (ctx , tenantNameContainer .Get ())
68
68
if err != nil {
69
69
return nil , err
70
70
}
71
71
72
+ // Use test override for tenant read-only status if provided.
73
+ if testArgs .TenantReadOnly {
74
+ tenantReadOnly = true
75
+ }
76
+
72
77
baseCfg , sqlCfg , err := s .makeSharedProcessTenantConfig (ctx , tenantID , tenantNameContainer .Get (), portStartHint ,
73
- tenantStopper , testArgs .Settings )
78
+ tenantStopper , testArgs .Settings , tenantReadOnly )
74
79
if err != nil {
75
80
return nil , err
76
81
}
@@ -100,23 +105,27 @@ var ErrInvalidTenant error = errInvalidTenantMarker{}
100
105
101
106
func (s * topLevelServer ) getTenantID (
102
107
ctx context.Context , tenantName roachpb.TenantName ,
103
- ) (roachpb.TenantID , error ) {
108
+ ) (roachpb.TenantID , bool , error ) {
104
109
var rec * mtinfopb.TenantInfo
105
110
if err := s .sqlServer .internalDB .Txn (ctx , func (ctx context.Context , txn isql.Txn ) error {
106
111
var err error
107
112
rec , err = sql .GetTenantRecordByName (ctx , s .cfg .Settings , txn , tenantName )
108
113
return err
109
114
}); err != nil {
110
- return roachpb.TenantID {}, errors .Mark (err , ErrInvalidTenant )
115
+ return roachpb.TenantID {}, false , errors .Mark (err , ErrInvalidTenant )
111
116
}
112
117
113
118
tenantID , err := roachpb .MakeTenantID (rec .ID )
114
119
if err != nil {
115
- return roachpb.TenantID {}, errors .Mark (
120
+ return roachpb.TenantID {}, false , errors .Mark (
116
121
errors .NewAssertionErrorWithWrappedErrf (err , "stored tenant ID %d does not convert to TenantID" , rec .ID ),
117
122
ErrInvalidTenant )
118
123
}
119
- return tenantID , nil
124
+
125
+ // Check if tenant is read-only (PCR reader tenant).
126
+ readOnlyTenant := rec .ReadFromTenant != nil
127
+
128
+ return tenantID , readOnlyTenant , nil
120
129
}
121
130
122
131
// newTenantServerInternal instantiates a server for the given target
@@ -151,6 +160,7 @@ func (s *topLevelServer) makeSharedProcessTenantConfig(
151
160
portStartHint int ,
152
161
stopper * stop.Stopper ,
153
162
testSettings * cluster.Settings ,
163
+ tenantReadOnly bool ,
154
164
) (BaseConfig , SQLConfig , error ) {
155
165
// Create a configuration for the new tenant.
156
166
parentCfg := s .cfg
@@ -167,7 +177,7 @@ func (s *topLevelServer) makeSharedProcessTenantConfig(
167
177
}
168
178
169
179
baseCfg , sqlCfg , err := makeSharedProcessTenantServerConfig (ctx , tenantID , tenantName , portStartHint , parentCfg ,
170
- localServerInfo , st , stopper , s .recorder )
180
+ localServerInfo , st , stopper , s .recorder , tenantReadOnly )
171
181
if err != nil {
172
182
return BaseConfig {}, SQLConfig {}, err
173
183
}
@@ -186,6 +196,7 @@ func makeSharedProcessTenantServerConfig(
186
196
st * cluster.Settings ,
187
197
stopper * stop.Stopper ,
188
198
nodeMetricsRecorder * status.MetricsRecorder ,
199
+ tenantReadOnly bool ,
189
200
) (baseCfg BaseConfig , sqlCfg SQLConfig , err error ) {
190
201
tr := tracing .NewTracerWithOpt (ctx , tracing .WithClusterSettings (& st .SV ))
191
202
@@ -333,6 +344,7 @@ func makeSharedProcessTenantServerConfig(
333
344
}
334
345
335
346
sqlCfg = MakeSQLConfig (tenantID , tenantName , tempStorageCfg )
347
+ sqlCfg .TenantReadOnly = tenantReadOnly
336
348
baseCfg .ExternalIODirConfig = kvServerCfg .BaseConfig .ExternalIODirConfig
337
349
338
350
baseCfg .ExternalIODir = kvServerCfg .BaseConfig .ExternalIODir
0 commit comments