Skip to content

Conversation

@cyyynthia
Copy link

Uses the schema proposed in #455, with a built-in upgrade script which makes the change transparent (and avoiding the breaking change). I added a test case to ensure the upgrade code does what it's supposed to do.

fix: #455

I also added the mention of Scylla on the README, since this tool has been working like a charm for it on my end 🎉 (not really surprising since it aims to be a drop-in Cassandra replacement)

@coveralls
Copy link

coveralls commented Mar 1, 2021

Pull Request Test Coverage Report for Build 153

  • 28 of 47 (59.57%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.1%) to 56.212%

Changes Missing Coverage Covered Lines Changed/Added Lines %
database/cassandra/cassandra.go 28 47 59.57%
Totals Coverage Status
Change from base Build 143: 0.1%
Covered Lines: 3149
Relevant Lines: 5602

💛 - Coveralls

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

Honestly, this would be a lot simpler if the db drivers used migrate to manage the schema versions... But that's a lot more work. e.g. figure out how to store the schema versions for the schema versions...

This approach is fine for now but isn't sustainable if the schema versions table continues to evolve.

* [Redshift](database/redshift)
* [Ql](database/ql)
* [Cassandra](database/cassandra)
* [Cassandra/ Scylla](database/cassandra)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the mention of scylla unless there are tests against it.

Copy link
Author

@cyyynthia cyyynthia Mar 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this would be fine since MariaDB is also mentioned despite not being tested as of now; I'll add tests

return &database.Error{OrigErr: err, Query: []byte(query)}
}
} else {
query := `DELETE FROM "` + c.config.MigrationsTable + `" WHERE dummy = 1`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to reproduce the original behavior of the TRUNCATE that were present before, which would have left the database empty if the condition wasn't met

query := `SELECT version, dirty FROM "` + c.config.MigrationsTable + `" LIMIT 1`
if err = c.session.Query(query).Scan(&version, &dirty); err != nil {
if err == gocql.ErrNotFound {
skip = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgrades should only be performed when we detect that an upgrade is needed.

Given that, we should error on attempted schema upgrade failures. e.g. failing to fetch the previous applied migration version & status when upgrading the cassandra schema table is a stopping error condition

Also, the previous version and status should be logged so subsequent failures can be manually recovered.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

failing to fetch the previous applied migration version

Given the previous implementation, the table may have been left in an empty state since the table is always emptied when SetVersion is called, but only filled back if a condition is met (and if it is not, no error is returned). This is why I don't error if it can't find previous version and instead just skip adding back the data

Also, the previous version and status should be logged so subsequent failures can be manually recovered.

That's a valid point, I'll add some logging

})
}

func TestSchemaVersionV2Migration(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding a test!
Also add a test for the case where upgradeVersionTable() is a noop.

}
if _, _, err = c.Version(); err != nil {
var count int8
err = c.session.Query(`SELECT COUNT(*) FROM system_schema.columns WHERE keyspace_name = '` + c.config.KeyspaceName + `' AND table_name = '` + c.config.MigrationsTable + `' AND column_name = 'dummy'`).Scan(&count)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not move this into createVersionTable() and make createVersionTable() call upgradeVersionTable()?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've put it here so in normal circumstances, this query is only performed if there is an error (which might indicate the table needs an update). Moving this in createVersionTable would mean there'd always be 2 calls done instead of 1

@cyyynthia
Copy link
Author

Honestly, this would be a lot simpler if the db drivers used migrate to manage the schema versions... But that's a lot more work. e.g. figure out how to store the schema versions for the schema versions...

I think there'd still be a catch in this case, as we are changing the primary key which requires dropping the table and building it back, and hold previous data in memory so we can insert it back, so it would most likely need specific code at some point anyway.

@mkorolyov
Copy link
Contributor

@dhui Hi, would you merge this PR if I will prepare scylladb tests as you asked above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve schema of cassandra version table

4 participants