Skip to content

Commit

Permalink
stmtdiagnostics: break into chunks
Browse files Browse the repository at this point in the history
Implement breaking support bundles into chunks. The bundles contain
traces which can be large, resulting in "command is too large" errors.

Release note (bug fix): better support for large statement diagnostic
bundles.
  • Loading branch information
RaduBerinde committed Jul 3, 2020
1 parent 9e0a39f commit 306eabc
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
4 changes: 4 additions & 0 deletions pkg/sql/explain_bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import (
"context"
"fmt"
"io"
"math/rand"
"regexp"
"sort"
"strings"
"testing"

"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/sql/stmtdiagnostics"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
Expand All @@ -44,6 +46,8 @@ func TestExplainAnalyzeDebug(t *testing.T) {
plans := "schema.sql opt.txt opt-v.txt opt-vv.txt plan.txt"

t.Run("basic", func(t *testing.T) {
// Set a small chunk size to test splitting into chunks.
defer stmtdiagnostics.TestingSetBundleChunkSize(1 + rand.Intn(100))()
rows := r.QueryStr(t, "EXPLAIN ANALYZE (DEBUG) SELECT * FROM abc WHERE c=1")
checkBundle(
t, fmt.Sprint(rows),
Expand Down
29 changes: 20 additions & 9 deletions pkg/sql/stmtdiagnostics/statement_diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ var stmtDiagnosticsPollingInterval = settings.RegisterDurationSetting(
"rate at which the stmtdiagnostics.Registry polls for requests, set to zero to disable",
10*time.Second)

var bundleChunkSize = 128 * 1024

// TestingSetBundleChunkSize is used to change the chunk size for testing.
func TestingSetBundleChunkSize(val int) (restore func()) {
old := bundleChunkSize
bundleChunkSize = val
return func() { bundleChunkSize = old }
}

// Registry maintains a view on the statement fingerprints
// on which data is to be collected (i.e. system.statement_diagnostics_requests)
// and provides utilities for checking a query against this list and satisfying
Expand Down Expand Up @@ -394,27 +403,29 @@ func (r *Registry) insertStatementDiagnostics(
errorVal = tree.NewDString(collectionErr.Error())
}

bundleChunksVal := tree.DNull
if len(bundle) != 0 {
// Insert the bundle into system.statement_bundle_chunks.
// TODO(radu): split in chunks.
bundleChunksVal := tree.NewDArray(types.Int)
for len(bundle) > 0 {
chunk := bundle
if len(chunk) > bundleChunkSize {
chunk = chunk[:bundleChunkSize]
}
bundle = bundle[len(chunk):]

// Insert the chunk into system.statement_bundle_chunks.
row, err := r.ie.QueryRowEx(
ctx, "stmt-bundle-chunks-insert", txn,
sqlbase.InternalExecutorSessionDataOverride{User: security.RootUser},
"INSERT INTO system.statement_bundle_chunks(description, data) VALUES ($1, $2) RETURNING id",
"statement diagnostics bundle",
tree.NewDBytes(tree.DBytes(bundle)),
tree.NewDBytes(tree.DBytes(chunk)),
)
if err != nil {
return err
}
chunkID := row[0].(*tree.DInt)

array := tree.NewDArray(types.Int)
if err := array.Append(chunkID); err != nil {
if err := bundleChunksVal.Append(chunkID); err != nil {
return err
}
bundleChunksVal = array
}

collectionTime := timeutil.Now()
Expand Down

0 comments on commit 306eabc

Please sign in to comment.