Skip to content

Commit ccf72b6

Browse files
authored
Merge pull request #5134 from wazir-ahmed/mysqldump
Improve `mysqldump` compatibility
2 parents 3b4369b + b6d796c commit ccf72b6

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed

include/MySQL_Session.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class MySQL_Session: public Base_Session<MySQL_Session, MySQL_Data_Stream, MySQL
154154
*/
155155
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_USE_DB(PtrSize_t *pkt);
156156
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PING(PtrSize_t *);
157+
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_REFRESH(PtrSize_t *pkt);
157158

158159
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_CHANGE_USER(PtrSize_t *, bool *);
159160
/**

lib/Admin_Handler.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,6 +2355,89 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) {
23552355
// add global mutex, see bug #1188
23562356
pthread_mutex_lock(&pa->sql_query_global_mutex);
23572357

2358+
if (strcasestr(query_no_space, "INFORMATION_SCHEMA.TABLES") != nullptr) {
2359+
const char* info_table_name = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = DATABASE() AND table_name = '";
2360+
const char* info_engine_table_type = "SELECT engine, table_type FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = DATABASE() AND table_name = '";
2361+
2362+
if (query_no_space_length > strlen(info_table_name) &&
2363+
strncasecmp(query_no_space, info_table_name, strlen(info_table_name)) == 0) {
2364+
std::string query_str(query_no_space, query_no_space_length);
2365+
2366+
size_t start_pos = strlen(info_table_name);
2367+
size_t end_pos = query_str.find('\'', start_pos);
2368+
2369+
if (end_pos != std::string::npos) {
2370+
std::string table_name_value = query_str.substr(start_pos, end_pos - start_pos);
2371+
2372+
char buf[256];
2373+
snprintf(buf, sizeof(buf),
2374+
"SELECT name as TABLE_NAME FROM sqlite_master WHERE type = 'table' AND name = '%s'",
2375+
table_name_value.c_str());
2376+
2377+
l_free(query_length, query);
2378+
query = l_strdup(buf);
2379+
query_length = strlen(query) + 1;
2380+
goto __run_query;
2381+
}
2382+
}
2383+
2384+
if (query_no_space_length > strlen(info_engine_table_type) &&
2385+
strncasecmp(query_no_space, info_engine_table_type, strlen(info_engine_table_type)) == 0) {
2386+
std::string query_str(query_no_space, query_no_space_length);
2387+
2388+
size_t start_pos = strlen(info_engine_table_type);
2389+
size_t end_pos = query_str.find('\'', start_pos);
2390+
2391+
if (end_pos != std::string::npos) {
2392+
std::string table_name_value = query_str.substr(start_pos, end_pos - start_pos);
2393+
2394+
char buf[256];
2395+
snprintf(buf, sizeof(buf),
2396+
"SELECT 'SQLite' as ENGINE, 'BASE TABLE' as TABLE_TYPE FROM sqlite_master WHERE type = 'table' AND name = '%s'",
2397+
table_name_value.c_str());
2398+
2399+
l_free(query_length, query);
2400+
query = l_strdup(buf);
2401+
query_length = strlen(query) + 1;
2402+
goto __run_query;
2403+
}
2404+
}
2405+
}
2406+
2407+
if (strcasestr(query_no_space, "INFORMATION_SCHEMA.COLUMNS") != nullptr) {
2408+
const char* info_column_data_type = "SELECT column_name, extra, generation_expression, data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema=database() AND table_name='";
2409+
2410+
if (query_no_space_length > strlen(info_column_data_type) &&
2411+
strncasecmp(query_no_space, info_column_data_type, strlen(info_column_data_type)) == 0) {
2412+
std::string query_str(query_no_space, query_no_space_length);
2413+
2414+
size_t start_pos = strlen(info_column_data_type);
2415+
size_t end_pos = query_str.find('\'', start_pos);
2416+
2417+
if (end_pos != std::string::npos) {
2418+
std::string table_name_value = query_str.substr(start_pos, end_pos - start_pos);
2419+
2420+
char buf[256];
2421+
snprintf(buf, sizeof(buf),
2422+
"SELECT name as COLUMN_NAME, '' as EXTRA, '' as GENERATION_EXPRESSION, type as DATA_TYPE FROM pragma_table_info('%s') ORDER BY cid",
2423+
table_name_value.c_str());
2424+
2425+
l_free(query_length, query);
2426+
query = l_strdup(buf);
2427+
query_length = strlen(query) + 1;
2428+
goto __run_query;
2429+
}
2430+
}
2431+
}
2432+
2433+
if (!strncasecmp("SELECT LOGFILE", query_no_space, strlen("SELECT LOGFILE")) && strcasestr(query_no_space, "FROM INFORMATION_SCHEMA.FILES") != nullptr) {
2434+
string err_msg = "Invalid command - SELECT .. FROM INFORMATION_SCHEMA.FILES. ";
2435+
err_msg += "If you are using mysqldump, use --no-tablespaces flag to avoid this error message";
2436+
SPA->send_error_msg_to_client(sess, const_cast<char*>(err_msg.c_str()));
2437+
run_query = false;
2438+
goto __run_query;
2439+
}
2440+
23582441
if (sess->session_type == PROXYSQL_SESSION_ADMIN) { // no stats
23592442
if (!strncasecmp("LOGENTRY ", query_no_space, strlen("LOGENTRY "))) {
23602443
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Received command LOGENTRY: %s\n", query_no_space + strlen("LOGENTRY "));
@@ -2877,12 +2960,14 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) {
28772960
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
28782961
if (
28792962
!strncmp("/*!40014 SET ", query_no_space, 13) ||
2963+
!strncmp("/*!40100 SET ", query_no_space, 13) ||
28802964
!strncmp("/*!40101 SET ", query_no_space, 13) ||
28812965
!strncmp("/*!40103 SET ", query_no_space, 13) ||
28822966
!strncmp("/*!40111 SET ", query_no_space, 13) ||
28832967
!strncmp("/*!80000 SET ", query_no_space, 13) ||
28842968
!strncmp("/*!50503 SET ", query_no_space, 13) ||
28852969
!strncmp("/*!50717 SET ", query_no_space, 13) ||
2970+
!strncmp("/*M!100100 SET ", query_no_space, 15) ||
28862971
!strncmp("/*!50717 SELECT ", query_no_space, strlen("/*!50717 SELECT ")) ||
28872972
!strncmp("/*!50717 PREPARE ", query_no_space, strlen("/*!50717 PREPARE ")) ||
28882973
!strncmp("/*!50717 EXECUTE ", query_no_space, strlen("/*!50717 EXECUTE ")) ||
@@ -2905,13 +2990,68 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) {
29052990
||
29062991
!strncmp("SET SESSION character_set_results", query_no_space, strlen("SET SESSION character_set_results"))
29072992
||
2993+
!strncasecmp("FLUSH /*!40101 LOCAL */ TABLES", query_no_space, strlen("FLUSH /*!40101 LOCAL */ TABLES"))
2994+
||
2995+
!strncasecmp("FLUSH /*!40101 LOCAL */ LOGS", query_no_space, strlen("FLUSH /*!40101 LOCAL */ LOGS"))
2996+
||
2997+
!strncasecmp("FLUSH TABLES WITH READ LOCK", query_no_space, strlen("FLUSH TABLES WITH READ LOCK"))
2998+
||
29082999
!strncasecmp("USE ", query_no_space, strlen("USE ")) // this applies to all clients, not only mysqldump
29093000
) {
29103001
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
29113002
run_query=false;
29123003
goto __run_query;
29133004
}
29143005

3006+
if (query_no_space_length == strlen("SHOW MASTER STATUS") && !strncasecmp("SHOW MASTER STATUS", query_no_space, query_no_space_length)) {
3007+
l_free(query_length, query);
3008+
query = l_strdup("SELECT '' AS 'File', 0 AS 'Position', '' AS 'Binlog_Do_DB', '' AS 'Binlog_Ignore_DB', '' AS 'Executed_Gtid_Set' WHERE 1=0");
3009+
query_length = strlen(query) + 1;
3010+
goto __run_query;
3011+
}
3012+
3013+
if (query_no_space_length == strlen("SHOW BINARY LOG STATUS") && !strncasecmp("SHOW BINARY LOG STATUS", query_no_space, query_no_space_length)) {
3014+
l_free(query_length, query);
3015+
query = l_strdup("SELECT '' AS 'File', 0 AS 'Position', '' AS 'Binlog_Do_DB', '' AS 'Binlog_Ignore_DB', '' AS 'Executed_Gtid_Set' WHERE 1=0");
3016+
query_length = strlen(query) + 1;
3017+
goto __run_query;
3018+
}
3019+
3020+
if (query_no_space_length >= strlen("SHOW FUNCTION STATUS") && !strncasecmp("SHOW FUNCTION STATUS", query_no_space, strlen("SHOW FUNCTION STATUS"))) {
3021+
l_free(query_length, query);
3022+
query = l_strdup("SELECT '' AS 'Db', '' AS 'Name', '' AS 'Type', '' AS 'Definer', '' AS 'Modified', '' AS 'Created', '' AS 'Security_type', '' AS 'Comment', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
3023+
query_length = strlen(query) + 1;
3024+
goto __run_query;
3025+
}
3026+
3027+
if (query_no_space_length >= strlen("SHOW PROCEDURE STATUS") && !strncasecmp("SHOW PROCEDURE STATUS", query_no_space, strlen("SHOW PROCEDURE STATUS"))) {
3028+
l_free(query_length, query);
3029+
query = l_strdup("SELECT '' AS 'Db', '' AS 'Name', '' AS 'Type', '' AS 'Definer', '' AS 'Modified', '' AS 'Created', '' AS 'Security_type', '' AS 'Comment', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
3030+
query_length = strlen(query) + 1;
3031+
goto __run_query;
3032+
}
3033+
3034+
if (query_no_space_length >= strlen("SHOW TRIGGERS") && !strncasecmp("SHOW TRIGGERS", query_no_space, strlen("SHOW TRIGGERS"))) {
3035+
l_free(query_length, query);
3036+
query = l_strdup("SELECT '' AS 'Trigger', '' AS 'Event', '' AS 'Table', '' AS 'Statement', '' AS 'Timing', '' AS 'Created', '' AS 'sql_mode', '' AS 'Definer', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
3037+
query_length = strlen(query) + 1;
3038+
goto __run_query;
3039+
}
3040+
3041+
if (query_no_space_length >= strlen("SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS") && !strncasecmp("SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS", query_no_space, strlen("SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS"))) {
3042+
l_free(query_length, query);
3043+
query = l_strdup("SELECT '' AS 'TRIGGER_NAME' WHERE 1=0");
3044+
query_length = strlen(query) + 1;
3045+
goto __run_query;
3046+
}
3047+
3048+
if (query_no_space_length >= strlen("SHOW EVENTS") && !strncasecmp("SHOW EVENTS", query_no_space, strlen("SHOW EVENTS"))) {
3049+
l_free(query_length, query);
3050+
query = l_strdup("SELECT '' AS 'Db', '' AS 'Name', '' AS 'Definer', '' AS 'Time zone', '' AS 'Type', '' AS 'Execute at', '' AS 'Interval value', '' AS 'Interval field', '' AS 'Starts', '' AS 'Ends', '' AS 'Status', '' AS 'Originator', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
3051+
query_length = strlen(query) + 1;
3052+
goto __run_query;
3053+
}
3054+
29153055
if (!strncmp("SHOW STATUS LIKE 'binlog_snapshot_gtid_executed'", query_no_space, strlen("SHOW STATUS LIKE 'binlog_snapshot_gtid_executed'"))) {
29163056
l_free(query_length, query);
29173057
query = l_strdup("SELECT variable_name AS Variable_name, Variable_value AS Value FROM global_variables WHERE 1=0");

lib/MySQL_Session.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3671,6 +3671,9 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
36713671
case _MYSQL_COM_RESET_CONNECTION:
36723672
handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_RESET_CONNECTION(pkt);
36733673
break;
3674+
case _MYSQL_COM_REFRESH:
3675+
handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_REFRESH(pkt);
3676+
break;
36743677
default:
36753678
return false;
36763679
break;
@@ -5819,6 +5822,21 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
58195822
}
58205823
}
58215824

5825+
void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_REFRESH(PtrSize_t *pkt) {
5826+
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_REFRESH packet\n");
5827+
5828+
l_free(pkt->size, pkt->ptr);
5829+
client_myds->setDSS_STATE_QUERY_SENT_NET();
5830+
5831+
unsigned int nTrx = NumActiveTransactions();
5832+
uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0);
5833+
if (autocommit)
5834+
setStatus |= SERVER_STATUS_AUTOCOMMIT;
5835+
5836+
client_myds->myprot.generate_pkt_OK(true, NULL, NULL, 1, 0, 0, setStatus, 0, NULL);
5837+
client_myds->DSS=STATE_SLEEP;
5838+
}
5839+
58225840
void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PROCESS_KILL(PtrSize_t *pkt) {
58235841
l_free(pkt->size,pkt->ptr);
58245842
client_myds->setDSS_STATE_QUERY_SENT_NET();

0 commit comments

Comments
 (0)