Skip to content

Commit 8b288c1

Browse files
author
Aditya A
committed
Merge branch 'mysql-8.4' into mysql-trunk
2 parents fa11f59 + 2e1f32d commit 8b288c1

File tree

10 files changed

+274
-140
lines changed

10 files changed

+274
-140
lines changed

mysql-test/suite/innodb/r/alter_datadir_path.result

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,53 +232,78 @@ DROP TABLE dbtest.t7c;
232232
CREATE TABLE `t8a` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY='MYSQL_TMP_DIR/external_dir', PARTITION p1 VALUES LESS THAN (20) DATA DIRECTORY='MYSQL_TMP_DIR/external_dir2');
233233
CREATE TABLE `t8b` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY='MYSQL_TMP_DIR/external_dir', PARTITION p1 VALUES LESS THAN (20) DATA DIRECTORY='MYSQL_TMP_DIR/external_dir2');
234234
CREATE TABLE `t8c` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY='MYSQL_TMP_DIR/external_dir', PARTITION p1 VALUES LESS THAN (20) DATA DIRECTORY='MYSQL_TMP_DIR/external_dir2');
235+
# Partition table with one partition in external directory and one in default directory
236+
CREATE TABLE `t8d` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (10) DATA DIRECTORY='MYSQL_TMP_DIR/external_dir', PARTITION p1 VALUES LESS THAN (20) );
235237
# Shutdown server
236-
# Check that for partition p0 for t8a, t8b, t8c exist in EXTERNAL_DIR and partition p1 for for t8a, t8b, t8c exist in EXTERNAL_DIR2
238+
# Check that for partition p0 for t8a, t8b, t8c and t8d exist in EXTERNAL_DIR and partition p1 for for t8a, t8b, t8c exist in EXTERNAL_DIR2
237239
# Listing EXTERNAL_DIR
238240
t8a#p#p0.ibd
239241
t8b#p#p0.ibd
240242
t8c#p#p0.ibd
243+
t8d#p#p0.ibd
241244
# Listing EXTERNAL_DIR2
242245
t8a#p#p1.ibd
243246
t8b#p#p1.ibd
244247
t8c#p#p1.ibd
248+
# List default directory. t8d's p1 partition should be present
249+
t8d#p#p1.ibd
245250
# Restart the server
246251
# restart: --innodb-directories=MYSQL_TMP_DIR/external_dir;MYSQL_TMP_DIR/external_dir2
247252
# Alter table
248253
ALTER TABLE dbtest.t8a FORCE;
249254
ALTER TABLE dbtest.t8b FORCE, ALGORITHM=INPLACE;
250255
ALTER TABLE dbtest.t8c FORCE, ALGORITHM=COPY;
256+
ALTER TABLE dbtest.t8d FORCE, ALGORITHM=COPY;
251257
# Check that for partition p0 for t8a, t8b, t8c still exist in EXTERNAL_DIR and partition p1 for for t8a, t8b, t8c still exist in EXTERNAL_DIR2
252258
# Listing EXTERNAL_DIR
253259
t8a#p#p0.ibd
254260
t8b#p#p0.ibd
255261
t8c#p#p0.ibd
262+
t8d#p#p0.ibd
256263
# Listing EXTERNAL_DIR2
257264
t8a#p#p1.ibd
258265
t8b#p#p1.ibd
259266
t8c#p#p1.ibd
267+
# List default directory. t8d's p1 partition should be present
268+
t8d#p#p1.ibd
260269
# Shutdown server
261-
# Now lets move all partitioned tables p0 of t8a, t8b, t8c from EXTERNAL_DIR and partitioned tables p1 of t8a, t8b, t8c from EXTERNAL_DIR2 to default directory
270+
# Now lets move all partitioned tables p0 of t8a, t8b, t8c, t8d from EXTERNAL_DIR and partitioned tables p1 of t8a, t8b, t8c from EXTERNAL_DIR2 to default directory
262271
# Restart the server
263272
# restart: --innodb-directories=MYSQL_TMP_DIR/external_dir;MYSQL_TMP_DIR/external_dir2
264273
# Alter table
265274
ALTER TABLE dbtest.t8a FORCE;
266275
ALTER TABLE dbtest.t8b FORCE, ALGORITHM=INPLACE;
267276
ALTER TABLE dbtest.t8c FORCE, ALGORITHM=COPY;
268-
# Check that all the partitioned tables for t8a, t8b, t8c now exist in default directory
277+
# Check that all the partitioned tables for t8a, t8b, t8c and t8d now exist in default directory
269278
t8a#p#p0.ibd
270279
t8a#p#p1.ibd
271280
t8b#p#p0.ibd
272281
t8b#p#p1.ibd
273282
t8c#p#p0.ibd
274283
t8c#p#p1.ibd
284+
t8d#p#p0.ibd
285+
t8d#p#p1.ibd
286+
# Check that EXTERNAL_DIR and EXTERNAL_DIR2 are empty
287+
# Listing EXTERNAL_DIR
288+
# Listing EXTERNAL_DIR2
289+
ALTER TABLE dbtest.t8d FORCE, ALGORITHM=COPY;
290+
# Check that all the partitioned tables for t8a, t8b, t8c and t8d now exist in default directory
291+
t8a#p#p0.ibd
292+
t8a#p#p1.ibd
293+
t8b#p#p0.ibd
294+
t8b#p#p1.ibd
295+
t8c#p#p0.ibd
296+
t8c#p#p1.ibd
297+
t8d#p#p0.ibd
298+
t8d#p#p1.ibd
275299
# Check that EXTERNAL_DIR and EXTERNAL_DIR2 are empty
276300
# Listing EXTERNAL_DIR
277301
# Listing EXTERNAL_DIR2
278302
# Drop tables
279303
DROP TABLE dbtest.t8a;
280304
DROP TABLE dbtest.t8b;
281305
DROP TABLE dbtest.t8c;
306+
DROP TABLE dbtest.t8d;
282307
# Clean up for other tests
283308
# 2. Creating partitioned table without data directory clause but moving each partition to different external directories
284309
# Partition tables

mysql-test/suite/innodb/t/alter_datadir_path.test

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#Table t8a: Covers scenario create partitioned table with data directory clause and both partitions in different directories, move to default dir and alter table force
2929
#Table t8b: Covers scenario create partitioned table with data directory clause and both partitions in different directories, move to default dir and alter table force algo=inplace
3030
#Table t8c: Covers scenario create partitioned table with data directory clause and both partitions in different directories, move to default dir and alter table force algo=copy
31+
#Table t8d: Covers scenario create partitioned table with one partition in data directory clause and the other partition in default data dir path, move to default dir and alter table force algo=copy
3132
#Table t9a: Covers scenario create partitioned table without data directory clause but moving each partition to different external directories and alter table force
3233
#Table t9b: Covers scenario create partitioned table without data directory clause but moving each partition to different external directories and alter table force algo=inplace
3334
#Table t9c: Covers scenario create partitioned table without data directory clause but moving each partition to different external directories and alter table force algo=copy
@@ -296,18 +297,24 @@ eval CREATE TABLE `t8a` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUE
296297
eval CREATE TABLE `t8b` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (10) $data_directory_clause, PARTITION p1 VALUES LESS THAN (20) $data_directory_clause2);
297298
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
298299
eval CREATE TABLE `t8c` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (10) $data_directory_clause, PARTITION p1 VALUES LESS THAN (20) $data_directory_clause2);
300+
--echo # Partition table with one partition in external directory and one in default directory
301+
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
302+
eval CREATE TABLE `t8d` (a INT, b INT) PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (10) $data_directory_clause, PARTITION p1 VALUES LESS THAN (20) );
299303

300304
--echo # Shutdown server
301305
--source include/shutdown_mysqld.inc
302306

303-
--echo # Check that for partition p0 for t8a, t8b, t8c exist in EXTERNAL_DIR and partition p1 for for t8a, t8b, t8c exist in EXTERNAL_DIR2
307+
--echo # Check that for partition p0 for t8a, t8b, t8c and t8d exist in EXTERNAL_DIR and partition p1 for for t8a, t8b, t8c exist in EXTERNAL_DIR2
304308

305309
--echo # Listing EXTERNAL_DIR
306310
--list_files $EXTERNAL_DIR/dbtest/ *
307311

308312
--echo # Listing EXTERNAL_DIR2
309313
--list_files $EXTERNAL_DIR2/dbtest/ *
310314

315+
--echo # List default directory. t8d's p1 partition should be present
316+
--list_files $MYSQLD_DATADIR/dbtest *
317+
311318
--echo # Restart the server
312319
--let $innodb_dirs=$EXTERNAL_DIR;$EXTERNAL_DIR2
313320
let restart_parameters = restart: --innodb-directories=$innodb_dirs;
@@ -318,7 +325,7 @@ let restart_parameters = restart: --innodb-directories=$innodb_dirs;
318325
ALTER TABLE dbtest.t8a FORCE;
319326
ALTER TABLE dbtest.t8b FORCE, ALGORITHM=INPLACE;
320327
ALTER TABLE dbtest.t8c FORCE, ALGORITHM=COPY;
321-
328+
ALTER TABLE dbtest.t8d FORCE, ALGORITHM=COPY;
322329
--echo # Check that for partition p0 for t8a, t8b, t8c still exist in EXTERNAL_DIR and partition p1 for for t8a, t8b, t8c still exist in EXTERNAL_DIR2
323330

324331
--echo # Listing EXTERNAL_DIR
@@ -327,10 +334,13 @@ ALTER TABLE dbtest.t8c FORCE, ALGORITHM=COPY;
327334
--echo # Listing EXTERNAL_DIR2
328335
--list_files $EXTERNAL_DIR2/dbtest/ *
329336

337+
--echo # List default directory. t8d's p1 partition should be present
338+
--list_files $MYSQLD_DATADIR/dbtest *
339+
330340
--echo # Shutdown server
331341
--source include/shutdown_mysqld.inc
332342

333-
--echo # Now lets move all partitioned tables p0 of t8a, t8b, t8c from EXTERNAL_DIR and partitioned tables p1 of t8a, t8b, t8c from EXTERNAL_DIR2 to default directory
343+
--echo # Now lets move all partitioned tables p0 of t8a, t8b, t8c, t8d from EXTERNAL_DIR and partitioned tables p1 of t8a, t8b, t8c from EXTERNAL_DIR2 to default directory
334344
--copy_files_wildcard $EXTERNAL_DIR/dbtest/ $MYSQLD_DATADIR/dbtest/ *
335345
--remove_files_wildcard $EXTERNAL_DIR/dbtest/ *
336346
--copy_files_wildcard $EXTERNAL_DIR2/dbtest/ $MYSQLD_DATADIR/dbtest/ *
@@ -347,7 +357,19 @@ ALTER TABLE dbtest.t8a FORCE;
347357
ALTER TABLE dbtest.t8b FORCE, ALGORITHM=INPLACE;
348358
ALTER TABLE dbtest.t8c FORCE, ALGORITHM=COPY;
349359

350-
--echo # Check that all the partitioned tables for t8a, t8b, t8c now exist in default directory
360+
--echo # Check that all the partitioned tables for t8a, t8b, t8c and t8d now exist in default directory
361+
--list_files $MYSQLD_DATADIR/dbtest *
362+
363+
--echo # Check that EXTERNAL_DIR and EXTERNAL_DIR2 are empty
364+
--echo # Listing EXTERNAL_DIR
365+
--list_files $EXTERNAL_DIR/dbtest/ *
366+
367+
--echo # Listing EXTERNAL_DIR2
368+
--list_files $EXTERNAL_DIR2/dbtest/ *
369+
370+
ALTER TABLE dbtest.t8d FORCE, ALGORITHM=COPY;
371+
372+
--echo # Check that all the partitioned tables for t8a, t8b, t8c and t8d now exist in default directory
351373
--list_files $MYSQLD_DATADIR/dbtest *
352374

353375
--echo # Check that EXTERNAL_DIR and EXTERNAL_DIR2 are empty
@@ -361,6 +383,7 @@ ALTER TABLE dbtest.t8c FORCE, ALGORITHM=COPY;
361383
DROP TABLE dbtest.t8a;
362384
DROP TABLE dbtest.t8b;
363385
DROP TABLE dbtest.t8c;
386+
DROP TABLE dbtest.t8d;
364387

365388
--echo # Clean up for other tests
366389
--remove_files_wildcard $EXTERNAL_DIR/dbtest/ *

share/messages_to_error_log.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12769,8 +12769,8 @@ ER_LOG_DEPRECATE_NON_COMPOSABLE_MULTIPLE_ENGINE
1276912769
ER_DD_UPDATE_DATADIR_FLAG_FAIL
1277012770
eng "Failed to update data directory flag for dd table with tablespace id '%llu' when ibd file for '%s' is moved to new location '%s' during server shutdown"
1277112771

12772-
ER_IB_MSG_FIL_STATE_MOVED_PREV_OR_HAS_DATADIR
12773-
eng "%s DD ID: %llu - Tablespace %u, name '%s', found at '%s' outside default data directory. It is either moved or is created with 'DATA DIRECTORY'"
12772+
ER_IB_MSG_FIL_STATE_MOVED_PREV
12773+
eng "%s DD ID: %llu - Tablespace %u, name '%s', found at '%s' outside default data directory, but DD misses info about DATA DIRECTORY"
1277412774

1277512775
ER_LOAD_BULK_JSON_ERROR
1277612776
eng "Bulk CSV parser reports JSON error: %s at %zu"

sql/dd/impl/types/table_impl.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,23 @@ Partition *Table_impl::get_partition(Object_id partition_id) {
785785
return nullptr;
786786
}
787787

788+
///////////////////////////////////////////////////////////////////////////
789+
Partition *Table_impl::get_leaf_partition(const std::string &part_name) {
790+
return const_cast<Partition *>(
791+
std::as_const(*this).get_leaf_partition(part_name));
792+
}
793+
794+
const Partition *Table_impl::get_leaf_partition(
795+
const std::string &part_name) const {
796+
for (Partition *leaf : m_leaf_partitions) {
797+
if (!my_strcasecmp(system_charset_info, leaf->name().c_str(),
798+
part_name.c_str())) {
799+
return leaf;
800+
}
801+
}
802+
return nullptr;
803+
}
804+
788805
///////////////////////////////////////////////////////////////////////////
789806
// Trigger collection.
790807
///////////////////////////////////////////////////////////////////////////

sql/dd/impl/types/table_impl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,11 @@ class Table_impl : public Abstract_table_impl, virtual public Table {
402402
return &m_leaf_partitions;
403403
}
404404

405+
Partition *get_leaf_partition(const std::string &part_name) override;
406+
407+
const Partition *get_leaf_partition(
408+
const std::string &part_name) const override;
409+
405410
// non-virtual
406411
void add_leaf_partition(Partition *p) { m_leaf_partitions.push_back(p); }
407412

sql/dd/types/table.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ class Table : virtual public Abstract_table {
290290

291291
virtual Partition_leaf_vector *leaf_partitions() = 0;
292292

293+
virtual Partition *get_leaf_partition(const std::string &part_name) = 0;
294+
295+
virtual const Partition *get_leaf_partition(
296+
const std::string &part_name) const = 0;
297+
293298
/////////////////////////////////////////////////////////////////////////
294299
// Trigger collection.
295300
/////////////////////////////////////////////////////////////////////////

storage/innobase/dict/dict0dd.cc

Lines changed: 43 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ Data dictionary interface */
3535
#include <sql_backup_lock.h>
3636
#include <sql_class.h>
3737
#include <sql_thd_internal_api.h>
38+
3839
#include "item.h"
3940
#else /* !UNIV_HOTBACKUP */
4041
#include <my_base.h>
4142
#endif /* !UNIV_HOTBACKUP */
4243

4344
#include <dd/properties.h>
45+
4446
#include "dict0crea.h"
4547
#include "dict0dd.h"
4648
#include "dict0dict.h"
@@ -1186,69 +1188,41 @@ dberr_t dd_update_table_and_partitions_after_dir_change(dd::Object_id object_id,
11861188
ut_o(return DB_ERROR);
11871189
}
11881190

1189-
ut_ad(dd_table != nullptr);
11901191
std::string dd_table_name{dd_table->table().name()};
11911192
Fil_path fpath{path};
11921193

1193-
std::string part_name = (!table_info.subpartition.empty())
1194-
? table_info.subpartition
1195-
: table_info.partition;
1196-
to_lower(part_name);
1197-
1198-
/* This function may be hit by those tables which are marked as
1199-
Fil_state::MOVED_PREV_OR_HAS_DATADIR which includes tables that are moved
1200-
before 8.0.38/8.4.1/9.0.0 and tables that are created using data directory
1201-
clause. We want to set the flag for tables moved before 8.0.38/8.4.1/9.0.0
1202-
only and ignore those tables which are created using data directory clause
1203-
as the dd_table data dir flag is already set for them. Additionally, we
1204-
explicitly remove the flag if moved from external to default data dir. We
1205-
do this because dd_table data dir flag should not exist if the ibd file is
1206-
located in default dir */
1207-
if (part_name.empty()) {
1208-
/* The table is non-partitioned table */
1209-
bool dd_flag = dd_table->se_private_data().exists(
1210-
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY]);
1211-
bool set_true = !(MySQL_datadir_path.is_same_as(fpath) ||
1212-
MySQL_datadir_path.is_ancestor(fpath)) &&
1213-
!dd_flag;
1214-
bool set_false = MySQL_datadir_path.is_same_as(fpath) ||
1215-
MySQL_datadir_path.is_ancestor(fpath);
1194+
bool set_true = !MySQL_datadir_path.is_ancestor(fpath);
1195+
if (!dd_table_is_partitioned(*dd_table)) {
1196+
/* Set the DATA DIRECTORY FLAG to true for dd table if ibd file is moved to
1197+
directory other than default data dir. Remove the flag if moved from
1198+
external to default data dir.*/
12161199
if (set_true) {
12171200
dd_table->se_private_data().set(
12181201
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY], set_true);
1219-
}
1220-
if (set_false) {
1202+
} else {
12211203
dd_table->se_private_data().remove(
12221204
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY]);
12231205
}
12241206
} else {
1225-
/* The table is partitioned table */
1226-
for (dd::Partition *part_obj : *dd_table->leaf_partitions()) {
1227-
std::string part_obj_name{part_obj->name()};
1228-
to_lower(part_obj_name);
1229-
if (part_obj_name == part_name) {
1230-
dd::Properties &part_options = part_obj->options();
1231-
bool dd_flag = part_obj->se_private_data().exists(
1232-
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY]);
1233-
bool set_true = !(MySQL_datadir_path.is_same_as(fpath) ||
1234-
MySQL_datadir_path.is_ancestor(fpath)) &&
1235-
!dd_flag;
1236-
bool set_false = MySQL_datadir_path.is_same_as(fpath) ||
1237-
MySQL_datadir_path.is_ancestor(fpath);
1238-
if (set_true) {
1239-
part_obj->se_private_data().set(
1240-
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY], set_true);
1241-
/* Update data_file_name for dd::partition as we do not set data
1242-
directory for whole partitioned table. We acquire dd::partition later
1243-
and read from it*/
1244-
part_options.set(data_file_name_key, table_info.directory.c_str());
1245-
}
1246-
if (set_false) {
1247-
part_obj->se_private_data().remove(
1248-
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY]);
1249-
part_options.remove(data_file_name_key);
1250-
}
1251-
}
1207+
dd::Partition *part_obj = dd_table->get_leaf_partition(
1208+
(!table_info.subpartition.empty()) ? table_info.subpartition
1209+
: table_info.partition);
1210+
if (!part_obj) {
1211+
ut_d(ut_error);
1212+
ut_o(return DB_ERROR);
1213+
}
1214+
dd::Properties &part_options = part_obj->options();
1215+
if (set_true) {
1216+
part_obj->se_private_data().set(
1217+
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY], true);
1218+
/* Update data_file_name for dd::partition as we do not set data
1219+
directory for whole partitioned table. We acquire dd::partition later
1220+
and read from it*/
1221+
part_options.set(data_file_name_key, table_info.directory.c_str());
1222+
} else {
1223+
part_obj->se_private_data().remove(
1224+
dd_table_key_strings[DD_TABLE_DATA_DIRECTORY]);
1225+
part_options.remove(data_file_name_key);
12521226
}
12531227
}
12541228

@@ -7545,16 +7519,27 @@ std::optional<table_name_components> parse_tablespace_path(std::string path) {
75457519
table_info.table_name = temp_table.substr(0, hash_pos);
75467520
file_to_table(table_info.table_name, false);
75477521

7522+
std::string part_seperator(PART_SEPARATOR);
7523+
std::string sub_part_seperator(SUB_PART_SEPARATOR);
7524+
75487525
// Check for partitions and subpartitions
75497526
bool has_partitions = temp_table.find(PART_SEPARATOR) != std::string::npos;
7527+
if (!has_partitions) {
7528+
has_partitions = temp_table.find(ALT_PART_SEPARATOR) != std::string::npos;
7529+
if (has_partitions) {
7530+
part_seperator = ALT_PART_SEPARATOR;
7531+
sub_part_seperator = ALT_SUB_PART_SEPARATOR;
7532+
}
7533+
}
7534+
75507535
bool has_subpartitions =
7551-
temp_table.find(SUB_PART_SEPARATOR) != std::string::npos;
7536+
temp_table.find(sub_part_seperator) != std::string::npos;
75527537

75537538
if (has_partitions) {
75547539
// Extract partition name
75557540
size_t part_start =
7556-
temp_table.find(PART_SEPARATOR) + std::string(PART_SEPARATOR).length();
7557-
size_t part_end = has_subpartitions ? temp_table.find(SUB_PART_SEPARATOR)
7541+
temp_table.find(part_seperator) + std::string(part_seperator).length();
7542+
size_t part_end = has_subpartitions ? temp_table.find(sub_part_seperator)
75587543
: temp_table.find('.');
75597544

75607545
ut_ad(part_end != std::string::npos);
@@ -7566,8 +7551,8 @@ std::optional<table_name_components> parse_tablespace_path(std::string path) {
75667551

75677552
if (has_subpartitions) {
75687553
// Extract subpartition name
7569-
size_t sub_part_start = temp_table.find(SUB_PART_SEPARATOR) +
7570-
std::string(SUB_PART_SEPARATOR).length();
7554+
size_t sub_part_start = temp_table.find(sub_part_seperator) +
7555+
std::string(sub_part_seperator).length();
75717556
size_t sub_part_end = temp_table.find('.');
75727557
ut_ad(sub_part_end != std::string::npos);
75737558
std::string temp_subpartition =

0 commit comments

Comments
 (0)