1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge 10.6 into 10.9

This commit is contained in:
Marko Mäkelä
2023-06-07 14:32:46 +03:00
19 changed files with 429 additions and 202 deletions

View File

@@ -86,7 +86,7 @@ sanity_checks() {
datadir=`mariadbd_get_param datadir` datadir=`mariadbd_get_param datadir`
# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024 # As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024
# 4096 blocks is then lower than 4 MB # 4096 blocks is then lower than 4 MB
df_available_blocks=`LC_ALL=C BLOCKSIZE= df --output=avail "$datadir" | tail -n 1` df_available_blocks="$(LC_ALL=C BLOCKSIZE='' df --output=avail "$datadir" | tail -n 1)"
if [ "$df_available_blocks" -lt "4096" ]; then if [ "$df_available_blocks" -lt "4096" ]; then
log_failure_msg "$0: ERROR: The partition with $datadir is too full!" log_failure_msg "$0: ERROR: The partition with $datadir is too full!"
echo "ERROR: The partition with $datadir is too full!" | $ERR_LOGGER echo "ERROR: The partition with $datadir is too full!" | $ERR_LOGGER

View File

@@ -223,14 +223,23 @@ then
mkdir -Z $mysql_datadir mkdir -Z $mysql_datadir
fi fi
# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024 # Check if MariaDB datadir is available if not fails.
# 4096 blocks is then lower than 4 MB # There should be symlink or directory available or something will fail.
df_available_blocks=`LC_ALL=C BLOCKSIZE= df --output=avail "$datadir" | tail -n 1` if [ -d "$mysql_datadir" ] || [ -L "$mysql_datadir" ]
if [ "$df_available_blocks" -lt "4096" ]
then then
echo "ERROR: There's not enough space in $mysql_datadir/" 1>&2 # As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024
db_stop # 4096 blocks is then lower than 4 MB
exit 1 df_available_blocks="$(LC_ALL=C BLOCKSIZE='' df --output=avail "$mysql_datadir" | tail -n 1)"
if [ "$df_available_blocks" -lt "4096" ]
then
echo "ERROR: There's not enough space in $mysql_datadir/" 1>&2
db_stop
exit 1
fi
else
echo "ERROR: There's no directory or symlink available: $mysql_datadir/" 1>&2
db_stop
exit 1
fi fi
# Since the home directory was created before putting the user into # Since the home directory was created before putting the user into

View File

@@ -26,4 +26,60 @@ UPDATE mysql.innodb_table_stats SET last_update=NULL WHERE table_name='t1';
XA END 'test'; XA END 'test';
XA ROLLBACK 'test'; XA ROLLBACK 'test';
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
#
#
# Testing a non-default format: Field_timestamp0 - UINT4 based
#
SET @@global.mysql56_temporal_format=0;
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
Field Type Null Key Default Extra
last_update timestamp /* mariadb-5.3 */ NO current_timestamp() on update current_timestamp()
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
Field Type Null Key Default Extra
last_update timestamp /* mariadb-5.3 */ NO current_timestamp() on update current_timestamp()
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
TIMESTAMPDIFF(DAY,last_update,now())<=1
1
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
TIMESTAMPDIFF(DAY,last_update,now())<=1
1
DROP TABLE t1;
#
# Now as the table t1 is dropped, expect no statistics
#
SELECT * FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes
SELECT * FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
#
# Testing with the default format: Field_timestampf - BINARY(4) based with the UNSIGNED_FLAG
#
SET @@global.mysql56_temporal_format=1;
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
Field Type Null Key Default Extra
last_update timestamp NO current_timestamp() on update current_timestamp()
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
Field Type Null Key Default Extra
last_update timestamp NO current_timestamp() on update current_timestamp()
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
TIMESTAMPDIFF(DAY,last_update,now())<=1
1
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
TIMESTAMPDIFF(DAY,last_update,now())<=1
1
DROP TABLE t1;
# End of 10.6 tests # End of 10.6 tests

View File

@@ -28,4 +28,57 @@ XA END 'test';
XA ROLLBACK 'test'; XA ROLLBACK 'test';
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-30483 After upgrade to 10.6 from Mysql 5.7 seeing "InnoDB: Column last_update in table mysql.innodb_table_stats is BINARY(4) NOT NULL but should be INT UNSIGNED NOT NULL"
--echo #
# The following tests demonstrate that these columns:
# - innodb_table_stats.last_update
# - innodb_index_stats.last_update
# have sane values close to NOW(), rather than any garbage,
# with all TIMESTAMP formats.
--echo #
--echo # Testing a non-default format: Field_timestamp0 - UINT4 based
--echo #
SET @@global.mysql56_temporal_format=0;
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
DROP TABLE t1;
--echo #
--echo # Now as the table t1 is dropped, expect no statistics
--echo #
SELECT * FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
SELECT * FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
--echo #
--echo # Testing with the default format: Field_timestampf - BINARY(4) based with the UNSIGNED_FLAG
--echo #
SET @@global.mysql56_temporal_format=1;
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
DROP TABLE t1;
--echo # End of 10.6 tests --echo # End of 10.6 tests

View File

@@ -0,0 +1,26 @@
CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
PARTITION BY LIST(f1) (
PARTITION p1 VALUES in (1, 2, 3),
PARTITION p2 VALUES in (4, 5, 6));
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
connect con1,localhost,root,,,;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connect con2,localhost,root,,,;
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
ALTER TABLE t1 ADD UNIQUE INDEX(f1);
connection default;
set DEBUG_SYNC="now WAIT_FOR default_resume";
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
DELETE FROM t1;
connection con2;
ERROR 23000: Duplicate entry '1' for key 'f1_2'
SET DEBUG_SYNC="now SIGNAL alter_finish";
connection default;
connection con1;
commit;
connection default;
disconnect con1;
disconnect con2;
InnoDB 0 transactions not purged
drop table t1;
SET DEBUG_SYNC=reset;

View File

@@ -0,0 +1 @@
--innodb_purge_threads=1

View File

@@ -0,0 +1,37 @@
--source include/have_innodb.inc
--source include/have_partition.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
CREATE TABLE t1(f1 INT, f2 INT, INDEX(f1))ENGINE=InnoDB
PARTITION BY LIST(f1) (
PARTITION p1 VALUES in (1, 2, 3),
PARTITION p2 VALUES in (4, 5, 6));
INSERT INTO t1 VALUES(1, 1), (1, 1), (6, 1);
connect(con1,localhost,root,,,);
START TRANSACTION WITH CONSISTENT SNAPSHOT;
connect(con2,localhost,root,,,);
SET DEBUG_SYNC="innodb_rollback_inplace_alter_table SIGNAL default_resume WAIT_FOR alter_resume";
send ALTER TABLE t1 ADD UNIQUE INDEX(f1);
connection default;
set DEBUG_SYNC="now WAIT_FOR default_resume";
SET DEBUG_SYNC="innodb_row_update_for_mysql_begin SIGNAL alter_resume WAIT_FOR alter_finish";
send DELETE FROM t1;
connection con2;
--error ER_DUP_ENTRY
reap;
SET DEBUG_SYNC="now SIGNAL alter_finish";
connection default;
reap;
connection con1;
commit;
connection default;
disconnect con1;
disconnect con2;
--source ../../innodb/include/wait_all_purged.inc
drop table t1;
SET DEBUG_SYNC=reset;

View File

@@ -13,7 +13,7 @@ innodb_table_stats CREATE TABLE `innodb_table_stats` (
`sum_of_other_index_sizes` bigint(20) unsigned NOT NULL, `sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`database_name`,`table_name`) PRIMARY KEY (`database_name`,`table_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP; ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_table_stats; SHOW CREATE TABLE mysql.innodb_table_stats;
Table Create Table Table Create Table
innodb_table_stats CREATE TABLE `innodb_table_stats` ( innodb_table_stats CREATE TABLE `innodb_table_stats` (
@@ -25,7 +25,7 @@ innodb_table_stats CREATE TABLE `innodb_table_stats` (
`sum_of_other_index_sizes` bigint(20) unsigned NOT NULL, `sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`database_name`,`table_name`) PRIMARY KEY (`database_name`,`table_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP; ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_index_stats; SHOW CREATE TABLE mysql.innodb_index_stats;
Table Create Table Table Create Table
innodb_index_stats CREATE TABLE `innodb_index_stats` ( innodb_index_stats CREATE TABLE `innodb_index_stats` (
@@ -44,7 +44,7 @@ CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (10);
DROP TABLE t1; DROP TABLE t1;
SET @@global.innodb_stats_persistent=0; SET @@global.innodb_stats_persistent=0;
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP; ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_table_stats; SHOW CREATE TABLE mysql.innodb_table_stats;
Table Create Table Table Create Table
innodb_table_stats CREATE TABLE `innodb_table_stats` ( innodb_table_stats CREATE TABLE `innodb_table_stats` (
@@ -56,7 +56,7 @@ innodb_table_stats CREATE TABLE `innodb_table_stats` (
`sum_of_other_index_sizes` bigint(20) unsigned NOT NULL, `sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`database_name`,`table_name`) PRIMARY KEY (`database_name`,`table_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP; ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_index_stats; SHOW CREATE TABLE mysql.innodb_index_stats;
Table Create Table Table Create Table
innodb_index_stats CREATE TABLE `innodb_index_stats` ( innodb_index_stats CREATE TABLE `innodb_index_stats` (
@@ -71,3 +71,38 @@ innodb_index_stats CREATE TABLE `innodb_index_stats` (
PRIMARY KEY (`database_name`,`table_name`,`index_name`,`stat_name`) PRIMARY KEY (`database_name`,`table_name`,`index_name`,`stat_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
SET @@global.innodb_stats_persistent=1; SET @@global.innodb_stats_persistent=1;
#
# Testing MySQL-5.6-alike Field_timestampf: BINARY(4) based, without UNSIGNED_FLAG
#
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
Field Type Null Key Default Extra
last_update type_mysql_timestamp NO current_timestamp() on update current_timestamp()
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
Field Type Null Key Default Extra
last_update type_mysql_timestamp NO current_timestamp() on update current_timestamp()
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
TIMESTAMPDIFF(DAY,last_update,now())<=1
1
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
TIMESTAMPDIFF(DAY,last_update,now())<=1
1
DROP TABLE t1;
#
# Now as the table t1 is dropped, expect no statistics
#
SELECT * FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
database_name table_name last_update n_rows clustered_index_size sum_of_other_index_sizes
SELECT * FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
#
# Restore the structure of the tables
#
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();

View File

@@ -6,9 +6,9 @@
SET @@global.innodb_stats_persistent=0; SET @@global.innodb_stats_persistent=0;
SHOW CREATE TABLE mysql.innodb_table_stats; SHOW CREATE TABLE mysql.innodb_table_stats;
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP; ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_table_stats; SHOW CREATE TABLE mysql.innodb_table_stats;
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP; ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_index_stats; SHOW CREATE TABLE mysql.innodb_index_stats;
SET @@global.innodb_stats_persistent=1; SET @@global.innodb_stats_persistent=1;
@@ -17,8 +17,46 @@ INSERT INTO t1 VALUES (10);
DROP TABLE t1; DROP TABLE t1;
SET @@global.innodb_stats_persistent=0; SET @@global.innodb_stats_persistent=0;
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP; ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_table_stats; SHOW CREATE TABLE mysql.innodb_table_stats;
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP; ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW CREATE TABLE mysql.innodb_index_stats; SHOW CREATE TABLE mysql.innodb_index_stats;
SET @@global.innodb_stats_persistent=1; SET @@global.innodb_stats_persistent=1;
# The following test demonstrate that these columns:
# - innodb_table_stats.last_update
# - innodb_index_stats.last_update
# have sane values close to NOW(), rather than any garbage,
# with MySQL-alike Field_timestampf
--echo #
--echo # Testing MySQL-5.6-alike Field_timestampf: BINARY(4) based, without UNSIGNED_FLAG
--echo #
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TYPE_MYSQL_TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
SHOW COLUMNS FROM mysql.innodb_table_stats LIKE 'last_update';
SHOW COLUMNS FROM mysql.innodb_index_stats LIKE 'last_update';
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB STATS_PERSISTENT=1;
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
SELECT TIMESTAMPDIFF(DAY,last_update,now())<=1 FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
DROP TABLE t1;
--echo #
--echo # Now as the table t1 is dropped, expect no statistics
--echo #
SELECT * FROM mysql.innodb_table_stats
WHERE database_name='test' AND table_name='t1';
SELECT * FROM mysql.innodb_index_stats
WHERE database_name='test' AND table_name='t1' AND stat_name='size';
--echo #
--echo # Restore the structure of the tables
--echo #
ALTER TABLE mysql.innodb_table_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();
ALTER TABLE mysql.innodb_index_stats MODIFY last_update TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp();

View File

@@ -2140,6 +2140,8 @@ void buf_page_free(fil_space_t *space, uint32_t page, mtr_t *mtr)
} }
block->page.lock.x_lock(); block->page.lock.x_lock();
if (block->page.is_ibuf_exist())
ibuf_merge_or_delete_for_page(nullptr, page_id, block->page.zip_size());
#ifdef BTR_CUR_HASH_ADAPT #ifdef BTR_CUR_HASH_ADAPT
if (block->index) if (block->index)
btr_search_drop_page_hash_index(block, false); btr_search_drop_page_hash_index(block, false);

View File

@@ -2438,6 +2438,7 @@ static void buf_flush_page_cleaner()
else if (buf_pool.ran_out()) else if (buf_pool.ran_out())
{ {
buf_pool.page_cleaner_set_idle(false); buf_pool.page_cleaner_set_idle(false);
buf_pool.get_oldest_modification(0);
mysql_mutex_unlock(&buf_pool.flush_list_mutex); mysql_mutex_unlock(&buf_pool.flush_list_mutex);
n= srv_max_io_capacity; n= srv_max_io_capacity;
mysql_mutex_lock(&buf_pool.mutex); mysql_mutex_lock(&buf_pool.mutex);

View File

@@ -1955,8 +1955,8 @@ err_exit:
FIL_TYPE_TABLESPACE, FIL_TYPE_TABLESPACE,
crypt_data, mode, true)) { crypt_data, mode, true)) {
fil_node_t* node = space->add(path, file, size, false, true); fil_node_t* node = space->add(path, file, size, false, true);
mysql_mutex_unlock(&fil_system.mutex);
IF_WIN(node->find_metadata(), node->find_metadata(file, true)); IF_WIN(node->find_metadata(), node->find_metadata(file, true));
mysql_mutex_unlock(&fil_system.mutex);
mtr.start(); mtr.start();
mtr.set_named_space(space); mtr.set_named_space(space);
ut_a(fsp_header_init(space, size, &mtr) == DB_SUCCESS); ut_a(fsp_header_init(space, size, &mtr) == DB_SUCCESS);

View File

@@ -2364,6 +2364,7 @@ tablespace_deleted:
} }
const ulint zip_size = s->zip_size(), size = s->size; const ulint zip_size = s->zip_size(), size = s->size;
s->x_lock();
s->release(); s->release();
mtr_t mtr; mtr_t mtr;
@@ -2381,13 +2382,17 @@ tablespace_deleted:
|| !page_is_leaf(block->page.frame); || !page_is_leaf(block->page.frame);
mtr.commit(); mtr.commit();
if (err == DB_TABLESPACE_DELETED) { if (err == DB_TABLESPACE_DELETED) {
s->x_unlock();
goto tablespace_deleted; goto tablespace_deleted;
} }
if (!remove) { if (!remove) {
s->x_unlock();
continue; continue;
} }
} }
s->x_unlock();
if (srv_shutdown_state == SRV_SHUTDOWN_NONE if (srv_shutdown_state == SRV_SHUTDOWN_NONE
|| srv_fast_shutdown) { || srv_fast_shutdown) {
continue; continue;
@@ -2416,7 +2421,7 @@ tablespace_deleted:
/* Prevent an infinite loop, by removing entries from /* Prevent an infinite loop, by removing entries from
the change buffer in the case the bitmap bits were the change buffer in the case the bitmap bits were
wrongly clear even though buffered changes exist. */ wrongly clear even though buffered changes exist. */
ibuf_delete_recs(page_id_t(space_ids[i], page_nos[i])); ibuf_delete_recs(page_id_t(space_id, page_nos[i]));
} }
} }
@@ -4194,25 +4199,26 @@ dberr_t ibuf_merge_or_delete_for_page(buf_block_t *block,
ibuf_mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
if (bitmap_bits if (!bitmap_bits) {
&& DB_SUCCESS done:
/* No changes are buffered for this page. */
space->release();
return DB_SUCCESS;
}
if (!block
|| DB_SUCCESS
== fseg_page_is_allocated(space, page_id.page_no())) { == fseg_page_is_allocated(space, page_id.page_no())) {
ibuf_mtr_start(&mtr); ibuf_mtr_start(&mtr);
mtr.set_named_space(space); mtr.set_named_space(space);
ibuf_reset_bitmap(block, page_id, zip_size, &mtr); ibuf_reset_bitmap(block, page_id, zip_size, &mtr);
ibuf_mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
bitmap_bits = 0;
if (!block if (!block
|| btr_page_get_index_id(block->page.frame) || btr_page_get_index_id(block->page.frame)
!= DICT_IBUF_ID_MIN + IBUF_SPACE_ID) { != DICT_IBUF_ID_MIN + IBUF_SPACE_ID) {
ibuf_delete_recs(page_id); ibuf_delete_recs(page_id);
} }
} goto done;
if (!bitmap_bits) {
/* No changes are buffered for this page. */
space->release();
return DB_SUCCESS;
} }
} }

View File

@@ -216,14 +216,6 @@ buf_block_t*
trx_undo_assign_low(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo, trx_undo_assign_low(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo,
mtr_t *mtr, dberr_t *err) mtr_t *mtr, dberr_t *err)
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Sets the state of the undo log segment at a transaction finish.
@return undo log segment header page, x-latched */
buf_block_t*
trx_undo_set_state_at_finish(
/*=========================*/
trx_undo_t* undo, /*!< in: undo log memory copy */
mtr_t* mtr); /*!< in: mtr */
/** Set the state of the undo log segment at a XA PREPARE or XA ROLLBACK. /** Set the state of the undo log segment at a XA PREPARE or XA ROLLBACK.
@param[in,out] trx transaction @param[in,out] trx transaction

View File

@@ -2491,7 +2491,7 @@ inline
recv_sys_t::parse_mtr_result recv_sys_t::parse(source &l, bool if_exists) recv_sys_t::parse_mtr_result recv_sys_t::parse(source &l, bool if_exists)
noexcept noexcept
{ {
restart: restart:
#ifndef SUX_LOCK_GENERIC #ifndef SUX_LOCK_GENERIC
ut_ad(log_sys.latch.is_write_locked() || ut_ad(log_sys.latch.is_write_locked() ||
srv_operation == SRV_OPERATION_BACKUP || srv_operation == SRV_OPERATION_BACKUP ||
@@ -3279,9 +3279,6 @@ set_start_lsn:
|| recv_sys.is_corrupt_log()) && !srv_force_recovery) { || recv_sys.is_corrupt_log()) && !srv_force_recovery) {
if (init) { if (init) {
init->created = false; init->created = false;
if (space || block->page.id().page_no()) {
block->page.lock.x_lock_recursive();
}
} }
mtr.discard_modifications(); mtr.discard_modifications();
@@ -3847,10 +3844,12 @@ void recv_sys_t::apply(bool last_batch)
if (fil_space_t *space = fil_space_get(id + srv_undo_space_id_start)) if (fil_space_t *space = fil_space_get(id + srv_undo_space_id_start))
{ {
ut_ad(UT_LIST_GET_LEN(space->chain) == 1); ut_ad(UT_LIST_GET_LEN(space->chain) == 1);
ut_ad(space->recv_size >= t.pages);
fil_node_t *file= UT_LIST_GET_FIRST(space->chain); fil_node_t *file= UT_LIST_GET_FIRST(space->chain);
ut_ad(file->is_open()); ut_ad(file->is_open());
os_file_truncate(file->name, file->handle, os_file_truncate(file->name, file->handle,
os_offset_t{t.pages} << srv_page_size_shift, true); os_offset_t{space->recv_size} <<
srv_page_size_shift, true);
} }
} }
} }

View File

@@ -214,14 +214,14 @@ row_ins_sec_index_entry_by_modify(
made to the clustered index, and completed the made to the clustered index, and completed the
secondary index creation before we got here. In this secondary index creation before we got here. In this
case, the change would already be there. The CREATE case, the change would already be there. The CREATE
INDEX should be waiting for a MySQL meta-data lock INDEX should be in wait_while_table_is_used() at least
upgrade at least until this INSERT or UPDATE until this INSERT or UPDATE returns. After that point,
returns. After that point, set_committed(true) set_committed(true) would be invoked in
would be invoked in commit_inplace_alter_table(). */ commit_inplace_alter_table(). */
ut_a(update->n_fields == 0); ut_a(update->n_fields == 0);
ut_a(!cursor->index()->is_committed());
ut_ad(!dict_index_is_online_ddl(cursor->index())); ut_ad(!dict_index_is_online_ddl(cursor->index()));
return(DB_SUCCESS); return cursor->index()->is_committed()
? DB_CORRUPTION : DB_SUCCESS;
} }
if (mode == BTR_MODIFY_LEAF) { if (mode == BTR_MODIFY_LEAF) {

View File

@@ -615,6 +615,8 @@ row_purge_del_mark(
const auto type= node->index->type; const auto type= node->index->type;
if (type & (DICT_FTS | DICT_CORRUPT)) if (type & (DICT_FTS | DICT_CORRUPT))
continue; continue;
if (node->index->online_status > ONLINE_INDEX_CREATION)
continue;
if (UNIV_UNLIKELY(DICT_VIRTUAL & type) && !node->index->is_committed() && if (UNIV_UNLIKELY(DICT_VIRTUAL & type) && !node->index->is_committed() &&
node->index->has_new_v_col()) node->index->has_new_v_col())
continue; continue;
@@ -767,6 +769,11 @@ row_purge_upd_exist_or_extern_func(
continue; continue;
} }
if (node->index->online_status
> ONLINE_INDEX_CREATION) {
continue;
}
if (row_upd_changes_ord_field_binary(node->index, node->update, if (row_upd_changes_ord_field_binary(node->index, node->update,
thr, NULL, NULL)) { thr, NULL, NULL)) {
/* Build the older version of the index entry */ /* Build the older version of the index entry */

View File

@@ -246,127 +246,121 @@ Remove the undo log segment from the rseg slot if it is too big for reuse.
void void
trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr) trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
{ {
DBUG_PRINT("trx", ("commit(" TRX_ID_FMT "," TRX_ID_FMT ")", DBUG_PRINT("trx", ("commit(" TRX_ID_FMT "," TRX_ID_FMT ")",
trx->id, trx_id_t{trx->rw_trx_hash_element->no})); trx->id, trx_id_t{trx->rw_trx_hash_element->no}));
ut_ad(undo == trx->rsegs.m_redo.undo); ut_ad(undo->id < TRX_RSEG_N_SLOTS);
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg; ut_ad(undo == trx->rsegs.m_redo.undo);
ut_ad(undo->rseg == rseg); trx_rseg_t *rseg= trx->rsegs.m_redo.rseg;
buf_block_t* rseg_header = rseg->get(mtr, nullptr); ut_ad(undo->rseg == rseg);
/* We are in transaction commit; we cannot return an error. If the buf_block_t *rseg_header= rseg->get(mtr, nullptr);
database is corrupted, it is better to crash it than to /* We are in transaction commit; we cannot return an error. If the
intentionally violate ACID by committing something that is known to database is corrupted, it is better to crash it than to
be corrupted. */ intentionally violate ACID by committing something that is known to
ut_ad(rseg_header); be corrupted. */
buf_block_t* undo_page = trx_undo_set_state_at_finish( ut_ad(rseg_header);
undo, mtr); buf_block_t *undo_page=
trx_ulogf_t* undo_header = undo_page->page.frame buf_page_get(page_id_t(rseg->space->id, undo->hdr_page_no), 0,
+ undo->hdr_offset; RW_X_LATCH, mtr);
/* This function is invoked during transaction commit, which is not
allowed to fail. If we get a corrupted undo header, we will crash here. */
ut_a(undo_page);
trx_ulogf_t *undo_header= undo_page->page.frame + undo->hdr_offset;
ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1); ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1);
ut_ad(rseg->needs_purge > trx->id); ut_ad(rseg->needs_purge > trx->id);
if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT if (rseg->last_page_no == FIL_NULL)
+ rseg_header->page.frame))) { {
/* This database must have been upgraded from rseg->last_page_no= undo->hdr_page_no;
before MariaDB 10.3.5. */ rseg->set_last_commit(undo->hdr_offset, trx->rw_trx_hash_element->no);
trx_rseg_format_upgrade(rseg_header, mtr); }
}
if (undo->state != TRX_UNDO_CACHED) { rseg->history_size++;
/* The undo log segment will not be reused */
ut_a(undo->id < TRX_RSEG_N_SLOTS);
static_assert(FIL_NULL == 0xffffffff, "");
mtr->memset(rseg_header,
TRX_RSEG + TRX_RSEG_UNDO_SLOTS
+ undo->id * TRX_RSEG_SLOT_SIZE, 4, 0xff);
uint32_t hist_size = mach_read_from_4( if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT +
TRX_RSEG_HISTORY_SIZE + TRX_RSEG rseg_header->page.frame)))
+ rseg_header->page.frame); /* This database must have been upgraded from before MariaDB 10.3.5. */
trx_rseg_format_upgrade(rseg_header, mtr);
ut_ad(undo->size == flst_get_len(TRX_UNDO_SEG_HDR uint16_t undo_state;
+ TRX_UNDO_PAGE_LIST
+ undo_page->page.frame));
mtr->write<4>(*rseg_header, TRX_RSEG + TRX_RSEG_HISTORY_SIZE if (undo->size == 1 &&
+ rseg_header->page.frame, TRX_UNDO_PAGE_REUSE_LIMIT >
hist_size + undo->size); mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE +
mtr->write<8>(*rseg_header, TRX_RSEG + TRX_RSEG_MAX_TRX_ID undo_page->page.frame))
+ rseg_header->page.frame, {
trx_sys.get_max_trx_id()); undo->state= undo_state= TRX_UNDO_CACHED;
} UT_LIST_ADD_FIRST(rseg->undo_cached, undo);
}
else
{
ut_ad(undo->size == flst_get_len(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST +
undo_page->page.frame));
/* The undo log segment will not be reused */
static_assert(FIL_NULL == 0xffffffff, "");
mtr->memset(rseg_header, TRX_RSEG + TRX_RSEG_UNDO_SLOTS +
undo->id * TRX_RSEG_SLOT_SIZE, 4, 0xff);
uint32_t hist_size= mach_read_from_4(TRX_RSEG_HISTORY_SIZE + TRX_RSEG +
rseg_header->page.frame);
mtr->write<4>(*rseg_header, TRX_RSEG + TRX_RSEG_HISTORY_SIZE +
rseg_header->page.frame, hist_size + undo->size);
mtr->write<8>(*rseg_header, TRX_RSEG + TRX_RSEG_MAX_TRX_ID +
rseg_header->page.frame, trx_sys.get_max_trx_id());
ut_free(undo);
undo_state= TRX_UNDO_TO_PURGE;
}
/* After the purge thread has been given permission to exit, undo= nullptr;
we may roll back transactions (trx->undo_no==0)
in THD::cleanup() invoked from unlink_thd() in fast shutdown,
or in trx_rollback_recovered() in slow shutdown.
Before any transaction-generating background threads or the /* After the purge thread has been given permission to exit,
purge have been started, we can we may roll back transactions (trx->undo_no==0)
start transactions in row_merge_drop_temp_indexes(), in THD::cleanup() invoked from unlink_thd() in fast shutdown,
and roll back recovered transactions. or in trx_rollback_recovered() in slow shutdown.
Arbitrary user transactions may be executed when all the undo log Before any transaction-generating background threads or the purge
related background processes (including purge) are disabled due to have been started, we can start transactions in
innodb_force_recovery=2 or innodb_force_recovery=3. row_merge_drop_temp_indexes(), and roll back recovered transactions.
DROP TABLE may be executed at any innodb_force_recovery level.
During fast shutdown, we may also continue to execute Arbitrary user transactions may be executed when all the undo log
user transactions. */ related background processes (including purge) are disabled due to
ut_ad(srv_undo_sources innodb_force_recovery=2 or innodb_force_recovery=3. DROP TABLE may
|| trx->undo_no == 0 be executed at any innodb_force_recovery level.
|| (!purge_sys.enabled()
&& (srv_is_being_started
|| trx_rollback_is_active
|| srv_force_recovery >= SRV_FORCE_NO_BACKGROUND))
|| srv_fast_shutdown);
#ifdef WITH_WSREP During fast shutdown, we may also continue to execute user
if (wsrep_is_wsrep_xid(&trx->xid)) { transactions. */
trx_rseg_update_wsrep_checkpoint(rseg_header, &trx->xid, mtr); ut_ad(srv_undo_sources || trx->undo_no == 0 ||
} (!purge_sys.enabled() &&
(srv_is_being_started ||
trx_rollback_is_active ||
srv_force_recovery >= SRV_FORCE_NO_BACKGROUND)) ||
srv_fast_shutdown);
#ifdef WITH_WSREP
if (wsrep_is_wsrep_xid(&trx->xid))
trx_rseg_update_wsrep_checkpoint(rseg_header, &trx->xid, mtr);
#endif #endif
if (trx->mysql_log_file_name && *trx->mysql_log_file_name) { if (trx->mysql_log_file_name && *trx->mysql_log_file_name)
/* Update the latest MySQL binlog name and offset info /* Update the latest binlog name and offset if log_bin=ON or this
in rollback segment header if MySQL binlogging is on is a replica. */
or the database server is a MySQL replication save. */ trx_rseg_update_binlog_offset(rseg_header, trx, mtr);
trx_rseg_update_binlog_offset(rseg_header, trx, mtr);
}
/* Add the log as the first in the history list */ /* Add the log as the first in the history list */
/* We are in transaction commit; we cannot return an error /* We are in transaction commit; we cannot return an error
when detecting corruption. It is better to crash the server when detecting corruption. It is better to crash the server
than to intentionally violate ACID by committing something than to intentionally violate ACID by committing something
that is known to be corrupted. */ that is known to be corrupted. */
ut_a(flst_add_first(rseg_header, TRX_RSEG + TRX_RSEG_HISTORY, undo_page, ut_a(flst_add_first(rseg_header, TRX_RSEG + TRX_RSEG_HISTORY, undo_page,
static_cast<uint16_t>(undo->hdr_offset uint16_t(page_offset(undo_header) +
+ TRX_UNDO_HISTORY_NODE), TRX_UNDO_HISTORY_NODE), mtr) == DB_SUCCESS);
mtr) == DB_SUCCESS);
mtr->write<8,mtr_t::MAYBE_NOP>(*undo_page, mtr->write<2>(*undo_page, TRX_UNDO_SEG_HDR + TRX_UNDO_STATE +
undo_header + TRX_UNDO_TRX_NO, undo_page->page.frame, undo_state);
trx->rw_trx_hash_element->no); mtr->write<8,mtr_t::MAYBE_NOP>(*undo_page, undo_header + TRX_UNDO_TRX_NO,
mtr->write<2,mtr_t::MAYBE_NOP>(*undo_page, undo_header trx->rw_trx_hash_element->no);
+ TRX_UNDO_NEEDS_PURGE, 1U); mtr->write<2,mtr_t::MAYBE_NOP>(*undo_page, undo_header +
TRX_UNDO_NEEDS_PURGE, 1U);
if (rseg->last_page_no == FIL_NULL) {
rseg->last_page_no = undo->hdr_page_no;
rseg->set_last_commit(undo->hdr_offset,
trx->rw_trx_hash_element->no);
}
rseg->history_size++;
if (undo->state == TRX_UNDO_CACHED) {
UT_LIST_ADD_FIRST(rseg->undo_cached, undo);
} else {
ut_ad(undo->state == TRX_UNDO_TO_PURGE);
ut_free(undo);
}
undo = NULL;
} }
/** Free an undo log segment. /** Free an undo log segment.
@@ -685,6 +679,7 @@ not_free:
mtr_t mtr; mtr_t mtr;
mtr.start(); mtr.start();
mtr.x_lock_space(&space); mtr.x_lock_space(&space);
const auto space_id= space.id;
/* Lock all modified pages of the tablespace. /* Lock all modified pages of the tablespace.
@@ -694,8 +689,8 @@ not_free:
mini-transaction commit and the server was killed, then mini-transaction commit and the server was killed, then
discarding the to-be-trimmed pages without flushing would discarding the to-be-trimmed pages without flushing would
break crash recovery. */ break crash recovery. */
rescan:
mysql_mutex_lock(&buf_pool.flush_list_mutex); mysql_mutex_lock(&buf_pool.flush_list_mutex);
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list); bpage; ) for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list); bpage; )
{ {
ut_ad(bpage->oldest_modification()); ut_ad(bpage->oldest_modification());
@@ -703,46 +698,47 @@ not_free:
buf_page_t *prev= UT_LIST_GET_PREV(list, bpage); buf_page_t *prev= UT_LIST_GET_PREV(list, bpage);
if (bpage->id().space() == space.id && if (bpage->oldest_modification() > 2 && bpage->id().space() == space_id)
bpage->oldest_modification() != 1)
{ {
ut_ad(bpage->frame); ut_ad(bpage->frame);
auto block= reinterpret_cast<buf_block_t*>(bpage); bpage->fix();
if (!bpage->lock.x_lock_try())
{ {
rescan: /* Try to acquire an exclusive latch while the cache line is
/* Let buf_pool_t::release_freed_page() proceed. */ fresh after fix(). */
const bool got_lock{bpage->lock.x_lock_try()};
buf_pool.flush_hp.set(prev);
mysql_mutex_unlock(&buf_pool.flush_list_mutex); mysql_mutex_unlock(&buf_pool.flush_list_mutex);
mysql_mutex_lock(&buf_pool.mutex); if (!got_lock)
mysql_mutex_lock(&buf_pool.flush_list_mutex); bpage->lock.x_lock();
mysql_mutex_unlock(&buf_pool.mutex);
bpage= UT_LIST_GET_LAST(buf_pool.flush_list);
continue;
} }
buf_pool.flush_hp.set(prev);
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
#ifdef BTR_CUR_HASH_ADAPT #ifdef BTR_CUR_HASH_ADAPT
ut_ad(!block->index); /* There is no AHI on undo tablespaces. */ /* There is no AHI on undo tablespaces. */
ut_ad(!reinterpret_cast<buf_block_t*>(bpage)->index);
#endif #endif
bpage->fix();
ut_ad(!bpage->is_io_fixed()); ut_ad(!bpage->is_io_fixed());
mysql_mutex_lock(&buf_pool.flush_list_mutex); ut_ad(bpage->id().space() == space_id);
if (bpage->oldest_modification() > 1) if (bpage->oldest_modification() > 2)
{ {
mtr.memo_push(reinterpret_cast<buf_block_t*>(bpage),
MTR_MEMO_PAGE_X_FIX);
mysql_mutex_lock(&buf_pool.flush_list_mutex);
ut_ad(bpage->oldest_modification() > 2);
bpage->reset_oldest_modification(); bpage->reset_oldest_modification();
mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX);
} }
else else
{ {
bpage->unfix(); bpage->unfix();
bpage->lock.x_unlock(); bpage->lock.x_unlock();
mysql_mutex_lock(&buf_pool.flush_list_mutex);
} }
if (prev != buf_pool.flush_hp.get()) if (prev != buf_pool.flush_hp.get())
/* Rescan, because we may have lost the position. */ {
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
goto rescan; goto rescan;
}
} }
bpage= prev; bpage= prev;

View File

@@ -1463,37 +1463,6 @@ template buf_block_t*
trx_undo_assign_low<true>(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo, trx_undo_assign_low<true>(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo,
mtr_t *mtr, dberr_t *err); mtr_t *mtr, dberr_t *err);
/******************************************************************//**
Sets the state of the undo log segment at a transaction finish.
@return undo log segment header page, x-latched */
buf_block_t*
trx_undo_set_state_at_finish(
/*=========================*/
trx_undo_t* undo, /*!< in: undo log memory copy */
mtr_t* mtr) /*!< in: mtr */
{
ut_ad(undo->id < TRX_RSEG_N_SLOTS);
ut_ad(undo->rseg->is_persistent());
buf_block_t *block=
buf_page_get(page_id_t(undo->rseg->space->id, undo->hdr_page_no), 0,
RW_X_LATCH, mtr);
/* This function is invoked during transaction commit, which is not
allowed to fail. If we get a corrupted undo header, we will crash here. */
ut_a(block);
const uint16_t state = undo->size == 1 &&
TRX_UNDO_PAGE_REUSE_LIMIT >
mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE +
block->page.frame)
? TRX_UNDO_CACHED
: TRX_UNDO_TO_PURGE;
undo->state= state;
mtr->write<2>(*block, TRX_UNDO_SEG_HDR + TRX_UNDO_STATE + block->page.frame,
state);
return block;
}
/** Set the state of the undo log segment at a XA PREPARE or XA ROLLBACK. /** Set the state of the undo log segment at a XA PREPARE or XA ROLLBACK.
@param[in,out] trx transaction @param[in,out] trx transaction
@param[in,out] undo undo log @param[in,out] undo undo log