Skip to content

Commit b055fda

Browse files
committed
feat: add reading of transaction info file
Signed-off-by: Andres Taylor <andres@planetscale.com>
1 parent 2b86f61 commit b055fda

5 files changed

Lines changed: 93 additions & 37 deletions

File tree

go/summarize/reading.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/vitessio/vt/go/keys"
2626
"github.com/vitessio/vt/go/schema"
27+
"github.com/vitessio/vt/go/transactions"
2728
)
2829

2930
func readTracedFile(fileName string) traceSummary {
@@ -60,6 +61,27 @@ func readTracedFile(fileName string) traceSummary {
6061
}
6162
}
6263

64+
func readTransactionFile(fileName string) func(s *Summary) error {
65+
c, err := os.ReadFile(fileName)
66+
if err != nil {
67+
exit("Error opening file: " + err.Error())
68+
}
69+
70+
type txOutput struct {
71+
FileType string `json:"fileType"`
72+
Signatures []transactions.Signature `json:"signatures"`
73+
}
74+
75+
var to txOutput
76+
err = json.Unmarshal(c, &to)
77+
if err != nil {
78+
exit("Error parsing json: " + err.Error())
79+
}
80+
return func(*Summary) error {
81+
return nil
82+
}
83+
}
84+
6385
func readKeysFile(fileName string) func(s *Summary) error {
6486
c, err := os.ReadFile(fileName)
6587
if err != nil {

go/summarize/reading_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2024 The Vitess Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package summarize
18+
19+
import (
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
)
24+
25+
func TestReadTransaction(t *testing.T) {
26+
file := readTransactionFile("../testdata/small-slow-query-transactions.json")
27+
assert.NotNil(t, file)
28+
}

go/summarize/summarize.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,15 @@ func Run(files []string, hotMetric string) {
6161
var workers []summaryWorker
6262

6363
for _, file := range files {
64-
typ, _ := getFileType(file)
64+
typ, err := getFileType(file)
65+
if err != nil {
66+
panic(err.Error())
67+
}
6568
switch typ {
6669
case dbInfoFile:
6770
workers = append(workers, readDBInfoFile(file))
6871
case transactionFile:
69-
fmt.Printf("transaction file: %s\n", file)
72+
workers = append(workers, readTransactionFile(file))
7073
case traceFile:
7174
traces = append(traces, readTracedFile(file))
7275
case keysFile:
@@ -76,16 +79,22 @@ func Run(files []string, hotMetric string) {
7679
}
7780
}
7881

79-
checkTraceConditions(traces, workers, hotMetric)
80-
81-
if len(traces) == 2 {
82-
compareTraces(os.Stdout, terminalWidth(), highlightQuery, traces[0], traces[1])
82+
traceCount := len(traces)
83+
if traceCount <= 0 {
84+
printSummary(hotMetric, workers)
8385
return
84-
} else if len(traces) == 1 {
86+
}
87+
88+
checkTraceConditions(traces, workers, hotMetric)
89+
switch traceCount {
90+
case 1:
8591
printTraceSummary(os.Stdout, terminalWidth(), highlightQuery, traces[0])
86-
return
92+
case 2:
93+
compareTraces(os.Stdout, terminalWidth(), highlightQuery, traces[0], traces[1])
8794
}
95+
}
8896

97+
func printSummary(hotMetric string, workers []summaryWorker) {
8998
s := NewSummary(hotMetric)
9099
for _, worker := range workers {
91100
err := worker(s)
@@ -134,9 +143,6 @@ func (s *Summary) AddTable(table *TableSummary) {
134143
}
135144

136145
func checkTraceConditions(traces []traceSummary, workers []summaryWorker, hotMetric string) {
137-
if len(traces) == 0 {
138-
return
139-
}
140146
if len(workers) > 0 {
141147
panic("Trace files cannot be mixed with other file types")
142148
}

go/transactions/transaction_signature.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ import (
2828
)
2929

3030
type (
31-
TxSignature struct {
32-
Count int `json:"count"`
33-
Queries []TxQuery `json:"qqueries"`
31+
Signature struct {
32+
Count int `json:"count"`
33+
Queries []Query `json:"qqueries"`
3434
}
3535

36-
TxQuery struct {
36+
Query struct {
3737
Op string `json:"op"`
3838
AffectedTable string `json:"affected_table"`
3939
UpdatedColumns []string `json:"updated_columns,omitempty"`
4040
Predicates []predicateInfo `json:"predicates,omitempty"`
4141
}
4242

4343
txSignatureMap struct {
44-
data map[uint64][]*TxSignature
44+
data map[uint64][]*Signature
4545
}
4646

4747
predicateInfo struct {
@@ -60,17 +60,17 @@ func (pi predicateInfo) String() string {
6060
return fmt.Sprintf("%s.%s %s %s", pi.Table, pi.Col, pi.Op.ToString(), val)
6161
}
6262

63-
func (tx *TxSignature) MarshalJSON() ([]byte, error) {
63+
func (tx *Signature) MarshalJSON() ([]byte, error) {
6464
return json.Marshal(struct {
65-
Count int `json:"count"`
66-
Queries []TxQuery `json:"query-signatures"`
65+
Count int `json:"count"`
66+
Queries []Query `json:"query-signatures"`
6767
}{
6868
Count: tx.Count,
6969
Queries: tx.Queries,
7070
})
7171
}
7272

73-
func (tx *TxSignature) Hash64() uint64 {
73+
func (tx *Signature) Hash64() uint64 {
7474
hasher := fnv.New64a()
7575

7676
for _, query := range tx.Queries {
@@ -80,7 +80,7 @@ func (tx *TxSignature) Hash64() uint64 {
8080
return hasher.Sum64()
8181
}
8282

83-
func (tx TxQuery) addToHash(hash hash.Hash64) {
83+
func (tx Query) addToHash(hash hash.Hash64) {
8484
_, _ = hash.Write([]byte(tx.Op))
8585
_, _ = hash.Write([]byte{0})
8686
_, _ = hash.Write([]byte(tx.AffectedTable))
@@ -97,7 +97,7 @@ func (tx TxQuery) addToHash(hash hash.Hash64) {
9797
}
9898
}
9999

100-
func (tx TxQuery) Equals(other TxQuery) bool {
100+
func (tx Query) Equals(other Query) bool {
101101
if tx.Op != other.Op {
102102
return false
103103
}
@@ -125,19 +125,19 @@ func (tx TxQuery) Equals(other TxQuery) bool {
125125

126126
func newTxSignatureMap() *txSignatureMap {
127127
return &txSignatureMap{
128-
data: make(map[uint64][]*TxSignature),
128+
data: make(map[uint64][]*Signature),
129129
}
130130
}
131131

132-
func (m *txSignatureMap) Add(tx *TxSignature) {
132+
func (m *txSignatureMap) Add(tx *Signature) {
133133
hash := tx.Hash64()
134134

135135
bucket, exists := m.data[hash]
136136

137137
// Check if the hash already exists
138138
if !exists {
139139
tx.Count = 1
140-
m.data[hash] = []*TxSignature{tx}
140+
m.data[hash] = []*Signature{tx}
141141
return
142142
}
143143

@@ -153,7 +153,7 @@ func (m *txSignatureMap) Add(tx *TxSignature) {
153153
m.data[hash] = append(bucket, tx)
154154
}
155155

156-
func (tx *TxSignature) Equals(other *TxSignature) bool {
156+
func (tx *Signature) Equals(other *Signature) bool {
157157
if len(tx.Queries) != len(other.Queries) {
158158
return false
159159
}
@@ -167,7 +167,7 @@ func (tx *TxSignature) Equals(other *TxSignature) bool {
167167
}
168168

169169
// CleanUp removes values that are only used once and replaces them with -1
170-
func (tx *TxSignature) CleanUp() *TxSignature {
170+
func (tx *Signature) CleanUp() *Signature {
171171
usedValues := make(map[int]int)
172172

173173
// First let's count how many times each value is used
@@ -180,7 +180,7 @@ func (tx *TxSignature) CleanUp() *TxSignature {
180180
// Now we replace values only used once with -1
181181
newCount := 0
182182
newValues := make(map[int]int)
183-
newQueries := make([]TxQuery, 0, len(tx.Queries))
183+
newQueries := make([]Query, 0, len(tx.Queries))
184184
for _, query := range tx.Queries {
185185
newPredicates := make([]predicateInfo, 0, len(query.Predicates))
186186
for _, predicate := range query.Predicates {
@@ -198,23 +198,23 @@ func (tx *TxSignature) CleanUp() *TxSignature {
198198
}
199199
newPredicates = append(newPredicates, predicate)
200200
}
201-
newQueries = append(newQueries, TxQuery{
201+
newQueries = append(newQueries, Query{
202202
Op: query.Op,
203203
AffectedTable: query.AffectedTable,
204204
UpdatedColumns: query.UpdatedColumns,
205205
Predicates: newPredicates,
206206
})
207207
}
208208

209-
return &TxSignature{
209+
return &Signature{
210210
Queries: newQueries,
211211
Count: tx.Count,
212212
}
213213
}
214214

215215
func (m *txSignatureMap) MarshalJSON() ([]byte, error) {
216216
// Collect all interesting TxSignatures into a slice
217-
var signatures []*TxSignature
217+
var signatures []*Signature
218218
for _, bucket := range m.data {
219219
for _, txSig := range bucket {
220220
if txSig.Count > 1 {

go/transactions/transactions.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func (s *state) consume(ch <-chan []sqlparser.Statement, wg *sync.WaitGroup) {
204204
defer wg.Done()
205205
for queries := range ch {
206206
n := &normalizer{m: make(map[string]int)}
207-
tx := &TxSignature{}
207+
tx := &Signature{}
208208
for _, query := range queries {
209209
st, err := semantics.Analyze(query, "ks", s.si)
210210
if err != nil {
@@ -222,7 +222,7 @@ func (s *state) consume(ch <-chan []sqlparser.Statement, wg *sync.WaitGroup) {
222222
}
223223
}
224224

225-
func (s *state) consumeUpdate(query *sqlparser.Update, st *semantics.SemTable, n *normalizer, tx *TxSignature) {
225+
func (s *state) consumeUpdate(query *sqlparser.Update, st *semantics.SemTable, n *normalizer, tx *Signature) {
226226
// Find all predicates in the where clause that use a column and a literal
227227
var predicates []predicateInfo
228228
if query.Where != nil {
@@ -239,15 +239,15 @@ func (s *state) consumeUpdate(query *sqlparser.Update, st *semantics.SemTable, n
239239
panic("multi-table updates not supported")
240240
}
241241

242-
tx.Queries = append(tx.Queries, TxQuery{
242+
tx.Queries = append(tx.Queries, Query{
243243
Op: "update",
244244
AffectedTable: sqlparser.String(query.TableExprs[0]),
245245
UpdatedColumns: updatedColumns,
246246
Predicates: predicates,
247247
})
248248
}
249249

250-
func (s *state) consumeDelete(del *sqlparser.Delete, st *semantics.SemTable, n *normalizer, tx *TxSignature) {
250+
func (s *state) consumeDelete(del *sqlparser.Delete, st *semantics.SemTable, n *normalizer, tx *Signature) {
251251
var predicates []predicateInfo
252252
if del.Where != nil {
253253
predicates = getPredicates(del.Where.Expr, st, n)
@@ -257,14 +257,14 @@ func (s *state) consumeDelete(del *sqlparser.Delete, st *semantics.SemTable, n *
257257
panic("multi-table updates not supported")
258258
}
259259

260-
tx.Queries = append(tx.Queries, TxQuery{
260+
tx.Queries = append(tx.Queries, Query{
261261
Op: "delete",
262262
AffectedTable: sqlparser.String(del.TableExprs[0]),
263263
Predicates: predicates,
264264
})
265265
}
266266

267-
func (s *state) addSignature(tx *TxSignature) {
267+
func (s *state) addSignature(tx *Signature) {
268268
s.mu.Lock()
269269
defer s.mu.Unlock()
270270

0 commit comments

Comments
 (0)