17
17
/* create and drop of databases */
23
#include <drizzled/serialize/serialize.h>
25
#include <drizzled/server_includes.h>
26
#include <mysys/mysys_err.h>
27
#include <mysys/my_dir.h>
19
#include "mysql_priv.h"
20
#include <mysys_err.h>
29
#include <drizzled/drizzled_error_messages.h>
30
#include <libdrizzle/gettext.h>
33
25
#define MAX_DROP_TABLE_Q_LEN 1024
35
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NULL};
27
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
36
28
static TYPELIB deletable_extentions=
37
29
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
39
31
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
40
const char *db, const char *path, uint32_t level,
41
TableList **dropped_tables);
32
const char *db, const char *path, uint level,
33
TABLE_LIST **dropped_tables);
43
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
35
static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
36
static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
44
37
static void mysql_change_db_impl(THD *thd,
45
38
LEX_STRING *new_db_name,
46
const CHARSET_INFO * const new_db_charset);
39
CHARSET_INFO *new_db_charset);
49
42
/* Database lock hash */
377
420
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
383
memset(create, 0, sizeof(*create));
427
bzero((char*) create,sizeof(*create));
384
428
create->default_table_charset= thd->variables.collation_server;
386
430
/* Check if options for this database are already in the hash */
387
431
if (!get_dbopt(path, create))
390
fstream input(path, ios::in | ios::binary);
393
else if (!db.ParseFromIstream(&input))
396
buffer= db.characterset();
397
if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
399
sql_print_error(_("Error while loading database options: '%s':"),path);
400
sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
401
create->default_table_charset= default_charset_info;
404
buffer= db.collation();
405
if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
407
sql_print_error(_("Error while loading database options: '%s':"),path);
408
sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
409
create->default_table_charset= default_charset_info;
434
/* Otherwise, load options from the .opt file */
435
if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
439
if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
442
while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
444
char *pos= buf+nbytes-1;
445
/* Remove end space and control characters */
446
while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
449
if ((pos= strchr(buf, '=')))
451
if (!strncmp(buf,"default-character-set", (pos-buf)))
454
Try character set name, and if it fails
455
try collation name, probably it's an old
456
4.1.0 db.opt file, which didn't have
457
separate default-character-set and
458
default-collation commands.
460
if (!(create->default_table_charset=
461
get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
462
!(create->default_table_charset=
463
get_charset_by_name(pos+1, MYF(0))))
465
sql_print_error("Error while loading database options: '%s':",path);
466
sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
467
create->default_table_charset= default_charset_info;
470
else if (!strncmp(buf,"default-collation", (pos-buf)))
472
if (!(create->default_table_charset= get_charset_by_name(pos+1,
475
sql_print_error("Error while loading database options: '%s':",path);
476
sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
477
create->default_table_charset= default_charset_info;
413
483
Put the loaded value into the hash.
414
484
Note that another thread could've added the same
953
1037
(file->name[1] == '.' && !file->name[2])))
1040
/* Check if file is a raid directory */
1041
if ((my_isdigit(system_charset_info, file->name[0]) ||
1042
(file->name[0] >= 'a' && file->name[0] <= 'f')) &&
1043
(my_isdigit(system_charset_info, file->name[1]) ||
1044
(file->name[1] >= 'a' && file->name[1] <= 'f')) &&
1045
!file->name[2] && !level)
1047
char newpath[FN_REFLEN], *copy_of_path;
1052
strxmov(newpath,org_path,"/",file->name,NullS);
1053
length= unpack_filename(newpath,newpath);
1054
if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
1056
if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0)
1058
if (!(copy_of_path= (char*) thd->memdup(newpath, length+1)) ||
1059
!(dir= new (thd->mem_root) String(copy_of_path, length,
1060
&my_charset_bin)) ||
1061
raid_dirs.push_back(dir))
1065
found_other_files++;
1068
else if (file->name[0] == 'a' && file->name[1] == 'r' &&
1069
file->name[2] == 'c' && file->name[3] == '\0')
1072
char newpath[FN_REFLEN];
1074
strxmov(newpath, org_path, "/", "arc", NullS);
1075
(void) unpack_filename(newpath, newpath);
1076
if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
1078
if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0)
1082
found_other_files++;
956
1085
if (!(extension= strrchr(file->name, '.')))
957
extension= strchr(file->name, '\0');
1086
extension= strend(file->name);
958
1087
if (find_type(extension, &deletable_extentions,1+2) <= 0)
960
1089
if (find_type(extension, ha_known_exts(),1+2) <= 0)
1630
lock_databases(THD *thd, const char *db1, uint length1,
1631
const char *db2, uint length2)
1633
pthread_mutex_lock(&LOCK_lock_db);
1634
while (!thd->killed &&
1635
(hash_search(&lock_db_cache,(uchar*) db1, length1) ||
1636
hash_search(&lock_db_cache,(uchar*) db2, length2)))
1638
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1639
pthread_mutex_lock(&LOCK_lock_db);
1644
pthread_mutex_unlock(&LOCK_lock_db);
1648
lock_db_insert(db1, length1);
1649
lock_db_insert(db2, length2);
1650
creating_database++;
1653
Wait if a concurent thread is creating a table at the same time.
1654
The assumption here is that it will not take too long until
1655
there is a point in time when a table is not created.
1658
while (!thd->killed && creating_table)
1660
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1661
pthread_mutex_lock(&LOCK_lock_db);
1666
lock_db_delete(db1, length1);
1667
lock_db_delete(db2, length2);
1668
creating_database--;
1669
pthread_mutex_unlock(&LOCK_lock_db);
1670
pthread_cond_signal(&COND_refresh);
1675
We can unlock now as the hash will protect against anyone creating a table
1676
in the databases we are using
1678
pthread_mutex_unlock(&LOCK_lock_db);
1684
Upgrade a 5.0 database.
1685
This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
1686
ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
1688
If we have managed to rename (move) tables to the new database
1689
but something failed on a later step, then we store the
1690
RENAME DATABASE event in the log. mysql_rename_db() is atomic in
1691
the sense that it will rename all or none of the tables.
1693
@param thd Current thread
1694
@param old_db 5.0 database name, in #mysql50#name format
1695
@return 0 on success, 1 on error
1697
bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
1699
int error= 0, change_to_newdb= 0;
1700
char path[FN_REFLEN+16];
1702
HA_CREATE_INFO create_info;
1704
TABLE_LIST *table_list;
1705
SELECT_LEX *sl= thd->lex->current_select;
1708
if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
1709
(strncmp(old_db->str,
1710
MYSQL50_TABLE_NAME_PREFIX,
1711
MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
1713
my_error(ER_WRONG_USAGE, MYF(0),
1714
"ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
1719
/* `#mysql50#<name>` converted to encoded `<name>` */
1720
new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1721
new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1723
if (lock_databases(thd, old_db->str, old_db->length,
1724
new_db.str, new_db.length))
1728
Let's remember if we should do "USE newdb" afterwards.
1729
thd->db will be cleared in mysql_rename_db()
1731
if (thd->db && !strcmp(thd->db, old_db->str))
1734
build_table_filename(path, sizeof(path)-1,
1735
old_db->str, "", MY_DB_OPT_FILE, 0);
1736
if ((load_db_opt(thd, path, &create_info)))
1737
create_info.default_table_charset= thd->variables.collation_server;
1739
length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
1740
if (length && path[length-1] == FN_LIBCHAR)
1741
path[length-1]=0; // remove ending '\'
1742
if ((error= my_access(path,F_OK)))
1744
my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
1748
/* Step1: Create the new database */
1749
if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
1752
/* Step2: Move tables to the new database */
1753
if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1755
uint nfiles= (uint) dirp->number_off_files;
1756
for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
1758
FILEINFO *file= dirp->dir_entry + idx;
1759
char *extension, tname[FN_REFLEN];
1760
LEX_STRING table_str;
1762
/* skiping non-FRM files */
1763
if (my_strcasecmp(files_charset_info,
1764
(extension= fn_rext(file->name)), reg_ext))
1767
/* A frm file found, add the table info rename list */
1770
table_str.length= filename_to_tablename(file->name,
1771
tname, sizeof(tname)-1);
1772
table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
1773
Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
1774
Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
1775
if (!old_ident || !new_ident ||
1776
!sl->add_table_to_list(thd, old_ident, NULL,
1777
TL_OPTION_UPDATING, TL_IGNORE) ||
1778
!sl->add_table_to_list(thd, new_ident, NULL,
1779
TL_OPTION_UPDATING, TL_IGNORE))
1789
if ((table_list= thd->lex->query_tables) &&
1790
(error= mysql_rename_tables(thd, table_list, 1)))
1793
Failed to move all tables from the old database to the new one.
1794
In the best case mysql_rename_tables() moved all tables back to the old
1795
database. In the worst case mysql_rename_tables() moved some tables
1796
to the new database, then failed, then started to move the tables back,
1797
and then failed again. In this situation we have some tables in the
1798
old database and some tables in the new database.
1799
Let's delete the option file, and then the new database directory.
1800
If some tables were left in the new directory, rmdir() will fail.
1801
It garantees we never loose any tables.
1803
build_table_filename(path, sizeof(path)-1,
1804
new_db.str,"",MY_DB_OPT_FILE, 0);
1805
my_delete(path, MYF(MY_WME));
1806
length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
1807
if (length && path[length-1] == FN_LIBCHAR)
1808
path[length-1]=0; // remove ending '\'
1814
if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1816
uint nfiles= (uint) dirp->number_off_files;
1817
for (uint idx=0 ; idx < nfiles ; idx++)
1819
FILEINFO *file= dirp->dir_entry + idx;
1820
char oldname[FN_REFLEN], newname[FN_REFLEN];
1822
/* skiping . and .. and MY_DB_OPT_FILE */
1823
if ((file->name[0] == '.' &&
1824
(!file->name[1] || (file->name[1] == '.' && !file->name[2]))) ||
1825
!my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
1828
/* pass empty file name, and file->name as extension to avoid encoding */
1829
build_table_filename(oldname, sizeof(oldname)-1,
1830
old_db->str, "", file->name, 0);
1831
build_table_filename(newname, sizeof(newname)-1,
1832
new_db.str, "", file->name, 0);
1833
my_rename(oldname, newname, MYF(MY_WME));
1839
Step7: drop the old database.
1840
remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
1841
are done inside mysql_rm_db(), no needs to execute them again.
1842
mysql_rm_db() also "unuses" if we drop the current database.
1844
error= mysql_rm_db(thd, old_db->str, 0, 1);
1846
/* Step8: logging */
1847
if (mysql_bin_log.is_open())
1849
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, true);
1851
mysql_bin_log.write(&qinfo);
1854
/* Step9: Let's do "use newdb" if we renamed the current database */
1855
if (change_to_newdb)
1856
error|= mysql_change_db(thd, & new_db, false);
1859
pthread_mutex_lock(&LOCK_lock_db);
1860
/* Remove the databases from db lock cache */
1861
lock_db_delete(old_db->str, old_db->length);
1862
lock_db_delete(new_db.str, new_db.length);
1863
creating_database--;
1864
/* Signal waiting CREATE TABLE's to continue */
1865
pthread_cond_signal(&COND_refresh);
1866
pthread_mutex_unlock(&LOCK_lock_db);
1420
1874
Check if there is directory for the database name.