MySQL 9.1.0
Source Code Documentation
sql_db.cc File Reference
#include "sql/sql_db.h"
#include "my_config.h"
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <atomic>
#include <set>
#include <vector>
#include "lex_string.h"
#include "m_string.h"
#include "my_command.h"
#include "my_dbug.h"
#include "my_dir.h"
#include "my_inttypes.h"
#include "my_io.h"
#include "my_macros.h"
#include "my_sys.h"
#include "my_thread_local.h"
#include "mysql/components/services/log_builtins.h"
#include "mysql/components/services/log_shared.h"
#include "mysql/psi/mysql_file.h"
#include "mysql/psi/mysql_mutex.h"
#include "mysql/service_mysql_alloc.h"
#include "mysql/strings/int2str.h"
#include "mysql/strings/m_ctype.h"
#include "mysql_com.h"
#include "mysqld_error.h"
#include "mysys_err.h"
#include "nulls.h"
#include "sql/auth/auth_acls.h"
#include "sql/auth/auth_common.h"
#include "sql/auth/sql_security_ctx.h"
#include "sql/binlog.h"
#include "sql/dd/cache/dictionary_client.h"
#include "sql/dd/dd.h"
#include "sql/dd/dd_schema.h"
#include "sql/dd/dd_table.h"
#include "sql/dd/dictionary.h"
#include "sql/dd/impl/bootstrap/bootstrap_ctx.h"
#include "sql/dd/impl/tables/dd_properties.h"
#include "sql/dd/string_type.h"
#include "sql/dd/types/abstract_table.h"
#include "sql/dd/types/schema.h"
#include "sql/debug_sync.h"
#include "sql/derror.h"
#include "sql/error_handler.h"
#include "sql/events.h"
#include "sql/handler.h"
#include "sql/lock.h"
#include "sql/log.h"
#include "sql/log_event.h"
#include "sql/mdl.h"
#include "sql/mysqld.h"
#include "sql/psi_memory_key.h"
#include "sql/rpl_gtid.h"
#include "sql/rpl_replica_commit_order_manager.h"
#include "sql/session_tracker.h"
#include "sql/sp.h"
#include "sql/sql_base.h"
#include "sql/sql_class.h"
#include "sql/sql_const.h"
#include "sql/sql_error.h"
#include "sql/sql_handler.h"
#include "sql/sql_table.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "sql/thd_raii.h"
#include "sql/transaction.h"
#include "sql_string.h"
#include "string_with_len.h"
#include "strmake.h"
#include "strxmov.h"
#include "typelib.h"

Classes

class  Create_db_cleanup_handler
 
class  Rmdir_error_handler
 Error handler which converts errors during database directory removal to warnings/messages to error log. More...
 

Functions

static bool find_unknown_and_remove_deletable_files (THD *thd, MY_DIR *dirp, const char *path)
 Auxiliary function which checks if database directory has any files which won't be deleted automatically - either because we know that these are temporary/backup files which are safe for delete or by dropping the tables in the database. More...
 
static bool find_db_tables (THD *thd, const dd::Schema &schema, const char *db, Table_ref **tables)
 Auxiliary function which retrieves list of all tables in the database from the data-dictionary. More...
 
static long mysql_rm_arc_files (THD *thd, MY_DIR *dirp, const char *org_path)
 
static bool rm_dir_w_symlink (const char *org_path, bool send_error)
 
static void mysql_change_db_impl (THD *thd, const LEX_CSTRING &new_db_name, ulong new_db_access, const CHARSET_INFO *new_db_charset)
 Internal implementation: switch current database to a valid one. More...
 
bool get_default_db_collation (const dd::Schema &schema, const CHARSET_INFO **collation)
 
bool get_default_db_collation (THD *thd, const char *db_name, const CHARSET_INFO **collation)
 Return default database collation. More...
 
static bool thread_can_ignore_schema_read_only (THD *thd)
 Check if the thread type is allowed to ignore the schema read only option. More...
 
bool check_schema_readonly (THD *thd, const char *schema_name, TABLE_SHARE *share)
 Check the read_only option for the given schema, and report error if the schema is not writable. More...
 
static bool write_db_cmd_to_binlog (THD *thd, const char *db, bool trx_cache)
 Auxiliary function which writes CREATE/ALTER or DROP DATABASE statement to the binary log overriding connection's current database with one being dropped. More...
 
static void set_db_default_charset (const THD *thd, HA_CREATE_INFO *create_info)
 
static bool use_ddl_log_for_schema_ddl ()
 Helps decide whether we should use DDL Logging for schema DDLs (CREATE/DROP SCHEMA). More...
 
bool mysql_create_db (THD *thd, const char *db, HA_CREATE_INFO *create_info)
 Create a database. More...
 
bool mysql_alter_db (THD *thd, const char *db, HA_CREATE_INFO *create_info)
 
bool mysql_rm_db (THD *thd, const LEX_CSTRING &db, bool if_exists)
 Drop all tables, routines and events in a database and the database itself. More...
 
static void backup_current_db_name (THD *thd, LEX_STRING *saved_db_name)
 Backup the current database name before switch. More...
 
static bool cmp_db_names (const char *db1_name, const char *db2_name)
 Return true if db1_name is equal to db2_name, false otherwise. More...
 
bool mysql_change_db (THD *thd, const LEX_CSTRING &new_db_name, bool force_switch)
 Change the current database and its attributes unconditionally. More...
 
bool mysql_opt_change_db (THD *thd, const LEX_CSTRING &new_db_name, LEX_STRING *saved_db_name, bool force_switch, bool *cur_db_changed)
 Change the current database and its attributes if needed. More...
 

Variables

const char * del_exts []
 
static TYPELIB deletable_extentions
 

Function Documentation

◆ backup_current_db_name()

static void backup_current_db_name ( THD thd,
LEX_STRING saved_db_name 
)
static

Backup the current database name before switch.

Parameters
[in]thdthread handle
[in,out]saved_db_nameIN: "str" points to a buffer where to store the old database name, "length" contains the buffer size OUT: if the current (default) database is not NULL, its name is copied to the buffer pointed at by "str" and "length" is updated accordingly. Otherwise "str" is set to NULL and "length" is set to 0.

◆ check_schema_readonly()

bool check_schema_readonly ( THD thd,
const char *  schema_name,
TABLE_SHARE share 
)

Check the read_only option for the given schema, and report error if the schema is not writable.

Parameters
thdThread context.
schema_nameName of schema to check.
shareFor tables, we cache the read only option in the table share, and can therefore get the read only option from the share.

Caching the read only state in the table share is done for performance reasons. If a share is submitted, we get the read only state from the share. Otherwise, we get the schema object from the DD cache in order to see the read only state.

Returns
false if the schema is writable, true if not. If returning true, then error is already reported.

◆ cmp_db_names()

static bool cmp_db_names ( const char *  db1_name,
const char *  db2_name 
)
inlinestatic

Return true if db1_name is equal to db2_name, false otherwise.

The function allows to compare database names according to the MySQL rules. The database names db1 and db2 are equal if:

  • db1 is NULL and db2 is NULL; or
  • db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to db2 in system character set (UTF8).

◆ find_db_tables()

static bool find_db_tables ( THD thd,
const dd::Schema schema,
const char *  db,
Table_ref **  tables 
)
static

Auxiliary function which retrieves list of all tables in the database from the data-dictionary.

◆ find_unknown_and_remove_deletable_files()

static bool find_unknown_and_remove_deletable_files ( THD thd,
MY_DIR dirp,
const char *  path 
)
static

Auxiliary function which checks if database directory has any files which won't be deleted automatically - either because we know that these are temporary/backup files which are safe for delete or by dropping the tables in the database.

Also deletes various temporary/backup files which are known to be safe to delete.

◆ get_default_db_collation() [1/2]

bool get_default_db_collation ( const dd::Schema schema,
const CHARSET_INFO **  collation 
)

◆ get_default_db_collation() [2/2]

bool get_default_db_collation ( THD thd,
const char *  db_name,
const CHARSET_INFO **  collation 
)

Return default database collation.

Parameters
thdThread context.
db_nameDatabase name.
[out]collationCharset object pointer if object exists else NULL.
Returns
false No error. true Error (thd->is_error is assumed to be set.)

◆ mysql_alter_db()

bool mysql_alter_db ( THD thd,
const char *  db,
HA_CREATE_INFO create_info 
)

◆ mysql_change_db()

bool mysql_change_db ( THD thd,
const LEX_CSTRING new_db_name,
bool  force_switch 
)

Change the current database and its attributes unconditionally.

Parameters
thdthread handle
new_db_namedatabase name
force_switchif force_switch is false, then the operation will fail if
                  - new_db_name is NULL or empty;

                  - OR new database name is invalid
                    (check_db_name() failed);

                  - OR user has no privilege on the new database;

                  - OR new database does not exist;

                if force_switch is true, then

                  - if new_db_name is NULL or empty, the current
                    database will be NULL, @@collation_database will
                    be set to @@collation_server, the operation will
                    succeed.

                  - if new database name is invalid
                    (check_db_name() failed), the current database
                    will be NULL, @@collation_database will be set to
                    @@collation_server, but the operation will fail;

                  - user privileges will not be checked
                    (THD::db_access however is updated);

                    TODO: is this really the intention?
                          (see sp-security.test).

                  - if new database does not exist,the current database
                    will be NULL, @@collation_database will be set to
                    @@collation_server, a warning will be thrown, the
                    operation will succeed.

The function checks that the database name corresponds to a valid and existent database, checks access rights and changes the current database with database attributes (@collation_database session variable, THD::db_access).

This function is not the only way to switch the database that is currently employed. When the replication slave thread switches the database before executing a query, it calls thd->set_db directly. However, if the query, in turn, uses a stored routine, the stored routine will use this function, even if it's run on the slave.

This function allocates the name of the database on the system heap: this is necessary to be able to uniformly change the database from any module of the server. Up to 5.0 different modules were using different memory to store the name of the database, and this led to memory corruption: a stack pointer set by Stored Procedures was used by replication after the stack address was long gone.

Returns
Operation status
Return values
falseSuccess
trueError

◆ mysql_change_db_impl()

static void mysql_change_db_impl ( THD thd,
const LEX_CSTRING new_db_name,
ulong  new_db_access,
const CHARSET_INFO new_db_charset 
)
static

Internal implementation: switch current database to a valid one.

Parameters
thdThread context.
new_db_nameName of the database to switch to. The function will take ownership of the name (the caller must not free the allocated memory). If the name is NULL, we're going to switch to NULL db.
new_db_accessPrivileges of the new database. (with roles)
new_db_charsetCharacter set of the new database.

◆ mysql_create_db()

bool mysql_create_db ( THD thd,
const char *  db,
HA_CREATE_INFO create_info 
)

Create a database.

Parameters
thdThread handler
dbName of database to create Function assumes that this is already validated.
create_infoDatabase create options (like character set)

SIDE-EFFECTS

  1. Report back to client that command succeeded (my_ok)
  2. Report errors to client
  3. Log event to binary log
Return values
falseok
trueError

◆ mysql_opt_change_db()

bool mysql_opt_change_db ( THD thd,
const LEX_CSTRING new_db_name,
LEX_STRING saved_db_name,
bool  force_switch,
bool *  cur_db_changed 
)

Change the current database and its attributes if needed.

Parameters
thdthread handle
new_db_namedatabase name
[in,out]saved_db_nameIN: "str" points to a buffer where to store the old database name, "length" contains the buffer size OUT: if the current (default) database is not NULL, its name is copied to the buffer pointed at by "str" and "length" is updated accordingly. Otherwise "str" is set to NULL and "length" is set to 0.
force_switchif the change of the current database shall be forced
See also
mysql_change_db()
Parameters
[out]cur_db_changedout-flag to indicate whether the current database has been changed (valid only if the function succeeded)

◆ mysql_rm_arc_files()

long mysql_rm_arc_files ( THD thd,
MY_DIR dirp,
const char *  org_path 
)
static

◆ mysql_rm_db()

bool mysql_rm_db ( THD thd,
const LEX_CSTRING db,
bool  if_exists 
)

Drop all tables, routines and events in a database and the database itself.

Parameters
thdThread handle
dbDatabase name in the case given by user It's already validated and set to lower case (if needed) when we come here
if_existsDon't give error if database doesn't exists
Note
We do a "best effort" - try to drop as much as possible. If dropping the database itself fails, we try to binlog the drop of the tables we managed to do.
Return values
falseOK (Database dropped)
trueError

◆ rm_dir_w_symlink()

static bool rm_dir_w_symlink ( const char *  org_path,
bool  send_error 
)
static

◆ set_db_default_charset()

static void set_db_default_charset ( const THD thd,
HA_CREATE_INFO create_info 
)
static

◆ thread_can_ignore_schema_read_only()

static bool thread_can_ignore_schema_read_only ( THD thd)
static

Check if the thread type is allowed to ignore the schema read only option.

Parameters
thdThread context.
Returns
true if the thread is allowed to ignore read only, otherwise false.

◆ use_ddl_log_for_schema_ddl()

static bool use_ddl_log_for_schema_ddl ( )
static

Helps decide whether we should use DDL Logging for schema DDLs (CREATE/DROP SCHEMA).

It helps us switch to traditional/non-atomic behaviour in the cases where upgrade hasn't yet reached "point of no return".

This is done to address below scenario: During a database upgrade, a crash might leave an incomplete log entry in the Log_DDL table. If the user attempts to revert to the previous version of the server, it won't recognize this leftover log, potentially causing a crash.

Return values
falsewe should not (during upgrade)
truewe should use it (every other scenario)

◆ write_db_cmd_to_binlog()

static bool write_db_cmd_to_binlog ( THD thd,
const char *  db,
bool  trx_cache 
)
static

Auxiliary function which writes CREATE/ALTER or DROP DATABASE statement to the binary log overriding connection's current database with one being dropped.

Variable Documentation

◆ del_exts

const char* del_exts[]
Initial value:
= {".frm", ".BAK", ".TMD", ".opt",
".OLD", ".cfg", ".SDI", NullS}
#define NullS
Definition of the null string (a null pointer of type char *), used in some of our string handling co...
Definition: nulls.h:33

◆ deletable_extentions

TYPELIB deletable_extentions
static
Initial value:
= {array_elements(del_exts) - 1, "del_exts",
del_exts, nullptr}
const char * del_exts[]
Definition: sql_db.cc:114
#define array_elements(A)
Definition: validate_password_imp.cc:50