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:
@@ -8,8 +8,7 @@ MariaDB Server has a vibrant community contributing in a wide range of areas. Th
|
|||||||
- [maria-developers mailing list](http://launchpad.net/~maria-developers)
|
- [maria-developers mailing list](http://launchpad.net/~maria-developers)
|
||||||
- [maria-discuss mailing list](http://launchpad.net/~maria-discuss)
|
- [maria-discuss mailing list](http://launchpad.net/~maria-discuss)
|
||||||
- [maria-docs mailing list](http://launchpad.net/~maria-docs)
|
- [maria-docs mailing list](http://launchpad.net/~maria-docs)
|
||||||
- ircs://chat.freenode.net/maria ([see the IRC page on the Knowledge Base](https://mariadb.com/kb/en/meta/irc-chat-servers-and-zulip-instance/) for help with IRC).
|
- The MariaDB Foundation and MariaDB Corporation have a presence on Reddit, Twitter and Facebook. See the [social media page](https://mariadb.com/kb/en/mariadb/social-media/).
|
||||||
- The MariaDB Foundation and MariaDB Corporation have a presence on Reddit, Twitter, Facebook and Google Plus. See the [social media page](https://mariadb.com/kb/en/mariadb/social-media/).
|
|
||||||
|
|
||||||
### Help document MariaDB
|
### Help document MariaDB
|
||||||
----
|
----
|
||||||
@@ -36,7 +35,7 @@ You’re very welcome to support MariaDB Server as an individual, or talk your c
|
|||||||
|
|
||||||
### Live QA for beginner contributors
|
### Live QA for beginner contributors
|
||||||
----
|
----
|
||||||
MariaDB has a dedicated time each week when we answer new contributor questions live on Zulip and IRC.
|
MariaDB has a dedicated time each week when we answer new contributor questions live on Zulip.
|
||||||
From 8:00 to 10:00 UTC on Mondays, and 10:00 to 12:00 UTC on Thursdays, anyone can ask any questions they’d like,
|
From 8:00 to 10:00 UTC on Mondays, and 10:00 to 12:00 UTC on Thursdays, anyone can ask any questions they’d like,
|
||||||
and a live developer will be available to assist.
|
and a live developer will be available to assist.
|
||||||
New contributors can ask questions any time, but we will provide immediate feedback during that interval.
|
New contributors can ask questions any time, but we will provide immediate feedback during that interval.
|
||||||
|
@@ -39,11 +39,10 @@ Help
|
|||||||
More help is available from the Maria Discuss mailing list
|
More help is available from the Maria Discuss mailing list
|
||||||
https://launchpad.net/~maria-discuss, MariaDB's Zulip
|
https://launchpad.net/~maria-discuss, MariaDB's Zulip
|
||||||
instance, https://mariadb.zulipchat.com/
|
instance, https://mariadb.zulipchat.com/
|
||||||
and the #maria IRC channel on Freenode.
|
|
||||||
|
|
||||||
Live QA for beginner contributors
|
Live QA for beginner contributors
|
||||||
----
|
----
|
||||||
MariaDB has a dedicated time each week when we answer new contributor questions live on Zulip and IRC.
|
MariaDB has a dedicated time each week when we answer new contributor questions live on Zulip.
|
||||||
From 8:00 to 10:00 UTC on Mondays, and 10:00 to 12:00 UTC on Thursdays,
|
From 8:00 to 10:00 UTC on Mondays, and 10:00 to 12:00 UTC on Thursdays,
|
||||||
anyone can ask any questions they’d like, and a live developer will be available to assist.
|
anyone can ask any questions they’d like, and a live developer will be available to assist.
|
||||||
|
|
||||||
|
@@ -245,6 +245,7 @@ ELSEIF(RPM MATCHES "(rhel|centos)8")
|
|||||||
ALTERNATIVE_NAME("server" "mariadb-server-utils")
|
ALTERNATIVE_NAME("server" "mariadb-server-utils")
|
||||||
ALTERNATIVE_NAME("shared" "mariadb-connector-c" ${MARIADB_CONNECTOR_C_VERSION}-1)
|
ALTERNATIVE_NAME("shared" "mariadb-connector-c" ${MARIADB_CONNECTOR_C_VERSION}-1)
|
||||||
ALTERNATIVE_NAME("shared" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1)
|
ALTERNATIVE_NAME("shared" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1)
|
||||||
|
ALTERNATIVE_NAME("devel" "mariadb-connector-c-devel" ${MARIADB_CONNECTOR_C_VERSION}-1)
|
||||||
SETA(CPACK_RPM_client_PACKAGE_PROVIDES "mariadb-galera = 3:%{version}-%{release}")
|
SETA(CPACK_RPM_client_PACKAGE_PROVIDES "mariadb-galera = 3:%{version}-%{release}")
|
||||||
SETA(CPACK_RPM_common_PACKAGE_PROVIDES "mariadb-galera-common = 3:%{version}-%{release}")
|
SETA(CPACK_RPM_common_PACKAGE_PROVIDES "mariadb-galera-common = 3:%{version}-%{release}")
|
||||||
SETA(CPACK_RPM_common_PACKAGE_REQUIRES "MariaDB-shared")
|
SETA(CPACK_RPM_common_PACKAGE_REQUIRES "MariaDB-shared")
|
||||||
@@ -257,6 +258,12 @@ ELSEIF(RPM MATCHES "sles")
|
|||||||
"mariadb-server = %{version}-%{release}"
|
"mariadb-server = %{version}-%{release}"
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
# MDEV-24629, we need it outside of ELSIFs
|
||||||
|
IF(RPM MATCHES "fedora3[234]")
|
||||||
|
ALTERNATIVE_NAME("common" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
SET(PYTHON_SHEBANG "/usr/bin/python3" CACHE STRING "python shebang")
|
SET(PYTHON_SHEBANG "/usr/bin/python3" CACHE STRING "python shebang")
|
||||||
|
|
||||||
# If we want to build build MariaDB-shared-compat,
|
# If we want to build build MariaDB-shared-compat,
|
||||||
|
@@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "datasink.h"
|
#include "datasink.h"
|
||||||
#include "ds_compress.h"
|
#include "ds_compress.h"
|
||||||
#include "ds_archive.h"
|
|
||||||
#include "ds_xbstream.h"
|
#include "ds_xbstream.h"
|
||||||
#include "ds_local.h"
|
#include "ds_local.h"
|
||||||
#include "ds_stdout.h"
|
#include "ds_stdout.h"
|
||||||
@@ -45,13 +44,6 @@ ds_create(const char *root, ds_type_t type)
|
|||||||
case DS_TYPE_LOCAL:
|
case DS_TYPE_LOCAL:
|
||||||
ds = &datasink_local;
|
ds = &datasink_local;
|
||||||
break;
|
break;
|
||||||
case DS_TYPE_ARCHIVE:
|
|
||||||
#ifdef HAVE_LIBARCHIVE
|
|
||||||
ds = &datasink_archive;
|
|
||||||
#else
|
|
||||||
die("mariabackup was built without libarchive support");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case DS_TYPE_XBSTREAM:
|
case DS_TYPE_XBSTREAM:
|
||||||
ds = &datasink_xbstream;
|
ds = &datasink_xbstream;
|
||||||
break;
|
break;
|
||||||
|
@@ -63,7 +63,6 @@ static inline int dummy_remove(const char *) {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
DS_TYPE_STDOUT,
|
DS_TYPE_STDOUT,
|
||||||
DS_TYPE_LOCAL,
|
DS_TYPE_LOCAL,
|
||||||
DS_TYPE_ARCHIVE,
|
|
||||||
DS_TYPE_XBSTREAM,
|
DS_TYPE_XBSTREAM,
|
||||||
DS_TYPE_COMPRESS,
|
DS_TYPE_COMPRESS,
|
||||||
DS_TYPE_ENCRYPT,
|
DS_TYPE_ENCRYPT,
|
||||||
|
@@ -1,282 +0,0 @@
|
|||||||
/******************************************************
|
|
||||||
Copyright (c) 2013 Percona LLC and/or its affiliates.
|
|
||||||
|
|
||||||
Streaming implementation for XtraBackup.
|
|
||||||
|
|
||||||
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 Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
||||||
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
#include <my_global.h>
|
|
||||||
#include <my_base.h>
|
|
||||||
#include <archive.h>
|
|
||||||
#include <archive_entry.h>
|
|
||||||
#include "common.h"
|
|
||||||
#include "datasink.h"
|
|
||||||
|
|
||||||
#if ARCHIVE_VERSION_NUMBER < 3000000
|
|
||||||
#define archive_write_add_filter_none(X) archive_write_set_compression_none(X)
|
|
||||||
#define archive_write_free(X) archive_write_finish(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct archive *archive;
|
|
||||||
ds_file_t *dest_file;
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
} ds_archive_ctxt_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct archive_entry *entry;
|
|
||||||
ds_archive_ctxt_t *archive_ctxt;
|
|
||||||
} ds_archive_file_t;
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
General archive interface */
|
|
||||||
|
|
||||||
static ds_ctxt_t *archive_init(const char *root);
|
|
||||||
static ds_file_t *archive_open(ds_ctxt_t *ctxt, const char *path,
|
|
||||||
MY_STAT *mystat);
|
|
||||||
static int archive_write(ds_file_t *file, const void *buf, size_t len);
|
|
||||||
static int archive_close(ds_file_t *file);
|
|
||||||
static void archive_deinit(ds_ctxt_t *ctxt);
|
|
||||||
|
|
||||||
datasink_t datasink_archive = {
|
|
||||||
&archive_init,
|
|
||||||
&archive_open,
|
|
||||||
&archive_write,
|
|
||||||
&archive_close,
|
|
||||||
&dummy_remove,
|
|
||||||
&archive_deinit
|
|
||||||
};
|
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
my_archive_open_callback(struct archive *a __attribute__((unused)),
|
|
||||||
void *data __attribute__((unused)))
|
|
||||||
{
|
|
||||||
return ARCHIVE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
ssize_t
|
|
||||||
my_archive_write_callback(struct archive *a __attribute__((unused)),
|
|
||||||
void *data, const void *buffer, size_t length)
|
|
||||||
{
|
|
||||||
ds_archive_ctxt_t *archive_ctxt;
|
|
||||||
|
|
||||||
archive_ctxt = (ds_archive_ctxt_t *) data;
|
|
||||||
|
|
||||||
xb_ad(archive_ctxt != NULL);
|
|
||||||
xb_ad(archive_ctxt->dest_file != NULL);
|
|
||||||
|
|
||||||
if (!ds_write(archive_ctxt->dest_file, buffer, length)) {
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
my_archive_close_callback(struct archive *a __attribute__((unused)),
|
|
||||||
void *data __attribute__((unused)))
|
|
||||||
{
|
|
||||||
return ARCHIVE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
ds_ctxt_t *
|
|
||||||
archive_init(const char *root __attribute__((unused)))
|
|
||||||
{
|
|
||||||
ds_ctxt_t *ctxt;
|
|
||||||
ds_archive_ctxt_t *archive_ctxt;
|
|
||||||
struct archive *a;
|
|
||||||
|
|
||||||
ctxt = my_malloc(sizeof(ds_ctxt_t) + sizeof(ds_archive_ctxt_t),
|
|
||||||
MYF(MY_FAE));
|
|
||||||
archive_ctxt = (ds_archive_ctxt_t *)(ctxt + 1);
|
|
||||||
|
|
||||||
if (pthread_mutex_init(&archive_ctxt->mutex, NULL)) {
|
|
||||||
msg("archive_init: pthread_mutex_init() failed.\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
a = archive_write_new();
|
|
||||||
if (a == NULL) {
|
|
||||||
msg("archive_write_new() failed.\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
archive_ctxt->archive = a;
|
|
||||||
archive_ctxt->dest_file = NULL;
|
|
||||||
|
|
||||||
if(archive_write_add_filter_none(a) != ARCHIVE_OK ||
|
|
||||||
archive_write_set_format_pax_restricted(a) != ARCHIVE_OK ||
|
|
||||||
/* disable internal buffering so we don't have to flush the
|
|
||||||
output in xtrabackup */
|
|
||||||
archive_write_set_bytes_per_block(a, 0) != ARCHIVE_OK) {
|
|
||||||
msg("failed to set libarchive archive options: %s\n",
|
|
||||||
archive_error_string(a));
|
|
||||||
archive_write_free(a);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (archive_write_open(a, archive_ctxt, my_archive_open_callback,
|
|
||||||
my_archive_write_callback,
|
|
||||||
my_archive_close_callback) != ARCHIVE_OK) {
|
|
||||||
msg("cannot open output archive.\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctxt->ptr = archive_ctxt;
|
|
||||||
|
|
||||||
return ctxt;
|
|
||||||
|
|
||||||
err:
|
|
||||||
my_free(ctxt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
ds_file_t *
|
|
||||||
archive_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat)
|
|
||||||
{
|
|
||||||
ds_archive_ctxt_t *archive_ctxt;
|
|
||||||
ds_ctxt_t *dest_ctxt;
|
|
||||||
ds_file_t *file;
|
|
||||||
ds_archive_file_t *archive_file;
|
|
||||||
|
|
||||||
struct archive *a;
|
|
||||||
struct archive_entry *entry;
|
|
||||||
|
|
||||||
xb_ad(ctxt->pipe_ctxt != NULL);
|
|
||||||
dest_ctxt = ctxt->pipe_ctxt;
|
|
||||||
|
|
||||||
archive_ctxt = (ds_archive_ctxt_t *) ctxt->ptr;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&archive_ctxt->mutex);
|
|
||||||
if (archive_ctxt->dest_file == NULL) {
|
|
||||||
archive_ctxt->dest_file = ds_open(dest_ctxt, path, mystat);
|
|
||||||
if (archive_ctxt->dest_file == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&archive_ctxt->mutex);
|
|
||||||
|
|
||||||
file = (ds_file_t *) my_malloc(sizeof(ds_file_t) +
|
|
||||||
sizeof(ds_archive_file_t),
|
|
||||||
MYF(MY_FAE));
|
|
||||||
|
|
||||||
archive_file = (ds_archive_file_t *) (file + 1);
|
|
||||||
|
|
||||||
a = archive_ctxt->archive;
|
|
||||||
|
|
||||||
entry = archive_entry_new();
|
|
||||||
if (entry == NULL) {
|
|
||||||
msg("archive_entry_new() failed.\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
archive_entry_set_size(entry, mystat->st_size);
|
|
||||||
archive_entry_set_mode(entry, 0660);
|
|
||||||
archive_entry_set_filetype(entry, AE_IFREG);
|
|
||||||
archive_entry_set_pathname(entry, path);
|
|
||||||
archive_entry_set_mtime(entry, mystat->st_mtime, 0);
|
|
||||||
|
|
||||||
archive_file->entry = entry;
|
|
||||||
archive_file->archive_ctxt = archive_ctxt;
|
|
||||||
|
|
||||||
if (archive_write_header(a, entry) != ARCHIVE_OK) {
|
|
||||||
msg("archive_write_header() failed.\n");
|
|
||||||
archive_entry_free(entry);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->ptr = archive_file;
|
|
||||||
file->path = archive_ctxt->dest_file->path;
|
|
||||||
|
|
||||||
return file;
|
|
||||||
|
|
||||||
err:
|
|
||||||
if (archive_ctxt->dest_file) {
|
|
||||||
ds_close(archive_ctxt->dest_file);
|
|
||||||
archive_ctxt->dest_file = NULL;
|
|
||||||
}
|
|
||||||
my_free(file);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
archive_write(ds_file_t *file, const void *buf, size_t len)
|
|
||||||
{
|
|
||||||
ds_archive_file_t *archive_file;
|
|
||||||
struct archive *a;
|
|
||||||
|
|
||||||
archive_file = (ds_archive_file_t *) file->ptr;
|
|
||||||
|
|
||||||
a = archive_file->archive_ctxt->archive;
|
|
||||||
|
|
||||||
xb_ad(archive_file->archive_ctxt->dest_file != NULL);
|
|
||||||
if (archive_write_data(a, buf, len) < 0) {
|
|
||||||
msg("archive_write_data() failed: %s (errno = %d)\n",
|
|
||||||
archive_error_string(a), archive_errno(a));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
int
|
|
||||||
archive_close(ds_file_t *file)
|
|
||||||
{
|
|
||||||
ds_archive_file_t *archive_file;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
archive_file = (ds_archive_file_t *)file->ptr;
|
|
||||||
|
|
||||||
archive_entry_free(archive_file->entry);
|
|
||||||
|
|
||||||
my_free(file);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void
|
|
||||||
archive_deinit(ds_ctxt_t *ctxt)
|
|
||||||
{
|
|
||||||
struct archive *a;
|
|
||||||
ds_archive_ctxt_t *archive_ctxt;
|
|
||||||
|
|
||||||
archive_ctxt = (ds_archive_ctxt_t *) ctxt->ptr;
|
|
||||||
|
|
||||||
a = archive_ctxt->archive;
|
|
||||||
|
|
||||||
if (archive_write_close(a) != ARCHIVE_OK) {
|
|
||||||
msg("archive_write_close() failed.\n");
|
|
||||||
}
|
|
||||||
archive_write_free(a);
|
|
||||||
|
|
||||||
if (archive_ctxt->dest_file) {
|
|
||||||
ds_close(archive_ctxt->dest_file);
|
|
||||||
archive_ctxt->dest_file = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&archive_ctxt->mutex);
|
|
||||||
|
|
||||||
my_free(ctxt);
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
/******************************************************
|
|
||||||
Copyright (c) 2013 Percona LLC and/or its affiliates.
|
|
||||||
|
|
||||||
Streaming interface for XtraBackup.
|
|
||||||
|
|
||||||
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 Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
||||||
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
#ifndef DS_ARCHIVE_H
|
|
||||||
#define DS_ARCHIVE_H
|
|
||||||
|
|
||||||
#include "datasink.h"
|
|
||||||
|
|
||||||
extern datasink_t datasink_archive;
|
|
||||||
|
|
||||||
#endif
|
|
@@ -126,14 +126,20 @@ xbstream_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat)
|
|||||||
pthread_mutex_lock(&stream_ctxt->mutex);
|
pthread_mutex_lock(&stream_ctxt->mutex);
|
||||||
if (stream_ctxt->dest_file == NULL) {
|
if (stream_ctxt->dest_file == NULL) {
|
||||||
stream_ctxt->dest_file = ds_open(dest_ctxt, path, mystat);
|
stream_ctxt->dest_file = ds_open(dest_ctxt, path, mystat);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&stream_ctxt->mutex);
|
||||||
if (stream_ctxt->dest_file == NULL) {
|
if (stream_ctxt->dest_file == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&stream_ctxt->mutex);
|
|
||||||
|
|
||||||
file = (ds_file_t *) my_malloc(PSI_NOT_INSTRUMENTED,
|
file = (ds_file_t *) my_malloc(PSI_NOT_INSTRUMENTED,
|
||||||
sizeof(ds_file_t) + sizeof(ds_stream_file_t), MYF(MY_FAE));
|
sizeof(ds_file_t) +
|
||||||
|
sizeof(ds_stream_file_t),
|
||||||
|
MYF(MY_FAE));
|
||||||
|
if (!file) {
|
||||||
|
msg("my_malloc() failed.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
stream_file = (ds_stream_file_t *) (file + 1);
|
stream_file = (ds_stream_file_t *) (file + 1);
|
||||||
|
|
||||||
xbstream = stream_ctxt->xbstream;
|
xbstream = stream_ctxt->xbstream;
|
||||||
|
Submodule libmariadb updated: 2ca0c22fd3...ffa3451fa5
@@ -3966,6 +3966,7 @@ static my_bool is_binary_compatible(enum enum_field_types type1,
|
|||||||
|
|
||||||
static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
|
static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
|
||||||
{
|
{
|
||||||
|
my_bool field_is_unsigned;
|
||||||
DBUG_ENTER("setup_one_fetch_function");
|
DBUG_ENTER("setup_one_fetch_function");
|
||||||
|
|
||||||
/* Setup data copy functions for the different supported types */
|
/* Setup data copy functions for the different supported types */
|
||||||
@@ -4042,6 +4043,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
|
|||||||
|
|
||||||
/* Setup skip_result functions (to calculate max_length) */
|
/* Setup skip_result functions (to calculate max_length) */
|
||||||
param->skip_result= skip_result_fixed;
|
param->skip_result= skip_result_fixed;
|
||||||
|
field_is_unsigned= MY_TEST(field->flags & UNSIGNED_FLAG);
|
||||||
switch (field->type) {
|
switch (field->type) {
|
||||||
case MYSQL_TYPE_NULL: /* for dummy binds */
|
case MYSQL_TYPE_NULL: /* for dummy binds */
|
||||||
param->pack_length= 0;
|
param->pack_length= 0;
|
||||||
@@ -4049,23 +4051,23 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
|
|||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TINY:
|
case MYSQL_TYPE_TINY:
|
||||||
param->pack_length= 1;
|
param->pack_length= 1;
|
||||||
field->max_length= 4; /* as in '-127' */
|
field->max_length= field_is_unsigned ? 3 : 4; /* '255' and '-127' */
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_YEAR:
|
case MYSQL_TYPE_YEAR:
|
||||||
case MYSQL_TYPE_SHORT:
|
case MYSQL_TYPE_SHORT:
|
||||||
param->pack_length= 2;
|
param->pack_length= 2;
|
||||||
field->max_length= 6; /* as in '-32767' */
|
field->max_length= field_is_unsigned ? 5 : 6; /* 65536 and '-32767' */
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_INT24:
|
case MYSQL_TYPE_INT24:
|
||||||
field->max_length= 9; /* as in '16777216' or in '-8388607' */
|
field->max_length= 8; /* '16777216' or in '-8388607' */
|
||||||
param->pack_length= 4;
|
param->pack_length= 4;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_LONG:
|
case MYSQL_TYPE_LONG:
|
||||||
field->max_length= 11; /* '-2147483647' */
|
field->max_length= field_is_unsigned ? 10 : 11; /* '4294967295' and '-2147483647' */
|
||||||
param->pack_length= 4;
|
param->pack_length= 4;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_LONGLONG:
|
case MYSQL_TYPE_LONGLONG:
|
||||||
field->max_length= 21; /* '18446744073709551616' */
|
field->max_length= 20; /* '18446744073709551616' or -9223372036854775808 */
|
||||||
param->pack_length= 8;
|
param->pack_length= 8;
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_FLOAT:
|
case MYSQL_TYPE_FLOAT:
|
||||||
|
@@ -2279,7 +2279,7 @@ servers \- remote (federated) servers as \fBCREATE SERVER\fR\&.
|
|||||||
.sp -1
|
.sp -1
|
||||||
.IP \(bu 2.3
|
.IP \(bu 2.3
|
||||||
.\}
|
.\}
|
||||||
stats \- statistics tables, InnoDB and Engine Independent Table Statistics (EITS), are dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-into\fR is specified) statements without (re)creating tables\&.
|
stats \- statistics tables, InnoDB and Engine Independent Table Statistics (EITS), are dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-ignore\fR is specified) statements without (re)creating tables\&.
|
||||||
.RE
|
.RE
|
||||||
.RS 4
|
.RS 4
|
||||||
.ie n \{\
|
.ie n \{\
|
||||||
@@ -2289,17 +2289,17 @@ stats \- statistics tables, InnoDB and Engine Independent Table Statistics (EITS
|
|||||||
.sp -1
|
.sp -1
|
||||||
.IP \(bu 2.3
|
.IP \(bu 2.3
|
||||||
.\}
|
.\}
|
||||||
timezones \- timezone related system tables dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-into\fR is specified) statements without (re)creating tables\&.
|
timezones \- timezone related system tables dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-ignore\fR is specified) statements without (re)creating tables\&.
|
||||||
.RE
|
.RE
|
||||||
.sp
|
.sp
|
||||||
The format of the output is affected by \fB\-\-replace\fR and \fB\-\-insert\-into\fR\&. The \fB\-\-replace\fR option will output \fBCREATE OR REPLACE\fR
|
The format of the output is affected by \fB\-\-replace\fR and \fB\-\-insert\-ignore\fR\&. The \fB\-\-replace\fR option will output \fBCREATE OR REPLACE\fR
|
||||||
forms of SQL, and also \fBDROP IF EXISTS\fR prior to \fBCREATE\fR, if a \fBCREATE OR REPLACE\fR option isn't available.
|
forms of SQL, and also \fBDROP IF EXISTS\fR prior to \fBCREATE\fR, if a \fBCREATE OR REPLACE\fR option isn't available.
|
||||||
.sp
|
.sp
|
||||||
With \fB\-\-system=user\fR (or \fBall\fR), and \fB\-\-replace\fR, SQL is generated to generate an error if attempting to import the dump with a connection user that is being replaced within the dump\&.
|
With \fB\-\-system=user\fR (or \fBall\fR), and \fB\-\-replace\fR, SQL is generated to generate an error if attempting to import the dump with a connection user that is being replaced within the dump\&.
|
||||||
.sp
|
.sp
|
||||||
The \fB\-\-insert\-into\fR option will cause \fBCREATE IF NOT EXIST\fR forms of SQL to generated if available.
|
The \fB\-\-insert\-ignore\fR option will cause \fBCREATE IF NOT EXIST\fR forms of SQL to generated if available.
|
||||||
.sp
|
.sp
|
||||||
For stats, and timezones, \fB\-\-replace\fR and \fB\-\-insert\-into\fR have the usual effects.
|
For stats, and timezones, \fB\-\-replace\fR and \fB\-\-insert\-ignore\fR have the usual effects.
|
||||||
.sp
|
.sp
|
||||||
Enabling specific options here will cause the relevant tables in the mysql database to be ignored when dumping the mysql database or \fB\-\-all\-databases\fR\&.
|
Enabling specific options here will cause the relevant tables in the mysql database to be ignored when dumping the mysql database or \fB\-\-all\-databases\fR\&.
|
||||||
.sp
|
.sp
|
||||||
|
@@ -223,16 +223,16 @@ disconnect c1;
|
|||||||
#
|
#
|
||||||
create or replace table t1 (a int);
|
create or replace table t1 (a int);
|
||||||
create or replace table t2 (b int);
|
create or replace table t2 (b int);
|
||||||
insert into t1 values(1<<30),(1<<29);
|
insert into t1 values(111111111),(-2147483648);
|
||||||
insert into t2 values(1),(2);
|
insert into t2 values(1),(2);
|
||||||
select t1.a as a1 from t1 as t1,t2 order by t2.b,t1.a;
|
select t1.a as a1 from t1 as t1,t2 order by t2.b,t1.a;
|
||||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
def test t1 t1 a a1 3 11 10 Y 32768 0 63
|
def test t1 t1 a a1 3 11 11 Y 32768 0 63
|
||||||
a1
|
a1
|
||||||
536870912
|
-2147483648
|
||||||
1073741824
|
111111111
|
||||||
536870912
|
-2147483648
|
||||||
1073741824
|
111111111
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
#
|
#
|
||||||
# End of 10.4 tests
|
# End of 10.4 tests
|
||||||
|
@@ -231,7 +231,7 @@ disconnect c1;
|
|||||||
--echo #
|
--echo #
|
||||||
create or replace table t1 (a int);
|
create or replace table t1 (a int);
|
||||||
create or replace table t2 (b int);
|
create or replace table t2 (b int);
|
||||||
insert into t1 values(1<<30),(1<<29);
|
insert into t1 values(111111111),(-2147483648);
|
||||||
insert into t2 values(1),(2);
|
insert into t2 values(1),(2);
|
||||||
--enable_metadata
|
--enable_metadata
|
||||||
select t1.a as a1 from t1 as t1,t2 order by t2.b,t1.a;
|
select t1.a as a1 from t1 as t1,t2 order by t2.b,t1.a;
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
set @save_use_stat_tables=@@global.use_stat_tables;
|
|
||||||
SET GLOBAL net_write_timeout = 900;
|
|
||||||
CREATE TABLE A (
|
|
||||||
pk INTEGER AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
fdate DATE
|
|
||||||
) ENGINE=MyISAM;
|
|
||||||
CREATE PROCEDURE p_analyze()
|
|
||||||
BEGIN
|
|
||||||
DECLARE attempts INTEGER DEFAULT 100;
|
|
||||||
wl_loop: WHILE attempts > 0 DO
|
|
||||||
ANALYZE TABLE A;
|
|
||||||
SET attempts = attempts - 1;
|
|
||||||
END WHILE wl_loop;
|
|
||||||
END |
|
|
||||||
CREATE FUNCTION rnd3() RETURNS INT
|
|
||||||
BEGIN
|
|
||||||
RETURN ROUND(3 * RAND() + 0.5);
|
|
||||||
END |
|
|
||||||
SET GLOBAL use_stat_tables = PREFERABLY;
|
|
||||||
connection default;
|
|
||||||
DROP TABLE A;
|
|
||||||
DROP PROCEDURE p_analyze;
|
|
||||||
DROP FUNCTION rnd3;
|
|
||||||
SET GLOBAL use_stat_tables = @save_use_stat_tables;
|
|
||||||
SET GLOBAL net_write_timeout = DEFAULT;
|
|
@@ -1,82 +0,0 @@
|
|||||||
--source include/not_valgrind.inc
|
|
||||||
--source include/no_protocol.inc
|
|
||||||
|
|
||||||
set @save_use_stat_tables=@@global.use_stat_tables;
|
|
||||||
|
|
||||||
SET GLOBAL net_write_timeout = 900;
|
|
||||||
|
|
||||||
CREATE TABLE A (
|
|
||||||
pk INTEGER AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
fdate DATE
|
|
||||||
) ENGINE=MyISAM;
|
|
||||||
|
|
||||||
--delimiter |
|
|
||||||
|
|
||||||
CREATE PROCEDURE p_analyze()
|
|
||||||
BEGIN
|
|
||||||
DECLARE attempts INTEGER DEFAULT 100;
|
|
||||||
wl_loop: WHILE attempts > 0 DO
|
|
||||||
ANALYZE TABLE A;
|
|
||||||
SET attempts = attempts - 1;
|
|
||||||
END WHILE wl_loop;
|
|
||||||
END |
|
|
||||||
|
|
||||||
CREATE FUNCTION rnd3() RETURNS INT
|
|
||||||
BEGIN
|
|
||||||
RETURN ROUND(3 * RAND() + 0.5);
|
|
||||||
END |
|
|
||||||
|
|
||||||
--delimiter ;
|
|
||||||
|
|
||||||
SET GLOBAL use_stat_tables = PREFERABLY;
|
|
||||||
|
|
||||||
--let $trial = 100
|
|
||||||
|
|
||||||
--disable_query_log
|
|
||||||
--disable_result_log
|
|
||||||
--disable_warnings
|
|
||||||
while ($trial)
|
|
||||||
{
|
|
||||||
|
|
||||||
--connect (con1,localhost,root,,)
|
|
||||||
--send CALL p_analyze()
|
|
||||||
|
|
||||||
--connect (con2,localhost,root,,)
|
|
||||||
--send CALL p_analyze()
|
|
||||||
|
|
||||||
--let $run = 100
|
|
||||||
|
|
||||||
while ($run)
|
|
||||||
{
|
|
||||||
--connect (con3,localhost,root,,)
|
|
||||||
|
|
||||||
let $query = `SELECT CASE rnd3()
|
|
||||||
WHEN 1 THEN 'INSERT INTO A (pk) VALUES (NULL)'
|
|
||||||
WHEN 2 THEN 'DELETE FROM A LIMIT 1'
|
|
||||||
ELSE 'UPDATE IGNORE A SET fdate = 2 LIMIT 1' END`;
|
|
||||||
--eval $query
|
|
||||||
--disconnect con3
|
|
||||||
--dec $run
|
|
||||||
}
|
|
||||||
|
|
||||||
--connection con2
|
|
||||||
--reap
|
|
||||||
--disconnect con2
|
|
||||||
--connection con1
|
|
||||||
--reap
|
|
||||||
--disconnect con1
|
|
||||||
|
|
||||||
--dec $trial
|
|
||||||
}
|
|
||||||
|
|
||||||
--enable_query_log
|
|
||||||
--enable_result_log
|
|
||||||
--enable_warnings
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
--connection default
|
|
||||||
DROP TABLE A;
|
|
||||||
DROP PROCEDURE p_analyze;
|
|
||||||
DROP FUNCTION rnd3;
|
|
||||||
SET GLOBAL use_stat_tables = @save_use_stat_tables;
|
|
||||||
SET GLOBAL net_write_timeout = DEFAULT;
|
|
@@ -19,7 +19,7 @@ innodb_system
|
|||||||
# Success!
|
# Success!
|
||||||
# Now turn off encryption and wait for threads to decrypt everything
|
# Now turn off encryption and wait for threads to decrypt everything
|
||||||
SET GLOBAL innodb_encrypt_tables = off;
|
SET GLOBAL innodb_encrypt_tables = off;
|
||||||
# Wait max 10 min for key encryption threads to encrypt all spaces
|
# Wait max 10 min for key encryption threads to decrypt all spaces
|
||||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0
|
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0
|
||||||
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
|
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
|
||||||
NAME
|
NAME
|
||||||
|
@@ -33,7 +33,7 @@ AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NA
|
|||||||
--echo # Now turn off encryption and wait for threads to decrypt everything
|
--echo # Now turn off encryption and wait for threads to decrypt everything
|
||||||
SET GLOBAL innodb_encrypt_tables = off;
|
SET GLOBAL innodb_encrypt_tables = off;
|
||||||
|
|
||||||
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
|
--echo # Wait max 10 min for key encryption threads to decrypt all spaces
|
||||||
--let $wait_timeout= 600
|
--let $wait_timeout= 600
|
||||||
--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
|
114
mysql-test/suite/galera/r/galera_schema.result
Normal file
114
mysql-test/suite/galera/r/galera_schema.result
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
connection node_2;
|
||||||
|
connection node_1;
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_cluster
|
||||||
|
(
|
||||||
|
cluster_uuid CHAR(36) PRIMARY KEY,
|
||||||
|
view_id BIGINT NOT NULL,
|
||||||
|
view_seqno BIGINT NOT NULL,
|
||||||
|
protocol_version INT NOT NULL,
|
||||||
|
capabilities INT NOT NULL
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_cluster_members
|
||||||
|
(
|
||||||
|
node_uuid CHAR(36) PRIMARY KEY,
|
||||||
|
cluster_uuid CHAR(36) NOT NULL,
|
||||||
|
node_name CHAR(32) NOT NULL,
|
||||||
|
node_incoming_address VARCHAR(256) NOT NULL
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_cluster_members_history
|
||||||
|
(
|
||||||
|
node_uuid CHAR(36) PRIMARY KEY,
|
||||||
|
cluster_uuid CHAR(36) NOT NULL,
|
||||||
|
last_view_id BIGINT NOT NULL,
|
||||||
|
last_view_seqno BIGINT NOT NULL,
|
||||||
|
node_name CHAR(32) NOT NULL,
|
||||||
|
node_incoming_address VARCHAR(256) NOT NULL
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_streaming_log
|
||||||
|
(
|
||||||
|
node_uuid CHAR(36),
|
||||||
|
trx_id BIGINT,
|
||||||
|
seqno BIGINT,
|
||||||
|
flags INT NOT NULL,
|
||||||
|
frag LONGBLOB NOT NULL,
|
||||||
|
PRIMARY KEY (node_uuid, trx_id, seqno)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
DELETE FROM wsrep_cluster;
|
||||||
|
DELETE FROM wsrep_cluster_members;
|
||||||
|
ALTER TABLE wsrep_cluster STATS_PERSISTENT=0;
|
||||||
|
ALTER TABLE wsrep_cluster_members STATS_PERSISTENT=0;
|
||||||
|
ALTER TABLE wsrep_cluster_members_history STATS_PERSISTENT=0;
|
||||||
|
ALTER TABLE wsrep_streaming_log STATS_PERSISTENT=0;
|
||||||
|
SHOW CREATE TABLE wsrep_cluster;
|
||||||
|
Table Create Table
|
||||||
|
wsrep_cluster CREATE TABLE `wsrep_cluster` (
|
||||||
|
`cluster_uuid` char(36) NOT NULL,
|
||||||
|
`view_id` bigint(20) NOT NULL,
|
||||||
|
`view_seqno` bigint(20) NOT NULL,
|
||||||
|
`protocol_version` int(11) NOT NULL,
|
||||||
|
`capabilities` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`cluster_uuid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
|
SHOW CREATE TABLE wsrep_cluster_members;
|
||||||
|
Table Create Table
|
||||||
|
wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
||||||
|
`node_uuid` char(36) NOT NULL,
|
||||||
|
`cluster_uuid` char(36) NOT NULL,
|
||||||
|
`node_name` char(32) NOT NULL,
|
||||||
|
`node_incoming_address` varchar(256) NOT NULL,
|
||||||
|
PRIMARY KEY (`node_uuid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
|
SHOW CREATE TABLE wsrep_cluster_members_history;
|
||||||
|
Table Create Table
|
||||||
|
wsrep_cluster_members_history CREATE TABLE `wsrep_cluster_members_history` (
|
||||||
|
`node_uuid` char(36) NOT NULL,
|
||||||
|
`cluster_uuid` char(36) NOT NULL,
|
||||||
|
`last_view_id` bigint(20) NOT NULL,
|
||||||
|
`last_view_seqno` bigint(20) NOT NULL,
|
||||||
|
`node_name` char(32) NOT NULL,
|
||||||
|
`node_incoming_address` varchar(256) NOT NULL,
|
||||||
|
PRIMARY KEY (`node_uuid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
|
SHOW CREATE TABLE wsrep_streaming_log;
|
||||||
|
Table Create Table
|
||||||
|
wsrep_streaming_log CREATE TABLE `wsrep_streaming_log` (
|
||||||
|
`node_uuid` char(36) NOT NULL,
|
||||||
|
`trx_id` bigint(20) NOT NULL,
|
||||||
|
`seqno` bigint(20) NOT NULL,
|
||||||
|
`flags` int(11) NOT NULL,
|
||||||
|
`frag` longblob NOT NULL,
|
||||||
|
PRIMARY KEY (`node_uuid`,`trx_id`,`seqno`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
|
SHOW CREATE TABLE mysql.wsrep_cluster;
|
||||||
|
Table Create Table
|
||||||
|
wsrep_cluster CREATE TABLE `wsrep_cluster` (
|
||||||
|
`cluster_uuid` char(36) NOT NULL,
|
||||||
|
`view_id` bigint(20) NOT NULL,
|
||||||
|
`view_seqno` bigint(20) NOT NULL,
|
||||||
|
`protocol_version` int(11) NOT NULL,
|
||||||
|
`capabilities` int(11) NOT NULL,
|
||||||
|
PRIMARY KEY (`cluster_uuid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
|
SHOW CREATE TABLE mysql.wsrep_cluster_members;
|
||||||
|
Table Create Table
|
||||||
|
wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
||||||
|
`node_uuid` char(36) NOT NULL,
|
||||||
|
`cluster_uuid` char(36) NOT NULL,
|
||||||
|
`node_name` char(32) NOT NULL,
|
||||||
|
`node_incoming_address` varchar(256) NOT NULL,
|
||||||
|
PRIMARY KEY (`node_uuid`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
|
SHOW CREATE TABLE mysql.wsrep_streaming_log;
|
||||||
|
Table Create Table
|
||||||
|
wsrep_streaming_log CREATE TABLE `wsrep_streaming_log` (
|
||||||
|
`node_uuid` char(36) NOT NULL,
|
||||||
|
`trx_id` bigint(20) NOT NULL,
|
||||||
|
`seqno` bigint(20) NOT NULL,
|
||||||
|
`flags` int(11) NOT NULL,
|
||||||
|
`frag` longblob NOT NULL,
|
||||||
|
PRIMARY KEY (`node_uuid`,`trx_id`,`seqno`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
|
DROP TABLE wsrep_cluster;
|
||||||
|
DROP TABLE wsrep_cluster_members;
|
||||||
|
DROP TABLE wsrep_cluster_members_history;
|
||||||
|
DROP TABLE wsrep_streaming_log;
|
61
mysql-test/suite/galera/t/galera_schema.test
Normal file
61
mysql-test/suite/galera/t/galera_schema.test
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
--source include/galera_cluster.inc
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_cluster
|
||||||
|
(
|
||||||
|
cluster_uuid CHAR(36) PRIMARY KEY,
|
||||||
|
view_id BIGINT NOT NULL,
|
||||||
|
view_seqno BIGINT NOT NULL,
|
||||||
|
protocol_version INT NOT NULL,
|
||||||
|
capabilities INT NOT NULL
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_cluster_members
|
||||||
|
(
|
||||||
|
node_uuid CHAR(36) PRIMARY KEY,
|
||||||
|
cluster_uuid CHAR(36) NOT NULL,
|
||||||
|
node_name CHAR(32) NOT NULL,
|
||||||
|
node_incoming_address VARCHAR(256) NOT NULL
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_cluster_members_history
|
||||||
|
(
|
||||||
|
node_uuid CHAR(36) PRIMARY KEY,
|
||||||
|
cluster_uuid CHAR(36) NOT NULL,
|
||||||
|
last_view_id BIGINT NOT NULL,
|
||||||
|
last_view_seqno BIGINT NOT NULL,
|
||||||
|
node_name CHAR(32) NOT NULL,
|
||||||
|
node_incoming_address VARCHAR(256) NOT NULL
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS wsrep_streaming_log
|
||||||
|
(
|
||||||
|
node_uuid CHAR(36),
|
||||||
|
trx_id BIGINT,
|
||||||
|
seqno BIGINT,
|
||||||
|
flags INT NOT NULL,
|
||||||
|
frag LONGBLOB NOT NULL,
|
||||||
|
PRIMARY KEY (node_uuid, trx_id, seqno)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
DELETE FROM wsrep_cluster;
|
||||||
|
DELETE FROM wsrep_cluster_members;
|
||||||
|
|
||||||
|
ALTER TABLE wsrep_cluster STATS_PERSISTENT=0;
|
||||||
|
ALTER TABLE wsrep_cluster_members STATS_PERSISTENT=0;
|
||||||
|
ALTER TABLE wsrep_cluster_members_history STATS_PERSISTENT=0;
|
||||||
|
ALTER TABLE wsrep_streaming_log STATS_PERSISTENT=0;
|
||||||
|
|
||||||
|
SHOW CREATE TABLE wsrep_cluster;
|
||||||
|
SHOW CREATE TABLE wsrep_cluster_members;
|
||||||
|
SHOW CREATE TABLE wsrep_cluster_members_history;
|
||||||
|
SHOW CREATE TABLE wsrep_streaming_log;
|
||||||
|
|
||||||
|
SHOW CREATE TABLE mysql.wsrep_cluster;
|
||||||
|
SHOW CREATE TABLE mysql.wsrep_cluster_members;
|
||||||
|
#SHOW CREATE TABLE mysql.wsrep_cluster_members_history;
|
||||||
|
SHOW CREATE TABLE mysql.wsrep_streaming_log;
|
||||||
|
|
||||||
|
DROP TABLE wsrep_cluster;
|
||||||
|
DROP TABLE wsrep_cluster_members;
|
||||||
|
DROP TABLE wsrep_cluster_members_history;
|
||||||
|
DROP TABLE wsrep_streaming_log;
|
@@ -14,7 +14,7 @@ wsrep_cluster CREATE TABLE `wsrep_cluster` (
|
|||||||
`protocol_version` int(11) NOT NULL,
|
`protocol_version` int(11) NOT NULL,
|
||||||
`capabilities` int(11) NOT NULL,
|
`capabilities` int(11) NOT NULL,
|
||||||
PRIMARY KEY (`cluster_uuid`)
|
PRIMARY KEY (`cluster_uuid`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
SHOW CREATE TABLE mysql.wsrep_cluster_members;
|
SHOW CREATE TABLE mysql.wsrep_cluster_members;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
||||||
@@ -23,7 +23,7 @@ wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
|||||||
`node_name` char(32) NOT NULL,
|
`node_name` char(32) NOT NULL,
|
||||||
`node_incoming_address` varchar(256) NOT NULL,
|
`node_incoming_address` varchar(256) NOT NULL,
|
||||||
PRIMARY KEY (`node_uuid`)
|
PRIMARY KEY (`node_uuid`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_cluster;
|
SELECT COUNT(*) AS EXPECT_1 FROM mysql.wsrep_cluster;
|
||||||
EXPECT_1
|
EXPECT_1
|
||||||
1
|
1
|
||||||
|
@@ -14,7 +14,7 @@ wsrep_cluster CREATE TABLE `wsrep_cluster` (
|
|||||||
`protocol_version` int(11) NOT NULL,
|
`protocol_version` int(11) NOT NULL,
|
||||||
`capabilities` int(11) NOT NULL,
|
`capabilities` int(11) NOT NULL,
|
||||||
PRIMARY KEY (`cluster_uuid`)
|
PRIMARY KEY (`cluster_uuid`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
SHOW CREATE TABLE mysql.wsrep_cluster_members;
|
SHOW CREATE TABLE mysql.wsrep_cluster_members;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
||||||
@@ -23,7 +23,7 @@ wsrep_cluster_members CREATE TABLE `wsrep_cluster_members` (
|
|||||||
`node_name` char(32) NOT NULL,
|
`node_name` char(32) NOT NULL,
|
||||||
`node_incoming_address` varchar(256) NOT NULL,
|
`node_incoming_address` varchar(256) NOT NULL,
|
||||||
PRIMARY KEY (`node_uuid`)
|
PRIMARY KEY (`node_uuid`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=0
|
||||||
SELECT @@sql_safe_updates;
|
SELECT @@sql_safe_updates;
|
||||||
@@sql_safe_updates
|
@@sql_safe_updates
|
||||||
1
|
1
|
||||||
|
@@ -2,7 +2,6 @@ connection node_2;
|
|||||||
connection node_1;
|
connection node_1;
|
||||||
connection node_1;
|
connection node_1;
|
||||||
CREATE TABLE t1 (f1 INTEGER, f2 VARCHAR(10)) ENGINE=InnoDB;
|
CREATE TABLE t1 (f1 INTEGER, f2 VARCHAR(10)) ENGINE=InnoDB;
|
||||||
CREATE TABLE t2 (f1 INTEGER);
|
|
||||||
SET SESSION wsrep_trx_fragment_size = 1;
|
SET SESSION wsrep_trx_fragment_size = 1;
|
||||||
SET AUTOCOMMIT=OFF;
|
SET AUTOCOMMIT=OFF;
|
||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
@@ -16,9 +15,10 @@ connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
|||||||
INSERT INTO t1 VALUES (2);
|
INSERT INTO t1 VALUES (2);
|
||||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||||
connection node_1;
|
connection node_1;
|
||||||
SELECT * FROM mysql.wsrep_streaming_log;
|
SELECT COUNT(*) FROM mysql.wsrep_streaming_log;
|
||||||
node_uuid trx_id seqno flags frag
|
COUNT(*)
|
||||||
|
0
|
||||||
connection node_2;
|
connection node_2;
|
||||||
SELECT * FROM mysql.wsrep_streaming_log;
|
SELECT COUNT(*) FROM mysql.wsrep_streaming_log;
|
||||||
node_uuid trx_id seqno flags frag
|
COUNT(*)
|
||||||
DROP TABLE t2;
|
0
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
--source include/galera_cluster.inc
|
--source include/galera_cluster.inc
|
||||||
--source include/have_innodb.inc
|
|
||||||
|
|
||||||
--connection node_1
|
--connection node_1
|
||||||
CREATE TABLE t1 (f1 INTEGER, f2 VARCHAR(10)) ENGINE=InnoDB;
|
CREATE TABLE t1 (f1 INTEGER, f2 VARCHAR(10)) ENGINE=InnoDB;
|
||||||
CREATE TABLE t2 (f1 INTEGER);
|
|
||||||
|
|
||||||
SET SESSION wsrep_trx_fragment_size = 1;
|
SET SESSION wsrep_trx_fragment_size = 1;
|
||||||
SET AUTOCOMMIT=OFF;
|
SET AUTOCOMMIT=OFF;
|
||||||
@@ -25,11 +23,9 @@ INSERT INTO t1 VALUES (2);
|
|||||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
|
--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
SELECT * FROM mysql.wsrep_streaming_log;
|
SELECT COUNT(*) FROM mysql.wsrep_streaming_log;
|
||||||
|
|
||||||
--connection node_2
|
--connection node_2
|
||||||
--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
|
--let $wait_condition = SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
SELECT * FROM mysql.wsrep_streaming_log;
|
SELECT COUNT(*) FROM mysql.wsrep_streaming_log;
|
||||||
|
|
||||||
DROP TABLE t2;
|
|
||||||
|
@@ -1,25 +1,32 @@
|
|||||||
select @@global.innodb_stats_persistent;
|
SET GLOBAL innodb_defragment_stats_accuracy = 20;
|
||||||
@@global.innodb_stats_persistent
|
DELETE FROM mysql.innodb_index_stats;
|
||||||
1
|
# Create table.
|
||||||
set global innodb_defragment_stats_accuracy = 20;
|
CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256),
|
||||||
CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(256), KEY SECOND(a, b))
|
KEY SECOND(a, b)) ENGINE=INNODB STATS_PERSISTENT=0;
|
||||||
ENGINE=INNODB;
|
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
|
||||||
# Not enough page splits to trigger persistent stats write yet.
|
# Not enough page splits to trigger persistent stats write yet.
|
||||||
select * from mysql.innodb_index_stats where table_name='t1'
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
and stat_name in ('n_page_split','n_pages_freed,n_leaf_pages_defrag');
|
count(stat_value) = 0
|
||||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
1
|
||||||
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
|
count(stat_value) = 0
|
||||||
|
1
|
||||||
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
count(stat_value) = 0
|
||||||
|
1
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
|
||||||
# Persistent stats recorded.
|
# Persistent stats recorded.
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
count(stat_value) = 0
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
1
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
# Delete some rows.
|
# Delete some rows.
|
||||||
|
BEGIN;
|
||||||
delete from t1 where a between 100 * 20 and 100 * 20 + 30;
|
delete from t1 where a between 100 * 20 and 100 * 20 + 30;
|
||||||
delete from t1 where a between 100 * 19 and 100 * 19 + 30;
|
delete from t1 where a between 100 * 19 and 100 * 19 + 30;
|
||||||
delete from t1 where a between 100 * 18 and 100 * 18 + 30;
|
delete from t1 where a between 100 * 18 and 100 * 18 + 30;
|
||||||
@@ -40,82 +47,93 @@ delete from t1 where a between 100 * 4 and 100 * 4 + 30;
|
|||||||
delete from t1 where a between 100 * 3 and 100 * 3 + 30;
|
delete from t1 where a between 100 * 3 and 100 * 3 + 30;
|
||||||
delete from t1 where a between 100 * 2 and 100 * 2 + 30;
|
delete from t1 where a between 100 * 2 and 100 * 2 + 30;
|
||||||
delete from t1 where a between 100 * 1 and 100 * 1 + 30;
|
delete from t1 where a between 100 * 1 and 100 * 1 + 30;
|
||||||
# restart
|
COMMIT;
|
||||||
# Server Restarted
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
# Confirm persistent stats still there after restart.
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
count(stat_value) = 0
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
1
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 optimize status OK
|
test.t1 optimize status OK
|
||||||
select sleep(2);
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
sleep(2)
|
|
||||||
0
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
set global innodb_defragment_stats_accuracy = 40;
|
set global innodb_defragment_stats_accuracy = 40;
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_2049_to_4096;
|
INSERT INTO t1 (b) SELECT b from t1;
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_4097_to_8192;
|
INSERT INTO t1 (b) SELECT b from t1;
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
# Table rename should cause stats rename.
|
# Table rename should cause stats rename.
|
||||||
rename table t1 to t2;
|
rename table t1 to t2;
|
||||||
select * from mysql.innodb_index_stats where table_name = 't1';
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
count(stat_value) = 0
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
1
|
||||||
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
|
count(stat_value) = 0
|
||||||
|
1
|
||||||
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
count(stat_value) = 0
|
||||||
|
1
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
# Drop index should cause stats drop.
|
# Drop index should cause stats drop, but will not.
|
||||||
drop index SECOND on t2;
|
drop index SECOND on t2;
|
||||||
select * from mysql.innodb_index_stats where table_name = 't2' and index_name = 'SECOND';
|
SELECT stat_name, stat_value>0 FROM mysql.innodb_index_stats
|
||||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
WHERE table_name like '%t2%' AND index_name='SECOND';
|
||||||
|
stat_name stat_value>0
|
||||||
|
#
|
||||||
|
# MDEV-26636: Statistics must not be written for temporary tables
|
||||||
|
#
|
||||||
|
SET GLOBAL innodb_defragment_stats_accuracy = 1;
|
||||||
|
CREATE TEMPORARY TABLE t (a INT PRIMARY KEY, c CHAR(255) NOT NULL)
|
||||||
|
ENGINE=InnoDB;
|
||||||
|
INSERT INTO t SELECT seq, '' FROM seq_1_to_100;
|
||||||
# restart
|
# restart
|
||||||
Server Restarted
|
SELECT * FROM mysql.innodb_index_stats where table_name like '%t1%';
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
count(stat_value) > 0
|
SELECT table_name, index_name, stat_name, stat_value>0
|
||||||
1
|
FROM mysql.innodb_index_stats;
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
table_name index_name stat_name stat_value>0
|
||||||
count(stat_value) > 0
|
t2 PRIMARY n_leaf_pages_defrag 1
|
||||||
1
|
t2 PRIMARY n_leaf_pages_reserved 1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
t2 PRIMARY n_page_split 1
|
||||||
count(stat_value) > 0
|
t2 PRIMARY n_pages_freed 0
|
||||||
1
|
# Clean up
|
||||||
# Clean up
|
ALTER TABLE t2 STATS_PERSISTENT=1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
select * from mysql.innodb_index_stats where table_name = 't2';
|
SELECT * FROM mysql.innodb_index_stats;
|
||||||
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
|
@@ -1,34 +1,13 @@
|
|||||||
SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
|
||||||
SET @save_truncate = @@GLOBAL.innodb_undo_log_truncate;
|
|
||||||
SET GLOBAL innodb_undo_log_truncate = 0;
|
SET GLOBAL innodb_undo_log_truncate = 0;
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||||
SET @trunc_start=
|
|
||||||
(SELECT variable_value FROM information_schema.global_status
|
|
||||||
WHERE variable_name = 'innodb_undo_truncations');
|
|
||||||
create table t1(keyc int primary key, c char(100)) engine = innodb;
|
create table t1(keyc int primary key, c char(100)) engine = innodb;
|
||||||
create table t2(keyc int primary key, c char(100)) engine = innodb;
|
create table t2(keyc int primary key, c char(100)) engine = innodb;
|
||||||
CREATE PROCEDURE populate_t1()
|
|
||||||
BEGIN
|
|
||||||
DECLARE i INT DEFAULT 1;
|
|
||||||
while (i <= 20000) DO
|
|
||||||
insert into t1 values (i, 'a');
|
|
||||||
SET i = i + 1;
|
|
||||||
END WHILE;
|
|
||||||
END |
|
|
||||||
CREATE PROCEDURE populate_t2()
|
|
||||||
BEGIN
|
|
||||||
DECLARE i INT DEFAULT 1;
|
|
||||||
while (i <= 20000) DO
|
|
||||||
insert into t2 values (i, 'a');
|
|
||||||
SET i = i + 1;
|
|
||||||
END WHILE;
|
|
||||||
END |
|
|
||||||
connect con1,localhost,root,,;
|
connect con1,localhost,root,,;
|
||||||
begin;
|
begin;
|
||||||
call populate_t1();
|
insert into t1 select seq,'a' from seq_1_to_20000;
|
||||||
connect con2,localhost,root,,;
|
connect con2,localhost,root,,;
|
||||||
begin;
|
begin;
|
||||||
call populate_t2();
|
insert into t2 select seq,'a' from seq_1_to_20000;
|
||||||
connection con1;
|
connection con1;
|
||||||
update t1 set c = 'mysql';
|
update t1 set c = 'mysql';
|
||||||
connection con2;
|
connection con2;
|
||||||
@@ -49,9 +28,6 @@ connection con2;
|
|||||||
commit;
|
commit;
|
||||||
disconnect con2;
|
disconnect con2;
|
||||||
connection default;
|
connection default;
|
||||||
|
set global innodb_fast_shutdown=0;
|
||||||
|
# restart
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
drop PROCEDURE populate_t1;
|
|
||||||
drop PROCEDURE populate_t2;
|
|
||||||
InnoDB 0 transactions not purged
|
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
|
||||||
SET GLOBAL innodb_undo_log_truncate = @save_truncate;
|
|
||||||
|
@@ -1,28 +1,32 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
--source include/have_sequence.inc
|
|
||||||
--source include/big_test.inc
|
|
||||||
--source include/not_valgrind.inc
|
--source include/not_valgrind.inc
|
||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
select @@global.innodb_stats_persistent;
|
SET GLOBAL innodb_defragment_stats_accuracy = 20;
|
||||||
set global innodb_defragment_stats_accuracy = 20;
|
|
||||||
|
DELETE FROM mysql.innodb_index_stats;
|
||||||
|
|
||||||
|
--echo # Create table.
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256),
|
||||||
|
KEY SECOND(a, b)) ENGINE=INNODB STATS_PERSISTENT=0;
|
||||||
|
|
||||||
CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(256), KEY SECOND(a, b))
|
|
||||||
ENGINE=INNODB;
|
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
|
||||||
|
|
||||||
--echo # Not enough page splits to trigger persistent stats write yet.
|
--echo # Not enough page splits to trigger persistent stats write yet.
|
||||||
select * from mysql.innodb_index_stats where table_name='t1'
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
and stat_name in ('n_page_split','n_pages_freed,n_leaf_pages_defrag');
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
|
||||||
|
|
||||||
--echo # Persistent stats recorded.
|
--echo # Persistent stats recorded.
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
--echo # Delete some rows.
|
--echo # Delete some rows.
|
||||||
|
BEGIN;
|
||||||
let $num_delete = 20;
|
let $num_delete = 20;
|
||||||
while ($num_delete)
|
while ($num_delete)
|
||||||
{
|
{
|
||||||
@@ -30,58 +34,71 @@ while ($num_delete)
|
|||||||
eval delete from t1 where a between $j and $j + 30;
|
eval delete from t1 where a between $j and $j + 30;
|
||||||
dec $num_delete;
|
dec $num_delete;
|
||||||
}
|
}
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
--source include/restart_mysqld.inc
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
--echo # Server Restarted
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
--echo # Confirm persistent stats still there after restart.
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
|
||||||
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
|
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
select sleep(2);
|
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
set global innodb_defragment_stats_accuracy = 40;
|
set global innodb_defragment_stats_accuracy = 40;
|
||||||
|
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_2049_to_4096;
|
INSERT INTO t1 (b) SELECT b from t1;
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_4097_to_8192;
|
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
INSERT INTO t1 (b) SELECT b from t1;
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
|
|
||||||
--echo # Table rename should cause stats rename.
|
--echo # Table rename should cause stats rename.
|
||||||
rename table t1 to t2;
|
rename table t1 to t2;
|
||||||
select * from mysql.innodb_index_stats where table_name = 't1';
|
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
--echo # Drop index should cause stats drop.
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
|
--echo # Drop index should cause stats drop, but will not.
|
||||||
drop index SECOND on t2;
|
drop index SECOND on t2;
|
||||||
|
|
||||||
select * from mysql.innodb_index_stats where table_name = 't2' and index_name = 'SECOND';
|
--sorted_result
|
||||||
|
SELECT stat_name, stat_value>0 FROM mysql.innodb_index_stats
|
||||||
|
WHERE table_name like '%t2%' AND index_name='SECOND';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-26636: Statistics must not be written for temporary tables
|
||||||
|
--echo #
|
||||||
|
SET GLOBAL innodb_defragment_stats_accuracy = 1;
|
||||||
|
CREATE TEMPORARY TABLE t (a INT PRIMARY KEY, c CHAR(255) NOT NULL)
|
||||||
|
ENGINE=InnoDB;
|
||||||
|
INSERT INTO t SELECT seq, '' FROM seq_1_to_100;
|
||||||
|
|
||||||
--source include/restart_mysqld.inc
|
--source include/restart_mysqld.inc
|
||||||
--echo Server Restarted
|
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
SELECT * FROM mysql.innodb_index_stats where table_name like '%t1%';
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
--sorted_result
|
||||||
|
SELECT table_name, index_name, stat_name, stat_value>0
|
||||||
|
FROM mysql.innodb_index_stats;
|
||||||
|
|
||||||
--echo # Clean up
|
--echo # Clean up
|
||||||
|
# DROP TABLE will not touch persistent statistics if the table has none!
|
||||||
|
ALTER TABLE t2 STATS_PERSISTENT=1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
select * from mysql.innodb_index_stats where table_name = 't2';
|
SELECT * FROM mysql.innodb_index_stats;
|
||||||
|
1
mysql-test/suite/innodb/t/undo_truncate.opt
Normal file
1
mysql-test/suite/innodb/t/undo_truncate.opt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--innodb-buffer-pool-size=24M
|
@@ -1,16 +1,16 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
--source include/innodb_page_size.inc
|
--source include/innodb_page_size.inc
|
||||||
--source include/have_undo_tablespaces.inc
|
--source include/have_undo_tablespaces.inc
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
call mtr.add_suppression("InnoDB: Difficult to find free blocks in the buffer pool");
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
|
||||||
SET @save_truncate = @@GLOBAL.innodb_undo_log_truncate;
|
|
||||||
SET GLOBAL innodb_undo_log_truncate = 0;
|
SET GLOBAL innodb_undo_log_truncate = 0;
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||||
|
|
||||||
SET @trunc_start=
|
|
||||||
(SELECT variable_value FROM information_schema.global_status
|
|
||||||
WHERE variable_name = 'innodb_undo_truncations');
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Perform DML action using multiple clients and multiple undo tablespace.
|
# Perform DML action using multiple clients and multiple undo tablespace.
|
||||||
@@ -19,37 +19,14 @@ WHERE variable_name = 'innodb_undo_truncations');
|
|||||||
create table t1(keyc int primary key, c char(100)) engine = innodb;
|
create table t1(keyc int primary key, c char(100)) engine = innodb;
|
||||||
create table t2(keyc int primary key, c char(100)) engine = innodb;
|
create table t2(keyc int primary key, c char(100)) engine = innodb;
|
||||||
#
|
#
|
||||||
delimiter |;
|
|
||||||
CREATE PROCEDURE populate_t1()
|
|
||||||
BEGIN
|
|
||||||
DECLARE i INT DEFAULT 1;
|
|
||||||
while (i <= 20000) DO
|
|
||||||
insert into t1 values (i, 'a');
|
|
||||||
SET i = i + 1;
|
|
||||||
END WHILE;
|
|
||||||
END |
|
|
||||||
delimiter ;|
|
|
||||||
#
|
|
||||||
delimiter |;
|
|
||||||
CREATE PROCEDURE populate_t2()
|
|
||||||
BEGIN
|
|
||||||
DECLARE i INT DEFAULT 1;
|
|
||||||
while (i <= 20000) DO
|
|
||||||
insert into t2 values (i, 'a');
|
|
||||||
SET i = i + 1;
|
|
||||||
END WHILE;
|
|
||||||
END |
|
|
||||||
delimiter ;|
|
|
||||||
#
|
|
||||||
#
|
|
||||||
let DATADIR = `select @@datadir`;
|
let DATADIR = `select @@datadir`;
|
||||||
connect (con1,localhost,root,,);
|
connect (con1,localhost,root,,);
|
||||||
begin;
|
begin;
|
||||||
send call populate_t1();
|
send insert into t1 select seq,'a' from seq_1_to_20000;
|
||||||
|
|
||||||
connect (con2,localhost,root,,);
|
connect (con2,localhost,root,,);
|
||||||
begin;
|
begin;
|
||||||
send call populate_t2();
|
send insert into t2 select seq,'a' from seq_1_to_20000;
|
||||||
|
|
||||||
connection con1; reap; send update t1 set c = 'mysql';
|
connection con1; reap; send update t1 set c = 'mysql';
|
||||||
connection con2; reap; send update t2 set c = 'mysql';
|
connection con2; reap; send update t2 set c = 'mysql';
|
||||||
@@ -59,62 +36,25 @@ connection con1; reap; send delete from t1;
|
|||||||
connection con2; reap; delete from t2;
|
connection con2; reap; delete from t2;
|
||||||
connection con1; reap;
|
connection con1; reap;
|
||||||
|
|
||||||
let CHECKFILE = $MYSQL_TMP_DIR/check.txt;
|
|
||||||
perl;
|
|
||||||
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
|
|
||||||
= stat("$ENV{DATADIR}/undo001");
|
|
||||||
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
|
|
||||||
= stat("$ENV{DATADIR}/undo002");
|
|
||||||
open(OUT, ">$ENV{CHECKFILE}") || die;
|
|
||||||
print OUT "let \$size1='$size1,$size2';\n";
|
|
||||||
close(OUT);
|
|
||||||
EOF
|
|
||||||
|
|
||||||
SET GLOBAL innodb_undo_log_truncate = 1;
|
SET GLOBAL innodb_undo_log_truncate = 1;
|
||||||
commit; disconnect con1;
|
commit; disconnect con1;
|
||||||
connection con2; commit; disconnect con2;
|
connection con2; commit; disconnect con2;
|
||||||
|
|
||||||
connection default;
|
connection default;
|
||||||
|
|
||||||
|
--replace_regex /.*Trx id counter ([0-9]+).*/\1/
|
||||||
|
let $trx_before= `SHOW ENGINE INNODB STATUS`;
|
||||||
|
let $trx_before= `select substr('$trx_before',9)+2`;
|
||||||
|
|
||||||
|
set global innodb_fast_shutdown=0;
|
||||||
|
--source include/restart_mysqld.inc
|
||||||
|
--replace_regex /.*Trx id counter ([0-9]+).*/\1/
|
||||||
|
let $trx_after= `SHOW ENGINE INNODB STATUS`;
|
||||||
|
let $trx_after= `select substr('$trx_after',9)`;
|
||||||
|
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
drop PROCEDURE populate_t1;
|
|
||||||
drop PROCEDURE populate_t2;
|
|
||||||
|
|
||||||
--source include/wait_all_purged.inc
|
if ($trx_before != $trx_after)
|
||||||
|
|
||||||
# Truncation will normally not occur with innodb_page_size=64k,
|
|
||||||
# and occasionally not with innodb_page_size=32k,
|
|
||||||
# because the undo log will not grow enough.
|
|
||||||
# TODO: For some reason this does not occur on 4k either!
|
|
||||||
if (`select @@innodb_page_size IN (8192,16384)`)
|
|
||||||
{
|
{
|
||||||
let $wait_condition = (SELECT variable_value!=@trunc_start
|
echo Transaction sequence mismatch: $trx_before != $trx_after;
|
||||||
FROM information_schema.global_status
|
|
||||||
WHERE variable_name = 'innodb_undo_truncations');
|
|
||||||
source include/wait_condition.inc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--source $CHECKFILE
|
|
||||||
perl;
|
|
||||||
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
|
|
||||||
= stat("$ENV{DATADIR}/undo001");
|
|
||||||
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
|
|
||||||
= stat("$ENV{DATADIR}/undo002");
|
|
||||||
open(OUT, ">$ENV{CHECKFILE}") || die;
|
|
||||||
print OUT "let \$size2='$size1,$size2';\n";
|
|
||||||
close(OUT);
|
|
||||||
EOF
|
|
||||||
|
|
||||||
--source $CHECKFILE
|
|
||||||
--remove_file $CHECKFILE
|
|
||||||
|
|
||||||
if ($size1 == $size2)
|
|
||||||
{
|
|
||||||
# This fails for innodb_page_size=64k, occasionally also for 32k.
|
|
||||||
if (`select @@innodb_page_size IN (8192,16384)`)
|
|
||||||
{
|
|
||||||
echo Truncation did not happen: $size1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
|
||||||
SET GLOBAL innodb_undo_log_truncate = @save_truncate;
|
|
||||||
|
@@ -949,8 +949,10 @@ then
|
|||||||
tmpdir=$(parse_cnf "$encgroups" 'tmpdir')
|
tmpdir=$(parse_cnf "$encgroups" 'tmpdir')
|
||||||
if [ -z "$tmpdir" ]; then
|
if [ -z "$tmpdir" ]; then
|
||||||
xtmpdir="$(mktemp -d)"
|
xtmpdir="$(mktemp -d)"
|
||||||
else
|
elif [ "$OS" = 'Linux' ]; then
|
||||||
xtmpdir=$(mktemp '-d' "--tmpdir=$tmpdir")
|
xtmpdir=$(mktemp '-d' "--tmpdir=$tmpdir")
|
||||||
|
else
|
||||||
|
xtmpdir=$(TMPDIR="$tmpdir"; mktemp '-d')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
wsrep_log_info "Using '$xtmpdir' as mariabackup temporary directory"
|
wsrep_log_info "Using '$xtmpdir' as mariabackup temporary directory"
|
||||||
|
@@ -725,8 +725,10 @@ EOF
|
|||||||
tmpdir=$(parse_cnf '--mysqld|sst' 'tmpdir')
|
tmpdir=$(parse_cnf '--mysqld|sst' 'tmpdir')
|
||||||
if [ -z "$tmpdir" ]; then
|
if [ -z "$tmpdir" ]; then
|
||||||
tmpfile="$(mktemp)"
|
tmpfile="$(mktemp)"
|
||||||
else
|
elif [ "$OS" = 'Linux' ]; then
|
||||||
tmpfile=$(mktemp "--tmpdir=$tmpdir")
|
tmpfile=$(mktemp "--tmpdir=$tmpdir")
|
||||||
|
else
|
||||||
|
tmpfile=$(TMPDIR="$tmpdir"; mktemp '-d')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
wsrep_log_info "Extracting binlog files:"
|
wsrep_log_info "Extracting binlog files:"
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# Copyright (c) 2006, 2014, Oracle and/or its affiliates.
|
# Copyright (c) 2006, 2014, Oracle and/or its affiliates.
|
||||||
# Copyright (c) 2010, 2020, MariaDB Corporation.
|
# Copyright (c) 2010, 2021, MariaDB Corporation.
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -65,6 +65,8 @@ ADD_CUSTOM_COMMAND(
|
|||||||
DEPENDS gen_lex_token
|
DEPENDS gen_lex_token
|
||||||
)
|
)
|
||||||
|
|
||||||
|
FIND_PACKAGE(BISON 2.4)
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(
|
ADD_CUSTOM_COMMAND(
|
||||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yy_mariadb.yy
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yy_mariadb.yy
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/yy_oracle.yy
|
${CMAKE_CURRENT_BINARY_DIR}/yy_oracle.yy
|
||||||
@@ -72,6 +74,7 @@ ADD_CUSTOM_COMMAND(
|
|||||||
"-DOUT1=${CMAKE_CURRENT_BINARY_DIR}/yy_oracle.yy"
|
"-DOUT1=${CMAKE_CURRENT_BINARY_DIR}/yy_oracle.yy"
|
||||||
"-DOUT2=${CMAKE_CURRENT_BINARY_DIR}/yy_mariadb.yy"
|
"-DOUT2=${CMAKE_CURRENT_BINARY_DIR}/yy_mariadb.yy"
|
||||||
"-DIN=${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.yy"
|
"-DIN=${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.yy"
|
||||||
|
"-DBISON_VERSION=${BISON_VERSION}"
|
||||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/gen_yy_files.cmake
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/gen_yy_files.cmake
|
||||||
COMMENT "Building yy_mariadb.yy and yy_oracle.yy from sql_yacc.yy"
|
COMMENT "Building yy_mariadb.yy and yy_oracle.yy from sql_yacc.yy"
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.yy
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/sql_yacc.yy
|
||||||
@@ -325,9 +328,6 @@ IF(WITH_MYSQLD_LDFLAGS)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
FIND_PACKAGE(BISON 2.4)
|
|
||||||
|
|
||||||
|
|
||||||
# Handle out-of-source build from source package with possibly broken
|
# Handle out-of-source build from source package with possibly broken
|
||||||
# bison. Copy bison output to from source to build directory, if not already
|
# bison. Copy bison output to from source to build directory, if not already
|
||||||
# there
|
# there
|
||||||
|
@@ -5,6 +5,9 @@ file(READ "${IN}" data)
|
|||||||
file(WRITE "${OUT1}" "")
|
file(WRITE "${OUT1}" "")
|
||||||
file(WRITE "${OUT2}" "")
|
file(WRITE "${OUT2}" "")
|
||||||
set(where 0)
|
set(where 0)
|
||||||
|
if(NOT(BISON_VERSION VERSION_LESS "3.0.0"))
|
||||||
|
string(REPLACE "\n%pure-parser" "\n%define api.pure" data "${data}")
|
||||||
|
endif()
|
||||||
string(REGEX REPLACE "/\\* sql_yacc\\.yy \\*/" "/* DON'T EDIT THIS FILE. IT'S GENERATED. EDIT sql_yacc.yy INSTEAD */" data "${data}")
|
string(REGEX REPLACE "/\\* sql_yacc\\.yy \\*/" "/* DON'T EDIT THIS FILE. IT'S GENERATED. EDIT sql_yacc.yy INSTEAD */" data "${data}")
|
||||||
while(NOT data STREQUAL "")
|
while(NOT data STREQUAL "")
|
||||||
string(REGEX MATCH "^(%[ie][^\n]*\n)|((%[^ie\n]|[^%\n])[^\n]*\n)+|\n+" line "${data}")
|
string(REGEX MATCH "^(%[ie][^\n]*\n)|((%[^ie\n]|[^%\n])[^\n]*\n)+|\n+" line "${data}")
|
||||||
|
@@ -4928,6 +4928,9 @@ MYSQL_THD create_background_thd()
|
|||||||
thd->set_command(COM_DAEMON);
|
thd->set_command(COM_DAEMON);
|
||||||
thd->system_thread= SYSTEM_THREAD_GENERIC;
|
thd->system_thread= SYSTEM_THREAD_GENERIC;
|
||||||
thd->security_ctx->host_or_ip= "";
|
thd->security_ctx->host_or_ip= "";
|
||||||
|
thd->real_id= 0;
|
||||||
|
thd->thread_id= 0;
|
||||||
|
thd->query_id= 0;
|
||||||
return thd;
|
return thd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -631,14 +631,18 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
if (!table->check_virtual_columns_marked_for_read())
|
if (!table->check_virtual_columns_marked_for_read())
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("Trying direct delete"));
|
DBUG_PRINT("info", ("Trying direct delete"));
|
||||||
if (select && select->cond &&
|
bool use_direct_delete= !select || !select->cond;
|
||||||
(select->cond->used_tables() == table->map))
|
if (!use_direct_delete &&
|
||||||
|
(select->cond->used_tables() & ~RAND_TABLE_BIT) == table->map)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!table->file->pushed_cond);
|
DBUG_ASSERT(!table->file->pushed_cond);
|
||||||
if (!table->file->cond_push(select->cond))
|
if (!table->file->cond_push(select->cond))
|
||||||
|
{
|
||||||
|
use_direct_delete= TRUE;
|
||||||
table->file->pushed_cond= select->cond;
|
table->file->pushed_cond= select->cond;
|
||||||
}
|
}
|
||||||
if (!table->file->direct_delete_rows_init())
|
}
|
||||||
|
if (use_direct_delete && !table->file->direct_delete_rows_init())
|
||||||
{
|
{
|
||||||
/* Direct deleting is supported */
|
/* Direct deleting is supported */
|
||||||
DBUG_PRINT("info", ("Using direct delete"));
|
DBUG_PRINT("info", ("Using direct delete"));
|
||||||
|
@@ -754,15 +754,20 @@ int mysql_update(THD *thd,
|
|||||||
!table->check_virtual_columns_marked_for_write())
|
!table->check_virtual_columns_marked_for_write())
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("Trying direct update"));
|
DBUG_PRINT("info", ("Trying direct update"));
|
||||||
if (select && select->cond &&
|
bool use_direct_update= !select || !select->cond;
|
||||||
(select->cond->used_tables() == table->map))
|
if (!use_direct_update &&
|
||||||
|
(select->cond->used_tables() & ~RAND_TABLE_BIT) == table->map)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!table->file->pushed_cond);
|
DBUG_ASSERT(!table->file->pushed_cond);
|
||||||
if (!table->file->cond_push(select->cond))
|
if (!table->file->cond_push(select->cond))
|
||||||
|
{
|
||||||
|
use_direct_update= TRUE;
|
||||||
table->file->pushed_cond= select->cond;
|
table->file->pushed_cond= select->cond;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!table->file->info_push(INFO_KIND_UPDATE_FIELDS, &fields) &&
|
if (use_direct_update &&
|
||||||
|
!table->file->info_push(INFO_KIND_UPDATE_FIELDS, &fields) &&
|
||||||
!table->file->info_push(INFO_KIND_UPDATE_VALUES, &values) &&
|
!table->file->info_push(INFO_KIND_UPDATE_VALUES, &values) &&
|
||||||
!table->file->direct_update_rows_init(&fields))
|
!table->file->direct_update_rows_init(&fields))
|
||||||
{
|
{
|
||||||
|
@@ -75,6 +75,9 @@
|
|||||||
/* warning C4065: switch statement contains 'default' but no 'case' labels */
|
/* warning C4065: switch statement contains 'default' but no 'case' labels */
|
||||||
#pragma warning (disable : 4065)
|
#pragma warning (disable : 4065)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-label" /* yyexhaustedlab: */
|
||||||
|
#endif
|
||||||
|
|
||||||
int yylex(void *yylval, void *yythd);
|
int yylex(void *yylval, void *yythd);
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2015-2019 Codership Oy <info@codership.com>
|
/* Copyright (C) 2015-2021 Codership Oy <info@codership.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -54,7 +54,7 @@ static const std::string create_cluster_table_str=
|
|||||||
"view_seqno BIGINT NOT NULL,"
|
"view_seqno BIGINT NOT NULL,"
|
||||||
"protocol_version INT NOT NULL,"
|
"protocol_version INT NOT NULL,"
|
||||||
"capabilities INT NOT NULL"
|
"capabilities INT NOT NULL"
|
||||||
") ENGINE=InnoDB";
|
") ENGINE=InnoDB STATS_PERSISTENT=0";
|
||||||
|
|
||||||
static const std::string create_members_table_str=
|
static const std::string create_members_table_str=
|
||||||
"CREATE TABLE IF NOT EXISTS " + wsrep_schema_str + "." + members_table_str +
|
"CREATE TABLE IF NOT EXISTS " + wsrep_schema_str + "." + members_table_str +
|
||||||
@@ -63,7 +63,7 @@ static const std::string create_members_table_str=
|
|||||||
"cluster_uuid CHAR(36) NOT NULL,"
|
"cluster_uuid CHAR(36) NOT NULL,"
|
||||||
"node_name CHAR(32) NOT NULL,"
|
"node_name CHAR(32) NOT NULL,"
|
||||||
"node_incoming_address VARCHAR(256) NOT NULL"
|
"node_incoming_address VARCHAR(256) NOT NULL"
|
||||||
") ENGINE=InnoDB";
|
") ENGINE=InnoDB STATS_PERSISTENT=0";
|
||||||
|
|
||||||
#ifdef WSREP_SCHEMA_MEMBERS_HISTORY
|
#ifdef WSREP_SCHEMA_MEMBERS_HISTORY
|
||||||
static const std::string cluster_member_history_table_str= "wsrep_cluster_member_history";
|
static const std::string cluster_member_history_table_str= "wsrep_cluster_member_history";
|
||||||
@@ -76,7 +76,7 @@ static const std::string create_members_history_table_str=
|
|||||||
"last_view_seqno BIGINT NOT NULL,"
|
"last_view_seqno BIGINT NOT NULL,"
|
||||||
"node_name CHAR(32) NOT NULL,"
|
"node_name CHAR(32) NOT NULL,"
|
||||||
"node_incoming_address VARCHAR(256) NOT NULL"
|
"node_incoming_address VARCHAR(256) NOT NULL"
|
||||||
") ENGINE=InnoDB";
|
") ENGINE=InnoDB STATS_PERSISTENT=0";
|
||||||
#endif /* WSREP_SCHEMA_MEMBERS_HISTORY */
|
#endif /* WSREP_SCHEMA_MEMBERS_HISTORY */
|
||||||
|
|
||||||
static const std::string create_frag_table_str=
|
static const std::string create_frag_table_str=
|
||||||
@@ -88,7 +88,7 @@ static const std::string create_frag_table_str=
|
|||||||
"flags INT NOT NULL, "
|
"flags INT NOT NULL, "
|
||||||
"frag LONGBLOB NOT NULL, "
|
"frag LONGBLOB NOT NULL, "
|
||||||
"PRIMARY KEY (node_uuid, trx_id, seqno)"
|
"PRIMARY KEY (node_uuid, trx_id, seqno)"
|
||||||
") ENGINE=InnoDB";
|
") ENGINE=InnoDB STATS_PERSISTENT=0";
|
||||||
|
|
||||||
static const std::string delete_from_cluster_table=
|
static const std::string delete_from_cluster_table=
|
||||||
"DELETE FROM " + wsrep_schema_str + "." + cluster_table_str;
|
"DELETE FROM " + wsrep_schema_str + "." + cluster_table_str;
|
||||||
@@ -96,6 +96,26 @@ static const std::string delete_from_cluster_table=
|
|||||||
static const std::string delete_from_members_table=
|
static const std::string delete_from_members_table=
|
||||||
"DELETE FROM " + wsrep_schema_str + "." + members_table_str;
|
"DELETE FROM " + wsrep_schema_str + "." + members_table_str;
|
||||||
|
|
||||||
|
/* For rolling upgrade we need to use ALTER. We do not want
|
||||||
|
persistent statistics to be collected from these tables. */
|
||||||
|
static const std::string alter_cluster_table=
|
||||||
|
"ALTER TABLE " + wsrep_schema_str + "." + cluster_table_str +
|
||||||
|
" STATS_PERSISTENT=0";
|
||||||
|
|
||||||
|
static const std::string alter_members_table=
|
||||||
|
"ALTER TABLE " + wsrep_schema_str + "." + members_table_str +
|
||||||
|
" STATS_PERSISTENT=0";
|
||||||
|
|
||||||
|
#ifdef WSREP_SCHEMA_MEMBERS_HISTORY
|
||||||
|
static const std::string alter_members_history_table=
|
||||||
|
"ALTER TABLE " + wsrep_schema_str + "." + members_history_table_str +
|
||||||
|
" STATS_PERSISTENT=0";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const std::string alter_frag_table=
|
||||||
|
"ALTER TABLE " + wsrep_schema_str + "." + sr_table_str +
|
||||||
|
" STATS_PERSISTENT=0";
|
||||||
|
|
||||||
namespace Wsrep_schema_impl
|
namespace Wsrep_schema_impl
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -675,13 +695,27 @@ int Wsrep_schema::init()
|
|||||||
Wsrep_schema_impl::execute_SQL(thd,
|
Wsrep_schema_impl::execute_SQL(thd,
|
||||||
create_members_history_table_str.c_str(),
|
create_members_history_table_str.c_str(),
|
||||||
create_members_history_table_str.size()) ||
|
create_members_history_table_str.size()) ||
|
||||||
|
Wsrep_schema_impl::execute_SQL(thd,
|
||||||
|
alter_members_history_table.c_str(),
|
||||||
|
alter_members_history_table.size()) ||
|
||||||
#endif /* WSREP_SCHEMA_MEMBERS_HISTORY */
|
#endif /* WSREP_SCHEMA_MEMBERS_HISTORY */
|
||||||
Wsrep_schema_impl::execute_SQL(thd,
|
Wsrep_schema_impl::execute_SQL(thd,
|
||||||
create_frag_table_str.c_str(),
|
create_frag_table_str.c_str(),
|
||||||
create_frag_table_str.size())) {
|
create_frag_table_str.size()) ||
|
||||||
|
Wsrep_schema_impl::execute_SQL(thd,
|
||||||
|
alter_cluster_table.c_str(),
|
||||||
|
alter_cluster_table.size()) ||
|
||||||
|
Wsrep_schema_impl::execute_SQL(thd,
|
||||||
|
alter_members_table.c_str(),
|
||||||
|
alter_members_table.size()) ||
|
||||||
|
Wsrep_schema_impl::execute_SQL(thd,
|
||||||
|
alter_frag_table.c_str(),
|
||||||
|
alter_frag_table.size()))
|
||||||
|
{
|
||||||
ret= 1;
|
ret= 1;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
ret= 0;
|
ret= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -225,6 +225,7 @@ void btr_defragment_save_defrag_stats_if_needed(dict_index_t *index)
|
|||||||
{
|
{
|
||||||
if (srv_defragment_stats_accuracy != 0 // stats tracking disabled
|
if (srv_defragment_stats_accuracy != 0 // stats tracking disabled
|
||||||
&& index->table->space_id != 0 // do not track system tables
|
&& index->table->space_id != 0 // do not track system tables
|
||||||
|
&& !index->table->is_temporary()
|
||||||
&& index->stat_defrag_modified_counter
|
&& index->stat_defrag_modified_counter
|
||||||
>= srv_defragment_stats_accuracy) {
|
>= srv_defragment_stats_accuracy) {
|
||||||
dict_stats_defrag_pool_add(index);
|
dict_stats_defrag_pool_add(index);
|
||||||
|
@@ -3387,6 +3387,7 @@ loop:
|
|||||||
/* Delete possible entries for the page from the insert buffer:
|
/* Delete possible entries for the page from the insert buffer:
|
||||||
such can exist if the page belonged to an index which was dropped */
|
such can exist if the page belonged to an index which was dropped */
|
||||||
if (page_id < page_id_t{SRV_SPACE_ID_UPPER_BOUND, 0} &&
|
if (page_id < page_id_t{SRV_SPACE_ID_UPPER_BOUND, 0} &&
|
||||||
|
!srv_is_undo_tablespace(page_id.space()) &&
|
||||||
!recv_recovery_is_on())
|
!recv_recovery_is_on())
|
||||||
ibuf_merge_or_delete_for_page(nullptr, page_id, zip_size);
|
ibuf_merge_or_delete_for_page(nullptr, page_id, zip_size);
|
||||||
|
|
||||||
|
@@ -366,10 +366,12 @@ void buf_page_write_complete(const IORequest &request)
|
|||||||
const bool temp= fsp_is_system_temporary(bpage->id().space());
|
const bool temp= fsp_is_system_temporary(bpage->id().space());
|
||||||
|
|
||||||
mysql_mutex_lock(&buf_pool.mutex);
|
mysql_mutex_lock(&buf_pool.mutex);
|
||||||
|
mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex);
|
||||||
buf_pool.stat.n_pages_written++;
|
buf_pool.stat.n_pages_written++;
|
||||||
/* While we do not need any mutex for clearing oldest_modification
|
/* While we do not need any mutex for clearing oldest_modification
|
||||||
here, we hope that it will be in the same cache line with io_fix,
|
here, we hope that it will be in the same cache line with io_fix,
|
||||||
whose changes must be protected by buf_pool.mutex. */
|
whose changes must be protected by buf_pool.mutex. */
|
||||||
|
ut_ad(temp || bpage->oldest_modification() > 2);
|
||||||
bpage->clear_oldest_modification(temp);
|
bpage->clear_oldest_modification(temp);
|
||||||
ut_ad(bpage->io_fix() == BUF_IO_WRITE);
|
ut_ad(bpage->io_fix() == BUF_IO_WRITE);
|
||||||
bpage->set_io_fix(BUF_IO_NONE);
|
bpage->set_io_fix(BUF_IO_NONE);
|
||||||
@@ -2234,7 +2236,9 @@ unemployed:
|
|||||||
|
|
||||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||||
|
|
||||||
if (!recv_recovery_is_on() && srv_operation == SRV_OPERATION_NORMAL)
|
if (!recv_recovery_is_on() &&
|
||||||
|
!srv_startup_is_before_trx_rollback_phase &&
|
||||||
|
srv_operation == SRV_OPERATION_NORMAL)
|
||||||
log_checkpoint();
|
log_checkpoint();
|
||||||
|
|
||||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||||
|
@@ -173,7 +173,7 @@ dict_stats_defrag_pool_del(
|
|||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Get the first index that has been added for updating persistent defrag
|
Get the first index that has been added for updating persistent defrag
|
||||||
stats and eventually save its stats. */
|
stats and eventually save its stats. */
|
||||||
static void dict_stats_process_entry_from_defrag_pool()
|
static void dict_stats_process_entry_from_defrag_pool(THD *thd)
|
||||||
{
|
{
|
||||||
table_id_t table_id;
|
table_id_t table_id;
|
||||||
index_id_t index_id;
|
index_id_t index_id;
|
||||||
@@ -185,31 +185,28 @@ static void dict_stats_process_entry_from_defrag_pool()
|
|||||||
/* no index in defrag pool */
|
/* no index in defrag pool */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dict_sys.freeze(SRW_LOCK_CALL);
|
|
||||||
|
|
||||||
/* If the table is no longer cached, we've already lost the in
|
/* If the table is no longer cached, we've already lost the in
|
||||||
memory stats so there's nothing really to write to disk. */
|
memory stats so there's nothing really to write to disk. */
|
||||||
dict_table_t *table= dict_sys.find_table(table_id);
|
MDL_ticket *mdl= nullptr;
|
||||||
dict_index_t *index= table && table->corrupted
|
if (dict_table_t *table=
|
||||||
? nullptr : dict_table_find_index_on_id(table, index_id);
|
dict_table_open_on_id(table_id, false, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED,
|
||||||
const bool save= index && !index->is_corrupted();
|
thd, &mdl))
|
||||||
if (save)
|
|
||||||
table->acquire();
|
|
||||||
dict_sys.unfreeze();
|
|
||||||
if (save)
|
|
||||||
{
|
{
|
||||||
|
if (dict_index_t *index= !table->corrupted
|
||||||
|
? dict_table_find_index_on_id(table, index_id) : nullptr)
|
||||||
|
if (!index->is_corrupted())
|
||||||
dict_stats_save_defrag_stats(index);
|
dict_stats_save_defrag_stats(index);
|
||||||
table->release();
|
dict_table_close(table, false, thd, mdl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the first index that has been added for updating persistent defrag
|
Get the first index that has been added for updating persistent defrag
|
||||||
stats and eventually save its stats. */
|
stats and eventually save its stats. */
|
||||||
void dict_defrag_process_entries_from_defrag_pool()
|
void dict_defrag_process_entries_from_defrag_pool(THD *thd)
|
||||||
{
|
{
|
||||||
while (!defrag_pool.empty())
|
while (!defrag_pool.empty())
|
||||||
dict_stats_process_entry_from_defrag_pool();
|
dict_stats_process_entry_from_defrag_pool(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
|
@@ -391,7 +391,7 @@ static void dict_stats_func(void*)
|
|||||||
THD *thd= innobase_create_background_thd("InnoDB statistics");
|
THD *thd= innobase_create_background_thd("InnoDB statistics");
|
||||||
set_current_thd(thd);
|
set_current_thd(thd);
|
||||||
while (dict_stats_process_entry_from_recalc_pool(thd)) {}
|
while (dict_stats_process_entry_from_recalc_pool(thd)) {}
|
||||||
dict_defrag_process_entries_from_defrag_pool();
|
dict_defrag_process_entries_from_defrag_pool(thd);
|
||||||
set_current_thd(nullptr);
|
set_current_thd(nullptr);
|
||||||
innobase_destroy_background_thd(thd);
|
innobase_destroy_background_thd(thd);
|
||||||
}
|
}
|
||||||
|
@@ -758,10 +758,12 @@ fsp_try_extend_data_file(fil_space_t *space, buf_block_t *header, mtr_t *mtr)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We ignore any fragments of a full megabyte when storing the size
|
/* For the system tablespace, we ignore any fragments of a
|
||||||
to the space header */
|
full megabyte when storing the size to the space header */
|
||||||
|
|
||||||
space->size_in_header = ut_2pow_round(space->size, (1024 * 1024) / ps);
|
space->size_in_header = space->id
|
||||||
|
? space->size
|
||||||
|
: ut_2pow_round(space->size, (1024 * 1024) / ps);
|
||||||
|
|
||||||
/* recv_sys_t::parse() expects to find a WRITE record that
|
/* recv_sys_t::parse() expects to find a WRITE record that
|
||||||
covers all 4 bytes. Therefore, we must specify mtr_t::FORCED
|
covers all 4 bytes. Therefore, we must specify mtr_t::FORCED
|
||||||
@@ -1045,11 +1047,36 @@ static
|
|||||||
buf_block_t*
|
buf_block_t*
|
||||||
fsp_page_create(fil_space_t *space, page_no_t offset, mtr_t *mtr)
|
fsp_page_create(fil_space_t *space, page_no_t offset, mtr_t *mtr)
|
||||||
{
|
{
|
||||||
buf_block_t *free_block= buf_LRU_get_free_block(false);
|
buf_block_t *block, *free_block;
|
||||||
buf_block_t *block= buf_page_create(space, static_cast<uint32_t>(offset),
|
|
||||||
|
if (UNIV_UNLIKELY(space->is_being_truncated))
|
||||||
|
{
|
||||||
|
const page_id_t page_id{space->id, offset};
|
||||||
|
const ulint fold= page_id.fold();
|
||||||
|
mysql_mutex_lock(&buf_pool.mutex);
|
||||||
|
block= reinterpret_cast<buf_block_t*>
|
||||||
|
(buf_pool.page_hash_get_low(page_id, fold));
|
||||||
|
if (block && block->page.oldest_modification() <= 1)
|
||||||
|
block= nullptr;
|
||||||
|
mysql_mutex_unlock(&buf_pool.mutex);
|
||||||
|
|
||||||
|
if (block)
|
||||||
|
{
|
||||||
|
ut_ad(block->page.buf_fix_count() >= 1);
|
||||||
|
ut_ad(block->lock.x_lock_count() == 1);
|
||||||
|
ut_ad(mtr->have_x_latch(*block));
|
||||||
|
free_block= block;
|
||||||
|
goto got_free_block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free_block= buf_LRU_get_free_block(false);
|
||||||
|
got_free_block:
|
||||||
|
block= buf_page_create(space, static_cast<uint32_t>(offset),
|
||||||
space->zip_size(), mtr, free_block);
|
space->zip_size(), mtr, free_block);
|
||||||
if (UNIV_UNLIKELY(block != free_block))
|
if (UNIV_UNLIKELY(block != free_block))
|
||||||
buf_pool.free_block(free_block);
|
buf_pool.free_block(free_block);
|
||||||
|
|
||||||
fsp_init_file_page(space, block, mtr);
|
fsp_init_file_page(space, block, mtr);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@@ -1753,7 +1780,10 @@ fseg_create(fil_space_t *space, ulint byte_offset, mtr_t *mtr,
|
|||||||
goto funct_exit;
|
goto funct_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(block->lock.not_recursive());
|
ut_d(const auto x = block->lock.x_lock_count());
|
||||||
|
ut_ad(x || block->lock.not_recursive());
|
||||||
|
ut_ad(x == 1 || space->is_being_truncated);
|
||||||
|
ut_ad(x <= 2);
|
||||||
ut_ad(!fil_page_get_type(block->frame));
|
ut_ad(!fil_page_get_type(block->frame));
|
||||||
mtr->write<1>(*block, FIL_PAGE_TYPE + 1 + block->frame,
|
mtr->write<1>(*block, FIL_PAGE_TYPE + 1 + block->frame,
|
||||||
FIL_PAGE_TYPE_SYS);
|
FIL_PAGE_TYPE_SYS);
|
||||||
@@ -2179,14 +2209,14 @@ take_hinted_page:
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space->size <= ret_page && !is_system_tablespace(space_id)) {
|
if (space->size <= ret_page && !is_predefined_tablespace(space_id)) {
|
||||||
/* It must be that we are extending a single-table
|
/* It must be that we are extending a single-table
|
||||||
tablespace whose size is still < 64 pages */
|
tablespace whose size is still < 64 pages */
|
||||||
|
|
||||||
if (ret_page >= FSP_EXTENT_SIZE) {
|
if (ret_page >= FSP_EXTENT_SIZE) {
|
||||||
ib::error() << "Error (2): trying to extend"
|
ib::error() << "Trying to extend '"
|
||||||
" a single-table tablespace " << space_id
|
<< space->chain.start->name
|
||||||
<< " by single page(s) though the"
|
<< "' by single page(s) though the"
|
||||||
<< " space size " << space->size
|
<< " space size " << space->size
|
||||||
<< ". Page no " << ret_page << ".";
|
<< ". Page no " << ret_page << ".";
|
||||||
ut_ad(!has_done_reservation);
|
ut_ad(!has_done_reservation);
|
||||||
|
@@ -2138,9 +2138,7 @@ inline void buf_page_t::clear_oldest_modification()
|
|||||||
it from buf_pool.flush_list */
|
it from buf_pool.flush_list */
|
||||||
inline void buf_page_t::clear_oldest_modification(bool temporary)
|
inline void buf_page_t::clear_oldest_modification(bool temporary)
|
||||||
{
|
{
|
||||||
mysql_mutex_assert_not_owner(&buf_pool.flush_list_mutex);
|
|
||||||
ut_ad(temporary == fsp_is_system_temporary(id().space()));
|
ut_ad(temporary == fsp_is_system_temporary(id().space()));
|
||||||
ut_ad(io_fix_ == BUF_IO_WRITE);
|
|
||||||
if (temporary)
|
if (temporary)
|
||||||
{
|
{
|
||||||
ut_ad(oldest_modification() == 2);
|
ut_ad(oldest_modification() == 2);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2016, 2020, MariaDB Corporation.
|
Copyright (c) 2016, 2021, 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
|
||||||
@@ -80,12 +80,10 @@ dict_stats_defrag_pool_del(
|
|||||||
all entries for the table */
|
all entries for the table */
|
||||||
const dict_index_t* index); /*!< in: index to remove */
|
const dict_index_t* index); /*!< in: index to remove */
|
||||||
|
|
||||||
/*****************************************************************//**
|
/**
|
||||||
Get the first index that has been added for updating persistent defrag
|
Get the first index that has been added for updating persistent defrag
|
||||||
stats and eventually save its stats. */
|
stats and eventually save its stats. */
|
||||||
void
|
void dict_defrag_process_entries_from_defrag_pool(THD *thd);
|
||||||
dict_defrag_process_entries_from_defrag_pool();
|
|
||||||
/*===========================================*/
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Save defragmentation result.
|
Save defragmentation result.
|
||||||
|
@@ -113,12 +113,16 @@ struct completion_callback;
|
|||||||
void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key = false,
|
void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key = false,
|
||||||
const completion_callback* cb=nullptr);
|
const completion_callback* cb=nullptr);
|
||||||
|
|
||||||
/** write to the log file up to the last log entry.
|
/** Write to the log file up to the last log entry.
|
||||||
@param[in] sync whether we want the written log
|
@param sync whether to wait for a durable write to complete */
|
||||||
also to be flushed to disk. */
|
void log_buffer_flush_to_disk(bool sync= true);
|
||||||
void
|
|
||||||
log_buffer_flush_to_disk(
|
|
||||||
bool sync = true);
|
/** Prepare to invoke log_write_and_flush(), before acquiring log_sys.mutex. */
|
||||||
|
ATTRIBUTE_COLD void log_write_and_flush_prepare();
|
||||||
|
|
||||||
|
/** Durably write the log up to log_sys.lsn() and release log_sys.mutex. */
|
||||||
|
ATTRIBUTE_COLD void log_write_and_flush();
|
||||||
|
|
||||||
/** Make a checkpoint */
|
/** Make a checkpoint */
|
||||||
ATTRIBUTE_COLD void log_make_checkpoint();
|
ATTRIBUTE_COLD void log_make_checkpoint();
|
||||||
|
@@ -101,6 +101,10 @@ struct mtr_t {
|
|||||||
/** Commit the mini-transaction. */
|
/** Commit the mini-transaction. */
|
||||||
void commit();
|
void commit();
|
||||||
|
|
||||||
|
/** Commit a mini-transaction that is shrinking a tablespace.
|
||||||
|
@param space tablespace that is being shrunk */
|
||||||
|
ATTRIBUTE_COLD void commit_shrink(fil_space_t &space);
|
||||||
|
|
||||||
/** Commit a mini-transaction that did not modify any pages,
|
/** Commit a mini-transaction that did not modify any pages,
|
||||||
but generated some redo log on a higher level, such as
|
but generated some redo log on a higher level, such as
|
||||||
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
|
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
|
||||||
|
@@ -48,8 +48,8 @@ mtr_t::memo_push(void* object, mtr_memo_type_t type)
|
|||||||
|
|
||||||
/* If this mtr has x-fixed a clean page then we set
|
/* If this mtr has x-fixed a clean page then we set
|
||||||
the made_dirty flag. This tells us if we need to
|
the made_dirty flag. This tells us if we need to
|
||||||
grab log_flush_order_mutex at mtr_commit so that we
|
grab log_sys.flush_order_mutex at mtr_t::commit() so that we
|
||||||
can insert the dirtied page to the flush list. */
|
can insert the dirtied page into the flush list. */
|
||||||
|
|
||||||
if ((type == MTR_MEMO_PAGE_X_FIX || type == MTR_MEMO_PAGE_SX_FIX)
|
if ((type == MTR_MEMO_PAGE_X_FIX || type == MTR_MEMO_PAGE_SX_FIX)
|
||||||
&& !m_made_dirty) {
|
&& !m_made_dirty) {
|
||||||
|
@@ -98,6 +98,9 @@ public:
|
|||||||
ut_ad(recursive);
|
ut_ad(recursive);
|
||||||
return recursive == RECURSIVE_X || recursive == RECURSIVE_U;
|
return recursive == RECURSIVE_X || recursive == RECURSIVE_U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the number of X locks being held (by any thread) */
|
||||||
|
unsigned x_lock_count() const { return recursive & RECURSIVE_MAX; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Acquire a recursive lock */
|
/** Acquire a recursive lock */
|
||||||
|
@@ -43,6 +43,7 @@ trx_rsegf_get(fil_space_t* space, uint32_t page_no, mtr_t* mtr);
|
|||||||
/** Create a rollback segment header.
|
/** Create a rollback segment header.
|
||||||
@param[in,out] space system, undo, or temporary tablespace
|
@param[in,out] space system, undo, or temporary tablespace
|
||||||
@param[in] rseg_id rollback segment identifier
|
@param[in] rseg_id rollback segment identifier
|
||||||
|
@param[in] max_trx_id new value of TRX_RSEG_MAX_TRX_ID
|
||||||
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
|
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return the created rollback segment
|
@return the created rollback segment
|
||||||
@@ -51,6 +52,7 @@ buf_block_t*
|
|||||||
trx_rseg_header_create(
|
trx_rseg_header_create(
|
||||||
fil_space_t* space,
|
fil_space_t* space,
|
||||||
ulint rseg_id,
|
ulint rseg_id,
|
||||||
|
trx_id_t max_trx_id,
|
||||||
buf_block_t* sys_header,
|
buf_block_t* sys_header,
|
||||||
mtr_t* mtr);
|
mtr_t* mtr);
|
||||||
|
|
||||||
|
@@ -833,15 +833,41 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key,
|
|||||||
DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE(););
|
DBUG_EXECUTE_IF("crash_after_log_write_upto", DBUG_SUICIDE(););
|
||||||
}
|
}
|
||||||
|
|
||||||
/** write to the log file up to the last log entry.
|
/** Write to the log file up to the last log entry.
|
||||||
@param[in] sync whether we want the written log
|
@param sync whether to wait for a durable write to complete */
|
||||||
also to be flushed to disk. */
|
|
||||||
void log_buffer_flush_to_disk(bool sync)
|
void log_buffer_flush_to_disk(bool sync)
|
||||||
{
|
{
|
||||||
ut_ad(!srv_read_only_mode);
|
ut_ad(!srv_read_only_mode);
|
||||||
log_write_up_to(log_sys.get_lsn(std::memory_order_acquire), sync);
|
log_write_up_to(log_sys.get_lsn(std::memory_order_acquire), sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Prepare to invoke log_write_and_flush(), before acquiring log_sys.mutex. */
|
||||||
|
ATTRIBUTE_COLD void log_write_and_flush_prepare()
|
||||||
|
{
|
||||||
|
mysql_mutex_assert_not_owner(&log_sys.mutex);
|
||||||
|
|
||||||
|
while (flush_lock.acquire(log_sys.get_lsn() + 1, nullptr) !=
|
||||||
|
group_commit_lock::ACQUIRED);
|
||||||
|
while (write_lock.acquire(log_sys.get_lsn() + 1, nullptr) !=
|
||||||
|
group_commit_lock::ACQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Durably write the log and release log_sys.mutex */
|
||||||
|
ATTRIBUTE_COLD void log_write_and_flush()
|
||||||
|
{
|
||||||
|
ut_ad(!srv_read_only_mode);
|
||||||
|
auto lsn= log_sys.get_lsn();
|
||||||
|
write_lock.set_pending(lsn);
|
||||||
|
log_write(false);
|
||||||
|
ut_a(log_sys.write_lsn == lsn);
|
||||||
|
write_lock.release(lsn);
|
||||||
|
|
||||||
|
lsn= write_lock.value();
|
||||||
|
flush_lock.set_pending(lsn);
|
||||||
|
log_write_flush_to_disk_low(lsn);
|
||||||
|
flush_lock.release(lsn);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
|
||||||
Tries to establish a big enough margin of free space in the log buffer, such
|
Tries to establish a big enough margin of free space in the log buffer, such
|
||||||
|
@@ -461,6 +461,114 @@ void mtr_t::commit()
|
|||||||
release_resources();
|
release_resources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Shrink a tablespace. */
|
||||||
|
struct Shrink
|
||||||
|
{
|
||||||
|
/** the first non-existing page in the tablespace */
|
||||||
|
const page_id_t high;
|
||||||
|
|
||||||
|
Shrink(const fil_space_t &space) : high({space.id, space.size}) {}
|
||||||
|
|
||||||
|
bool operator()(mtr_memo_slot_t *slot) const
|
||||||
|
{
|
||||||
|
if (!slot->object)
|
||||||
|
return true;
|
||||||
|
switch (slot->type) {
|
||||||
|
default:
|
||||||
|
ut_ad("invalid type" == 0);
|
||||||
|
return false;
|
||||||
|
case MTR_MEMO_SPACE_X_LOCK:
|
||||||
|
ut_ad(high.space() == static_cast<fil_space_t*>(slot->object)->id);
|
||||||
|
return true;
|
||||||
|
case MTR_MEMO_PAGE_X_MODIFY:
|
||||||
|
case MTR_MEMO_PAGE_SX_MODIFY:
|
||||||
|
case MTR_MEMO_PAGE_X_FIX:
|
||||||
|
case MTR_MEMO_PAGE_SX_FIX:
|
||||||
|
auto &bpage= static_cast<buf_block_t*>(slot->object)->page;
|
||||||
|
ut_ad(bpage.io_fix() == BUF_IO_NONE);
|
||||||
|
const auto id= bpage.id();
|
||||||
|
if (id < high)
|
||||||
|
{
|
||||||
|
ut_ad(id.space() == high.space() ||
|
||||||
|
(id == page_id_t{0, TRX_SYS_PAGE_NO} &&
|
||||||
|
srv_is_undo_tablespace(high.space())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ut_ad(id.space() == high.space());
|
||||||
|
ut_ad(bpage.state() == BUF_BLOCK_FILE_PAGE);
|
||||||
|
if (bpage.oldest_modification() > 1)
|
||||||
|
bpage.clear_oldest_modification(false);
|
||||||
|
slot->type= static_cast<mtr_memo_type_t>(slot->type & ~MTR_MEMO_MODIFY);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Commit a mini-transaction that is shrinking a tablespace.
|
||||||
|
@param space tablespace that is being shrunk */
|
||||||
|
void mtr_t::commit_shrink(fil_space_t &space)
|
||||||
|
{
|
||||||
|
ut_ad(is_active());
|
||||||
|
ut_ad(!is_inside_ibuf());
|
||||||
|
ut_ad(!high_level_read_only);
|
||||||
|
ut_ad(m_modifications);
|
||||||
|
ut_ad(m_made_dirty);
|
||||||
|
ut_ad(!recv_recovery_is_on());
|
||||||
|
ut_ad(m_log_mode == MTR_LOG_ALL);
|
||||||
|
ut_ad(UT_LIST_GET_LEN(space.chain) == 1);
|
||||||
|
|
||||||
|
log_write_and_flush_prepare();
|
||||||
|
|
||||||
|
const lsn_t start_lsn= finish_write(prepare_write()).first;
|
||||||
|
|
||||||
|
mysql_mutex_lock(&log_sys.flush_order_mutex);
|
||||||
|
/* Durably write the reduced FSP_SIZE before truncating the data file. */
|
||||||
|
log_write_and_flush();
|
||||||
|
|
||||||
|
os_file_truncate(space.chain.start->name, space.chain.start->handle,
|
||||||
|
os_offset_t{space.size} << srv_page_size_shift, true);
|
||||||
|
|
||||||
|
if (m_freed_pages)
|
||||||
|
{
|
||||||
|
ut_ad(!m_freed_pages->empty());
|
||||||
|
ut_ad(m_freed_space == &space);
|
||||||
|
ut_ad(memo_contains(*m_freed_space));
|
||||||
|
ut_ad(is_named_space(m_freed_space));
|
||||||
|
m_freed_space->update_last_freed_lsn(m_commit_lsn);
|
||||||
|
|
||||||
|
if (!is_trim_pages())
|
||||||
|
for (const auto &range : *m_freed_pages)
|
||||||
|
m_freed_space->add_free_range(range);
|
||||||
|
else
|
||||||
|
m_freed_space->clear_freed_ranges();
|
||||||
|
delete m_freed_pages;
|
||||||
|
m_freed_pages= nullptr;
|
||||||
|
m_freed_space= nullptr;
|
||||||
|
/* mtr_t::start() will reset m_trim_pages */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ut_ad(!m_freed_space);
|
||||||
|
|
||||||
|
m_memo.for_each_block_in_reverse(CIterate<Shrink>{space});
|
||||||
|
|
||||||
|
m_memo.for_each_block_in_reverse(CIterate<const ReleaseBlocks>
|
||||||
|
(ReleaseBlocks(start_lsn, m_commit_lsn,
|
||||||
|
m_memo)));
|
||||||
|
mysql_mutex_unlock(&log_sys.flush_order_mutex);
|
||||||
|
|
||||||
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
|
ut_ad(space.is_being_truncated);
|
||||||
|
ut_ad(space.is_stopping());
|
||||||
|
space.clear_stopping();
|
||||||
|
space.is_being_truncated= false;
|
||||||
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
|
m_memo.for_each_block_in_reverse(CIterate<ReleaseLatches>());
|
||||||
|
srv_stats.log_write_requests.inc();
|
||||||
|
|
||||||
|
release_resources();
|
||||||
|
}
|
||||||
|
|
||||||
/** Commit a mini-transaction that did not modify any pages,
|
/** Commit a mini-transaction that did not modify any pages,
|
||||||
but generated some redo log on a higher level, such as
|
but generated some redo log on a higher level, such as
|
||||||
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
|
FILE_MODIFY records and an optional FILE_CHECKPOINT marker.
|
||||||
|
@@ -1637,7 +1637,6 @@ row_fts_merge_insert(
|
|||||||
aux_table = dict_table_open_on_name(aux_table_name, false,
|
aux_table = dict_table_open_on_name(aux_table_name, false,
|
||||||
DICT_ERR_IGNORE_NONE);
|
DICT_ERR_IGNORE_NONE);
|
||||||
ut_ad(aux_table != NULL);
|
ut_ad(aux_table != NULL);
|
||||||
aux_table->release();
|
|
||||||
aux_index = dict_table_get_first_index(aux_table);
|
aux_index = dict_table_get_first_index(aux_table);
|
||||||
|
|
||||||
ut_ad(!aux_index->is_instant());
|
ut_ad(!aux_index->is_instant());
|
||||||
@@ -1762,6 +1761,8 @@ row_fts_merge_insert(
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
aux_table->release();
|
||||||
|
|
||||||
fts_sql_commit(trx);
|
fts_sql_commit(trx);
|
||||||
|
|
||||||
trx->op_info = "";
|
trx->op_info = "";
|
||||||
|
@@ -1809,7 +1809,9 @@ fewer_threads:
|
|||||||
if (history_size &&
|
if (history_size &&
|
||||||
trx_purge(n_use_threads,
|
trx_purge(n_use_threads,
|
||||||
!(++count % srv_purge_rseg_truncate_frequency) ||
|
!(++count % srv_purge_rseg_truncate_frequency) ||
|
||||||
purge_sys.truncate.current))
|
purge_sys.truncate.current ||
|
||||||
|
(srv_shutdown_state != SRV_SHUTDOWN_NONE &&
|
||||||
|
srv_fast_shutdown == 0)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (m_running == sigcount)
|
if (m_running == sigcount)
|
||||||
|
@@ -223,6 +223,14 @@ template void ssux_lock_impl<false>::destroy();
|
|||||||
template void ssux_lock_impl<false>::rd_unlock();
|
template void ssux_lock_impl<false>::rd_unlock();
|
||||||
template void ssux_lock_impl<false>::u_unlock();
|
template void ssux_lock_impl<false>::u_unlock();
|
||||||
template void ssux_lock_impl<false>::wr_unlock();
|
template void ssux_lock_impl<false>::wr_unlock();
|
||||||
|
template void ssux_lock_impl<true>::init();
|
||||||
|
template void ssux_lock_impl<true>::destroy();
|
||||||
|
template void ssux_lock_impl<true>::read_lock(uint32_t);
|
||||||
|
template void ssux_lock_impl<true>::rd_unlock();
|
||||||
|
template void ssux_lock_impl<true>::u_unlock();
|
||||||
|
template void ssux_lock_impl<true>::wr_unlock();
|
||||||
|
template void ssux_lock_impl<true>::write_lock(bool);
|
||||||
|
template void ssux_lock_impl<true>::update_lock(uint32_t);
|
||||||
#else /* SUX_LOCK_GENERIC */
|
#else /* SUX_LOCK_GENERIC */
|
||||||
static_assert(4 == sizeof(rw_lock), "ABI");
|
static_assert(4 == sizeof(rw_lock), "ABI");
|
||||||
# ifdef _WIN32
|
# ifdef _WIN32
|
||||||
|
@@ -547,114 +547,97 @@ function is called, the caller must not have any latches on undo log pages!
|
|||||||
static void trx_purge_truncate_history()
|
static void trx_purge_truncate_history()
|
||||||
{
|
{
|
||||||
ut_ad(purge_sys.head <= purge_sys.tail);
|
ut_ad(purge_sys.head <= purge_sys.tail);
|
||||||
purge_sys_t::iterator& head = purge_sys.head.trx_no
|
purge_sys_t::iterator &head= purge_sys.head.trx_no
|
||||||
? purge_sys.head : purge_sys.tail;
|
? purge_sys.head : purge_sys.tail;
|
||||||
|
|
||||||
if (head.trx_no >= purge_sys.low_limit_no()) {
|
if (head.trx_no >= purge_sys.low_limit_no())
|
||||||
|
{
|
||||||
/* This is sometimes necessary. TODO: find out why. */
|
/* This is sometimes necessary. TODO: find out why. */
|
||||||
head.trx_no = purge_sys.low_limit_no();
|
head.trx_no= purge_sys.low_limit_no();
|
||||||
head.undo_no = 0;
|
head.undo_no= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& rseg : trx_sys.rseg_array) {
|
for (auto &rseg : trx_sys.rseg_array)
|
||||||
if (rseg.space) {
|
if (rseg.space)
|
||||||
trx_purge_truncate_rseg_history(rseg, head);
|
trx_purge_truncate_rseg_history(rseg, head);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srv_undo_tablespaces_active < 2) {
|
if (srv_undo_tablespaces_active < 2)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
while (srv_undo_log_truncate) {
|
while (srv_undo_log_truncate)
|
||||||
if (!purge_sys.truncate.current) {
|
{
|
||||||
const ulint threshold = ulint(srv_max_undo_log_size
|
if (!purge_sys.truncate.current)
|
||||||
>> srv_page_size_shift);
|
{
|
||||||
for (uint32_t i = purge_sys.truncate.last
|
const ulint threshold=
|
||||||
? purge_sys.truncate.last->id
|
ulint(srv_max_undo_log_size >> srv_page_size_shift);
|
||||||
- srv_undo_space_id_start
|
for (uint32_t i= purge_sys.truncate.last
|
||||||
: 0, j = i;; ) {
|
? purge_sys.truncate.last->id - srv_undo_space_id_start : 0,
|
||||||
uint32_t space_id = srv_undo_space_id_start
|
j= i;; )
|
||||||
+ i;
|
{
|
||||||
|
const uint32_t space_id= srv_undo_space_id_start + i;
|
||||||
ut_ad(srv_is_undo_tablespace(space_id));
|
ut_ad(srv_is_undo_tablespace(space_id));
|
||||||
fil_space_t* space= fil_space_get(space_id);
|
fil_space_t *space= fil_space_get(space_id);
|
||||||
|
ut_a(UT_LIST_GET_LEN(space->chain) == 1);
|
||||||
|
|
||||||
if (space && space->get_size() > threshold) {
|
if (space && space->get_size() > threshold)
|
||||||
purge_sys.truncate.current = space;
|
{
|
||||||
|
purge_sys.truncate.current= space;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
i %= srv_undo_tablespaces_active;
|
i %= srv_undo_tablespaces_active;
|
||||||
if (i == j) {
|
if (i == j)
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!purge_sys.truncate.current) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fil_space_t& space = *purge_sys.truncate.current;
|
fil_space_t &space= *purge_sys.truncate.current;
|
||||||
/* Undo tablespace always are a single file. */
|
/* Undo tablespace always are a single file. */
|
||||||
ut_a(UT_LIST_GET_LEN(space.chain) == 1);
|
fil_node_t *file= UT_LIST_GET_FIRST(space.chain);
|
||||||
fil_node_t* file = UT_LIST_GET_FIRST(space.chain);
|
|
||||||
/* The undo tablespace files are never closed. */
|
/* The undo tablespace files are never closed. */
|
||||||
ut_ad(file->is_open());
|
ut_ad(file->is_open());
|
||||||
|
|
||||||
DBUG_LOG("undo", "marking for truncate: " << file->name);
|
DBUG_LOG("undo", "marking for truncate: " << file->name);
|
||||||
|
|
||||||
for (auto& rseg : trx_sys.rseg_array) {
|
for (auto &rseg : trx_sys.rseg_array)
|
||||||
if (rseg.space == &space) {
|
if (rseg.space == &space)
|
||||||
/* Once set, this rseg will
|
/* Once set, this rseg will not be allocated to subsequent
|
||||||
not be allocated to subsequent
|
transactions, but we will wait for existing active
|
||||||
transactions, but we will wait
|
|
||||||
for existing active
|
|
||||||
transactions to finish. */
|
transactions to finish. */
|
||||||
rseg.set_skip_allocation();
|
rseg.set_skip_allocation();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& rseg : trx_sys.rseg_array) {
|
for (auto &rseg : trx_sys.rseg_array)
|
||||||
if (rseg.space != &space) {
|
{
|
||||||
|
if (rseg.space != &space)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
ut_ad(rseg.skip_allocation());
|
|
||||||
if (rseg.is_referenced()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rseg.latch.rd_lock();
|
rseg.latch.rd_lock();
|
||||||
ut_ad(rseg.skip_allocation());
|
ut_ad(rseg.skip_allocation());
|
||||||
if (rseg.is_referenced()) {
|
if (rseg.is_referenced())
|
||||||
|
{
|
||||||
not_free:
|
not_free:
|
||||||
rseg.latch.rd_unlock();
|
rseg.latch.rd_unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rseg.curr_size != 1) {
|
if (rseg.curr_size != 1)
|
||||||
/* Check if all segments are
|
{
|
||||||
cached and safe to remove. */
|
/* Check if all segments are cached and safe to remove. */
|
||||||
ulint cached = 0;
|
ulint cached= 0;
|
||||||
|
for (trx_undo_t *undo= UT_LIST_GET_FIRST(rseg.undo_cached); undo;
|
||||||
for (trx_undo_t* undo = UT_LIST_GET_FIRST(
|
undo= UT_LIST_GET_NEXT(undo_list, undo))
|
||||||
rseg.undo_cached);
|
{
|
||||||
undo;
|
if (head.trx_no < undo->trx_id)
|
||||||
undo = UT_LIST_GET_NEXT(undo_list,
|
|
||||||
undo)) {
|
|
||||||
if (head.trx_no < undo->trx_id) {
|
|
||||||
goto not_free;
|
goto not_free;
|
||||||
} else {
|
else
|
||||||
cached += undo->size;
|
cached+= undo->size;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(rseg.curr_size > cached);
|
ut_ad(rseg.curr_size > cached);
|
||||||
|
|
||||||
if (rseg.curr_size > cached + 1) {
|
if (rseg.curr_size > cached + 1)
|
||||||
goto not_free;
|
goto not_free;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rseg.latch.rd_unlock();
|
rseg.latch.rd_unlock();
|
||||||
}
|
}
|
||||||
@@ -662,134 +645,155 @@ not_free:
|
|||||||
ib::info() << "Truncating " << file->name;
|
ib::info() << "Truncating " << file->name;
|
||||||
trx_purge_cleanse_purge_queue(space);
|
trx_purge_cleanse_purge_queue(space);
|
||||||
|
|
||||||
/* Flush all to-be-discarded pages of the tablespace.
|
log_free_check();
|
||||||
|
|
||||||
During truncation, we do not want any writes to the
|
mtr_t mtr;
|
||||||
to-be-discarded area, because we must set the space.size
|
mtr.start();
|
||||||
early in order to have deterministic page allocation.
|
mtr.x_lock_space(&space);
|
||||||
|
|
||||||
|
/* Lock all modified pages of the tablespace.
|
||||||
|
|
||||||
|
During truncation, we do not want any writes to the file.
|
||||||
|
|
||||||
If a log checkpoint was completed at LSN earlier than our
|
If a log checkpoint was completed at LSN earlier than our
|
||||||
mini-transaction commit and the server was killed, then
|
mini-transaction commit and the server was killed, then
|
||||||
discarding the to-be-trimmed pages without flushing would
|
discarding the to-be-trimmed pages without flushing would
|
||||||
break crash recovery. So, we cannot avoid the write. */
|
break crash recovery. */
|
||||||
while (buf_flush_list_space(&space));
|
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||||
|
|
||||||
log_free_check();
|
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.flush_list); bpage; )
|
||||||
|
{
|
||||||
|
ut_ad(bpage->oldest_modification());
|
||||||
|
ut_ad(bpage->in_file());
|
||||||
|
|
||||||
|
buf_page_t *prev= UT_LIST_GET_PREV(list, bpage);
|
||||||
|
|
||||||
|
if (bpage->id().space() == space.id &&
|
||||||
|
bpage->oldest_modification() != 1)
|
||||||
|
{
|
||||||
|
ut_ad(bpage->state() == BUF_BLOCK_FILE_PAGE);
|
||||||
|
auto block= reinterpret_cast<buf_block_t*>(bpage);
|
||||||
|
block->fix();
|
||||||
|
buf_pool.flush_hp.set(prev);
|
||||||
|
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||||
|
|
||||||
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
|
ut_ad(!block->index); /* There is no AHI on undo tablespaces. */
|
||||||
|
#endif
|
||||||
|
block->lock.x_lock();
|
||||||
|
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||||
|
ut_ad(bpage->io_fix() == BUF_IO_NONE);
|
||||||
|
|
||||||
|
if (bpage->oldest_modification() > 1)
|
||||||
|
{
|
||||||
|
bpage->clear_oldest_modification(false);
|
||||||
|
mtr.memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
block->lock.x_unlock();
|
||||||
|
block->unfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev != buf_pool.flush_hp.get())
|
||||||
|
{
|
||||||
|
/* Rescan, because we may have lost the position. */
|
||||||
|
bpage= UT_LIST_GET_LAST(buf_pool.flush_list);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bpage= prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||||
|
|
||||||
/* Re-initialize tablespace, in a single mini-transaction. */
|
/* Re-initialize tablespace, in a single mini-transaction. */
|
||||||
mtr_t mtr;
|
const ulint size= SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
|
||||||
const ulint size = SRV_UNDO_TABLESPACE_SIZE_IN_PAGES;
|
|
||||||
mtr.start();
|
|
||||||
mtr.x_lock_space(&space);
|
|
||||||
|
|
||||||
/* Adjust the tablespace metadata. */
|
/* Adjust the tablespace metadata. */
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
ut_d(bool stopped=) space.set_stopping();
|
space.set_stopping();
|
||||||
ut_ad(!stopped);
|
space.is_being_truncated= true;
|
||||||
space.is_being_truncated = true;
|
if (space.crypt_data)
|
||||||
if (space.crypt_data) {
|
{
|
||||||
space.reacquire();
|
space.reacquire();
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
fil_space_crypt_close_tablespace(&space);
|
fil_space_crypt_close_tablespace(&space);
|
||||||
space.release();
|
space.release();
|
||||||
} else {
|
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
uint i = 60;
|
for (auto i= 6000; space.referenced();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10)))
|
||||||
while (space.referenced()) {
|
{
|
||||||
if (!--i) {
|
if (!--i)
|
||||||
|
{
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
ib::error() << "Failed to freeze"
|
ib::error() << "Failed to freeze UNDO tablespace " << file->name;
|
||||||
" UNDO tablespace "
|
|
||||||
<< file->name;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Associate the undo tablespace with mtr.
|
/* Associate the undo tablespace with mtr.
|
||||||
During mtr::commit(), InnoDB can use the undo
|
During mtr::commit_shrink(), InnoDB can use the undo
|
||||||
tablespace object to clear all freed ranges */
|
tablespace object to clear all freed ranges */
|
||||||
mtr.set_named_space(&space);
|
mtr.set_named_space(&space);
|
||||||
mtr.trim_pages(page_id_t(space.id, size));
|
mtr.trim_pages(page_id_t(space.id, size));
|
||||||
fsp_header_init(&space, size, &mtr);
|
fsp_header_init(&space, size, &mtr);
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
space.size = file->size = size;
|
space.size= file->size= size;
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
buf_block_t* sys_header = trx_sysf_get(&mtr);
|
buf_block_t *sys_header= trx_sysf_get(&mtr);
|
||||||
|
|
||||||
for (auto& rseg : trx_sys.rseg_array) {
|
for (auto &rseg : trx_sys.rseg_array)
|
||||||
if (rseg.space != &space) {
|
{
|
||||||
|
if (rseg.space != &space)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
buf_block_t* rblock = trx_rseg_header_create(
|
buf_block_t *rblock= trx_rseg_header_create(&space,
|
||||||
purge_sys.truncate.current,
|
&rseg - trx_sys.rseg_array,
|
||||||
i, sys_header, &mtr);
|
trx_sys.get_max_trx_id(),
|
||||||
|
sys_header, &mtr);
|
||||||
ut_ad(rblock);
|
ut_ad(rblock);
|
||||||
/* These were written by trx_rseg_header_create(). */
|
/* These were written by trx_rseg_header_create(). */
|
||||||
ut_ad(!mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT
|
ut_ad(!mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT + rblock->frame));
|
||||||
+ rblock->frame));
|
ut_ad(!mach_read_from_4(TRX_RSEG + TRX_RSEG_HISTORY_SIZE +
|
||||||
ut_ad(!mach_read_from_4(TRX_RSEG + TRX_RSEG_HISTORY_SIZE
|
rblock->frame));
|
||||||
+ rblock->frame));
|
rseg.reinit(rblock ? rblock->page.id().page_no() : FIL_NULL);
|
||||||
rseg.reinit(rblock
|
|
||||||
? rblock->page.id().page_no() : FIL_NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit_shrink(space);
|
||||||
/* Write-ahead the redo log record. */
|
|
||||||
log_write_up_to(mtr.commit_lsn(), true);
|
|
||||||
|
|
||||||
/* Trim the file size. */
|
/* No mutex; this is only updated by the purge coordinator. */
|
||||||
os_file_truncate(file->name, file->handle,
|
|
||||||
os_offset_t(size) << srv_page_size_shift,
|
|
||||||
true);
|
|
||||||
|
|
||||||
/* This is only executed by srv_purge_coordinator_thread. */
|
|
||||||
export_vars.innodb_undo_truncations++;
|
export_vars.innodb_undo_truncations++;
|
||||||
|
|
||||||
/* In MDEV-8319 (10.5) we will PUNCH_HOLE the garbage
|
if (purge_sys.rseg && purge_sys.rseg->last_page_no == FIL_NULL)
|
||||||
(with write-ahead logging). */
|
{
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
/* If purge_sys.rseg is pointing to rseg that was recently
|
||||||
ut_ad(&space == purge_sys.truncate.current);
|
truncated then move to next rseg element.
|
||||||
ut_ad(space.is_being_truncated);
|
|
||||||
purge_sys.truncate.current->clear_stopping();
|
|
||||||
purge_sys.truncate.current->is_being_truncated = false;
|
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
|
||||||
|
|
||||||
if (purge_sys.rseg != NULL
|
Note: Ideally purge_sys.rseg should be NULL because purge should
|
||||||
&& purge_sys.rseg->last_page_no == FIL_NULL) {
|
complete processing of all the records but srv_purge_batch_size
|
||||||
/* If purge_sys.rseg is pointing to rseg that
|
can force the purge loop to exit before all the records are purged. */
|
||||||
was recently truncated then move to next rseg
|
purge_sys.rseg= nullptr;
|
||||||
element. Note: Ideally purge_sys.rseg should
|
purge_sys.next_stored= false;
|
||||||
be NULL because purge should complete
|
|
||||||
processing of all the records but there is
|
|
||||||
purge_batch_size that can force the purge loop
|
|
||||||
to exit before all the records are purged and
|
|
||||||
in this case purge_sys.rseg could point to a
|
|
||||||
valid rseg waiting for next purge cycle. */
|
|
||||||
purge_sys.next_stored = false;
|
|
||||||
purge_sys.rseg = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("ib_undo_trunc",
|
DBUG_EXECUTE_IF("ib_undo_trunc", ib::info() << "ib_undo_trunc";
|
||||||
ib::info() << "ib_undo_trunc";
|
|
||||||
log_buffer_flush_to_disk();
|
log_buffer_flush_to_disk();
|
||||||
DBUG_SUICIDE(););
|
DBUG_SUICIDE(););
|
||||||
|
|
||||||
for (auto& rseg : trx_sys.rseg_array) {
|
for (auto &rseg : trx_sys.rseg_array)
|
||||||
if (rseg.space == &space) {
|
if (rseg.space == &space)
|
||||||
rseg.clear_skip_allocation();
|
rseg.clear_skip_allocation();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ib::info() << "Truncated " << file->name;
|
ib::info() << "Truncated " << file->name;
|
||||||
purge_sys.truncate.last = purge_sys.truncate.current;
|
purge_sys.truncate.last= purge_sys.truncate.current;
|
||||||
purge_sys.truncate.current = NULL;
|
ut_ad(&space == purge_sys.truncate.current);
|
||||||
|
purge_sys.truncate.current= nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -316,6 +316,7 @@ void trx_rseg_format_upgrade(buf_block_t *rseg_header, mtr_t *mtr)
|
|||||||
/** Create a rollback segment header.
|
/** Create a rollback segment header.
|
||||||
@param[in,out] space system, undo, or temporary tablespace
|
@param[in,out] space system, undo, or temporary tablespace
|
||||||
@param[in] rseg_id rollback segment identifier
|
@param[in] rseg_id rollback segment identifier
|
||||||
|
@param[in] max_trx_id new value of TRX_RSEG_MAX_TRX_ID
|
||||||
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
|
@param[in,out] sys_header the TRX_SYS page (NULL for temporary rseg)
|
||||||
@param[in,out] mtr mini-transaction
|
@param[in,out] mtr mini-transaction
|
||||||
@return the created rollback segment
|
@return the created rollback segment
|
||||||
@@ -324,6 +325,7 @@ buf_block_t*
|
|||||||
trx_rseg_header_create(
|
trx_rseg_header_create(
|
||||||
fil_space_t* space,
|
fil_space_t* space,
|
||||||
ulint rseg_id,
|
ulint rseg_id,
|
||||||
|
trx_id_t max_trx_id,
|
||||||
buf_block_t* sys_header,
|
buf_block_t* sys_header,
|
||||||
mtr_t* mtr)
|
mtr_t* mtr)
|
||||||
{
|
{
|
||||||
@@ -344,10 +346,16 @@ trx_rseg_header_create(
|
|||||||
+ block->frame));
|
+ block->frame));
|
||||||
ut_ad(0 == mach_read_from_4(TRX_RSEG_HISTORY_SIZE + TRX_RSEG
|
ut_ad(0 == mach_read_from_4(TRX_RSEG_HISTORY_SIZE + TRX_RSEG
|
||||||
+ block->frame));
|
+ block->frame));
|
||||||
|
ut_ad(0 == mach_read_from_4(TRX_RSEG_MAX_TRX_ID + TRX_RSEG
|
||||||
|
+ block->frame));
|
||||||
|
|
||||||
/* Initialize the history list */
|
/* Initialize the history list */
|
||||||
flst_init(block, TRX_RSEG_HISTORY + TRX_RSEG, mtr);
|
flst_init(block, TRX_RSEG_HISTORY + TRX_RSEG, mtr);
|
||||||
|
|
||||||
|
mtr->write<8,mtr_t::MAYBE_NOP>(*block,
|
||||||
|
TRX_RSEG + TRX_RSEG_MAX_TRX_ID
|
||||||
|
+ block->frame, max_trx_id);
|
||||||
|
|
||||||
/* Reset the undo log slots */
|
/* Reset the undo log slots */
|
||||||
mtr->memset(block, TRX_RSEG_UNDO_SLOTS + TRX_RSEG,
|
mtr->memset(block, TRX_RSEG_UNDO_SLOTS + TRX_RSEG,
|
||||||
TRX_RSEG_N_SLOTS * 4, 0xff);
|
TRX_RSEG_N_SLOTS * 4, 0xff);
|
||||||
@@ -695,7 +703,7 @@ void trx_temp_rseg_create()
|
|||||||
mtr.x_lock_space(fil_system.temp_space);
|
mtr.x_lock_space(fil_system.temp_space);
|
||||||
|
|
||||||
buf_block_t* rblock = trx_rseg_header_create(
|
buf_block_t* rblock = trx_rseg_header_create(
|
||||||
fil_system.temp_space, i, NULL, &mtr);
|
fil_system.temp_space, i, 0, NULL, &mtr);
|
||||||
trx_sys.temp_rsegs[i].init(fil_system.temp_space,
|
trx_sys.temp_rsegs[i].init(fil_system.temp_space,
|
||||||
rblock->page.id().page_no());
|
rblock->page.id().page_no());
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
@@ -191,7 +191,7 @@ trx_sysf_create(
|
|||||||
/* Create the first rollback segment in the SYSTEM tablespace */
|
/* Create the first rollback segment in the SYSTEM tablespace */
|
||||||
slot_no = trx_sys_rseg_find_free(block);
|
slot_no = trx_sys_rseg_find_free(block);
|
||||||
buf_block_t* rblock = trx_rseg_header_create(fil_system.sys_space,
|
buf_block_t* rblock = trx_rseg_header_create(fil_system.sys_space,
|
||||||
slot_no, block, mtr);
|
slot_no, 0, block, mtr);
|
||||||
|
|
||||||
ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
|
ut_a(slot_no == TRX_SYS_SYSTEM_RSEG_ID);
|
||||||
ut_a(rblock->page.id() == page_id_t(0, FSP_FIRST_RSEG_PAGE_NO));
|
ut_a(rblock->page.id() == page_id_t(0, FSP_FIRST_RSEG_PAGE_NO));
|
||||||
@@ -293,7 +293,7 @@ static trx_rseg_t *trx_rseg_create(uint32_t space_id)
|
|||||||
{
|
{
|
||||||
ulint rseg_id= trx_sys_rseg_find_free(sys_header);
|
ulint rseg_id= trx_sys_rseg_find_free(sys_header);
|
||||||
if (buf_block_t *rblock= rseg_id == ULINT_UNDEFINED
|
if (buf_block_t *rblock= rseg_id == ULINT_UNDEFINED
|
||||||
? nullptr : trx_rseg_header_create(space, rseg_id, sys_header,
|
? nullptr : trx_rseg_header_create(space, rseg_id, 0, sys_header,
|
||||||
&mtr))
|
&mtr))
|
||||||
{
|
{
|
||||||
ut_ad(trx_sysf_rseg_get_space(sys_header, rseg_id) == space_id);
|
ut_ad(trx_sysf_rseg_get_space(sys_header, rseg_id) == space_id);
|
||||||
|
218
storage/spider/mysql-test/spider/r/udf_pushdown.result
Normal file
218
storage/spider/mysql-test/spider/r/udf_pushdown.result
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
for master_1
|
||||||
|
for child2
|
||||||
|
child2_1
|
||||||
|
child2_2
|
||||||
|
child2_3
|
||||||
|
for child3
|
||||||
|
child3_1
|
||||||
|
child3_2
|
||||||
|
child3_3
|
||||||
|
#
|
||||||
|
# MDEV-26545 Spider does not correctly handle UDF and stored function in where conds
|
||||||
|
#
|
||||||
|
|
||||||
|
##### enable general_log #####
|
||||||
|
connection child2_1;
|
||||||
|
SET @general_log_backup = @@global.general_log;
|
||||||
|
SET @log_output_backup = @@global.log_output;
|
||||||
|
SET @@global.general_log = 1;
|
||||||
|
SET @@global.log_output = "TABLE";
|
||||||
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
|
||||||
|
##### create databases #####
|
||||||
|
connection master_1;
|
||||||
|
CREATE DATABASE auto_test_local;
|
||||||
|
USE auto_test_local;
|
||||||
|
connection child2_1;
|
||||||
|
CREATE DATABASE auto_test_remote;
|
||||||
|
USE auto_test_remote;
|
||||||
|
|
||||||
|
##### create tables #####
|
||||||
|
connection child2_1;
|
||||||
|
CHILD_CREATE_TABLE
|
||||||
|
connection master_1;
|
||||||
|
MASTER_CREATE_TABLE
|
||||||
|
CREATE TABLE ta_l (
|
||||||
|
id INT NOT NULL,
|
||||||
|
a INT,
|
||||||
|
PRIMARY KEY(id)
|
||||||
|
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
|
||||||
|
INSERT INTO ta_l VALUES
|
||||||
|
(1, 11),
|
||||||
|
(2, 22),
|
||||||
|
(3, 33),
|
||||||
|
(4, 44),
|
||||||
|
(5, 55);
|
||||||
|
|
||||||
|
##### create functions #####
|
||||||
|
connection master_1;
|
||||||
|
CREATE FUNCTION `plusone`( param INT ) RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
RETURN param + 1;
|
||||||
|
END //
|
||||||
|
connection child2_1;
|
||||||
|
CREATE FUNCTION `plusone`( param INT ) RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
RETURN param + 1;
|
||||||
|
END //
|
||||||
|
|
||||||
|
########## spider_use_pushdown_udf=0 ##########
|
||||||
|
connection master_1;
|
||||||
|
SET @@spider_use_pushdown_udf = 0;
|
||||||
|
|
||||||
|
##### test SELECTs #####
|
||||||
|
connection master_1;
|
||||||
|
SELECT * FROM ta_l WHERE id = plusone(1);
|
||||||
|
id a
|
||||||
|
2 22
|
||||||
|
SELECT * FROM ta_l WHERE id IN (plusone(1), plusone(2)) AND a = plusone(32);
|
||||||
|
id a
|
||||||
|
3 33
|
||||||
|
connection child2_1;
|
||||||
|
SELECT argument FROM mysql.general_log WHERE argument LIKE "%select%" AND argument NOT LIKE "%argument%";
|
||||||
|
argument
|
||||||
|
select `id`,`a` from `auto_test_remote`.`ta_r`
|
||||||
|
select `id`,`a` from `auto_test_remote`.`ta_r`
|
||||||
|
|
||||||
|
##### test UPDATEs #####
|
||||||
|
connection master_1;
|
||||||
|
UPDATE ta_l SET a = plusone(221) WHERE id = plusone(1);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
2 222
|
||||||
|
3 33
|
||||||
|
4 44
|
||||||
|
5 55
|
||||||
|
UPDATE ta_l SET a = plusone(332) WHERE id IN (plusone(1), plusone(2)) AND a = plusone(32);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
2 222
|
||||||
|
3 333
|
||||||
|
4 44
|
||||||
|
5 55
|
||||||
|
connection child2_1;
|
||||||
|
SELECT argument FROM mysql.general_log WHERE argument LIKE "%update%" AND argument NOT LIKE "%argument%";
|
||||||
|
argument
|
||||||
|
select `id`,`a` from `auto_test_remote`.`ta_r` for update
|
||||||
|
update `auto_test_remote`.`ta_r` set `a` = 222 where `id` = 2 limit 1
|
||||||
|
select `id`,`a` from `auto_test_remote`.`ta_r` for update
|
||||||
|
update `auto_test_remote`.`ta_r` set `a` = 333 where `id` = 3 and `a` = 33 limit 1
|
||||||
|
|
||||||
|
##### test DELETEs #####
|
||||||
|
connection master_1;
|
||||||
|
DELETE FROM ta_l WHERE id = plusone(1);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
3 333
|
||||||
|
4 44
|
||||||
|
5 55
|
||||||
|
DELETE FROM ta_l WHERE id IN (plusone(1), plusone(2), plusone(3)) AND a = plusone(43);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
3 333
|
||||||
|
5 55
|
||||||
|
connection child2_1;
|
||||||
|
SELECT argument FROM mysql.general_log WHERE (argument LIKE "%delete%" OR argument LIKE "%update%") AND argument NOT LIKE "%argument%";
|
||||||
|
argument
|
||||||
|
select `id` from `auto_test_remote`.`ta_r` for update
|
||||||
|
delete from `auto_test_remote`.`ta_r` where `id` = 2 limit 1
|
||||||
|
select `id`,`a` from `auto_test_remote`.`ta_r` for update
|
||||||
|
delete from `auto_test_remote`.`ta_r` where `id` = 4 and `a` = 44 limit 1
|
||||||
|
|
||||||
|
##### reset records #####
|
||||||
|
connection master_1;
|
||||||
|
TRUNCATE TABLE ta_l;
|
||||||
|
INSERT INTO ta_l VALUES
|
||||||
|
(1, 11),
|
||||||
|
(2, 22),
|
||||||
|
(3, 33),
|
||||||
|
(4, 44),
|
||||||
|
(5, 55);
|
||||||
|
|
||||||
|
########## spider_use_pushdown_udf=1 ##########
|
||||||
|
connection master_1;
|
||||||
|
SET @@spider_use_pushdown_udf = 1;
|
||||||
|
|
||||||
|
##### test SELECTs #####
|
||||||
|
connection master_1;
|
||||||
|
SELECT * FROM ta_l WHERE id = plusone(1);
|
||||||
|
id a
|
||||||
|
2 22
|
||||||
|
SELECT * FROM ta_l WHERE id IN (plusone(1), plusone(2)) AND a = plusone(32);
|
||||||
|
id a
|
||||||
|
3 33
|
||||||
|
connection child2_1;
|
||||||
|
SELECT argument FROM mysql.general_log WHERE argument LIKE "%select%" AND argument NOT LIKE "%argument%";
|
||||||
|
argument
|
||||||
|
select t0.`id` `id`,t0.`a` `a` from `auto_test_remote`.`ta_r` t0 where (t0.`id` = (`plusone`(1)))
|
||||||
|
select t0.`id` `id`,t0.`a` `a` from `auto_test_remote`.`ta_r` t0 where ((t0.`id` in( (`plusone`(1)) , (`plusone`(2)))) and (t0.`a` = (`plusone`(32))))
|
||||||
|
|
||||||
|
##### test UPDATEs #####
|
||||||
|
connection master_1;
|
||||||
|
UPDATE ta_l SET a = plusone(221) WHERE id = plusone(1);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
2 222
|
||||||
|
3 33
|
||||||
|
4 44
|
||||||
|
5 55
|
||||||
|
UPDATE ta_l SET a = plusone(332) WHERE id IN (plusone(1), plusone(2)) AND a = plusone(32);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
2 222
|
||||||
|
3 333
|
||||||
|
4 44
|
||||||
|
5 55
|
||||||
|
connection child2_1;
|
||||||
|
SELECT argument FROM mysql.general_log WHERE argument LIKE "%update%" AND argument NOT LIKE "%argument%";
|
||||||
|
argument
|
||||||
|
update `auto_test_remote`.`ta_r` set `a` = (`plusone`(221)) where (`id` = (`plusone`(1)))
|
||||||
|
update `auto_test_remote`.`ta_r` set `a` = (`plusone`(332)) where ((`id` in( (`plusone`(1)) , (`plusone`(2)))) and (`a` = (`plusone`(32))))
|
||||||
|
|
||||||
|
##### test DELETEs #####
|
||||||
|
connection master_1;
|
||||||
|
DELETE FROM ta_l WHERE id = plusone(1);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
3 333
|
||||||
|
4 44
|
||||||
|
5 55
|
||||||
|
DELETE FROM ta_l WHERE id IN (plusone(1), plusone(2), plusone(3)) AND a = plusone(43);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
id a
|
||||||
|
1 11
|
||||||
|
3 333
|
||||||
|
5 55
|
||||||
|
connection child2_1;
|
||||||
|
SELECT argument FROM mysql.general_log WHERE (argument LIKE "%delete%" OR argument LIKE "%update%") AND argument NOT LIKE "%argument%";
|
||||||
|
argument
|
||||||
|
delete from `auto_test_remote`.`ta_r` where (`id` = (`plusone`(1)))
|
||||||
|
delete from `auto_test_remote`.`ta_r` where ((`id` in( (`plusone`(1)) , (`plusone`(2)) , (`plusone`(3)))) and (`a` = (`plusone`(43))))
|
||||||
|
|
||||||
|
deinit
|
||||||
|
connection master_1;
|
||||||
|
DROP FUNCTION `plusone`;
|
||||||
|
DROP DATABASE IF EXISTS auto_test_local;
|
||||||
|
connection child2_1;
|
||||||
|
SET @@global.general_log = @general_log_backup;
|
||||||
|
SET @@global.log_output = @log_output_backup;
|
||||||
|
DROP FUNCTION `plusone`;
|
||||||
|
DROP DATABASE IF EXISTS auto_test_remote;
|
||||||
|
for master_1
|
||||||
|
for child2
|
||||||
|
child2_1
|
||||||
|
child2_2
|
||||||
|
child2_3
|
||||||
|
for child3
|
||||||
|
child3_1
|
||||||
|
child3_2
|
||||||
|
child3_3
|
||||||
|
|
||||||
|
end of test
|
48
storage/spider/mysql-test/spider/t/udf_pushdown.inc
Normal file
48
storage/spider/mysql-test/spider/t/udf_pushdown.inc
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
--echo
|
||||||
|
--echo ##### test SELECTs #####
|
||||||
|
--connection master_1
|
||||||
|
SELECT * FROM ta_l WHERE id = plusone(1);
|
||||||
|
SELECT * FROM ta_l WHERE id IN (plusone(1), plusone(2)) AND a = plusone(32);
|
||||||
|
|
||||||
|
if ($USE_CHILD_GROUP2)
|
||||||
|
{
|
||||||
|
--connection child2_1
|
||||||
|
SELECT argument FROM mysql.general_log WHERE argument LIKE "%select%" AND argument NOT LIKE "%argument%";
|
||||||
|
--disable_query_log
|
||||||
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
--enable_query_log
|
||||||
|
}
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ##### test UPDATEs #####
|
||||||
|
--connection master_1
|
||||||
|
UPDATE ta_l SET a = plusone(221) WHERE id = plusone(1);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
UPDATE ta_l SET a = plusone(332) WHERE id IN (plusone(1), plusone(2)) AND a = plusone(32);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
|
||||||
|
if ($USE_CHILD_GROUP2)
|
||||||
|
{
|
||||||
|
--connection child2_1
|
||||||
|
SELECT argument FROM mysql.general_log WHERE argument LIKE "%update%" AND argument NOT LIKE "%argument%";
|
||||||
|
--disable_query_log
|
||||||
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
--enable_query_log
|
||||||
|
}
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ##### test DELETEs #####
|
||||||
|
--connection master_1
|
||||||
|
DELETE FROM ta_l WHERE id = plusone(1);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
DELETE FROM ta_l WHERE id IN (plusone(1), plusone(2), plusone(3)) AND a = plusone(43);
|
||||||
|
SELECT * FROM ta_l;
|
||||||
|
|
||||||
|
if ($USE_CHILD_GROUP2)
|
||||||
|
{
|
||||||
|
--connection child2_1
|
||||||
|
SELECT argument FROM mysql.general_log WHERE (argument LIKE "%delete%" OR argument LIKE "%update%") AND argument NOT LIKE "%argument%";
|
||||||
|
--disable_query_log
|
||||||
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
--enable_query_log
|
||||||
|
}
|
141
storage/spider/mysql-test/spider/t/udf_pushdown.test
Normal file
141
storage/spider/mysql-test/spider/t/udf_pushdown.test
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
--disable_warnings
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
--source test_init.inc
|
||||||
|
--enable_result_log
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-26545 Spider does not correctly handle UDF and stored function in where conds
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
let $CHILD_CREATE_TABLE=
|
||||||
|
CREATE TABLE ta_r (
|
||||||
|
id INT NOT NULL,
|
||||||
|
a INT,
|
||||||
|
PRIMARY KEY(id)
|
||||||
|
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
|
||||||
|
|
||||||
|
let $MASTER_CREATE_TABLE_OUTPUT=
|
||||||
|
CREATE TABLE ta_l (
|
||||||
|
id INT NOT NULL,
|
||||||
|
a INT,
|
||||||
|
PRIMARY KEY(id)
|
||||||
|
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
|
||||||
|
|
||||||
|
let $MASTER_CREATE_TABLE=
|
||||||
|
CREATE TABLE ta_l (
|
||||||
|
id INT NOT NULL,
|
||||||
|
a INT,
|
||||||
|
PRIMARY KEY(id)
|
||||||
|
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ##### enable general_log #####
|
||||||
|
--connection child2_1
|
||||||
|
SET @general_log_backup = @@global.general_log;
|
||||||
|
SET @log_output_backup = @@global.log_output;
|
||||||
|
SET @@global.general_log = 1;
|
||||||
|
SET @@global.log_output = "TABLE";
|
||||||
|
TRUNCATE TABLE mysql.general_log;
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ##### create databases #####
|
||||||
|
--connection master_1
|
||||||
|
CREATE DATABASE auto_test_local;
|
||||||
|
USE auto_test_local;
|
||||||
|
if ($USE_CHILD_GROUP2)
|
||||||
|
{
|
||||||
|
--connection child2_1
|
||||||
|
CREATE DATABASE auto_test_remote;
|
||||||
|
USE auto_test_remote;
|
||||||
|
}
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ##### create tables #####
|
||||||
|
if ($USE_CHILD_GROUP2)
|
||||||
|
{
|
||||||
|
--connection child2_1
|
||||||
|
--disable_query_log
|
||||||
|
echo CHILD_CREATE_TABLE;
|
||||||
|
eval $CHILD_CREATE_TABLE;
|
||||||
|
--enable_query_log
|
||||||
|
}
|
||||||
|
|
||||||
|
--connection master_1
|
||||||
|
--disable_query_log
|
||||||
|
echo MASTER_CREATE_TABLE;
|
||||||
|
echo $MASTER_CREATE_TABLE_OUTPUT;
|
||||||
|
eval $MASTER_CREATE_TABLE;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
INSERT INTO ta_l VALUES
|
||||||
|
(1, 11),
|
||||||
|
(2, 22),
|
||||||
|
(3, 33),
|
||||||
|
(4, 44),
|
||||||
|
(5, 55);
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ##### create functions #####
|
||||||
|
--connection master_1
|
||||||
|
DELIMITER //;
|
||||||
|
CREATE FUNCTION `plusone`( param INT ) RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
RETURN param + 1;
|
||||||
|
END //
|
||||||
|
DELIMITER ;//
|
||||||
|
|
||||||
|
--connection child2_1
|
||||||
|
DELIMITER //;
|
||||||
|
CREATE FUNCTION `plusone`( param INT ) RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
RETURN param + 1;
|
||||||
|
END //
|
||||||
|
DELIMITER ;//
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ########## spider_use_pushdown_udf=0 ##########
|
||||||
|
--connection master_1
|
||||||
|
SET @@spider_use_pushdown_udf = 0;
|
||||||
|
--source udf_pushdown.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ##### reset records #####
|
||||||
|
--connection master_1
|
||||||
|
TRUNCATE TABLE ta_l;
|
||||||
|
INSERT INTO ta_l VALUES
|
||||||
|
(1, 11),
|
||||||
|
(2, 22),
|
||||||
|
(3, 33),
|
||||||
|
(4, 44),
|
||||||
|
(5, 55);
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo ########## spider_use_pushdown_udf=1 ##########
|
||||||
|
--connection master_1
|
||||||
|
SET @@spider_use_pushdown_udf = 1;
|
||||||
|
--source udf_pushdown.inc
|
||||||
|
|
||||||
|
--echo
|
||||||
|
--echo deinit
|
||||||
|
--disable_warnings
|
||||||
|
--connection master_1
|
||||||
|
DROP FUNCTION `plusone`;
|
||||||
|
DROP DATABASE IF EXISTS auto_test_local;
|
||||||
|
if ($USE_CHILD_GROUP2)
|
||||||
|
{
|
||||||
|
--connection child2_1
|
||||||
|
SET @@global.general_log = @general_log_backup;
|
||||||
|
SET @@global.log_output = @log_output_backup;
|
||||||
|
DROP FUNCTION `plusone`;
|
||||||
|
DROP DATABASE IF EXISTS auto_test_remote;
|
||||||
|
}
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
--source test_deinit.inc
|
||||||
|
--enable_result_log
|
||||||
|
--enable_query_log
|
||||||
|
--enable_warnings
|
||||||
|
--echo
|
||||||
|
--echo end of test
|
@@ -6676,11 +6676,17 @@ int spider_db_mbase_util::open_item_func(
|
|||||||
separator_str_length = SPIDER_SQL_AND_LEN;
|
separator_str_length = SPIDER_SQL_AND_LEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Item_func::FUNC_SP:
|
||||||
case Item_func::UDF_FUNC:
|
case Item_func::UDF_FUNC:
|
||||||
use_pushdown_udf = spider_param_use_pushdown_udf(
|
use_pushdown_udf = spider_param_use_pushdown_udf(
|
||||||
spider->wide_handler->trx->thd,
|
spider->wide_handler->trx->thd,
|
||||||
spider->share->use_pushdown_udf);
|
spider->share->use_pushdown_udf);
|
||||||
if (!use_pushdown_udf)
|
if (!use_pushdown_udf)
|
||||||
|
/*
|
||||||
|
This is the default behavior because the remote nodes may deal with
|
||||||
|
the function in an unexpected way (e.g. not having the same
|
||||||
|
definition). Users can turn it on if they know what they are doing.
|
||||||
|
*/
|
||||||
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
|
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
|
@@ -2005,7 +2005,7 @@ static MYSQL_THDVAR_INT(
|
|||||||
"Remote server transmission existence when UDF is used at condition and \"engine_condition_pushdown=1\"", /* comment */
|
"Remote server transmission existence when UDF is used at condition and \"engine_condition_pushdown=1\"", /* comment */
|
||||||
NULL, /* check */
|
NULL, /* check */
|
||||||
NULL, /* update */
|
NULL, /* update */
|
||||||
-1, /* def */
|
0, /* def */
|
||||||
-1, /* min */
|
-1, /* min */
|
||||||
1, /* max */
|
1, /* max */
|
||||||
0 /* blk */
|
0 /* blk */
|
||||||
|
Submodule wsrep-lib updated: 4f1c201c9d...efb4aab090
Reference in New Issue
Block a user