Skip to content

Commit

Permalink
feat: add api end point to print the current database state
Browse files Browse the repository at this point in the history
Signed-off-by: Manan Gupta <[email protected]>
  • Loading branch information
GuptaManan100 committed Mar 14, 2024
1 parent d1d1901 commit d564200
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 1 deletion.
10 changes: 10 additions & 0 deletions go/test/endtoend/vtorc/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ func TestAPIEndpoints(t *testing.T) {
return response != "null"
})

t.Run("Database State", func(t *testing.T) {
// Get database state
status, resp, err := utils.MakeAPICall(t, vtorc, "/api/database-state")
require.NoError(t, err)
assert.Equal(t, 200, status)
assert.Contains(t, resp, "alias:{zone1-0000000101 true}")
assert.Contains(t, resp, `Table vitess_keyspace
map[durability_policy:{none true} keyspace:{ks true} keyspace_type:{0 true}]`)
})

t.Run("Disable Recoveries API", func(t *testing.T) {
// Disable recoveries of VTOrc
status, resp, err := utils.MakeAPICall(t, vtorc, "/api/disable-global-recoveries")
Expand Down
22 changes: 22 additions & 0 deletions go/vt/vtorc/db/generate_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@

package db

var TableNames = []string{
"database_instance",
"audit",
"active_node",
"node_health",
"topology_recovery",
"database_instance_topology_history",
"candidate_database_instance",
"topology_failure_detection",
"blocked_topology_recovery",
"database_instance_last_analysis",
"database_instance_analysis_changelog",
"node_health_history",
"vtorc_db_deployments",
"global_recovery_disable",
"topology_recovery_steps",
"database_instance_stale_binlog_coordinates",
"vitess_tablet",
"vitess_keyspace",
"vitess_shard",
}

// vtorcBackend is a list of SQL statements required to build the vtorc backend
var vtorcBackend = []string{
`
Expand Down
17 changes: 17 additions & 0 deletions go/vt/vtorc/inst/instance_dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -1210,3 +1210,20 @@ func ExpireStaleInstanceBinlogCoordinates() error {
}
return ExecDBWriteFunc(writeFunc)
}

// SnapshotDatabaseState takes the snapshot of the database and returns it.
func SnapshotDatabaseState() (string, error) {
var finalOutput string
for _, tableName := range db.TableNames {
finalOutput += "Table " + tableName + "\n"
err := db.QueryVTOrc("select * from "+tableName, nil, func(rowMap sqlutils.RowMap) error {
finalOutput += fmt.Sprintf("%v\n", rowMap)
return nil
})
if err != nil {
return "", err
}
finalOutput += "\n"
}
return finalOutput, nil
}
16 changes: 16 additions & 0 deletions go/vt/vtorc/inst/instance_dao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -746,3 +746,19 @@ func waitForCacheInitialization() {
time.Sleep(100 * time.Millisecond)
}
}

func TestSnapshotDatabaseState(t *testing.T) {
// Clear the database after the test. The easiest way to do that is to run all the initialization commands again.
defer func() {
db.ClearVTOrcDatabase()
}()

for _, query := range initialSQL {
_, err := db.ExecVTOrc(query)
require.NoError(t, err)
}

snapshot, err := SnapshotDatabaseState()
require.NoError(t, err)
require.Contains(t, snapshot, `alias:{zone1-0000000112 true}`)
}
16 changes: 15 additions & 1 deletion go/vt/vtorc/server/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (
disableGlobalRecoveriesAPI = "/api/disable-global-recoveries"
enableGlobalRecoveriesAPI = "/api/enable-global-recoveries"
replicationAnalysisAPI = "/api/replication-analysis"
databaseStateAPI = "/api/database-state"
healthAPI = "/debug/health"
AggregatedDiscoveryMetricsAPI = "/api/aggregated-discovery-metrics"

Expand All @@ -60,6 +61,7 @@ var (
disableGlobalRecoveriesAPI,
enableGlobalRecoveriesAPI,
replicationAnalysisAPI,
databaseStateAPI,
healthAPI,
AggregatedDiscoveryMetricsAPI,
}
Expand All @@ -86,6 +88,8 @@ func (v *vtorcAPI) ServeHTTP(response http.ResponseWriter, request *http.Request
errantGTIDsAPIHandler(response, request)
case replicationAnalysisAPI:
replicationAnalysisAPIHandler(response, request)
case databaseStateAPI:
databaseStateAPIHandler(response)
case AggregatedDiscoveryMetricsAPI:
AggregatedDiscoveryMetricsAPIHandler(response, request)
default:
Expand All @@ -104,7 +108,7 @@ func getACLPermissionLevelForAPI(apiEndpoint string) string {
return acl.ADMIN
case replicationAnalysisAPI:
return acl.MONITORING
case healthAPI:
case healthAPI, databaseStateAPI:
return acl.MONITORING
}
return acl.ADMIN
Expand Down Expand Up @@ -166,6 +170,16 @@ func errantGTIDsAPIHandler(response http.ResponseWriter, request *http.Request)
returnAsJSON(response, http.StatusOK, instances)
}

// databaseStateAPIHandler is the handler for the databaseStateAPI endpoint
func databaseStateAPIHandler(response http.ResponseWriter) {
snapshot, err := inst.SnapshotDatabaseState()
if err != nil {
http.Error(response, err.Error(), http.StatusInternalServerError)
return
}
writePlainTextResponse(response, snapshot, http.StatusOK)
}

// AggregatedDiscoveryMetricsAPIHandler is the handler for the discovery metrics endpoint
func AggregatedDiscoveryMetricsAPIHandler(response http.ResponseWriter, request *http.Request) {
// return metrics for last x seconds
Expand Down

0 comments on commit d564200

Please sign in to comment.