{"id":22870896,"url":"https://github.com/percona-lab/minimum_permissions","last_synced_at":"2025-05-05T22:16:21.279Z","repository":{"id":49141842,"uuid":"119601865","full_name":"Percona-Lab/minimum_permissions","owner":"Percona-Lab","description":"Get the minimum set of permissions needed to run a particular query","archived":false,"fork":false,"pushed_at":"2023-03-07T01:19:00.000Z","size":182,"stargazers_count":3,"open_issues_count":5,"forks_count":1,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-05T22:16:14.067Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Percona-Lab.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-30T22:20:52.000Z","updated_at":"2022-10-10T08:59:34.000Z","dependencies_parsed_at":"2024-06-19T16:22:59.704Z","dependency_job_id":"0e6c6aaf-78da-4406-923e-d45fb6b8275b","html_url":"https://github.com/Percona-Lab/minimum_permissions","commit_stats":{"total_commits":24,"total_committers":1,"mean_commits":24.0,"dds":0.0,"last_synced_commit":"34c6aca051ac44fd29e3166a159bdfa670b5ad00"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Percona-Lab%2Fminimum_permissions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Percona-Lab%2Fminimum_permissions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Percona-Lab%2Fminimum_permissions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Percona-Lab%2Fminimum_permissions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Percona-Lab","download_url":"https://codeload.github.com/Percona-Lab/minimum_permissions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252584334,"owners_count":21771945,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-13T13:16:32.447Z","updated_at":"2025-05-05T22:16:21.258Z","avatar_url":"https://github.com/Percona-Lab.png","language":"Go","readme":"# MySQL Minimum Permissions tool\nGet the minimum set of permissions needed to run a particular query\nMany times at Percona we found that a big number of MySQL instances running with users having too many permissions they\ndon't need. In general, many persons just do `GRANT ALL on *.* to 'user'@'host'`.\nThis is a big security risk not only to prevent external/unauthorized access to the database, but also lets that user to\nany any query, even those queries that deletes data o alter the database structure.\n  \nThis tool born when we were testing Percona Toolkit with MySQL 8.0.4-rc to prepare all the tools to run under the new MySQL\nversion and we came across this scenario:\n\nOne of pt-table-sync's test, needs to check the output when running with an underprivileged user.\nTo do that, it creates a user and grants him these permissions:\n\n```\nGRANT SUPER, SELECT, UPDATE, SHOW DATABASES ON *.* TO 'test_907'\\@'localhost' IDENTIFIED BY 'msandbox'\n```\nand then, pt-table-checksum runs this query:\n\n```\nSELECT `i`, COUNT(*) AS test_count FROM `issue_907`.`t` WHERE 1=1 GROUP BY i ORDER BY i LOCK IN SHARE MODE\n```\nThe problem here is that granting `UPDATE` and `SHOW DATABASES` is enough on MySQL 5.7 but it isn’t for MySQL 8.0.4-rc so, which \nare the minimum permissions we need?\n\n## How it works?\n\nThe tool builds a list of all possible all permissions and then creates a testing user granting him permissions individually, in groups of 2, in groups of 3, etc, using all combinations and runs the provided queries until it found the query execution was\nsuccessful, grouping queries with their minimum required grants.\n  \n####  Example:\n Suppose we are trying to get the minimum permissions for this query: `SHOW /*!40100 ENGINE*/ INNODB STATUS`.  \n The program will start the sandbox, and it will create a testing user granting him  `SELECT` permission and it will run the query. If the query execution fails, it will grant `INSERT` to the testing user and so on until, for this particular example, when the testing user has been granted with `SELECT, PROCESS` the query execution will succed and we know that `SELECT, PROCESS` are the minimum permissions required to run the query.\n \n### When a query execution was successful?\nSince the program runs in a MySQL sandbox, most queries will fail. For example, if we try to execute a `SELECT field1 FROM foo.bar`, the `foo` database and the `bar` table won't exists but, if while trying to run the query we got one of these errors, it means that at least, the testing user has been granted with the minimum permissions requiered to run the query:\n\n|Error Code|Meaning|\n|-----|-----|\n|1049|Database doesn't exists|\n|1067|Invalid default value for '%s'|\n|1146|Table doesn't exists|\n|1213|Deadlock found when trying to get lock|\n|1215|Cannot add FK constraint|\n|1231|Invalid value for variable|\n|1049|Unknown database '%s'|\n|1146|Table '%s.%s' doesn't exist|\n|1213|Deadlock found when trying to get lock|\n|1215|Cannot add foreign key constraint|\n|1231|Variable '%s' can't be set to the value of '%s'|\n\n## Why do we need a MySQL sandbox?\nThe program will start its own MySQL instance (sandbox) because it is dangerous to run a query on an existing database. Even if we try to enclose the queries in a transaction, there are statements that have implicit autocommit.  \nSee MySQL reference: [13.3.3 Statements That Cause an Implicit Commit](https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html)\n\n## Usage examples\nSince this program runs queries that could modify, alter or delete data, it cannot be ran using an existing MySQL\ninstance for security reasons. Because of that, the program needs to know the location of the MySQL binaries and it will\nstart its own MySQL sandbox instance in a temporary directory.\n\nLets assume we have these directories having different MySQL flavors and versions, at `~/mysql`:  \n```\n├── mdb-10.1\n├── mdb-10.2\n├── my-5.5\n├── my-5.6\n├── my-5.7\n├── my-8.0\n├── ps-5.5\n├── ps-5.6\n└── ps-5.7\n```\n#### Testing all queries from a slow.log file\n```\n./minimum_permissions --mysql-base-dir=~/mysql/my-8.0 --slow-log=~/slow.log\n\n```\n\n#### Testing individual queries\n```\n./minimum_permissions --mysql-base-dir=~/mysql/my-8.0 -q='SELECT f1 FROM foo.bar' -q='SELECT f2 FROM db1.t1'\n\n```\n\n#### Testing queries from multiple sources at the same time\n```\n./minimum_permissions --mysql-base-dir=~/mysql/my-8.0 -q='SELECT f1 FROM foo.bar' -q='SELECT f2 FROM db1.t1' --slow-log=~/slow.log --input-file=~/queries.txt --gen-log=~/genlog\n\n```\n### Flags\n|Flag|Description|Notes|\n|-----|-----|-----|\n|--debug|Show extra debug information|default: false |\n|-g, --gen-log|Load queries from genlog file|\n|-h, --help|Show context-sensitive help (also try --help-long and --help-man)| |\n|--hide-invalid-queries|Do not include invalid queries in the report|Default: false|\n|-i, --input-file|Load queries from plain text file. Queries in this file must end with a ; and can have multiple lines| |\n|--keep-sandbox|Do not stop/remove the sandbox after finishing|Default: false|\n|--max-depth|Maximum number of simultaneous permissions to try|Default: 10|\n|--mysql-base-dir|Path to the MySQL base directory (parent of bin/)|Required|\n|--no-trim-long-queries|Do not trim long queries|Default: false|\n|-q, --query|Individual query to test. Can be specified multiple times| |\n|--quiet|Don't show info level notificacions and progress|Default: false|\n|-s, --slow-log|Load queries from slow log file| |\n|--trim-query-size|Trim queries longer than trim-query-size|Default: 100|\n|--version|Show version and exit| |\n\n## Output\nThe output will be something like this:\n```\n### Minimum Permissions\n\n----------------------------------------------------------------------------------------------------\nGrants : ALTER\n----------------------------------------------------------------------------------------------------\nALTER TABLE `film_text` DISABLE KEYS\nALTER TABLE `country` DISABLE KEYS\nALTER TABLE `rental` ENABLE KEYS\nALTER TABLE `customer` ENABLE KEYS\nALTER TABLE `actor` ENABLE KEYS\nALTER TABLE `staff` DISABLE KEYS\nALTER TABLE `film` DISABLE KEYS\nALTER TABLE `language` DISABLE KEYS\nALTER TABLE `actor` DISABLE KEYS\nALTER TABLE `country` ENABLE KEYS\nALTER TABLE `payment` DISABLE KEYS\nALTER TABLE `inventory` DISABLE KEYS\nALTER TABLE `customer` DISABLE KEYS\nALTER TABLE `rental` DISABLE KEYS\nALTER TABLE `store` ENABLE KEYS\nALTER TABLE `film_category` DISABLE KEYS\nALTER TABLE `store` DISABLE KEYS\nALTER TABLE `category` DISABLE KEYS\nALTER TABLE `payment` ENABLE KEYS\nALTER TABLE `film_actor` ENABLE KEYS\nALTER TABLE `film` ENABLE KEYS\nALTER TABLE `film_actor` DISABLE KEYS\nALTER TABLE `address` DISABLE KEYS\nALTER TABLE `film_category` ENABLE KEYS\nALTER TABLE `category` ENABLE KEYS\nALTER TABLE `city` ENABLE KEYS\nALTER TABLE `city` DISABLE KEYS\nALTER TABLE `language` ENABLE KEYS\nALTER TABLE `film_text` ENABLE KEYS\nALTER TABLE `inventory` ENABLE KEYS\nALTER TABLE `address` ENABLE KEYS\nALTER TABLE `staff` ENABLE KEYS \n\n\n----------------------------------------------------------------------------------------------------\nGrants : CREATE\n----------------------------------------------------------------------------------------------------\nCREATE TABLE `ndb_binlog_index` (\n  `Position` bigint(20) unsigned NOT NULL,\n  `File` varchar(255) N ... (truncated)\nCREATE TABLE `country` (\n  `country_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,\n  `country` va ... (truncated)\nCREATE TABLE `proxies_priv` (\n  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',\n  `User` char( ... (truncated)\nCREATE TABLE IF NOT EXISTS `user` (\n  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',\n  `User` ... (truncated)\nCREATE TABLE IF NOT EXISTS percona_test.load_data (i int)\nCREATE DATABASE IF NOT EXISTS percona_test\nCREATE TABLE percona_test.checksums(\n          db_tbl varchar(128) not null primary key,\n          c ... (truncated)\nCREATE TABLE `tables_priv` (\n  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',\n  `Db` char(64) ... (truncated)\nCREATE TABLE IF NOT EXISTS `general_log` (\n  `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIME ... (truncated)\nCREATE TABLE `db` (\n  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',\n  `Db` char(64) COLLATE  ... (truncated)\nCREATE TABLE `language` (\n  `language_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,\n  `name` char ... (truncated)\nCREATE TABLE `func` (\n  `name` char(64) COLLATE utf8_bin NOT NULL DEFAULT '',\n  `ret` tinyint(1) NOT ... (truncated)\nCREATE TABLE `actor` (\n  `actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,\n  `first_name` var ... (truncated)\nCREATE TABLE `category` (\n  `category_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,\n  `name` varc ... (truncated)\nCREATE TABLE `columns_priv` (\n  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',\n  `Db` char(64 ... (truncated)\nCREATE TABLE `film_text` (\n  `film_id` smallint(6) NOT NULL,\n  `title` varchar(255) NOT NULL,\n  `des ... (truncated)\nCREATE DATABASE `sakila`\nCREATE TABLE IF NOT EXISTS percona_test.sentinel (id INT PRIMARY KEY, ping VARCHAR(64) NOT NULL DEFA ... (truncated)\nCREATE TABLE `proc` (\n  `db` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',\n  `na ... (truncated)\nCREATE TABLE `event` (\n  `db` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',\n  `n ... (truncated)\nCREATE TABLE `procs_priv` (\n  `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',\n  `Db` char(64)  ... (truncated)\nCREATE TABLE IF NOT EXISTS `slow_log` (\n  `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTA ... (truncated) \n\n\n----------------------------------------------------------------------------------------------------\nGrants : CREATE, REFERENCES\n----------------------------------------------------------------------------------------------------\nCREATE TABLE `city` (\n  `city_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,\n  `city` varchar(50) ... (truncated)\nCREATE TABLE `staff` (\n  `staff_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,\n  `first_name` varc ... (truncated)\nCREATE TABLE `address` (\n  `address_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,\n  `address` va ... (truncated)\nCREATE TABLE `store` (\n  `store_id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,\n  `manager_staff_id ... (truncated)\nCREATE TABLE `payment` (\n  `payment_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,\n  `customer_id ... (truncated)\nCREATE TABLE `rental` (\n  `rental_id` int(11) NOT NULL AUTO_INCREMENT,\n  `rental_date` datetime NOT  ... (truncated)\nCREATE TABLE `customer` (\n  `customer_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,\n  `store_id` ... (truncated)\nCREATE TABLE `inventory` (\n  `inventory_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,\n  `film_i ... (truncated)\nCREATE TABLE `film_actor` (\n  `actor_id` smallint(5) unsigned NOT NULL,\n  `film_id` smallint(5) unsi ... (truncated)\nCREATE TABLE `film` (\n  `film_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,\n  `title` varchar(25 ... (truncated)\nCREATE TABLE `film_category` (\n  `film_id` smallint(5) unsigned NOT NULL,\n  `category_id` tinyint(3) ... (truncated) \n\n\n----------------------------------------------------------------------------------------------------\nGrants : DROP\n----------------------------------------------------------------------------------------------------\nDROP TABLE IF EXISTS `procs_priv`\nDROP TABLE IF EXISTS percona_test.checksums\nDROP TABLE IF EXISTS `func`\nDROP TABLE IF EXISTS `tables_priv`\nDROP TABLE IF EXISTS `ndb_binlog_index`\nDROP TABLE IF EXISTS `proxies_priv`\nDROP DATABASE IF EXISTS `sakila`\nDROP TABLE IF EXISTS `db`\nDROP TABLE IF EXISTS `event`\nDROP TABLE IF EXISTS `proc`\nDROP TABLE IF EXISTS `columns_priv` \n\n\n----------------------------------------------------------------------------------------------------\nGrants : INSERT\n----------------------------------------------------------------------------------------------------\nINSERT INTO `category` VALUES (1,'Action','2006-02-15 11:46:27')\nINSERT INTO `city` VALUES (1,'A Corua (La Corua)',87,'2006-02-15 11:45:25')\nINSERT INTO `inventory` VALUES (1,1,1,'2006-02-15 12:09:17')\nINSERT INTO `store` VALUES (1,1,1,'2006-02-15 11:57:12'),(2,2,2,'2006-02-15 11:57:12')\nINSERT INTO `address` VALUES (1,'47 MySakila Drive',NULL,'Alberta',300,'','','2006-02-15 11:45:30')\nINSERT INTO `film_actor` VALUES (1,1,'2006-02-15 12:05:03')\nINSERT INTO `film_category` VALUES (1,6,'2006-02-15 12:07:09')\nINSERT INTO `country` VALUES (1,'Afghanistan','2006-02-15 11:44:00')\nINSERT INTO `payment` VALUES (14872,554,2,15690,'4.99','2005-08-23 09:53:30','2006-02-16 05:21:52')\nINSERT INTO `film_text` VALUES (1,'ACADEMY DINOSAUR','A Epic Drama of a Feminist And a Mad Scientist ... (truncated)\nINSERT INTO `language` VALUES (1,'English','2006-02-15 12:02:19')\nINSERT INTO `rental` VALUES (12370,'2005-08-18 07:57:47',3343,503,'2005-08-22 11:32:47',1,'2006-02-1 ... (truncated)\nINSERT INTO `actor` VALUES (1,'PENELOPE','GUINESS','2006-02-15 11:34:33')\nINSERT INTO percona_test.checksums(db_tbl, checksum)\n   VALUES('sakila.store', 972255196)\nINSERT INTO `customer` VALUES (1,1,'MARY','SMITH','MARY.SMITH@sakilacustomer.org',5,1,'2006-02-14 22 ... (truncated)\nINSERT INTO `staff` VALUES (1,'Mike','Hillyer',3,NULL)\nINSERT INTO `film` VALUES (1,'ACADEMY DINOSAUR','A Epic Drama of a Feminist And a Mad Scientist who  ... (truncated) \n\n\n----------------------------------------------------------------------------------------------------\nGrants : INSERT, DELETE\n----------------------------------------------------------------------------------------------------\nREPLACE INTO percona_test.sentinela (id, ping) VALUES (1, '1dcc1893f940d4b0615d8cf540d52e8c') \n\n\n----------------------------------------------------------------------------------------------------\nGrants : INSERT, FILE\n----------------------------------------------------------------------------------------------------\nLOAD DATA INFILE '/tmp/load_data_test.24252' INTO TABLE percona_test.load_data \n\n\n----------------------------------------------------------------------------------------------------\nGrants : SELECT\n----------------------------------------------------------------------------------------------------\n/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */\nUSE `sakila`\ncommit\n/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */\nSET @slave_uuid= 'cd111826-0a1e-11e8-98c3-88787342351a'\n/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */\n/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */\nSELECT @@GLOBAL.SERVER_ID\n/*!50003 SET character_set_client  = @saved_cs_client */\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */\n/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */\nSET UNIQUE_CHECKS=0\nCHECKSUM TABLES mysql.columns_priv, mysql.db, mysql.engine_cost, mysql.event, mysql.func, mysql.gtid ... (truncated)\nSET @master_heartbeat_period= 30000001024\nSELECT @master_binlog_checksum\nrollback\n/*!40101 SET @saved_cs_client     = @@character_set_client */\nSELECT @@GLOBAL.GTID_MODE\nUNLOCK TABLES\n/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */\nSELECT VERSION()\nSELECT i FROM percona_test.load_data\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */\n/*!50003 SET @saved_cs_results     = @@character_set_results */\nSELECT MD5(RAND())\nselect @@version_comment limit 1\nSET AUTOCOMMIT=1\n/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */\nSELECT UNIX_TIMESTAMP()\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */\n/*!40103 SET TIME_ZONE='+00:00' */\nSET FOREIGN_KEY_CHECKS=0\n/*!40101 SET SQL_MODE=@OLD_SQL_MODE */\n/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */\nSET NAMES utf8\n/*!50003 SET @saved_col_connection = @@collation_connection */\n/*!50003 SET character_set_results = latin1 */\n/*!40101 SET character_set_client = utf8 */\n/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */\n/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */\n/*!50003 SET character_set_client  = latin1 */\n/*!50003 SET collation_connection  = latin1_swedish_ci */\nSELECT @@GLOBAL.SERVER_UUID\n/*!40101 SET NAMES utf8 */\n/*!40101 SET character_set_client = @saved_cs_client */\n/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */\nSELECT DATABASE()\n/*!50003 SET @saved_cs_client      = @@character_set_client */\n/*!50003 SET @saved_sql_mode       = @@sql_mode */\n/*!50003 SET collation_connection  = @saved_col_connection */\nSET @master_binlog_checksum= @@global.binlog_checksum\n/*!50003 SET sql_mode              = '' */\n/*!50003 SET sql_mode              = @saved_sql_mode */\n/*!50003 SET character_set_results = @saved_cs_results */\nSHOW TABLES FROM mysql\n/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */ \n\n\n----------------------------------------------------------------------------------------------------\nGrants : SELECT, CREATE VIEW\n----------------------------------------------------------------------------------------------------\nCREATE DEFINER=CURRENT_USER SQL SECURITY INVOKER VIEW actor_info\nAS\nSELECT\na.actor_id,\na.first_name, ... (truncated)\nCREATE VIEW sales_by_film_category\nAS\nSELECT\nc.name AS category\n, SUM(p.amount) AS total_sales\nFROM  ... (truncated)\nCREATE VIEW staff_list\nAS\nSELECT s.staff_id AS ID, CONCAT(s.first_name, _utf8' ', s.last_name) AS na ... (truncated)\nCREATE VIEW sales_by_store\nAS\nSELECT\nCONCAT(c.city, _utf8',', cy.country) AS store\n, CONCAT(m.first_ ... (truncated)\nCREATE VIEW customer_list\nAS\nSELECT cu.customer_id AS ID, CONCAT(cu.first_name, _utf8' ', cu.last_na ... (truncated)\nCREATE VIEW film_list\nAS\nSELECT film.film_id AS FID, film.title AS title, film.description AS descri ... (truncated)\nCREATE VIEW nicer_but_slower_film_list\nAS\nSELECT film.film_id AS FID, film.title AS title, film.desc ... (truncated) \n\n\n----------------------------------------------------------------------------------------------------\nGrants : SELECT, INSERT\n----------------------------------------------------------------------------------------------------\nANALYZE TABLE actor, address, category, city, country, customer, film, film_actor, film_category, fi ... (truncated) \n\n\n----------------------------------------------------------------------------------------------------\nGrants : SELECT, LOCK TABLES\n----------------------------------------------------------------------------------------------------\nLOCK TABLES `language` WRITE\nLOCK TABLES `store` WRITE\nLOCK TABLES `category` WRITE\nLOCK TABLES `city` WRITE\nLOCK TABLES `film_actor` WRITE\nLOCK TABLES `film_text` WRITE\nLOCK TABLES `actor` WRITE\nLOCK TABLES `rental` WRITE\nLOCK TABLES `payment` WRITE\nLOCK TABLES `film_category` WRITE\nLOCK TABLES `customer` WRITE\nLOCK TABLES `staff` WRITE\nLOCK TABLES `film` WRITE\nLOCK TABLES `inventory` WRITE\nLOCK TABLES `address` WRITE\nLOCK TABLES `country` WRITE\n\n\n----------------------------------------------------------------------------------------------------\nGrants : SELECT, PROCESS\n----------------------------------------------------------------------------------------------------\nSHOW /*!40100 ENGINE*/ INNODB STATUS\n\n\n----------------------------------------------------------------------------------------------------\nGrants : SELECT, RELOAD\n----------------------------------------------------------------------------------------------------\nFLUSH TABLES\n\n\n----------------------------------------------------------------------------------------------------\nGrants : TRIGGER\n----------------------------------------------------------------------------------------------------\n/*!50003 CREATE*/ /*!50017 DEFINER=`msandbox`@`%`*/ /*!50003 TRIGGER rental_date BEFORE INSERT ON re ... (truncated)\n/*!50003 CREATE*/ /*!50017 DEFINER=`msandbox`@`%`*/ /*!50003 TRIGGER payment_date BEFORE INSERT ON p ... (truncated)\n/*!50003 CREATE*/ /*!50017 DEFINER=`msandbox`@`%`*/ /*!50003 TRIGGER customer_create_date BEFORE INS ... (truncated)\n\n\n----------------------------------------------------------------------------------------------------\nGrants : UPDATE\n----------------------------------------------------------------------------------------------------\nUPDATE mysql.proc SET created='2012-06-05 00:00:00', modified='2012-06-05 00:00:00'\n\n```\n\n# TODO\n- [ ] RDS support\n\n## Authors\n- **Carlos Salguero** - Initial work\n\n## Acknowledgments\n- **Alexander Rubin** - Specs review\n- **Roel Van de Paar** - Specs review, sandbox specs, testing\n- **[Giuseppe Maxia](https://github.com/datacharmer)** For the sanbox package from [dbdeployer](https://github.com/datacharmer/dbdeployer) and for all\n  the work making it possible to use the sandbox package from external projects like this one.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpercona-lab%2Fminimum_permissions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpercona-lab%2Fminimum_permissions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpercona-lab%2Fminimum_permissions/lists"}