Skip to content

Commit

Permalink
Added db_metadata options to create database command
Browse files Browse the repository at this point in the history
Summary:
Added new option db_metadata to the create database
`CREATE DATABASE [IF NOT EXISTS] db_name DB_METADATA [=] metadata`

The new option is stored in the db.opt file along with other database options like charset and read_only.
The options accepts any string value. If not specified, it writes empty string as the default value in the db.opt file.
To retrieve the option value for a particular database, the show command can be used as follows:
`SHOW CREATE DATABASE db_name`

Example Usage:

create database test2 charset utf8 read_only = true db_metadata '{\'shard_name\':\'myshard_for_test2\'}';
show create database test2;

Output:

+----------+--------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                                                                                                          |
+----------+--------------------------------------------------------------------------------------------------------------------------+
| test2    | CREATE DATABASE `test2` /*!40100 DEFAULT CHARACTER SET utf8 READ_ONLY DB_METADATA {'shard_name':'myshard_for_test2'} */ |
+----------+--------------------------------------------------------------------------------------------------------------------------+

Reviewed By: tianx

Differential Revision: D5358178

fbshipit-source-id: 4308ca2
  • Loading branch information
yashtc authored and facebook-github-bot committed Jul 25, 2017
1 parent 745ad33 commit 2f08e3a
Show file tree
Hide file tree
Showing 10 changed files with 427 additions and 15 deletions.
186 changes: 186 additions & 0 deletions mysql-test/r/db_metadata.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
drop database if exists test2;
drop database if exists test3;
drop database if exists test4;
drop database if exists test5;
drop database if exists test6;
drop database if exists test7;
drop database if exists test8;
drop database if exists test9;
create database test2;
show create database test2;
Database Create Database
test2 CREATE DATABASE `test2` /*!40100 DEFAULT CHARACTER SET latin1 */
default-character-set=latin1
default-collation=latin1_swedish_ci
db-read-only=0
db-metadata=
create database test3 character set utf8;
show create database test3;
Database Create Database
test3 CREATE DATABASE `test3` /*!40100 DEFAULT CHARACTER SET utf8 */
default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=0
db-metadata=
create database test4 read_only = true;
show create database test4;
Database Create Database
test4 CREATE DATABASE `test4` /*!40100 DEFAULT CHARACTER SET latin1 READ_ONLY */
default-character-set=latin1
default-collation=latin1_swedish_ci
db-read-only=1
db-metadata=
create database test5 db_metadata = "{\"shard\":\"test5_shard\"}";
show create database test5;
Database Create Database
test5 CREATE DATABASE `test5` /*!40100 DEFAULT CHARACTER SET latin1 DB_METADATA {"shard":"test5_shard"} */
default-character-set=latin1
default-collation=latin1_swedish_ci
db-read-only=0
db-metadata={"shard":"test5_shard"}
create database test6 character set utf8 db_metadata = "{\"shard\":\"test6_shard\"}";
show create database test6;
Database Create Database
test6 CREATE DATABASE `test6` /*!40100 DEFAULT CHARACTER SET utf8 DB_METADATA {"shard":"test6_shard"} */
default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=0
db-metadata={"shard":"test6_shard"}
create database test7 read_only = true db_metadata = "{\"shard\":\"test7_shard\"}";
show create database test7;
Database Create Database
test7 CREATE DATABASE `test7` /*!40100 DEFAULT CHARACTER SET latin1 READ_ONLY DB_METADATA {"shard":"test7_shard"} */
default-character-set=latin1
default-collation=latin1_swedish_ci
db-read-only=1
db-metadata={"shard":"test7_shard"}
create database test8 character set utf8 read_only = true;
show create database test8;
Database Create Database
test8 CREATE DATABASE `test8` /*!40100 DEFAULT CHARACTER SET utf8 READ_ONLY */
default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=1
db-metadata=
create database test9 character set utf8 read_only = true db_metadata = "{\"shard\":\"test9_shard\"}";
show create database test9;
Database Create Database
test9 CREATE DATABASE `test9` /*!40100 DEFAULT CHARACTER SET utf8 READ_ONLY DB_METADATA {"shard":"test9_shard"} */
default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=1
db-metadata={"shard":"test9_shard"}
alter database test3 character set ascii;
show create database test3;
Database Create Database
test3 CREATE DATABASE `test3` /*!40100 DEFAULT CHARACTER SET ascii */
default-character-set=ascii
default-collation=ascii_general_ci
db-read-only=0
db-metadata=
alter database test4 read_only = true;
show create database test4;
Database Create Database
test4 CREATE DATABASE `test4` /*!40100 DEFAULT CHARACTER SET latin1 READ_ONLY */
default-character-set=latin1
default-collation=latin1_swedish_ci
db-read-only=1
db-metadata=
alter database test5 db_metadata = "{\"shard\":\"test5_shard_altered\"}";
show create database test5;
Database Create Database
test5 CREATE DATABASE `test5` /*!40100 DEFAULT CHARACTER SET latin1 DB_METADATA {"shard":"test5_shard_altered"} */
default-character-set=latin1
default-collation=latin1_swedish_ci
db-read-only=0
db-metadata={"shard":"test5_shard_altered"}
alter database test5 character set ascii;
show create database test5;
Database Create Database
test5 CREATE DATABASE `test5` /*!40100 DEFAULT CHARACTER SET ascii DB_METADATA {"shard":"test5_shard_altered"} */
default-character-set=ascii
default-collation=ascii_general_ci
db-read-only=0
db-metadata={"shard":"test5_shard_altered"}
alter database test5 read_only = true;
show create database test5;
Database Create Database
test5 CREATE DATABASE `test5` /*!40100 DEFAULT CHARACTER SET ascii READ_ONLY DB_METADATA {"shard":"test5_shard_altered"} */
default-character-set=ascii
default-collation=ascii_general_ci
db-read-only=1
db-metadata={"shard":"test5_shard_altered"}
alter database test5 character set utf8 read_only = false;
show create database test5;
Database Create Database
test5 CREATE DATABASE `test5` /*!40100 DEFAULT CHARACTER SET utf8 DB_METADATA {"shard":"test5_shard_altered"} */
default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=0
db-metadata={"shard":"test5_shard_altered"}
alter database test5 db_metadata "";
show create database test5;
Database Create Database
test5 CREATE DATABASE `test5` /*!40100 DEFAULT CHARACTER SET utf8 */
default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=0
db-metadata=
alter database test5 db_metadata "{\"shard\":\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\"}";
show create database test5;
Database Create Database
test5 CREATE DATABASE `test5` /*!40100 DEFAULT CHARACTER SET utf8 DB_METADATA {"shard":"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin"} */
default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=0
db-metadata={"shard":"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin"}
alter database test5 db_metadata "{\"shard\":\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\"}";;
ERROR HY000: Metadata for the database is too long. Max length is 1024 bytes
alter database test6 character set ascii db_metadata = "{\"shard\":\"test6_shard_altered\"}";
show create database test6;
Database Create Database
test6 CREATE DATABASE `test6` /*!40100 DEFAULT CHARACTER SET ascii DB_METADATA {"shard":"test6_shard_altered"} */
default-character-set=ascii
default-collation=ascii_general_ci
db-read-only=0
db-metadata={"shard":"test6_shard_altered"}
alter database test7 read_only = true db_metadata = "{\"shard\":\"test7_shard_altered\"}";
show create database test7;
Database Create Database
test7 CREATE DATABASE `test7` /*!40100 DEFAULT CHARACTER SET latin1 READ_ONLY DB_METADATA {"shard":"test7_shard_altered"} */
default-character-set=latin1
default-collation=latin1_swedish_ci
db-read-only=1
db-metadata={"shard":"test7_shard_altered"}
alter database test8 character set ascii read_only = true;
show create database test8;
Database Create Database
test8 CREATE DATABASE `test8` /*!40100 DEFAULT CHARACTER SET ascii READ_ONLY */
default-character-set=ascii
default-collation=ascii_general_ci
db-read-only=1
db-metadata=
alter database test9 character set ascii read_only = true db_metadata = "{\"shard\":\"test9_shard_altered\"}";
show create database test9;
Database Create Database
test9 CREATE DATABASE `test9` /*!40100 DEFAULT CHARACTER SET ascii READ_ONLY DB_METADATA {"shard":"test9_shard_altered"} */
default-character-set=ascii
default-collation=ascii_general_ci
db-read-only=1
db-metadata={"shard":"test9_shard_altered"}
show create database information_schema;
Database Create Database
information_schema CREATE DATABASE `information_schema` /*!40100 DEFAULT CHARACTER SET utf8 */
show create database mysql;
Database Create Database
mysql CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */
alter database information_schema db_metadata "{\"shard\":\"is_shard\"}";;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
drop database if exists test2;
drop database if exists test3;
drop database if exists test4;
drop database if exists test5;
drop database if exists test6;
drop database if exists test7;
drop database if exists test8;
drop database if exists test9;
147 changes: 147 additions & 0 deletions mysql-test/t/db_metadata.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Test per-database database-metadata attribute
--source include/have_innodb.inc
connection default;

--disable_warnings
drop database if exists test2;
drop database if exists test3;
drop database if exists test4;
drop database if exists test5;
drop database if exists test6;
drop database if exists test7;
drop database if exists test8;
drop database if exists test9;
--enable_warnings

--disable_query_log
let $MYSQLD_DATADIR= `select @@datadir`;
--enable_query_log

--error 1
file_exists $MYSQLD_DATADIR/mysql/db.opt;
--error 1
file_exists $MYSQLD_DATADIR/test/db.opt;

# create database without any options
create database test2;
show create database test2;
--exec cat $MYSQLD_DATADIR/test2/db.opt;

# create database with character set
create database test3 character set utf8;
show create database test3;
--exec cat $MYSQLD_DATADIR/test3/db.opt;

# create database with read only
create database test4 read_only = true;
show create database test4;
--exec cat $MYSQLD_DATADIR/test4/db.opt;

# create database with db metadata
create database test5 db_metadata = "{\"shard\":\"test5_shard\"}";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;

# create database with character set and db metadata
create database test6 character set utf8 db_metadata = "{\"shard\":\"test6_shard\"}";
show create database test6;
--exec cat $MYSQLD_DATADIR/test6/db.opt;

# create database with read only and db metadata
create database test7 read_only = true db_metadata = "{\"shard\":\"test7_shard\"}";
show create database test7;
--exec cat $MYSQLD_DATADIR/test7/db.opt;

# create database with character set and read only
create database test8 character set utf8 read_only = true;
show create database test8;
--exec cat $MYSQLD_DATADIR/test8/db.opt;

# create database with character set, read only and db metadata
create database test9 character set utf8 read_only = true db_metadata = "{\"shard\":\"test9_shard\"}";
show create database test9;
--exec cat $MYSQLD_DATADIR/test9/db.opt;

# alter database tests

# alter database character set
alter database test3 character set ascii;
show create database test3;
--exec cat $MYSQLD_DATADIR/test3/db.opt;

# alter database read only
alter database test4 read_only = true;
show create database test4;
--exec cat $MYSQLD_DATADIR/test4/db.opt;

# alter database db metadata
alter database test5 db_metadata = "{\"shard\":\"test5_shard_altered\"}";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;

# alter database character set but keep db metadata intact
alter database test5 character set ascii;
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;

# alter database read only but keep db metadata intact
alter database test5 read_only = true;
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;

# alter database character set and read only but keep db metadata intact
alter database test5 character set utf8 read_only = false;
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;

# alter database reset db metadata
alter database test5 db_metadata "";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;

# alter database set db metadata to max length string
alter database test5 db_metadata "{\"shard\":\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\"}";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;

# alter database exceed db metadata max length
--error ER_DB_METADATA_TOO_LONG
--eval alter database test5 db_metadata \"{\\\"shard\\\":\\\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\\\"}\";

# alter database character set and db metadata
alter database test6 character set ascii db_metadata = "{\"shard\":\"test6_shard_altered\"}";
show create database test6;
--exec cat $MYSQLD_DATADIR/test6/db.opt;

# alter database read only and db metadata
alter database test7 read_only = true db_metadata = "{\"shard\":\"test7_shard_altered\"}";
show create database test7;
--exec cat $MYSQLD_DATADIR/test7/db.opt;

# alter database character set and read only
alter database test8 character set ascii read_only = true;
show create database test8;
--exec cat $MYSQLD_DATADIR/test8/db.opt;

# alter database character set, read only and db metadata
alter database test9 character set ascii read_only = true db_metadata = "{\"shard\":\"test9_shard_altered\"}";
show create database test9;
--exec cat $MYSQLD_DATADIR/test9/db.opt;

# ensure information_schema and mysql tables are intact
show create database information_schema;
show create database mysql;
--error ER_DBACCESS_DENIED_ERROR
--eval alter database information_schema db_metadata \"{\\"shard\\":\\"is_shard\\"}\";

# cleanup
--disable_warnings
drop database if exists test2;
drop database if exists test3;
drop database if exists test4;
drop database if exists test5;
drop database if exists test6;
drop database if exists test7;
drop database if exists test8;
drop database if exists test9;
--enable_warnings
2 changes: 2 additions & 0 deletions sql/handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <regex>
#include <vector>
#include <unordered_set>
#include <sql_string.h>

class Alter_info;

Expand Down Expand Up @@ -1094,6 +1095,7 @@ typedef struct st_ha_create_information
means it is explicitly set to default or
it is not specified in alter */
enum enum_db_read_only db_read_only;
String db_metadata;
LEX_STRING connect_string;
const char *password, *tablespace;
LEX_STRING comment;
Expand Down
1 change: 1 addition & 0 deletions sql/lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ static SYMBOL symbols[] = {
{ "DAY_MICROSECOND", SYM(DAY_MICROSECOND_SYM)},
{ "DAY_MINUTE", SYM(DAY_MINUTE_SYM)},
{ "DAY_SECOND", SYM(DAY_SECOND_SYM)},
{ "DB_METADATA", SYM(DB_METADATA_SYM)},
{ "DEALLOCATE", SYM(DEALLOCATE_SYM)},
{ "DEC", SYM(DECIMAL_SYM)},
{ "DECIMAL", SYM(DECIMAL_SYM)},
Expand Down
6 changes: 6 additions & 0 deletions sql/share/errmsg-utf8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7323,6 +7323,12 @@ ER_CANT_SET_DEPENDENCY_REPLICATION_WITHOUT_IDEMPOTENT_RECOVERY
ER_SLAVE_WORKER_STOPPED_PREVIOUS_THD_ERROR
eng "Slave worker has stopped after at least one previous worker encountered an error when mts_dependency_order_commits was enabled. To preserve commit order, the last transaction executed by this thread has not been committed. When restarting the slave after fixing any failed threads, you should fix this worker as well."

ER_DB_METADATA_TOO_LONG
eng "Metadata for the database is too long. Max length is %d bytes"

ER_DB_METADATA_READ_ERROR
eng "Error reading db metadata option: '%-.64s'"

#
# End of 5.6 error messages.
#
Loading

0 comments on commit 2f08e3a

Please sign in to comment.