1
0
mirror of https://github.com/MariaDB/server.git synced 2025-04-18 21:44:20 +03:00

load_db_opt was always doing a file access if db.opt file did not exist

Added caching of database directories that did not have a db.opt file.
This was common for older MariaDB installaiton or if a user created
a database with 'mkdir'.

Other things:
- Give a note "no db.opt file" if one uses SHOW CREATE DATABASE one
  a database without a db.opt file.
This commit is contained in:
Monty 2025-02-25 15:45:44 +02:00
parent cf01bfe811
commit 2c0ba2680b
7 changed files with 67 additions and 17 deletions

View File

@ -76,3 +76,16 @@ WHERE schema_name='comment';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH SCHEMA_COMMENT
def comment latin2 latin2_general_ci NULL comment
DROP DATABASE comment;
CREATE DATABASE db1;
# restart
SHOW CREATE DATABASE db1;
Database Create Database
db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */
Warnings:
Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed
SHOW CREATE DATABASE db1;
Database Create Database
db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */
Warnings:
Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed
DROP DATABASE db1;

View File

@ -63,3 +63,11 @@ SELECT * FROM information_schema.schemata
WHERE schema_name='comment';
DROP DATABASE comment;
--enable_service_connection
CREATE DATABASE db1;
--remove_file $MARIADB_DATADIR/db1/db.opt
--source include/restart_mysqld.inc
# We need to call this two times to ensure all code paths are used
SHOW CREATE DATABASE db1;
SHOW CREATE DATABASE db1;
DROP DATABASE db1;

View File

@ -53,6 +53,8 @@ SET @@character_set_database=DEFAULT;
SHOW CREATE DATABASE db1;
Database Create Database
db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci */
Warnings:
Note 1105 Database 'db1' does not have a db.opt file. You can create one with ALTER DATABASE if needed
USE db1;
SELECT @@character_set_database, 'taken from defaults' AS comment;
@@character_set_database comment

View File

@ -12,6 +12,8 @@ FLUSH TABLES;
SHOW CREATE DATABASE sys;
Database Create Database
sys CREATE DATABASE `sys` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci */
Warnings:
Note 1105 Database 'sys' does not have a db.opt file. You can create one with ALTER DATABASE if needed
Phase 1/8: Checking and upgrading mysql database
Processing databases
mysql

View File

@ -536,36 +536,53 @@ static bool write_db_opt(THD *thd, const char *path,
DESCRIPTION
create->default_table_charset is guaranteed to be alway set
Required by some callers
RETURN VALUES
0 File found
1 No database file or could not open it
-1 No database file (file was not found or 'empty' file was cached)
1 Could not open it
*/
bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
int load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
{
File file;
char buf[256+DATABASE_COMMENT_MAXLEN];
DBUG_ENTER("load_db_opt");
bool error=1;
int error= 0;
size_t nbytes;
myf utf8_flag= thd->get_utf8_flag();
bzero((char*) create,sizeof(*create));
create->default_table_charset= thd->variables.collation_server;
/* Check if options for this database are already in the hash */
if (!get_dbopt(thd, path, create))
DBUG_RETURN(0);
{
if (!create->default_table_charset)
error= -1; // db.opt did not exists
goto err1;
}
/* Otherwise, load options from the .opt file */
if ((file= mysql_file_open(key_file_dbopt,
path, O_RDONLY | O_SHARE, MYF(0))) < 0)
{
/*
Create an empty entry, to avoid doing an extra file open for every create
table.
*/
put_dbopt(path, create);
error= -1;
goto err1;
}
IO_CACHE cache;
if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
goto err2;
{
error= 1;
goto err2; // Not cached
}
while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
{
@ -586,7 +603,7 @@ bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
default-collation commands.
*/
if (!(create->default_table_charset=
get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(utf8_flag))) &&
get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(utf8_flag))) &&
!(create->default_table_charset=
get_charset_by_name(pos+1, MYF(utf8_flag))))
{
@ -621,10 +638,11 @@ bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
err2:
mysql_file_close(file, MYF(0));
err1:
if (!create->default_table_charset) // In case of error
create->default_table_charset= thd->variables.collation_server;
DBUG_RETURN(error);
}
/*
Retrieve database options by name. Load database options file or fetch from
cache.
@ -651,11 +669,12 @@ err1:
db_create_info right after that.
RETURN VALUES (read NOTE!)
FALSE Success
TRUE Failed to retrieve options
0 File found
-1 No database file (file was not found or 'empty' file was cached)
1 Could not open it
*/
bool load_db_opt_by_name(THD *thd, const char *db_name,
int load_db_opt_by_name(THD *thd, const char *db_name,
Schema_specification_st *db_create_info)
{
char db_opt_path[FN_REFLEN + 1];
@ -1951,8 +1970,7 @@ bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db)
build_table_filename(path, sizeof(path)-1,
old_db->str, "", MY_DB_OPT_FILE, 0);
if ((load_db_opt(thd, path, &create_info)))
create_info.default_table_charset= thd->variables.collation_server;
load_db_opt(thd, path, &create_info);
length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
if (length && path[length-1] == FN_LIBCHAR)

View File

@ -37,8 +37,8 @@ bool mysql_opt_change_db(THD *thd,
bool my_dboptions_cache_init(void);
void my_dboptions_cache_free(void);
bool check_db_dir_existence(const char *db_name);
bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create);
bool load_db_opt_by_name(THD *thd, const char *db_name,
int load_db_opt(THD *thd, const char *path, Schema_specification_st *create);
int load_db_opt_by_name(THD *thd, const char *db_name,
Schema_specification_st *db_create_info);
CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name);
bool my_dbopt_init(void);

View File

@ -1435,7 +1435,14 @@ bool mysqld_show_create_db(THD *thd, LEX_CSTRING *dbname,
DBUG_RETURN(TRUE);
}
load_db_opt_by_name(thd, dbname->str, &create);
if (load_db_opt_by_name(thd, dbname->str, &create) < 0)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_UNKNOWN_ERROR,
"Database '%.192s' does not have a db.opt file. "
"You can create one with ALTER DATABASE if needed",
dbname->str);
}
}
mysqld_show_create_db_get_fields(thd, &field_list);