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

sql/mysql_db: Rework how we store and access table data for users, grants and replica_source_info. #1904

Merged
merged 7 commits into from Jul 28, 2023

Conversation

reltuk
Copy link
Contributor

@reltuk reltuk commented Jul 26, 2023

In general, we keep the same structure of storing the data in structs, keyed in multimaps, and having converters for going to and from sql.Rows. We change the following important things:

  1. We more explicitly model a multimap and an indexed set of entities with multiple keyers.

  2. We add read and write locking around edits and reads of the data table.

  3. We explicitly do not expose the raw indexed set or multimap from the MySQLDb instance itself. The unprincipled access of the various *Data instances in the old implementation was somewhat problematic.

reltuk and others added 2 commits July 26, 2023 15:15
…ants and replica_source_info.

In general, we keep the same structure of storing the data in structs, keyed in
multimaps, and having converters for going to and from sql.Rows. We change the
following important things:

1) We more explicitly model a multimap and an indexed set of entities with
multiple keyers.

2) We add read and write locking around edits and reads of the data table.

3) We explicitly do not expose the raw indexed set or multimap from the MySQLDb
instance itself. The unprincipled access of the various *Data instances in the
old implementation was somewhat problematic.
Copy link
Contributor

@fulghum fulghum left a comment

Choose a reason for hiding this comment

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

Nice refactoring! I only had a couple very minor thoughts. Looks like a nice improvement to the mysqldb.

Comment on lines 32 to 35
// TODO: The management around closing this editor is sad. If you add
// an early exit before the Close after the GetUser below, make sure to
// close this editor.
ed := mysqlDb.Editor()
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it worth moving this line down to line 47ish, so that the editor open is closer to the ed.Close() call and less likely to have a return statement added in between? Seems like that would prevent you from needing to close it on line 43, too, unless I'm just missing something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm doing something kinda gross here where I'm using the Editor() to lock the access to Enabled as well. I will poke around to see how to change Enabled somehow to be more thread-safe.

}

func (is IndexedSet[V]) VisitEntries(f func(v V)) {
is.Indexes[0].VisitEntries(f)
Copy link
Contributor

Choose a reason for hiding this comment

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

It wasn't immediately obvious to me why why only iterate over the first element of Indexes. Is that because it's the primary index and we don't want to visit secondary indexes? Might be worth some godocs to explain why this function only looks at the first element of Indexes or maybe even a different name?

@@ -1201,23 +1200,37 @@ func schemaPrivilegesRowIter(ctx *Context, c Catalog) (RowIter, error) {
if !ok {
return nil, ErrDatabaseNotFound.New("mysql")
}

var keys []mysql_db.UserPrimaryKey
Copy link
Contributor

Choose a reason for hiding this comment

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

(super minor) might be nice to move this var declaration down to line 1210, so it's right by the code that populates the variable. (Took me an extra second to notice this was where the keys variable came from.)

@@ -1601,23 +1660,36 @@ func tablePrivilegesRowIter(ctx *Context, c Catalog) (RowIter, error) {
if !ok {
return nil, ErrDatabaseNotFound.New("mysql")
}

var keys []mysql_db.UserPrimaryKey
Copy link
Contributor

Choose a reason for hiding this comment

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

(super minor) similar comment; this var definition just felt a little "floaty" and would be nice to move it down to line 1670 so it's right before where the keys get populated.

@@ -664,33 +666,30 @@ func (n *GrantRole) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOp
//TODO: only active roles may be assigned if the SUPER privilege is not held
mysqlDb := n.MySQLDb.(*mysql_db.MySQLDb)
client := ctx.Session.Client()
user := mysqlDb.GetUser(client.User, client.Address, false)

// TODO: Locking
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there more locking needed here beyond what the reader encapsulates? I didn't understand concretely what this TODO was recommending.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was a stale comment from before we had locking! Good catch :D.

…tion location, how locking is done in some places. Make mysql_db.Enabled access thread-safe.
@reltuk reltuk merged commit 623d669 into main Jul 28, 2023
6 checks passed
@Hydrocharged Hydrocharged deleted the aaron/mysql_db-locking branch August 24, 2023 00:17
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.

None yet

2 participants