Skip to content

Commit f360c1b

Browse files
craig[bot]jeffswensonrafissknzdt
committed
105592: tenantcostmodel: charge for cross region network traffic r=JeffSwenson a=JeffSwenson Previously the 'tenant_cost_model.region_multiplier_table' allowed configuring the cost of multi-region operations by applying a multiplier to the entire operation cost. There were three problems with this approach that prevented deploying it to production: 1. There was a flat multiplier for reads and writes. Because the fixed overhead of a read is much lower, the cost impact of cross region network traffic is much larger when compared to writes. The break even read multiplier was an order of magnitude higher than the break even write multiplier. 2. The correct multiplier depends heavily on how many bytes are in an operation. Large operations require a larger multiplier to break even than smaller operations. Again the break even multiplier for large operations needed to be an order of magnitude larger than the break even for small operations. 3. The original setting assumed the cost of network traffic was symmetric between two different regions. That assumption is true for some cloud providers, but is not true for all cloud providers. Now, the 'tenant_cost_model.cross_region_network_cost' setting allows configuring the RU/byte cost of network traffic between region pairs. The cost is computed by the dist sender because computing the network cost requires locality information for the local node, the target replica, and all replica's in the range. The network cost only applies to logical byte traffic, it does not apply to RPC overhead. This is believed to be okay, because the fixed RU cost of each request and batch is high enough to cover the network cost of the operation overhead. This only accounts for network traffic incurred by reads or writes between the sql server or the kv server. It does not account for network traffic generated by zone configuration changes, replica rebalancing, or distsql. - Currently distsql is disabled in production Serverless and will only be reenabled once distsql properly accounts for network traffic. Distsql should use the same byte per RU cost table as sql server <-> kv traffic. - Zone configuration is expected to generate a small enough amount of the overall network traffic that we do not need to charge for it. We can revise this decision in the future if production data shows that is not true. - Replica rebalancing is something controlled by CRDB. If rebalancing cost ends up being a problem, we could look into reducing the amount of cross-region rebalancing traffic or we could start charging for rebalancing traffic. This change is backwards incompatible and will be back ported to 23.1. This is safe because Serverless is the only user of the setting. Release Note: none Part of: https://cockroachlabs.atlassian.net/browse/CC-7140 105944: sql: populate information_schema.routines and parameters r=rafiss a=rafiss fixes cockroachdb#104083 --- ### builtins: add nameconcatoid function This adds the nameconcatoid in order to match PostgreSQL. It is used by the information_schema to create unique names. Release note (sql change): Added the nameconcatoid builtin function, which concatenates a name with an OID. --- ### sql: populate pg_catalog.pg_language Release note (sql change): The pg_catalog.pg_language table is now populated with data about languages used to define functions. --- ### sql: implement information_schema.routines view Release note (sql change): The information_schema.routines view is now populated with information about functions. --- ### builtins: add pg_get_function_arg_default Add an implementation for pg_get_function_arg_default to match PostgreSQL. Since we don't support function defaults, this always returns NULL. Release note: None --- ### sql: populate information_schema.parameters Release note (sql change): The information_schema.parameters table is now populated with information about function parameters. 106931: server: ensure SQL statement diagnostic requests work with secondary tenants r=yuzefovich a=knz Fixes cockroachdb#107243. Release note (bug fix): A bug with the "SQL statement diagnostic request" HTTP API that would affect e.g. CC Serverless was fixed. This bug had existed since v22.x. Epic: CRDB-26687 Informs: CRDB-18499 Informs cockroachdb#76378. 107284: backupccl: fix URI map keys r=dt a=dt Protos as keys aren't useful if they have pointers, but the string repr should be equal. Release note: none. Epic: none. Co-authored-by: Jeff <[email protected]> Co-authored-by: Rafi Shamim <[email protected]> Co-authored-by: Raphael 'kena' Poss <[email protected]> Co-authored-by: David Taylor <[email protected]>
5 parents b76924e + d5f3d61 + 6e1de01 + 618813b + 9f45f28 commit f360c1b

File tree

25 files changed

+882
-1065
lines changed

25 files changed

+882
-1065
lines changed

docs/generated/sql/functions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3587,6 +3587,8 @@ table. Returns an error if validation fails.</p>
35873587
</span></td><td>Immutable</td></tr>
35883588
<tr><td><a name="information_schema._pg_numeric_scale"></a><code>information_schema._pg_numeric_scale(typid: oid, typmod: int4) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Returns the scale of the given type with type modifier</p>
35893589
</span></td><td>Immutable</td></tr>
3590+
<tr><td><a name="nameconcatoid"></a><code>nameconcatoid(name: <a href="string.html">string</a>, oid: oid) &rarr; name</code></td><td><span class="funcdesc"><p>Used in the information_schema to produce specific_name columns, which are supposed to be unique per schema. The result is the same as ($1::text || ‘_’ || $2::text)::name except that, if it would not fit in 63 characters, we make it do so by truncating the name input (not the oid).</p>
3591+
</span></td><td>Immutable</td></tr>
35903592
<tr><td><a name="obj_description"></a><code>obj_description(object_oid: oid) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the comment for a database object specified by its OID alone. This is deprecated since there is no guarantee that OIDs are unique across different system catalogs; therefore, the wrong comment might be returned.</p>
35913593
</span></td><td>Stable</td></tr>
35923594
<tr><td><a name="obj_description"></a><code>obj_description(object_oid: oid, catalog_name: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the comment for a database object specified by its OID and the name of the containing system catalog. For example, obj_description(123456, ‘pg_class’) would retrieve the comment for the table with OID 123456.</p>
@@ -3601,6 +3603,8 @@ table. Returns an error if validation fails.</p>
36013603
</span></td><td>Immutable</td></tr>
36023604
<tr><td><a name="pg_function_is_visible"></a><code>pg_function_is_visible(oid: oid) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Returns whether the function with the given OID belongs to one of the schemas on the search path.</p>
36033605
</span></td><td>Stable</td></tr>
3606+
<tr><td><a name="pg_get_function_arg_default"></a><code>pg_get_function_arg_default(func_oid: oid, arg_num: int4) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Get textual representation of a function argument’s default value. The second argument of this function is the argument number among all arguments (i.e. proallargtypes, <em>not</em> proargtypes), starting with 1, because that’s how information_schema.sql uses it. Currently, this always returns NULL, since CockroachDB does not support default values.</p>
3607+
</span></td><td>Stable</td></tr>
36043608
<tr><td><a name="pg_get_function_arguments"></a><code>pg_get_function_arguments(func_oid: oid) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the argument list (with defaults) necessary to identify a function, in the form it would need to appear in within CREATE FUNCTION.</p>
36053609
</span></td><td>Stable</td></tr>
36063610
<tr><td><a name="pg_get_function_identity_arguments"></a><code>pg_get_function_identity_arguments(func_oid: oid) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the argument list (without defaults) necessary to identify a function, in the form it would need to appear in within ALTER FUNCTION, for instance.</p>

pkg/ccl/backupccl/restore_job.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,21 +3203,21 @@ func sendAddRemoteSSTs(
32033203
// We can then look in this map using the proto attached to each file to find
32043204
// the URI for that file.
32053205
// TODO(dt/butler): should we plumb the original string instead?
3206-
urisForDirs := make(map[cloudpb.ExternalStorage]string)
3206+
urisForDirs := make(map[string]string)
32073207
for _, u := range uris {
32083208
dir, err := cloud.ExternalStorageConfFromURI(u, username.SQLUsername{})
32093209
if err != nil {
32103210
return err
32113211
}
3212-
urisForDirs[dir] = u
3212+
urisForDirs[dir.String()] = u
32133213
}
32143214
for _, loc := range backupLocalityInfo {
32153215
for _, u := range loc.URIsByOriginalLocalityKV {
32163216
dir, err := cloud.ExternalStorageConfFromURI(u, username.SQLUsername{})
32173217
if err != nil {
32183218
return err
32193219
}
3220-
urisForDirs[dir] = u
3220+
urisForDirs[dir.String()] = u
32213221
}
32223222
}
32233223

@@ -3268,7 +3268,7 @@ func sendAddRemoteSSTs(
32683268
}
32693269
file.BackingFileSize = uint64(sz)
32703270
}
3271-
uri, ok := urisForDirs[file.Dir]
3271+
uri, ok := urisForDirs[file.Dir.String()]
32723272
if !ok {
32733273
return errors.AssertionFailedf("URI not found for %s", file.Dir.String())
32743274
}

pkg/ccl/multitenantccl/tenantcostclient/tenant_side_test.go

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@ func (ts *testState) stop() {
165165
}
166166

167167
type cmdArgs struct {
168-
count int64
169-
bytes int64
170-
repeat int64
171-
label string
172-
wait bool
173-
ruMultiplier float64
168+
count int64
169+
bytes int64
170+
repeat int64
171+
label string
172+
wait bool
173+
networkCost float64
174174
}
175175

176176
func parseBytesVal(arg datadriven.CmdArg) (int64, error) {
@@ -234,15 +234,17 @@ func parseArgs(t *testing.T, d *datadriven.TestData) cmdArgs {
234234
d.Fatalf(t, "invalid wait value")
235235
}
236236

237-
case "ruMultiplier":
237+
case "networkCost":
238238
if len(args.Vals) != 1 {
239-
d.Fatalf(t, "expected one value for ruMultiplier")
239+
d.Fatalf(t, "expected one value for networkCost")
240240
}
241241
val, err := strconv.ParseFloat(args.Vals[0], 64)
242242
if err != nil {
243-
d.Fatalf(t, "invalid ruMultiplier value")
243+
d.Fatalf(t, "invalid networkCost value")
244244
}
245-
res.ruMultiplier = val
245+
res.networkCost = val
246+
default:
247+
d.Fatalf(t, "uknown command: '%s'", args.Key)
246248
}
247249
}
248250
return res
@@ -313,24 +315,18 @@ func (ts *testState) request(
313315
}
314316

315317
var writeCount, readCount, writeBytes, readBytes int64
316-
var writeRUMultiplier, readRUMultiplier tenantcostmodel.RUMultiplier
318+
var writeNetworkCost, readNetworkCost tenantcostmodel.NetworkCost
317319
if isWrite {
318320
writeCount = args.count
319321
writeBytes = args.bytes
320-
writeRUMultiplier = tenantcostmodel.RUMultiplier(args.ruMultiplier)
321-
if writeRUMultiplier == 0 {
322-
writeRUMultiplier = 1
323-
}
322+
writeNetworkCost = tenantcostmodel.NetworkCost(args.networkCost)
324323
} else {
325324
readCount = args.count
326325
readBytes = args.bytes
327-
readRUMultiplier = tenantcostmodel.RUMultiplier(args.ruMultiplier)
328-
if readRUMultiplier == 0 {
329-
readRUMultiplier = 1
330-
}
326+
readNetworkCost = tenantcostmodel.NetworkCost(args.networkCost)
331327
}
332-
reqInfo := tenantcostmodel.TestingRequestInfo(1, writeCount, writeBytes, writeRUMultiplier)
333-
respInfo := tenantcostmodel.TestingResponseInfo(!isWrite, readCount, readBytes, readRUMultiplier)
328+
reqInfo := tenantcostmodel.TestingRequestInfo(1, writeCount, writeBytes, writeNetworkCost)
329+
respInfo := tenantcostmodel.TestingResponseInfo(!isWrite, readCount, readBytes, readNetworkCost)
334330

335331
for ; repeat > 0; repeat-- {
336332
ts.runOperation(t, d, args.label, func() {
@@ -788,7 +784,7 @@ func TestWaitingRU(t *testing.T) {
788784

789785
// Immediately consume the initial 10K RUs.
790786
require.NoError(t, ctrl.OnResponseWait(ctx,
791-
tenantcostmodel.TestingRequestInfo(1, 1, 10237952, 1), tenantcostmodel.ResponseInfo{}))
787+
tenantcostmodel.TestingRequestInfo(1, 1, 10237952, 0), tenantcostmodel.ResponseInfo{}))
792788

793789
stopper := stop.NewStopper()
794790
defer stopper.Stop(ctx)
@@ -806,7 +802,7 @@ func TestWaitingRU(t *testing.T) {
806802
// Send 20 KV requests for 1K RU each.
807803
const count = 20
808804
const fillRate = 100
809-
req := tenantcostmodel.TestingRequestInfo(1, 1, 1021952, 1)
805+
req := tenantcostmodel.TestingRequestInfo(1, 1, 1021952, 0)
810806
resp := tenantcostmodel.TestingResponseInfo(false, 0, 0, 0)
811807

812808
testutils.SucceedsWithin(t, func() error {

pkg/ccl/multitenantccl/tenantcostclient/testdata/consumption

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -364,9 +364,9 @@ PGWire egress: 12345 bytes
364364
ExternalIO egress: 1026000 bytes
365365
ExternalIO ingress: 1034000 bytes
366366

367-
# Read the same amount of bytes as the first subtest. Increase in RUs should be
368-
# multiplied by 2 of the ones in the first subtest.
369-
read bytes=1048576 ruMultiplier=2.0
367+
# Read the same amount of bytes as the first subtest. Should have an increase
368+
# of ~10.5 RUs compared to the first test.
369+
read bytes=1048576 networkCost=0.00001
370370
----
371371

372372
advance
@@ -380,18 +380,17 @@ token-bucket-response
380380

381381
usage
382382
----
383-
RU: 2357.64
384-
KVRU: 72.25
383+
RU: 2351.50
384+
KVRU: 66.11
385385
Reads: 5 requests in 4 batches (2228224 bytes)
386386
Writes: 5 requests in 4 batches (10240 bytes)
387387
SQL Pods CPU seconds: 3.82
388388
PGWire egress: 12345 bytes
389389
ExternalIO egress: 1026000 bytes
390390
ExternalIO ingress: 1034000 bytes
391391

392-
# Test write operation consumption with RU multiplier of 3.5 on the RUs
393-
# increased in the second subtest.
394-
write bytes=1024 ruMultiplier=3.5
392+
# This write is expected to consume an extra 5.12 RUs from network cost usage.
393+
write bytes=1024 networkCost=0.005
395394
----
396395

397396
advance
@@ -405,8 +404,8 @@ token-bucket-response
405404

406405
usage
407406
----
408-
RU: 2368.14
409-
KVRU: 82.75
407+
RU: 2359.62
408+
KVRU: 74.23
410409
Reads: 5 requests in 4 batches (2228224 bytes)
411410
Writes: 6 requests in 5 batches (11264 bytes)
412411
SQL Pods CPU seconds: 3.82
@@ -415,10 +414,10 @@ ExternalIO egress: 1026000 bytes
415414
ExternalIO ingress: 1034000 bytes
416415

417416
# Test multiple requests in the same batch with RU multiplier of 1.
418-
write count=2 bytes=1024 ruMultiplier=1.0
417+
write count=2 bytes=1024 networkCost=0
419418
----
420419

421-
read count=2 bytes=65536 ruMultiplier=1.0
420+
read count=2 bytes=65536 networkCost=0
422421
----
423422

424423
advance
@@ -432,8 +431,8 @@ token-bucket-response
432431

433432
usage
434433
----
435-
RU: 2373.89
436-
KVRU: 88.50
434+
RU: 2365.37
435+
KVRU: 79.98
437436
Reads: 7 requests in 5 batches (2293760 bytes)
438437
Writes: 8 requests in 6 batches (12288 bytes)
439438
SQL Pods CPU seconds: 3.82

pkg/cli/clisqlshell/testdata/describe

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,13 +585,13 @@ https://www.postgresql.org/docs/9.5/view-pg-indexes.html"
585585
pg_catalog,pg_inherits,table,admin,NULL,permanent,prefix,"table inheritance hierarchy (empty - feature does not exist)
586586
https://www.postgresql.org/docs/9.5/catalog-pg-inherits.html"
587587
pg_catalog,pg_init_privs,table,admin,NULL,permanent,prefix,pg_init_privs was created for compatibility and is currently unimplemented
588-
pg_catalog,pg_language,table,admin,NULL,permanent,prefix,"available languages (empty - feature does not exist)
588+
pg_catalog,pg_language,table,admin,NULL,permanent,prefix,"available languages
589589
https://www.postgresql.org/docs/9.5/catalog-pg-language.html"
590590
pg_catalog,pg_largeobject,table,admin,NULL,permanent,prefix,pg_largeobject was created for compatibility and is currently unimplemented
591591
pg_catalog,pg_largeobject_metadata,table,admin,NULL,permanent,prefix,pg_largeobject_metadata was created for compatibility and is currently unimplemented
592592
pg_catalog,pg_locks,table,admin,NULL,permanent,prefix,"locks held by active processes (empty - feature does not exist)
593593
https://www.postgresql.org/docs/9.6/view-pg-locks.html"
594-
pg_catalog,pg_matviews,table,admin,NULL,permanent,prefix,"available materialized views (empty - feature does not exist)
594+
pg_catalog,pg_matviews,table,admin,NULL,permanent,prefix,"available materialized views
595595
https://www.postgresql.org/docs/9.6/view-pg-matviews.html"
596596
pg_catalog,pg_namespace,table,admin,NULL,permanent,prefix,"available namespaces
597597
https://www.postgresql.org/docs/9.5/catalog-pg-namespace.html"

0 commit comments

Comments
 (0)