mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 01:34:17 +01:00
Merge 10.4 into 10.5
This commit is contained in:
commit
68fe5f534c
18 changed files with 418 additions and 195 deletions
include
mysql-test
main
suite
storage/innobase
190
include/intrusive_list.h
Normal file
190
include/intrusive_list.h
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
Copyright (c) 2019, 2020, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; version 2 of
|
||||
the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace intrusive
|
||||
{
|
||||
|
||||
// Derive your class from this struct to insert to a linked list.
|
||||
template <class Tag= void> struct list_node
|
||||
{
|
||||
list_node(list_node *next= NULL, list_node *prev= NULL)
|
||||
: next(next), prev(prev)
|
||||
{
|
||||
}
|
||||
|
||||
list_node *next;
|
||||
list_node *prev;
|
||||
};
|
||||
|
||||
// Modelled after std::list<T>
|
||||
template <class T, class Tag= void> class list
|
||||
{
|
||||
public:
|
||||
typedef list_node<Tag> ListNode;
|
||||
class Iterator;
|
||||
|
||||
// All containers in C++ should define these types to implement generic
|
||||
// container interface.
|
||||
typedef T value_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef value_type &reference;
|
||||
typedef const value_type &const_reference;
|
||||
typedef T *pointer;
|
||||
typedef const T *const_pointer;
|
||||
typedef Iterator iterator;
|
||||
typedef Iterator const_iterator; /* FIXME */
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const iterator> const_reverse_iterator;
|
||||
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
// All iterators in C++ should define these types to implement generic
|
||||
// iterator interface.
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef T value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T *pointer;
|
||||
typedef T &reference;
|
||||
|
||||
Iterator(ListNode *node) : node_(node) {}
|
||||
|
||||
Iterator &operator++()
|
||||
{
|
||||
node_= node_->next;
|
||||
return *this;
|
||||
}
|
||||
Iterator operator++(int)
|
||||
{
|
||||
Iterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Iterator &operator--()
|
||||
{
|
||||
node_= node_->prev;
|
||||
return *this;
|
||||
}
|
||||
Iterator operator--(int)
|
||||
{
|
||||
Iterator tmp(*this);
|
||||
operator--();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
reference operator*() { return *static_cast<pointer>(node_); }
|
||||
pointer operator->() { return static_cast<pointer>(node_); }
|
||||
|
||||
bool operator==(const Iterator &rhs) { return node_ == rhs.node_; }
|
||||
bool operator!=(const Iterator &rhs) { return !(*this == rhs); }
|
||||
|
||||
private:
|
||||
ListNode *node_;
|
||||
|
||||
friend class list;
|
||||
};
|
||||
|
||||
list() : sentinel_(&sentinel_, &sentinel_), size_(0) {}
|
||||
|
||||
reference front() { return *begin(); }
|
||||
reference back() { return *--end(); }
|
||||
const_reference front() const { return *begin(); }
|
||||
const_reference back() const { return *--end(); }
|
||||
|
||||
iterator begin() { return iterator(sentinel_.next); }
|
||||
const_iterator begin() const
|
||||
{
|
||||
return iterator(const_cast<ListNode *>(sentinel_.next));
|
||||
}
|
||||
iterator end() { return iterator(&sentinel_); }
|
||||
const_iterator end() const
|
||||
{
|
||||
return iterator(const_cast<ListNode *>(&sentinel_));
|
||||
}
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return reverse_iterator(begin()); }
|
||||
|
||||
bool empty() const { return size_ == 0; }
|
||||
size_type size() const { return size_; }
|
||||
|
||||
void clear()
|
||||
{
|
||||
sentinel_.next= &sentinel_;
|
||||
sentinel_.prev= &sentinel_;
|
||||
size_= 0;
|
||||
}
|
||||
|
||||
iterator insert(iterator pos, reference value)
|
||||
{
|
||||
ListNode *curr= pos.node_;
|
||||
ListNode *prev= pos.node_->prev;
|
||||
|
||||
prev->next= &value;
|
||||
curr->prev= &value;
|
||||
|
||||
static_cast<ListNode &>(value).prev= prev;
|
||||
static_cast<ListNode &>(value).next= curr;
|
||||
|
||||
++size_;
|
||||
return iterator(&value);
|
||||
}
|
||||
|
||||
iterator erase(iterator pos)
|
||||
{
|
||||
ListNode *prev= pos.node_->prev;
|
||||
ListNode *next= pos.node_->next;
|
||||
|
||||
prev->next= next;
|
||||
next->prev= prev;
|
||||
|
||||
// This is not required for list functioning. But maybe it'll prevent bugs
|
||||
// and ease debugging.
|
||||
ListNode *curr= pos.node_;
|
||||
curr->prev= NULL;
|
||||
curr->next= NULL;
|
||||
|
||||
--size_;
|
||||
return next;
|
||||
}
|
||||
|
||||
void push_back(reference value) { insert(end(), value); }
|
||||
void pop_back() { erase(end()); }
|
||||
|
||||
void push_front(reference value) { insert(begin(), value); }
|
||||
void pop_front() { erase(begin()); }
|
||||
|
||||
// STL version is O(n) but this is O(1) because an element can't be inserted
|
||||
// several times in the same intrusive list.
|
||||
void remove(reference value) { erase(iterator(&value)); }
|
||||
|
||||
private:
|
||||
ListNode sentinel_;
|
||||
size_type size_;
|
||||
};
|
||||
|
||||
} // namespace intrusive
|
|
@ -2847,16 +2847,16 @@ drop table t1;
|
|||
# MDEV-20922: Adding an order by changes the query results
|
||||
#
|
||||
CREATE TABLE t1(a int, b int);
|
||||
INSERT INTO t1 values (1, 100), (2, 200), (3, 100), (4, 200);
|
||||
INSERT INTO t1 values (1, 100), (2, 200), (3, 100), (4, 200), (5, 200);
|
||||
create view v1 as select a, b+1 as x from t1;
|
||||
SELECT x, COUNT(DISTINCT a) AS y FROM v1 GROUP BY x ORDER BY y;
|
||||
x y
|
||||
101 2
|
||||
201 2
|
||||
201 3
|
||||
SELECT b+1 AS x, COUNT(DISTINCT a) AS y FROM t1 GROUP BY x ORDER BY y;
|
||||
x y
|
||||
101 2
|
||||
201 2
|
||||
201 3
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
#
|
||||
|
|
|
@ -1959,7 +1959,7 @@ drop table t1;
|
|||
--echo #
|
||||
|
||||
CREATE TABLE t1(a int, b int);
|
||||
INSERT INTO t1 values (1, 100), (2, 200), (3, 100), (4, 200);
|
||||
INSERT INTO t1 values (1, 100), (2, 200), (3, 100), (4, 200), (5, 200);
|
||||
|
||||
create view v1 as select a, b+1 as x from t1;
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
-- source include/have_file_key_management_plugin.inc
|
||||
# embedded does not support restart
|
||||
-- source include/not_embedded.inc
|
||||
# MDEV-20839 innodb-redo-badkey sporadically fails on buildbot with page dump
|
||||
# We only require a debug build to avoid getting page dumps, making use of
|
||||
# MDEV-19766: Disable page dump output in debug builds
|
||||
-- source include/have_debug.inc
|
||||
|
||||
call mtr.add_suppression("Plugin 'file_key_management'");
|
||||
call mtr.add_suppression("Plugin 'InnoDB' init function returned error.");
|
||||
|
|
|
@ -16,6 +16,30 @@ col_1 TEXT
|
|||
) ENGINE=INNODB ROW_FORMAT=COMPACT;
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
TRUNCATE TABLE t1;
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
ALTER TABLE t1 FORCE;
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
SET innodb_strict_mode = ON;
|
||||
TRUNCATE TABLE t1;
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
ALTER TABLE t1 FORCE;
|
||||
Warnings:
|
||||
Warning 139 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
DROP TABLE t1;
|
||||
SET @@global.log_warnings = 2;
|
||||
SET innodb_strict_mode = 1;
|
||||
|
|
|
@ -139,6 +139,7 @@ CHECK TABLE t1;
|
|||
DROP TABLE t1;
|
||||
|
||||
SET @save_algo = @@GLOBAL.innodb_compression_algorithm;
|
||||
--error 0,ER_WRONG_VALUE_FOR_VAR
|
||||
SET GLOBAL innodb_compression_algorithm=2;
|
||||
CREATE TABLE t1(a SERIAL) PAGE_COMPRESSED=1 ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES(1);
|
||||
|
@ -170,7 +171,7 @@ INSERT INTO t1 VALUES(2);
|
|||
SELECT * FROM t1;
|
||||
|
||||
|
||||
--error 0,1231
|
||||
--error 0,ER_WRONG_VALUE_FOR_VAR
|
||||
SET GLOBAL innodb_compression_algorithm=3;
|
||||
FLUSH TABLE t1 FOR EXPORT;
|
||||
--echo # List before copying files
|
||||
|
|
|
@ -18,7 +18,15 @@ CREATE TABLE t1 (
|
|||
,col_10 TEXT
|
||||
,col_11 TEXT
|
||||
) ENGINE=INNODB ROW_FORMAT=COMPACT;
|
||||
--enable_warnings
|
||||
TRUNCATE TABLE t1;
|
||||
OPTIMIZE TABLE t1;
|
||||
ALTER TABLE t1 FORCE;
|
||||
SET innodb_strict_mode = ON;
|
||||
TRUNCATE TABLE t1;
|
||||
OPTIMIZE TABLE t1;
|
||||
ALTER TABLE t1 FORCE;
|
||||
DROP TABLE t1;
|
||||
--disable_warnings
|
||||
|
||||
SET @@global.log_warnings = 2;
|
||||
SET innodb_strict_mode = 1;
|
||||
|
|
|
@ -4,7 +4,7 @@ use My::Platform;
|
|||
|
||||
@ISA = qw(My::Suite);
|
||||
|
||||
if (-d '../sql') {
|
||||
if (-d '../sql' && !&::using_extern()) {
|
||||
my $src = "$::bindir/plugin/auth_pam/auth_pam_tool";
|
||||
my $dst = "$::plugindir/auth_pam_tool_dir/auth_pam_tool";
|
||||
::mkpath( "$::plugindir/auth_pam_tool_dir");
|
||||
|
|
|
@ -170,6 +170,9 @@ SELECT @@global.wsrep_slave_threads;
|
|||
SELECT @@global.wsrep_cluster_address;
|
||||
@@global.wsrep_cluster_address
|
||||
|
||||
SELECT @@global.wsrep_on;
|
||||
@@global.wsrep_on
|
||||
1
|
||||
SHOW STATUS LIKE 'threads_connected';
|
||||
Variable_name Value
|
||||
Threads_connected 1
|
||||
|
@ -183,6 +186,9 @@ SELECT @@global.wsrep_provider;
|
|||
SELECT @@global.wsrep_cluster_address;
|
||||
@@global.wsrep_cluster_address
|
||||
|
||||
SELECT @@global.wsrep_on;
|
||||
@@global.wsrep_on
|
||||
1
|
||||
SHOW STATUS LIKE 'threads_connected';
|
||||
Variable_name Value
|
||||
Threads_connected 1
|
||||
|
@ -210,6 +216,9 @@ SELECT @@global.wsrep_provider;
|
|||
SELECT @@global.wsrep_cluster_address;
|
||||
@@global.wsrep_cluster_address
|
||||
gcomm://
|
||||
SELECT @@global.wsrep_on;
|
||||
@@global.wsrep_on
|
||||
1
|
||||
SHOW STATUS LIKE 'threads_connected';
|
||||
Variable_name Value
|
||||
Threads_connected 1
|
||||
|
|
|
@ -79,6 +79,7 @@ eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
|||
SELECT @@global.wsrep_provider;
|
||||
SELECT @@global.wsrep_slave_threads;
|
||||
SELECT @@global.wsrep_cluster_address;
|
||||
SELECT @@global.wsrep_on;
|
||||
SHOW STATUS LIKE 'threads_connected';
|
||||
SHOW STATUS LIKE 'wsrep_thread_count';
|
||||
--echo
|
||||
|
@ -90,6 +91,7 @@ eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
|
|||
--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
|
||||
SELECT @@global.wsrep_provider;
|
||||
SELECT @@global.wsrep_cluster_address;
|
||||
SELECT @@global.wsrep_on;
|
||||
SHOW STATUS LIKE 'threads_connected';
|
||||
SHOW STATUS LIKE 'wsrep_thread_count';
|
||||
--echo
|
||||
|
@ -112,6 +114,7 @@ SELECT VARIABLE_VALUE AS EXPECT_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VA
|
|||
--replace_regex /.*libgalera_smm.*/libgalera_smm.so/
|
||||
SELECT @@global.wsrep_provider;
|
||||
SELECT @@global.wsrep_cluster_address;
|
||||
SELECT @@global.wsrep_on;
|
||||
SHOW STATUS LIKE 'threads_connected';
|
||||
SHOW STATUS LIKE 'wsrep_thread_count';
|
||||
--echo
|
||||
|
@ -134,6 +137,7 @@ SHOW STATUS LIKE 'threads_connected';
|
|||
#
|
||||
set wsrep_on=0;
|
||||
set wsrep_on=1;
|
||||
--source include/wait_until_connected_again.inc
|
||||
create user test@localhost;
|
||||
connect con1,localhost,test;
|
||||
set auto_increment_increment=10;
|
||||
|
|
|
@ -2546,7 +2546,7 @@ static void fil_crypt_rotation_list_fill()
|
|||
}
|
||||
}
|
||||
|
||||
UT_LIST_ADD_LAST(fil_system.rotation_list, space);
|
||||
fil_system.rotation_list.push_back(*space);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -745,9 +745,7 @@ skip_flush:
|
|||
if (space->is_in_unflushed_spaces()
|
||||
&& fil_space_is_flushed(space)) {
|
||||
|
||||
UT_LIST_REMOVE(
|
||||
fil_system.unflushed_spaces,
|
||||
space);
|
||||
fil_system.unflushed_spaces.remove(*space);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1032,7 +1030,7 @@ fil_node_close_to_free(
|
|||
} else if (space->is_in_unflushed_spaces()
|
||||
&& fil_space_is_flushed(space)) {
|
||||
|
||||
UT_LIST_REMOVE(fil_system.unflushed_spaces, space);
|
||||
fil_system.unflushed_spaces.remove(*space);
|
||||
}
|
||||
|
||||
node->close();
|
||||
|
@ -1055,13 +1053,11 @@ fil_space_detach(
|
|||
if (space->is_in_unflushed_spaces()) {
|
||||
|
||||
ut_ad(!fil_buffering_disabled(space));
|
||||
|
||||
UT_LIST_REMOVE(fil_system.unflushed_spaces, space);
|
||||
fil_system.unflushed_spaces.remove(*space);
|
||||
}
|
||||
|
||||
if (space->is_in_rotation_list()) {
|
||||
|
||||
UT_LIST_REMOVE(fil_system.rotation_list, space);
|
||||
fil_system.rotation_list.remove(*space);
|
||||
}
|
||||
|
||||
UT_LIST_REMOVE(fil_system.space_list, space);
|
||||
|
@ -1275,7 +1271,7 @@ fil_space_create(
|
|||
|| srv_encrypt_tables)) {
|
||||
/* Key rotation is not enabled, need to inform background
|
||||
encryption threads. */
|
||||
UT_LIST_ADD_LAST(fil_system.rotation_list, space);
|
||||
fil_system.rotation_list.push_back(*space);
|
||||
mutex_exit(&fil_system.mutex);
|
||||
os_event_set(fil_crypt_threads_event);
|
||||
} else {
|
||||
|
@ -1578,7 +1574,7 @@ void fil_system_t::close()
|
|||
{
|
||||
ut_ad(this == &fil_system);
|
||||
ut_a(!UT_LIST_GET_LEN(LRU));
|
||||
ut_a(!UT_LIST_GET_LEN(unflushed_spaces));
|
||||
ut_a(unflushed_spaces.empty());
|
||||
ut_a(!UT_LIST_GET_LEN(space_list));
|
||||
ut_ad(!sys_space);
|
||||
ut_ad(!temp_space);
|
||||
|
@ -3924,8 +3920,8 @@ fil_node_complete_io(fil_node_t* node, const IORequest& type)
|
|||
node->needs_flush = true;
|
||||
|
||||
if (!node->space->is_in_unflushed_spaces()) {
|
||||
UT_LIST_ADD_FIRST(fil_system.unflushed_spaces,
|
||||
node->space);
|
||||
fil_system.unflushed_spaces.push_front(
|
||||
*node->space);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4328,7 +4324,6 @@ void
|
|||
fil_flush_file_spaces(
|
||||
fil_type_t purpose)
|
||||
{
|
||||
fil_space_t* space;
|
||||
ulint* space_ids;
|
||||
ulint n_space_ids;
|
||||
|
||||
|
@ -4336,30 +4331,25 @@ fil_flush_file_spaces(
|
|||
|
||||
mutex_enter(&fil_system.mutex);
|
||||
|
||||
n_space_ids = UT_LIST_GET_LEN(fil_system.unflushed_spaces);
|
||||
n_space_ids = fil_system.unflushed_spaces.size();
|
||||
if (n_space_ids == 0) {
|
||||
|
||||
mutex_exit(&fil_system.mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Assemble a list of space ids to flush. Previously, we
|
||||
traversed fil_system.unflushed_spaces and called UT_LIST_GET_NEXT()
|
||||
on a space that was just removed from the list by fil_flush().
|
||||
Thus, the space could be dropped and the memory overwritten. */
|
||||
space_ids = static_cast<ulint*>(
|
||||
ut_malloc_nokey(n_space_ids * sizeof(*space_ids)));
|
||||
|
||||
n_space_ids = 0;
|
||||
|
||||
for (space = UT_LIST_GET_FIRST(fil_system.unflushed_spaces);
|
||||
space;
|
||||
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
|
||||
for (intrusive::list<fil_space_t, unflushed_spaces_tag_t>::iterator it
|
||||
= fil_system.unflushed_spaces.begin(),
|
||||
end = fil_system.unflushed_spaces.end();
|
||||
it != end; ++it) {
|
||||
|
||||
if (space->purpose == purpose
|
||||
&& !space->is_stopping()) {
|
||||
|
||||
space_ids[n_space_ids++] = space->id;
|
||||
if (it->purpose == purpose && !it->is_stopping()) {
|
||||
space_ids[n_space_ids++] = it->id;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4860,8 +4850,8 @@ fil_space_remove_from_keyrotation(fil_space_t* space)
|
|||
ut_ad(space);
|
||||
|
||||
if (!space->referenced() && space->is_in_rotation_list()) {
|
||||
ut_a(UT_LIST_GET_LEN(fil_system.rotation_list) > 0);
|
||||
UT_LIST_REMOVE(fil_system.rotation_list, space);
|
||||
ut_a(!fil_system.rotation_list.empty());
|
||||
fil_system.rotation_list.remove(*space);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4877,53 +4867,45 @@ If NULL, use the first fil_space_t on fil_system.space_list.
|
|||
@param[in] key_version key version of the key state thread
|
||||
@return pointer to the next fil_space_t.
|
||||
@retval NULL if this was the last */
|
||||
fil_space_t*
|
||||
fil_system_t::keyrotate_next(
|
||||
fil_space_t* prev_space,
|
||||
bool recheck,
|
||||
uint key_version)
|
||||
fil_space_t *fil_system_t::keyrotate_next(fil_space_t *prev_space,
|
||||
bool recheck, uint key_version)
|
||||
{
|
||||
mutex_enter(&fil_system.mutex);
|
||||
mutex_enter(&fil_system.mutex);
|
||||
|
||||
/* If one of the encryption threads already started the encryption
|
||||
of the table then don't remove the unencrypted spaces from
|
||||
rotation list
|
||||
/* If one of the encryption threads already started the encryption
|
||||
of the table then don't remove the unencrypted spaces from rotation list
|
||||
|
||||
If there is a change in innodb_encrypt_tables variables value then
|
||||
don't remove the last processed tablespace from the rotation list. */
|
||||
const bool remove = ((!recheck || prev_space->crypt_data)
|
||||
&& (!key_version == !srv_encrypt_tables));
|
||||
If there is a change in innodb_encrypt_tables variables value then
|
||||
don't remove the last processed tablespace from the rotation list. */
|
||||
const bool remove= (!recheck || prev_space->crypt_data) &&
|
||||
!key_version == !srv_encrypt_tables;
|
||||
intrusive::list<fil_space_t, rotation_list_tag_t>::iterator it=
|
||||
prev_space == NULL ? fil_system.rotation_list.end() : prev_space;
|
||||
|
||||
fil_space_t* space = prev_space;
|
||||
if (it == fil_system.rotation_list.end())
|
||||
it= fil_system.rotation_list.begin();
|
||||
else
|
||||
{
|
||||
/* Move on to the next fil_space_t */
|
||||
prev_space->release();
|
||||
|
||||
if (prev_space == NULL) {
|
||||
space = UT_LIST_GET_FIRST(fil_system.rotation_list);
|
||||
++it;
|
||||
|
||||
/* We can trust that space is not NULL because we
|
||||
checked list length above */
|
||||
} else {
|
||||
/* Move on to the next fil_space_t */
|
||||
space->release();
|
||||
while (it != fil_system.rotation_list.end() &&
|
||||
(UT_LIST_GET_LEN(it->chain) == 0 || it->is_stopping()))
|
||||
++it;
|
||||
|
||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
||||
if (remove)
|
||||
fil_space_remove_from_keyrotation(prev_space);
|
||||
}
|
||||
|
||||
while (space != NULL
|
||||
&& (UT_LIST_GET_LEN(space->chain) == 0
|
||||
|| space->is_stopping())) {
|
||||
space = UT_LIST_GET_NEXT(rotation_list, space);
|
||||
}
|
||||
fil_space_t *space= it == fil_system.rotation_list.end() ? NULL : &*it;
|
||||
|
||||
if (remove) {
|
||||
fil_space_remove_from_keyrotation(prev_space);
|
||||
}
|
||||
}
|
||||
if (space)
|
||||
space->acquire();
|
||||
|
||||
if (space != NULL) {
|
||||
space->acquire();
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system.mutex);
|
||||
return(space);
|
||||
mutex_exit(&fil_system.mutex);
|
||||
return space;
|
||||
}
|
||||
|
||||
/** Determine the block size of the data file.
|
||||
|
@ -4978,18 +4960,21 @@ fil_space_found_by_id(
|
|||
|
||||
/** Checks that this tablespace in a list of unflushed tablespaces.
|
||||
@return true if in a list */
|
||||
bool fil_space_t::is_in_unflushed_spaces() const {
|
||||
ut_ad(mutex_own(&fil_system.mutex));
|
||||
bool fil_space_t::is_in_unflushed_spaces() const
|
||||
{
|
||||
ut_ad(mutex_own(&fil_system.mutex));
|
||||
|
||||
return fil_system.unflushed_spaces.start == this
|
||||
|| unflushed_spaces.next || unflushed_spaces.prev;
|
||||
return static_cast<const intrusive::list_node<unflushed_spaces_tag_t> *>(
|
||||
this)
|
||||
->next;
|
||||
}
|
||||
|
||||
/** Checks that this tablespace needs key rotation.
|
||||
@return true if in a rotation list */
|
||||
bool fil_space_t::is_in_rotation_list() const {
|
||||
ut_ad(mutex_own(&fil_system.mutex));
|
||||
bool fil_space_t::is_in_rotation_list() const
|
||||
{
|
||||
ut_ad(mutex_own(&fil_system.mutex));
|
||||
|
||||
return fil_system.rotation_list.start == this || rotation_list.next
|
||||
|| rotation_list.prev;
|
||||
return static_cast<const intrusive::list_node<rotation_list_tag_t> *>(this)
|
||||
->next;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
|
|||
Copyright (c) 2008, 2009 Google Inc.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
Copyright (c) 2012, Facebook Inc.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -3241,17 +3241,6 @@ trx_is_interrupted(
|
|||
return(trx && trx->mysql_thd && thd_kill_level(trx->mysql_thd));
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Determines if the currently running transaction is in strict mode.
|
||||
@return TRUE if strict */
|
||||
ibool
|
||||
trx_is_strict(
|
||||
/*==========*/
|
||||
trx_t* trx) /*!< in: transaction */
|
||||
{
|
||||
return(trx && trx->mysql_thd && THDVAR(trx->mysql_thd, strict_mode));
|
||||
}
|
||||
|
||||
/**************************************************************//**
|
||||
Resets some fields of a m_prebuilt struct. The template is used in fast
|
||||
retrieval of just those column values MySQL needs in its processing. */
|
||||
|
@ -11549,6 +11538,12 @@ create_table_info_t::parse_table_name(
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/** @return whether innodb_strict_mode is active */
|
||||
bool ha_innobase::is_innodb_strict_mode(THD *thd)
|
||||
{
|
||||
return THDVAR(thd, strict_mode);
|
||||
}
|
||||
|
||||
/** Determine InnoDB table flags.
|
||||
If strict_mode=OFF, this will adjust the flags to what should be assumed.
|
||||
@retval true on success
|
||||
|
@ -12831,7 +12826,9 @@ int create_table_info_t::create_table(bool create_fk)
|
|||
err, m_flags, NULL));
|
||||
}
|
||||
|
||||
if (!row_size_is_acceptable(*m_table)) {
|
||||
/* In TRUNCATE TABLE, we will merely warn about the maximum
|
||||
row size being too large. */
|
||||
if (!row_size_is_acceptable(*m_table, create_fk)) {
|
||||
DBUG_RETURN(convert_error_code_to_mysql(
|
||||
DB_TOO_BIG_RECORD, m_flags, NULL));
|
||||
}
|
||||
|
@ -12840,18 +12837,12 @@ int create_table_info_t::create_table(bool create_fk)
|
|||
}
|
||||
|
||||
bool create_table_info_t::row_size_is_acceptable(
|
||||
const dict_table_t &table) const
|
||||
const dict_table_t &table, bool strict) const
|
||||
{
|
||||
for (dict_index_t *index= dict_table_get_first_index(&table); index;
|
||||
index= dict_table_get_next_index(index))
|
||||
{
|
||||
|
||||
if (!row_size_is_acceptable(*index))
|
||||
{
|
||||
if (!row_size_is_acceptable(*index, strict))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -13029,7 +13020,7 @@ static void ib_warn_row_too_big(THD *thd, const dict_table_t *table)
|
|||
}
|
||||
|
||||
bool create_table_info_t::row_size_is_acceptable(
|
||||
const dict_index_t &index) const
|
||||
const dict_index_t &index, bool strict) const
|
||||
{
|
||||
if ((index.type & DICT_FTS) || index.table->is_system_db)
|
||||
{
|
||||
|
@ -13038,7 +13029,7 @@ bool create_table_info_t::row_size_is_acceptable(
|
|||
return true;
|
||||
}
|
||||
|
||||
const bool strict= THDVAR(m_thd, strict_mode);
|
||||
const bool innodb_strict_mode= THDVAR(m_thd, strict_mode);
|
||||
dict_index_t::record_size_info_t info= index.record_size_info();
|
||||
|
||||
if (info.row_is_too_big())
|
||||
|
@ -13050,9 +13041,9 @@ bool create_table_info_t::row_size_is_acceptable(
|
|||
const dict_field_t *field= dict_index_get_nth_field(&index, idx);
|
||||
|
||||
ut_ad((!field->name) == field->col->is_dropped());
|
||||
if (strict || global_system_variables.log_warnings > 2)
|
||||
if (innodb_strict_mode || global_system_variables.log_warnings > 2)
|
||||
{
|
||||
ib::error_or_warn eow(strict);
|
||||
ib::error_or_warn eow(strict && innodb_strict_mode);
|
||||
if (field->name)
|
||||
eow << "Cannot add field " << field->name << " in table ";
|
||||
else
|
||||
|
@ -13063,10 +13054,8 @@ bool create_table_info_t::row_size_is_acceptable(
|
|||
<< info.max_leaf_size << " bytes) for a record on index leaf page.";
|
||||
}
|
||||
|
||||
if (strict)
|
||||
{
|
||||
if (strict && innodb_strict_mode)
|
||||
return false;
|
||||
}
|
||||
|
||||
ib_warn_row_too_big(m_thd, index.table);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -439,6 +439,13 @@ public:
|
|||
can_convert_blob(const Field_blob* field,
|
||||
const Column_definition& new_field) const override;
|
||||
|
||||
/** @return whether innodb_strict_mode is active */
|
||||
static bool is_innodb_strict_mode(THD* thd);
|
||||
|
||||
/** @return whether innodb_strict_mode is active */
|
||||
bool is_innodb_strict_mode()
|
||||
{ return is_innodb_strict_mode(m_user_thd); }
|
||||
|
||||
protected:
|
||||
dberr_t innobase_get_autoinc(ulonglong* value);
|
||||
dberr_t innobase_lock_autoinc();
|
||||
|
@ -682,9 +689,11 @@ public:
|
|||
void allocate_trx();
|
||||
|
||||
/** Checks that every index have sane size. Depends on strict mode */
|
||||
bool row_size_is_acceptable(const dict_table_t& table) const;
|
||||
bool row_size_is_acceptable(const dict_table_t& table,
|
||||
bool strict) const;
|
||||
/** Checks that given index have sane size. Depends on strict mode */
|
||||
bool row_size_is_acceptable(const dict_index_t& index) const;
|
||||
bool row_size_is_acceptable(const dict_index_t& index,
|
||||
bool strict) const;
|
||||
|
||||
/** Determines InnoDB table flags.
|
||||
If strict_mode=OFF, this will adjust the flags to what should be assumed.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -124,6 +124,15 @@ static const alter_table_operations INNOBASE_ALTER_NOCREATE
|
|||
= ALTER_DROP_NON_UNIQUE_NON_PRIM_INDEX
|
||||
| ALTER_DROP_UNIQUE_INDEX;
|
||||
|
||||
/** Operations that InnoDB cares about and can perform without validation */
|
||||
static const alter_table_operations INNOBASE_ALTER_NOVALIDATE
|
||||
= INNOBASE_ALTER_NOCREATE
|
||||
| ALTER_VIRTUAL_COLUMN_ORDER
|
||||
| ALTER_COLUMN_NAME
|
||||
| INNOBASE_FOREIGN_OPERATIONS
|
||||
| ALTER_COLUMN_UNVERSIONED
|
||||
| ALTER_DROP_VIRTUAL_COLUMN;
|
||||
|
||||
/** Operations that InnoDB cares about and can perform without rebuild */
|
||||
static const alter_table_operations INNOBASE_ALTER_NOREBUILD
|
||||
= INNOBASE_ONLINE_CREATE
|
||||
|
@ -2286,7 +2295,7 @@ next_column:
|
|||
|
||||
const bool supports_instant = instant_alter_column_possible(
|
||||
*m_prebuilt->table, ha_alter_info, table, altered_table,
|
||||
trx_is_strict(m_prebuilt->trx));
|
||||
is_innodb_strict_mode());
|
||||
if (add_drop_v_cols) {
|
||||
ulonglong flags = ha_alter_info->handler_flags;
|
||||
|
||||
|
@ -6437,7 +6446,7 @@ new_clustered_failed:
|
|||
|
||||
if (ctx->need_rebuild() && instant_alter_column_possible(
|
||||
*user_table, ha_alter_info, old_table, altered_table,
|
||||
trx_is_strict(ctx->trx))) {
|
||||
ha_innobase::is_innodb_strict_mode(ctx->trx->mysql_thd))) {
|
||||
for (uint a = 0; a < ctx->num_to_add_index; a++) {
|
||||
ctx->add_index[a]->table = ctx->new_table;
|
||||
error = dict_index_add_to_cache(
|
||||
|
@ -6670,7 +6679,15 @@ error_handling_drop_uncached_1:
|
|||
}
|
||||
|
||||
ctx->add_index[a] = index;
|
||||
if (!info.row_size_is_acceptable(*index)) {
|
||||
/* For ALTER TABLE...FORCE or OPTIMIZE TABLE,
|
||||
we may only issue warnings, because there will
|
||||
be no schema change from the user perspective. */
|
||||
if (!info.row_size_is_acceptable(
|
||||
*index,
|
||||
!!(ha_alter_info->handler_flags
|
||||
& ~(INNOBASE_INPLACE_IGNORE
|
||||
| INNOBASE_ALTER_NOVALIDATE
|
||||
| ALTER_RECREATE_TABLE)))) {
|
||||
error = DB_TOO_BIG_RECORD;
|
||||
goto error_handling_drop_uncached_1;
|
||||
}
|
||||
|
@ -6771,7 +6788,7 @@ error_handling_drop_uncached:
|
|||
DBUG_ASSERT(index != ctx->add_index[a]);
|
||||
}
|
||||
ctx->add_index[a]= index;
|
||||
if (!info.row_size_is_acceptable(*index)) {
|
||||
if (!info.row_size_is_acceptable(*index, true)) {
|
||||
error = DB_TOO_BIG_RECORD;
|
||||
goto error_handling_drop_uncached;
|
||||
}
|
||||
|
@ -6824,7 +6841,7 @@ error_handling_drop_uncached:
|
|||
}
|
||||
}
|
||||
} else if (ctx->is_instant()
|
||||
&& !info.row_size_is_acceptable(*user_table)) {
|
||||
&& !info.row_size_is_acceptable(*user_table, true)) {
|
||||
error = DB_TOO_BIG_RECORD;
|
||||
goto error_handling;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2018, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2018, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -29,7 +29,8 @@ Created 2013-03-16 Sunny Bains
|
|||
|
||||
#include "mem0mem.h"
|
||||
#include "dyn0types.h"
|
||||
#include "ut0lst.h"
|
||||
#include "intrusive_list.h"
|
||||
|
||||
|
||||
/** Class that manages dynamic buffers. It uses a UT_LIST of
|
||||
mtr_buf_t::block_t instances. We don't use STL containers in
|
||||
|
@ -40,17 +41,11 @@ backend for the custom allocator because we would like the data in
|
|||
the blocks to be contiguous. */
|
||||
class mtr_buf_t {
|
||||
public:
|
||||
|
||||
class block_t;
|
||||
|
||||
typedef UT_LIST_NODE_T(block_t) block_node_t;
|
||||
typedef UT_LIST_BASE_NODE_T(block_t) block_list_t;
|
||||
|
||||
/** SIZE - sizeof(m_node) + sizeof(m_used) */
|
||||
enum { MAX_DATA_SIZE = DYN_ARRAY_DATA_SIZE
|
||||
- sizeof(block_node_t) + sizeof(ib_uint32_t) };
|
||||
- sizeof(intrusive::list_node<>) + sizeof(uint32_t) };
|
||||
|
||||
class block_t {
|
||||
class block_t : public intrusive::list_node<> {
|
||||
public:
|
||||
|
||||
block_t()
|
||||
|
@ -158,9 +153,6 @@ public:
|
|||
/** Storage */
|
||||
byte m_data[MAX_DATA_SIZE];
|
||||
|
||||
/** Doubly linked list node. */
|
||||
block_node_t m_node;
|
||||
|
||||
/** number of data bytes used in this block;
|
||||
DYN_BLOCK_FULL_FLAG is set when the block becomes full */
|
||||
uint32_t m_used;
|
||||
|
@ -168,13 +160,14 @@ public:
|
|||
friend class mtr_buf_t;
|
||||
};
|
||||
|
||||
typedef intrusive::list<block_t> list_t;
|
||||
|
||||
/** Default constructor */
|
||||
mtr_buf_t()
|
||||
:
|
||||
m_heap(),
|
||||
m_size()
|
||||
{
|
||||
UT_LIST_INIT(m_list, &block_t::m_node);
|
||||
push_back(&m_first_block);
|
||||
}
|
||||
|
||||
|
@ -192,11 +185,11 @@ public:
|
|||
m_heap = NULL;
|
||||
|
||||
/* Initialise the list and add the first block. */
|
||||
UT_LIST_INIT(m_list, &block_t::m_node);
|
||||
push_back(&m_first_block);
|
||||
m_list.clear();
|
||||
m_list.push_back(m_first_block);
|
||||
} else {
|
||||
m_first_block.init();
|
||||
ut_ad(UT_LIST_GET_LEN(m_list) == 1);
|
||||
ut_ad(m_list.size() == 1);
|
||||
}
|
||||
|
||||
m_size = 0;
|
||||
|
@ -228,7 +221,7 @@ public:
|
|||
@param ptr end of used space */
|
||||
void close(const byte* ptr)
|
||||
{
|
||||
ut_ad(UT_LIST_GET_LEN(m_list) > 0);
|
||||
ut_ad(!m_list.empty());
|
||||
block_t* block = back();
|
||||
|
||||
m_size -= block->used();
|
||||
|
@ -310,11 +303,10 @@ public:
|
|||
#ifdef UNIV_DEBUG
|
||||
ulint total_size = 0;
|
||||
|
||||
for (const block_t* block = UT_LIST_GET_FIRST(m_list);
|
||||
block != NULL;
|
||||
block = UT_LIST_GET_NEXT(m_node, block)) {
|
||||
|
||||
total_size += block->used();
|
||||
for (typename list_t::iterator it = m_list.begin(),
|
||||
end = m_list.end();
|
||||
it != end; ++it) {
|
||||
total_size += it->used();
|
||||
}
|
||||
|
||||
ut_ad(total_size == m_size);
|
||||
|
@ -328,12 +320,12 @@ public:
|
|||
template <typename Functor>
|
||||
bool for_each_block(Functor& functor) const
|
||||
{
|
||||
for (const block_t* block = UT_LIST_GET_FIRST(m_list);
|
||||
block != NULL;
|
||||
block = UT_LIST_GET_NEXT(m_node, block)) {
|
||||
for (typename list_t::iterator it = m_list.begin(),
|
||||
end = m_list.end();
|
||||
it != end; ++it) {
|
||||
|
||||
if (!functor(block)) {
|
||||
return(false);
|
||||
if (!functor(&*it)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,12 +338,12 @@ public:
|
|||
template <typename Functor>
|
||||
bool for_each_block_in_reverse(Functor& functor) const
|
||||
{
|
||||
for (block_t* block = UT_LIST_GET_LAST(m_list);
|
||||
block != NULL;
|
||||
block = UT_LIST_GET_PREV(m_node, block)) {
|
||||
for (typename list_t::reverse_iterator it = m_list.rbegin(),
|
||||
end = m_list.rend();
|
||||
it != end; ++it) {
|
||||
|
||||
if (!functor(block)) {
|
||||
return(false);
|
||||
if (!functor(&*it)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,12 +356,12 @@ public:
|
|||
template <typename Functor>
|
||||
bool for_each_block_in_reverse(const Functor& functor) const
|
||||
{
|
||||
for (block_t* block = UT_LIST_GET_LAST(m_list);
|
||||
block != NULL;
|
||||
block = UT_LIST_GET_PREV(m_node, block)) {
|
||||
for (typename list_t::reverse_iterator it = m_list.rbegin(),
|
||||
end = m_list.rend();
|
||||
it != end; ++it) {
|
||||
|
||||
if (!functor(block)) {
|
||||
return(false);
|
||||
if (!functor(&*it)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,8 +373,7 @@ public:
|
|||
block_t* front()
|
||||
MY_ATTRIBUTE((warn_unused_result))
|
||||
{
|
||||
ut_ad(UT_LIST_GET_LEN(m_list) > 0);
|
||||
return(UT_LIST_GET_FIRST(m_list));
|
||||
return &m_list.front();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -403,14 +394,13 @@ private:
|
|||
void push_back(block_t* block)
|
||||
{
|
||||
block->init();
|
||||
|
||||
UT_LIST_ADD_LAST(m_list, block);
|
||||
m_list.push_back(*block);
|
||||
}
|
||||
|
||||
/** @return the last block in the list */
|
||||
block_t* back() const
|
||||
{
|
||||
return(UT_LIST_GET_LAST(m_list));
|
||||
return &const_cast<block_t&>(m_list.back());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -433,25 +423,22 @@ private:
|
|||
@return the block containing the pos. */
|
||||
block_t* find(ulint& pos)
|
||||
{
|
||||
block_t* block;
|
||||
ut_ad(!m_list.empty());
|
||||
|
||||
ut_ad(UT_LIST_GET_LEN(m_list) > 0);
|
||||
for (typename list_t::iterator it = m_list.begin(),
|
||||
end = m_list.end();
|
||||
it != end; ++it) {
|
||||
|
||||
for (block = UT_LIST_GET_FIRST(m_list);
|
||||
block != NULL;
|
||||
block = UT_LIST_GET_NEXT(m_node, block)) {
|
||||
if (pos < it->used()) {
|
||||
ut_ad(it->used() >= pos);
|
||||
|
||||
if (pos < block->used()) {
|
||||
break;
|
||||
return &*it;
|
||||
}
|
||||
|
||||
pos -= block->used();
|
||||
pos -= it->used();
|
||||
}
|
||||
|
||||
ut_ad(block != NULL);
|
||||
ut_ad(block->used() >= pos);
|
||||
|
||||
return(block);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -477,7 +464,7 @@ private:
|
|||
mem_heap_t* m_heap;
|
||||
|
||||
/** Allocated blocks */
|
||||
block_list_t m_list;
|
||||
list_t m_list;
|
||||
|
||||
/** Total size used by all blocks */
|
||||
ulint m_size;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -34,10 +34,14 @@ Created 10/25/1995 Heikki Tuuri
|
|||
#include "hash0hash.h"
|
||||
#include "log0recv.h"
|
||||
#include "dict0types.h"
|
||||
#include "intrusive_list.h"
|
||||
#ifdef UNIV_LINUX
|
||||
# include <set>
|
||||
#endif
|
||||
|
||||
struct unflushed_spaces_tag_t;
|
||||
struct rotation_list_tag_t;
|
||||
|
||||
/** whether to reduce redo logging during ALTER TABLE */
|
||||
extern my_bool innodb_log_optimize_ddl;
|
||||
// Forward declaration
|
||||
|
@ -78,7 +82,13 @@ struct fil_node_t;
|
|||
#endif
|
||||
|
||||
/** Tablespace or log data space */
|
||||
struct fil_space_t {
|
||||
#ifndef UNIV_INNOCHECKSUM
|
||||
struct fil_space_t : intrusive::list_node<unflushed_spaces_tag_t>,
|
||||
intrusive::list_node<rotation_list_tag_t>
|
||||
#else
|
||||
struct fil_space_t
|
||||
#endif
|
||||
{
|
||||
#ifndef UNIV_INNOCHECKSUM
|
||||
ulint id; /*!< space id */
|
||||
hash_node_t hash; /*!< hash chain node */
|
||||
|
@ -148,9 +158,6 @@ struct fil_space_t {
|
|||
std::atomic<ulint> n_pending_ios;
|
||||
rw_lock_t latch; /*!< latch protecting the file space storage
|
||||
allocation */
|
||||
UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
|
||||
/*!< list of spaces with at least one unflushed
|
||||
file we have written to */
|
||||
UT_LIST_NODE_T(fil_space_t) named_spaces;
|
||||
/*!< list of spaces for which MLOG_FILE_NAME
|
||||
records have been issued */
|
||||
|
@ -159,8 +166,6 @@ struct fil_space_t {
|
|||
bool is_in_unflushed_spaces() const;
|
||||
UT_LIST_NODE_T(fil_space_t) space_list;
|
||||
/*!< list of all spaces */
|
||||
/** other tablespaces needing key rotation */
|
||||
UT_LIST_NODE_T(fil_space_t) rotation_list;
|
||||
/** Checks that this tablespace needs key rotation.
|
||||
@return true if in a rotation list */
|
||||
bool is_in_rotation_list() const;
|
||||
|
@ -268,7 +273,7 @@ struct fil_space_t {
|
|||
void release_for_io() { ut_ad(pending_io()); n_pending_ios--; }
|
||||
/** @return whether I/O is pending */
|
||||
bool pending_io() const { return n_pending_ios; }
|
||||
#endif
|
||||
#endif /* !UNIV_INNOCHECKSUM */
|
||||
/** FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
|
||||
check fsp0types.h to more info about flags. */
|
||||
ulint flags;
|
||||
|
@ -888,8 +893,6 @@ struct fil_system_t {
|
|||
{
|
||||
UT_LIST_INIT(LRU, &fil_node_t::LRU);
|
||||
UT_LIST_INIT(space_list, &fil_space_t::space_list);
|
||||
UT_LIST_INIT(rotation_list, &fil_space_t::rotation_list);
|
||||
UT_LIST_INIT(unflushed_spaces, &fil_space_t::unflushed_spaces);
|
||||
UT_LIST_INIT(named_spaces, &fil_space_t::named_spaces);
|
||||
}
|
||||
|
||||
|
@ -941,8 +944,8 @@ public:
|
|||
not put to this list: they are opened
|
||||
after the startup, and kept open until
|
||||
shutdown */
|
||||
UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
|
||||
/*!< base node for the list of those
|
||||
intrusive::list<fil_space_t, unflushed_spaces_tag_t> unflushed_spaces;
|
||||
/*!< list of those
|
||||
tablespaces whose files contain
|
||||
unflushed writes; those spaces have
|
||||
at least one file node where
|
||||
|
@ -962,7 +965,7 @@ public:
|
|||
record has been written since
|
||||
the latest redo log checkpoint.
|
||||
Protected only by log_sys.mutex. */
|
||||
UT_LIST_BASE_NODE_T(fil_space_t) rotation_list;
|
||||
intrusive::list<fil_space_t, rotation_list_tag_t> rotation_list;
|
||||
/*!< list of all file spaces needing
|
||||
key rotation.*/
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2015, 2019, MariaDB Corporation.
|
||||
Copyright (c) 2015, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -342,13 +342,6 @@ bool
|
|||
trx_is_interrupted(
|
||||
/*===============*/
|
||||
const trx_t* trx); /*!< in: transaction */
|
||||
/**********************************************************************//**
|
||||
Determines if the currently running transaction is in strict mode.
|
||||
@return TRUE if strict */
|
||||
ibool
|
||||
trx_is_strict(
|
||||
/*==========*/
|
||||
trx_t* trx); /*!< in: transaction */
|
||||
|
||||
/*******************************************************************//**
|
||||
Calculates the "weight" of a transaction. The weight of one transaction
|
||||
|
|
Loading…
Add table
Reference in a new issue