mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Merge 10.6 into 10.9
This commit is contained in:
commit
878a86f276
19 changed files with 429 additions and 202 deletions
2
debian/mariadb-server.mariadb.init
vendored
2
debian/mariadb-server.mariadb.init
vendored
|
@ -86,7 +86,7 @@ sanity_checks() {
|
|||
datadir=`mariadbd_get_param datadir`
|
||||
# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024
|
||||
# 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
|
||||
log_failure_msg "$0: ERROR: The partition with $datadir is too full!"
|
||||
echo "ERROR: The partition with $datadir is too full!" | $ERR_LOGGER
|
||||
|
|
23
debian/mariadb-server.preinst
vendored
23
debian/mariadb-server.preinst
vendored
|
@ -223,14 +223,23 @@ then
|
|||
mkdir -Z $mysql_datadir
|
||||
fi
|
||||
|
||||
# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024
|
||||
# 4096 blocks is then lower than 4 MB
|
||||
df_available_blocks=`LC_ALL=C BLOCKSIZE= df --output=avail "$datadir" | tail -n 1`
|
||||
if [ "$df_available_blocks" -lt "4096" ]
|
||||
# Check if MariaDB datadir is available if not fails.
|
||||
# There should be symlink or directory available or something will fail.
|
||||
if [ -d "$mysql_datadir" ] || [ -L "$mysql_datadir" ]
|
||||
then
|
||||
echo "ERROR: There's not enough space in $mysql_datadir/" 1>&2
|
||||
db_stop
|
||||
exit 1
|
||||
# As preset blocksize of GNU df is 1024 then available bytes is $df_available_blocks * 1024
|
||||
# 4096 blocks is then lower than 4 MB
|
||||
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
|
||||
|
||||
# Since the home directory was created before putting the user into
|
||||
|
|
|
@ -26,4 +26,60 @@ UPDATE mysql.innodb_table_stats SET last_update=NULL WHERE table_name='t1';
|
|||
XA END 'test';
|
||||
XA ROLLBACK 'test';
|
||||
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
|
||||
|
|
|
@ -28,4 +28,57 @@ XA END 'test';
|
|||
XA ROLLBACK 'test';
|
||||
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
|
||||
|
|
26
mysql-test/suite/parts/r/partition_purge.result
Normal file
26
mysql-test/suite/parts/r/partition_purge.result
Normal 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;
|
1
mysql-test/suite/parts/t/partition_purge.opt
Normal file
1
mysql-test/suite/parts/t/partition_purge.opt
Normal file
|
@ -0,0 +1 @@
|
|||
--innodb_purge_threads=1
|
37
mysql-test/suite/parts/t/partition_purge.test
Normal file
37
mysql-test/suite/parts/t/partition_purge.test
Normal 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;
|
|
@ -13,7 +13,7 @@ innodb_table_stats CREATE TABLE `innodb_table_stats` (
|
|||
`sum_of_other_index_sizes` bigint(20) unsigned NOT NULL,
|
||||
PRIMARY KEY (`database_name`,`table_name`)
|
||||
) 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;
|
||||
Table Create Table
|
||||
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,
|
||||
PRIMARY KEY (`database_name`,`table_name`)
|
||||
) 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;
|
||||
Table Create Table
|
||||
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);
|
||||
DROP TABLE t1;
|
||||
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;
|
||||
Table Create Table
|
||||
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,
|
||||
PRIMARY KEY (`database_name`,`table_name`)
|
||||
) 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;
|
||||
Table Create Table
|
||||
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`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0
|
||||
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();
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
SET @@global.innodb_stats_persistent=0;
|
||||
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;
|
||||
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;
|
||||
SET @@global.innodb_stats_persistent=1;
|
||||
|
||||
|
@ -17,8 +17,46 @@ INSERT INTO t1 VALUES (10);
|
|||
DROP TABLE t1;
|
||||
|
||||
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;
|
||||
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;
|
||||
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();
|
||||
|
|
|
@ -2140,6 +2140,8 @@ void buf_page_free(fil_space_t *space, uint32_t page, mtr_t *mtr)
|
|||
}
|
||||
|
||||
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
|
||||
if (block->index)
|
||||
btr_search_drop_page_hash_index(block, false);
|
||||
|
|
|
@ -2438,6 +2438,7 @@ static void buf_flush_page_cleaner()
|
|||
else if (buf_pool.ran_out())
|
||||
{
|
||||
buf_pool.page_cleaner_set_idle(false);
|
||||
buf_pool.get_oldest_modification(0);
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
n= srv_max_io_capacity;
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
|
|
|
@ -1955,8 +1955,8 @@ err_exit:
|
|||
FIL_TYPE_TABLESPACE,
|
||||
crypt_data, mode, 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));
|
||||
mysql_mutex_unlock(&fil_system.mutex);
|
||||
mtr.start();
|
||||
mtr.set_named_space(space);
|
||||
ut_a(fsp_header_init(space, size, &mtr) == DB_SUCCESS);
|
||||
|
|
|
@ -2364,6 +2364,7 @@ tablespace_deleted:
|
|||
}
|
||||
|
||||
const ulint zip_size = s->zip_size(), size = s->size;
|
||||
s->x_lock();
|
||||
s->release();
|
||||
mtr_t mtr;
|
||||
|
||||
|
@ -2381,13 +2382,17 @@ tablespace_deleted:
|
|||
|| !page_is_leaf(block->page.frame);
|
||||
mtr.commit();
|
||||
if (err == DB_TABLESPACE_DELETED) {
|
||||
s->x_unlock();
|
||||
goto tablespace_deleted;
|
||||
}
|
||||
if (!remove) {
|
||||
s->x_unlock();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
s->x_unlock();
|
||||
|
||||
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
||||
|| srv_fast_shutdown) {
|
||||
continue;
|
||||
|
@ -2416,7 +2421,7 @@ tablespace_deleted:
|
|||
/* Prevent an infinite loop, by removing entries from
|
||||
the change buffer in the case the bitmap bits were
|
||||
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);
|
||||
|
||||
if (bitmap_bits
|
||||
&& DB_SUCCESS
|
||||
if (!bitmap_bits) {
|
||||
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())) {
|
||||
ibuf_mtr_start(&mtr);
|
||||
mtr.set_named_space(space);
|
||||
ibuf_reset_bitmap(block, page_id, zip_size, &mtr);
|
||||
ibuf_mtr_commit(&mtr);
|
||||
bitmap_bits = 0;
|
||||
if (!block
|
||||
|| btr_page_get_index_id(block->page.frame)
|
||||
!= DICT_IBUF_ID_MIN + IBUF_SPACE_ID) {
|
||||
ibuf_delete_recs(page_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bitmap_bits) {
|
||||
/* No changes are buffered for this page. */
|
||||
space->release();
|
||||
return DB_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -216,14 +216,6 @@ buf_block_t*
|
|||
trx_undo_assign_low(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo,
|
||||
mtr_t *mtr, dberr_t *err)
|
||||
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.
|
||||
@param[in,out] trx transaction
|
||||
|
|
|
@ -2491,7 +2491,7 @@ inline
|
|||
recv_sys_t::parse_mtr_result recv_sys_t::parse(source &l, bool if_exists)
|
||||
noexcept
|
||||
{
|
||||
restart:
|
||||
restart:
|
||||
#ifndef SUX_LOCK_GENERIC
|
||||
ut_ad(log_sys.latch.is_write_locked() ||
|
||||
srv_operation == SRV_OPERATION_BACKUP ||
|
||||
|
@ -3279,9 +3279,6 @@ set_start_lsn:
|
|||
|| recv_sys.is_corrupt_log()) && !srv_force_recovery) {
|
||||
if (init) {
|
||||
init->created = false;
|
||||
if (space || block->page.id().page_no()) {
|
||||
block->page.lock.x_lock_recursive();
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
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);
|
||||
ut_ad(file->is_open());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,14 +214,14 @@ row_ins_sec_index_entry_by_modify(
|
|||
made to the clustered index, and completed the
|
||||
secondary index creation before we got here. In this
|
||||
case, the change would already be there. The CREATE
|
||||
INDEX should be waiting for a MySQL meta-data lock
|
||||
upgrade at least until this INSERT or UPDATE
|
||||
returns. After that point, set_committed(true)
|
||||
would be invoked in commit_inplace_alter_table(). */
|
||||
INDEX should be in wait_while_table_is_used() at least
|
||||
until this INSERT or UPDATE returns. After that point,
|
||||
set_committed(true) would be invoked in
|
||||
commit_inplace_alter_table(). */
|
||||
ut_a(update->n_fields == 0);
|
||||
ut_a(!cursor->index()->is_committed());
|
||||
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) {
|
||||
|
|
|
@ -615,6 +615,8 @@ row_purge_del_mark(
|
|||
const auto type= node->index->type;
|
||||
if (type & (DICT_FTS | DICT_CORRUPT))
|
||||
continue;
|
||||
if (node->index->online_status > ONLINE_INDEX_CREATION)
|
||||
continue;
|
||||
if (UNIV_UNLIKELY(DICT_VIRTUAL & type) && !node->index->is_committed() &&
|
||||
node->index->has_new_v_col())
|
||||
continue;
|
||||
|
@ -767,6 +769,11 @@ row_purge_upd_exist_or_extern_func(
|
|||
continue;
|
||||
}
|
||||
|
||||
if (node->index->online_status
|
||||
> ONLINE_INDEX_CREATION) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (row_upd_changes_ord_field_binary(node->index, node->update,
|
||||
thr, NULL, NULL)) {
|
||||
/* Build the older version of the index entry */
|
||||
|
|
|
@ -246,127 +246,121 @@ Remove the undo log segment from the rseg slot if it is too big for reuse.
|
|||
void
|
||||
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 ")",
|
||||
trx->id, trx_id_t{trx->rw_trx_hash_element->no}));
|
||||
ut_ad(undo == trx->rsegs.m_redo.undo);
|
||||
trx_rseg_t* rseg = trx->rsegs.m_redo.rseg;
|
||||
ut_ad(undo->rseg == rseg);
|
||||
buf_block_t* rseg_header = rseg->get(mtr, nullptr);
|
||||
/* We are in transaction commit; we cannot return an error. If the
|
||||
database is corrupted, it is better to crash it than to
|
||||
intentionally violate ACID by committing something that is known to
|
||||
be corrupted. */
|
||||
ut_ad(rseg_header);
|
||||
buf_block_t* undo_page = trx_undo_set_state_at_finish(
|
||||
undo, mtr);
|
||||
trx_ulogf_t* undo_header = undo_page->page.frame
|
||||
+ undo->hdr_offset;
|
||||
DBUG_PRINT("trx", ("commit(" TRX_ID_FMT "," TRX_ID_FMT ")",
|
||||
trx->id, trx_id_t{trx->rw_trx_hash_element->no}));
|
||||
ut_ad(undo->id < TRX_RSEG_N_SLOTS);
|
||||
ut_ad(undo == trx->rsegs.m_redo.undo);
|
||||
trx_rseg_t *rseg= trx->rsegs.m_redo.rseg;
|
||||
ut_ad(undo->rseg == rseg);
|
||||
buf_block_t *rseg_header= rseg->get(mtr, nullptr);
|
||||
/* We are in transaction commit; we cannot return an error. If the
|
||||
database is corrupted, it is better to crash it than to
|
||||
intentionally violate ACID by committing something that is known to
|
||||
be corrupted. */
|
||||
ut_ad(rseg_header);
|
||||
buf_block_t *undo_page=
|
||||
buf_page_get(page_id_t(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(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(rseg->needs_purge > trx->id);
|
||||
ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1);
|
||||
ut_ad(rseg->needs_purge > trx->id);
|
||||
|
||||
if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT
|
||||
+ rseg_header->page.frame))) {
|
||||
/* This database must have been upgraded from
|
||||
before MariaDB 10.3.5. */
|
||||
trx_rseg_format_upgrade(rseg_header, mtr);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (undo->state != TRX_UNDO_CACHED) {
|
||||
/* 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);
|
||||
rseg->history_size++;
|
||||
|
||||
uint32_t hist_size = mach_read_from_4(
|
||||
TRX_RSEG_HISTORY_SIZE + TRX_RSEG
|
||||
+ rseg_header->page.frame);
|
||||
if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT +
|
||||
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
|
||||
+ TRX_UNDO_PAGE_LIST
|
||||
+ undo_page->page.frame));
|
||||
uint16_t undo_state;
|
||||
|
||||
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());
|
||||
}
|
||||
if (undo->size == 1 &&
|
||||
TRX_UNDO_PAGE_REUSE_LIMIT >
|
||||
mach_read_from_2(TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE +
|
||||
undo_page->page.frame))
|
||||
{
|
||||
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,
|
||||
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.
|
||||
undo= nullptr;
|
||||
|
||||
Before any transaction-generating background threads or the
|
||||
purge have been started, we can
|
||||
start transactions in row_merge_drop_temp_indexes(),
|
||||
and roll back recovered transactions.
|
||||
/* After the purge thread has been given permission to exit,
|
||||
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.
|
||||
|
||||
Arbitrary user transactions may be executed when all the undo log
|
||||
related background processes (including purge) are disabled due to
|
||||
innodb_force_recovery=2 or innodb_force_recovery=3.
|
||||
DROP TABLE may be executed at any innodb_force_recovery level.
|
||||
Before any transaction-generating background threads or the purge
|
||||
have been started, we can start transactions in
|
||||
row_merge_drop_temp_indexes(), and roll back recovered transactions.
|
||||
|
||||
During fast shutdown, we may also continue to execute
|
||||
user transactions. */
|
||||
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);
|
||||
Arbitrary user transactions may be executed when all the undo log
|
||||
related background processes (including purge) are disabled due to
|
||||
innodb_force_recovery=2 or innodb_force_recovery=3. DROP TABLE may
|
||||
be executed at any innodb_force_recovery level.
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (wsrep_is_wsrep_xid(&trx->xid)) {
|
||||
trx_rseg_update_wsrep_checkpoint(rseg_header, &trx->xid, mtr);
|
||||
}
|
||||
During fast shutdown, we may also continue to execute user
|
||||
transactions. */
|
||||
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
|
||||
|
||||
if (trx->mysql_log_file_name && *trx->mysql_log_file_name) {
|
||||
/* Update the latest MySQL binlog name and offset info
|
||||
in rollback segment header if MySQL binlogging is on
|
||||
or the database server is a MySQL replication save. */
|
||||
trx_rseg_update_binlog_offset(rseg_header, trx, mtr);
|
||||
}
|
||||
if (trx->mysql_log_file_name && *trx->mysql_log_file_name)
|
||||
/* Update the latest binlog name and offset if log_bin=ON or this
|
||||
is a replica. */
|
||||
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
|
||||
when detecting corruption. It is better to crash the server
|
||||
than to intentionally violate ACID by committing something
|
||||
that is known to be corrupted. */
|
||||
ut_a(flst_add_first(rseg_header, TRX_RSEG + TRX_RSEG_HISTORY, undo_page,
|
||||
static_cast<uint16_t>(undo->hdr_offset
|
||||
+ TRX_UNDO_HISTORY_NODE),
|
||||
mtr) == DB_SUCCESS);
|
||||
/* We are in transaction commit; we cannot return an error
|
||||
when detecting corruption. It is better to crash the server
|
||||
than to intentionally violate ACID by committing something
|
||||
that is known to be corrupted. */
|
||||
ut_a(flst_add_first(rseg_header, TRX_RSEG + TRX_RSEG_HISTORY, undo_page,
|
||||
uint16_t(page_offset(undo_header) +
|
||||
TRX_UNDO_HISTORY_NODE), mtr) == DB_SUCCESS);
|
||||
|
||||
mtr->write<8,mtr_t::MAYBE_NOP>(*undo_page,
|
||||
undo_header + TRX_UNDO_TRX_NO,
|
||||
trx->rw_trx_hash_element->no);
|
||||
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;
|
||||
mtr->write<2>(*undo_page, TRX_UNDO_SEG_HDR + TRX_UNDO_STATE +
|
||||
undo_page->page.frame, undo_state);
|
||||
mtr->write<8,mtr_t::MAYBE_NOP>(*undo_page, undo_header + TRX_UNDO_TRX_NO,
|
||||
trx->rw_trx_hash_element->no);
|
||||
mtr->write<2,mtr_t::MAYBE_NOP>(*undo_page, undo_header +
|
||||
TRX_UNDO_NEEDS_PURGE, 1U);
|
||||
}
|
||||
|
||||
/** Free an undo log segment.
|
||||
|
@ -685,6 +679,7 @@ not_free:
|
|||
mtr_t mtr;
|
||||
mtr.start();
|
||||
mtr.x_lock_space(&space);
|
||||
const auto space_id= space.id;
|
||||
|
||||
/* Lock all modified pages of the tablespace.
|
||||
|
||||
|
@ -694,8 +689,8 @@ not_free:
|
|||
mini-transaction commit and the server was killed, then
|
||||
discarding the to-be-trimmed pages without flushing would
|
||||
break crash recovery. */
|
||||
rescan:
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
|
||||
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list); bpage; )
|
||||
{
|
||||
ut_ad(bpage->oldest_modification());
|
||||
|
@ -703,46 +698,47 @@ not_free:
|
|||
|
||||
buf_page_t *prev= UT_LIST_GET_PREV(list, bpage);
|
||||
|
||||
if (bpage->id().space() == space.id &&
|
||||
bpage->oldest_modification() != 1)
|
||||
if (bpage->oldest_modification() > 2 && bpage->id().space() == space_id)
|
||||
{
|
||||
ut_ad(bpage->frame);
|
||||
auto block= reinterpret_cast<buf_block_t*>(bpage);
|
||||
if (!bpage->lock.x_lock_try())
|
||||
bpage->fix();
|
||||
{
|
||||
rescan:
|
||||
/* Let buf_pool_t::release_freed_page() proceed. */
|
||||
/* Try to acquire an exclusive latch while the cache line is
|
||||
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_lock(&buf_pool.mutex);
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
bpage= UT_LIST_GET_LAST(buf_pool.flush_list);
|
||||
continue;
|
||||
if (!got_lock)
|
||||
bpage->lock.x_lock();
|
||||
}
|
||||
buf_pool.flush_hp.set(prev);
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
|
||||
#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
|
||||
bpage->fix();
|
||||
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();
|
||||
mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||
}
|
||||
else
|
||||
{
|
||||
bpage->unfix();
|
||||
bpage->lock.x_unlock();
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
bpage= prev;
|
||||
|
|
|
@ -1463,37 +1463,6 @@ template buf_block_t*
|
|||
trx_undo_assign_low<true>(trx_t *trx, trx_rseg_t *rseg, trx_undo_t **undo,
|
||||
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.
|
||||
@param[in,out] trx transaction
|
||||
@param[in,out] undo undo log
|
||||
|
|
Loading…
Reference in a new issue