Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VTOrc: Update the primary key for all the tables from hostname, port to alias #13243

Merged
merged 21 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
dd2d727
feat: remove unused code and rename orchestrator file
GuptaManan100 Jun 6, 2023
514357a
feat: remove code for hostname resolution since it is unrequired
GuptaManan100 Jun 6, 2023
14a7980
feat: remove more unused code and tables
GuptaManan100 Jun 6, 2023
bcaecb9
feat: remove database_instance_downtime from VTOrc as we weren't inse…
GuptaManan100 Jun 6, 2023
f4c0431
feat: get rid of group replication information that isn't required
GuptaManan100 Jun 13, 2023
d26b242
feat: fix bugs
GuptaManan100 Jun 14, 2023
9b85890
test: fix insert queries for test
GuptaManan100 Jun 14, 2023
06e4026
feat: introduce alias in all the tables and use it as the primary key…
GuptaManan100 Jun 15, 2023
d49b36e
Merge remote-tracking branch 'upstream/main' into vtorc-alias-primary…
GuptaManan100 Jun 15, 2023
72affbf
feat: fix all the unit tests
GuptaManan100 Jun 15, 2023
a2ed8e6
feat: fix end to end test expectations
GuptaManan100 Jun 15, 2023
6f27c67
feat: remove unused parameters
GuptaManan100 Jun 16, 2023
0e2c037
feat: add test for auditInstanceAnalysisInChangelog
GuptaManan100 Jun 16, 2023
33d1369
test: augment test to also verify reading of audit operations works a…
GuptaManan100 Jun 16, 2023
3885b63
feat: remove generics code in VTOrc around durability policies since …
GuptaManan100 Jun 16, 2023
1929395
feat: add tests for more functions changed in this PR
GuptaManan100 Jun 16, 2023
347dc87
feat: refactor forgetting instance code a little and add tests for it
GuptaManan100 Jun 16, 2023
e574ccb
feat: fix snapshot topologies code and add test for it
GuptaManan100 Jun 16, 2023
6c45fe4
test: add tests for savetablet and readtablet
GuptaManan100 Jun 16, 2023
703da07
feat: fix remaining tests
GuptaManan100 Jun 16, 2023
05bf273
feat: fix comment
GuptaManan100 Jun 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions go/vt/vtorc/inst/analysis_dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,11 @@ import (
"github.com/rcrowley/go-metrics"
)

var analysisChangeWriteAttemptCounter = metrics.NewCounter()
var analysisChangeWriteCounter = metrics.NewCounter()

var recentInstantAnalysis *cache.Cache

func init() {
_ = metrics.Register("analysis.change.write.attempt", analysisChangeWriteAttemptCounter)
_ = metrics.Register("analysis.change.write", analysisChangeWriteCounter)

go initializeAnalysisDaoPostConfiguration()
Expand Down Expand Up @@ -611,11 +609,8 @@ func auditInstanceAnalysisInChangelog(tabletAlias string, analysisCode AnalysisC
return nil
}
}
// Passed the cache; but does database agree that there's a change? Here's a persistent cache; this comes here
// to verify no two vtorc services are doing this without coordinating (namely, one dies, the other taking its place
// and has no familiarity of the former's cache)
analysisChangeWriteAttemptCounter.Inc(1)

// Find if the lastAnalysisHasChanged or not while updating the row if it has.
lastAnalysisChanged := false
{
sqlResult, err := db.ExecVTOrc(`
Expand All @@ -637,10 +632,15 @@ func auditInstanceAnalysisInChangelog(tabletAlias string, analysisCode AnalysisC
log.Error(err)
return err
}
lastAnalysisChanged = (rows > 0)
lastAnalysisChanged = rows > 0
}

// If the last analysis has not changed, then there is a chance that this is the first insertion.
// We need to find that out too when we insert into the database.
firstInsertion := false
if !lastAnalysisChanged {
_, err := db.ExecVTOrc(`
// The insert only returns more than 1 row changed if this is the first insertion.
sqlResult, err := db.ExecVTOrc(`
insert ignore into database_instance_last_analysis (
alias, analysis_timestamp, analysis
) values (
Expand All @@ -653,9 +653,16 @@ func auditInstanceAnalysisInChangelog(tabletAlias string, analysisCode AnalysisC
log.Error(err)
return err
}
rows, err := sqlResult.RowsAffected()
if err != nil {
log.Error(err)
return err
}
firstInsertion = rows > 0
}
recentInstantAnalysis.Set(tabletAlias, analysisCode, cache.DefaultExpiration)
if !lastAnalysisChanged {
// If the analysis has changed or if it is the first insertion, we need to make sure we write this change to the database.
if !lastAnalysisChanged && !firstInsertion {
return nil
}

Expand Down
75 changes: 75 additions & 0 deletions go/vt/vtorc/inst/analysis_dao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ package inst

import (
"testing"
"time"

"github.com/patrickmn/go-cache"
"github.com/rcrowley/go-metrics"
"github.com/stretchr/testify/require"

"vitess.io/vitess/go/vt/external/golib/sqlutils"
Expand Down Expand Up @@ -672,3 +675,75 @@ func TestGetReplicationAnalysis(t *testing.T) {
})
}
}

// TestAuditInstanceAnalysisInChangelog tests the functionality of the auditInstanceAnalysisInChangelog function
// and verifies that we write the correct amount of times to the database.
GuptaManan100 marked this conversation as resolved.
Show resolved Hide resolved
func TestAuditInstanceAnalysisInChangelog(t *testing.T) {
tests := []struct {
name string
cacheExpiration time.Duration
}{
{
name: "Long expiration",
cacheExpiration: 2 * time.Minute,
}, {
name: "Very short expiration",
cacheExpiration: 100 * time.Millisecond,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create the cache for the test to use.
oldRecentInstantAnalysisCache := recentInstantAnalysis
oldAnalysisChangeWriteCounter := analysisChangeWriteCounter

recentInstantAnalysis = cache.New(tt.cacheExpiration, 100*time.Millisecond)
analysisChangeWriteCounter = metrics.NewCounter()

defer func() {
// Set the old values back.
recentInstantAnalysis = oldRecentInstantAnalysisCache
analysisChangeWriteCounter = oldAnalysisChangeWriteCounter
// Each test should clear the database. The easiest way to do that is to run all the initialization commands again.
db.ClearVTOrcDatabase()
}()

updates := []struct {
tabletAlias string
analysisCode AnalysisCode
writeCounterExpectation int
wantErr string
}{
{
// Store a new analysis for the zone1-100 tablet.
tabletAlias: "zone1-100",
analysisCode: ReplicationStopped,
writeCounterExpectation: 1,
}, {
// Write the same analysis, no new write should happen.
tabletAlias: "zone1-100",
analysisCode: ReplicationStopped,
writeCounterExpectation: 1,
}, {
// Change the analysis. This should trigger an update.
tabletAlias: "zone1-100",
analysisCode: ReplicaSemiSyncMustBeSet,
writeCounterExpectation: 2,
},
}

for _, upd := range updates {
// We sleep 200 milliseconds to make sure that the cache has had time to update.
// It should be able to delete entries if the expiration is less than 200 milliseconds.
time.Sleep(200 * time.Millisecond)
err := auditInstanceAnalysisInChangelog(upd.tabletAlias, upd.analysisCode)
if upd.wantErr != "" {
require.EqualError(t, err, upd.wantErr)
continue
}
require.NoError(t, err)
require.EqualValues(t, upd.writeCounterExpectation, analysisChangeWriteCounter.Count())
}
})
}
}