Skip to content

Commit 7ae812c

Browse files
committed
Fix that BACKUP STAGE BLOCK_COMMIT blocks commit to the Aria engine
MDEV-22468 BACKUP STAGE BLOCK_COMMIT should block commit in the Aria engine This is needed to ensure that mariabackup works properly with Aria tables This code ads new calls to ha_maria::implicit_commit(). These will be deleted by MDEV-22531 Remove maria::implicit_commit().
1 parent b156156 commit 7ae812c

File tree

6 files changed

+122
-23
lines changed

6 files changed

+122
-23
lines changed

mysql-test/main/backup_lock.result

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,10 @@ BACKUP STAGE END;
192192
SET GLOBAL lock_wait_timeout=0;
193193
CREATE TABLE t_permanent_innodb (col1 INT) ENGINE = InnoDB;
194194
CREATE TABLE t_permanent_myisam (col1 INT) ENGINE = MyISAM;
195+
CREATE TABLE t_permanent_aria (col1 INT) ENGINE = Aria transactional=1;
195196
INSERT INTO t_permanent_innodb SET col1 = 1;
196197
INSERT INTO t_permanent_myisam SET col1 = 1;
198+
INSERT INTO t_permanent_aria SET col1 = 1;
197199
CREATE TABLE t_con1_innodb (col1 INT) ENGINE = InnoDB;
198200
CREATE TABLE t_con1_myisam (col1 INT) ENGINE = MyISAM;
199201
connect con1,localhost,root,,;
@@ -207,13 +209,23 @@ connection con1;
207209
UPDATE t_permanent_innodb SET col1 = 8;
208210
UPDATE t_permanent_myisam SET col1 = 8;
209211
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
212+
UPDATE t_permanent_aria SET col1 = 8;
210213
DROP TABLE t_con1_innodb;
211214
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
212215
DROP TABLE t_con1_myisam;
213216
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
214217
connection default;
215218
BACKUP STAGE END;
216-
DROP TABLE t_permanent_myisam, t_permanent_innodb;
219+
select * from t_permanent_innodb;
220+
col1
221+
1
222+
select * from t_permanent_myisam;
223+
col1
224+
1
225+
select * from t_permanent_aria;
226+
col1
227+
8
228+
DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria;
217229
DROP TABLE t_con1_innodb, t_con1_myisam;
218230
disconnect con1;
219231
set global lock_wait_timeout=default;

mysql-test/main/backup_lock.test

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,11 @@ BACKUP STAGE END;
251251
SET GLOBAL lock_wait_timeout=0;
252252
CREATE TABLE t_permanent_innodb (col1 INT) ENGINE = InnoDB;
253253
CREATE TABLE t_permanent_myisam (col1 INT) ENGINE = MyISAM;
254+
CREATE TABLE t_permanent_aria (col1 INT) ENGINE = Aria transactional=1;
254255
INSERT INTO t_permanent_innodb SET col1 = 1;
255-
256256
INSERT INTO t_permanent_myisam SET col1 = 1;
257+
INSERT INTO t_permanent_aria SET col1 = 1;
258+
257259
CREATE TABLE t_con1_innodb (col1 INT) ENGINE = InnoDB;
258260
CREATE TABLE t_con1_myisam (col1 INT) ENGINE = MyISAM;
259261

@@ -270,6 +272,8 @@ BACKUP STAGE BLOCK_COMMIT;
270272
UPDATE t_permanent_innodb SET col1 = 8;
271273
--error ER_LOCK_WAIT_TIMEOUT
272274
UPDATE t_permanent_myisam SET col1 = 8;
275+
UPDATE t_permanent_aria SET col1 = 8;
276+
273277
--error ER_LOCK_WAIT_TIMEOUT
274278
DROP TABLE t_con1_innodb;
275279

@@ -278,7 +282,12 @@ DROP TABLE t_con1_myisam;
278282

279283
--connection default
280284
BACKUP STAGE END;
281-
DROP TABLE t_permanent_myisam, t_permanent_innodb;
285+
286+
select * from t_permanent_innodb;
287+
select * from t_permanent_myisam;
288+
select * from t_permanent_aria;
289+
290+
DROP TABLE t_permanent_myisam, t_permanent_innodb, t_permanent_aria;
282291
DROP TABLE t_con1_innodb, t_con1_myisam;
283292
--disconnect con1
284293
set global lock_wait_timeout=default;

sql/handler.cc

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,16 +1531,6 @@ int ha_commit_trans(THD *thd, bool all)
15311531
DBUG_RETURN(2);
15321532
}
15331533

1534-
#ifdef WITH_ARIA_STORAGE_ENGINE
1535-
if ((error= ha_maria::implicit_commit(thd, TRUE)))
1536-
{
1537-
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
1538-
ha_rollback_trans(thd, all);
1539-
DBUG_RETURN(1);
1540-
}
1541-
1542-
#endif
1543-
15441534
if (!ha_info)
15451535
{
15461536
/*
@@ -1556,6 +1546,16 @@ int ha_commit_trans(THD *thd, bool all)
15561546
if (wsrep_is_active(thd) && is_real_trans && !error)
15571547
wsrep_commit_empty(thd, all);
15581548
#endif /* WITH_WSREP */
1549+
1550+
#if defined(WITH_ARIA_STORAGE_ENGINE)
1551+
/* This is needed to ensure that repair commits properly */
1552+
if ((error= ha_maria::implicit_commit(thd, TRUE)))
1553+
{
1554+
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
1555+
ha_rollback_trans(thd, all);
1556+
DBUG_RETURN(1);
1557+
}
1558+
#endif
15591559
DBUG_RETURN(0);
15601560
}
15611561

@@ -1570,10 +1570,16 @@ int ha_commit_trans(THD *thd, bool all)
15701570
bool rw_trans= is_real_trans &&
15711571
(rw_ha_count > (thd->is_current_stmt_binlog_disabled()?0U:1U));
15721572
MDL_request mdl_request;
1573+
mdl_request.ticket= 0;
15731574
DBUG_PRINT("info", ("is_real_trans: %d rw_trans: %d rw_ha_count: %d",
15741575
is_real_trans, rw_trans, rw_ha_count));
15751576

1576-
if (rw_trans)
1577+
/*
1578+
We need to test maria_hton because of plugin_innodb.test that changes
1579+
the plugin table to innodb and thus plugin_load will call
1580+
mysql_close_tables() which calls trans_commit_trans() with maria_hton = 0
1581+
*/
1582+
if (rw_trans || (likely(maria_hton) && thd_get_ha_data(thd, maria_hton)))
15771583
{
15781584
/*
15791585
Acquire a metadata lock which will ensure that COMMIT is blocked
@@ -1587,15 +1593,22 @@ int ha_commit_trans(THD *thd, bool all)
15871593
MDL_EXPLICIT);
15881594

15891595
if (!WSREP(thd) &&
1590-
thd->mdl_context.acquire_lock(&mdl_request,
1591-
thd->variables.lock_wait_timeout))
1596+
thd->mdl_context.acquire_lock(&mdl_request,
1597+
thd->variables.lock_wait_timeout))
15921598
{
15931599
ha_rollback_trans(thd, all);
15941600
DBUG_RETURN(1);
15951601
}
15961602

15971603
DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
15981604
}
1605+
#if defined(WITH_ARIA_STORAGE_ENGINE)
1606+
if ((error= ha_maria::implicit_commit(thd, TRUE)))
1607+
{
1608+
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
1609+
goto err;
1610+
}
1611+
#endif
15991612

16001613
if (rw_trans &&
16011614
opt_readonly &&
@@ -1797,7 +1810,7 @@ int ha_commit_trans(THD *thd, bool all)
17971810
thd->rgi_slave->is_parallel_exec);
17981811
}
17991812
end:
1800-
if (rw_trans && mdl_request.ticket)
1813+
if (mdl_request.ticket)
18011814
{
18021815
/*
18031816
We do not always immediately release transactional locks

sql/handler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class Column_definition;
7070
#define HA_ADMIN_NEEDS_UPGRADE -10
7171
#define HA_ADMIN_NEEDS_ALTER -11
7272
#define HA_ADMIN_NEEDS_CHECK -12
73+
#define HA_ADMIN_COMMIT_ERROR -13
7374

7475
/**
7576
Return values for check_if_supported_inplace_alter().

sql/sql_parse.cc

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,67 @@ uint maria_multi_check(THD *thd, char *packet, size_t packet_length)
15081508
}
15091509

15101510

1511+
#if defined(WITH_ARIA_STORAGE_ENGINE)
1512+
class Silence_all_errors : public Internal_error_handler
1513+
{
1514+
char m_message[MYSQL_ERRMSG_SIZE];
1515+
int error;
1516+
public:
1517+
Silence_all_errors():error(0) {}
1518+
virtual ~Silence_all_errors() {}
1519+
1520+
virtual bool handle_condition(THD *thd,
1521+
uint sql_errno,
1522+
const char* sql_state,
1523+
Sql_condition::enum_warning_level *level,
1524+
const char* msg,
1525+
Sql_condition ** cond_hdl)
1526+
{
1527+
error= sql_errno;
1528+
*cond_hdl= NULL;
1529+
strmake_buf(m_message, msg);
1530+
return true; // Error handled
1531+
}
1532+
};
1533+
#endif
1534+
1535+
/*
1536+
Do an implict commit into the Aria storage engine
1537+
*/
1538+
1539+
static inline my_bool aria_implicit_commit(THD *thd)
1540+
{
1541+
#if defined(WITH_ARIA_STORAGE_ENGINE)
1542+
if (thd_get_ha_data(thd, maria_hton))
1543+
{
1544+
MDL_request mdl_request;
1545+
bool locked;
1546+
int res;
1547+
Silence_all_errors error_handler;
1548+
DBUG_ASSERT(maria_hton);
1549+
1550+
MDL_REQUEST_INIT(&mdl_request, MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
1551+
MDL_EXPLICIT);
1552+
/*
1553+
We have to ignore any errors from acquire_lock and continue even if we
1554+
don't get the lock as Aria can't roll back!
1555+
This function is also called in some cases when the message is already
1556+
sent to the user, so we can't even send a warning.
1557+
*/
1558+
thd->push_internal_handler(& error_handler);
1559+
locked= !thd->mdl_context.acquire_lock(&mdl_request,
1560+
thd->variables.lock_wait_timeout);
1561+
thd->pop_internal_handler();
1562+
res= ha_maria::implicit_commit(thd, FALSE);
1563+
if (locked)
1564+
thd->mdl_context.release_lock(mdl_request.ticket);
1565+
return res;
1566+
}
1567+
#endif
1568+
return 0;
1569+
}
1570+
1571+
15111572
/**
15121573
Perform one connection-level (COM_XXXX) command.
15131574
@@ -1860,9 +1921,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
18601921
*/
18611922
char *beginning_of_next_stmt= (char*) parser_state.m_lip.found_semicolon;
18621923

1863-
#ifdef WITH_ARIA_STORAGE_ENGINE
1864-
ha_maria::implicit_commit(thd, FALSE);
1865-
#endif
1924+
aria_implicit_commit(thd);
18661925

18671926
/* Finalize server status flags after executing a statement. */
18681927
thd->update_server_status();
@@ -5990,9 +6049,7 @@ mysql_execute_command(THD *thd)
59906049
trans_commit_stmt(thd);
59916050
thd->get_stmt_da()->set_overwrite_status(false);
59926051
}
5993-
#ifdef WITH_ARIA_STORAGE_ENGINE
5994-
ha_maria::implicit_commit(thd, FALSE);
5995-
#endif
6052+
aria_implicit_commit(thd);
59966053
}
59976054

59986055
/* Free tables. Set stage 'closing tables' */

storage/maria/ha_maria.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,13 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
14771477
}
14781478
break;
14791479
}
1480+
/*
1481+
Commit is needed in the case of tables are locked to ensure that repair
1482+
is registered in the recovery log
1483+
*/
1484+
if (implicit_commit(thd, TRUE))
1485+
error= HA_ADMIN_COMMIT_ERROR;
1486+
14801487
if (!error && start_records != file->state->records &&
14811488
!(check_opt->flags & T_VERY_SILENT))
14821489
{

0 commit comments

Comments
 (0)