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

parser, executor: consistently lower identity hostnames #33172

Merged
merged 23 commits into from May 25, 2022

Conversation

morgo
Copy link
Contributor

@morgo morgo commented Mar 16, 2022

What problem does this PR solve?

Issue Number: close #33061

Problem Summary:

MySQL always stores the hostname portion of a user identity in lower case (whether it be for a user or a role). It doesn't depend on collations - manual inspection of the tables shows it is lower.

What is changed and how it works?

We have previously implemented this correctly for user grants, and inconsistently for roles. But this is challenging because it requires adjustment in many cases.

This PR takes a different approach where the host portion is lowered in the parser, and then executed in TiDB in lower case. Previous usage of lower casing in the code have been reverted (since it will always be lower).

I have added the tag for compatibility breaker, since it does not modify existing roles or hosts that are in the incorrect case. I considered writing a bootstrap task to fix this (see below) but opted against it because I think it's too destructive to modify user data without their interaction. It should instead be mentioned in the release notes.

--- a/session/bootstrap.go
+++ b/session/bootstrap.go
@@ -583,11 +583,13 @@ const (
        version84 = 84
        // version85 updates bindings with status 'using' in mysql.bind_info table to 'enabled' status
        version85 = 85
+       // version 86 consistently fixes hostnames in privilege tables to lowercase.
+       version86 = 86
 )
 
 // currentBootstrapVersion is defined as a variable, so we can modify its value for testing.
 // please make sure this is the largest version
-var currentBootstrapVersion int64 = version84
+var currentBootstrapVersion int64 = version86
 
 var (
        bootstrapVersion = []func(Session, int64){
@@ -676,6 +678,7 @@ var (
                upgradeToVer83,
                upgradeToVer84,
                upgradeToVer85,
+               upgradeToVer86,
        }
 )
 
@@ -1752,6 +1755,18 @@ func upgradeToVer85(s Session, ver int64) {
        mustExecute(s, fmt.Sprintf("UPDATE HIGH_PRIORITY mysql.bind_info SET status= '%s' WHERE status = '%s'", bindinfo.Enabled, bindinfo.Using))
 }
 
+func upgradeToVer86(s Session, ver int64) {
+       if ver >= version86 {
+               return
+       }
+       mustExecute(s, "UPDATE HIGH_PRIORITY mysql.user SET host = lower(host)")
+       mustExecute(s, "UPDATE HIGH_PRIORITY mysql.db SET host = lower(host)")
+       mustExecute(s, "UPDATE HIGH_PRIORITY mysql.default_roles SET host = lower(host)")
+       mustExecute(s, "UPDATE HIGH_PRIORITY mysql.global_grants SET host = lower(host)")
+       mustExecute(s, "UPDATE HIGH_PRIORITY mysql.global_priv SET host = lower(host)")
+       mustExecute(s, "UPDATE HIGH_PRIORITY mysql.role_edges SET from_host = lower(from_host), to_host = lower(to_host)")
+}

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No code

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

TiDB now consistently lower cases the hostname portion of user accounts and roles during statement parsing. This behavior is more consistent with MySQL, but might lead to unexpected behaviors if accounts had previously been created with hostnames using upper case characters.

@morgo morgo added the compatibility-breaker Violation of forwards/backwards compatibility in a design-time piece. label Mar 16, 2022
@ti-chi-bot
Copy link
Member

ti-chi-bot commented Mar 16, 2022

[REVIEW NOTIFICATION]

This pull request has been approved by:

  • dveeden
  • mjonss

To complete the pull request process, please ask the reviewers in the list to review by filling /cc @reviewer in the comment.
After your PR has acquired the required number of LGTMs, you can assign this pull request to the committer in the list by filling /assign @committer in the comment to help you merge this pull request.

The full list of commands accepted by this bot can be found here.

Reviewer can indicate their review by submitting an approval review.
Reviewer can cancel approval by submitting a request changes review.

@ti-chi-bot ti-chi-bot added do-not-merge/needs-triage-completed release-note size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Mar 16, 2022
@sre-bot
Copy link
Contributor

sre-bot commented Mar 16, 2022

@morgo
Copy link
Contributor Author

morgo commented Mar 22, 2022

/check-issue-triage-complete

@morgo
Copy link
Contributor Author

morgo commented Mar 22, 2022

/run-unit-test

@dveeden
Copy link
Contributor

dveeden commented Mar 24, 2022

The list of the tables in upgradeToVer86 in the description might not be complete:

mysql> SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.columns WHERE COLUMN_NAME COLLATE utf8mb4_general_ci LIKE '%host' AND TABLE_SCHEMA='mysql' ORDER BY
TABLE_NAME;
+---------------+-------------------+
| TABLE_NAME    | COLUMN_NAME       |
+---------------+-------------------+
| columns_priv  | Host              |
| db            | Host              |
| default_roles | HOST              |
| default_roles | DEFAULT_ROLE_HOST |
| global_grants | HOST              |
| global_priv   | Host              |
| role_edges    | FROM_HOST         |
| role_edges    | TO_HOST           |
| tables_priv   | Host              |
| user          | Host              |
+---------------+-------------------+
10 rows in set (0.13 sec)

@ti-chi-bot ti-chi-bot added the status/LGT1 Indicates that a PR has LGTM 1. label Mar 24, 2022
@morgo
Copy link
Contributor Author

morgo commented Apr 11, 2022

The list of the tables in upgradeToVer86 in the description might not be complete:

Yeah, I think that's OK. I said I considered doing this but elected not to since it could create issues modifying user data.

@morgo morgo requested a review from mjonss April 14, 2022 04:41
Copy link
Contributor

@mjonss mjonss left a comment

Choose a reason for hiding this comment

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

Will this also work with prepared statements (both binary and SQL statement interface)?

Also could you give an example of unexpected behaviour?

But still looks good to me :)

@ti-chi-bot ti-chi-bot added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels Apr 14, 2022
@tiancaiamao
Copy link
Contributor

/merge

@morgo
Copy link
Contributor Author

morgo commented May 25, 2022

/run-mysql-test

@morgo
Copy link
Contributor Author

morgo commented May 25, 2022

There's something wrong with the mysql-test. The new result file has been merged to master, but it's expecting the old values:

[2022-05-25T00:35:37.788Z] time="2022-05-25T08:35:33+08:00" level=error msg="run test [role] err: sql:SELECT * FROM mysql.role_edges order by FROM_USER;: failed to run query \n\"SELECT * FROM mysql.role_edges order by FROM_USER;\" \n around line 166, \nwe need(284):\nSELECT * FROM mysql.role_edges order by FROM_USER;\nFROM_HOST\tFROM_USER\tTO_HOST\tTO_USER\tWITH_ADMIN_OPTION\n%\tconsultants\t%\tjoan\tN\n%\tconsultants\t%\tsally\tN\n%\tengineering\t%\tsally\tN\nUS\tengineering\tINDIA\tengineering\tN\n%\tqa\t%\tconsultants\tN\n%\trole\t%\troot\tN\n%\twp_administrators\tlocalhost\tjoe\tN\n\nbut got(284):\nSELECT * FROM mysql.role_edges order by FROM_USER;\nFROM_HOST\tFROM_USER\tTO_HOST\tTO_USER\tWITH_ADMIN_OPTION\n%\tconsultants\t%\tjoan\tN\n%\tconsultants\t%\tsally\tN\n%\tengineering\t%\tsally\tN\nus\tengineering\tindia\tengineering\tN\n%\tqa\t%\tconsultants\tN\n%\trole\t%\troot\tN\n%\twp_administrators\tlocalhost\tjoe\tN\n\n"

@ti-chi-bot ti-chi-bot merged commit dce5064 into pingcap:master May 25, 2022
ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-4.0 in PR #34934

ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-5.0 in PR #34935

ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-5.1 in PR #34936

ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-5.2 in PR #34937

ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-5.3 in PR #34938

ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-5.4 in PR #34939

ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-6.0 in PR #34940

ti-srebot pushed a commit to ti-srebot/tidb that referenced this pull request May 25, 2022
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
@ti-srebot
Copy link
Contributor

cherry pick to release-6.1 in PR #34941

@sre-bot
Copy link
Contributor

sre-bot commented May 25, 2022

TiDB MergeCI notify

🔴 Bad News! [2] CI still failing after this pr merged.
These failed integration tests don't seem to be introduced by the current PR.

CI Name Result Duration Compare with Parent commit
idc-jenkins-ci-tidb/integration-common-test 🔴 failed 2, success 9, total 11 19 min Existing failure
idc-jenkins-ci-tidb/common-test 🔴 failed 2, success 10, total 12 7 min 40 sec Existing failure
idc-jenkins-ci/integration-cdc-test 🟢 all 34 tests passed 26 min Existing passed
idc-jenkins-ci-tidb/integration-ddl-test 🟢 all 6 tests passed 7 min 37 sec Existing passed
idc-jenkins-ci-tidb/sqllogic-test-1 🟢 all 26 tests passed 7 min 26 sec Existing passed
idc-jenkins-ci-tidb/sqllogic-test-2 🟢 all 28 tests passed 6 min 53 sec Existing passed
idc-jenkins-ci-tidb/tics-test 🟢 all 1 tests passed 6 min 14 sec Existing passed
idc-jenkins-ci-tidb/mybatis-test 🟢 all 1 tests passed 5 min 56 sec Existing passed
idc-jenkins-ci-tidb/integration-compatibility-test 🟢 all 1 tests passed 3 min 57 sec Existing passed
idc-jenkins-ci-tidb/plugin-test 🟢 build success, plugin test success 4min Existing passed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility-breaker Violation of forwards/backwards compatibility in a design-time piece. needs-cherry-pick-release-5.0 needs-cherry-pick-release-5.1 needs-cherry-pick-release-5.2 needs-cherry-pick-release-5.3 Type: Need cherry pick to release-5.3 needs-cherry-pick-release-5.4 Type: Need cherry pick to release-5.4 needs-cherry-pick-release-6.1 release-note size/M Denotes a PR that changes 30-99 lines, ignoring generated files. status/can-merge Indicates a PR has been approved by a committer. status/LGT2 Indicates that a PR has LGTM 2.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

inconsistent case insensitive behaviour with GRANT and SET ROLE hostnames.
7 participants