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

Merge 10.6 into 10.7

This commit is contained in:
Marko Mäkelä
2022-01-12 13:14:58 +02:00
23 changed files with 490 additions and 312 deletions

View File

@@ -48,6 +48,7 @@ MACRO(BUNDLE_PCRE2)
URL_MD5 8c1699a725d4b28410adf4b964ebbcb7 URL_MD5 8c1699a725d4b28410adf4b964ebbcb7
INSTALL_COMMAND "" INSTALL_COMMAND ""
CMAKE_ARGS CMAKE_ARGS
"-DCMAKE_WARN_DEPRECATED=FALSE"
"-DPCRE2_BUILD_TESTS=OFF" "-DPCRE2_BUILD_TESTS=OFF"
"-DPCRE2_BUILD_PCRE2GREP=OFF" "-DPCRE2_BUILD_PCRE2GREP=OFF"
"-DBUILD_SHARED_LIBS=OFF" "-DBUILD_SHARED_LIBS=OFF"

View File

@@ -3415,6 +3415,24 @@ ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITH
delete from t1 where a = 11; delete from t1 where a = 11;
drop table t1; drop table t1;
# #
# MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in
# Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK)
#
SET @max_session_mem_used_save= @@max_session_mem_used;
CREATE TABLE t1 (a INT);
SELECT * FROM t1;
a
ALTER TABLE x MODIFY xx INT;
ERROR 42S02: Table 'test.x' doesn't exist
SET SESSION max_session_mem_used= 8192;
LOCK TABLE t1 WRITE;
ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT;
Warnings:
Note 1054 Unknown column 'b' in 't1'
SET SESSION max_session_mem_used = @max_session_mem_used_save;
UNLOCK TABLES;
DROP TABLE t1;
#
# End of 10.5 tests # End of 10.5 tests
# #
# #

View File

@@ -2661,6 +2661,28 @@ delete from t1 where a = 11;
# cleanup # cleanup
drop table t1; drop table t1;
--echo #
--echo # MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in
--echo # Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK)
--echo #
SET @max_session_mem_used_save= @@max_session_mem_used;
CREATE TABLE t1 (a INT);
SELECT * FROM t1;
--error ER_NO_SUCH_TABLE
ALTER TABLE x MODIFY xx INT;
SET SESSION max_session_mem_used= 8192;
LOCK TABLE t1 WRITE;
ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT;
SET SESSION max_session_mem_used = @max_session_mem_used_save;
UNLOCK TABLES;
DROP TABLE t1;
--echo # --echo #
--echo # End of 10.5 tests --echo # End of 10.5 tests
--echo # --echo #

View File

@@ -0,0 +1,9 @@
SET @save_debug= @@GLOBAL.innodb_evict_tables_on_commit_debug;
SET GLOBAL innodb_evict_tables_on_commit_debug=on;
CREATE TEMPORARY TABLE t1(a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(2);
DROP TABLE t2;
SET GLOBAL innodb_evict_tables_on_commit_debug=@save_debug;
DROP TEMPORARY TABLE t1;

View File

@@ -0,0 +1,11 @@
--source include/have_innodb.inc
--source include/have_debug.inc
SET @save_debug= @@GLOBAL.innodb_evict_tables_on_commit_debug;
SET GLOBAL innodb_evict_tables_on_commit_debug=on;
CREATE TEMPORARY TABLE t1(a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(2);
DROP TABLE t2;
SET GLOBAL innodb_evict_tables_on_commit_debug=@save_debug;
DROP TEMPORARY TABLE t1;

View File

@@ -356,7 +356,7 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags)
end: end:
THD_STAGE_INFO(thd, org_stage); THD_STAGE_INFO(thd, org_stage);
if (thd->killed) if (thd->killed && !thd->get_stmt_da()->is_ok())
{ {
thd->send_kill_message(); thd->send_kill_message();
if (!rc) if (!rc)

File diff suppressed because it is too large Load Diff

View File

@@ -2616,7 +2616,9 @@ void Locked_tables_list::mark_table_for_reopen(THD *thd, TABLE *table)
bool bool
Locked_tables_list::reopen_tables(THD *thd, bool need_reopen) Locked_tables_list::reopen_tables(THD *thd, bool need_reopen)
{ {
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); bool is_ok= thd->get_stmt_da()->is_ok();
Open_table_context ot_ctx(thd, !is_ok ? MYSQL_OPEN_REOPEN:
MYSQL_OPEN_IGNORE_KILLED | MYSQL_OPEN_REOPEN);
uint reopen_count= 0; uint reopen_count= 0;
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
MYSQL_LOCK *merged_lock; MYSQL_LOCK *merged_lock;

View File

@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc. Copyright (c) 2008, Google Inc.
Copyright (c) 2017, 2021, MariaDB Corporation. Copyright (c) 2017, 2022, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -412,7 +412,7 @@ btr_search_update_block_hash_info(btr_search_t* info, buf_block_t* block)
ut_ad(block->page.lock.have_x() || block->page.lock.have_s()); ut_ad(block->page.lock.have_x() || block->page.lock.have_s());
info->last_hash_succ = FALSE; info->last_hash_succ = FALSE;
ut_ad(buf_pool.is_uncompressed(block)); ut_ad(block->page.frame);
ut_ad(info->magic_n == BTR_SEARCH_MAGIC_N); ut_ad(info->magic_n == BTR_SEARCH_MAGIC_N);
if ((block->n_hash_helps > 0) if ((block->n_hash_helps > 0)

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2011, 2021, Oracle and/or its affiliates. Copyright (c) 2011, 2021, Oracle and/or its affiliates.
Copyright (c) 2016, 2021, MariaDB Corporation. Copyright (c) 2016, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -23,9 +23,7 @@ Full Text Search interface
***********************************************************************/ ***********************************************************************/
#include "trx0roll.h" #include "trx0roll.h"
#ifdef UNIV_DEBUG #include "trx0purge.h"
# include "trx0purge.h"
#endif
#include "row0mysql.h" #include "row0mysql.h"
#include "row0upd.h" #include "row0upd.h"
#include "dict0types.h" #include "dict0types.h"
@@ -1565,6 +1563,60 @@ dberr_t fts_lock_common_tables(trx_t *trx, const dict_table_t &table)
return DB_SUCCESS; return DB_SUCCESS;
} }
/** This function make sure that table doesn't
have any other reference count.
@param table_name table name */
static void fts_table_no_ref_count(const char *table_name)
{
dict_table_t *table= dict_table_open_on_name(
table_name, false, DICT_ERR_IGNORE_TABLESPACE);
if (!table)
return;
while (table->get_ref_count() > 1)
std::this_thread::sleep_for(std::chrono::milliseconds(50));
table->release();
}
/** Stop the purge thread and check n_ref_count of all auxiliary
and common table associated with the fts table.
@param table parent FTS table */
void purge_sys_t::stop_FTS(const dict_table_t &table)
{
purge_sys.stop_FTS();
fts_table_t fts_table;
char table_name[MAX_FULL_NAME_LEN];
FTS_INIT_FTS_TABLE(&fts_table, nullptr, FTS_COMMON_TABLE, (&table));
for (const char **suffix= fts_common_tables; *suffix; suffix++)
{
fts_table.suffix= *suffix;
fts_get_table_name(&fts_table, table_name, false);
fts_table_no_ref_count(table_name);
}
if (!table.fts)
return;
auto indexes= table.fts->indexes;
if (!indexes)
return;
for (ulint i= 0;i < ib_vector_size(indexes); ++i)
{
const dict_index_t *index= static_cast<const dict_index_t*>(
ib_vector_getp(indexes, i));
FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, index);
for (const fts_index_selector_t *s= fts_index_selector;
s->suffix; s++)
{
fts_table.suffix= s->suffix;
fts_get_table_name(&fts_table, table_name, false);
fts_table_no_ref_count(table_name);
}
}
}
/** Lock the internal FTS_ tables for table, before fts_drop_tables(). /** Lock the internal FTS_ tables for table, before fts_drop_tables().
@param trx transaction @param trx transaction
@param table table containing FULLTEXT INDEX @param table table containing FULLTEXT INDEX

View File

@@ -4,7 +4,7 @@ Copyright (c) 2000, 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc. Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2021, MariaDB Corporation. Copyright (c) 2013, 2022, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -206,7 +206,7 @@ static char* innodb_version_str = (char*) INNODB_VERSION_STR;
extern uint srv_fil_crypt_rotate_key_age; extern uint srv_fil_crypt_rotate_key_age;
extern uint srv_n_fil_crypt_iops; extern uint srv_n_fil_crypt_iops;
#if defined SAFE_MUTEX && defined UNIV_DEBUG #ifdef UNIV_DEBUG
my_bool innodb_evict_tables_on_commit_debug; my_bool innodb_evict_tables_on_commit_debug;
#endif #endif
@@ -533,7 +533,6 @@ mysql_pfs_key_t ibuf_bitmap_mutex_key;
mysql_pfs_key_t ibuf_mutex_key; mysql_pfs_key_t ibuf_mutex_key;
mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key; mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
mysql_pfs_key_t log_sys_mutex_key; mysql_pfs_key_t log_sys_mutex_key;
mysql_pfs_key_t log_cmdq_mutex_key;
mysql_pfs_key_t log_flush_order_mutex_key; mysql_pfs_key_t log_flush_order_mutex_key;
mysql_pfs_key_t recalc_pool_mutex_key; mysql_pfs_key_t recalc_pool_mutex_key;
mysql_pfs_key_t purge_sys_pq_mutex_key; mysql_pfs_key_t purge_sys_pq_mutex_key;
@@ -13441,7 +13440,7 @@ int ha_innobase::delete_table(const char *name)
if (fts) if (fts)
{ {
fts_optimize_remove_table(table); fts_optimize_remove_table(table);
purge_sys.stop_FTS(); purge_sys.stop_FTS(*table);
err= fts_lock_tables(trx, *table); err= fts_lock_tables(trx, *table);
} }
@@ -13819,7 +13818,7 @@ int ha_innobase::truncate()
if (fts) { if (fts) {
fts_optimize_remove_table(ib_table); fts_optimize_remove_table(ib_table);
purge_sys.stop_FTS(); purge_sys.stop_FTS(*ib_table);
error = fts_lock_tables(trx, *ib_table); error = fts_lock_tables(trx, *ib_table);
} }
@@ -19616,12 +19615,10 @@ static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug,
" but the each purges were not done yet.", " but the each purges were not done yet.",
NULL, NULL, FALSE); NULL, NULL, FALSE);
# ifdef SAFE_MUTEX
static MYSQL_SYSVAR_BOOL(evict_tables_on_commit_debug, static MYSQL_SYSVAR_BOOL(evict_tables_on_commit_debug,
innodb_evict_tables_on_commit_debug, PLUGIN_VAR_OPCMDARG, innodb_evict_tables_on_commit_debug, PLUGIN_VAR_OPCMDARG,
"On transaction commit, try to evict tables from the data dictionary cache.", "On transaction commit, try to evict tables from the data dictionary cache.",
NULL, NULL, FALSE); NULL, NULL, FALSE);
# endif /* SAFE_MUTEX */
static MYSQL_SYSVAR_UINT(data_file_size_debug, static MYSQL_SYSVAR_UINT(data_file_size_debug,
srv_sys_space_size_debug, srv_sys_space_size_debug,
@@ -19874,9 +19871,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(trx_rseg_n_slots_debug), MYSQL_SYSVAR(trx_rseg_n_slots_debug),
MYSQL_SYSVAR(limit_optimistic_insert_debug), MYSQL_SYSVAR(limit_optimistic_insert_debug),
MYSQL_SYSVAR(trx_purge_view_update_only_debug), MYSQL_SYSVAR(trx_purge_view_update_only_debug),
# ifdef SAFE_MUTEX
MYSQL_SYSVAR(evict_tables_on_commit_debug), MYSQL_SYSVAR(evict_tables_on_commit_debug),
# endif /* SAFE_MUTEX */
MYSQL_SYSVAR(data_file_size_debug), MYSQL_SYSVAR(data_file_size_debug),
MYSQL_SYSVAR(fil_make_page_dirty_debug), MYSQL_SYSVAR(fil_make_page_dirty_debug),
MYSQL_SYSVAR(saved_page_number_debug), MYSQL_SYSVAR(saved_page_number_debug),

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2021, MariaDB Corporation. Copyright (c) 2013, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -6271,7 +6271,7 @@ acquire_lock:
} }
if (fts_exist) { if (fts_exist) {
purge_sys.stop_FTS(); purge_sys.stop_FTS(*ctx->new_table);
if (error == DB_SUCCESS) { if (error == DB_SUCCESS) {
error = fts_lock_tables(ctx->trx, *ctx->new_table); error = fts_lock_tables(ctx->trx, *ctx->new_table);
} }
@@ -8718,7 +8718,7 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info,
if (fts_exist) if (fts_exist)
{ {
fts_optimize_remove_table(ctx->new_table); fts_optimize_remove_table(ctx->new_table);
purge_sys.stop_FTS(); purge_sys.stop_FTS(*ctx->new_table);
} }
if (ctx->need_rebuild()) if (ctx->need_rebuild())
{ {
@@ -10876,14 +10876,14 @@ ha_innobase::commit_inplace_alter_table(
} }
} }
if (fts_exist) {
purge_sys.stop_FTS();
}
for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) {
auto ctx = static_cast<ha_innobase_inplace_ctx*>(*pctx); auto ctx = static_cast<ha_innobase_inplace_ctx*>(*pctx);
dberr_t error = DB_SUCCESS; dberr_t error = DB_SUCCESS;
if (fts_exist) {
purge_sys.stop_FTS(*ctx->old_table);
}
if (new_clustered && ctx->old_table->fts) { if (new_clustered && ctx->old_table->fts) {
ut_ad(!ctx->old_table->fts->add_wq); ut_ad(!ctx->old_table->fts->add_wq);
fts_optimize_remove_table(ctx->old_table); fts_optimize_remove_table(ctx->old_table);

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation. Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -283,6 +283,11 @@ public:
trx_sys.clone_oldest_view(&view); trx_sys.clone_oldest_view(&view);
latch.wr_unlock(); latch.wr_unlock();
} }
/** Stop the purge thread and check n_ref_count of all auxiliary
and common table associated with the fts table.
@param table parent FTS table */
void stop_FTS(const dict_table_t &table);
}; };
/** The global data structure coordinating a purge */ /** The global data structure coordinating a purge */

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2021, MariaDB Corporation. Copyright (c) 2013, 2022, MariaDB Corporation.
Copyright (c) 2008, Google Inc. Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by Portions of this file contain modifications contributed and copyrighted by
@@ -518,7 +518,6 @@ extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
extern mysql_pfs_key_t ibuf_mutex_key; extern mysql_pfs_key_t ibuf_mutex_key;
extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key; extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
extern mysql_pfs_key_t log_sys_mutex_key; extern mysql_pfs_key_t log_sys_mutex_key;
extern mysql_pfs_key_t log_cmdq_mutex_key;
extern mysql_pfs_key_t log_flush_order_mutex_key; extern mysql_pfs_key_t log_flush_order_mutex_key;
extern mysql_pfs_key_t recalc_pool_mutex_key; extern mysql_pfs_key_t recalc_pool_mutex_key;
extern mysql_pfs_key_t purge_sys_pq_mutex_key; extern mysql_pfs_key_t purge_sys_pq_mutex_key;

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2021, MariaDB Corporation. Copyright (c) 2014, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -3873,11 +3873,12 @@ restart:
and release possible other transactions waiting because of these locks. */ and release possible other transactions waiting because of these locks. */
void lock_release(trx_t *trx) void lock_release(trx_t *trx)
{ {
#if defined SAFE_MUTEX && defined UNIV_DEBUG #ifdef UNIV_DEBUG
std::set<table_id_t> to_evict; std::set<table_id_t> to_evict;
if (innodb_evict_tables_on_commit_debug && !trx->is_recovered) if (innodb_evict_tables_on_commit_debug &&
if (!!trx->dict_operation) !trx->is_recovered && !trx->dict_operation &&
for (const auto& p: trx->mod_tables) !trx->dict_operation_lock_mode)
for (const auto& p : trx->mod_tables)
if (!p.first->is_temporary()) if (!p.first->is_temporary())
to_evict.emplace(p.first->id); to_evict.emplace(p.first->id);
#endif #endif
@@ -3936,17 +3937,15 @@ released:
trx->lock.was_chosen_as_deadlock_victim= false; trx->lock.was_chosen_as_deadlock_victim= false;
trx->lock.n_rec_locks= 0; trx->lock.n_rec_locks= 0;
#if defined SAFE_MUTEX && defined UNIV_DEBUG #ifdef UNIV_DEBUG
if (to_evict.empty()) if (to_evict.empty())
return; return;
dict_sys.lock(SRW_LOCK_CALL); dict_sys.lock(SRW_LOCK_CALL);
LockMutexGuard g{SRW_LOCK_CALL}; LockMutexGuard g{SRW_LOCK_CALL};
for (const table_id_t id : to_evict) for (const table_id_t id : to_evict)
{
if (dict_table_t *table= dict_sys.find_table(id)) if (dict_table_t *table= dict_sys.find_table(id))
if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks)) if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks))
dict_sys.remove(table, true); dict_sys.remove(table, true);
}
dict_sys.unlock(); dict_sys.unlock();
#endif #endif
} }

View File

@@ -3081,6 +3081,32 @@ inline fil_space_t *fil_system_t::find(const char *path) const
return nullptr; return nullptr;
} }
/** Thread-safe function which sorts flush_list by oldest_modification */
static void log_sort_flush_list()
{
mysql_mutex_lock(&buf_pool.flush_list_mutex);
const size_t size= UT_LIST_GET_LEN(buf_pool.flush_list);
std::unique_ptr<buf_page_t *[]> list(new buf_page_t *[size]);
size_t idx= 0;
for (buf_page_t *p= UT_LIST_GET_FIRST(buf_pool.flush_list); p;
p= UT_LIST_GET_NEXT(list, p))
list.get()[idx++]= p;
std::sort(list.get(), list.get() + size,
[](const buf_page_t *lhs, const buf_page_t *rhs) {
return rhs->oldest_modification() < lhs->oldest_modification();
});
UT_LIST_INIT(buf_pool.flush_list, &buf_page_t::list);
for (size_t i= 0; i < size; i++)
UT_LIST_ADD_LAST(buf_pool.flush_list, list[i]);
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
}
/** Apply buffered log to persistent data pages. /** Apply buffered log to persistent data pages.
@param last_batch whether it is possible to write more redo log */ @param last_batch whether it is possible to write more redo log */
void recv_sys_t::apply(bool last_batch) void recv_sys_t::apply(bool last_batch)
@@ -3277,9 +3303,15 @@ next_page:
mysql_mutex_assert_not_owner(&log_sys.mutex); mysql_mutex_assert_not_owner(&log_sys.mutex);
mysql_mutex_unlock(&mutex); mysql_mutex_unlock(&mutex);
if (last_batch && srv_operation != SRV_OPERATION_RESTORE &&
srv_operation != SRV_OPERATION_RESTORE_EXPORT)
log_sort_flush_list();
else
{
/* Instead of flushing, last_batch could sort the buf_pool.flush_list /* Instead of flushing, last_batch could sort the buf_pool.flush_list
in ascending order of buf_page_t::oldest_modification. */ in ascending order of buf_page_t::oldest_modification. */
buf_flush_sync_batch(recovered_lsn); buf_flush_sync_batch(recovered_lsn);
}
if (!last_batch) if (!last_batch)
{ {

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation. Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -1372,7 +1372,6 @@ void mtr_t::modify(const buf_block_t &block)
{ {
/* This must be PageConverter::update_page() in IMPORT TABLESPACE. */ /* This must be PageConverter::update_page() in IMPORT TABLESPACE. */
ut_ad(!block.page.in_LRU_list); ut_ad(!block.page.in_LRU_list);
ut_ad(!buf_pool.is_uncompressed(&block));
return; return;
} }

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2015, 2021, MariaDB Corporation. Copyright (c) 2015, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -2484,7 +2484,7 @@ dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx)
if (fts_exist) if (fts_exist)
{ {
fts_optimize_remove_table(table); fts_optimize_remove_table(table);
purge_sys.stop_FTS(); purge_sys.stop_FTS(*table);
err= fts_lock_tables(trx, *table); err= fts_lock_tables(trx, *table);
if (err != DB_SUCCESS) if (err != DB_SUCCESS)
{ {

View File

@@ -703,8 +703,8 @@ not_free:
if (bpage->id().space() == space.id && if (bpage->id().space() == space.id &&
bpage->oldest_modification() != 1) bpage->oldest_modification() != 1)
{ {
ut_ad(bpage->frame);
auto block= reinterpret_cast<buf_block_t*>(bpage); auto block= reinterpret_cast<buf_block_t*>(bpage);
ut_ad(buf_pool.is_uncompressed(block));
if (!bpage->lock.x_lock_try()) if (!bpage->lock.x_lock_try())
{ {
/* Let buf_pool_t::release_freed_page() proceed. */ /* Let buf_pool_t::release_freed_page() proceed. */

View File

@@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation. Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
@@ -1978,7 +1978,7 @@ static bool trx_has_lock_x(const trx_t &trx, dict_table_t& table)
/* This thread is executing trx. No other thread can modify our table locks /* This thread is executing trx. No other thread can modify our table locks
(only record locks might be created, in an implicit-to-explicit conversion). (only record locks might be created, in an implicit-to-explicit conversion).
Hence, no mutex is needed here. */ Hence, no mutex is needed here. */
if (n == 1) if (n)
for (const lock_t *lock : trx.lock.table_locks) for (const lock_t *lock : trx.lock.table_locks)
if (lock && lock->type_mode == (LOCK_X | LOCK_TABLE)) if (lock && lock->type_mode == (LOCK_X | LOCK_TABLE))
return true; return true;

View File

@@ -161,35 +161,18 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
} }
out[pos++]= 0; out[pos++]= 0;
} }
/*
Check for if directory is empty during install, bool IsDirectoryEmptyOrNonExisting(const wchar_t *dir) {
sets "<PROPERTY>_NOT_EMPTY" otherise wchar_t wildcard[MAX_PATH+3];
*/
extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
const wchar_t *PropertyName)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
wchar_t buf[MAX_PATH];
DWORD len = MAX_PATH;
WIN32_FIND_DATAW data; WIN32_FIND_DATAW data;
HANDLE h; HANDLE h;
bool empty; wcscpy_s(wildcard, MAX_PATH, dir);
wcscat_s(wildcard, MAX_PATH, L"*.*");
hr = WcaInitialize(hInstall, __FUNCTION__); bool empty= true;
ExitOnFailure(hr, "Failed to initialize"); h= FindFirstFile(wildcard, &data);
WcaLog(LOGMSG_STANDARD, "Initialized.");
MsiGetPropertyW(hInstall, PropertyName, buf, &len);
wcscat_s(buf, MAX_PATH, L"*.*");
WcaLog(LOGMSG_STANDARD, "Checking files in %S", buf);
h= FindFirstFile(buf, &data);
if (h != INVALID_HANDLE_VALUE) if (h != INVALID_HANDLE_VALUE)
{ {
empty= true; for (;;)
for(;;)
{ {
if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L".."))
{ {
@@ -201,30 +184,77 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
} }
FindClose(h); FindClose(h);
} }
return empty;
}
/*
Check for valid data directory is empty during install
A valid data directory is non-existing, or empty.
In addition, it must be different from any directories that
are going to be installed. This is required. because the full
directory is removed on a feature uninstall, and we do not want
it to be lib or bin.
*/
extern "C" UINT __stdcall CheckDataDirectory(MSIHANDLE hInstall)
{
HRESULT hr= S_OK;
UINT er= ERROR_SUCCESS;
wchar_t datadir[MAX_PATH];
DWORD len= MAX_PATH;
bool empty;
wchar_t *path= 0;
MsiGetPropertyW(hInstall, L"DATADIR", datadir, &len);
hr= WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
WcaLog(LOGMSG_STANDARD, "Checking files in %S", datadir);
empty= IsDirectoryEmptyOrNonExisting(datadir);
if (empty)
WcaLog(LOGMSG_STANDARD, "DATADIR is empty or non-existent");
else else
WcaLog(LOGMSG_STANDARD, "DATADIR is NOT empty");
if (!empty)
{ {
/* Non-existent directory, we handle it as empty */ WcaSetProperty(L"DATADIRERROR", L"data directory exist and not empty");
empty = true; goto LExit;
} }
WcaSetProperty(L"DATADIRERROR", L"");
if(empty)
WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent",
PropertyName);
else
WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName);
wcscpy_s(buf, MAX_PATH, PropertyName);
wcscat_s(buf, L"NOTEMPTY");
WcaSetProperty(buf, empty? L"":L"1");
WcaGetFormattedString(L"[INSTALLDIR]",&path);
if (path && !wcsicmp(datadir, path))
{
WcaSetProperty(L"DATADIRERROR", L"data directory can not be "
L"installation root directory");
ReleaseStr(path);
goto LExit;
}
for (auto dir :
{L"[INSTALLDIR]bin\\", L"[INSTALLDIR]include\\",
L"[INSTALLDIR]lib\\", L"[INSTALLDIR]share\\"})
{
WcaGetFormattedString(dir, &path);
if (path && !wcsnicmp(datadir, path, wcslen(path)))
{
const wchar_t *subdir= dir + sizeof("[INSTALLDIR]") - 1;
wchar_t msg[MAX_PATH]= L"data directory conflicts with '";
wcsncat_s(msg, subdir, wcslen(subdir) - 1);
wcscat_s(msg, L"' directory, which is part of this installation");
WcaSetProperty(L"DATADIRERROR", msg);
ReleaseStr(path);
goto LExit;
}
ReleaseStr(path);
path= 0;
}
LExit: LExit:
return WcaFinalize(er); return WcaFinalize(er);
} }
extern "C" UINT __stdcall CheckDataDirectoryEmpty(MSIHANDLE hInstall)
{
return CheckDirectoryEmpty(hInstall, L"DATADIR");
}
bool CheckServiceExists(const wchar_t *name) bool CheckServiceExists(const wchar_t *name)
{ {

View File

@@ -5,6 +5,6 @@ PresetDatabaseProperties
RemoveDataDirectory RemoveDataDirectory
CreateDatabaseRollback CreateDatabaseRollback
CheckDatabaseProperties CheckDatabaseProperties
CheckDataDirectoryEmpty CheckDataDirectory
CheckDBInUse CheckDBInUse
CheckServiceUpgrades CheckServiceUpgrades

View File

@@ -84,17 +84,17 @@
<Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish> <Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish>
</Control> </Control>
<Control Id="RemoveDatadirText" Type="Text" X="60" Y="85" Width="280" Height="20"> <Control Id="RemoveDatadirText" Type="Text" X="60" Y="85" Width="280" Height="30">
<Text>Remove default database directory [DATADIR]. Ensures proper cleanup on uninstall.</Text> <Text>Remove [DATADIR]. Ensures proper cleanup on uninstall.</Text>
</Control> </Control>
<Control Id="KeepDatadirButton" Type="PushButton" X="40" Y="118" Width="80" Height="18" <Control Id="KeepDatadirButton" Type="PushButton" X="40" Y="128" Width="80" Height="18"
Text="Keep data"> Text="Keep data">
<Publish Property="CLEANUPDATA">1</Publish> <Publish Property="CLEANUPDATA">1</Publish>
<Publish Event="NewDialog" Value="VerifyReadyDlg">WixUI_InstallMode</Publish> <Publish Event="NewDialog" Value="VerifyReadyDlg">WixUI_InstallMode</Publish>
<Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish> <Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish>
</Control> </Control>
<Control Id="KeepDataDirText" Type="Text" X="60" Y="138" Width="280" Height="70" > <Control Id="KeepDataDirText" Type="Text" X="60" Y="148" Width="280" Height="70" >
<Text>Do not remove [DATADIR]. Choose this option if you intend to use data in the future</Text> <Text>Do not remove [DATADIR]. Choose this option if you intend to use data in the future</Text>
</Control> </Control>
@@ -230,12 +230,22 @@
<Control Id="CheckBoxUTF8" Type="CheckBox" X="8" Y="154" Width="250" Height="18" Property="UTF8" CheckBoxValue="1" TabSkip="no"> <Control Id="CheckBoxUTF8" Type="CheckBox" X="8" Y="154" Width="250" Height="18" Property="UTF8" CheckBoxValue="1" TabSkip="no">
<Text>{\Font1}Use UTF8 as default server's character set</Text> <Text>{\Font1}Use UTF8 as default server's character set</Text>
</Control> </Control>
<Control Type="Text" Id="Text11" Width="67" Height="17" X="8" Y="190" Text="{\Font1}Data directory" />
<Control Type="PathEdit" Id="TxtDir" Width="175" Height="18" X="80" Y="190" Property="DATADIR">
</Control>
<Control Id="btnDirBrowse" Type="PushButton" Width="56" Height="17" X="278" Y="190" Text="Browse...">
<Publish Property="_BrowseProperty" Value="DATADIR" Order="1">1</Publish>
<Publish Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
</Control>
<!-- Navigation buttons--> <!-- Navigation buttons-->
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&amp;Back"> <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&amp;Back">
<Publish Event="NewDialog" Value="CustomizeDlg">1</Publish> <Publish Event="NewDialog" Value="CustomizeDlg">1</Publish>
</Control> </Control>
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&amp;Next"> <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&amp;Next">
<Publish Event="DoAction" Value="CheckDataDirectory">1</Publish>
<Publish Property="WarningText" Value="Invalid data directory, choose a different one. Error: [DATADIRERROR]">
DATADIRERROR
</Publish>
<Publish Property="WarningText" Value="Passwords do not match."><![CDATA[PASSWORD <> RootPasswordConfirm]]></Publish> <Publish Property="WarningText" Value="Passwords do not match."><![CDATA[PASSWORD <> RootPasswordConfirm]]></Publish>
<Publish Event="SpawnDialog" Value="WarningDlg"><![CDATA[WarningText <>""]]></Publish> <Publish Event="SpawnDialog" Value="WarningDlg"><![CDATA[WarningText <>""]]></Publish>
<Publish Property="SERVICENAME" Value="MariaDB">NOT SERVICENAME AND NOT WarningText</Publish> <Publish Property="SERVICENAME" Value="MariaDB">NOT SERVICENAME AND NOT WarningText</Publish>
@@ -335,7 +345,7 @@
</UI> </UI>
<Property Id="CRLF" Value="&#xD;&#xA;" /> <Property Id="CRLF" Value="&#xD;&#xA;" />
<CustomAction Id="CheckDataDirectoryEmpty" BinaryKey="wixca.dll" DllEntry="CheckDataDirectoryEmpty" Execute="immediate" Impersonate="yes"/> <CustomAction Id="CheckDataDirectory" BinaryKey="wixca.dll" DllEntry="CheckDataDirectory" Execute="immediate" Impersonate="yes"/>
<!-- What to do when navigation buttons are clicked --> <!-- What to do when navigation buttons are clicked -->
<UI Id="MyWixUI_Mondo"> <UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_FeatureTree" /> <UIRef Id="WixUI_FeatureTree" />
@@ -355,13 +365,6 @@
<Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="NewOrUpgradeInstanceDlg" Order="999"> <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="NewOrUpgradeInstanceDlg" Order="999">
NOT Installed AND UpgradableServiceFound NOT Installed AND UpgradableServiceFound
</Publish> </Publish>
<Publish Dialog="CustomizeDlg" Control="Next" Event="DoAction" Value="CheckDataDirectoryEmpty" Order="1"><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
<Publish Dialog="CustomizeDlg" Property="DATADIRNOTEMPTY" Control="Next" Order="1"><![CDATA[NOT(&DBInstance=3 AND NOT !DBInstance=3)]]></Publish>
<Publish Dialog="CustomizeDlg" Control="Next" Property="WarningText" Order="2"
Value="Selected data directory [DATADIR] is not empty. Either clean it, or choose another location for 'Database Instance' feature.">
DATADIRNOTEMPTY
</Publish>
<Publish Dialog="CustomizeDlg" Control="Next" Event="SpawnDialog" Value="WarningDlg" Order="3">WarningText</Publish>
<Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="4"> <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="4">
<![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]> <![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]>
</Publish> </Publish>
@@ -634,13 +637,13 @@
Property="FailureProgram" Property="FailureProgram"
Execute="deferred" /> Execute="deferred" />
<CustomAction Id='ErrorDataDirNotEmpty' <CustomAction Id='ErrorDataDir'
Error='Chosen data directory [DATADIR] is not empty. It must be empty prior to installation.'/> Error='Invalid data directory, choose a different one. Error : [DATADIRERROR]'/>
<InstallExecuteSequence> <InstallExecuteSequence>
<Custom Action="CheckDataDirectoryEmpty" After="CostFinalize"> <Custom Action="CheckDataDirectory" After="CostFinalize">
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]> <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
</Custom> </Custom>
<Custom Action="ErrorDataDirNotEmpty" After="CheckDataDirectoryEmpty" >DATADIRNOTEMPTY</Custom> <Custom Action="ErrorDataDir" After="CheckDataDirectory">DATADIRERROR</Custom>
<Custom Action="CheckDatabaseProperties" Before="CreateDatabaseCommand">SERVICENAME</Custom> <Custom Action="CheckDatabaseProperties" Before="CreateDatabaseCommand">SERVICENAME</Custom>
<Custom Action="CreateDatabaseCommand" After="CostFinalize" > <Custom Action="CreateDatabaseCommand" After="CostFinalize" >
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]> <![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>