2 Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 /* create and drop of databases */
21 #include "mysql_priv.h"
22 #include <mysys_err.h>
28 #include "log_event.h"
32 #include "debug_sync.h"
34 #define MAX_DROP_TABLE_Q_LEN 1024
36 const char *del_exts
[]= {".frm", ".BAK", ".TMD",".opt", NullS
};
37 static TYPELIB deletable_extentions
=
38 {array_elements(del_exts
)-1,"del_exts", del_exts
, NULL
};
40 static long mysql_rm_known_files(THD
*thd
, MY_DIR
*dirp
,
41 const char *db
, const char *path
, uint level
,
42 TABLE_LIST
**dropped_tables
);
44 long mysql_rm_arc_files(THD
*thd
, MY_DIR
*dirp
, const char *org_path
);
45 static my_bool
rm_dir_w_symlink(const char *org_path
, my_bool send_error
);
46 static void mysql_change_db_impl(THD
*thd
,
47 LEX_STRING
*new_db_name
,
49 CHARSET_INFO
*new_db_charset
);
52 /* Database lock hash */
54 pthread_mutex_t LOCK_lock_db
;
55 int creating_database
= 0; // how many database locks are made
58 /* Structure for database lock */
59 typedef struct my_dblock_st
61 char *name
; /* Database name */
62 uint name_length
; /* Database length name */
70 extern "C" uchar
* lock_db_get_key(my_dblock_t
*, size_t *, my_bool not_used
);
72 uchar
* lock_db_get_key(my_dblock_t
*ptr
, size_t *length
,
73 my_bool not_used
__attribute__((unused
)))
75 *length
= ptr
->name_length
;
76 return (uchar
*) ptr
->name
;
81 Free lock_db hash element.
84 extern "C" void lock_db_free_element(void *ptr
);
86 void lock_db_free_element(void *ptr
)
93 Put a database lock entry into the hash.
96 Insert a database lock entry into hash.
97 LOCK_db_lock must be previously locked.
104 static my_bool
lock_db_insert(const char *dbname
, uint length
)
108 DBUG_ENTER("lock_db_insert");
110 safe_mutex_assert_owner(&LOCK_lock_db
);
112 if (!(opt
= (my_dblock_t
*) hash_search(&lock_db_cache
,
113 (uchar
*) dbname
, length
)))
115 /* Db is not in the hash, insert it */
117 if (!my_multi_malloc(MYF(MY_WME
| MY_ZEROFILL
),
118 &opt
, (uint
) sizeof(*opt
), &tmp_name
, (uint
) length
+1,
126 strmov(opt
->name
, dbname
);
127 opt
->name_length
= length
;
129 if ((error
= my_hash_insert(&lock_db_cache
, (uchar
*) opt
)))
130 my_free(opt
, MYF(0));
139 Delete a database lock entry from hash.
142 void lock_db_delete(const char *name
, uint length
)
145 safe_mutex_assert_owner(&LOCK_lock_db
);
146 if ((opt
= (my_dblock_t
*)hash_search(&lock_db_cache
,
147 (const uchar
*) name
, length
)))
148 hash_delete(&lock_db_cache
, (uchar
*) opt
);
152 /* Database options hash */
153 static HASH dboptions
;
154 static my_bool dboptions_init
= 0;
155 static rw_lock_t LOCK_dboptions
;
157 /* Structure for database options */
158 typedef struct my_dbopt_st
160 char *name
; /* Database name */
161 uint name_length
; /* Database length name */
162 CHARSET_INFO
*charset
; /* Database default character set */
167 Function we use in the creation of our hash to get key.
170 extern "C" uchar
* dboptions_get_key(my_dbopt_t
*opt
, size_t *length
,
173 uchar
* dboptions_get_key(my_dbopt_t
*opt
, size_t *length
,
174 my_bool not_used
__attribute__((unused
)))
176 *length
= opt
->name_length
;
177 return (uchar
*) opt
->name
;
182 Helper function to write a query to binlog used by mysql_rm_db()
185 static inline int write_to_binlog(THD
*thd
, char *query
, uint q_len
,
186 char *db
, uint db_len
)
188 Query_log_event
qinfo(thd
, query
, q_len
, 0, 0, 0);
190 qinfo
.db_len
= db_len
;
191 return mysql_bin_log
.write(&qinfo
);
196 Function to free dboptions hash element
199 extern "C" void free_dbopt(void *dbopt
);
201 void free_dbopt(void *dbopt
)
203 my_free((uchar
*) dbopt
, MYF(0));
208 Initialize database option hash and locked database hash.
214 Must be called before any other database function is called.
221 bool my_database_names_init(void)
224 (void) my_rwlock_init(&LOCK_dboptions
, NULL
);
228 error
= hash_init(&dboptions
, lower_case_table_names
?
229 &my_charset_bin
: system_charset_info
,
230 32, 0, 0, (hash_get_key
) dboptions_get_key
,
232 hash_init(&lock_db_cache
, lower_case_table_names
?
233 &my_charset_bin
: system_charset_info
,
234 32, 0, 0, (hash_get_key
) lock_db_get_key
,
235 lock_db_free_element
,0);
244 Free database option hash and locked databases hash.
247 void my_database_names_free(void)
252 hash_free(&dboptions
);
253 (void) rwlock_destroy(&LOCK_dboptions
);
254 hash_free(&lock_db_cache
);
260 Cleanup cached options
263 void my_dbopt_cleanup(void)
265 rw_wrlock(&LOCK_dboptions
);
266 hash_free(&dboptions
);
267 hash_init(&dboptions
, lower_case_table_names
?
268 &my_charset_bin
: system_charset_info
,
269 32, 0, 0, (hash_get_key
) dboptions_get_key
,
271 rw_unlock(&LOCK_dboptions
);
276 Find database options in the hash.
279 Search a database options in the hash, usings its path.
280 Fills "create" on success.
287 static my_bool
get_dbopt(const char *dbname
, HA_CREATE_INFO
*create
)
293 length
= (uint
) strlen(dbname
);
295 rw_rdlock(&LOCK_dboptions
);
296 if ((opt
= (my_dbopt_t
*) hash_search(&dboptions
, (uchar
*) dbname
, length
)))
298 create
->default_table_charset
= opt
->charset
;
301 rw_unlock(&LOCK_dboptions
);
307 Writes database options into the hash.
310 Inserts database options into the hash, or updates
311 options if they are already in the hash.
318 static my_bool
put_dbopt(const char *dbname
, HA_CREATE_INFO
*create
)
323 DBUG_ENTER("put_dbopt");
325 length
= (uint
) strlen(dbname
);
327 rw_wrlock(&LOCK_dboptions
);
328 if (!(opt
= (my_dbopt_t
*) hash_search(&dboptions
, (uchar
*) dbname
, length
)))
330 /* Options are not in the hash, insert them */
332 if (!my_multi_malloc(MYF(MY_WME
| MY_ZEROFILL
),
333 &opt
, (uint
) sizeof(*opt
), &tmp_name
, (uint
) length
+1,
341 strmov(opt
->name
, dbname
);
342 opt
->name_length
= length
;
344 if ((error
= my_hash_insert(&dboptions
, (uchar
*) opt
)))
346 my_free(opt
, MYF(0));
351 /* Update / write options in hash */
352 opt
->charset
= create
->default_table_charset
;
355 rw_unlock(&LOCK_dboptions
);
361 Deletes database options from the hash.
364 void del_dbopt(const char *path
)
367 rw_wrlock(&LOCK_dboptions
);
368 if ((opt
= (my_dbopt_t
*)hash_search(&dboptions
, (const uchar
*) path
,
370 hash_delete(&dboptions
, (uchar
*) opt
);
371 rw_unlock(&LOCK_dboptions
);
376 Create database options file:
379 Currently database default charset is only stored there.
383 1 Could not create file or write to it. Error sent through my_error()
386 static bool write_db_opt(THD
*thd
, const char *path
, HA_CREATE_INFO
*create
)
389 char buf
[256]; // Should be enough for one option
392 if (!create
->default_table_charset
)
393 create
->default_table_charset
= thd
->variables
.collation_server
;
395 if (put_dbopt(path
, create
))
398 if ((file
=my_create(path
, CREATE_MODE
,O_RDWR
| O_TRUNC
,MYF(MY_WME
))) >= 0)
401 length
= (ulong
) (strxnmov(buf
, sizeof(buf
)-1, "default-character-set=",
402 create
->default_table_charset
->csname
,
403 "\ndefault-collation=",
404 create
->default_table_charset
->name
,
407 /* Error is written by my_write */
408 if (!my_write(file
,(uchar
*) buf
, length
, MYF(MY_NABP
+MY_WME
)))
410 my_close(file
,MYF(0));
417 Load database options file
420 path Path for option file
421 create Where to store the read options
427 1 No database file or could not open it
431 bool load_db_opt(THD
*thd
, const char *path
, HA_CREATE_INFO
*create
)
435 DBUG_ENTER("load_db_opt");
439 bzero((char*) create
,sizeof(*create
));
440 create
->default_table_charset
= thd
->variables
.collation_server
;
442 /* Check if options for this database are already in the hash */
443 if (!get_dbopt(path
, create
))
446 /* Otherwise, load options from the .opt file */
447 if ((file
=my_open(path
, O_RDONLY
| O_SHARE
, MYF(0))) < 0)
451 if (init_io_cache(&cache
, file
, IO_SIZE
, READ_CACHE
, 0, 0, MYF(0)))
454 while ((int) (nbytes
= my_b_gets(&cache
, (char*) buf
, sizeof(buf
))) > 0)
456 char *pos
= buf
+nbytes
-1;
457 /* Remove end space and control characters */
458 while (pos
> buf
&& !my_isgraph(&my_charset_latin1
, pos
[-1]))
461 if ((pos
= strchr(buf
, '=')))
463 if (!strncmp(buf
,"default-character-set", (pos
-buf
)))
466 Try character set name, and if it fails
467 try collation name, probably it's an old
468 4.1.0 db.opt file, which didn't have
469 separate default-character-set and
470 default-collation commands.
472 if (!(create
->default_table_charset
=
473 get_charset_by_csname(pos
+1, MY_CS_PRIMARY
, MYF(0))) &&
474 !(create
->default_table_charset
=
475 get_charset_by_name(pos
+1, MYF(0))))
477 sql_print_error("Error while loading database options: '%s':",path
);
478 sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET
),pos
+1);
479 create
->default_table_charset
= default_charset_info
;
482 else if (!strncmp(buf
,"default-collation", (pos
-buf
)))
484 if (!(create
->default_table_charset
= get_charset_by_name(pos
+1,
487 sql_print_error("Error while loading database options: '%s':",path
);
488 sql_print_error(ER(ER_UNKNOWN_COLLATION
),pos
+1);
489 create
->default_table_charset
= default_charset_info
;
495 Put the loaded value into the hash.
496 Note that another thread could've added the same
497 entry to the hash after we called get_dbopt(),
498 but it's not an error, as put_dbopt() takes this
499 possibility into account.
501 error
= put_dbopt(path
, create
);
503 end_io_cache(&cache
);
505 my_close(file
,MYF(0));
512 Retrieve database options by name. Load database options file or fetch from
516 load_db_opt_by_name()
517 db_name Database name
518 db_create_info Where to store the database options
521 load_db_opt_by_name() is a shortcut for load_db_opt().
524 Although load_db_opt_by_name() (and load_db_opt()) returns status of
525 the operation, it is useless usually and should be ignored. The problem
526 is that there are 1) system databases ("mysql") and 2) virtual
527 databases ("information_schema"), which do not contain options file.
528 So, load_db_opt[_by_name]() returns FALSE for these databases, but this
531 load_db_opt[_by_name]() clears db_create_info structure in any case, so
532 even on failure it contains valid data. So, common use case is just
533 call load_db_opt[_by_name]() without checking return value and use
534 db_create_info right after that.
536 RETURN VALUES (read NOTE!)
538 TRUE Failed to retrieve options
541 bool load_db_opt_by_name(THD
*thd
, const char *db_name
,
542 HA_CREATE_INFO
*db_create_info
)
544 char db_opt_path
[FN_REFLEN
+ 1];
547 Pass an empty file name, and the database options file name as extension
548 to avoid table name to file name encoding.
550 (void) build_table_filename(db_opt_path
, sizeof(db_opt_path
) - 1,
551 db_name
, "", MY_DB_OPT_FILE
, 0);
553 return load_db_opt(thd
, db_opt_path
, db_create_info
);
558 Return default database collation.
560 @param thd Thread context.
561 @param db_name Database name.
563 @return CHARSET_INFO object. The operation always return valid character
564 set, even if the database does not exist.
567 CHARSET_INFO
*get_default_db_collation(THD
*thd
, const char *db_name
)
569 HA_CREATE_INFO db_info
;
571 if (thd
->db
!= NULL
&& strcmp(db_name
, thd
->db
) == 0)
572 return thd
->db_charset
;
574 load_db_opt_by_name(thd
, db_name
, &db_info
);
577 NOTE: even if load_db_opt_by_name() fails,
578 db_info.default_table_charset contains valid character set
579 (collation_server). We should not fail if load_db_opt_by_name() fails,
580 because it is valid case. If a database has been created just by
581 "mkdir", it does not contain db.opt file, but it is valid database.
584 return db_info
.default_table_charset
;
594 db Name of database to create
595 Function assumes that this is already validated.
596 create_info Database create options (like character set)
597 silent Used by replication when internally creating a database.
598 In this case the entry should not be logged.
601 1. Report back to client that command succeeded (my_ok)
602 2. Report errors to client
603 3. Log event to binary log
604 (The 'silent' flags turns off 1 and 3.)
612 int mysql_create_db(THD
*thd
, char *db
, HA_CREATE_INFO
*create_info
,
615 char path
[FN_REFLEN
+16];
616 char tmp_query
[FN_REFLEN
+16];
620 uint create_options
= create_info
? create_info
->options
: 0;
622 DBUG_ENTER("mysql_create_db");
624 /* do not create 'information_schema' db */
625 if (is_schema_db(db
))
627 my_error(ER_DB_CREATE_EXISTS
, MYF(0), db
);
632 Do not create database if another thread is holding read lock.
633 Wait for global read lock before acquiring LOCK_mysql_create_db.
634 After wait_if_global_read_lock() we have protection against another
635 global read lock. If we would acquire LOCK_mysql_create_db first,
636 another thread could step in and get the global read lock before we
637 reach wait_if_global_read_lock(). If this thread tries the same as we
638 (admin a db), it would then go and wait on LOCK_mysql_create_db...
639 Furthermore wait_if_global_read_lock() checks if the current thread
640 has the global read lock and refuses the operation with
641 ER_CANT_UPDATE_WITH_READLOCK if applicable.
643 if (wait_if_global_read_lock(thd
, 0, 1))
650 Close and mark for re-open all HANDLER tables which are marked for flush
651 or which there are pending conflicing locks against. This is needed to
654 if (thd
->handler_tables_hash
.records
)
656 pthread_mutex_lock(&LOCK_open
);
658 pthread_mutex_unlock(&LOCK_open
);
661 VOID(pthread_mutex_lock(&LOCK_mysql_create_db
));
663 /* Check directory */
664 path_len
= build_table_filename(path
, sizeof(path
) - 1, db
, "", "", 0);
665 path
[path_len
-1]= 0; // Remove last '/' from path
667 if (my_stat(path
,&stat_info
,MYF(0)))
669 if (!(create_options
& HA_LEX_CREATE_IF_NOT_EXISTS
))
671 my_error(ER_DB_CREATE_EXISTS
, MYF(0), db
);
675 push_warning_printf(thd
, MYSQL_ERROR::WARN_LEVEL_NOTE
,
676 ER_DB_CREATE_EXISTS
, ER(ER_DB_CREATE_EXISTS
), db
);
682 if (my_errno
!= ENOENT
)
684 my_error(EE_STAT
, MYF(0), path
, my_errno
);
687 if (my_mkdir(path
,0777,MYF(0)) < 0)
689 my_error(ER_CANT_CREATE_DB
, MYF(0), db
, my_errno
);
695 path
[path_len
-1]= FN_LIBCHAR
;
696 strmake(path
+path_len
, MY_DB_OPT_FILE
, sizeof(path
)-path_len
-1);
697 if (write_db_opt(thd
, path
, create_info
))
700 Could not create options file.
701 Restore things to beginning.
704 if (rmdir(path
) >= 0)
710 We come here when we managed to create the database, but not the option
711 file. In this case it's best to just continue as if nothing has
712 happened. (This is a very unlikely senario)
722 char db_name_quoted
[2 * FN_REFLEN
+ sizeof("create database ") + 2];
725 if (!thd
->query()) // Only in replication
727 id_len
= my_strmov_quoted_identifier(thd
, (char *) db_name_quoted
, db
,
729 db_name_quoted
[id_len
]= '\0';
731 query_length
= (uint
) (strxmov(tmp_query
,"create database ",
732 db_name_quoted
, NullS
) - tmp_query
);
737 query_length
= thd
->query_length();
740 ha_binlog_log_query(thd
, 0, LOGCOM_CREATE_DB
,
744 if (mysql_bin_log
.is_open())
746 int errcode
= query_error_code(thd
, TRUE
);
747 Query_log_event
qinfo(thd
, query
, query_length
, 0,
748 /* suppress_use */ TRUE
, errcode
);
751 Write should use the database being created as the "current
752 database" and not the threads current database, which is the
753 default. If we do not change the "current database" to the
754 database being created, the CREATE statement will not be
755 replicated when using --binlog-do-db to select databases to be
758 An example (--binlog-do-db=sisyfos):
760 CREATE DATABASE bob; # Not replicated
761 USE bob; # 'bob' is the current database
762 CREATE DATABASE sisyfos; # Not replicated since 'bob' is
764 USE sisyfos; # Will give error on slave since
765 # database does not exist.
768 qinfo
.db_len
= strlen(db
);
770 /* These DDL methods and logging protected with LOCK_mysql_create_db */
771 if (mysql_bin_log
.write(&qinfo
))
781 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db
));
782 start_waiting_global_read_lock(thd
);
788 /* db-name is already validated when we come here */
790 bool mysql_alter_db(THD
*thd
, const char *db
, HA_CREATE_INFO
*create_info
)
792 char path
[FN_REFLEN
+16];
795 DBUG_ENTER("mysql_alter_db");
798 Do not alter database if another thread is holding read lock.
799 Wait for global read lock before acquiring LOCK_mysql_create_db.
800 After wait_if_global_read_lock() we have protection against another
801 global read lock. If we would acquire LOCK_mysql_create_db first,
802 another thread could step in and get the global read lock before we
803 reach wait_if_global_read_lock(). If this thread tries the same as we
804 (admin a db), it would then go and wait on LOCK_mysql_create_db...
805 Furthermore wait_if_global_read_lock() checks if the current thread
806 has the global read lock and refuses the operation with
807 ER_CANT_UPDATE_WITH_READLOCK if applicable.
809 if ((error
=wait_if_global_read_lock(thd
,0,1)))
813 Close and mark for re-open all HANDLER tables which are marked for flush
814 or which there are pending conflicing locks against. This is needed to
817 if (thd
->handler_tables_hash
.records
)
819 pthread_mutex_lock(&LOCK_open
);
821 pthread_mutex_unlock(&LOCK_open
);
824 VOID(pthread_mutex_lock(&LOCK_mysql_create_db
));
827 Recreate db options file: /dbpath/.db.opt
828 We pass MY_DB_OPT_FILE as "extension" to avoid
829 "table name to file name" encoding.
831 build_table_filename(path
, sizeof(path
) - 1, db
, "", MY_DB_OPT_FILE
, 0);
832 if ((error
=write_db_opt(thd
, path
, create_info
)))
835 /* Change options if current database is being altered. */
837 if (thd
->db
&& !strcmp(thd
->db
,db
))
839 thd
->db_charset
= create_info
->default_table_charset
?
840 create_info
->default_table_charset
:
841 thd
->variables
.collation_server
;
842 thd
->variables
.collation_database
= thd
->db_charset
;
845 ha_binlog_log_query(thd
, 0, LOGCOM_ALTER_DB
,
846 thd
->query(), thd
->query_length(),
849 if (mysql_bin_log
.is_open())
852 Query_log_event
qinfo(thd
, thd
->query(), thd
->query_length(), 0,
853 /* suppress_use */ TRUE
, 0);
856 Write should use the database being created as the "current
857 database" and not the threads current database, which is the
861 qinfo
.db_len
= strlen(db
);
863 /* These DDL methods and logging protected with LOCK_mysql_create_db */
864 if ((error
= mysql_bin_log
.write(&qinfo
)))
870 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db
));
871 start_waiting_global_read_lock(thd
);
878 Drop all tables in a database and the database itself
883 db Database name in the case given by user
884 It's already validated and set to lower case
885 (if needed) when we come here
886 if_exists Don't give error if database doesn't exists
887 silent Don't generate errors
890 FALSE ok (Database dropped)
894 bool mysql_rm_db(THD
*thd
,char *db
,bool if_exists
, bool silent
)
898 char path
[2 * FN_REFLEN
+ 16];
901 TABLE_LIST
* dropped_tables
= 0;
902 DBUG_ENTER("mysql_rm_db");
905 Do not drop database if another thread is holding read lock.
906 Wait for global read lock before acquiring LOCK_mysql_create_db.
907 After wait_if_global_read_lock() we have protection against another
908 global read lock. If we would acquire LOCK_mysql_create_db first,
909 another thread could step in and get the global read lock before we
910 reach wait_if_global_read_lock(). If this thread tries the same as we
911 (admin a db), it would then go and wait on LOCK_mysql_create_db...
912 Furthermore wait_if_global_read_lock() checks if the current thread
913 has the global read lock and refuses the operation with
914 ER_CANT_UPDATE_WITH_READLOCK if applicable.
916 if (wait_if_global_read_lock(thd
, 0, 1))
923 Close and mark for re-open all HANDLER tables which are marked for flush
924 or which there are pending conflicing locks against. This is needed to
927 if (thd
->handler_tables_hash
.records
)
929 pthread_mutex_lock(&LOCK_open
);
931 pthread_mutex_unlock(&LOCK_open
);
934 VOID(pthread_mutex_lock(&LOCK_mysql_create_db
));
936 length
= build_table_filename(path
, sizeof(path
) - 1, db
, "", "", 0);
937 strmov(path
+length
, MY_DB_OPT_FILE
); // Append db option file name
938 del_dbopt(path
); // Remove dboption hash entry
939 path
[length
]= '\0'; // Remove file name
941 /* See if the directory exists */
942 if (!(dirp
= my_dir(path
,MYF(MY_DONT_SORT
))))
947 my_error(ER_DB_DROP_EXISTS
, MYF(0), db
);
951 push_warning_printf(thd
, MYSQL_ERROR::WARN_LEVEL_NOTE
,
952 ER_DB_DROP_EXISTS
, ER(ER_DB_DROP_EXISTS
), db
);
956 pthread_mutex_lock(&LOCK_open
);
957 remove_db_from_cache(db
);
958 pthread_mutex_unlock(&LOCK_open
);
962 We temporarily disable the binary log while dropping the objects
963 in the database. Since the DROP DATABASE statement is always
964 replicated as a statement, execution of it will drop all objects
965 in the database on the slave as well, so there is no need to
966 replicate the removal of the individual objects in the database
969 This is more of a safety precaution, since normally no objects
970 should be dropped while the database is being cleaned, but in
971 the event that a change in the code to remove other objects is
972 made, these drops should still not be logged.
974 Notice that the binary log have to be enabled over the call to
975 ha_drop_database(), since NDB otherwise detects the binary log
976 as disabled and will not log the drop database statement on any
977 other connected server.
979 if ((deleted
= mysql_rm_known_files(thd
, dirp
, db
, path
, 0,
980 &dropped_tables
)) >= 0)
982 ha_drop_database(path
);
983 tmp_disable_binlog(thd
);
984 query_cache_invalidate1(db
);
985 (void) sp_drop_db_routines(thd
, db
); /* @todo Do not ignore errors */
986 #ifdef HAVE_EVENT_SCHEDULER
987 Events::drop_schema_events(thd
, db
);
990 reenable_binlog(thd
);
994 if (!silent
&& deleted
>=0)
998 // quoted db name + wraping quote
999 char buffer_temp
[2 * FN_REFLEN
+ 2];
1004 /* The client used the old obsolete mysql_drop_db() call */
1006 id_len
= my_strmov_quoted_identifier(thd
, buffer_temp
, db
, strlen(db
));
1007 buffer_temp
[id_len
] ='\0';
1008 query_length
= (uint
) (strxmov(path
, "DROP DATABASE ", buffer_temp
, "",
1013 query
= thd
->query();
1014 query_length
= thd
->query_length();
1016 if (mysql_bin_log
.is_open())
1019 Query_log_event
qinfo(thd
, query
, query_length
, 0,
1020 /* suppress_use */ TRUE
, 0);
1022 Write should use the database being created as the "current
1023 database" and not the threads current database, which is the
1027 qinfo
.db_len
= strlen(db
);
1029 /* These DDL methods and logging protected with LOCK_mysql_create_db */
1030 if (mysql_bin_log
.write(&qinfo
))
1037 thd
->server_status
|= SERVER_STATUS_DB_DROPPED
;
1038 my_ok(thd
, (ulong
) deleted
);
1039 thd
->server_status
&= ~SERVER_STATUS_DB_DROPPED
;
1041 else if (mysql_bin_log
.is_open())
1043 char *query
, *query_pos
, *query_end
, *query_data_start
;
1044 char temp_identifier
[ 2 * FN_REFLEN
+ 2];
1046 uint db_len
, id_length
=0;
1048 if (!(query
= (char*) thd
->alloc(MAX_DROP_TABLE_Q_LEN
)))
1049 goto exit
; /* not much else we can do */
1050 query_pos
= query_data_start
= strmov(query
,"DROP TABLE ");
1051 query_end
= query
+ MAX_DROP_TABLE_Q_LEN
;
1054 for (tbl
= dropped_tables
; tbl
; tbl
= tbl
->next_local
)
1058 /* 3 for the quotes and the comma*/
1059 tbl_name_len
= strlen(tbl
->table_name
) + 3;
1060 if (query_pos
+ tbl_name_len
+ 1 >= query_end
)
1062 /* These DDL methods and logging protected with LOCK_mysql_create_db */
1063 if (write_to_binlog(thd
, query
, query_pos
-1 - query
, db
, db_len
))
1068 query_pos
= query_data_start
;
1070 id_length
= my_strmov_quoted_identifier(thd
, (char *)temp_identifier
,
1071 tbl
->table_name
, 0);
1072 temp_identifier
[id_length
]= '\0';
1073 query_pos
= strmov(query_pos
,(char *)&temp_identifier
);
1077 if (query_pos
!= query_data_start
)
1079 /* These DDL methods and logging protected with LOCK_mysql_create_db */
1080 if (write_to_binlog(thd
, query
, query_pos
-1 - query
, db
, db_len
))
1090 If this database was the client's selected database, we silently
1091 change the client's selected database to nothing (to have an empty
1092 SELECT DATABASE() in the future). For this we free() thd->db and set
1095 if (thd
->db
&& !strcmp(thd
->db
, db
))
1096 mysql_change_db_impl(thd
, NULL
, 0, thd
->variables
.collation_server
);
1097 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db
));
1098 start_waiting_global_read_lock(thd
);
1104 Removes files with known extensions plus all found subdirectories that
1105 are 2 hex digits (raid directories).
1106 thd MUST be set when calling this function!
1109 static long mysql_rm_known_files(THD
*thd
, MY_DIR
*dirp
, const char *db
,
1110 const char *org_path
, uint level
,
1111 TABLE_LIST
**dropped_tables
)
1114 ulong found_other_files
=0;
1115 char filePath
[FN_REFLEN
];
1116 TABLE_LIST
*tot_list
=0, **tot_list_next
;
1117 List
<String
> raid_dirs
;
1118 DBUG_ENTER("mysql_rm_known_files");
1119 DBUG_PRINT("enter",("path: %s", org_path
));
1121 tot_list_next
= &tot_list
;
1124 idx
< (uint
) dirp
->number_off_files
&& !thd
->killed
;
1127 FILEINFO
*file
=dirp
->dir_entry
+idx
;
1129 DBUG_PRINT("info",("Examining: %s", file
->name
));
1131 /* skiping . and .. */
1132 if (file
->name
[0] == '.' && (!file
->name
[1] ||
1133 (file
->name
[1] == '.' && !file
->name
[2])))
1136 /* Check if file is a raid directory */
1137 if ((my_isdigit(system_charset_info
, file
->name
[0]) ||
1138 (file
->name
[0] >= 'a' && file
->name
[0] <= 'f')) &&
1139 (my_isdigit(system_charset_info
, file
->name
[1]) ||
1140 (file
->name
[1] >= 'a' && file
->name
[1] <= 'f')) &&
1141 !file
->name
[2] && !level
)
1143 char newpath
[FN_REFLEN
], *copy_of_path
;
1148 strxmov(newpath
,org_path
,"/",file
->name
,NullS
);
1149 length
= unpack_filename(newpath
,newpath
);
1150 if ((new_dirp
= my_dir(newpath
,MYF(MY_DONT_SORT
))))
1152 DBUG_PRINT("my",("New subdir found: %s", newpath
));
1153 if ((mysql_rm_known_files(thd
, new_dirp
, NullS
, newpath
,1,0)) < 0)
1155 if (!(copy_of_path
= (char*) thd
->memdup(newpath
, length
+1)) ||
1156 !(dir
= new (thd
->mem_root
) String(copy_of_path
, length
,
1157 &my_charset_bin
)) ||
1158 raid_dirs
.push_back(dir
))
1162 found_other_files
++;
1165 else if (file
->name
[0] == 'a' && file
->name
[1] == 'r' &&
1166 file
->name
[2] == 'c' && file
->name
[3] == '\0')
1169 Those archives are obsolete, but following code should
1170 exist to remove existent "arc" directories.
1172 char newpath
[FN_REFLEN
];
1174 strxmov(newpath
, org_path
, "/", "arc", NullS
);
1175 (void) unpack_filename(newpath
, newpath
);
1176 if ((new_dirp
= my_dir(newpath
, MYF(MY_DONT_SORT
))))
1178 DBUG_PRINT("my",("Archive subdir found: %s", newpath
));
1179 if ((mysql_rm_arc_files(thd
, new_dirp
, newpath
)) < 0)
1183 found_other_files
++;
1186 if (!(extension
= strrchr(file
->name
, '.')))
1187 extension
= strend(file
->name
);
1188 if (find_type(extension
, &deletable_extentions
,1+2) <= 0)
1190 if (find_type(extension
, ha_known_exts(),1+2) <= 0)
1191 found_other_files
++;
1194 /* just for safety we use files_charset_info */
1195 if (db
&& !my_strcasecmp(files_charset_info
,
1196 extension
, reg_ext
))
1198 /* Drop the table nicely */
1199 *extension
= 0; // Remove extension
1200 TABLE_LIST
*table_list
=(TABLE_LIST
*)
1201 thd
->calloc(sizeof(*table_list
) +
1203 MYSQL50_TABLE_NAME_PREFIX_LENGTH
+
1204 strlen(file
->name
) + 1);
1208 table_list
->db
= (char*) (table_list
+1);
1209 table_list
->table_name
= strmov(table_list
->db
, db
) + 1;
1210 VOID(filename_to_tablename(file
->name
, table_list
->table_name
,
1211 MYSQL50_TABLE_NAME_PREFIX_LENGTH
+
1212 strlen(file
->name
) + 1));
1214 /* To be able to correctly look up the table in the table cache. */
1215 if (lower_case_table_names
)
1216 table_list
->table_name_length
= my_casedn_str(files_charset_info
,
1217 table_list
->table_name
);
1219 table_list
->alias
= table_list
->table_name
; // If lower_case_table_names=2
1220 table_list
->internal_tmp_table
= is_prefix(file
->name
, tmp_file_prefix
);
1221 /* Link into list */
1222 (*tot_list_next
)= table_list
;
1223 tot_list_next
= &table_list
->next_local
;
1228 strxmov(filePath
, org_path
, "/", file
->name
, NullS
);
1230 We ignore ENOENT error in order to skip files that was deleted
1231 by concurrently running statement like REAPIR TABLE ...
1233 if (my_delete_with_symlink(filePath
, MYF(0)) &&
1236 my_error(EE_DELETE
, MYF(0), filePath
, my_errno
);
1248 Drop_table_error_handler
err_handler(thd
->get_internal_handler());
1250 thd
->push_internal_handler(&err_handler
);
1251 res
= mysql_rm_table_part2(thd
, tot_list
, 1, 0, 1, 1);
1252 thd
->pop_internal_handler();
1257 /* Remove RAID directories */
1259 List_iterator
<String
> it(raid_dirs
);
1262 if (rmdir(dir
->c_ptr()) < 0)
1263 found_other_files
++;
1268 *dropped_tables
= tot_list
;
1271 If the directory is a symbolic link, remove the link first, then
1272 remove the directory the symbolic link pointed at
1274 if (found_other_files
)
1276 my_error(ER_DB_DROP_RMDIR
, MYF(0), org_path
, EEXIST
);
1281 /* Don't give errors if we can't delete 'RAID' directory */
1282 if (rm_dir_w_symlink(org_path
, level
== 0))
1286 DBUG_RETURN(deleted
);
1295 Remove directory with symlink
1299 org_path path of derictory
1300 send_error send errors
1306 static my_bool
rm_dir_w_symlink(const char *org_path
, my_bool send_error
)
1308 char tmp_path
[FN_REFLEN
], *pos
;
1309 char *path
= tmp_path
;
1310 DBUG_ENTER("rm_dir_w_symlink");
1311 unpack_filename(tmp_path
, org_path
);
1312 #ifdef HAVE_READLINK
1314 char tmp2_path
[FN_REFLEN
];
1316 /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1318 if (pos
> path
&& pos
[-1] == FN_LIBCHAR
)
1321 if ((error
= my_readlink(tmp2_path
, path
, MYF(MY_WME
))) < 0)
1325 if (my_delete(path
, MYF(send_error
? MY_WME
: 0)))
1327 DBUG_RETURN(send_error
);
1329 /* Delete directory symbolic link pointed at */
1333 /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1336 if (pos
> path
&& pos
[-1] == FN_LIBCHAR
)
1338 if (rmdir(path
) < 0 && send_error
)
1340 my_error(ER_DB_DROP_RMDIR
, MYF(0), path
, errno
);
1348 Remove .frm archives from directory
1352 dirp list of files in archive directory
1354 org_path path of archive directory
1357 > 0 number of removed files
1361 A support of "arc" directories is obsolete, however this
1362 function should exist to remove existent "arc" directories.
1364 long mysql_rm_arc_files(THD
*thd
, MY_DIR
*dirp
, const char *org_path
)
1367 ulong found_other_files
= 0;
1368 char filePath
[FN_REFLEN
];
1369 DBUG_ENTER("mysql_rm_arc_files");
1370 DBUG_PRINT("enter", ("path: %s", org_path
));
1373 idx
< (uint
) dirp
->number_off_files
&& !thd
->killed
;
1376 FILEINFO
*file
=dirp
->dir_entry
+idx
;
1377 char *extension
, *revision
;
1378 DBUG_PRINT("info",("Examining: %s", file
->name
));
1380 /* skiping . and .. */
1381 if (file
->name
[0] == '.' && (!file
->name
[1] ||
1382 (file
->name
[1] == '.' && !file
->name
[2])))
1385 extension
= fn_ext(file
->name
);
1386 if (extension
[0] != '.' ||
1387 extension
[1] != 'f' || extension
[2] != 'r' ||
1388 extension
[3] != 'm' || extension
[4] != '-')
1390 found_other_files
++;
1393 revision
= extension
+5;
1394 while (*revision
&& my_isdigit(system_charset_info
, *revision
))
1398 found_other_files
++;
1401 strxmov(filePath
, org_path
, "/", file
->name
, NullS
);
1402 if (my_delete_with_symlink(filePath
,MYF(MY_WME
)))
1414 If the directory is a symbolic link, remove the link first, then
1415 remove the directory the symbolic link pointed at
1417 if (!found_other_files
&&
1418 rm_dir_w_symlink(org_path
, 0))
1420 DBUG_RETURN(deleted
);
1429 @brief Internal implementation: switch current database to a valid one.
1431 @param thd Thread context.
1432 @param new_db_name Name of the database to switch to. The function will
1433 take ownership of the name (the caller must not free
1434 the allocated memory). If the name is NULL, we're
1435 going to switch to NULL db.
1436 @param new_db_access Privileges of the new database.
1437 @param new_db_charset Character set of the new database.
1440 static void mysql_change_db_impl(THD
*thd
,
1441 LEX_STRING
*new_db_name
,
1442 ulong new_db_access
,
1443 CHARSET_INFO
*new_db_charset
)
1445 /* 1. Change current database in THD. */
1447 if (new_db_name
== NULL
)
1450 THD::set_db() does all the job -- it frees previous database name and
1454 thd
->set_db(NULL
, 0);
1456 else if (new_db_name
== &INFORMATION_SCHEMA_NAME
)
1459 Here we must use THD::set_db(), because we want to copy
1460 INFORMATION_SCHEMA_NAME constant.
1463 thd
->set_db(INFORMATION_SCHEMA_NAME
.str
, INFORMATION_SCHEMA_NAME
.length
);
1468 Here we already have a copy of database name to be used in THD. So,
1469 we just call THD::reset_db(). Since THD::reset_db() does not releases
1470 the previous database name, we should do it explicitly.
1472 pthread_mutex_lock(&thd
->LOCK_thd_data
);
1475 DEBUG_SYNC(thd
, "after_freeing_thd_db");
1476 thd
->reset_db(new_db_name
->str
, new_db_name
->length
);
1477 pthread_mutex_unlock(&thd
->LOCK_thd_data
);
1480 /* 2. Update security context. */
1482 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1483 thd
->security_ctx
->db_access
= new_db_access
;
1486 /* 3. Update db-charset environment variables. */
1488 thd
->db_charset
= new_db_charset
;
1489 thd
->variables
.collation_database
= new_db_charset
;
1495 Backup the current database name before switch.
1497 @param[in] thd thread handle
1498 @param[in, out] saved_db_name IN: "str" points to a buffer where to store
1499 the old database name, "length" contains the
1501 OUT: if the current (default) database is
1502 not NULL, its name is copied to the
1503 buffer pointed at by "str"
1504 and "length" is updated accordingly.
1505 Otherwise "str" is set to NULL and
1506 "length" is set to 0.
1509 static void backup_current_db_name(THD
*thd
,
1510 LEX_STRING
*saved_db_name
)
1514 /* No current (default) database selected. */
1516 saved_db_name
->str
= NULL
;
1517 saved_db_name
->length
= 0;
1521 strmake(saved_db_name
->str
, thd
->db
, saved_db_name
->length
- 1);
1522 saved_db_name
->length
= thd
->db_length
;
1528 Return TRUE if db1_name is equal to db2_name, FALSE otherwise.
1530 The function allows to compare database names according to the MySQL
1531 rules. The database names db1 and db2 are equal if:
1532 - db1 is NULL and db2 is NULL;
1534 - db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
1535 db2 in system character set (UTF8).
1539 cmp_db_names(const char *db1_name
,
1540 const char *db2_name
)
1543 /* db1 is NULL and db2 is NULL */
1544 (!db1_name
&& !db2_name
) ||
1546 /* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
1547 (db1_name
&& db2_name
&&
1548 my_strcasecmp(system_charset_info
, db1_name
, db2_name
) == 0);
1553 @brief Change the current database and its attributes unconditionally.
1555 @param thd thread handle
1556 @param new_db_name database name
1557 @param force_switch if force_switch is FALSE, then the operation will fail if
1559 - new_db_name is NULL or empty;
1561 - OR new database name is invalid
1562 (check_db_name() failed);
1564 - OR user has no privilege on the new database;
1566 - OR new database does not exist;
1568 if force_switch is TRUE, then
1570 - if new_db_name is NULL or empty, the current
1571 database will be NULL, @@collation_database will
1572 be set to @@collation_server, the operation will
1575 - if new database name is invalid
1576 (check_db_name() failed), the current database
1577 will be NULL, @@collation_database will be set to
1578 @@collation_server, but the operation will fail;
1580 - user privileges will not be checked
1581 (THD::db_access however is updated);
1583 TODO: is this really the intention?
1584 (see sp-security.test).
1586 - if new database does not exist,the current database
1587 will be NULL, @@collation_database will be set to
1588 @@collation_server, a warning will be thrown, the
1589 operation will succeed.
1591 @details The function checks that the database name corresponds to a
1592 valid and existent database, checks access rights and changes the current
1593 database with database attributes (@@collation_database session variable,
1596 This function is not the only way to switch the database that is
1597 currently employed. When the replication slave thread switches the
1598 database before executing a query, it calls thd->set_db directly.
1599 However, if the query, in turn, uses a stored routine, the stored routine
1600 will use this function, even if it's run on the slave.
1602 This function allocates the name of the database on the system heap: this
1603 is necessary to be able to uniformly change the database from any module
1604 of the server. Up to 5.0 different modules were using different memory to
1605 store the name of the database, and this led to memory corruption:
1606 a stack pointer set by Stored Procedures was used by replication after
1607 the stack address was long gone.
1609 @return Operation status
1610 @retval FALSE Success
1614 bool mysql_change_db(THD
*thd
, const LEX_STRING
*new_db_name
, bool force_switch
)
1616 LEX_STRING new_db_file_name
;
1618 Security_context
*sctx
= thd
->security_ctx
;
1619 ulong db_access
= sctx
->db_access
;
1620 CHARSET_INFO
*db_default_cl
;
1622 DBUG_ENTER("mysql_change_db");
1623 DBUG_PRINT("enter",("name: '%s'", new_db_name
->str
));
1625 if (new_db_name
== NULL
||
1626 new_db_name
->length
== 0)
1631 This can happen only if we're switching the current database back
1632 after loading stored program. The thing is that loading of stored
1633 program can happen when there is no current database.
1635 TODO: actually, new_db_name and new_db_name->str seem to be always
1636 non-NULL. In case of stored program, new_db_name->str == "" and
1637 new_db_name->length == 0.
1640 mysql_change_db_impl(thd
, NULL
, 0, thd
->variables
.collation_server
);
1646 my_message(ER_NO_DB_ERROR
, ER(ER_NO_DB_ERROR
), MYF(0));
1652 if (is_schema_db(new_db_name
->str
, new_db_name
->length
))
1654 /* Switch the current database to INFORMATION_SCHEMA. */
1656 mysql_change_db_impl(thd
, &INFORMATION_SCHEMA_NAME
, SELECT_ACL
,
1657 system_charset_info
);
1663 Now we need to make a copy because check_db_name requires a
1664 non-constant argument. Actually, it takes database file name.
1666 TODO: fix check_db_name().
1669 new_db_file_name
.str
= my_strndup(new_db_name
->str
, new_db_name
->length
,
1671 new_db_file_name
.length
= new_db_name
->length
;
1673 if (new_db_file_name
.str
== NULL
)
1674 DBUG_RETURN(TRUE
); /* the error is set */
1677 NOTE: if check_db_name() fails, we should throw an error in any case,
1678 even if we are called from sp_head::execute().
1680 It's next to impossible however to get this error when we are called
1681 from sp_head::execute(). But let's switch the current database to NULL
1682 in this case to be sure.
1685 if (check_db_name(&new_db_file_name
))
1687 my_error(ER_WRONG_DB_NAME
, MYF(0), new_db_file_name
.str
);
1688 my_free(new_db_file_name
.str
, MYF(0));
1691 mysql_change_db_impl(thd
, NULL
, 0, thd
->variables
.collation_server
);
1696 DBUG_PRINT("info",("Use database: %s", new_db_file_name
.str
));
1698 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1700 test_all_bits(sctx
->master_access
, DB_ACLS
) ?
1705 new_db_file_name
.str
,
1706 FALSE
) | sctx
->master_access
;
1708 if (!force_switch
&&
1709 !(db_access
& DB_ACLS
) &&
1710 check_grant_db(thd
, new_db_file_name
.str
))
1712 my_error(ER_DBACCESS_DENIED_ERROR
, MYF(0),
1715 new_db_file_name
.str
);
1716 general_log_print(thd
, COM_INIT_DB
, ER(ER_DBACCESS_DENIED_ERROR
),
1717 sctx
->priv_user
, sctx
->priv_host
, new_db_file_name
.str
);
1718 my_free(new_db_file_name
.str
, MYF(0));
1723 DEBUG_SYNC(thd
, "before_db_dir_check");
1725 if (check_db_dir_existence(new_db_file_name
.str
))
1729 /* Throw a warning and free new_db_file_name. */
1731 push_warning_printf(thd
, MYSQL_ERROR::WARN_LEVEL_NOTE
,
1732 ER_BAD_DB_ERROR
, ER(ER_BAD_DB_ERROR
),
1733 new_db_file_name
.str
);
1735 my_free(new_db_file_name
.str
, MYF(0));
1737 /* Change db to NULL. */
1739 mysql_change_db_impl(thd
, NULL
, 0, thd
->variables
.collation_server
);
1741 /* The operation succeed. */
1747 /* Report an error and free new_db_file_name. */
1749 my_error(ER_BAD_DB_ERROR
, MYF(0), new_db_file_name
.str
);
1750 my_free(new_db_file_name
.str
, MYF(0));
1752 /* The operation failed. */
1759 NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1760 attributes and will be freed in THD::~THD().
1763 db_default_cl
= get_default_db_collation(thd
, new_db_file_name
.str
);
1765 mysql_change_db_impl(thd
, &new_db_file_name
, db_access
, db_default_cl
);
1772 Change the current database and its attributes if needed.
1774 @param thd thread handle
1775 @param new_db_name database name
1776 @param[in, out] saved_db_name IN: "str" points to a buffer where to store
1777 the old database name, "length" contains the
1779 OUT: if the current (default) database is
1780 not NULL, its name is copied to the
1781 buffer pointed at by "str"
1782 and "length" is updated accordingly.
1783 Otherwise "str" is set to NULL and
1784 "length" is set to 0.
1785 @param force_switch @see mysql_change_db()
1786 @param[out] cur_db_changed out-flag to indicate whether the current
1787 database has been changed (valid only if
1788 the function suceeded)
1791 bool mysql_opt_change_db(THD
*thd
,
1792 const LEX_STRING
*new_db_name
,
1793 LEX_STRING
*saved_db_name
,
1795 bool *cur_db_changed
)
1797 *cur_db_changed
= !cmp_db_names(thd
->db
, new_db_name
->str
);
1799 if (!*cur_db_changed
)
1802 backup_current_db_name(thd
, saved_db_name
);
1804 return mysql_change_db(thd
, new_db_name
, force_switch
);
1809 lock_databases(THD
*thd
, const char *db1
, uint length1
,
1810 const char *db2
, uint length2
)
1812 pthread_mutex_lock(&LOCK_lock_db
);
1813 while (!thd
->killed
&&
1814 (hash_search(&lock_db_cache
,(uchar
*) db1
, length1
) ||
1815 hash_search(&lock_db_cache
,(uchar
*) db2
, length2
)))
1817 wait_for_condition(thd
, &LOCK_lock_db
, &COND_refresh
);
1818 pthread_mutex_lock(&LOCK_lock_db
);
1823 pthread_mutex_unlock(&LOCK_lock_db
);
1827 lock_db_insert(db1
, length1
);
1828 lock_db_insert(db2
, length2
);
1829 creating_database
++;
1832 Wait if a concurent thread is creating a table at the same time.
1833 The assumption here is that it will not take too long until
1834 there is a point in time when a table is not created.
1837 while (!thd
->killed
&& creating_table
)
1839 wait_for_condition(thd
, &LOCK_lock_db
, &COND_refresh
);
1840 pthread_mutex_lock(&LOCK_lock_db
);
1845 lock_db_delete(db1
, length1
);
1846 lock_db_delete(db2
, length2
);
1847 creating_database
--;
1848 pthread_mutex_unlock(&LOCK_lock_db
);
1849 pthread_cond_signal(&COND_refresh
);
1854 We can unlock now as the hash will protect against anyone creating a table
1855 in the databases we are using
1857 pthread_mutex_unlock(&LOCK_lock_db
);
1863 Upgrade a 5.0 database.
1864 This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
1865 ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
1867 If we have managed to rename (move) tables to the new database
1868 but something failed on a later step, then we store the
1869 RENAME DATABASE event in the log. mysql_rename_db() is atomic in
1870 the sense that it will rename all or none of the tables.
1872 @param thd Current thread
1873 @param old_db 5.0 database name, in #mysql50#name format
1874 @return 0 on success, 1 on error
1876 bool mysql_upgrade_db(THD
*thd
, LEX_STRING
*old_db
)
1878 int error
= 0, change_to_newdb
= 0;
1879 char path
[FN_REFLEN
+16];
1881 HA_CREATE_INFO create_info
;
1883 TABLE_LIST
*table_list
;
1884 SELECT_LEX
*sl
= thd
->lex
->current_select
;
1886 DBUG_ENTER("mysql_upgrade_db");
1888 if ((old_db
->length
<= MYSQL50_TABLE_NAME_PREFIX_LENGTH
) ||
1889 (strncmp(old_db
->str
,
1890 MYSQL50_TABLE_NAME_PREFIX
,
1891 MYSQL50_TABLE_NAME_PREFIX_LENGTH
) != 0))
1893 my_error(ER_WRONG_USAGE
, MYF(0),
1894 "ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
1899 /* `#mysql50#<name>` converted to encoded `<name>` */
1900 new_db
.str
= old_db
->str
+ MYSQL50_TABLE_NAME_PREFIX_LENGTH
;
1901 new_db
.length
= old_db
->length
- MYSQL50_TABLE_NAME_PREFIX_LENGTH
;
1903 if (lock_databases(thd
, old_db
->str
, old_db
->length
,
1904 new_db
.str
, new_db
.length
))
1908 Let's remember if we should do "USE newdb" afterwards.
1909 thd->db will be cleared in mysql_rename_db()
1911 if (thd
->db
&& !strcmp(thd
->db
, old_db
->str
))
1914 build_table_filename(path
, sizeof(path
)-1,
1915 old_db
->str
, "", MY_DB_OPT_FILE
, 0);
1916 if ((load_db_opt(thd
, path
, &create_info
)))
1917 create_info
.default_table_charset
= thd
->variables
.collation_server
;
1919 length
= build_table_filename(path
, sizeof(path
)-1, old_db
->str
, "", "", 0);
1920 if (length
&& path
[length
-1] == FN_LIBCHAR
)
1921 path
[length
-1]=0; // remove ending '\'
1922 if ((error
= my_access(path
,F_OK
)))
1924 my_error(ER_BAD_DB_ERROR
, MYF(0), old_db
->str
);
1928 /* Step1: Create the new database */
1929 if ((error
= mysql_create_db(thd
, new_db
.str
, &create_info
, 1)))
1932 /* Step2: Move tables to the new database */
1933 if ((dirp
= my_dir(path
,MYF(MY_DONT_SORT
))))
1935 uint nfiles
= (uint
) dirp
->number_off_files
;
1936 for (uint idx
=0 ; idx
< nfiles
&& !thd
->killed
; idx
++)
1938 FILEINFO
*file
= dirp
->dir_entry
+ idx
;
1939 char *extension
, tname
[FN_REFLEN
+ 1];
1940 LEX_STRING table_str
;
1941 DBUG_PRINT("info",("Examining: %s", file
->name
));
1943 /* skiping non-FRM files */
1944 if (my_strcasecmp(files_charset_info
,
1945 (extension
= fn_rext(file
->name
)), reg_ext
))
1948 /* A frm file found, add the table info rename list */
1951 table_str
.length
= filename_to_tablename(file
->name
,
1952 tname
, sizeof(tname
)-1);
1953 table_str
.str
= (char*) sql_memdup(tname
, table_str
.length
+ 1);
1954 Table_ident
*old_ident
= new Table_ident(thd
, *old_db
, table_str
, 0);
1955 Table_ident
*new_ident
= new Table_ident(thd
, new_db
, table_str
, 0);
1956 if (!old_ident
|| !new_ident
||
1957 !sl
->add_table_to_list(thd
, old_ident
, NULL
,
1958 TL_OPTION_UPDATING
, TL_IGNORE
) ||
1959 !sl
->add_table_to_list(thd
, new_ident
, NULL
,
1960 TL_OPTION_UPDATING
, TL_IGNORE
))
1970 if ((table_list
= thd
->lex
->query_tables
) &&
1971 (error
= mysql_rename_tables(thd
, table_list
, 1)))
1974 Failed to move all tables from the old database to the new one.
1975 In the best case mysql_rename_tables() moved all tables back to the old
1976 database. In the worst case mysql_rename_tables() moved some tables
1977 to the new database, then failed, then started to move the tables back,
1978 and then failed again. In this situation we have some tables in the
1979 old database and some tables in the new database.
1980 Let's delete the option file, and then the new database directory.
1981 If some tables were left in the new directory, rmdir() will fail.
1982 It garantees we never loose any tables.
1984 build_table_filename(path
, sizeof(path
)-1,
1985 new_db
.str
,"",MY_DB_OPT_FILE
, 0);
1986 my_delete(path
, MYF(MY_WME
));
1987 length
= build_table_filename(path
, sizeof(path
)-1, new_db
.str
, "", "", 0);
1988 if (length
&& path
[length
-1] == FN_LIBCHAR
)
1989 path
[length
-1]=0; // remove ending '\'
1996 Step3: move all remaining files to the new db's directory.
1997 Skip db opt file: it's been created by mysql_create_db() in
1998 the new directory, and will be dropped by mysql_rm_db() in the old one.
1999 Trigger TRN and TRG files are be moved as regular files at the moment,
2000 without any special treatment.
2002 Triggers without explicit database qualifiers in table names work fine:
2004 create trigger trg1 before insert on t2 for each row set @a:=1
2005 rename database d1 to d2;
2007 TODO: Triggers, having the renamed database explicitely written
2008 in the table qualifiers.
2009 1. when the same database is renamed:
2010 create trigger d1.trg1 before insert on d1.t1 for each row set @a:=1;
2011 rename database d1 to d2;
2012 Problem: After database renaming, the trigger's body
2013 still points to the old database d1.
2014 2. when another database is renamed:
2015 create trigger d3.trg1 before insert on d3.t1 for each row
2016 insert into d1.t1 values (...);
2017 rename database d1 to d2;
2018 Problem: After renaming d1 to d2, the trigger's body
2019 in the database d3 still points to database d1.
2022 if ((dirp
= my_dir(path
,MYF(MY_DONT_SORT
))))
2024 uint nfiles
= (uint
) dirp
->number_off_files
;
2025 for (uint idx
=0 ; idx
< nfiles
; idx
++)
2027 FILEINFO
*file
= dirp
->dir_entry
+ idx
;
2028 char oldname
[FN_REFLEN
+ 1], newname
[FN_REFLEN
+ 1];
2029 DBUG_PRINT("info",("Examining: %s", file
->name
));
2031 /* skiping . and .. and MY_DB_OPT_FILE */
2032 if ((file
->name
[0] == '.' &&
2033 (!file
->name
[1] || (file
->name
[1] == '.' && !file
->name
[2]))) ||
2034 !my_strcasecmp(files_charset_info
, file
->name
, MY_DB_OPT_FILE
))
2037 /* pass empty file name, and file->name as extension to avoid encoding */
2038 build_table_filename(oldname
, sizeof(oldname
)-1,
2039 old_db
->str
, "", file
->name
, 0);
2040 build_table_filename(newname
, sizeof(newname
)-1,
2041 new_db
.str
, "", file
->name
, 0);
2042 my_rename(oldname
, newname
, MYF(MY_WME
));
2048 Step7: drop the old database.
2049 remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
2050 are done inside mysql_rm_db(), no needs to execute them again.
2051 mysql_rm_db() also "unuses" if we drop the current database.
2053 error
= mysql_rm_db(thd
, old_db
->str
, 0, 1);
2055 /* Step8: logging */
2056 if (mysql_bin_log
.is_open())
2058 int errcode
= query_error_code(thd
, TRUE
);
2059 Query_log_event
qinfo(thd
, thd
->query(), thd
->query_length(),
2062 error
|= mysql_bin_log
.write(&qinfo
);
2065 /* Step9: Let's do "use newdb" if we renamed the current database */
2066 if (change_to_newdb
)
2067 error
|= mysql_change_db(thd
, & new_db
, FALSE
);
2070 pthread_mutex_lock(&LOCK_lock_db
);
2071 /* Remove the databases from db lock cache */
2072 lock_db_delete(old_db
->str
, old_db
->length
);
2073 lock_db_delete(new_db
.str
, new_db
.length
);
2074 creating_database
--;
2075 /* Signal waiting CREATE TABLE's to continue */
2076 pthread_cond_signal(&COND_refresh
);
2077 pthread_mutex_unlock(&LOCK_lock_db
);
2085 Check if there is directory for the database name.
2088 check_db_dir_existence()
2089 db_name database name
2092 FALSE There is directory for the specified database name.
2093 TRUE The directory does not exist.
2096 bool check_db_dir_existence(const char *db_name
)
2098 char db_dir_path
[FN_REFLEN
+ 1];
2099 uint db_dir_path_len
;
2101 db_dir_path_len
= build_table_filename(db_dir_path
, sizeof(db_dir_path
) - 1,
2102 db_name
, "", "", 0);
2104 if (db_dir_path_len
&& db_dir_path
[db_dir_path_len
- 1] == FN_LIBCHAR
)
2105 db_dir_path
[db_dir_path_len
- 1]= 0;
2109 return my_access(db_dir_path
, F_OK
);