1498
lock_databases(THD *thd, const char *db1, uint length1,
1499
const char *db2, uint length2)
1501
pthread_mutex_lock(&LOCK_lock_db);
1502
while (!thd->killed &&
1503
(hash_search(&lock_db_cache,(uchar*) db1, length1) ||
1504
hash_search(&lock_db_cache,(uchar*) db2, length2)))
1506
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1507
pthread_mutex_lock(&LOCK_lock_db);
1512
pthread_mutex_unlock(&LOCK_lock_db);
1516
lock_db_insert(db1, length1);
1517
lock_db_insert(db2, length2);
1518
creating_database++;
1521
Wait if a concurent thread is creating a table at the same time.
1522
The assumption here is that it will not take too long until
1523
there is a point in time when a table is not created.
1526
while (!thd->killed && creating_table)
1528
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1529
pthread_mutex_lock(&LOCK_lock_db);
1534
lock_db_delete(db1, length1);
1535
lock_db_delete(db2, length2);
1536
creating_database--;
1537
pthread_mutex_unlock(&LOCK_lock_db);
1538
pthread_cond_signal(&COND_refresh);
1543
We can unlock now as the hash will protect against anyone creating a table
1544
in the databases we are using
1546
pthread_mutex_unlock(&LOCK_lock_db);
1552
Upgrade a 5.0 database.
1553
This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
1554
ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
1556
If we have managed to rename (move) tables to the new database
1557
but something failed on a later step, then we store the
1558
RENAME DATABASE event in the log. mysql_rename_db() is atomic in
1559
the sense that it will rename all or none of the tables.
1561
@param thd Current thread
1562
@param old_db 5.0 database name, in #mysql50#name format
1563
@return 0 on success, 1 on error
1565
bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
1567
int error= 0, change_to_newdb= 0;
1568
char path[FN_REFLEN+16];
1570
HA_CREATE_INFO create_info;
1572
TABLE_LIST *table_list;
1573
SELECT_LEX *sl= thd->lex->current_select;
1576
if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
1577
(strncmp(old_db->str,
1578
MYSQL50_TABLE_NAME_PREFIX,
1579
MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
1581
my_error(ER_WRONG_USAGE, MYF(0),
1582
"ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
1587
/* `#mysql50#<name>` converted to encoded `<name>` */
1588
new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1589
new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1591
if (lock_databases(thd, old_db->str, old_db->length,
1592
new_db.str, new_db.length))
1596
Let's remember if we should do "USE newdb" afterwards.
1597
thd->db will be cleared in mysql_rename_db()
1599
if (thd->db && !strcmp(thd->db, old_db->str))
1602
build_table_filename(path, sizeof(path)-1,
1603
old_db->str, "", MY_DB_OPT_FILE, 0);
1604
if ((load_db_opt(thd, path, &create_info)))
1605
create_info.default_table_charset= thd->variables.collation_server;
1607
length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
1608
if (length && path[length-1] == FN_LIBCHAR)
1609
path[length-1]=0; // remove ending '\'
1610
if ((error= my_access(path,F_OK)))
1612
my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
1616
/* Step1: Create the new database */
1617
if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
1620
/* Step2: Move tables to the new database */
1621
if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1623
uint nfiles= (uint) dirp->number_off_files;
1624
for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
1626
FILEINFO *file= dirp->dir_entry + idx;
1627
char *extension, tname[FN_REFLEN];
1628
LEX_STRING table_str;
1630
/* skiping non-FRM files */
1631
if (my_strcasecmp(files_charset_info,
1632
(extension= fn_rext(file->name)), reg_ext))
1635
/* A frm file found, add the table info rename list */
1638
table_str.length= filename_to_tablename(file->name,
1639
tname, sizeof(tname)-1);
1640
table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
1641
Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
1642
Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
1643
if (!old_ident || !new_ident ||
1644
!sl->add_table_to_list(thd, old_ident, NULL,
1645
TL_OPTION_UPDATING, TL_IGNORE) ||
1646
!sl->add_table_to_list(thd, new_ident, NULL,
1647
TL_OPTION_UPDATING, TL_IGNORE))
1657
if ((table_list= thd->lex->query_tables) &&
1658
(error= mysql_rename_tables(thd, table_list, 1)))
1661
Failed to move all tables from the old database to the new one.
1662
In the best case mysql_rename_tables() moved all tables back to the old
1663
database. In the worst case mysql_rename_tables() moved some tables
1664
to the new database, then failed, then started to move the tables back,
1665
and then failed again. In this situation we have some tables in the
1666
old database and some tables in the new database.
1667
Let's delete the option file, and then the new database directory.
1668
If some tables were left in the new directory, rmdir() will fail.
1669
It garantees we never loose any tables.
1671
build_table_filename(path, sizeof(path)-1,
1672
new_db.str,"",MY_DB_OPT_FILE, 0);
1673
my_delete(path, MYF(MY_WME));
1674
length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
1675
if (length && path[length-1] == FN_LIBCHAR)
1676
path[length-1]=0; // remove ending '\'
1682
if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1684
uint nfiles= (uint) dirp->number_off_files;
1685
for (uint idx=0 ; idx < nfiles ; idx++)
1687
FILEINFO *file= dirp->dir_entry + idx;
1688
char oldname[FN_REFLEN], newname[FN_REFLEN];
1690
/* skiping . and .. and MY_DB_OPT_FILE */
1691
if ((file->name[0] == '.' &&
1692
(!file->name[1] || (file->name[1] == '.' && !file->name[2]))) ||
1693
!my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
1696
/* pass empty file name, and file->name as extension to avoid encoding */
1697
build_table_filename(oldname, sizeof(oldname)-1,
1698
old_db->str, "", file->name, 0);
1699
build_table_filename(newname, sizeof(newname)-1,
1700
new_db.str, "", file->name, 0);
1701
my_rename(oldname, newname, MYF(MY_WME));
1707
Step7: drop the old database.
1708
remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
1709
are done inside mysql_rm_db(), no needs to execute them again.
1710
mysql_rm_db() also "unuses" if we drop the current database.
1712
error= mysql_rm_db(thd, old_db->str, 0, 1);
1714
/* Step8: logging */
1715
if (mysql_bin_log.is_open())
1717
Query_log_event qinfo(thd, thd->query, thd->query_length, 0, true);
1719
mysql_bin_log.write(&qinfo);
1722
/* Step9: Let's do "use newdb" if we renamed the current database */
1723
if (change_to_newdb)
1724
error|= mysql_change_db(thd, & new_db, false);
1727
pthread_mutex_lock(&LOCK_lock_db);
1728
/* Remove the databases from db lock cache */
1729
lock_db_delete(old_db->str, old_db->length);
1730
lock_db_delete(new_db.str, new_db.length);
1731
creating_database--;
1732
/* Signal waiting CREATE TABLE's to continue */
1733
pthread_cond_signal(&COND_refresh);
1734
pthread_mutex_unlock(&LOCK_lock_db);
1742
1453
Check if there is directory for the database name.