Skip to content

Commit 011586c

Browse files
committed
MDEV-15686: Loading MyRocks plugin back after it has been unloaded causes a crash
- Disallow loading of MyRocks (or any auxilary) plugins after it has been unloaded. - Do it carefully - Plugin's system variables may be accesssed (e.g. default value is set) after the first rocksdb_done_func() call but before the secon rocksdb_init_func() call.
1 parent 907aae2 commit 011586c

File tree

5 files changed

+80
-2
lines changed

5 files changed

+80
-2
lines changed

storage/rocksdb/ha_rocksdb.cc

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3957,14 +3957,25 @@ static rocksdb::Status check_rocksdb_options_compatibility(
39573957
return status;
39583958
}
39593959

3960+
bool prevent_myrocks_loading= false;
3961+
39603962

39613963
/*
39623964
Storage Engine initialization function, invoked when plugin is loaded.
39633965
*/
39643966

39653967
static int rocksdb_init_func(void *const p) {
3968+
39663969
DBUG_ENTER_FUNC();
39673970

3971+
if (prevent_myrocks_loading)
3972+
{
3973+
my_error(ER_INTERNAL_ERROR, MYF(0),
3974+
"Loading MyRocks plugin after it has been unloaded is not "
3975+
"supported. Please restart mysqld");
3976+
DBUG_RETURN(1);
3977+
}
3978+
39683979
// Validate the assumption about the size of ROCKSDB_SIZEOF_HIDDEN_PK_COLUMN.
39693980
static_assert(sizeof(longlong) == 8, "Assuming that longlong is 8 bytes.");
39703981

@@ -4505,12 +4516,27 @@ static int rocksdb_done_func(void *const p) {
45054516
}
45064517
#endif /* HAVE_purify */
45074518

4508-
rocksdb_db_options = nullptr;
4509-
rocksdb_tbl_options = nullptr;
4519+
/*
4520+
MariaDB: don't clear rocksdb_db_options and rocksdb_tbl_options.
4521+
MyRocks' plugin variables refer to them.
4522+
4523+
The plugin cannot be loaded again (see prevent_myrocks_loading) but plugin
4524+
variables are processed before myrocks::rocksdb_init_func is invoked, so
4525+
they must point to valid memory.
4526+
*/
4527+
//rocksdb_db_options = nullptr;
4528+
rocksdb_db_options->statistics = nullptr;
4529+
//rocksdb_tbl_options = nullptr;
45104530
rocksdb_stats = nullptr;
45114531

45124532
my_error_unregister(HA_ERR_ROCKSDB_FIRST, HA_ERR_ROCKSDB_LAST);
45134533

4534+
/*
4535+
Prevent loading the plugin after it has been loaded and then unloaded. This
4536+
doesn't work currently.
4537+
*/
4538+
prevent_myrocks_loading= true;
4539+
45144540
DBUG_RETURN(error);
45154541
}
45164542

storage/rocksdb/ha_rocksdb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,4 +1414,5 @@ struct Rdb_inplace_alter_ctx : public my_core::inplace_alter_handler_ctx {
14141414

14151415
const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_GAMMA;
14161416

1417+
extern bool prevent_myrocks_loading;
14171418
} // namespace myrocks

storage/rocksdb/mysql-test/rocksdb/r/mariadb_plugin.result

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,11 @@ insert into test.t1 values (1);
1010
connection default;
1111
DROP TABLE t1;
1212
UNINSTALL SONAME 'ha_rocksdb';
13+
#
14+
# MDEV-15686: Loading MyRocks plugin back after it has been unloaded causes a crash
15+
#
16+
call mtr.add_suppression("Plugin 'ROCKSDB.*' init function returned error.");
17+
call mtr.add_suppression("Plugin 'ROCKSDB.*' registration as a INFORMATION SCHEMA failed.");
18+
call mtr.add_suppression("Plugin 'ROCKSDB' registration as a STORAGE ENGINE failed");
19+
INSTALL SONAME 'ha_rocksdb';
20+
ERROR HY000: Internal error: Loading MyRocks plugin after it has been unloaded is not supported. Please restart mysqld

storage/rocksdb/mysql-test/rocksdb/t/mariadb_plugin.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,13 @@ connection default;
2626
# Cleanup
2727
DROP TABLE t1;
2828
UNINSTALL SONAME 'ha_rocksdb';
29+
30+
--echo #
31+
--echo # MDEV-15686: Loading MyRocks plugin back after it has been unloaded causes a crash
32+
--echo #
33+
call mtr.add_suppression("Plugin 'ROCKSDB.*' init function returned error.");
34+
call mtr.add_suppression("Plugin 'ROCKSDB.*' registration as a INFORMATION SCHEMA failed.");
35+
call mtr.add_suppression("Plugin 'ROCKSDB' registration as a STORAGE ENGINE failed");
36+
37+
--error ER_INTERNAL_ERROR
38+
INSTALL SONAME 'ha_rocksdb';

storage/rocksdb/rdb_i_s.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ static int rdb_i_s_cfstats_fill_table(
142142
static int rdb_i_s_cfstats_init(void *p) {
143143
DBUG_ENTER_FUNC();
144144

145+
if (prevent_myrocks_loading)
146+
DBUG_RETURN(1);
147+
145148
DBUG_ASSERT(p != nullptr);
146149

147150
my_core::ST_SCHEMA_TABLE *schema;
@@ -235,6 +238,9 @@ static int rdb_i_s_dbstats_fill_table(
235238
static int rdb_i_s_dbstats_init(void *const p) {
236239
DBUG_ENTER_FUNC();
237240

241+
if (prevent_myrocks_loading)
242+
DBUG_RETURN(1);
243+
238244
DBUG_ASSERT(p != nullptr);
239245

240246
my_core::ST_SCHEMA_TABLE *schema;
@@ -336,6 +342,8 @@ static int rdb_i_s_perf_context_fill_table(
336342
static int rdb_i_s_perf_context_init(void *const p) {
337343
DBUG_ENTER_FUNC();
338344

345+
if (prevent_myrocks_loading)
346+
DBUG_RETURN(1);
339347
DBUG_ASSERT(p != nullptr);
340348

341349
my_core::ST_SCHEMA_TABLE *schema;
@@ -403,6 +411,9 @@ static int rdb_i_s_perf_context_global_fill_table(
403411
static int rdb_i_s_perf_context_global_init(void *const p) {
404412
DBUG_ENTER_FUNC();
405413

414+
if (prevent_myrocks_loading)
415+
DBUG_RETURN(1);
416+
406417
DBUG_ASSERT(p != nullptr);
407418

408419
my_core::ST_SCHEMA_TABLE *schema;
@@ -1017,6 +1028,9 @@ static int rdb_i_s_ddl_fill_table(my_core::THD *const thd,
10171028
static int rdb_i_s_ddl_init(void *const p) {
10181029
DBUG_ENTER_FUNC();
10191030

1031+
if (prevent_myrocks_loading)
1032+
DBUG_RETURN(1);
1033+
10201034
my_core::ST_SCHEMA_TABLE *schema;
10211035

10221036
DBUG_ASSERT(p != nullptr);
@@ -1032,6 +1046,9 @@ static int rdb_i_s_ddl_init(void *const p) {
10321046
static int rdb_i_s_cfoptions_init(void *const p) {
10331047
DBUG_ENTER_FUNC();
10341048

1049+
if (prevent_myrocks_loading)
1050+
DBUG_RETURN(1);
1051+
10351052
DBUG_ASSERT(p != nullptr);
10361053

10371054
my_core::ST_SCHEMA_TABLE *schema;
@@ -1047,6 +1064,9 @@ static int rdb_i_s_cfoptions_init(void *const p) {
10471064
static int rdb_i_s_global_info_init(void *const p) {
10481065
DBUG_ENTER_FUNC();
10491066

1067+
if (prevent_myrocks_loading)
1068+
DBUG_RETURN(1);
1069+
10501070
DBUG_ASSERT(p != nullptr);
10511071

10521072
my_core::ST_SCHEMA_TABLE *schema;
@@ -1063,6 +1083,10 @@ static int rdb_i_s_compact_stats_init(void *p) {
10631083
my_core::ST_SCHEMA_TABLE *schema;
10641084

10651085
DBUG_ENTER_FUNC();
1086+
1087+
if (prevent_myrocks_loading)
1088+
DBUG_RETURN(1);
1089+
10661090
DBUG_ASSERT(p != nullptr);
10671091

10681092
schema = reinterpret_cast<my_core::ST_SCHEMA_TABLE *>(p);
@@ -1237,6 +1261,9 @@ static int rdb_i_s_index_file_map_fill_table(
12371261
static int rdb_i_s_index_file_map_init(void *const p) {
12381262
DBUG_ENTER_FUNC();
12391263

1264+
if (prevent_myrocks_loading)
1265+
DBUG_RETURN(1);
1266+
12401267
DBUG_ASSERT(p != nullptr);
12411268

12421269
my_core::ST_SCHEMA_TABLE *schema;
@@ -1320,6 +1347,9 @@ static int rdb_i_s_lock_info_fill_table(
13201347
static int rdb_i_s_lock_info_init(void *const p) {
13211348
DBUG_ENTER_FUNC();
13221349

1350+
if (prevent_myrocks_loading)
1351+
DBUG_RETURN(1);
1352+
13231353
DBUG_ASSERT(p != nullptr);
13241354

13251355
my_core::ST_SCHEMA_TABLE *schema;
@@ -1450,6 +1480,9 @@ static int rdb_i_s_trx_info_fill_table(
14501480
static int rdb_i_s_trx_info_init(void *const p) {
14511481
DBUG_ENTER_FUNC();
14521482

1483+
if (prevent_myrocks_loading)
1484+
DBUG_RETURN(1);
1485+
14531486
DBUG_ASSERT(p != nullptr);
14541487

14551488
my_core::ST_SCHEMA_TABLE *schema;

0 commit comments

Comments
 (0)