153
144
static void maybe_exit(int error);
154
145
static void die(int error, const char* reason, ...);
155
static void maybe_die(int error, const char* reason, ...);
156
146
static void write_header(FILE *sql_file, char *db_name);
157
147
static int dump_selected_tables(const string &db, const vector<string> &table_names);
158
148
static int dump_databases(const vector<string> &db_names);
174
164
void generate_dump(void)
176
std::vector<DrizzleDumpDatabase*>::iterator i;
166
std::vector<DrizzleDumpDatabase*>::iterator i;
167
DrizzleStringBuf sbuf(1024);
168
std::ostream sout(&sbuf);
177
169
for (i= database_store.begin(); i != database_store.end(); ++i)
179
171
DrizzleDumpDatabase *database= *i;
185
Print the supplied message if in verbose mode
190
... variable number of parameters
193
static void verbose_msg(const char *fmt, ...)
202
vfprintf(stderr, fmt, args);
207
178
exit with message if ferror(file)
232
203
fputs("-- ------------------------------------------------------\n",
234
205
fprintf(sql_file, "-- Server version\t%s",
235
drizzle_con_server_version(&dcon));
236
if (connected_server_type == SERVER_MYSQL_FOUND)
206
db_connection->getServerVersion());
207
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
237
208
fprintf(sql_file, " (MySQL server)");
238
else if (connected_server_type == SERVER_DRIZZLE_FOUND)
209
else if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_DRIZZLE_FOUND)
239
210
fprintf(sql_file, " (Drizzle server)");
241
212
if (opt_set_charset)
316
** DB_error -- prints DRIZZLE error message and exits the program.
318
static void DB_error(drizzle_result_st *res, drizzle_return_t ret,
321
if (ret == DRIZZLE_RETURN_ERROR_CODE)
323
maybe_die(EX_DRIZZLEERR, _("Got error: %s (%d) %s"),
324
drizzle_result_error(res),
325
drizzle_result_error_code(res),
327
drizzle_result_free(res);
330
maybe_die(EX_DRIZZLEERR, _("Got error: %d %s"), ret, when);
338
287
Prints out an error message and kills the process.
362
311
maybe_exit(error_num);
367
Prints out an error message and maybe kills the process.
371
error_num - process return value
372
fmt_reason - a format string for use by vsnprintf.
373
... - variable arguments for above fmt_reason string
376
This call prints out the formatted error message to stderr and then
377
terminates the process, unless the --force command line option is used.
379
This call should be used for non-fatal errors (such as database
380
errors) that the code may still be able to continue to the next unit
384
static void maybe_die(int error_num, const char* fmt_reason, ...)
388
va_start(args,fmt_reason);
389
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
392
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
395
maybe_exit(error_num);
401
Sends a query to server, optionally reads result, prints error message if
405
drizzleclient_query_with_error_report()
406
drizzle_con connection to use
407
res if non zero, result will be put there with
408
drizzleclient_store_result()
409
query query to send to server
412
0 query sending and (if res!=0) result reading went ok
416
static int drizzleclient_query_with_error_report(drizzle_con_st *con,
417
drizzle_result_st *result,
418
const char *query_str,
421
drizzle_return_t ret;
423
if (drizzle_query_str(con, result, query_str, &ret) == NULL ||
424
ret != DRIZZLE_RETURN_OK)
426
if (ret == DRIZZLE_RETURN_ERROR_CODE)
428
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
429
query_str, drizzle_result_error(result),
430
drizzle_result_error_code(result));
431
drizzle_result_free(result);
435
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
436
query_str, drizzle_con_error(con), ret);
442
ret= drizzle_column_buffer(result);
444
ret= drizzle_result_buffer(result);
445
if (ret != DRIZZLE_RETURN_OK)
447
drizzle_result_free(result);
448
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
449
query_str, drizzle_con_error(con), ret);
456
314
static void free_resources(void)
458
316
if (md_result_file && md_result_file != stdout)
467
325
first_error= error;
468
326
if (ignore_errors)
470
drizzle_con_free(&dcon);
471
drizzle_free(&drizzle);
328
delete db_connection;
472
329
free_resources();
478
db_connect -- connects to the host and selects DB.
481
static int connect_to_db(string host, string user,string passwd)
483
drizzle_return_t ret;
485
verbose_msg(_("-- Connecting to %s, using protocol %s...\n"), ! host.empty() ? (char *)host.c_str() : "localhost", opt_protocol.c_str());
486
drizzle_create(&drizzle);
487
drizzle_con_create(&drizzle, &dcon);
488
drizzle_con_set_tcp(&dcon, (char *)host.c_str(), opt_drizzle_port);
489
drizzle_con_set_auth(&dcon, (char *)user.c_str(), (char *)passwd.c_str());
490
drizzle_con_add_options(&dcon, use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
491
ret= drizzle_con_connect(&dcon);
492
if (ret != DRIZZLE_RETURN_OK)
494
DB_error(NULL, ret, "when trying to connect");
498
int found= get_server_type();
502
case SERVER_MYSQL_FOUND:
503
verbose_msg(_("-- Connected to a MySQL server\n"));
504
connected_server_type= SERVER_MYSQL_FOUND;
506
case SERVER_DRIZZLE_FOUND:
507
verbose_msg(_("-- Connected to a Drizzle server\n"));
508
connected_server_type= SERVER_DRIZZLE_FOUND;
511
verbose_msg(_("-- Connected to an unknown server type\n"));
512
connected_server_type= SERVER_DRIZZLE_FOUND;
517
} /* connect_to_db */
521
** dbDisconnect -- disconnects from the host.
523
static void dbDisconnect(string &host)
525
verbose_msg(_("-- Disconnecting from %s...\n"), ! host.empty() ? host.c_str() : "localhost");
526
drizzle_con_free(&dcon);
527
drizzle_free(&drizzle);
530
333
static int dump_all_databases()
532
335
drizzle_row_t row;
533
drizzle_result_st tableres;
336
drizzle_result_st *tableres;
535
338
std::string query;
536
339
DrizzleDumpDatabase *database;
538
if (connected_server_type == SERVER_MYSQL_FOUND)
341
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
539
342
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema')";
541
344
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
543
if (drizzleclient_query_with_error_report(&dcon, &tableres, query.c_str(), false))
545
while ((row= drizzle_row_next(&tableres)))
346
tableres= db_connection->query(query);
347
while ((row= drizzle_row_next(tableres)))
547
349
std::string database_name(row[0]);
548
if (connected_server_type == SERVER_MYSQL_FOUND)
549
database= new DrizzleDumpDatabaseMySQL(database_name);
350
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
351
database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
551
database= new DrizzleDumpDatabaseDrizzle(database_name);
353
database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
553
355
database->setCollate(row[1]);
554
356
database_store.push_back(database);
556
drizzle_result_free(&tableres);
358
db_connection->freeResult(tableres);
559
361
/* dump_all_databases */
568
370
for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
571
if (connected_server_type == SERVER_MYSQL_FOUND)
572
database= new DrizzleDumpDatabaseMySQL(temp);
373
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
374
database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
574
database= new DrizzleDumpDatabaseDrizzle(temp);
376
database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
575
377
database_store.push_back(database);
582
384
DrizzleDumpDatabase *database;
583
385
DrizzleDumpTable *table;
585
if (connected_server_type == SERVER_MYSQL_FOUND)
586
database= new DrizzleDumpDatabaseMySQL(db);
387
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
388
database= new DrizzleDumpDatabaseMySQL(db, db_connection);
588
database= new DrizzleDumpDatabaseDrizzle(db);
390
database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
590
392
database_store.push_back(database);
592
394
for (vector<string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it)
594
396
string temp= *it;
595
if (connected_server_type == SERVER_MYSQL_FOUND)
596
table= new DrizzleDumpTableMySQL(temp);
397
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
398
table= new DrizzleDumpTableMySQL(temp, db_connection);
598
table= new DrizzleDumpTableDrizzle(temp);
400
table= new DrizzleDumpTableDrizzle(temp, db_connection);
599
401
database->tables.push_back(table);
601
403
database_store.push_back(database);
613
415
and most client connections are stalled. Of course, if a second long
614
416
update starts between the two FLUSHes, we have that bad stall.
617
( drizzleclient_query_with_error_report(drizzle_con, 0, "FLUSH TABLES", false) ||
618
drizzleclient_query_with_error_report(drizzle_con, 0,
619
"FLUSH TABLES WITH READ LOCK", false) );
622
static int do_unlock_tables(drizzle_con_st *drizzle_con)
624
return drizzleclient_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES", false);
627
static int start_transaction(drizzle_con_st *drizzle_con)
629
return (drizzleclient_query_with_error_report(drizzle_con, 0,
630
"SET SESSION TRANSACTION ISOLATION "
631
"LEVEL REPEATABLE READ", false) ||
632
drizzleclient_query_with_error_report(drizzle_con, 0,
634
"WITH CONSISTENT SNAPSHOT", false));
638
int get_server_type()
640
boost::match_flag_type flags = boost::match_default;
642
boost::regex mysql_regex("(5\\.[0-9]+\\.[0-9]+)");
643
boost::regex drizzle_regex("(20[0-9]{2}\\.(0[1-9]|1[012])\\.[0-9]+)");
645
std::string version(drizzle_con_server_version(&dcon));
647
if (regex_search(version, mysql_regex, flags))
648
return SERVER_MYSQL_FOUND;
650
if (regex_search(version, drizzle_regex, flags))
651
return SERVER_DRIZZLE_FOUND;
653
return SERVER_UNKNOWN_FOUND;
419
db_connection->queryNoResult("FLUSH TABLES");
420
db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
425
static int do_unlock_tables()
427
db_connection->queryNoResult("UNLOCK TABLES");
431
static int start_transaction()
433
db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
434
db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
656
438
int main(int argc, char **argv)
953
if (connect_to_db(current_host, current_user, opt_password))
734
db_connection = new DrizzleDumpConnection(current_host, opt_drizzle_port,
735
current_user, opt_password, use_drizzle_protocol);
959
if (connected_server_type == SERVER_MYSQL_FOUND)
961
if (drizzleclient_query_with_error_report(&dcon, &result, "SET NAMES 'utf8'", false))
963
drizzle_result_free(&result);
737
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
738
db_connection->queryNoResult("SET NAMES 'utf8'");
966
740
if (path.empty() && vm.count("database-used"))
969
743
write_header(md_result_file, (char *)database_used.c_str());
972
if ((opt_lock_all_tables) && do_flush_tables_read_lock(&dcon))
746
if ((opt_lock_all_tables) && do_flush_tables_read_lock())
974
if (opt_single_transaction && start_transaction(&dcon))
748
if (opt_single_transaction && start_transaction())
976
750
if (opt_lock_all_tables)
978
if (drizzleclient_query_with_error_report(&dcon, &result, "FLUSH LOGS", false))
980
drizzle_result_free(&result);
981
flush_logs= 0; /* not anymore; that would not be sensible */
983
if (opt_single_transaction && do_unlock_tables(&dcon)) /* unlock but no commit! */
751
db_connection->queryNoResult("FLUSH LOGS");
752
if (opt_single_transaction && do_unlock_tables()) /* unlock but no commit! */