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
INSTALL_COMMAND ""
CMAKE_ARGS
"-DCMAKE_WARN_DEPRECATED=FALSE"
"-DPCRE2_BUILD_TESTS=OFF"
"-DPCRE2_BUILD_PCRE2GREP=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;
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
#
#

View File

@@ -2661,6 +2661,28 @@ delete from t1 where a = 11;
# cleanup
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 # End of 10.5 tests
--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:
THD_STAGE_INFO(thd, org_stage);
if (thd->killed)
if (thd->killed && !thd->get_stmt_da()->is_ok())
{
thd->send_kill_message();
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
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;
MYSQL_LOCK *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) 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
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());
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);
if ((block->n_hash_helps > 0)

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
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
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"
#ifdef UNIV_DEBUG
#include "trx0purge.h"
#endif
#include "row0mysql.h"
#include "row0upd.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;
}
/** 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().
@param trx transaction
@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) 2009, Percona 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
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_n_fil_crypt_iops;
#if defined SAFE_MUTEX && defined UNIV_DEBUG
#ifdef UNIV_DEBUG
my_bool innodb_evict_tables_on_commit_debug;
#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_pessimistic_insert_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 recalc_pool_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)
{
fts_optimize_remove_table(table);
purge_sys.stop_FTS();
purge_sys.stop_FTS(*table);
err= fts_lock_tables(trx, *table);
}
@@ -13819,7 +13818,7 @@ int ha_innobase::truncate()
if (fts) {
fts_optimize_remove_table(ib_table);
purge_sys.stop_FTS();
purge_sys.stop_FTS(*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.",
NULL, NULL, FALSE);
# ifdef SAFE_MUTEX
static MYSQL_SYSVAR_BOOL(evict_tables_on_commit_debug,
innodb_evict_tables_on_commit_debug, PLUGIN_VAR_OPCMDARG,
"On transaction commit, try to evict tables from the data dictionary cache.",
NULL, NULL, FALSE);
# endif /* SAFE_MUTEX */
static MYSQL_SYSVAR_UINT(data_file_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(limit_optimistic_insert_debug),
MYSQL_SYSVAR(trx_purge_view_update_only_debug),
# ifdef SAFE_MUTEX
MYSQL_SYSVAR(evict_tables_on_commit_debug),
# endif /* SAFE_MUTEX */
MYSQL_SYSVAR(data_file_size_debug),
MYSQL_SYSVAR(fil_make_page_dirty_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) 2013, 2021, MariaDB Corporation.
Copyright (c) 2013, 2022, 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
@@ -6271,7 +6271,7 @@ acquire_lock:
}
if (fts_exist) {
purge_sys.stop_FTS();
purge_sys.stop_FTS(*ctx->new_table);
if (error == DB_SUCCESS) {
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)
{
fts_optimize_remove_table(ctx->new_table);
purge_sys.stop_FTS();
purge_sys.stop_FTS(*ctx->new_table);
}
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++) {
auto ctx = static_cast<ha_innobase_inplace_ctx*>(*pctx);
dberr_t error = DB_SUCCESS;
if (fts_exist) {
purge_sys.stop_FTS(*ctx->old_table);
}
if (new_clustered && ctx->old_table->fts) {
ut_ad(!ctx->old_table->fts->add_wq);
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) 2017, 2021, MariaDB Corporation.
Copyright (c) 2017, 2022, 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
@@ -283,6 +283,11 @@ public:
trx_sys.clone_oldest_view(&view);
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 */

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
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.
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_pessimistic_insert_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 recalc_pool_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) 2014, 2021, MariaDB Corporation.
Copyright (c) 2014, 2022, 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
@@ -3873,10 +3873,11 @@ restart:
and release possible other transactions waiting because of these locks. */
void lock_release(trx_t *trx)
{
#if defined SAFE_MUTEX && defined UNIV_DEBUG
#ifdef UNIV_DEBUG
std::set<table_id_t> to_evict;
if (innodb_evict_tables_on_commit_debug && !trx->is_recovered)
if (!!trx->dict_operation)
if (innodb_evict_tables_on_commit_debug &&
!trx->is_recovered && !trx->dict_operation &&
!trx->dict_operation_lock_mode)
for (const auto& p : trx->mod_tables)
if (!p.first->is_temporary())
to_evict.emplace(p.first->id);
@@ -3936,17 +3937,15 @@ released:
trx->lock.was_chosen_as_deadlock_victim= false;
trx->lock.n_rec_locks= 0;
#if defined SAFE_MUTEX && defined UNIV_DEBUG
#ifdef UNIV_DEBUG
if (to_evict.empty())
return;
dict_sys.lock(SRW_LOCK_CALL);
LockMutexGuard g{SRW_LOCK_CALL};
for (const table_id_t id : to_evict)
{
if (dict_table_t *table= dict_sys.find_table(id))
if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks))
dict_sys.remove(table, true);
}
dict_sys.unlock();
#endif
}

View File

@@ -3081,6 +3081,32 @@ inline fil_space_t *fil_system_t::find(const char *path) const
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.
@param last_batch whether it is possible to write more redo log */
void recv_sys_t::apply(bool last_batch)
@@ -3277,9 +3303,15 @@ next_page:
mysql_mutex_assert_not_owner(&log_sys.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
in ascending order of buf_page_t::oldest_modification. */
buf_flush_sync_batch(recovered_lsn);
}
if (!last_batch)
{

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
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
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. */
ut_ad(!block.page.in_LRU_list);
ut_ad(!buf_pool.is_uncompressed(&block));
return;
}

View File

@@ -1,7 +1,7 @@
/*****************************************************************************
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
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)
{
fts_optimize_remove_table(table);
purge_sys.stop_FTS();
purge_sys.stop_FTS(*table);
err= fts_lock_tables(trx, *table);
if (err != DB_SUCCESS)
{

View File

@@ -703,8 +703,8 @@ not_free:
if (bpage->id().space() == space.id &&
bpage->oldest_modification() != 1)
{
ut_ad(bpage->frame);
auto block= reinterpret_cast<buf_block_t*>(bpage);
ut_ad(buf_pool.is_uncompressed(block));
if (!bpage->lock.x_lock_try())
{
/* 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) 2017, 2021, MariaDB Corporation.
Copyright (c) 2017, 2022, 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
@@ -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
(only record locks might be created, in an implicit-to-explicit conversion).
Hence, no mutex is needed here. */
if (n == 1)
if (n)
for (const lock_t *lock : trx.lock.table_locks)
if (lock && lock->type_mode == (LOCK_X | LOCK_TABLE))
return true;

View File

@@ -161,34 +161,17 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
}
out[pos++]= 0;
}
/*
Check for if directory is empty during install,
sets "<PROPERTY>_NOT_EMPTY" otherise
*/
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;
bool IsDirectoryEmptyOrNonExisting(const wchar_t *dir) {
wchar_t wildcard[MAX_PATH+3];
WIN32_FIND_DATAW data;
HANDLE h;
bool empty;
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
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);
wcscpy_s(wildcard, MAX_PATH, dir);
wcscat_s(wildcard, MAX_PATH, L"*.*");
bool empty= true;
h= FindFirstFile(wildcard, &data);
if (h != INVALID_HANDLE_VALUE)
{
empty= true;
for (;;)
{
if (wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L".."))
@@ -201,30 +184,77 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
}
FindClose(h);
}
else
{
/* Non-existent directory, we handle it as empty */
empty = true;
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, "Directory %S is empty or non-existent",
PropertyName);
WcaLog(LOGMSG_STANDARD, "DATADIR is empty or non-existent");
else
WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName);
WcaLog(LOGMSG_STANDARD, "DATADIR is NOT empty");
wcscpy_s(buf, MAX_PATH, PropertyName);
wcscat_s(buf, L"NOTEMPTY");
WcaSetProperty(buf, empty? L"":L"1");
if (!empty)
{
WcaSetProperty(L"DATADIRERROR", L"data directory exist and not empty");
goto LExit;
}
WcaSetProperty(L"DATADIRERROR", L"");
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:
return WcaFinalize(er);
}
extern "C" UINT __stdcall CheckDataDirectoryEmpty(MSIHANDLE hInstall)
{
return CheckDirectoryEmpty(hInstall, L"DATADIR");
}
bool CheckServiceExists(const wchar_t *name)
{

View File

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

View File

@@ -84,17 +84,17 @@
<Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish>
</Control>
<Control Id="RemoveDatadirText" Type="Text" X="60" Y="85" Width="280" Height="20">
<Text>Remove default database directory [DATADIR]. Ensures proper cleanup on uninstall.</Text>
<Control Id="RemoveDatadirText" Type="Text" X="60" Y="85" Width="280" Height="30">
<Text>Remove [DATADIR]. Ensures proper cleanup on uninstall.</Text>
</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">
<Publish Property="CLEANUPDATA">1</Publish>
<Publish Event="NewDialog" Value="VerifyReadyDlg">WixUI_InstallMode</Publish>
<Publish Event="EndDialog" Value="Return">NOT WixUI_InstallMode</Publish>
</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>
</Control>
@@ -230,12 +230,22 @@
<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>
</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-->
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&amp;Back">
<Publish Event="NewDialog" Value="CustomizeDlg">1</Publish>
</Control>
<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 Event="SpawnDialog" Value="WarningDlg"><![CDATA[WarningText <>""]]></Publish>
<Publish Property="SERVICENAME" Value="MariaDB">NOT SERVICENAME AND NOT WarningText</Publish>
@@ -335,7 +345,7 @@
</UI>
<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 -->
<UI Id="MyWixUI_Mondo">
<UIRef Id="WixUI_FeatureTree" />
@@ -355,13 +365,6 @@
<Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="NewOrUpgradeInstanceDlg" Order="999">
NOT Installed AND UpgradableServiceFound
</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">
<![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]>
</Publish>
@@ -634,13 +637,13 @@
Property="FailureProgram"
Execute="deferred" />
<CustomAction Id='ErrorDataDirNotEmpty'
Error='Chosen data directory [DATADIR] is not empty. It must be empty prior to installation.'/>
<CustomAction Id='ErrorDataDir'
Error='Invalid data directory, choose a different one. Error : [DATADIRERROR]'/>
<InstallExecuteSequence>
<Custom Action="CheckDataDirectoryEmpty" After="CostFinalize">
<Custom Action="CheckDataDirectory" After="CostFinalize">
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
</Custom>
<Custom Action="ErrorDataDirNotEmpty" After="CheckDataDirectoryEmpty" >DATADIRNOTEMPTY</Custom>
<Custom Action="ErrorDataDir" After="CheckDataDirectory">DATADIRERROR</Custom>
<Custom Action="CheckDatabaseProperties" Before="CreateDatabaseCommand">SERVICENAME</Custom>
<Custom Action="CreateDatabaseCommand" After="CostFinalize" >
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>