Skip to content

Commit 922e7ba

Browse files
committed
MDEV-16791 mariabackup : Support DDL commands during backup
1 parent 9a4998a commit 922e7ba

26 files changed

+1074
-80
lines changed

extra/mariabackup/backup_copy.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,30 @@ backup_files(const char *from, bool prep_mode)
13881388
return(ret);
13891389
}
13901390

1391+
void backup_fix_ddl(void);
1392+
1393+
#define LSN_PREFIX_IN_SHOW_STATUS "\nLog sequence number "
1394+
static lsn_t get_current_lsn(MYSQL *connection) {
1395+
MYSQL_RES *res = xb_mysql_query(connection, "SHOW ENGINE INNODB STATUS", true, false);
1396+
if (!res)
1397+
return 0;
1398+
MYSQL_ROW row = mysql_fetch_row(res);
1399+
DBUG_ASSERT(row);
1400+
if (row) {
1401+
const char *p = strstr(row[2],LSN_PREFIX_IN_SHOW_STATUS);
1402+
DBUG_ASSERT(p);
1403+
if (p)
1404+
{
1405+
p += sizeof(LSN_PREFIX_IN_SHOW_STATUS) - 1;
1406+
return (lsn_t)strtoll(p, NULL, 10);
1407+
}
1408+
}
1409+
mysql_free_result(res);
1410+
return 0;
1411+
}
1412+
1413+
lsn_t server_lsn_after_lock;
1414+
extern void backup_wait_for_lsn(lsn_t lsn);
13911415
/** Start --backup */
13921416
bool backup_start()
13931417
{
@@ -1407,6 +1431,7 @@ bool backup_start()
14071431
if (!lock_tables(mysql_connection)) {
14081432
return(false);
14091433
}
1434+
server_lsn_after_lock = get_current_lsn(mysql_connection);
14101435
}
14111436

14121437
if (!backup_files(fil_path_to_mysql_datadir, false)) {
@@ -1421,6 +1446,10 @@ bool backup_start()
14211446
rocksdb_create_checkpoint();
14221447
}
14231448

1449+
msg_ts("Waiting for log copy thread to read lsn %llu\n", (ulonglong)server_lsn_after_lock);
1450+
backup_wait_for_lsn(server_lsn_after_lock);
1451+
backup_fix_ddl();
1452+
14241453
// There is no need to stop slave thread before coping non-Innodb data when
14251454
// --no-lock option is used because --no-lock option requires that no DDL or
14261455
// DML to non-transaction tables can occur.
@@ -2230,6 +2259,7 @@ static void rocksdb_lock_checkpoint()
22302259
msg_ts("Could not obtain rocksdb checkpont lock\n");
22312260
exit(EXIT_FAILURE);
22322261
}
2262+
mysql_free_result(res);
22332263
}
22342264

22352265
static void rocksdb_unlock_checkpoint()

extra/mariabackup/backup_mysql.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1794,7 +1794,12 @@ mdl_lock_table(ulint space_id)
17941794
std::ostringstream lock_query;
17951795
lock_query << "SELECT 1 FROM " << full_table_name << " LIMIT 0";
17961796
msg_ts("Locking MDL for %s\n", full_table_name.c_str());
1797-
xb_mysql_query(mdl_con, lock_query.str().c_str(), false, true);
1797+
if (mysql_query(mdl_con, lock_query.str().c_str())) {
1798+
msg_ts("Warning : locking MDL failed for space id %zu, name %s\n", space_id, full_table_name.c_str());
1799+
} else {
1800+
MYSQL_RES *r = mysql_store_result(mdl_con);
1801+
mysql_free_result(r);
1802+
}
17981803
}
17991804

18001805
pthread_mutex_unlock(&mdl_lock_con_mutex);

extra/mariabackup/datasink.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ Write to a datasink file.
108108
int
109109
ds_write(ds_file_t *file, const void *buf, size_t len)
110110
{
111+
if (len == 0) {
112+
return 0;
113+
}
111114
return file->datasink->write(file, (const uchar *)buf, len);
112115
}
113116

extra/mariabackup/fil_cur.cc

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,15 @@ Open a source file cursor and initialize the associated read filter.
131131
be skipped and XB_FIL_CUR_ERROR on error. */
132132
xb_fil_cur_result_t
133133
xb_fil_cur_open(
134-
/*============*/
134+
/*============*/
135135
xb_fil_cur_t* cursor, /*!< out: source file cursor */
136136
xb_read_filt_t* read_filter, /*!< in/out: the read filter */
137137
fil_node_t* node, /*!< in: source tablespace node */
138-
uint thread_n) /*!< thread number for diagnostics */
138+
uint thread_n, /*!< thread number for diagnostics */
139+
ulonglong max_file_size)
139140
{
140141
bool success;
141-
142+
int err;
142143
/* Initialize these first so xb_fil_cur_close() handles them correctly
143144
in case of error */
144145
cursor->orig_buf = NULL;
@@ -173,7 +174,7 @@ xb_fil_cur_open(
173174
"tablespace %s\n",
174175
thread_n, cursor->abs_path);
175176

176-
return(XB_FIL_CUR_ERROR);
177+
return(XB_FIL_CUR_SKIP);
177178
}
178179
mutex_enter(&fil_system->mutex);
179180

@@ -194,14 +195,31 @@ xb_fil_cur_open(
194195

195196
cursor->node = node;
196197
cursor->file = node->handle;
197-
198-
if (stat(cursor->abs_path, &cursor->statinfo)) {
199-
msg("[%02u] mariabackup: error: cannot stat %s\n",
198+
#ifdef _WIN32
199+
HANDLE hDup;
200+
DuplicateHandle(GetCurrentProcess(),cursor->file.m_file,
201+
GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
202+
int filenr = _open_osfhandle((intptr_t)hDup, 0);
203+
if (filenr < 0) {
204+
err = EINVAL;
205+
}
206+
else {
207+
err = _fstat64(filenr, &cursor->statinfo);
208+
close(filenr);
209+
}
210+
#else
211+
err = fstat(cursor->file.m_file, &cursor->statinfo);
212+
#endif
213+
if (max_file_size < (ulonglong)cursor->statinfo.st_size) {
214+
cursor->statinfo.st_size = (ulonglong)max_file_size;
215+
}
216+
if (err) {
217+
msg("[%02u] mariabackup: error: cannot fstat %s\n",
200218
thread_n, cursor->abs_path);
201219

202220
xb_fil_cur_close(cursor);
203221

204-
return(XB_FIL_CUR_ERROR);
222+
return(XB_FIL_CUR_SKIP);
205223
}
206224

207225
if (srv_file_flush_method == SRV_O_DIRECT
@@ -374,7 +392,9 @@ xb_fil_cur_close(
374392
/*=============*/
375393
xb_fil_cur_t *cursor) /*!< in/out: source file cursor */
376394
{
377-
cursor->read_filter->deinit(&cursor->read_filter_ctxt);
395+
if (cursor->read_filter) {
396+
cursor->read_filter->deinit(&cursor->read_filter_ctxt);
397+
}
378398

379399
free(cursor->orig_buf);
380400

extra/mariabackup/fil_cur.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct xb_fil_cur_t {
5757
ulint space_size; /*!< space size in pages */
5858

5959
/** TODO: remove this default constructor */
60-
xb_fil_cur_t() : page_size(0), read_filter_ctxt() {}
60+
xb_fil_cur_t() : page_size(0), read_filter(0), read_filter_ctxt() {}
6161

6262
/** @return whether this is not a file-per-table tablespace */
6363
bool is_system() const
@@ -86,7 +86,8 @@ xb_fil_cur_open(
8686
xb_fil_cur_t* cursor, /*!< out: source file cursor */
8787
xb_read_filt_t* read_filter, /*!< in/out: the read filter */
8888
fil_node_t* node, /*!< in: source tablespace node */
89-
uint thread_n); /*!< thread number for diagnostics */
89+
uint thread_n, /*!< thread number for diagnostics */
90+
ulonglong max_file_size = ULLONG_MAX);
9091

9192
/************************************************************************
9293
Reads and verifies the next block of pages from the source

0 commit comments

Comments
 (0)