Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Implements per-database scope read-only setting. The read-only can be turned on in `alter database` statement. Privilege to set read-only follows alter-database ACL. ALTER DATABASE db_name [SUPER_READ_ONLY | READ_ONLY = FALSE | TRUE]] `SUPER_READ_ONLY = TRUE` will prevent all write transactions from committing for any user (including super users). `READ_ONLY = TRUE` will prevent any write transaction from committing for regular users, while super users can still write to the database. `SUPER_READ_ONLY = FALSE` will turn off super_read_only on the database, and the database remains on read_only (for regular users), `READ_ONLY = FALSE` will turn off read_only on the database, The READ_ONLY database status can be shown by `show create database`. mysql> alter database test read_only = true; Query OK, 1 row affected (0.00 sec) mysql> show create database test; +----------+---------------------------------------------------------------------------+ | Database | Create Database | +----------+---------------------------------------------------------------------------+ | test | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 READ_ONLY */ | +----------+---------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> alter database test super_read_only = true; Query OK, 1 row affected (0.00 sec) mysql> show create database test; +----------+---------------------------------------------------------------------------------+ | Database | Create Database | +----------+---------------------------------------------------------------------------------+ | test | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 SUPER_READ_ONLY */ | +----------+---------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> alter database test super_read_only = false; Query OK, 1 row affected (0.00 sec) mysql> show create database test; +----------+---------------------------------------------------------------------------+ | Database | Create Database | +----------+---------------------------------------------------------------------------+ | test | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 READ_ONLY */ | +----------+---------------------------------------------------------------------------+ 1 row in set (0.00 sec) Details: * READ_ONLY flag is persisted in db.ops and survives restarts. * Alter database will only return when no write transaction is still committing. Uncommitted write transactions will fail after alter database succeeds. * DB options are stored in each thread (using hash map), so checking the read_only options doesn't grab a global lock. Only db_read_only that is turned on is stored in the local hash map. * The first time thead local hash map is initialized (once), shared db option map will be locked and accessed. Since the db options are not automatically loaded into the shared hash map (cache) at the beginning, we have to explicitly load the db options during the first time any thread initializes its local hash map. * create/alter/delete database DDLs will iterate through thread array to update local db opt (if needed), similar to how show processlist works. * write transactions are checked against local hashmap at commit time (either explicit commit or auto-commit). This will make the explicit commit and auto-commits consistent, and avoid problems such that explicit commit may become a "read-only" transaction if we block write-statements at the parsing time. * The list of databases accessed in a write transaction is obtained through the metadata locks (MDL) that the transaction holds. As I noted in the code, this may rollback some false positives, such as the read-only DB in the list may not actually be modified in the transaction (for cross-db transactions). We do not differentiate such cases. Test Plan: main.db_read_only Reviewers: ebergen, santoshb, pengt Reviewed By: pengt
- Loading branch information