[fix](mysqldb) Fix mysqldb upgrade (#25111)
If user has database with same name mysql, will introduce problem when doing checkpoint. Solution: Add check for this situation, if duplicate, exit and print log info to prevent damage of metadata; Add fe config field: mysqldb_replace_name to make things correct if user already has mysql db. Related pr: #23087 #22868
This commit is contained in:
@ -17,9 +17,9 @@
|
||||
|
||||
package org.apache.doris.analysis;
|
||||
|
||||
import org.apache.doris.catalog.Database;
|
||||
import org.apache.doris.catalog.DatabaseIf;
|
||||
import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.catalog.InfoSchemaDb;
|
||||
import org.apache.doris.catalog.MysqlDb;
|
||||
import org.apache.doris.cluster.ClusterNamespace;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
@ -60,9 +60,10 @@ public class DropDbStmt extends DdlStmt {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_WRONG_DB_NAME, dbName);
|
||||
}
|
||||
dbName = ClusterNamespace.getFullName(getClusterName(), dbName);
|
||||
// Don't allowed to drop 'information_schema' & 'mysql'
|
||||
if (dbName.equalsIgnoreCase(ClusterNamespace.getFullName(getClusterName(), InfoSchemaDb.DATABASE_NAME))
|
||||
|| dbName.equalsIgnoreCase(ClusterNamespace.getFullName(getClusterName(), MysqlDb.DATABASE_NAME))) {
|
||||
|
||||
// Don't allow to drop mysql compatible databases
|
||||
DatabaseIf db = Env.getCurrentInternalCatalog().getDbNullable(dbName);
|
||||
if (db != null && (db instanceof Database) && ((Database) db).isMysqlCompatibleDatabase()) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
|
||||
analyzer.getQualifiedUser(), dbName);
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
package org.apache.doris.catalog;
|
||||
|
||||
import org.apache.doris.cluster.ClusterNamespace;
|
||||
import org.apache.doris.common.Config;
|
||||
|
||||
/**
|
||||
* This class is used for MySQL compatibility.
|
||||
@ -33,7 +34,7 @@ import org.apache.doris.cluster.ClusterNamespace;
|
||||
* We will add useful system tables in the future.
|
||||
*/
|
||||
public class MysqlDb extends MysqlCompatibleDatabase {
|
||||
public static final String DATABASE_NAME = "mysql";
|
||||
public static final String DATABASE_NAME = Config.mysqldb_replace_name;
|
||||
/**
|
||||
* Database created by user will have database id starting from 10000 {@link Env#NEXT_ID_INIT_VALUE}.
|
||||
* InfoSchemaDb takes id 0, so we assign id 1 to MysqlDb.
|
||||
|
||||
@ -3178,6 +3178,21 @@ public class InternalCatalog implements CatalogIf<Database> {
|
||||
Database db = new Database();
|
||||
db.readFields(dis);
|
||||
newChecksum ^= db.getId();
|
||||
|
||||
Database dbPrev = fullNameToDb.get(db.getFullName());
|
||||
if (dbPrev != null) {
|
||||
String errMsg;
|
||||
if (dbPrev.isMysqlCompatibleDatabase() || db.isMysqlCompatibleDatabase()) {
|
||||
errMsg = String.format(
|
||||
"Mysql compatibility problem, previous checkpoint already has a database with full name "
|
||||
+ "%s. If its name is mysql, try to add mysqldb_replace_name=\"mysql_comp\" in fe.conf.",
|
||||
db.getFullName());
|
||||
} else {
|
||||
errMsg = String.format("Logical error, duplicated database fullname: %s, id: %d %d.",
|
||||
db.getFullName(), db.getId(), fullNameToDb.get(db.getFullName()).getId());
|
||||
}
|
||||
throw new IOException(errMsg);
|
||||
}
|
||||
idToDb.put(db.getId(), db);
|
||||
fullNameToDb.put(db.getFullName(), db);
|
||||
Env.getCurrentGlobalTransactionMgr().addDatabaseTransactionMgr(db.getId());
|
||||
|
||||
Reference in New Issue
Block a user