pt-query-digest review table privilege checks don't work
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Percona Toolkit moved to https://jira.percona.com/projects/PT |
Fix Released
|
Medium
|
Brian Fraser |
Bug Description
pt-query-digest reports an error about 'INSERT' privileges when the problem is missing DELETE privileges (related to bug 940421?)
# TableParser:8321 5635 Checking `maatkit`
# TableParser:8325 5635 SHOW TABLES FROM `maatkit` LIKE 'query\_review'
# TableParser:8339 5635 Table exists; no privs to check
# TableParser:8343 5635 SHOW FULL COLUMNS FROM `maatkit`
# TableParser:8358 5635 DELETE FROM `maatkit`
# TableParser:8364 5635 User privs on `maatkit`
# TableParser:8369 5635 User does not have all privs
The query review table `maatkit`
Related branches
- Daniel Nichter: Approve
-
Diff: 748 lines (+45/-509)14 files modifiedbin/pt-archiver (+2/-35)
bin/pt-duplicate-key-checker (+2/-35)
bin/pt-find (+2/-35)
bin/pt-heartbeat (+2/-35)
bin/pt-index-usage (+2/-35)
bin/pt-kill (+2/-35)
bin/pt-online-schema-change (+2/-35)
bin/pt-query-advisor (+2/-35)
bin/pt-query-digest (+17/-49)
bin/pt-table-checksum (+2/-35)
bin/pt-table-sync (+2/-35)
bin/pt-table-usage (+2/-35)
bin/pt-upgrade (+2/-35)
lib/TableParser.pm (+4/-40)
tags: | added: error-message privs pt-query-digest |
Changed in percona-toolkit: | |
status: | New → Triaged |
summary: |
- Confusing error with incorrect privileges pt-table-digest + Confusing error with incorrect privileges pt-query-digest |
Changed in percona-toolkit: | |
assignee: | nobody → Brian Fraser (fraserbn) |
Changed in percona-toolkit: | |
milestone: | none → 2.1.6 |
importance: | Undecided → Medium |
Changed in percona-toolkit: | |
status: | Triaged → In Progress |
summary: |
- Confusing error with incorrect privileges pt-query-digest + pt-query-digest review table privilege checks don't work |
Changed in percona-toolkit: | |
status: | In Progress → Fix Committed |
Changed in percona-toolkit: | |
status: | Fix Committed → Fix Released |
This privilege check doesn't work because there isn't a good way in MySQL to check what privileges you have on a table. The tool can't do what it's trying to do, and the only way to get the tool to run with --review is to comment out the privilege check in the code. Here's an example of what the tool will see when it runs the checks it's trying to do. First, the privileges:
mysql> show grants; ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ---+ ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ---+ 49E926E3DAA6037 7E5E0B3EEBC3' | ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ------- ---+
+------
| Grants for anemometer@% |
+------
| GRANT SUPER ON *.* TO 'anemometer'@'%' IDENTIFIED BY PASSWORD '*A350DA83CF711
| GRANT ALL PRIVILEGES ON `slow_query_log`.* TO 'anemometer'@'%' |
+------
I have only added SUPER because I have to add --set-vars= binlog_ format= row to avoid errors the server throws back otherwise. Anyway, you can see the tool has full privileges on the tables in the slow_query_log database. Now, the tool does this:
8253 return 1 unless $args{all_privs};
8254
8255 $sql = "SHOW FULL COLUMNS FROM $db_tbl";
This returns a table with rows like this:
mysql> show full columns from slow_query_ log.global_ query_review\ G ******* ******* ****** 1. row ******* ******* ******* ****** insert, update, references
*******
Field: checksum
Type: bigint(20) unsigned
Collation: NULL
Null: NO
Key: PRI
Default: NULL
Extra:
Privileges: select,
Comment:
So you can see the Privileges column doesn't include DELETE. This we already knew, because the tool handles this case:
8268 my $privs = $row->{privileges} || $row->{Privileges};
8269
8270 $sql = "DELETE FROM $db_tbl LIMIT 0";
8271 PTDEBUG && _d($sql);
8272 eval {
8273 $dbh->do($sql);
8274 };
8275 my $can_delete = $EVAL_ERROR ? 0 : 1;
The problem is, that DELETE FROM statement is going to throw an error like this:
mysql> delete from slow_query_ log.global_ query_review limit 0;
ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
That's the same error I'm adding the call to set the binlog_format to avoid. The tool isn't distinguishing this error from a lack of privileges to DELETE.
I think it's a losing game to play around with this; handling all the cases correctly (setting the transaction isolation level, maybe setting the SQL_MODE in some cases, setting the binlog format which requires SUPER) is going to just make the code a mess. In some tools we'll need different binlog formats and transaction isolation levels for specific purposes anyway.
I'd suggest to just skip the check, other than checking that the table exists. I know it will suck ...