Fix problems related to drop dababase

This commit is contained in:
lazio579 2018-12-13 10:39:55 +08:00
commit e9eadc2f80
10 changed files with 79 additions and 7 deletions

View File

@ -439,6 +439,7 @@ opt_unique ::= .
//
drop_database_stmt ::= DROP db_schema ifexists(A) nm(B). {
sql_drop_database_t *p = sql_drop_database_new();
sql_drop_database(context, p);
p->schema_name = sql_token_dup(B);
p->ifexists = A;
}

View File

@ -427,6 +427,7 @@ ifexists(A) ::= . {A = 0;}
cmd ::= DROP db_schema ifexists(A) nm(B). {
sql_drop_database_t *p = sql_drop_database_new();
sql_drop_database(context, p);
p->schema_name = sql_token_dup(B);
p->ifexists = A;
}

View File

@ -948,6 +948,9 @@ sql_statement_free(void *clause, sql_stmt_type_t stmt_type)
case STMT_ROLLBACK:
case STMT_COMMON_DDL:
break;
case STMT_DROP_DATABASE:
sql_drop_database_free(clause);
break;
case STMT_CALL:
sql_expr_free(clause);
break;

View File

@ -48,6 +48,8 @@ void sql_rollback_transaction(sql_context_t *st);
void sql_savepoint(sql_context_t *st, int, char *);
void sql_drop_database(sql_context_t *st, sql_drop_database_t *drop_database);
void sql_explain_table(sql_context_t *st, sql_src_list_t *table);
void sql_use_database(sql_context_t *ps, char *val);

View File

@ -1199,6 +1199,13 @@ process_query_or_stmt_prepare(network_mysqld_con *con, proxy_plugin_con_t *st,
case STMT_DELETE:
stats->com_delete += 1;
break;
case STMT_DROP_DATABASE: {
sql_drop_database_t *drop_database = context->sql_statement;
if (drop_database) {
truncate_default_db_when_drop_database(con, drop_database->schema_name);
}
break;
}
default:
break;
}
@ -1263,6 +1270,13 @@ network_read_query(network_mysqld_con *con, proxy_plugin_con_t *st)
return PROXY_SEND_RESULT;
}
if (con->client->default_db->len == 0) {
if (con->srv->default_db != NULL) {
g_string_assign(con->client->default_db, con->srv->default_db);
g_debug("%s:set default db:%s for con:%p", G_STRLOC, con->client->default_db->str, con);
}
}
packet.offset = 0;
mysqld_query_attr_t query_attr = { 0 };
@ -1708,6 +1722,18 @@ NETWORK_MYSQLD_PLUGIN_PROTO(proxy_send_query_result)
injection *inj;
proxy_plugin_con_t *st = con->plugin_con_state;
if (st->sql_context->stmt_type == STMT_DROP_DATABASE) {
network_mysqld_com_query_result_t *com_query = con->parse.data;
if (com_query->query_status == MYSQLD_PACKET_OK) {
if (con->servers != NULL) {
con->server_to_be_closed = 1;
} else if (con->server) {
g_string_truncate(con->server->default_db, 0);
g_message("%s:truncate server database for con:%p", G_STRLOC, con);
}
}
}
con->server_in_tran_and_auto_commit_received = 0;
if (con->server_to_be_closed) {

View File

@ -1216,6 +1216,13 @@ proxy_get_server_list(network_mysqld_con *con)
case STMT_DELETE:
stats->com_delete_shard += 1;
break;
case STMT_DROP_DATABASE: {
sql_drop_database_t *drop_database = st->sql_context->sql_statement;
if (drop_database) {
truncate_default_db_when_drop_database(con, drop_database->schema_name);
}
break;
}
default:
break;
}
@ -1577,13 +1584,15 @@ check_and_set_attr_bitmap(network_mysqld_con *con)
} else {
if (con->parse.command != COM_INIT_DB) {
/* check default db */
if (!g_string_equal(con->client->default_db, ss->server->default_db)) {
g_debug("%s:default db for client:%s", G_STRLOC, con->client->default_db->str);
ss->attr_diff = ATTR_DIF_DEFAULT_DB;
result = FALSE;
con->unmatched_attribute |= ATTR_DIF_DEFAULT_DB;
consistant = FALSE;
g_debug("%s: default db different", G_STRLOC);
if (con->client->default_db && con->client->default_db->len > 0) {
if (!g_string_equal(con->client->default_db, ss->server->default_db)) {
g_debug("%s:default db for client:%s", G_STRLOC, con->client->default_db->str);
ss->attr_diff = ATTR_DIF_DEFAULT_DB;
result = FALSE;
con->unmatched_attribute |= ATTR_DIF_DEFAULT_DB;
consistant = FALSE;
g_debug("%s: default db different", G_STRLOC);
}
}
}
}
@ -1961,6 +1970,23 @@ NETWORK_MYSQLD_PLUGIN_PROTO(proxy_get_server_conn_list)
*/
NETWORK_MYSQLD_PLUGIN_PROTO(proxy_send_query_result)
{
shard_plugin_con_t *st = con->plugin_con_state;
sql_context_t *context = st->sql_context;
if (context->stmt_type == STMT_DROP_DATABASE) {
network_mysqld_com_query_result_t *com_query = con->parse.data;
if (com_query->query_status == MYSQLD_PACKET_OK) {
if (con->servers != NULL) {
int i;
for (i = 0; i < con->servers->len; i++) {
server_session_t *ss = g_ptr_array_index(con->servers, i);
g_string_truncate(ss->server->default_db, 0);
g_message("%s:truncate server database for con:%p", G_STRLOC, con);
}
}
}
}
if (con->server_to_be_closed) {
if (con->servers != NULL) {
g_debug("%s:call proxy_put_shard_conn_to_pool for con:%p", G_STRLOC, con);

View File

@ -1617,6 +1617,7 @@ sharding_parse_groups(GString *default_db, sql_context_t *context, query_stats_t
return USE_PREVIOUS_TRAN_CONNS;
case STMT_CALL:
return rc;
case STMT_DROP_DATABASE:
case STMT_COMMON_DDL: /* ddl without comments sent to all */
shard_conf_get_all_groups(groups);
sharding_plan_add_groups(plan, groups);

View File

@ -1665,6 +1665,8 @@ shard_set_default_db_consistant(network_mysqld_con *con)
} else {
g_warning("%s:default db adjust warning:not consistant", G_STRLOC);
}
} else {
g_warning("%s:client default db is empty ", G_STRLOC);
}
}

View File

@ -688,3 +688,12 @@ remove_mul_server_recv_packets(network_mysqld_con *con)
network_mysqld_queue_reset(ss->server);
}
}
void
truncate_default_db_when_drop_database(network_mysqld_con *con, char *schema_name)
{
if (schema_name && strcasecmp(con->client->default_db->str, schema_name) == 0) {
g_string_truncate(con->client->default_db, 0);
}
}

View File

@ -51,5 +51,6 @@ NETWORK_API int do_check_qeury_cache(network_mysqld_con *con);
NETWORK_API int try_to_get_resp_from_query_cache(network_mysqld_con *con);
NETWORK_API gboolean proxy_put_shard_conn_to_pool(network_mysqld_con *con);
NETWORK_API void remove_mul_server_recv_packets(network_mysqld_con *con);
NETWORK_API void truncate_default_db_when_drop_database(network_mysqld_con *con, char *);
#endif