mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Merge 11.0 into 11.1
This commit is contained in:
commit
6e58d5ab6a
105 changed files with 2944 additions and 1547 deletions
|
@ -331,6 +331,7 @@ mysql-test-run-asan:
|
|||
needs:
|
||||
- "fedora-sanitizer: [-DWITH_ASAN=YES]"
|
||||
<<: *mysql-test-run-def
|
||||
allow_failure: true
|
||||
artifacts:
|
||||
when: always # Also show results when tests fail
|
||||
reports:
|
||||
|
@ -489,6 +490,8 @@ mini-benchmark:
|
|||
stage: test
|
||||
dependencies:
|
||||
- fedora
|
||||
needs:
|
||||
- fedora
|
||||
script:
|
||||
- ls -la rpm; rm -vf rpm/*.el?.* # Delete artifacts from Centos builds
|
||||
# Don't use cracklib, otherwise the Sysbench user password will be rejected
|
||||
|
@ -503,7 +506,7 @@ mini-benchmark:
|
|||
- |
|
||||
mariadb --skip-column-names -e "SELECT @@version, @@version_comment" | tee /tmp/version
|
||||
grep $MARIADB_MAJOR_VERSION /tmp/version || echo "MariaDB didn't install properly"
|
||||
- yum install -y sysbench procps-ng perf || yum install -y https://kojipkgs.fedoraproject.org//packages/luajit/2.0.4/3.el7/x86_64/luajit-2.0.4-3.el7.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/sysbench/1.0.17/2.el7/x86_64/sysbench-1.0.17-2.el7.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/ck/0.5.2/2.el7/x86_64/ck-0.5.2-2.el7.x86_64.rpm
|
||||
- yum install -y sysbench procps-ng perf util-linux || yum install -y https://kojipkgs.fedoraproject.org//packages/luajit/2.0.4/3.el7/x86_64/luajit-2.0.4-3.el7.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/sysbench/1.0.17/2.el7/x86_64/sysbench-1.0.17-2.el7.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/ck/0.5.2/2.el7/x86_64/ck-0.5.2-2.el7.x86_64.rpm
|
||||
- /usr/share/mysql/mini-benchmark
|
||||
- cp -av */sysbench-run-*.log */metrics.txt .. # Move files one level down so they can be saved as artifacts
|
||||
artifacts:
|
||||
|
|
1
debian/libmariadb-dev.install
vendored
1
debian/libmariadb-dev.install
vendored
|
@ -15,6 +15,7 @@ usr/include/mariadb/mariadb_version.h
|
|||
usr/include/mariadb/my_config.h
|
||||
usr/include/mariadb/my_global.h
|
||||
usr/include/mariadb/my_sys.h
|
||||
usr/include/mariadb/my_alloca.h
|
||||
usr/include/mariadb/mysql.h
|
||||
usr/include/mariadb/mysql/
|
||||
usr/include/mariadb/mysql/client_plugin.h
|
||||
|
|
1
debian/mariadb-server-core.install
vendored
1
debian/mariadb-server-core.install
vendored
|
@ -19,6 +19,7 @@ usr/share/mysql/estonian
|
|||
usr/share/mysql/fill_help_tables.sql
|
||||
usr/share/mysql/french
|
||||
usr/share/mysql/german
|
||||
usr/share/mysql/georgian
|
||||
usr/share/mysql/greek
|
||||
usr/share/mysql/hindi
|
||||
usr/share/mysql/hungarian
|
||||
|
|
108
debian/po/ka.po
vendored
Normal file
108
debian/po/ka.po
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
# Translation of ka.po to Georgian
|
||||
# Copyright (C) 2023, MariaDB authors.
|
||||
# This file is distributed under the same license as the mariadb package.
|
||||
# Ekaterine Papava <papava.e@gtu.ge>, 2023.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mariadb\n"
|
||||
"Report-Msgid-Bugs-To: mariadb@packages.debian.org\n"
|
||||
"POT-Creation-Date: 2019-07-23 19:16-0300\n"
|
||||
"PO-Revision-Date: 2023-03-04 05:18+0100\n"
|
||||
"Last-Translator: Ekaterine Papava <papava.e@gtu.ge>\n"
|
||||
"Language-Team: Georgian <(nothing)>\n"
|
||||
"Language: ka\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.2.2\n"
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:2001
|
||||
msgid "The old data directory will be saved at new location"
|
||||
msgstr "ძველი მონაცემების საქაღალდე ახალ მდებარეობაზე იქნება შენახული"
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:2001
|
||||
msgid ""
|
||||
"A file named /var/lib/mysql/debian-*.flag exists on this system. The number "
|
||||
"indicates a database binary format version that cannot automatically be "
|
||||
"upgraded (or downgraded)."
|
||||
msgstr ""
|
||||
"ამ სისტემაში არსებობს ფაილი სახელით /var/lib/mysql/debian-*.flag. რიცხვი "
|
||||
"მიუთითებს ბაზის ბინარული ფორმატის ვერსიაზე, რომლის განახლება (ან ვერსიის "
|
||||
"ჩამოწევა) შეუძლებელია."
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:2001
|
||||
msgid ""
|
||||
"Therefore the previous data directory will be renamed to /var/lib/mysql-* "
|
||||
"and a new data directory will be initialized at /var/lib/mysql."
|
||||
msgstr ""
|
||||
"ამიტომ წინა მონაცემების საქაღალდეს სახელი /var/lib/mysql-*-ზე გადაერქმევა "
|
||||
"და /var/lib/mysql მონაცემების საქაღალდე თავიდან შეიქმნება."
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:2001
|
||||
msgid ""
|
||||
"Please manually export/import your data (e.g. with mysqldump) if needed."
|
||||
msgstr ""
|
||||
"საჭიროების შემთხვევაში თქვენი მონაცემები ხელით გაიტანეთ/შემოიტანეთ (მაგ: "
|
||||
"mysqldump-ით)."
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:3001
|
||||
msgid "Important note for NIS/YP users"
|
||||
msgstr "მნიშვნელოვანი შენიშვნა NIS/YP მომხმარებლებისთვის"
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:3001
|
||||
msgid ""
|
||||
"Using MariaDB under NIS/YP requires a mysql user account to be added on the "
|
||||
"local system with:"
|
||||
msgstr ""
|
||||
"MariaDB-ის გამოყენება NIS/YP-ის ქვეშ გასაშვებად მოითხოვს ლოკალურ სისტემაში "
|
||||
"mysql-ის მომხმარებლის დამატებას შემდეგი პარამეტრებით:"
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:3001
|
||||
msgid ""
|
||||
"You should also check the permissions and ownership of the /var/lib/mysql "
|
||||
"directory:"
|
||||
msgstr "ასევე შეამოწმეთ /var/lib/mysql საქაღალდის წვდომები და მფლობელი:"
|
||||
|
||||
#. Type: boolean
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:4001
|
||||
msgid "Remove all MariaDB databases?"
|
||||
msgstr "წავშალო MariaDB-ის ყველა ბაზა?"
|
||||
|
||||
#. Type: boolean
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:4001
|
||||
msgid ""
|
||||
"The /var/lib/mysql directory which contains the MariaDB databases is about "
|
||||
"to be removed."
|
||||
msgstr ""
|
||||
"საქაღალდე /var/lib/mysql, რომელიც MariaDB-ის მონაცემთა ბაზებს შეიცავს, "
|
||||
"წაიშლება."
|
||||
|
||||
#. Type: boolean
|
||||
#. Description
|
||||
#: ../mariadb-server.templates:4001
|
||||
msgid ""
|
||||
"If you're removing the MariaDB package in order to later install a more "
|
||||
"recent version or if a different mariadb-server package is already using it, "
|
||||
"the data should be kept."
|
||||
msgstr ""
|
||||
"თუ შლით MariaDB-ის პაკეტს იმისთვის, რომ მოგვიანებით უფრო ახალი ვერსია "
|
||||
"დააყენოთ ან mariadb-server-ის სხვა პაკეტი უკვე იყენებს მას, მონაცემები უნდა "
|
||||
"შენარჩუნდეს."
|
|
@ -37,7 +37,7 @@
|
|||
#define ERRORS_PER_RANGE 1000
|
||||
#define MAX_SECTIONS 4
|
||||
#define HEADER_LENGTH 32 /* Length of header in errmsg.sys */
|
||||
#define ERRMSG_VERSION 4 /* Version number of errmsg.sys */
|
||||
#define ERRMSG_VERSION 5 /* Version number of errmsg.sys */
|
||||
#define DEFAULT_CHARSET_DIR "../sql/share/charsets"
|
||||
#define ER_PREFIX "ER_"
|
||||
#define ER_PREFIX2 "MARIA_ER_"
|
||||
|
@ -85,7 +85,6 @@ struct languages
|
|||
{
|
||||
char *lang_long_name; /* full name of the language */
|
||||
char *lang_short_name; /* abbreviation of the lang. */
|
||||
char *charset; /* Character set name */
|
||||
struct languages *next_lang; /* Pointer to next language */
|
||||
};
|
||||
|
||||
|
@ -329,7 +328,7 @@ static int create_sys_files(struct languages *lang_head,
|
|||
uint error_count)
|
||||
{
|
||||
FILE *to;
|
||||
uint csnum= 0, i, row_nr;
|
||||
uint i, row_nr;
|
||||
ulong length;
|
||||
uchar head[HEADER_LENGTH];
|
||||
char outfile[FN_REFLEN], *outfile_end;
|
||||
|
@ -345,16 +344,6 @@ static int create_sys_files(struct languages *lang_head,
|
|||
*/
|
||||
for (tmp_lang= lang_head; tmp_lang; tmp_lang= tmp_lang->next_lang)
|
||||
{
|
||||
|
||||
/* setting charset name */
|
||||
if (!(csnum= get_charset_number(tmp_lang->charset, MY_CS_PRIMARY,
|
||||
MYF(MY_UTF8_IS_UTF8MB3))))
|
||||
{
|
||||
fprintf(stderr, "Unknown charset '%s' in '%s'\n", tmp_lang->charset,
|
||||
TXTFILE);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
outfile_end= strxmov(outfile, DATADIRECTORY,
|
||||
tmp_lang->lang_long_name, NullS);
|
||||
if (!my_stat(outfile, &stat_info,MYF(0)))
|
||||
|
@ -410,7 +399,6 @@ static int create_sys_files(struct languages *lang_head,
|
|||
int2store(head + 10, max_error); /* Max error */
|
||||
int2store(head + 12, row_nr);
|
||||
int2store(head + 14, section_count);
|
||||
head[30]= csnum;
|
||||
|
||||
my_fseek(to, 0l, MY_SEEK_SET, MYF(0));
|
||||
if (my_fwrite(to, (uchar*) head, HEADER_LENGTH, MYF(MY_WME | MY_FNABP)) ||
|
||||
|
@ -450,7 +438,6 @@ static void clean_up(struct languages *lang_head, struct errors *error_head)
|
|||
next_language= tmp_lang->next_lang;
|
||||
my_free(tmp_lang->lang_short_name);
|
||||
my_free(tmp_lang->lang_long_name);
|
||||
my_free(tmp_lang->charset);
|
||||
my_free(tmp_lang);
|
||||
}
|
||||
|
||||
|
@ -1113,12 +1100,6 @@ static struct languages *parse_charset_string(char *str)
|
|||
DBUG_RETURN(0); /* OOM: Fatal error */
|
||||
DBUG_PRINT("info", ("short_name: %s", new_lang->lang_short_name));
|
||||
|
||||
/* getting the charset name */
|
||||
str= skip_delimiters(str);
|
||||
if (!(new_lang->charset= get_word(&str)))
|
||||
DBUG_RETURN(0); /* Fatal error */
|
||||
DBUG_PRINT("info", ("charset: %s", new_lang->charset));
|
||||
|
||||
/* skipping space, tab or "," */
|
||||
str= skip_delimiters(str);
|
||||
}
|
||||
|
|
|
@ -2270,8 +2270,14 @@ static bool innodb_init()
|
|||
/* Check if the data files exist or not. */
|
||||
dberr_t err= srv_sys_space.check_file_spec(&create_new_db, 5U << 20);
|
||||
|
||||
if (create_new_db)
|
||||
{
|
||||
msg("mariadb-backup: InnoDB files do not exist");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (err == DB_SUCCESS)
|
||||
err= srv_start(create_new_db);
|
||||
err= srv_start(false);
|
||||
|
||||
if (err != DB_SUCCESS)
|
||||
{
|
||||
|
@ -2282,6 +2288,7 @@ static bool innodb_init()
|
|||
ut_ad(srv_force_recovery <= SRV_FORCE_IGNORE_CORRUPT);
|
||||
ut_ad(recv_no_log_write);
|
||||
buf_flush_sync();
|
||||
recv_sys.debug_free();
|
||||
DBUG_ASSERT(!buf_pool.any_io_pending());
|
||||
log_sys.close_file();
|
||||
|
||||
|
@ -3497,7 +3504,9 @@ static void xb_load_single_table_tablespace(const char *dirname,
|
|||
if (err == DB_SUCCESS && file->space_id() != SRV_TMP_SPACE_ID) {
|
||||
space = fil_space_t::create(
|
||||
file->space_id(), file->flags(),
|
||||
FIL_TYPE_TABLESPACE, NULL/* TODO: crypt_data */);
|
||||
FIL_TYPE_TABLESPACE, nullptr/* TODO: crypt_data */,
|
||||
FIL_ENCRYPTION_DEFAULT,
|
||||
file->handle() != OS_FILE_CLOSED);
|
||||
|
||||
ut_a(space != NULL);
|
||||
fil_node_t* node= space->add(
|
||||
|
@ -5217,7 +5226,8 @@ exit:
|
|||
ut_ad(fil_space_t::physical_size(flags) == info.page_size);
|
||||
|
||||
if (fil_space_t::create(info.space_id, flags,
|
||||
FIL_TYPE_TABLESPACE, 0)) {
|
||||
FIL_TYPE_TABLESPACE, 0, FIL_ENCRYPTION_DEFAULT,
|
||||
true)) {
|
||||
*success = xb_space_create_file(real_name, info.space_id,
|
||||
flags, &file);
|
||||
} else {
|
||||
|
|
|
@ -51,6 +51,8 @@ static struct my_option my_long_options[] =
|
|||
#endif
|
||||
{"mysqld", 0, "Read the same set of groups that the mysqld binary does.",
|
||||
&opt_mysqld, &opt_mysqld, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"mariadbd", 0, "Read the same set of groups that the mariadbd binary does.",
|
||||
&opt_mysqld, &opt_mysqld, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"no-defaults", 'n', "Return an empty string (useful for scripts).",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", '?', "Display this help message and exit.",
|
||||
|
|
|
@ -37,6 +37,7 @@ SET(HEADERS
|
|||
ma_dyncol.h
|
||||
my_list.h
|
||||
my_alloc.h
|
||||
my_alloca.h
|
||||
typelib.h
|
||||
my_dbug.h
|
||||
m_string.h
|
||||
|
@ -111,7 +112,9 @@ ${footer}
|
|||
ENDMACRO()
|
||||
|
||||
INSTALL_COMPAT_HEADER(my_global.h "")
|
||||
INSTALL_COMPAT_HEADER(my_alloca.h "")
|
||||
INSTALL_COMPAT_HEADER(my_config.h "")
|
||||
INSTALL_COMPAT_HEADER(my_alloca.h "")
|
||||
INSTALL_COMPAT_HEADER(my_sys.h "")
|
||||
INSTALL_COMPAT_HEADER(mysql_version.h "
|
||||
#include <mariadb_version.h>
|
||||
|
|
45
include/my_alloca.h
Normal file
45
include/my_alloca.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* Copyright (c) 2023, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software 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 MY_ALLOCA_INCLUDED
|
||||
#define MY_ALLOCA_INCLUDED
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h> /*for alloca*/
|
||||
/*
|
||||
MSVC may define "alloca" when compiling in /Ze mode
|
||||
(with extensions from Microsoft), but otherwise only
|
||||
the _alloca function is defined:
|
||||
*/
|
||||
#ifndef alloca
|
||||
#define alloca _alloca
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ALLOCA)
|
||||
/*
|
||||
If the GCC/LLVM compiler from the MinGW is used,
|
||||
alloca may not be defined when using the MSVC CRT:
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) && !defined(alloca)
|
||||
#define alloca __builtin_alloca
|
||||
#endif /* GNUC */
|
||||
#endif
|
||||
|
||||
#endif /* MY_ALLOCA_INCLUDED */
|
|
@ -330,13 +330,6 @@ C_MODE_END
|
|||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA)
|
||||
#undef HAVE_ALLOCA
|
||||
#undef HAVE_ALLOCA_H
|
||||
#endif
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h> /* Recommended by debian */
|
||||
/* We need the following to go around a problem with openssl on solaris */
|
||||
|
@ -493,6 +486,7 @@ typedef unsigned short ushort;
|
|||
#endif
|
||||
|
||||
#include <my_compiler.h>
|
||||
#include <my_alloca.h>
|
||||
|
||||
/*
|
||||
Wen using the embedded library, users might run into link problems,
|
||||
|
|
|
@ -28,9 +28,7 @@ C_MODE_START
|
|||
#include <m_ctype.h> /* for CHARSET_INFO */
|
||||
#include <stdarg.h>
|
||||
#include <typelib.h>
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h> /*for alloca*/
|
||||
#endif
|
||||
#include <my_alloca.h>
|
||||
#include <mysql/plugin.h>
|
||||
#include <mysql/service_my_print_error.h>
|
||||
|
||||
|
@ -195,16 +193,6 @@ my_bool my_test_if_thinly_provisioned(File handle);
|
|||
extern my_bool my_may_have_atomic_write;
|
||||
|
||||
#if defined(HAVE_ALLOCA) && !defined(HAVE_valgrind)
|
||||
#if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43)
|
||||
#pragma alloca
|
||||
#endif /* _AIX */
|
||||
#if defined(__MWERKS__)
|
||||
#undef alloca
|
||||
#define alloca _alloca
|
||||
#endif /* __MWERKS__ */
|
||||
#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) && ! defined(alloca)
|
||||
#define alloca __builtin_alloca
|
||||
#endif /* GNUC */
|
||||
#define my_alloca(SZ) alloca((size_t) (SZ))
|
||||
#define my_afree(PTR) ((void)0)
|
||||
#define MAX_ALLOCA_SZ 4096
|
||||
|
|
|
@ -24,22 +24,19 @@
|
|||
*provider* (encryption plugin).
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MYSQL_ABI_CHECK
|
||||
#include <my_alloca.h>
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h>
|
||||
#ifndef __cplusplus
|
||||
#define inline __inline
|
||||
#endif
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* returned from encryption_key_get_latest_version() */
|
||||
|
|
|
@ -22610,3 +22610,20 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
drop view v1;
|
||||
drop table t1;
|
||||
# End of 10.4 tests
|
||||
#
|
||||
# MDEV-28958: condition pushable into view after simplification
|
||||
# contains constant TRUE/FALSE as subformula
|
||||
#
|
||||
create table t1 (c1 int);
|
||||
insert into t1 values (3), (7), (1), (3), (1), (3);
|
||||
create table t2 (c2 int);
|
||||
insert into t2 values (3), (5), (7), (3);
|
||||
create view v1 as select * from t1 group by c1;
|
||||
create view v2 as select c1 as a, c2 as b from v1,t2 where c1=c2;
|
||||
select * from v2 group by a,b having a=b or b > a+10;
|
||||
a b
|
||||
3 3
|
||||
7 7
|
||||
drop view v1,v2;
|
||||
drop table t1,t2;
|
||||
# End of 10.7 tests
|
||||
|
|
|
@ -4144,3 +4144,24 @@ drop view v1;
|
|||
drop table t1;
|
||||
|
||||
--echo # End of 10.4 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-28958: condition pushable into view after simplification
|
||||
--echo # contains constant TRUE/FALSE as subformula
|
||||
--echo #
|
||||
|
||||
create table t1 (c1 int);
|
||||
insert into t1 values (3), (7), (1), (3), (1), (3);
|
||||
|
||||
create table t2 (c2 int);
|
||||
insert into t2 values (3), (5), (7), (3);
|
||||
|
||||
create view v1 as select * from t1 group by c1;
|
||||
create view v2 as select c1 as a, c2 as b from v1,t2 where c1=c2;
|
||||
|
||||
select * from v2 group by a,b having a=b or b > a+10;
|
||||
|
||||
drop view v1,v2;
|
||||
drop table t1,t2;
|
||||
|
||||
--echo # End of 10.7 tests
|
||||
|
|
|
@ -306,3 +306,13 @@ date_format('2001-01-06', '%w %a %W', 'de_CH')
|
|||
select date_format('2001-09-01', '%c %b %M', 'de_CH');
|
||||
date_format('2001-09-01', '%c %b %M', 'de_CH')
|
||||
9 Sep September
|
||||
#
|
||||
# MDEV-30789 Add Georgian error messages and locale
|
||||
#
|
||||
SET lc_messages=ka_GE;
|
||||
SELECT x;
|
||||
ERROR 42S22: უცნობი სვეტი 'x' 'field list'-ში
|
||||
SET lc_messages=DEFAULT;
|
||||
#
|
||||
# End of 10.11 tests
|
||||
#
|
||||
|
|
|
@ -181,3 +181,18 @@ select date_format('2001-10-01', '%c %b %M', 'rm_CH');
|
|||
select date_format('2001-12-01', '%c %b %M', 'rm_CH');
|
||||
select date_format('2001-01-06', '%w %a %W', 'de_CH');
|
||||
select date_format('2001-09-01', '%c %b %M', 'de_CH');
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30789 Add Georgian error messages and locale
|
||||
--echo #
|
||||
|
||||
SET lc_messages=ka_GE;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
SELECT x;
|
||||
|
||||
SET lc_messages=DEFAULT;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.11 tests
|
||||
--echo #
|
||||
|
|
|
@ -20,3 +20,24 @@ create table t1 (a varchar(1), primary key (a))
|
|||
partition by list (ascii(a))
|
||||
(partition p1 values in (65));
|
||||
ERROR HY000: This partition function is not allowed
|
||||
#
|
||||
# Start of 10.9 tests
|
||||
#
|
||||
#
|
||||
# MDEV-30805 SIGSEGV in my_convert and UBSAN: member access within null pointer of type 'const struct MY_CHARSET_HANDLER' in my_convert
|
||||
#
|
||||
CREATE TABLE t1 (a CHAR CHARACTER SET ucs2)
|
||||
PARTITION BY RANGE COLUMNS (a)
|
||||
(PARTITION p0 VALUES LESS THAN ('a'));
|
||||
ALTER TABLE t1 CHANGE COLUMN a a CHAR BINARY;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(1) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
PARTITION BY RANGE COLUMNS(`a`)
|
||||
(PARTITION `p0` VALUES LESS THAN ('a') ENGINE = MyISAM)
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 10.9 tests
|
||||
#
|
||||
|
|
|
@ -27,3 +27,23 @@ partition by list (ascii(a))
|
|||
#insert into t1 values ('A');
|
||||
#replace into t1 values ('A');
|
||||
#drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.9 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30805 SIGSEGV in my_convert and UBSAN: member access within null pointer of type 'const struct MY_CHARSET_HANDLER' in my_convert
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a CHAR CHARACTER SET ucs2)
|
||||
PARTITION BY RANGE COLUMNS (a)
|
||||
(PARTITION p0 VALUES LESS THAN ('a'));
|
||||
ALTER TABLE t1 CHANGE COLUMN a a CHAR BINARY;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.9 tests
|
||||
--echo #
|
||||
|
||||
|
|
24
mysql-test/main/partition_innodb2.result
Normal file
24
mysql-test/main/partition_innodb2.result
Normal file
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# MDEV-30442: Assertion `!m_innodb' failed in ha_partition::cmp_ref on MULTI-DELETE
|
||||
#
|
||||
create table t1 (a int) engine=innodb;
|
||||
insert into t1 values (1),(2),(1),(2);
|
||||
create table t2 (
|
||||
a int,
|
||||
b int,
|
||||
key(a)
|
||||
) engine=innodb partition by list(a)
|
||||
(
|
||||
partition p0 values in (1),
|
||||
partition p1 values in (2),
|
||||
partition p2 values in (0,3,4,5,6,7,8,9)
|
||||
);
|
||||
insert into t2 select
|
||||
mod(seq, 10), seq from seq_1_to_50;
|
||||
explain
|
||||
delete t1, t2 from t1, t2 where t1.a=t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
|
||||
1 SIMPLE t2 ref a a 5 test.t1.a 1
|
||||
delete t1, t2 from t1, t2 where t1.a=t2.a;
|
||||
drop table t1,t2;
|
30
mysql-test/main/partition_innodb2.test
Normal file
30
mysql-test/main/partition_innodb2.test
Normal file
|
@ -0,0 +1,30 @@
|
|||
--source include/not_embedded.inc
|
||||
--source include/have_partition.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_sequence.inc
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30442: Assertion `!m_innodb' failed in ha_partition::cmp_ref on MULTI-DELETE
|
||||
--echo #
|
||||
create table t1 (a int) engine=innodb;
|
||||
insert into t1 values (1),(2),(1),(2);
|
||||
|
||||
create table t2 (
|
||||
a int,
|
||||
b int,
|
||||
key(a)
|
||||
) engine=innodb partition by list(a)
|
||||
(
|
||||
partition p0 values in (1),
|
||||
partition p1 values in (2),
|
||||
partition p2 values in (0,3,4,5,6,7,8,9)
|
||||
);
|
||||
|
||||
insert into t2 select
|
||||
mod(seq, 10), seq from seq_1_to_50;
|
||||
|
||||
explain
|
||||
delete t1, t2 from t1, t2 where t1.a=t2.a;
|
||||
delete t1, t2 from t1, t2 where t1.a=t2.a;
|
||||
|
||||
drop table t1,t2;
|
|
@ -77,7 +77,7 @@ CREATE OR REPLACE TABLE t1 (a DATE) CHARACTER SET utf8
|
|||
PARTITION BY LIST COLUMNS (a) (PARTITION p0 VALUES IN (FROM_DAYS(100)));
|
||||
Warnings:
|
||||
Note 1003 PARTITION BY LIST COLUMNS(`a`)
|
||||
(PARTITION `p0` VALUES IN (_utf8mb3 0x303030302d30302d3030) ENGINE = MyISAM)
|
||||
(PARTITION `p0` VALUES IN (_latin1 0x303030302d30302d3030) ENGINE = MyISAM)
|
||||
SELECT PARTITION_DESCRIPTION FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='t1';
|
||||
PARTITION_DESCRIPTION
|
||||
'0000-00-00'
|
||||
|
|
|
@ -2322,5 +2322,14 @@ b
|
|||
9
|
||||
DROP TABLE t;
|
||||
#
|
||||
# MDEV-30693: Assertion `dbl_records <= s->records' failed in apply_selectivity_for_table on SELECT
|
||||
#
|
||||
set @tmp_oucs= @@optimizer_use_condition_selectivity;
|
||||
CREATE TABLE t1 (c INT KEY) ENGINE=InnoDB;
|
||||
SELECT * FROM (SELECT * FROM t1) a JOIN (SELECT * FROM (SELECT * FROM t1 GROUP BY c) d WHERE c>1) b ON a.c=b.c;
|
||||
c c
|
||||
DROP TABLE t1;
|
||||
SET optimizer_use_condition_selectivity=1;
|
||||
#
|
||||
# End of 11.0 tests
|
||||
#
|
||||
|
|
|
@ -282,6 +282,15 @@ SELECT b FROM t WHERE a > 'a' GROUP BY b HAVING b >= 6 OR b <= 0;
|
|||
# Cleanup
|
||||
DROP TABLE t;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30693: Assertion `dbl_records <= s->records' failed in apply_selectivity_for_table on SELECT
|
||||
--echo #
|
||||
set @tmp_oucs= @@optimizer_use_condition_selectivity;
|
||||
CREATE TABLE t1 (c INT KEY) ENGINE=InnoDB;
|
||||
SELECT * FROM (SELECT * FROM t1) a JOIN (SELECT * FROM (SELECT * FROM t1 GROUP BY c) d WHERE c>1) b ON a.c=b.c;
|
||||
DROP TABLE t1;
|
||||
SET optimizer_use_condition_selectivity=1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 11.0 tests
|
||||
--echo #
|
||||
|
|
|
@ -777,16 +777,16 @@ select @@lc_time_names;
|
|||
@@lc_time_names
|
||||
en_US
|
||||
LC_TIME_NAMES: testing locale with the last ID:
|
||||
set lc_time_names=110;
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
rm_CH
|
||||
LC_TIME_NAMES: testing a number beyond the valid ID range:
|
||||
set lc_time_names=111;
|
||||
ERROR HY000: Unknown locale: '111'
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
rm_CH
|
||||
ka_GE
|
||||
LC_TIME_NAMES: testing a number beyond the valid ID range:
|
||||
set lc_time_names=112;
|
||||
ERROR HY000: Unknown locale: '112'
|
||||
select @@lc_time_names;
|
||||
@@lc_time_names
|
||||
ka_GE
|
||||
LC_TIME_NAMES: testing that 0 is en_US:
|
||||
set lc_time_names=0;
|
||||
select @@lc_time_names;
|
||||
|
|
|
@ -538,12 +538,13 @@ set lc_time_names=NULL;
|
|||
--error ER_UNKNOWN_LOCALE
|
||||
set lc_time_names=-1;
|
||||
select @@lc_time_names;
|
||||
# note same boundary condition tests in sys_vars.lc_time_names_basic
|
||||
--echo LC_TIME_NAMES: testing locale with the last ID:
|
||||
set lc_time_names=110;
|
||||
set lc_time_names=111;
|
||||
select @@lc_time_names;
|
||||
--echo LC_TIME_NAMES: testing a number beyond the valid ID range:
|
||||
--error ER_UNKNOWN_LOCALE
|
||||
set lc_time_names=111;
|
||||
set lc_time_names=112;
|
||||
select @@lc_time_names;
|
||||
--echo LC_TIME_NAMES: testing that 0 is en_US:
|
||||
set lc_time_names=0;
|
||||
|
|
|
@ -30,8 +30,10 @@ insert into t8 values (1, 'publicmessage');
|
|||
insert into t9 values (1, 'pugliccompressedaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc');
|
||||
|
||||
--echo # should list tables t1-t6
|
||||
--sorted_result
|
||||
SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'enctests%';
|
||||
--echo # should list tables t7-t9
|
||||
--sorted_result
|
||||
SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 and NAME LIKE 'enctests%';
|
||||
|
||||
--let $MYSQLD_DATADIR=`select @@datadir`
|
||||
|
|
|
@ -9,6 +9,7 @@ INSERT INTO t2 VALUES ('foobar');
|
|||
#
|
||||
# MDEV-9640: Add used key_id to INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION
|
||||
#
|
||||
--sorted_result
|
||||
SELECT NAME, ENCRYPTION_SCHEME, MIN_KEY_VERSION, CURRENT_KEY_VERSION,
|
||||
CURRENT_KEY_ID
|
||||
FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION
|
||||
|
|
|
@ -77,6 +77,9 @@ test/t_dynamic test/t_dynamic 33 5 Dynamic 0
|
|||
test/t_redundant test/t_redundant 0 5 Redundant 0
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t_redundant DEFAULT DEFAULT MYSQLD_DATADIR/test/t_redundant.ibd
|
||||
test/t_compact DEFAULT DEFAULT MYSQLD_DATADIR/test/t_compact.ibd
|
||||
test/t_compressed DEFAULT 2048 MYSQLD_DATADIR/test/t_compressed.ibd
|
||||
|
|
|
@ -182,7 +182,7 @@ compress_pages_page_decompressed compression 0 NULL NULL NULL 0 NULL NULL NULL N
|
|||
compress_pages_page_compression_error compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of page compression errors
|
||||
compress_pages_encrypted compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages encrypted
|
||||
compress_pages_decrypted compression 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of pages decrypted
|
||||
index_page_splits index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of index page splits
|
||||
index_page_splits index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of index page splits
|
||||
index_page_merge_attempts index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of index page merge attempts
|
||||
index_page_merge_successful index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of successful index page merges
|
||||
index_page_reorg_attempts index 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of index page reorganization attempts
|
||||
|
|
|
@ -23,6 +23,7 @@ INNODB_BUFFER_POOL_PAGES_OLD
|
|||
INNODB_BUFFER_POOL_PAGES_TOTAL
|
||||
INNODB_BUFFER_POOL_PAGES_LRU_FLUSHED
|
||||
INNODB_BUFFER_POOL_PAGES_LRU_FREED
|
||||
INNODB_BUFFER_POOL_PAGES_SPLIT
|
||||
INNODB_BUFFER_POOL_READ_AHEAD_RND
|
||||
INNODB_BUFFER_POOL_READ_AHEAD
|
||||
INNODB_BUFFER_POOL_READ_AHEAD_EVICTED
|
||||
|
|
|
@ -214,6 +214,21 @@ WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
|
|||
TABLE_ROWS AVG_ROW_LENGTH>0
|
||||
3 1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-29975 InnoDB fails to release savepoint during bulk insert
|
||||
#
|
||||
CREATE TABLE t (c INT KEY) ENGINE=InnoDB;
|
||||
begin;
|
||||
INSERT INTO t VALUES (0,0);
|
||||
ERROR 21S01: Column count doesn't match value count at row 1
|
||||
SAVEPOINT a;
|
||||
INSERT INTO t VALUES (0),(0);
|
||||
ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
|
||||
SAVEPOINT a;
|
||||
commit;
|
||||
SELECT * FROM t;
|
||||
c
|
||||
DROP TABLE t;
|
||||
# End of 10.6 tests
|
||||
#
|
||||
# MDEV-26947 UNIQUE column checks fail in InnoDB resulting
|
||||
|
|
|
@ -43,5 +43,25 @@ t1 CREATE TABLE `t1` (
|
|||
PRIMARY KEY (`f1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-30183 Assertion `!memcmp(rec_trx_id, old_pk_trx_id->data,
|
||||
# 6 + 7)' failed in row_log_table_apply_update
|
||||
#
|
||||
set @old_sql_mode = @@sql_mode;
|
||||
set @@sql_mode="";
|
||||
CREATE TABLE t1(col_int int, col_varchar varchar(500))ENGINE=InnoDB;
|
||||
INSERT INTO t1(col_int) values(2560);
|
||||
set debug_sync="row_log_table_apply1_before SIGNAL con1_begin WAIT_FOR con1_commit";
|
||||
ALTER TABLE t1 ADD PRIMARY KEY ( col_varchar);
|
||||
connection con1;
|
||||
SET DEBUG_SYNC="now WAIT_FOR con1_begin";
|
||||
UPDATE t1 SET col_int = 2178;
|
||||
INSERT INTO t1(col_int) VALUES(3016);
|
||||
UPDATE t1 set col_int=2802;
|
||||
SET DEBUG_SYNC="now SIGNAL con1_commit";
|
||||
connection default;
|
||||
ERROR 23000: Duplicate entry '' for key 'PRIMARY'
|
||||
DROP TABLE t1;
|
||||
SET @@sql_mode = @old_sql_mode;
|
||||
disconnect con1;
|
||||
SET DEBUG_SYNC=reset;
|
||||
|
|
|
@ -2,6 +2,11 @@ SET GLOBAL innodb_fast_shutdown=0;
|
|||
# restart: --innodb_undo_tablespaces=2
|
||||
SET GLOBAL innodb_undo_log_truncate = 0;
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1
|
||||
create table t1(keyc int primary key, c char(100)) engine = innodb;
|
||||
create table t2(keyc int primary key, c char(100)) engine = innodb;
|
||||
connect con1,localhost,root,,;
|
||||
|
|
|
@ -235,6 +235,20 @@ SELECT TABLE_ROWS, AVG_ROW_LENGTH>0 FROM INFORMATION_SCHEMA.TABLES
|
|||
WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test';
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-29975 InnoDB fails to release savepoint during bulk insert
|
||||
--echo #
|
||||
CREATE TABLE t (c INT KEY) ENGINE=InnoDB;
|
||||
begin;
|
||||
--error ER_WRONG_VALUE_COUNT_ON_ROW
|
||||
INSERT INTO t VALUES (0,0);
|
||||
SAVEPOINT a;
|
||||
--error ER_ERROR_DURING_COMMIT
|
||||
INSERT INTO t VALUES (0),(0);
|
||||
SAVEPOINT a;
|
||||
commit;
|
||||
SELECT * FROM t;
|
||||
DROP TABLE t;
|
||||
--echo # End of 10.6 tests
|
||||
|
||||
--echo #
|
||||
|
|
|
@ -59,5 +59,29 @@ connection default;
|
|||
reap;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30183 Assertion `!memcmp(rec_trx_id, old_pk_trx_id->data,
|
||||
--echo # 6 + 7)' failed in row_log_table_apply_update
|
||||
--echo #
|
||||
set @old_sql_mode = @@sql_mode;
|
||||
set @@sql_mode="";
|
||||
CREATE TABLE t1(col_int int, col_varchar varchar(500))ENGINE=InnoDB;
|
||||
INSERT INTO t1(col_int) values(2560);
|
||||
set debug_sync="row_log_table_apply1_before SIGNAL con1_begin WAIT_FOR con1_commit";
|
||||
send ALTER TABLE t1 ADD PRIMARY KEY ( col_varchar);
|
||||
|
||||
connection con1;
|
||||
SET DEBUG_SYNC="now WAIT_FOR con1_begin";
|
||||
UPDATE t1 SET col_int = 2178;
|
||||
INSERT INTO t1(col_int) VALUES(3016);
|
||||
UPDATE t1 set col_int=2802;
|
||||
SET DEBUG_SYNC="now SIGNAL con1_commit";
|
||||
|
||||
connection default;
|
||||
--error ER_DUP_ENTRY
|
||||
reap;
|
||||
DROP TABLE t1;
|
||||
SET @@sql_mode = @old_sql_mode;
|
||||
disconnect con1;
|
||||
SET DEBUG_SYNC=reset;
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
--innodb-buffer-pool-size=24M
|
||||
--innodb-immediate-scrub-data-uncompressed=ON
|
||||
--loose-innodb-sys-tablespaces
|
||||
|
|
|
@ -19,6 +19,9 @@ let $restart_parameters="--innodb_undo_tablespaces=2";
|
|||
SET GLOBAL innodb_undo_log_truncate = 0;
|
||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||
|
||||
LET $MYSQLD_DATADIR = `select @@datadir`;
|
||||
LET $INNODB_PAGE_SIZE = `select @@innodb_page_size`;
|
||||
--source suite/innodb/include/show_i_s_tablespaces.inc
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# Perform DML action using multiple clients and multiple undo tablespace.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# Test 3) Query some information_shema tables that are dependent upon
|
||||
# the page size.
|
||||
SELECT t.name table_name, t.n_cols, t.flag table_flags,
|
||||
@@ -36,13 +36,13 @@
|
||||
@@ -36,7 +36,7 @@
|
||||
table_name n_cols table_flags index_name root_page type n_fields merge_threshold
|
||||
test/t1 5 0 PRIMARY 3 3 1 50
|
||||
test/t2 5 1 PRIMARY 3 3 1 50
|
||||
|
@ -16,6 +16,8 @@
|
|||
test/t4 5 33 PRIMARY 3 3 1 50
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
@@ -45,7 +45,7 @@
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t1 DEFAULT DEFAULT MYSQLD_DATADIR/test/t1.ibd
|
||||
test/t2 DEFAULT DEFAULT MYSQLD_DATADIR/test/t2.ibd
|
||||
-test/t3 DEFAULT 8192 MYSQLD_DATADIR/test/t3.ibd
|
||||
|
@ -23,7 +25,7 @@
|
|||
test/t4 DEFAULT DEFAULT MYSQLD_DATADIR/test/t4.ibd
|
||||
innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1
|
||||
DROP TABLE t1, t2, t3, t4;
|
||||
@@ -52,141 +52,90 @@
|
||||
@@ -55,141 +55,90 @@
|
||||
SET SESSION innodb_strict_mode = ON;
|
||||
CREATE TABLE t1 (
|
||||
c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200),
|
||||
|
@ -211,7 +213,7 @@
|
|||
ALTER TABLE t1 KEY_BLOCK_SIZE=4;
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
@@ -218,15 +167,21 @@
|
||||
@@ -221,15 +170,21 @@
|
||||
DROP TABLE t1;
|
||||
SET SESSION innodb_strict_mode = OFF;
|
||||
CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16;
|
||||
|
@ -233,7 +235,7 @@
|
|||
SELECT table_name, row_format, create_options
|
||||
FROM information_schema.tables WHERE table_name = 't1';
|
||||
table_name row_format create_options
|
||||
@@ -272,6 +227,7 @@
|
||||
@@ -275,6 +230,7 @@
|
||||
ERROR HY000: Can't create table `test`.`t4` (errno: 140 "Wrong create options")
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
|
@ -241,7 +243,7 @@
|
|||
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
|
||||
Error 1005 Can't create table `test`.`t4` (errno: 140 "Wrong create options")
|
||||
Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
|
||||
@@ -279,107 +235,13 @@
|
||||
@@ -282,107 +238,13 @@
|
||||
ERROR HY000: Can't create table `test`.`t5` (errno: 140 "Wrong create options")
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
|
@ -350,7 +352,7 @@
|
|||
# Test 8) Test creating a table that could lead to undo log overflow.
|
||||
CREATE TABLE t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,
|
||||
h blob,i blob,j blob,k blob,l blob,m blob,n blob,
|
||||
@@ -394,10 +256,6 @@
|
||||
@@ -397,10 +259,6 @@
|
||||
UPDATE t1 SET a=@b,b=@b,c=@b,d=@b,e=@b,f=@b,g=@b,h=@b,i=@b,j=@b,
|
||||
k=@b,l=@b,m=@b,n=@b,o=@b,p=@b,q=@b,r=@b,s=@b,t=@b,u=@b;
|
||||
CREATE INDEX t1a ON t1 (a(767));
|
||||
|
@ -361,7 +363,7 @@
|
|||
UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c,
|
||||
k=@c,l=@c,m=@c,n=@c,o=@c,p=@c,q=@c,r=@c,s=@c,t=@c,u=@c;
|
||||
CREATE INDEX t1f ON t1 (f(767));
|
||||
@@ -412,37 +270,15 @@
|
||||
@@ -415,37 +273,15 @@
|
||||
COMMIT;
|
||||
CREATE INDEX t1g ON t1 (g(767));
|
||||
UPDATE t1 SET g=@e;
|
||||
|
@ -403,7 +405,7 @@
|
|||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
@@ -468,28 +304,12 @@
|
||||
@@ -471,28 +307,12 @@
|
||||
`t` blob DEFAULT NULL,
|
||||
`u` blob DEFAULT NULL,
|
||||
KEY `t1a` (`a`(767)),
|
||||
|
@ -434,7 +436,7 @@
|
|||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
|
||||
DROP TABLE t1;
|
||||
# Bug#12547647 UPDATE LOGGING COULD EXCEED LOG PAGE SIZE
|
||||
@@ -574,27 +394,25 @@
|
||||
@@ -577,27 +397,25 @@
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(
|
||||
c text NOT NULL, d text NOT NULL,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# Test 3) Query some information_shema tables that are dependent upon
|
||||
# the page size.
|
||||
SELECT t.name table_name, t.n_cols, t.flag table_flags,
|
||||
@@ -36,13 +36,13 @@
|
||||
@@ -36,7 +36,7 @@
|
||||
table_name n_cols table_flags index_name root_page type n_fields merge_threshold
|
||||
test/t1 5 0 PRIMARY 3 3 1 50
|
||||
test/t2 5 1 PRIMARY 3 3 1 50
|
||||
|
@ -16,6 +16,8 @@
|
|||
test/t4 5 33 PRIMARY 3 3 1 50
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
@@ -45,7 +45,7 @@
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t1 DEFAULT DEFAULT MYSQLD_DATADIR/test/t1.ibd
|
||||
test/t2 DEFAULT DEFAULT MYSQLD_DATADIR/test/t2.ibd
|
||||
-test/t3 DEFAULT 8192 MYSQLD_DATADIR/test/t3.ibd
|
||||
|
@ -23,7 +25,7 @@
|
|||
test/t4 DEFAULT DEFAULT MYSQLD_DATADIR/test/t4.ibd
|
||||
innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1
|
||||
DROP TABLE t1, t2, t3, t4;
|
||||
@@ -54,133 +54,97 @@
|
||||
@@ -57,133 +57,97 @@
|
||||
c01 char(200), c02 char(200), c03 char(200), c04 char(200), c05 char(200),
|
||||
c06 char(200), c07 char(200), c08 char(200), c09 char(200), c10 char(200),
|
||||
c11 char(200), c12 char(200), c13 char(200), c14 char(200), c15 char(200),
|
||||
|
@ -199,7 +201,7 @@
|
|||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
SELECT table_name, row_format, create_options
|
||||
@@ -218,8 +182,11 @@
|
||||
@@ -221,8 +185,11 @@
|
||||
DROP TABLE t1;
|
||||
SET SESSION innodb_strict_mode = OFF;
|
||||
CREATE TABLE t1 (i int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16;
|
||||
|
@ -211,7 +213,7 @@
|
|||
SELECT table_name, row_format, create_options
|
||||
FROM information_schema.tables WHERE table_name = 't1';
|
||||
table_name row_format create_options
|
||||
@@ -279,107 +246,13 @@
|
||||
@@ -282,107 +249,13 @@
|
||||
ERROR HY000: Can't create table `test`.`t5` (errno: 140 "Wrong create options")
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
|
@ -320,7 +322,7 @@
|
|||
# Test 8) Test creating a table that could lead to undo log overflow.
|
||||
CREATE TABLE t1(a blob,b blob,c blob,d blob,e blob,f blob,g blob,
|
||||
h blob,i blob,j blob,k blob,l blob,m blob,n blob,
|
||||
@@ -394,10 +267,6 @@
|
||||
@@ -397,10 +270,6 @@
|
||||
UPDATE t1 SET a=@b,b=@b,c=@b,d=@b,e=@b,f=@b,g=@b,h=@b,i=@b,j=@b,
|
||||
k=@b,l=@b,m=@b,n=@b,o=@b,p=@b,q=@b,r=@b,s=@b,t=@b,u=@b;
|
||||
CREATE INDEX t1a ON t1 (a(767));
|
||||
|
@ -331,7 +333,7 @@
|
|||
UPDATE t1 SET a=@c,b=@c,c=@c,d=@c,e=@c,f=@c,g=@c,h=@c,i=@c,j=@c,
|
||||
k=@c,l=@c,m=@c,n=@c,o=@c,p=@c,q=@c,r=@c,s=@c,t=@c,u=@c;
|
||||
CREATE INDEX t1f ON t1 (f(767));
|
||||
@@ -412,30 +281,6 @@
|
||||
@@ -415,30 +284,6 @@
|
||||
COMMIT;
|
||||
CREATE INDEX t1g ON t1 (g(767));
|
||||
UPDATE t1 SET g=@e;
|
||||
|
@ -362,7 +364,7 @@
|
|||
CREATE INDEX t1t ON t1 (t(767));
|
||||
BEGIN;
|
||||
UPDATE t1 SET t=@e;
|
||||
@@ -468,24 +313,8 @@
|
||||
@@ -471,24 +316,8 @@
|
||||
`t` blob DEFAULT NULL,
|
||||
`u` blob DEFAULT NULL,
|
||||
KEY `t1a` (`a`(767)),
|
||||
|
@ -387,7 +389,7 @@
|
|||
KEY `t1t` (`t`(767)),
|
||||
KEY `t1u` (`u`(767)),
|
||||
KEY `t1ut` (`u`(767),`t`(767)),
|
||||
@@ -577,14 +406,14 @@
|
||||
@@ -580,14 +409,14 @@
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
Warnings:
|
||||
|
@ -404,7 +406,7 @@
|
|||
DROP TABLE t1;
|
||||
CREATE TABLE t1(
|
||||
c text NOT NULL, d text NOT NULL,
|
||||
@@ -594,7 +423,7 @@
|
||||
@@ -597,7 +426,7 @@
|
||||
CREATE TABLE t1(c text, PRIMARY KEY (c(440)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
Warnings:
|
||||
|
|
|
@ -40,6 +40,9 @@ test/t3 5 41 PRIMARY 3 3 1 50
|
|||
test/t4 5 33 PRIMARY 3 3 1 50
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t1 DEFAULT DEFAULT MYSQLD_DATADIR/test/t1.ibd
|
||||
test/t2 DEFAULT DEFAULT MYSQLD_DATADIR/test/t2.ibd
|
||||
test/t3 DEFAULT 8192 MYSQLD_DATADIR/test/t3.ibd
|
||||
|
|
|
@ -210,6 +210,9 @@ test/t7_restart#p#p1#sp#s2 test/t7_restart#p#p1#sp#s2 97 8 Dynamic 0
|
|||
test/t7_restart#p#p1#sp#s3 test/t7_restart#p#p1#sp#s3 97 8 Dynamic 0
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t1_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t1_restart.ibd
|
||||
test/t2_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t2_restart.ibd
|
||||
test/t3_restart DEFAULT 2048 MYSQLD_DATADIR/test/t3_restart.ibd
|
||||
|
@ -393,6 +396,9 @@ test/t7_restart#p#p1#sp#s2 test/t7_restart#p#p1#sp#s2 97 8 Dynamic 0
|
|||
test/t7_restart#p#p1#sp#s3 test/t7_restart#p#p1#sp#s3 97 8 Dynamic 0
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t1_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t1_restart.ibd
|
||||
test/t2_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t2_restart.ibd
|
||||
test/t3_restart DEFAULT 2048 MYSQLD_DATADIR/test/t3_restart.ibd
|
||||
|
@ -417,6 +423,9 @@ ALTER TABLE t6_restart TRUNCATE PARTITION p2;
|
|||
ALTER TABLE t7_restart TRUNCATE PARTITION p1;
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
|
||||
test/t6_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
|
||||
test/t6_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
|
||||
|
@ -520,6 +529,9 @@ t7_restart#p#p1#sp#s3.ibd
|
|||
# restart
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
|
||||
test/t6_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
|
||||
test/t6_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
|
||||
|
@ -622,6 +634,9 @@ RENAME TABLE t6_restart TO t66_restart;
|
|||
RENAME TABLE t7_restart TO t77_restart;
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
|
||||
test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
|
||||
test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
|
||||
|
@ -718,6 +733,9 @@ t77_restart#p#p1#sp#s3.ibd
|
|||
# restart
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
|
||||
test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
|
||||
test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
|
||||
|
@ -853,6 +871,9 @@ t77_restart#p#p1#sp#s3.ibd
|
|||
# restart
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t4_restart DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd
|
||||
test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p0.ibd
|
||||
test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p1.ibd
|
||||
|
@ -992,6 +1013,9 @@ t77_restart.par
|
|||
# restart
|
||||
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
|
||||
Space_Name Page_Size Zip_Size Path
|
||||
innodb_undo001 DEFAULT DEFAULT MYSQLD_DATADIR//undo001
|
||||
innodb_undo002 DEFAULT DEFAULT MYSQLD_DATADIR//undo002
|
||||
innodb_undo003 DEFAULT DEFAULT MYSQLD_DATADIR//undo003
|
||||
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
|
||||
test/t66_restart#p#p0 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p0.ibd
|
||||
test/t66_restart#p#p1 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p1.ibd
|
||||
|
|
|
@ -181,16 +181,19 @@ CREATE TABLE `t12` (
|
|||
(
|
||||
pt1 PAGE_COMPRESSED=0
|
||||
);
|
||||
--sorted_result
|
||||
SELECT name, flag FROM information_schema.innodb_sys_tablespaces WHERE name like 'test/t12%';
|
||||
|
||||
ALTER TABLE `t12` ADD PARTITION (
|
||||
PARTITION pt2 PAGE_COMPRESSED=1
|
||||
);
|
||||
--sorted_result
|
||||
SELECT name, flag FROM information_schema.innodb_sys_tablespaces WHERE name like 'test/t12%';
|
||||
|
||||
ALTER TABLE `t12` ADD PARTITION (
|
||||
PARTITION pt3 PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=3
|
||||
);
|
||||
--sorted_result
|
||||
SELECT name, flag FROM information_schema.innodb_sys_tablespaces WHERE name like 'test/t12%';
|
||||
|
||||
DROP TABLE `t12`;
|
||||
|
@ -203,6 +206,7 @@ CREATE TABLE `t13` (
|
|||
PARTITION pt3 VALUES LESS THAN MAXVALUE
|
||||
);
|
||||
SHOW CREATE TABLE `t13`;
|
||||
--sorted_result
|
||||
SELECT name, flag FROM information_schema.innodb_sys_tablespaces WHERE name like 'test/t13%';
|
||||
|
||||
ALTER TABLE `t13` PARTITION BY RANGE(id) (
|
||||
|
@ -211,6 +215,7 @@ ALTER TABLE `t13` PARTITION BY RANGE(id) (
|
|||
PARTITION pt3 VALUES LESS THAN MAXVALUE PAGE_COMPRESSED=0
|
||||
);
|
||||
SHOW CREATE TABLE `t13`;
|
||||
--sorted_result
|
||||
SELECT name, flag FROM information_schema.innodb_sys_tablespaces WHERE name like 'test/t13%';
|
||||
|
||||
DROP TABLE `t13`;
|
||||
|
|
|
@ -112,6 +112,7 @@ ID NAME DESCRIPTION MAX_MONTH_NAME_LENGTH MAX_DAY_NAME_LENGTH DECIMAL_POINT THOU
|
|||
108 zh_HK Chinese - Hong Kong SAR 3 3 . , english
|
||||
109 el_GR Greek - Greece 11 9 , . greek
|
||||
110 rm_CH Romansh - Switzerland 9 9 , ' english
|
||||
111 ka_GE Georgian - Georgia 10 9 , georgian
|
||||
show locales;
|
||||
Id Name Description Error_Message_Language
|
||||
0 en_US English - United States english
|
||||
|
@ -225,6 +226,7 @@ Id Name Description Error_Message_Language
|
|||
108 zh_HK Chinese - Hong Kong SAR english
|
||||
109 el_GR Greek - Greece greek
|
||||
110 rm_CH Romansh - Switzerland english
|
||||
111 ka_GE Georgian - Georgia georgian
|
||||
show locales like '%spanish%';
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'like '%spanish%'' at line 1
|
||||
show locales where description like '%spanish%';
|
||||
|
|
|
@ -1024,7 +1024,11 @@ SELECT @@lc_time_names;
|
|||
@@lc_time_names
|
||||
rm_CH
|
||||
SET @@lc_time_names = 111;
|
||||
ERROR HY000: Unknown locale: '111'
|
||||
SELECT @@lc_time_names;
|
||||
@@lc_time_names
|
||||
ka_GE
|
||||
SET @@lc_time_names = 112;
|
||||
ERROR HY000: Unknown locale: '112'
|
||||
'#--------------------FN_DYNVARS_060_10-------------------------#'
|
||||
SET @@lc_time_names = en_EN;
|
||||
ERROR HY000: Unknown locale: 'en_EN'
|
||||
|
|
|
@ -621,8 +621,10 @@ SET @@lc_time_names = 109;
|
|||
SELECT @@lc_time_names;
|
||||
SET @@lc_time_names = 110;
|
||||
SELECT @@lc_time_names;
|
||||
--Error ER_UNKNOWN_LOCALE
|
||||
SET @@lc_time_names = 111;
|
||||
SELECT @@lc_time_names;
|
||||
--Error ER_UNKNOWN_LOCALE
|
||||
SET @@lc_time_names = 112;
|
||||
|
||||
--echo '#--------------------FN_DYNVARS_060_10-------------------------#'
|
||||
#############################################################################
|
||||
|
|
|
@ -176,6 +176,12 @@ my_bool my_init(void)
|
|||
mysql_stdin= & instrumented_stdin;
|
||||
|
||||
my_progname_short= "unknown";
|
||||
/* Initialize our mutex handling */
|
||||
my_mutex_init();
|
||||
|
||||
if (my_thread_global_init())
|
||||
return 1;
|
||||
|
||||
if (my_progname)
|
||||
{
|
||||
char link_name[FN_REFLEN];
|
||||
|
@ -198,12 +204,6 @@ my_bool my_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Initialize our mutex handling */
|
||||
my_mutex_init();
|
||||
|
||||
if (my_thread_global_init())
|
||||
return 1;
|
||||
|
||||
#if defined(SAFEMALLOC) && !defined(DBUG_OFF)
|
||||
dbug_sanity= sf_sanity;
|
||||
#endif
|
||||
|
|
|
@ -54,10 +54,8 @@ int my_readlink(char *to, const char *filename, myf MyFlags)
|
|||
|
||||
if ((length=readlink(filename, to, FN_REFLEN-1)) < 0)
|
||||
{
|
||||
if (my_thread_var)
|
||||
my_errno= errno;
|
||||
/* Don't give an error if this wasn't a symlink */
|
||||
if (errno == EINVAL)
|
||||
if ((my_errno=errno) == EINVAL)
|
||||
{
|
||||
result= 1;
|
||||
strnmov(to, filename, FN_REFLEN);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_alloca.h>
|
||||
#include <mysql/plugin_password_validation.h>
|
||||
#include <crack.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* See COPYRIGHT.txt for details.
|
||||
*/
|
||||
|
||||
#include <my_global.h>
|
||||
#include <my_alloca.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
|
@ -17,9 +17,6 @@
|
|||
#if __linux__
|
||||
#include <sys/epoll.h>
|
||||
#endif
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "hstcpsvr_worker.hpp"
|
||||
#include "string_buffer.hpp"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <my_alloca.h>
|
||||
|
||||
#if 0
|
||||
extern "C" {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
# This scripts creates the MariaDB Server system tables
|
||||
#
|
||||
# All unrecognized arguments to this script are passed to mysqld.
|
||||
# All unrecognized arguments to this script are passed to mariadbd.
|
||||
|
||||
basedir=""
|
||||
builddir=""
|
||||
|
@ -33,6 +33,7 @@ mysqld_opt=""
|
|||
user=""
|
||||
group=""
|
||||
silent_startup="--silent-startup"
|
||||
log_error=""
|
||||
|
||||
force=0
|
||||
in_rpm=0
|
||||
|
@ -328,9 +329,9 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Now we can get arguments from the groups [mysqld] and [mysql_install_db]
|
||||
# Now we can get arguments from the groups [mariadbd] and [mysql_install_db]
|
||||
# in the my.cfg file, then re-run to merge with command line arguments.
|
||||
parse_arguments `"$print_defaults" $defaults $defaults_group_suffix --mysqld mysql_install_db mariadb-install-db`
|
||||
parse_arguments `"$print_defaults" $defaults $defaults_group_suffix --mariadbd mysql_install_db mariadb-install-db`
|
||||
|
||||
parse_arguments PICK-ARGS-FROM-ARGV "$@"
|
||||
|
||||
|
@ -533,7 +534,7 @@ then
|
|||
args="$args --user=$user"
|
||||
fi
|
||||
|
||||
#To be enabled if/when we enable --group as an option to mysqld
|
||||
#To be enabled if/when we enable --group as an option to mariadbd
|
||||
#if test -n "$group"
|
||||
#then
|
||||
# args="$args --group=$group"
|
||||
|
@ -556,7 +557,18 @@ else
|
|||
filter_cmd_line="cat"
|
||||
fi
|
||||
|
||||
# Configure mysqld command line
|
||||
# Disable log error if the user don't have write access to the directory.
|
||||
# This is common when a user tries to install a personal mariadbd server
|
||||
if test -n $log_error
|
||||
then
|
||||
if test ! -w $log_error
|
||||
then
|
||||
log_error=""
|
||||
args="$args --skip-log-error"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure mariadbd command line
|
||||
mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}"
|
||||
mysqld_install_cmd_line()
|
||||
{
|
||||
|
@ -599,7 +611,7 @@ cat_sql()
|
|||
fi
|
||||
}
|
||||
|
||||
# Create the system and help tables by passing them to "mysqld --bootstrap"
|
||||
# Create the system and help tables by passing them to "mariadbd --bootstrap"
|
||||
s_echo "Installing MariaDB/MySQL system tables in '$ldata' ..."
|
||||
if cat_sql | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null
|
||||
then
|
||||
|
|
|
@ -258,7 +258,7 @@ static File open_error_msg_file(const char *file_name, const char *language,
|
|||
goto err;
|
||||
error_pos=2;
|
||||
if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
|
||||
head[2] != 2 || head[3] != 4)
|
||||
head[2] != 2 || head[3] != 5)
|
||||
goto err; /* purecov: inspected */
|
||||
|
||||
ret->text_length= uint4korr(head+6);
|
||||
|
|
10
sql/field.h
10
sql/field.h
|
@ -5377,7 +5377,7 @@ public:
|
|||
bool sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root);
|
||||
|
||||
bool prepare_stage1(THD *thd, MEM_ROOT *mem_root,
|
||||
handler *file, ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes *derived_attr);
|
||||
void prepare_stage1_simple(CHARSET_INFO *cs)
|
||||
{
|
||||
|
@ -5385,11 +5385,9 @@ public:
|
|||
create_length_to_internal_length_simple();
|
||||
}
|
||||
bool prepare_stage1_typelib(THD *thd, MEM_ROOT *mem_root,
|
||||
handler *file, ulonglong table_flags);
|
||||
bool prepare_stage1_string(THD *thd, MEM_ROOT *mem_root,
|
||||
handler *file, ulonglong table_flags);
|
||||
bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root,
|
||||
handler *file, ulonglong table_flags);
|
||||
column_definition_type_t deftype);
|
||||
bool prepare_stage1_string(THD *thd, MEM_ROOT *mem_root);
|
||||
bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root);
|
||||
|
||||
bool bulk_alter(const Column_derived_attributes *derived_attr,
|
||||
const Column_bulk_alter_attributes *bulk_attr)
|
||||
|
|
|
@ -10784,13 +10784,6 @@ int ha_partition::cmp_ref(const uchar *ref1, const uchar *ref2)
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
In Innodb we compare with either primary key value or global DB_ROW_ID so
|
||||
it is not possible that the two references are equal and are in different
|
||||
partitions, but in myisam it is possible since we are comparing offsets.
|
||||
Remove this assert if DB_ROW_ID is changed to be per partition.
|
||||
*/
|
||||
DBUG_ASSERT(!m_innodb);
|
||||
DBUG_RETURN(diff2 > diff1 ? -1 : 1);
|
||||
}
|
||||
|
||||
|
|
23
sql/item.h
23
sql/item.h
|
@ -2687,18 +2687,27 @@ public:
|
|||
void register_in(THD *thd);
|
||||
|
||||
bool depends_only_on(table_map view_map)
|
||||
{ return marker & MARKER_FULL_EXTRACTION; }
|
||||
int get_extraction_flag() const
|
||||
{ return marker & MARKER_EXTRACTION_MASK; }
|
||||
{ return get_extraction_flag() & MARKER_FULL_EXTRACTION; }
|
||||
int get_extraction_flag() const
|
||||
{
|
||||
if (basic_const_item())
|
||||
return MARKER_FULL_EXTRACTION;
|
||||
else
|
||||
return marker & MARKER_EXTRACTION_MASK;
|
||||
}
|
||||
void set_extraction_flag(int16 flags)
|
||||
{
|
||||
marker &= ~MARKER_EXTRACTION_MASK;
|
||||
marker|= flags;
|
||||
if (!basic_const_item())
|
||||
{
|
||||
marker= marker & ~MARKER_EXTRACTION_MASK;
|
||||
marker|= flags;
|
||||
}
|
||||
}
|
||||
void clear_extraction_flag()
|
||||
{
|
||||
marker &= ~MARKER_EXTRACTION_MASK;
|
||||
}
|
||||
if (!basic_const_item())
|
||||
marker= marker & ~MARKER_EXTRACTION_MASK;
|
||||
}
|
||||
void check_pushable_cond(Pushdown_checker excl_dep_func, uchar *arg);
|
||||
bool pushable_cond_checker_for_derived(uchar *arg)
|
||||
{
|
||||
|
|
|
@ -792,8 +792,9 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table,
|
|||
*/
|
||||
sql_f->length= sql_f->char_length;
|
||||
|
||||
if (sql_f->prepare_stage1(thd, thd->mem_root, table->file,
|
||||
table->file->ha_table_flags(), &da))
|
||||
if (sql_f->prepare_stage1(thd, thd->mem_root,
|
||||
COLUMN_DEFINITION_TABLE_FIELD,
|
||||
&da))
|
||||
goto err_exit;
|
||||
|
||||
while ((jc2= it2++) != jc)
|
||||
|
|
|
@ -741,7 +741,12 @@ void JOIN::add_keyuses_for_splitting()
|
|||
if (ext_keyuses_for_splitting->push(keyuse_ext_end))
|
||||
goto err;
|
||||
|
||||
spl_opt_info->unsplit_card= join_record_count;
|
||||
/*
|
||||
Use the number of rows that was computed by
|
||||
TABLE_LIST::fetch_number_of_rows():
|
||||
*/
|
||||
spl_opt_info->unsplit_card=
|
||||
rows2double(select_lex->master_unit()->derived->table->stat_records());
|
||||
|
||||
rec_len= table->s->rec_buff_length;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ english
|
|||
estonian
|
||||
french
|
||||
german
|
||||
georgian
|
||||
greek
|
||||
hindi
|
||||
hungarian
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5284,7 +5284,7 @@ private:
|
|||
bool use_temporary_table(TABLE *table, TABLE **out_table);
|
||||
void close_temporary_table(TABLE *table);
|
||||
bool log_events_and_free_tmp_shares();
|
||||
void free_tmp_table_share(TMP_TABLE_SHARE *share, bool delete_table);
|
||||
bool free_tmp_table_share(TMP_TABLE_SHARE *share, bool delete_table);
|
||||
void free_temporary_table(TABLE *table);
|
||||
bool lock_temporary_tables();
|
||||
void unlock_temporary_tables();
|
||||
|
|
|
@ -31,7 +31,7 @@ enum err_msgs_index
|
|||
{
|
||||
en_US= 0, cs_CZ, da_DK, nl_NL, et_EE, fr_FR, de_DE, el_GR, hu_HU, it_IT,
|
||||
ja_JP, ko_KR, no_NO, nn_NO, pl_PL, pt_PT, ro_RO, ru_RU, sr_RS, sk_SK,
|
||||
es_ES, sv_SE, uk_UA, hi_IN
|
||||
es_ES, sv_SE, uk_UA, hi_IN, ka_GE
|
||||
} ERR_MSGS_INDEX;
|
||||
|
||||
|
||||
|
@ -61,6 +61,7 @@ MY_LOCALE_ERRMSGS global_errmsgs[]=
|
|||
{"swedish", NULL},
|
||||
{"ukrainian", NULL},
|
||||
{"hindi", NULL},
|
||||
{"georgian", NULL},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -3317,6 +3318,51 @@ MY_LOCALE my_locale_rm_CH
|
|||
/***** LOCALE END rm_CH *****/
|
||||
|
||||
|
||||
/***** LOCALE BEGIN ka_GE: Georgian - Georgia *****/
|
||||
static const char *my_locale_month_names_ka_GE[13] =
|
||||
{"იანვარი","თებერვალი","მარტი","აპრილი","მაისი","ივნისი","ივლისი","სექტემბერი","ოქტომბერი","ნოემბერი","დეკემბერი", NullS };
|
||||
|
||||
static const char *my_locale_ab_month_names_ka_GE[13] =
|
||||
{"იან","თებ","მარ","აპრ","მაი","ივნ","ივლ","აგვ","სექტ","ოქტ","ნოე","დეკ", NullS };
|
||||
|
||||
static const char *my_locale_day_names_ka_GE[8] =
|
||||
{"ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი","კვირა", NullS };
|
||||
|
||||
static const char *my_locale_ab_day_names_ka_GE[8] =
|
||||
{"ორშ","სამშ","ოთხშ","ხუთშ","პარ","შაბ","კვ", NullS };
|
||||
|
||||
static TYPELIB my_locale_typelib_month_names_ka_GE =
|
||||
{ array_elements(my_locale_month_names_ka_GE)-1, "", my_locale_month_names_ka_GE, NULL };
|
||||
|
||||
static TYPELIB my_locale_typelib_ab_month_names_ka_GE =
|
||||
{ array_elements(my_locale_ab_month_names_ka_GE)-1, "", my_locale_ab_month_names_ka_GE, NULL };
|
||||
|
||||
static TYPELIB my_locale_typelib_day_names_ka_GE =
|
||||
{ array_elements(my_locale_day_names_ka_GE)-1, "", my_locale_day_names_ka_GE, NULL };
|
||||
|
||||
static TYPELIB my_locale_typelib_ab_day_names_ka_GE =
|
||||
{ array_elements(my_locale_ab_day_names_ka_GE)-1, "", my_locale_ab_day_names_ka_GE, NULL };
|
||||
|
||||
MY_LOCALE my_locale_ka_GE
|
||||
(
|
||||
111,
|
||||
"ka_GE",
|
||||
"Georgian - Georgia",
|
||||
FALSE,
|
||||
&my_locale_typelib_month_names_ka_GE,
|
||||
&my_locale_typelib_ab_month_names_ka_GE,
|
||||
&my_locale_typelib_day_names_ka_GE,
|
||||
&my_locale_typelib_ab_day_names_ka_GE,
|
||||
10,
|
||||
9,
|
||||
',', /* decimal point ka_GE */
|
||||
' ', /* thousands_sep ka_GE */
|
||||
"\x03", /* grouping ka_GE */
|
||||
&global_errmsgs[ka_GE]
|
||||
);
|
||||
/***** LOCALE END ka_GE *****/
|
||||
|
||||
|
||||
/*
|
||||
The list of all locales.
|
||||
Note, locales must be ordered according to their
|
||||
|
@ -3436,6 +3482,7 @@ MY_LOCALE *my_locales[]=
|
|||
&my_locale_zh_HK,
|
||||
&my_locale_el_GR,
|
||||
&my_locale_rm_CH,
|
||||
&my_locale_ka_GE,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
221
sql/sql_table.cc
221
sql/sql_table.cc
|
@ -2396,17 +2396,16 @@ static void check_duplicate_key(THD *thd, const Key *key, const KEY *key_info,
|
|||
|
||||
bool Column_definition::prepare_stage1_typelib(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
handler *file,
|
||||
ulonglong table_flags)
|
||||
column_definition_type_t deftype)
|
||||
{
|
||||
/*
|
||||
Pass the last parameter to prepare_interval_field() as follows:
|
||||
- If we are preparing for an SP variable (file is NULL), we pass "false",
|
||||
- If we are preparing for an SP variable, we pass "false",
|
||||
to force allocation and full copying of TYPELIB values on the given
|
||||
mem_root, even if no character set conversion is needed. This is needed
|
||||
because a life cycle of an SP variable is longer than the current query.
|
||||
|
||||
- If we are preparing for a CREATE TABLE, (file != NULL), we pass "true".
|
||||
- If we are preparing for a CREATE TABLE, we pass "true".
|
||||
This will create the typelib in runtime memory - we will free the
|
||||
occupied memory at the same time when we free this
|
||||
sql_field -- at the end of execution.
|
||||
|
@ -2414,11 +2413,11 @@ bool Column_definition::prepare_stage1_typelib(THD *thd,
|
|||
values in "interval" in cases when no character conversion is needed,
|
||||
to avoid extra copying.
|
||||
*/
|
||||
if (prepare_interval_field(mem_root, file != NULL))
|
||||
if (prepare_interval_field(mem_root,
|
||||
deftype == COLUMN_DEFINITION_TABLE_FIELD))
|
||||
return true; // E.g. wrong values with commas: SET('a,b')
|
||||
create_length_to_internal_length_typelib();
|
||||
|
||||
DBUG_ASSERT(file || !default_value); // SP variables have no default_value
|
||||
if (default_value && default_value->expr->basic_const_item())
|
||||
{
|
||||
if ((charset != default_value->expr->collation.collation &&
|
||||
|
@ -2431,14 +2430,11 @@ bool Column_definition::prepare_stage1_typelib(THD *thd,
|
|||
|
||||
|
||||
bool Column_definition::prepare_stage1_string(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
handler *file,
|
||||
ulonglong table_flags)
|
||||
MEM_ROOT *mem_root)
|
||||
{
|
||||
create_length_to_internal_length_string();
|
||||
if (prepare_blob_field(thd))
|
||||
return true;
|
||||
DBUG_ASSERT(file || !default_value); // SP variables have no default_value
|
||||
/*
|
||||
Convert the default value from client character
|
||||
set into the column character set if necessary.
|
||||
|
@ -2458,13 +2454,9 @@ bool Column_definition::prepare_stage1_string(THD *thd,
|
|||
|
||||
|
||||
bool Column_definition::prepare_stage1_bit(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
handler *file,
|
||||
ulonglong table_flags)
|
||||
MEM_ROOT *mem_root)
|
||||
{
|
||||
pack_flag= FIELDFLAG_NUMBER;
|
||||
if (!(table_flags & HA_CAN_BIT_FIELD))
|
||||
pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
|
||||
create_length_to_internal_length_bit();
|
||||
return false;
|
||||
}
|
||||
|
@ -2472,14 +2464,15 @@ bool Column_definition::prepare_stage1_bit(THD *thd,
|
|||
|
||||
bool Column_definition::prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t deftype,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
{
|
||||
// SP variables have no default_value
|
||||
DBUG_ASSERT(deftype == COLUMN_DEFINITION_TABLE_FIELD || !default_value);
|
||||
|
||||
return type_handler()->Column_definition_prepare_stage1(thd, mem_root,
|
||||
this, file,
|
||||
table_flags,
|
||||
this, deftype,
|
||||
derived_attr);
|
||||
}
|
||||
|
||||
|
@ -2703,10 +2696,77 @@ key_add_part_check_null(const handler *file, KEY *key_info,
|
|||
|
||||
|
||||
/*
|
||||
Preparation for table creation
|
||||
Prepare for a table creation.
|
||||
Stage 1: prepare the field list.
|
||||
*/
|
||||
static bool mysql_prepare_create_table_stage1(THD *thd,
|
||||
HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info)
|
||||
{
|
||||
DBUG_ENTER("mysql_prepare_create_table_stage1");
|
||||
const Column_derived_attributes dattr(create_info->default_table_charset);
|
||||
const Column_bulk_alter_attributes
|
||||
battr(create_info->alter_table_convert_to_charset);
|
||||
Create_field *sql_field;
|
||||
List_iterator_fast<Create_field> it(alter_info->create_list);
|
||||
|
||||
DBUG_EXECUTE_IF("test_pseudo_invisible",{
|
||||
mysql_add_invisible_field(thd, &alter_info->create_list,
|
||||
"invisible", &type_handler_slong, INVISIBLE_SYSTEM,
|
||||
new (thd->mem_root)Item_int(thd, 9));
|
||||
});
|
||||
DBUG_EXECUTE_IF("test_completely_invisible",{
|
||||
mysql_add_invisible_field(thd, &alter_info->create_list,
|
||||
"invisible", &type_handler_slong, INVISIBLE_FULL,
|
||||
new (thd->mem_root)Item_int(thd, 9));
|
||||
});
|
||||
DBUG_EXECUTE_IF("test_invisible_index",{
|
||||
LEX_CSTRING temp;
|
||||
temp.str= "invisible";
|
||||
temp.length= strlen("invisible");
|
||||
mysql_add_invisible_index(thd, &alter_info->key_list
|
||||
, &temp, Key::MULTIPLE);
|
||||
});
|
||||
|
||||
|
||||
for ( ; (sql_field=it++) ; )
|
||||
{
|
||||
/* Virtual fields are always NULL */
|
||||
if (sql_field->vcol_info)
|
||||
sql_field->flags&= ~NOT_NULL_FLAG;
|
||||
|
||||
/*
|
||||
Initialize length from its original value (number of characters),
|
||||
which was set in the parser. This is necessary if we're
|
||||
executing a prepared statement for the second time.
|
||||
*/
|
||||
sql_field->length= sql_field->char_length;
|
||||
|
||||
if (sql_field->bulk_alter(&dattr, &battr))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
if (sql_field->prepare_stage1(thd, thd->mem_root,
|
||||
COLUMN_DEFINITION_TABLE_FIELD,
|
||||
&dattr))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
DBUG_ASSERT(sql_field->charset);
|
||||
|
||||
if (check_column_name(sql_field->field_name.str))
|
||||
{
|
||||
my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name.str);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(false);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Preparation for table creation, final stage.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_prepare_create_table()
|
||||
mysql_prepare_create_table_finalize()
|
||||
thd Thread object.
|
||||
create_info Create information (like MAX_ROWS).
|
||||
alter_info List of columns and indexes to create
|
||||
|
@ -2729,11 +2789,12 @@ key_add_part_check_null(const handler *file, KEY *key_info,
|
|||
*/
|
||||
|
||||
static int
|
||||
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info, uint *db_options,
|
||||
handler *file, KEY **key_info_buffer,
|
||||
uint *key_count, int create_table_mode,
|
||||
const LEX_CSTRING db, const LEX_CSTRING table_name)
|
||||
mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info, uint *db_options,
|
||||
handler *file, KEY **key_info_buffer,
|
||||
uint *key_count, int create_table_mode,
|
||||
const LEX_CSTRING db,
|
||||
const LEX_CSTRING table_name)
|
||||
{
|
||||
const char *key_name;
|
||||
Create_field *sql_field,*dup_field;
|
||||
|
@ -2749,28 +2810,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
bool tmp_table= create_table_mode == C_ALTER_TABLE;
|
||||
const bool create_simple= thd->lex->create_simple();
|
||||
bool is_hash_field_needed= false;
|
||||
const Column_derived_attributes dattr(create_info->default_table_charset);
|
||||
const Column_bulk_alter_attributes
|
||||
battr(create_info->alter_table_convert_to_charset);
|
||||
DBUG_ENTER("mysql_prepare_create_table");
|
||||
|
||||
DBUG_EXECUTE_IF("test_pseudo_invisible",{
|
||||
mysql_add_invisible_field(thd, &alter_info->create_list,
|
||||
"invisible", &type_handler_slong, INVISIBLE_SYSTEM,
|
||||
new (thd->mem_root)Item_int(thd, 9));
|
||||
});
|
||||
DBUG_EXECUTE_IF("test_completely_invisible",{
|
||||
mysql_add_invisible_field(thd, &alter_info->create_list,
|
||||
"invisible", &type_handler_slong, INVISIBLE_FULL,
|
||||
new (thd->mem_root)Item_int(thd, 9));
|
||||
});
|
||||
DBUG_EXECUTE_IF("test_invisible_index",{
|
||||
LEX_CSTRING temp;
|
||||
temp.str= "invisible";
|
||||
temp.length= strlen("invisible");
|
||||
mysql_add_invisible_index(thd, &alter_info->key_list
|
||||
, &temp, Key::MULTIPLE);
|
||||
});
|
||||
LEX_CSTRING* connect_string = &create_info->connect_string;
|
||||
if (connect_string->length != 0 &&
|
||||
connect_string->length > CONNECT_STRING_MAXLEN &&
|
||||
|
@ -2805,42 +2846,16 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
||||
for (field_no=0; (sql_field=it++) ; field_no++)
|
||||
{
|
||||
/* Virtual fields are always NULL */
|
||||
if (sql_field->vcol_info)
|
||||
sql_field->flags&= ~NOT_NULL_FLAG;
|
||||
|
||||
/*
|
||||
Initialize length from its original value (number of characters),
|
||||
which was set in the parser. This is necessary if we're
|
||||
executing a prepared statement for the second time.
|
||||
*/
|
||||
sql_field->length= sql_field->char_length;
|
||||
|
||||
if (sql_field->bulk_alter(&dattr, &battr))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
if (sql_field->prepare_stage1(thd, thd->mem_root,
|
||||
file, file->ha_table_flags(),
|
||||
&dattr))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
DBUG_ASSERT(sql_field->charset);
|
||||
if (!(sql_field->flags & NOT_NULL_FLAG))
|
||||
null_fields++;
|
||||
|
||||
if (sql_field->real_field_type() == MYSQL_TYPE_BIT &&
|
||||
file->ha_table_flags() & HA_CAN_BIT_FIELD)
|
||||
total_uneven_bit_length+= sql_field->length & 7;
|
||||
|
||||
if (!(sql_field->flags & NOT_NULL_FLAG))
|
||||
null_fields++;
|
||||
|
||||
if (check_column_name(sql_field->field_name.str))
|
||||
{
|
||||
my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name.str);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* Check if we have used the same field name before */
|
||||
for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
|
||||
{
|
||||
|
@ -3829,6 +3844,49 @@ without_overlaps_err:
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Preparation for table creation
|
||||
|
||||
SYNOPSIS
|
||||
mysql_prepare_create_table()
|
||||
thd Thread object.
|
||||
create_info Create information (like MAX_ROWS).
|
||||
alter_info List of columns and indexes to create
|
||||
db_options INOUT Table options (like HA_OPTION_PACK_RECORD).
|
||||
file The handler for the new table.
|
||||
key_info_buffer OUT An array of KEY structs for the indexes.
|
||||
key_count OUT The number of elements in the array.
|
||||
create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE,
|
||||
C_CREATE_SELECT, C_ASSISTED_DISCOVERY
|
||||
|
||||
DESCRIPTION
|
||||
Prepares the table and key structures for table creation.
|
||||
|
||||
NOTES
|
||||
sets create_info->varchar if the table has a varchar
|
||||
|
||||
RETURN VALUES
|
||||
FALSE OK
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
static int
|
||||
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info, uint *db_options,
|
||||
handler *file, KEY **key_info_buffer,
|
||||
uint *key_count, int create_table_mode,
|
||||
const LEX_CSTRING db,
|
||||
const LEX_CSTRING table_name)
|
||||
{
|
||||
return mysql_prepare_create_table_stage1(thd, create_info, alter_info) ||
|
||||
mysql_prepare_create_table_finalize(thd, create_info, alter_info,
|
||||
db_options, file, key_info_buffer,
|
||||
key_count, create_table_mode,
|
||||
db, table_name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
check comment length of table, column, index and partition
|
||||
|
||||
|
@ -3957,7 +4015,8 @@ bool Column_definition::prepare_blob_field(THD *thd)
|
|||
bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
|
||||
{
|
||||
const Column_derived_attributes dattr(thd->variables.collation_database);
|
||||
return prepare_stage1(thd, mem_root, NULL, HA_CAN_GEOMETRY, &dattr) ||
|
||||
return prepare_stage1(thd, mem_root,
|
||||
COLUMN_DEFINITION_ROUTINE_LOCAL, &dattr) ||
|
||||
prepare_stage2(NULL, HA_CAN_GEOMETRY);
|
||||
}
|
||||
|
||||
|
@ -4052,6 +4111,9 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
|
|||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
if (mysql_prepare_create_table_stage1(thd, create_info, alter_info))
|
||||
DBUG_RETURN(NULL);
|
||||
|
||||
db_options= create_info->table_options_with_row_type();
|
||||
|
||||
if (unlikely(!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
|
||||
|
@ -4268,9 +4330,10 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (mysql_prepare_create_table(thd, create_info, alter_info, &db_options,
|
||||
file, key_info, key_count,
|
||||
create_table_mode, db, table_name))
|
||||
if (mysql_prepare_create_table_finalize(thd, create_info,
|
||||
alter_info, &db_options,
|
||||
file, key_info, key_count,
|
||||
create_table_mode, db, table_name))
|
||||
goto err;
|
||||
create_info->table_options=db_options;
|
||||
|
||||
|
|
|
@ -3008,8 +3008,7 @@ bool Type_handler::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
|
@ -3022,8 +3021,7 @@ bool Type_handler_null::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
|
@ -3037,8 +3035,7 @@ bool Type_handler_row::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
|
@ -3052,8 +3049,7 @@ bool Type_handler_temporal_result::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
|
@ -3067,8 +3063,7 @@ bool Type_handler_numeric::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
|
@ -3081,8 +3076,7 @@ bool Type_handler_newdecimal::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
|
@ -3096,28 +3090,26 @@ bool Type_handler_bit::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
{
|
||||
def->charset= &my_charset_numeric;
|
||||
return def->prepare_stage1_bit(thd, mem_root, file, table_flags);
|
||||
return def->prepare_stage1_bit(thd, mem_root);
|
||||
}
|
||||
|
||||
bool Type_handler_typelib::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
{
|
||||
return def->prepare_charset_for_string(derived_attr) ||
|
||||
def->prepare_stage1_typelib(thd, mem_root, file, table_flags);
|
||||
def->prepare_stage1_typelib(thd, mem_root, type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3125,14 +3117,13 @@ bool Type_handler_string_result::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
{
|
||||
return def->prepare_charset_for_string(derived_attr) ||
|
||||
def->prepare_stage1_string(thd, mem_root, file, table_flags);
|
||||
def->prepare_stage1_string(thd, mem_root);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3343,10 +3334,11 @@ bool Type_handler_bit::
|
|||
handler *file,
|
||||
ulonglong table_flags) const
|
||||
{
|
||||
/*
|
||||
We have sql_field->pack_flag already set here, see
|
||||
mysql_prepare_create_table().
|
||||
*/
|
||||
if (!(table_flags & HA_CAN_BIT_FIELD))
|
||||
{
|
||||
def->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
|
||||
def->create_length_to_internal_length_bit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3962,8 +3962,7 @@ public:
|
|||
virtual bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const;
|
||||
|
@ -4441,8 +4440,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
@ -4756,8 +4754,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
@ -5310,8 +5307,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
@ -5414,8 +5410,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
@ -5947,8 +5942,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
@ -6791,8 +6785,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
@ -6849,8 +6842,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
@ -7286,8 +7278,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
|
|
@ -382,8 +382,8 @@ public:
|
|||
}
|
||||
|
||||
bool Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root,
|
||||
Column_definition *def, handler *file,
|
||||
ulonglong table_flags,
|
||||
Column_definition *def,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes *derived_attr)
|
||||
const override
|
||||
{
|
||||
|
|
|
@ -280,8 +280,7 @@ bool Type_handler_geometry::
|
|||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr) const
|
||||
{
|
||||
|
|
|
@ -108,8 +108,7 @@ public:
|
|||
bool Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *c,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const override;
|
||||
|
|
|
@ -671,7 +671,7 @@ bool THD::drop_temporary_table(TABLE *table, bool *is_trans, bool delete_table)
|
|||
temporary_tables->remove(share);
|
||||
|
||||
/* Free the TABLE_SHARE and/or delete the files. */
|
||||
free_tmp_table_share(share, delete_table);
|
||||
result= free_tmp_table_share(share, delete_table);
|
||||
|
||||
end:
|
||||
if (locked)
|
||||
|
@ -1464,20 +1464,21 @@ bool THD::log_events_and_free_tmp_shares()
|
|||
@param share [IN] TABLE_SHARE to free
|
||||
@param delete_table [IN] Whether to delete the table files?
|
||||
|
||||
@return void
|
||||
@return false Success
|
||||
true Error
|
||||
*/
|
||||
void THD::free_tmp_table_share(TMP_TABLE_SHARE *share, bool delete_table)
|
||||
bool THD::free_tmp_table_share(TMP_TABLE_SHARE *share, bool delete_table)
|
||||
{
|
||||
bool error= false;
|
||||
DBUG_ENTER("THD::free_tmp_table_share");
|
||||
|
||||
if (delete_table)
|
||||
{
|
||||
rm_temporary_table(share->db_type(), share->path.str);
|
||||
error= rm_temporary_table(share->db_type(), share->path.str);
|
||||
}
|
||||
free_table_share(share);
|
||||
my_free(share);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ Gets the root node of a tree and x- or s-latches it.
|
|||
buf_block_t*
|
||||
btr_root_block_get(
|
||||
/*===============*/
|
||||
const dict_index_t* index, /*!< in: index tree */
|
||||
dict_index_t* index, /*!< in: index tree */
|
||||
rw_lock_type_t mode, /*!< in: either RW_S_LATCH
|
||||
or RW_X_LATCH */
|
||||
mtr_t* mtr, /*!< in: mtr */
|
||||
|
@ -262,18 +262,42 @@ btr_root_block_get(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
buf_block_t *block = btr_block_get(*index, index->page, mode, mtr, err);
|
||||
if (block)
|
||||
buf_block_t *block;
|
||||
#ifndef BTR_CUR_ADAPT
|
||||
static constexpr buf_block_t *guess= nullptr;
|
||||
#else
|
||||
buf_block_t *&guess= btr_search_get_info(index)->root_guess;
|
||||
guess=
|
||||
#endif
|
||||
block=
|
||||
buf_page_get_gen(page_id_t{index->table->space->id, index->page},
|
||||
index->table->space->zip_size(), mode, guess, BUF_GET,
|
||||
mtr, err);
|
||||
ut_ad(!block == (*err != DB_SUCCESS));
|
||||
|
||||
if (UNIV_LIKELY(block != nullptr))
|
||||
{
|
||||
if (!btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF,
|
||||
*block, *index->table->space) ||
|
||||
!btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP,
|
||||
*block, *index->table->space))
|
||||
if (!!page_is_comp(block->page.frame) != index->table->not_redundant() ||
|
||||
btr_page_get_index_id(block->page.frame) != index->id ||
|
||||
!fil_page_index_page_check(block->page.frame) ||
|
||||
index->is_spatial() !=
|
||||
(fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE))
|
||||
{
|
||||
*err= DB_PAGE_CORRUPTED;
|
||||
block= nullptr;
|
||||
}
|
||||
else if (!btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF,
|
||||
*block, *index->table->space) ||
|
||||
!btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP,
|
||||
*block, *index->table->space))
|
||||
{
|
||||
*err= DB_CORRUPTION;
|
||||
block= nullptr;
|
||||
}
|
||||
}
|
||||
else if (*err == DB_DECRYPTION_FAILED)
|
||||
btr_decryption_failed(*index);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -284,7 +308,7 @@ static
|
|||
page_t*
|
||||
btr_root_get(
|
||||
/*=========*/
|
||||
const dict_index_t* index, /*!< in: index tree */
|
||||
dict_index_t* index, /*!< in: index tree */
|
||||
mtr_t* mtr, /*!< in: mtr */
|
||||
dberr_t* err) /*!< out: error code */
|
||||
{
|
||||
|
@ -496,9 +520,7 @@ btr_block_reget(mtr_t *mtr, const dict_index_t &index,
|
|||
return block;
|
||||
}
|
||||
|
||||
#if 0 /* MDEV-29385 FIXME: Acquire the page latch upfront. */
|
||||
ut_ad(mtr->memo_contains_flagged(&index.lock, MTR_MEMO_X_LOCK));
|
||||
#endif
|
||||
return btr_block_get(index, id.page_no(), rw_latch, mtr, err);
|
||||
}
|
||||
|
||||
|
@ -686,9 +708,7 @@ btr_page_get_father_node_ptr_for_validate(
|
|||
const uint32_t page_no = btr_cur_get_block(cursor)->page.id().page_no();
|
||||
dict_index_t* index = btr_cur_get_index(cursor);
|
||||
ut_ad(!dict_index_is_spatial(index));
|
||||
|
||||
ut_ad(mtr->memo_contains_flagged(&index->lock, MTR_MEMO_X_LOCK
|
||||
| MTR_MEMO_SX_LOCK));
|
||||
ut_ad(mtr->memo_contains(index->lock, MTR_MEMO_X_LOCK));
|
||||
ut_ad(dict_index_get_page(index) != page_no);
|
||||
|
||||
const auto level = btr_page_get_level(btr_cur_get_page(cursor));
|
||||
|
@ -706,10 +726,6 @@ btr_page_get_father_node_ptr_for_validate(
|
|||
}
|
||||
|
||||
const rec_t* node_ptr = btr_cur_get_rec(cursor);
|
||||
#if 0 /* MDEV-29835 FIXME */
|
||||
ut_ad(!btr_cur_get_block(cursor)->page.lock.not_recursive()
|
||||
|| mtr->memo_contains(index->lock, MTR_MEMO_X_LOCK));
|
||||
#endif
|
||||
|
||||
offsets = rec_get_offsets(node_ptr, index, offsets, 0,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
@ -2287,11 +2303,10 @@ btr_insert_on_non_leaf_level(
|
|||
}
|
||||
|
||||
ut_ad(cursor.flag == BTR_CUR_BINARY);
|
||||
#if 0 /* MDEV-29835 FIXME */
|
||||
ut_ad(!btr_cur_get_block(&cursor)->page.lock.not_recursive()
|
||||
ut_ad(btr_cur_get_block(&cursor)
|
||||
!= mtr->at_savepoint(mtr->get_savepoint() - 1)
|
||||
|| index->is_spatial()
|
||||
|| mtr->memo_contains(index->lock, MTR_MEMO_X_LOCK));
|
||||
#endif
|
||||
|
||||
if (UNIV_LIKELY(err == DB_SUCCESS)) {
|
||||
err = btr_cur_optimistic_insert(flags,
|
||||
|
@ -2399,10 +2414,8 @@ btr_attach_half_pages(
|
|||
prev_block = mtr->get_already_latched(id, MTR_MEMO_PAGE_X_FIX);
|
||||
#if 1 /* MDEV-29835 FIXME: acquire page latches upfront */
|
||||
if (!prev_block) {
|
||||
# if 0 /* MDEV-29835 FIXME */
|
||||
ut_ad(mtr->memo_contains(index->lock,
|
||||
MTR_MEMO_X_LOCK));
|
||||
# endif
|
||||
prev_block = btr_block_get(*index, prev_page_no,
|
||||
RW_X_LATCH, mtr);
|
||||
}
|
||||
|
@ -2413,10 +2426,8 @@ btr_attach_half_pages(
|
|||
next_block = mtr->get_already_latched(id, MTR_MEMO_PAGE_X_FIX);
|
||||
#if 1 /* MDEV-29835 FIXME: acquire page latches upfront */
|
||||
if (!next_block) {
|
||||
# if 0 /* MDEV-29835 FIXME */
|
||||
ut_ad(mtr->memo_contains(index->lock,
|
||||
MTR_MEMO_X_LOCK));
|
||||
# endif
|
||||
next_block = btr_block_get(*index, next_page_no,
|
||||
RW_X_LATCH, mtr);
|
||||
}
|
||||
|
@ -2757,6 +2768,8 @@ btr_page_split_and_insert(
|
|||
ut_ad(dtuple_check_typed(tuple));
|
||||
ut_ad(!cursor->index()->is_spatial());
|
||||
|
||||
buf_pool.pages_split++;
|
||||
|
||||
if (!*heap) {
|
||||
*heap = mem_heap_create(1024);
|
||||
}
|
||||
|
@ -3124,8 +3137,6 @@ insert_failed:
|
|||
}
|
||||
|
||||
func_exit:
|
||||
MONITOR_INC(MONITOR_INDEX_SPLIT);
|
||||
|
||||
ut_ad(page_validate(buf_block_get_frame(left_block),
|
||||
page_cursor->index));
|
||||
ut_ad(page_validate(buf_block_get_frame(right_block),
|
||||
|
@ -3160,9 +3171,7 @@ dberr_t btr_level_list_remove(const buf_block_t& block,
|
|||
#if 1 /* MDEV-29835 FIXME: acquire page latches upfront */
|
||||
if (!prev)
|
||||
{
|
||||
# if 0 /* MDEV-29835 FIXME */
|
||||
ut_ad(mtr->memo_contains(index.lock, MTR_MEMO_X_LOCK));
|
||||
# endif
|
||||
prev= btr_block_get(index, id.page_no(), RW_X_LATCH, mtr, &err);
|
||||
if (UNIV_UNLIKELY(!prev))
|
||||
return err;
|
||||
|
@ -3177,9 +3186,7 @@ dberr_t btr_level_list_remove(const buf_block_t& block,
|
|||
#if 1 /* MDEV-29835 FIXME: acquire page latches upfront */
|
||||
if (!next)
|
||||
{
|
||||
# if 0 /* MDEV-29835 FIXME */
|
||||
ut_ad(mtr->memo_contains(index.lock, MTR_MEMO_X_LOCK));
|
||||
# endif
|
||||
next= btr_block_get(index, id.page_no(), RW_X_LATCH, mtr, &err);
|
||||
if (UNIV_UNLIKELY(!next))
|
||||
return err;
|
||||
|
@ -4009,7 +4016,7 @@ btr_discard_page(
|
|||
if (UNIV_UNLIKELY(!merge_block)) {
|
||||
return err;
|
||||
}
|
||||
#if 0 /* MDEV-29385 FIXME: Acquire the page latch upfront. */
|
||||
#if 1 /* MDEV-29835 FIXME: Acquire the page latch upfront. */
|
||||
ut_ad(!memcmp_aligned<4>(merge_block->page.frame
|
||||
+ FIL_PAGE_NEXT,
|
||||
block->page.frame + FIL_PAGE_OFFSET,
|
||||
|
@ -4035,7 +4042,7 @@ btr_discard_page(
|
|||
if (UNIV_UNLIKELY(!merge_block)) {
|
||||
return err;
|
||||
}
|
||||
#if 0 /* MDEV-29385 FIXME: Acquire the page latch upfront. */
|
||||
#if 1 /* MDEV-29835 FIXME: Acquire the page latch upfront. */
|
||||
ut_ad(!memcmp_aligned<4>(merge_block->page.frame
|
||||
+ FIL_PAGE_PREV,
|
||||
block->page.frame + FIL_PAGE_OFFSET,
|
||||
|
@ -4606,8 +4613,7 @@ btr_validate_level(
|
|||
/*===============*/
|
||||
dict_index_t* index, /*!< in: index tree */
|
||||
const trx_t* trx, /*!< in: transaction or NULL */
|
||||
ulint level, /*!< in: level number */
|
||||
bool lockout)/*!< in: true if X-latch index is intended */
|
||||
ulint level) /*!< in: level number */
|
||||
{
|
||||
buf_block_t* block;
|
||||
page_t* page;
|
||||
|
@ -4626,18 +4632,10 @@ btr_validate_level(
|
|||
#ifdef UNIV_ZIP_DEBUG
|
||||
page_zip_des_t* page_zip;
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
ulint savepoint = 0;
|
||||
uint32_t parent_page_no = FIL_NULL;
|
||||
uint32_t parent_right_page_no = FIL_NULL;
|
||||
bool rightmost_child = false;
|
||||
|
||||
mtr.start();
|
||||
|
||||
if (lockout) {
|
||||
mtr_x_lock_index(index, &mtr);
|
||||
} else {
|
||||
mtr_sx_lock_index(index, &mtr);
|
||||
}
|
||||
mtr_x_lock_index(index, &mtr);
|
||||
|
||||
dberr_t err;
|
||||
block = btr_root_block_get(index, RW_SX_LATCH, &mtr, &err);
|
||||
|
@ -4732,11 +4730,7 @@ func_exit:
|
|||
mem_heap_empty(heap);
|
||||
offsets = offsets2 = NULL;
|
||||
|
||||
if (lockout) {
|
||||
mtr_x_lock_index(index, &mtr);
|
||||
} else {
|
||||
mtr_sx_lock_index(index, &mtr);
|
||||
}
|
||||
mtr_x_lock_index(index, &mtr);
|
||||
|
||||
page = block->page.frame;
|
||||
|
||||
|
@ -4780,7 +4774,6 @@ func_exit:
|
|||
|
||||
if (right_page_no != FIL_NULL) {
|
||||
const rec_t* right_rec;
|
||||
savepoint = mtr.get_savepoint();
|
||||
|
||||
right_block = btr_block_get(*index, right_page_no, RW_SX_LATCH,
|
||||
&mtr, &err);
|
||||
|
@ -4883,11 +4876,6 @@ broken_links:
|
|||
father_page = btr_cur_get_page(&node_cur);
|
||||
node_ptr = btr_cur_get_rec(&node_cur);
|
||||
|
||||
parent_page_no = page_get_page_no(father_page);
|
||||
parent_right_page_no = btr_page_get_next(father_page);
|
||||
rightmost_child = page_rec_is_supremum(
|
||||
page_rec_get_next(node_ptr));
|
||||
|
||||
rec = page_rec_get_prev(page_get_supremum_rec(page));
|
||||
if (rec) {
|
||||
btr_cur_position(index, rec, block, &node_cur);
|
||||
|
@ -4969,35 +4957,6 @@ broken_links:
|
|||
}
|
||||
} else if (const rec_t* right_node_ptr
|
||||
= page_rec_get_next(node_ptr)) {
|
||||
if (!lockout && rightmost_child) {
|
||||
|
||||
/* To obey latch order of tree blocks,
|
||||
we should release the right_block once to
|
||||
obtain lock of the uncle block. */
|
||||
ut_ad(right_block
|
||||
== mtr.at_savepoint(savepoint));
|
||||
mtr.rollback_to_savepoint(savepoint,
|
||||
savepoint + 1);
|
||||
|
||||
if (parent_right_page_no != FIL_NULL) {
|
||||
btr_block_get(*index,
|
||||
parent_right_page_no,
|
||||
RW_SX_LATCH, &mtr);
|
||||
}
|
||||
|
||||
right_block = btr_block_get(*index,
|
||||
right_page_no,
|
||||
RW_SX_LATCH,
|
||||
&mtr, &err);
|
||||
if (!right_block) {
|
||||
btr_validate_report1(index, level,
|
||||
block);
|
||||
fputs("InnoDB: broken FIL_PAGE_NEXT"
|
||||
" link\n", stderr);
|
||||
goto invalid_page;
|
||||
}
|
||||
}
|
||||
|
||||
btr_cur_position(
|
||||
index,
|
||||
page_get_infimum_rec(right_block->page.frame),
|
||||
|
@ -5069,19 +5028,6 @@ node_ptr_fails:
|
|||
|
||||
mtr.start();
|
||||
|
||||
if (!lockout) {
|
||||
if (rightmost_child) {
|
||||
if (parent_right_page_no != FIL_NULL) {
|
||||
btr_block_get(*index,
|
||||
parent_right_page_no,
|
||||
RW_SX_LATCH, &mtr);
|
||||
}
|
||||
} else if (parent_page_no != FIL_NULL) {
|
||||
btr_block_get(*index, parent_page_no,
|
||||
RW_SX_LATCH, &mtr);
|
||||
}
|
||||
}
|
||||
|
||||
block = btr_block_get(*index, right_page_no, RW_SX_LATCH,
|
||||
&mtr, &err);
|
||||
goto loop;
|
||||
|
@ -5099,21 +5045,16 @@ btr_validate_index(
|
|||
dict_index_t* index, /*!< in: index */
|
||||
const trx_t* trx) /*!< in: transaction or NULL */
|
||||
{
|
||||
const bool lockout= index->is_spatial();
|
||||
|
||||
mtr_t mtr;
|
||||
mtr.start();
|
||||
|
||||
if (lockout)
|
||||
mtr_x_lock_index(index, &mtr);
|
||||
else
|
||||
mtr_sx_lock_index(index, &mtr);
|
||||
mtr_x_lock_index(index, &mtr);
|
||||
|
||||
dberr_t err;
|
||||
if (page_t *root= btr_root_get(index, &mtr, &err))
|
||||
for (auto level= btr_page_get_level(root);; level--)
|
||||
{
|
||||
if (dberr_t err_level= btr_validate_level(index, trx, level, lockout))
|
||||
if (dberr_t err_level= btr_validate_level(index, trx, level))
|
||||
err= err_level;
|
||||
if (!level)
|
||||
break;
|
||||
|
|
|
@ -750,29 +750,34 @@ btr_cur_will_modify_tree(
|
|||
|
||||
/** Detects whether the modifying record might need a opposite modification
|
||||
to the intention.
|
||||
@param[in] page page
|
||||
@param[in] lock_intention lock intention for the tree operation
|
||||
@param[in] rec record (current node_ptr)
|
||||
@param page page
|
||||
@param lock_intention lock intention for the tree operation
|
||||
@param node_ptr_max_size the maximum size of a node pointer
|
||||
@param compress_limit BTR_CUR_PAGE_COMPRESS_LIMIT(index)
|
||||
@param rec record (current node_ptr)
|
||||
@return true if tree modification is needed */
|
||||
static
|
||||
bool
|
||||
btr_cur_need_opposite_intention(
|
||||
const page_t* page,
|
||||
btr_intention_t lock_intention,
|
||||
const rec_t* rec)
|
||||
static bool btr_cur_need_opposite_intention(const page_t *page,
|
||||
btr_intention_t lock_intention,
|
||||
ulint node_ptr_max_size,
|
||||
ulint compress_limit,
|
||||
const rec_t *rec)
|
||||
{
|
||||
switch (lock_intention) {
|
||||
case BTR_INTENTION_DELETE:
|
||||
return (page_has_prev(page) && page_rec_is_first(rec, page)) ||
|
||||
(page_has_next(page) && page_rec_is_last(rec, page));
|
||||
case BTR_INTENTION_INSERT:
|
||||
return page_has_next(page) && page_rec_is_last(rec, page);
|
||||
case BTR_INTENTION_BOTH:
|
||||
return(false);
|
||||
}
|
||||
|
||||
MY_ASSERT_UNREACHABLE();
|
||||
return(false);
|
||||
if (lock_intention != BTR_INTENTION_INSERT)
|
||||
{
|
||||
/* We compensate also for btr_cur_compress_recommendation() */
|
||||
if (!page_has_siblings(page) ||
|
||||
page_rec_is_first(rec, page) || page_rec_is_last(rec, page) ||
|
||||
page_get_data_size(page) < node_ptr_max_size + compress_limit)
|
||||
return true;
|
||||
if (lock_intention == BTR_INTENTION_DELETE)
|
||||
return false;
|
||||
}
|
||||
else if (page_has_next(page) && page_rec_is_last(rec, page))
|
||||
return true;
|
||||
LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page), return true);
|
||||
const ulint max_size= page_get_max_insert_size_after_reorganize(page, 2);
|
||||
return max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT + node_ptr_max_size ||
|
||||
max_size < node_ptr_max_size * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -997,7 +1002,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
|
|||
|
||||
const ulint savepoint= mtr->get_savepoint();
|
||||
|
||||
ulint node_ptr_max_size= 0;
|
||||
ulint node_ptr_max_size= 0, compress_limit= 0;
|
||||
rw_lock_type_t rw_latch= RW_S_LATCH;
|
||||
|
||||
switch (latch_mode) {
|
||||
|
@ -1009,13 +1014,19 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
|
|||
ut_ad(mtr->memo_contains_flagged(&index()->lock, MTR_MEMO_X_LOCK));
|
||||
break;
|
||||
}
|
||||
if (lock_intention == BTR_INTENTION_DELETE && buf_pool.n_pend_reads &&
|
||||
trx_sys.history_size_approx() > BTR_CUR_FINE_HISTORY_LENGTH)
|
||||
/* Most delete-intended operations are due to the purge of history.
|
||||
Prioritize them when the history list is growing huge. */
|
||||
mtr_x_lock_index(index(), mtr);
|
||||
else
|
||||
mtr_sx_lock_index(index(), mtr);
|
||||
if (lock_intention == BTR_INTENTION_DELETE)
|
||||
{
|
||||
compress_limit= BTR_CUR_PAGE_COMPRESS_LIMIT(index());
|
||||
if (buf_pool.n_pend_reads &&
|
||||
trx_sys.history_size_approx() > BTR_CUR_FINE_HISTORY_LENGTH)
|
||||
{
|
||||
/* Most delete-intended operations are due to the purge of history.
|
||||
Prioritize them when the history list is growing huge. */
|
||||
mtr_x_lock_index(index(), mtr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtr_sx_lock_index(index(), mtr);
|
||||
break;
|
||||
#ifdef UNIV_DEBUG
|
||||
case BTR_CONT_MODIFY_TREE:
|
||||
|
@ -1221,6 +1232,10 @@ release_tree:
|
|||
!btr_block_get(*index(), btr_page_get_next(block->page.frame),
|
||||
RW_X_LATCH, mtr, &err))
|
||||
goto func_exit;
|
||||
if (btr_cur_need_opposite_intention(block->page.frame, lock_intention,
|
||||
node_ptr_max_size, compress_limit,
|
||||
page_cur.rec))
|
||||
goto need_opposite_intention;
|
||||
}
|
||||
|
||||
reached_latched_leaf:
|
||||
|
@ -1274,6 +1289,7 @@ release_tree:
|
|||
break;
|
||||
case BTR_MODIFY_TREE:
|
||||
if (btr_cur_need_opposite_intention(block->page.frame, lock_intention,
|
||||
node_ptr_max_size, compress_limit,
|
||||
page_cur.rec))
|
||||
/* If the rec is the first or last in the page for pessimistic
|
||||
delete intention, it might cause node_ptr insert for the upper
|
||||
|
@ -1417,6 +1433,17 @@ release_tree:
|
|||
goto search_loop;
|
||||
}
|
||||
|
||||
ATTRIBUTE_COLD void mtr_t::index_lock_upgrade()
|
||||
{
|
||||
auto &slot= m_memo[get_savepoint() - 1];
|
||||
if (slot.type == MTR_MEMO_X_LOCK)
|
||||
return;
|
||||
ut_ad(slot.type == MTR_MEMO_SX_LOCK);
|
||||
index_lock *lock= static_cast<index_lock*>(slot.object);
|
||||
lock->u_x_upgrade(SRW_LOCK_CALL);
|
||||
slot.type= MTR_MEMO_X_LOCK;
|
||||
}
|
||||
|
||||
ATTRIBUTE_COLD
|
||||
dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple,
|
||||
page_cur_mode_t mode, mtr_t *mtr)
|
||||
|
@ -1434,8 +1461,7 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple,
|
|||
ut_ad(block->page.id().page_no() == index()->page);
|
||||
block->page.fix();
|
||||
mtr->rollback_to_savepoint(1);
|
||||
ut_ad(mtr->memo_contains_flagged(&index()->lock,
|
||||
MTR_MEMO_SX_LOCK | MTR_MEMO_X_LOCK));
|
||||
mtr->index_lock_upgrade();
|
||||
|
||||
const page_cur_mode_t page_mode{btr_cur_nonleaf_mode(mode)};
|
||||
|
||||
|
@ -1665,7 +1691,6 @@ search_loop:
|
|||
dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
||||
btr_latch_mode latch_mode, mtr_t *mtr)
|
||||
{
|
||||
btr_intention_t lock_intention;
|
||||
ulint n_blocks= 0;
|
||||
mem_heap_t *heap= nullptr;
|
||||
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
|
@ -1677,7 +1702,7 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
const bool latch_by_caller= latch_mode & BTR_ALREADY_S_LATCHED;
|
||||
latch_mode= btr_latch_mode(latch_mode & ~BTR_ALREADY_S_LATCHED);
|
||||
|
||||
lock_intention= btr_cur_get_and_clear_intention(&latch_mode);
|
||||
btr_intention_t lock_intention= btr_cur_get_and_clear_intention(&latch_mode);
|
||||
|
||||
/* Store the position of the tree latch we push to mtr so that we
|
||||
know how to release it when we have latched the leaf node */
|
||||
|
@ -1685,7 +1710,7 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
auto savepoint= mtr->get_savepoint();
|
||||
|
||||
rw_lock_type_t upper_rw_latch= RW_X_LATCH;
|
||||
ulint node_ptr_max_size= 0;
|
||||
ulint node_ptr_max_size= 0, compress_limit= 0;
|
||||
|
||||
if (latch_mode == BTR_MODIFY_TREE)
|
||||
{
|
||||
|
@ -1694,12 +1719,18 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
and read IO bandwidth should be prioritized for them, when the
|
||||
history list is growing huge. */
|
||||
savepoint++;
|
||||
if (lock_intention == BTR_INTENTION_DELETE
|
||||
&& buf_pool.n_pend_reads
|
||||
&& trx_sys.history_size_approx() > BTR_CUR_FINE_HISTORY_LENGTH)
|
||||
mtr_x_lock_index(index, mtr);
|
||||
else
|
||||
mtr_sx_lock_index(index, mtr);
|
||||
if (lock_intention == BTR_INTENTION_DELETE)
|
||||
{
|
||||
compress_limit= BTR_CUR_PAGE_COMPRESS_LIMIT(index);
|
||||
|
||||
if (buf_pool.n_pend_reads &&
|
||||
trx_sys.history_size_approx() > BTR_CUR_FINE_HISTORY_LENGTH)
|
||||
{
|
||||
mtr_x_lock_index(index, mtr);
|
||||
goto index_locked;
|
||||
}
|
||||
}
|
||||
mtr_sx_lock_index(index, mtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1720,6 +1751,7 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
}
|
||||
}
|
||||
|
||||
index_locked:
|
||||
ut_ad(savepoint == mtr->get_savepoint());
|
||||
|
||||
const rw_lock_type_t root_leaf_rw_latch=
|
||||
|
@ -1792,15 +1824,28 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
!btr_block_get(*index, btr_page_get_next(block->page.frame),
|
||||
RW_X_LATCH, mtr, &err))
|
||||
break;
|
||||
|
||||
if (!index->lock.have_x() &&
|
||||
btr_cur_need_opposite_intention(block->page.frame,
|
||||
lock_intention,
|
||||
node_ptr_max_size,
|
||||
compress_limit, page_cur.rec))
|
||||
goto need_opposite_intention;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rw_latch == RW_NO_LATCH)
|
||||
mtr->upgrade_buffer_fix(leaf_savepoint - 1,
|
||||
rw_lock_type_t(latch_mode));
|
||||
/* Release index->lock if needed, and the non-leaf pages. */
|
||||
mtr->rollback_to_savepoint(savepoint - !latch_by_caller,
|
||||
leaf_savepoint - 1);
|
||||
rw_lock_type_t(latch_mode &
|
||||
(RW_X_LATCH | RW_S_LATCH)));
|
||||
if (latch_mode != BTR_CONT_MODIFY_TREE)
|
||||
{
|
||||
ut_ad(latch_mode == BTR_MODIFY_LEAF ||
|
||||
latch_mode == BTR_SEARCH_LEAF);
|
||||
/* Release index->lock if needed, and the non-leaf pages. */
|
||||
mtr->rollback_to_savepoint(savepoint - !latch_by_caller,
|
||||
leaf_savepoint - 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1822,22 +1867,25 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
: !page_cur_move_to_prev(&page_cur))
|
||||
goto corrupted;
|
||||
|
||||
const rec_t *node_ptr= page_cur.rec;
|
||||
offsets= rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED,
|
||||
offsets= rec_get_offsets(page_cur.rec, index, offsets, 0, ULINT_UNDEFINED,
|
||||
&heap);
|
||||
|
||||
ut_ad(latch_mode != BTR_MODIFY_TREE || upper_rw_latch == RW_X_LATCH);
|
||||
|
||||
if (latch_mode != BTR_MODIFY_TREE);
|
||||
else if (btr_cur_need_opposite_intention(block->page.frame,
|
||||
lock_intention, node_ptr))
|
||||
else if (btr_cur_need_opposite_intention(block->page.frame, lock_intention,
|
||||
node_ptr_max_size, compress_limit,
|
||||
page_cur.rec))
|
||||
{
|
||||
need_opposite_intention:
|
||||
/* If the rec is the first or last in the page for pessimistic
|
||||
delete intention, it might cause node_ptr insert for the upper
|
||||
level. We should change the intention and retry. */
|
||||
|
||||
mtr->rollback_to_savepoint(savepoint);
|
||||
lock_intention= BTR_INTENTION_BOTH;
|
||||
mtr->index_lock_upgrade();
|
||||
/* X-latch all pages from now on */
|
||||
latch_mode= BTR_CONT_MODIFY_TREE;
|
||||
page= index->page;
|
||||
height= ULINT_UNDEFINED;
|
||||
n_blocks= 0;
|
||||
|
@ -1846,7 +1894,7 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
else
|
||||
{
|
||||
if (!btr_cur_will_modify_tree(index, block->page.frame,
|
||||
lock_intention, node_ptr,
|
||||
lock_intention, page_cur.rec,
|
||||
node_ptr_max_size, zip_size, mtr))
|
||||
{
|
||||
ut_ad(n_blocks);
|
||||
|
@ -1876,7 +1924,7 @@ dberr_t btr_cur_t::open_leaf(bool first, dict_index_t *index,
|
|||
}
|
||||
|
||||
/* Go to the child node */
|
||||
page= btr_node_ptr_get_child_page_no(node_ptr, offsets);
|
||||
page= btr_node_ptr_get_child_page_no(page_cur.rec, offsets);
|
||||
n_blocks++;
|
||||
}
|
||||
|
||||
|
@ -2178,8 +2226,7 @@ convert_big_rec:
|
|||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
|
||||
LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page),
|
||||
goto fail);
|
||||
LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page), goto fail);
|
||||
|
||||
if (block->page.zip.data && leaf
|
||||
&& (page_get_data_size(page) + rec_size
|
||||
|
@ -2193,7 +2240,7 @@ fail:
|
|||
|
||||
/* prefetch siblings of the leaf for the pessimistic
|
||||
operation, if the page is leaf. */
|
||||
if (page_is_leaf(page)) {
|
||||
if (leaf) {
|
||||
btr_cur_prefetch_siblings(block, index);
|
||||
}
|
||||
fail_err:
|
||||
|
@ -2262,7 +2309,7 @@ fail_err:
|
|||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (!(flags & BTR_CREATE_FLAG)
|
||||
&& index->is_primary() && page_is_leaf(page)) {
|
||||
&& leaf && index->is_primary()) {
|
||||
const dfield_t* trx_id = dtuple_get_nth_field(
|
||||
entry, dict_col_get_clust_pos(
|
||||
dict_table_get_sys_col(index->table,
|
||||
|
|
|
@ -408,7 +408,6 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage,
|
|||
if (id.space() == SRV_TMP_SPACE_ID
|
||||
&& innodb_encrypt_temporary_tables) {
|
||||
slot = buf_pool.io_buf_reserve();
|
||||
ut_a(slot);
|
||||
slot->allocate();
|
||||
bool ok = buf_tmp_page_decrypt(slot->crypt_buf, dst_frame);
|
||||
slot->release();
|
||||
|
@ -431,7 +430,6 @@ decompress:
|
|||
}
|
||||
|
||||
slot = buf_pool.io_buf_reserve();
|
||||
ut_a(slot);
|
||||
slot->allocate();
|
||||
|
||||
decompress_with_slot:
|
||||
|
@ -455,7 +453,6 @@ decrypt_failed:
|
|||
}
|
||||
|
||||
slot = buf_pool.io_buf_reserve();
|
||||
ut_a(slot);
|
||||
slot->allocate();
|
||||
|
||||
/* decrypt using crypt_buf to dst_frame */
|
||||
|
@ -1287,6 +1284,41 @@ inline bool buf_pool_t::realloc(buf_block_t *block)
|
|||
return(true); /* free_list was enough */
|
||||
}
|
||||
|
||||
void buf_pool_t::io_buf_t::create(ulint n_slots)
|
||||
{
|
||||
this->n_slots= n_slots;
|
||||
slots= static_cast<buf_tmp_buffer_t*>
|
||||
(ut_malloc_nokey(n_slots * sizeof *slots));
|
||||
memset((void*) slots, 0, n_slots * sizeof *slots);
|
||||
}
|
||||
|
||||
void buf_pool_t::io_buf_t::close()
|
||||
{
|
||||
for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++)
|
||||
{
|
||||
aligned_free(s->crypt_buf);
|
||||
aligned_free(s->comp_buf);
|
||||
}
|
||||
ut_free(slots);
|
||||
slots= nullptr;
|
||||
n_slots= 0;
|
||||
}
|
||||
|
||||
buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++)
|
||||
if (s->acquire())
|
||||
return s;
|
||||
os_aio_wait_until_no_pending_writes();
|
||||
for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++)
|
||||
if (s->acquire())
|
||||
return s;
|
||||
os_aio_wait_until_no_pending_reads();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the global variable that feeds MySQL's innodb_buffer_pool_resize_status
|
||||
to the specified string. The format and the following parameters are the
|
||||
same as the ones used for printf(3).
|
||||
|
@ -1353,21 +1385,25 @@ inline bool buf_pool_t::withdraw_blocks()
|
|||
|
||||
block = next_block;
|
||||
}
|
||||
mysql_mutex_unlock(&mutex);
|
||||
|
||||
/* reserve free_list length */
|
||||
if (UT_LIST_GET_LEN(withdraw) < withdraw_target) {
|
||||
buf_flush_LRU(
|
||||
std::max<ulint>(withdraw_target
|
||||
- UT_LIST_GET_LEN(withdraw),
|
||||
srv_LRU_scan_depth));
|
||||
buf_flush_wait_batch_end_acquiring_mutex(true);
|
||||
srv_LRU_scan_depth),
|
||||
true);
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
buf_dblwr.flush_buffered_writes();
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
buf_flush_wait_LRU_batch_end();
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
}
|
||||
|
||||
/* relocate blocks/buddies in withdrawn area */
|
||||
ulint count2 = 0;
|
||||
|
||||
mysql_mutex_lock(&mutex);
|
||||
buf_pool_mutex_exit_forbid();
|
||||
for (buf_page_t* bpage = UT_LIST_GET_FIRST(LRU), *next_bpage;
|
||||
bpage; bpage = next_bpage) {
|
||||
|
@ -2095,13 +2131,15 @@ lookup:
|
|||
return bpage;
|
||||
|
||||
must_read_page:
|
||||
if (dberr_t err= buf_read_page(page_id, zip_size, chain))
|
||||
{
|
||||
switch (dberr_t err= buf_read_page(page_id, zip_size, chain)) {
|
||||
case DB_SUCCESS:
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
goto lookup;
|
||||
default:
|
||||
ib::error() << "Reading compressed page " << page_id
|
||||
<< " failed with error: " << err;
|
||||
return nullptr;
|
||||
}
|
||||
goto lookup;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -2245,15 +2283,14 @@ buf_page_get_low(
|
|||
|
||||
#ifdef UNIV_DEBUG
|
||||
switch (mode) {
|
||||
case BUF_PEEK_IF_IN_POOL:
|
||||
default:
|
||||
ut_ad(mode == BUF_PEEK_IF_IN_POOL);
|
||||
break;
|
||||
case BUF_GET_POSSIBLY_FREED:
|
||||
case BUF_GET_IF_IN_POOL:
|
||||
/* The caller may pass a dummy page size,
|
||||
because it does not really matter. */
|
||||
break;
|
||||
default:
|
||||
MY_ASSERT_UNREACHABLE();
|
||||
case BUF_GET_POSSIBLY_FREED:
|
||||
break;
|
||||
case BUF_GET:
|
||||
ut_ad(!mtr->is_freeing_tree());
|
||||
fil_space_t* s = fil_space_get(page_id.space());
|
||||
|
@ -2319,20 +2356,23 @@ loop:
|
|||
corrupted, or if an encrypted page with a valid
|
||||
checksum cannot be decypted. */
|
||||
|
||||
if (dberr_t local_err = buf_read_page(page_id, zip_size, chain)) {
|
||||
if (local_err != DB_CORRUPTION
|
||||
&& mode != BUF_GET_POSSIBLY_FREED
|
||||
switch (dberr_t local_err = buf_read_page(page_id, zip_size, chain)) {
|
||||
case DB_SUCCESS:
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
buf_read_ahead_random(page_id, zip_size);
|
||||
break;
|
||||
default:
|
||||
if (mode != BUF_GET_POSSIBLY_FREED
|
||||
&& retries++ < BUF_PAGE_READ_MAX_RETRIES) {
|
||||
DBUG_EXECUTE_IF("intermittent_read_failure",
|
||||
retries = BUF_PAGE_READ_MAX_RETRIES;);
|
||||
} else {
|
||||
if (err) {
|
||||
*err = local_err;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
buf_read_ahead_random(page_id, zip_size);
|
||||
/* fall through */
|
||||
case DB_PAGE_CORRUPTED:
|
||||
if (err) {
|
||||
*err = local_err;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ut_d(if (!(++buf_dbg_counter % 5771)) buf_pool.validate());
|
||||
|
@ -2383,11 +2423,12 @@ ignore_block:
|
|||
return nullptr;
|
||||
}
|
||||
} else if (mode != BUF_PEEK_IF_IN_POOL) {
|
||||
} else if (!mtr) {
|
||||
} else if (!mtr) {
|
||||
ut_ad(!block->page.oldest_modification());
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
block->unfix();
|
||||
|
||||
free_unfixed_block:
|
||||
if (!buf_LRU_free_page(&block->page, true)) {
|
||||
ut_ad(0);
|
||||
}
|
||||
|
@ -2495,20 +2536,19 @@ wait_for_unfix:
|
|||
|
||||
/* Decompress the page while not holding
|
||||
buf_pool.mutex. */
|
||||
auto ok = buf_zip_decompress(block, false);
|
||||
block->page.read_unfix(state);
|
||||
state = block->page.state();
|
||||
block->page.lock.x_unlock();
|
||||
const auto ok = buf_zip_decompress(block, false);
|
||||
--buf_pool.n_pend_unzip;
|
||||
|
||||
if (!ok) {
|
||||
/* FIXME: Evict the corrupted
|
||||
ROW_FORMAT=COMPRESSED page! */
|
||||
|
||||
if (err) {
|
||||
*err = DB_PAGE_CORRUPTED;
|
||||
}
|
||||
return nullptr;
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
}
|
||||
state = block->page.read_unfix(state);
|
||||
block->page.lock.x_unlock();
|
||||
|
||||
if (!ok) {
|
||||
goto free_unfixed_block;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2606,35 +2646,37 @@ buf_page_get_gen(
|
|||
mtr_t* mtr,
|
||||
dberr_t* err)
|
||||
{
|
||||
if (buf_block_t *block= recv_sys.recover(page_id))
|
||||
buf_block_t *block= recv_sys.recover(page_id);
|
||||
if (UNIV_LIKELY(!block))
|
||||
return buf_page_get_low(page_id, zip_size, rw_latch,
|
||||
guess, mode, mtr, err);
|
||||
else if (UNIV_UNLIKELY(block == reinterpret_cast<buf_block_t*>(-1)))
|
||||
{
|
||||
if (UNIV_UNLIKELY(block == reinterpret_cast<buf_block_t*>(-1)))
|
||||
{
|
||||
corrupted:
|
||||
if (err)
|
||||
*err= DB_CORRUPTION;
|
||||
return nullptr;
|
||||
}
|
||||
/* Recovery is a special case; we fix() before acquiring lock. */
|
||||
auto s= block->page.fix();
|
||||
ut_ad(s >= buf_page_t::FREED);
|
||||
/* The block may be write-fixed at this point because we are not
|
||||
holding a lock, but it must not be read-fixed. */
|
||||
ut_ad(s < buf_page_t::READ_FIX || s >= buf_page_t::WRITE_FIX);
|
||||
if (s < buf_page_t::UNFIXED)
|
||||
{
|
||||
ut_ad(mode == BUF_GET_POSSIBLY_FREED || mode == BUF_PEEK_IF_IN_POOL);
|
||||
block->page.unfix();
|
||||
goto corrupted;
|
||||
}
|
||||
corrupted:
|
||||
if (err)
|
||||
*err= DB_SUCCESS;
|
||||
mtr->page_lock(block, rw_latch);
|
||||
return block;
|
||||
*err= DB_CORRUPTION;
|
||||
return nullptr;
|
||||
}
|
||||
if (err)
|
||||
*err= DB_SUCCESS;
|
||||
/* Recovery is a special case; we fix() before acquiring lock. */
|
||||
auto s= block->page.fix();
|
||||
ut_ad(s >= buf_page_t::FREED);
|
||||
/* The block may be write-fixed at this point because we are not
|
||||
holding a lock, but it must not be read-fixed. */
|
||||
ut_ad(s < buf_page_t::READ_FIX || s >= buf_page_t::WRITE_FIX);
|
||||
if (s < buf_page_t::UNFIXED)
|
||||
{
|
||||
ut_ad(mode == BUF_GET_POSSIBLY_FREED || mode == BUF_PEEK_IF_IN_POOL);
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
block->page.unfix();
|
||||
buf_LRU_free_page(&block->page, true);
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
goto corrupted;
|
||||
}
|
||||
|
||||
return buf_page_get_low(page_id, zip_size, rw_latch,
|
||||
guess, mode, mtr, err);
|
||||
mtr->page_lock(block, rw_latch);
|
||||
return block;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
|
@ -2922,12 +2964,12 @@ retry:
|
|||
buf_unzip_LRU_add_block(reinterpret_cast<buf_block_t*>(bpage), FALSE);
|
||||
}
|
||||
|
||||
buf_pool.stat.n_pages_created++;
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
|
||||
mtr->memo_push(reinterpret_cast<buf_block_t*>(bpage), MTR_MEMO_PAGE_X_FIX);
|
||||
|
||||
bpage->set_accessed();
|
||||
buf_pool.stat.n_pages_created++;
|
||||
|
||||
static_assert(FIL_PAGE_PREV + 4 == FIL_PAGE_NEXT, "adjacent");
|
||||
memset_aligned<8>(bpage->frame + FIL_PAGE_PREV, 0xff, 8);
|
||||
|
@ -3145,7 +3187,6 @@ dberr_t buf_page_t::read_complete(const fil_node_t &node)
|
|||
|
||||
ut_d(auto n=) buf_pool.n_pend_reads--;
|
||||
ut_ad(n > 0);
|
||||
buf_pool.stat.n_pages_read++;
|
||||
|
||||
const byte *read_frame= zip.data ? zip.data : frame;
|
||||
ut_ad(read_frame);
|
||||
|
@ -3286,9 +3327,6 @@ void buf_pool_invalidate()
|
|||
{
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
|
||||
buf_flush_wait_batch_end(true);
|
||||
buf_flush_wait_batch_end(false);
|
||||
|
||||
/* It is possible that a write batch that has been posted
|
||||
earlier is still not complete. For buffer pool invalidation to
|
||||
proceed we must ensure there is NO write activity happening. */
|
||||
|
@ -3439,8 +3477,8 @@ void buf_pool_t::print()
|
|||
<< UT_LIST_GET_LEN(flush_list)
|
||||
<< ", n pending decompressions=" << n_pend_unzip
|
||||
<< ", n pending reads=" << n_pend_reads
|
||||
<< ", n pending flush LRU=" << n_flush_LRU_
|
||||
<< " list=" << n_flush_list_
|
||||
<< ", n pending flush LRU=" << n_flush()
|
||||
<< " list=" << buf_dblwr.pending_writes()
|
||||
<< ", pages made young=" << stat.n_pages_made_young
|
||||
<< ", not young=" << stat.n_pages_not_made_young
|
||||
<< ", pages read=" << stat.n_pages_read
|
||||
|
@ -3552,13 +3590,13 @@ void buf_stats_get_pool_info(buf_pool_info_t *pool_info)
|
|||
pool_info->flush_list_len = UT_LIST_GET_LEN(buf_pool.flush_list);
|
||||
|
||||
pool_info->n_pend_unzip = UT_LIST_GET_LEN(buf_pool.unzip_LRU);
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
|
||||
pool_info->n_pend_reads = buf_pool.n_pend_reads;
|
||||
|
||||
pool_info->n_pending_flush_lru = buf_pool.n_flush_LRU_;
|
||||
pool_info->n_pending_flush_lru = buf_pool.n_flush();
|
||||
|
||||
pool_info->n_pending_flush_list = buf_pool.n_flush_list_;
|
||||
pool_info->n_pending_flush_list = buf_dblwr.pending_writes();
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
|
||||
current_time = time(NULL);
|
||||
time_elapsed = 0.001 + difftime(current_time,
|
||||
|
|
|
@ -46,7 +46,17 @@ inline buf_block_t *buf_dblwr_trx_sys_get(mtr_t *mtr)
|
|||
0, RW_X_LATCH, mtr);
|
||||
}
|
||||
|
||||
/** Initialize the doublewrite buffer data structure.
|
||||
void buf_dblwr_t::init()
|
||||
{
|
||||
if (!active_slot)
|
||||
{
|
||||
active_slot= &slots[0];
|
||||
mysql_mutex_init(buf_dblwr_mutex_key, &mutex, nullptr);
|
||||
pthread_cond_init(&cond, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialise the persistent storage of the doublewrite buffer.
|
||||
@param header doublewrite page header in the TRX_SYS page */
|
||||
inline void buf_dblwr_t::init(const byte *header)
|
||||
{
|
||||
|
@ -54,8 +64,6 @@ inline void buf_dblwr_t::init(const byte *header)
|
|||
ut_ad(!active_slot->reserved);
|
||||
ut_ad(!batch_running);
|
||||
|
||||
mysql_mutex_init(buf_dblwr_mutex_key, &mutex, nullptr);
|
||||
pthread_cond_init(&cond, nullptr);
|
||||
block1= page_id_t(0, mach_read_from_4(header + TRX_SYS_DOUBLEWRITE_BLOCK1));
|
||||
block2= page_id_t(0, mach_read_from_4(header + TRX_SYS_DOUBLEWRITE_BLOCK2));
|
||||
|
||||
|
@ -74,7 +82,7 @@ inline void buf_dblwr_t::init(const byte *header)
|
|||
@return whether the operation succeeded */
|
||||
bool buf_dblwr_t::create()
|
||||
{
|
||||
if (is_initialised())
|
||||
if (is_created())
|
||||
return true;
|
||||
|
||||
mtr_t mtr;
|
||||
|
@ -341,7 +349,7 @@ func_exit:
|
|||
void buf_dblwr_t::recover()
|
||||
{
|
||||
ut_ad(log_sys.last_checkpoint_lsn);
|
||||
if (!is_initialised())
|
||||
if (!is_created())
|
||||
return;
|
||||
|
||||
uint32_t page_no_dblwr= 0;
|
||||
|
@ -450,10 +458,9 @@ next_page:
|
|||
/** Free the doublewrite buffer. */
|
||||
void buf_dblwr_t::close()
|
||||
{
|
||||
if (!is_initialised())
|
||||
if (!active_slot)
|
||||
return;
|
||||
|
||||
/* Free the double write data structures. */
|
||||
ut_ad(!active_slot->reserved);
|
||||
ut_ad(!active_slot->first_free);
|
||||
ut_ad(!batch_running);
|
||||
|
@ -467,35 +474,41 @@ void buf_dblwr_t::close()
|
|||
mysql_mutex_destroy(&mutex);
|
||||
|
||||
memset((void*) this, 0, sizeof *this);
|
||||
active_slot= &slots[0];
|
||||
}
|
||||
|
||||
/** Update the doublewrite buffer on write completion. */
|
||||
void buf_dblwr_t::write_completed()
|
||||
void buf_dblwr_t::write_completed(bool with_doublewrite)
|
||||
{
|
||||
ut_ad(this == &buf_dblwr);
|
||||
ut_ad(srv_use_doublewrite_buf);
|
||||
ut_ad(is_initialised());
|
||||
ut_ad(!srv_read_only_mode);
|
||||
|
||||
mysql_mutex_lock(&mutex);
|
||||
|
||||
ut_ad(batch_running);
|
||||
slot *flush_slot= active_slot == &slots[0] ? &slots[1] : &slots[0];
|
||||
ut_ad(flush_slot->reserved);
|
||||
ut_ad(flush_slot->reserved <= flush_slot->first_free);
|
||||
ut_ad(writes_pending);
|
||||
if (!--writes_pending)
|
||||
pthread_cond_broadcast(&write_cond);
|
||||
|
||||
if (!--flush_slot->reserved)
|
||||
if (with_doublewrite)
|
||||
{
|
||||
mysql_mutex_unlock(&mutex);
|
||||
/* This will finish the batch. Sync data files to the disk. */
|
||||
fil_flush_file_spaces();
|
||||
mysql_mutex_lock(&mutex);
|
||||
ut_ad(is_created());
|
||||
ut_ad(srv_use_doublewrite_buf);
|
||||
ut_ad(batch_running);
|
||||
slot *flush_slot= active_slot == &slots[0] ? &slots[1] : &slots[0];
|
||||
ut_ad(flush_slot->reserved);
|
||||
ut_ad(flush_slot->reserved <= flush_slot->first_free);
|
||||
|
||||
/* We can now reuse the doublewrite memory buffer: */
|
||||
flush_slot->first_free= 0;
|
||||
batch_running= false;
|
||||
pthread_cond_broadcast(&cond);
|
||||
if (!--flush_slot->reserved)
|
||||
{
|
||||
mysql_mutex_unlock(&mutex);
|
||||
/* This will finish the batch. Sync data files to the disk. */
|
||||
fil_flush_file_spaces();
|
||||
mysql_mutex_lock(&mutex);
|
||||
|
||||
/* We can now reuse the doublewrite memory buffer: */
|
||||
flush_slot->first_free= 0;
|
||||
batch_running= false;
|
||||
pthread_cond_broadcast(&cond);
|
||||
}
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&mutex);
|
||||
|
@ -640,7 +653,7 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request)
|
|||
{
|
||||
ut_ad(this == &buf_dblwr);
|
||||
ut_ad(srv_use_doublewrite_buf);
|
||||
ut_ad(is_initialised());
|
||||
ut_ad(is_created());
|
||||
ut_ad(!srv_read_only_mode);
|
||||
ut_ad(!request.bpage);
|
||||
ut_ad(request.node == fil_system.sys_space->chain.start);
|
||||
|
@ -706,7 +719,7 @@ posted, and also when we may have to wait for a page latch!
|
|||
Otherwise a deadlock of threads can occur. */
|
||||
void buf_dblwr_t::flush_buffered_writes()
|
||||
{
|
||||
if (!is_initialised() || !srv_use_doublewrite_buf)
|
||||
if (!is_created() || !srv_use_doublewrite_buf)
|
||||
{
|
||||
fil_flush_file_spaces();
|
||||
return;
|
||||
|
@ -739,6 +752,7 @@ void buf_dblwr_t::add_to_batch(const IORequest &request, size_t size)
|
|||
const ulint buf_size= 2 * block_size();
|
||||
|
||||
mysql_mutex_lock(&mutex);
|
||||
writes_pending++;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -136,7 +136,6 @@ static void buf_LRU_block_free_hashed_page(buf_block_t *block)
|
|||
@param[in] bpage control block */
|
||||
static inline void incr_LRU_size_in_bytes(const buf_page_t* bpage)
|
||||
{
|
||||
/* FIXME: use atomics, not mutex */
|
||||
mysql_mutex_assert_owner(&buf_pool.mutex);
|
||||
|
||||
buf_pool.stat.LRU_bytes += bpage->physical_size();
|
||||
|
@ -401,8 +400,10 @@ buf_block_t* buf_LRU_get_free_block(buf_LRU_get get)
|
|||
DBUG_EXECUTE_IF("recv_ran_out_of_buffer",
|
||||
if (recv_recovery_is_on()
|
||||
&& recv_sys.apply_log_recs) {
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
goto flush_lru;
|
||||
});
|
||||
get_mutex:
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
got_mutex:
|
||||
buf_LRU_check_size_of_non_data_objects();
|
||||
|
@ -451,20 +452,32 @@ got_block:
|
|||
if ((block = buf_LRU_get_free_only()) != nullptr) {
|
||||
goto got_block;
|
||||
}
|
||||
if (!buf_pool.n_flush_LRU_) {
|
||||
break;
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
const auto n_flush = buf_pool.n_flush();
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
if (!n_flush) {
|
||||
goto not_found;
|
||||
}
|
||||
if (!buf_pool.try_LRU_scan) {
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
buf_pool.page_cleaner_wakeup(true);
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
my_cond_wait(&buf_pool.done_free,
|
||||
&buf_pool.mutex.m_mutex);
|
||||
}
|
||||
my_cond_wait(&buf_pool.done_free, &buf_pool.mutex.m_mutex);
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
not_found:
|
||||
#endif
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
if (n_iterations > 1) {
|
||||
MONITOR_INC( MONITOR_LRU_GET_FREE_WAITS );
|
||||
}
|
||||
|
||||
if (n_iterations > 20 && !buf_lru_free_blocks_error_printed
|
||||
if (n_iterations == 21 && !buf_lru_free_blocks_error_printed
|
||||
&& srv_buf_pool_old_size == srv_buf_pool_size) {
|
||||
|
||||
buf_lru_free_blocks_error_printed = true;
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
ib::warn() << "Difficult to find free blocks in the buffer pool"
|
||||
" (" << n_iterations << " search iterations)! "
|
||||
<< flush_failures << " failed attempts to"
|
||||
|
@ -476,12 +489,7 @@ not_found:
|
|||
<< os_n_file_writes << " OS file writes, "
|
||||
<< os_n_fsyncs
|
||||
<< " OS fsyncs.";
|
||||
|
||||
buf_lru_free_blocks_error_printed = true;
|
||||
}
|
||||
|
||||
if (n_iterations > 1) {
|
||||
MONITOR_INC( MONITOR_LRU_GET_FREE_WAITS );
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
}
|
||||
|
||||
/* No free block was found: try to flush the LRU list.
|
||||
|
@ -495,15 +503,16 @@ not_found:
|
|||
#ifndef DBUG_OFF
|
||||
flush_lru:
|
||||
#endif
|
||||
if (!buf_flush_LRU(innodb_lru_flush_size)) {
|
||||
if (!buf_flush_LRU(innodb_lru_flush_size, true)) {
|
||||
MONITOR_INC(MONITOR_LRU_SINGLE_FLUSH_FAILURE_COUNT);
|
||||
++flush_failures;
|
||||
}
|
||||
|
||||
n_iterations++;
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
buf_pool.stat.LRU_waits++;
|
||||
goto got_mutex;
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
buf_dblwr.flush_buffered_writes();
|
||||
goto get_mutex;
|
||||
}
|
||||
|
||||
/** Move the LRU_old pointer so that the length of the old blocks list
|
||||
|
@ -812,50 +821,57 @@ bool buf_LRU_free_page(buf_page_t *bpage, bool zip)
|
|||
/* We cannot use transactional_lock_guard here,
|
||||
because buf_buddy_relocate() in buf_buddy_free() could get stuck. */
|
||||
hash_lock.lock();
|
||||
lsn_t oldest_modification = bpage->oldest_modification_acquire();
|
||||
const lsn_t oldest_modification = bpage->oldest_modification_acquire();
|
||||
|
||||
if (UNIV_UNLIKELY(!bpage->can_relocate())) {
|
||||
/* Do not free buffer fixed and I/O-fixed blocks. */
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (oldest_modification == 1) {
|
||||
switch (oldest_modification) {
|
||||
case 2:
|
||||
ut_ad(id.space() == SRV_TMP_SPACE_ID);
|
||||
ut_ad(!bpage->zip.data);
|
||||
if (!bpage->is_freed()) {
|
||||
goto func_exit;
|
||||
}
|
||||
bpage->clear_oldest_modification();
|
||||
break;
|
||||
case 1:
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
oldest_modification = bpage->oldest_modification();
|
||||
if (oldest_modification) {
|
||||
ut_ad(oldest_modification == 1);
|
||||
if (const lsn_t om = bpage->oldest_modification()) {
|
||||
ut_ad(om == 1);
|
||||
buf_pool.delete_from_flush_list(bpage);
|
||||
}
|
||||
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
|
||||
ut_ad(!bpage->oldest_modification());
|
||||
oldest_modification = 0;
|
||||
}
|
||||
|
||||
if (zip || !bpage->zip.data) {
|
||||
/* This would completely free the block. */
|
||||
/* Do not completely free dirty blocks. */
|
||||
|
||||
if (oldest_modification) {
|
||||
goto func_exit;
|
||||
/* fall through */
|
||||
case 0:
|
||||
if (zip || !bpage->zip.data || !bpage->frame) {
|
||||
break;
|
||||
}
|
||||
} else if (oldest_modification && !bpage->frame) {
|
||||
func_exit:
|
||||
hash_lock.unlock();
|
||||
return(false);
|
||||
|
||||
} else if (bpage->frame) {
|
||||
relocate_compressed:
|
||||
b = static_cast<buf_page_t*>(ut_zalloc_nokey(sizeof *b));
|
||||
ut_a(b);
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
new (b) buf_page_t(*bpage);
|
||||
b->frame = nullptr;
|
||||
b->set_state(buf_page_t::UNFIXED + 1);
|
||||
break;
|
||||
default:
|
||||
if (zip || !bpage->zip.data || !bpage->frame) {
|
||||
/* This would completely free the block. */
|
||||
/* Do not completely free dirty blocks. */
|
||||
func_exit:
|
||||
hash_lock.unlock();
|
||||
return(false);
|
||||
}
|
||||
goto relocate_compressed;
|
||||
}
|
||||
|
||||
mysql_mutex_assert_owner(&buf_pool.mutex);
|
||||
|
||||
DBUG_PRINT("ib_buf", ("free page %u:%u",
|
||||
id.space(), id.page_no()));
|
||||
DBUG_PRINT("ib_buf", ("free page %u:%u", id.space(), id.page_no()));
|
||||
|
||||
ut_ad(bpage->can_relocate());
|
||||
|
||||
|
@ -1026,7 +1042,8 @@ buf_LRU_block_free_non_file_page(
|
|||
} else {
|
||||
UT_LIST_ADD_FIRST(buf_pool.free, &block->page);
|
||||
ut_d(block->page.in_free_list = true);
|
||||
pthread_cond_signal(&buf_pool.done_free);
|
||||
buf_pool.try_LRU_scan= true;
|
||||
pthread_cond_broadcast(&buf_pool.done_free);
|
||||
}
|
||||
|
||||
block->page.set_os_unused();
|
||||
|
|
|
@ -186,6 +186,7 @@ page_exists:
|
|||
buf_LRU_add_block(bpage, true/* to old blocks */);
|
||||
}
|
||||
|
||||
buf_pool.stat.n_pages_read++;
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
buf_pool.n_pend_reads++;
|
||||
return bpage;
|
||||
|
@ -205,35 +206,31 @@ flag is cleared and the x-lock released by an i/o-handler thread.
|
|||
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0,
|
||||
bitwise-ORed with 1 in recovery
|
||||
@param[in,out] chain buf_pool.page_hash cell for page_id
|
||||
@param[out] err DB_SUCCESS or DB_TABLESPACE_DELETED
|
||||
if we are trying
|
||||
to read from a non-existent tablespace
|
||||
@param[in,out] space tablespace
|
||||
@param[in,out] block preallocated buffer block
|
||||
@param[in] sync true if synchronous aio is desired
|
||||
@return whether a read request was enqueued */
|
||||
@return error code
|
||||
@retval DB_SUCCESS if the page was read
|
||||
@retval DB_SUCCESS_LOCKED_REC if the page exists in the buffer pool already */
|
||||
static
|
||||
bool
|
||||
dberr_t
|
||||
buf_read_page_low(
|
||||
const page_id_t page_id,
|
||||
ulint zip_size,
|
||||
buf_pool_t::hash_chain& chain,
|
||||
dberr_t* err,
|
||||
fil_space_t* space,
|
||||
buf_block_t*& block,
|
||||
bool sync = false)
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
|
||||
*err = DB_SUCCESS;
|
||||
|
||||
ut_ad(!buf_dblwr.is_inside(page_id));
|
||||
|
||||
bpage = buf_page_init_for_read(page_id, zip_size, chain, block);
|
||||
|
||||
if (!bpage) {
|
||||
space->release();
|
||||
return false;
|
||||
return DB_SUCCESS_LOCKED_REC;
|
||||
}
|
||||
|
||||
ut_ad(bpage->in_file());
|
||||
|
@ -253,7 +250,6 @@ buf_read_page_low(
|
|||
? IORequest::READ_SYNC
|
||||
: IORequest::READ_ASYNC),
|
||||
page_id.page_no() * len, len, dst, bpage);
|
||||
*err = fio.err;
|
||||
|
||||
if (UNIV_UNLIKELY(fio.err != DB_SUCCESS)) {
|
||||
ut_d(auto n=) buf_pool.n_pend_reads--;
|
||||
|
@ -262,14 +258,14 @@ buf_read_page_low(
|
|||
} else if (sync) {
|
||||
thd_wait_end(NULL);
|
||||
/* The i/o was already completed in space->io() */
|
||||
*err = bpage->read_complete(*fio.node);
|
||||
fio.err = bpage->read_complete(*fio.node);
|
||||
space->release();
|
||||
if (*err == DB_FAIL) {
|
||||
*err = DB_PAGE_CORRUPTED;
|
||||
if (fio.err == DB_FAIL) {
|
||||
fio.err = DB_PAGE_CORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return fio.err;
|
||||
}
|
||||
|
||||
/** Acquire a buffer block. */
|
||||
|
@ -353,9 +349,8 @@ read_ahead:
|
|||
if (space->is_stopping())
|
||||
break;
|
||||
buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(i.fold());
|
||||
dberr_t err;
|
||||
space->reacquire();
|
||||
if (buf_read_page_low(i, zip_size, chain, &err, space, block))
|
||||
if (buf_read_page_low(i, zip_size, chain, space, block) == DB_SUCCESS)
|
||||
{
|
||||
count++;
|
||||
ut_ad(!block);
|
||||
|
@ -365,18 +360,20 @@ read_ahead:
|
|||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
DBUG_PRINT("ib_buf", ("random read-ahead %zu pages from %s: %u",
|
||||
count, space->chain.start->name,
|
||||
low.page_no()));
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
/* Read ahead is considered one I/O operation for the purpose of
|
||||
LRU policy decision. */
|
||||
buf_LRU_stat_inc_io();
|
||||
buf_pool.stat.n_ra_pages_read_rnd+= count;
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
}
|
||||
|
||||
space->release();
|
||||
|
||||
/* Read ahead is considered one I/O operation for the purpose of
|
||||
LRU policy decision. */
|
||||
buf_LRU_stat_inc_io();
|
||||
buf_read_release(block);
|
||||
|
||||
buf_pool.stat.n_ra_pages_read_rnd+= count;
|
||||
srv_stats.buf_pool_reads.add(count);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -388,6 +385,7 @@ released by the i/o-handler thread.
|
|||
@param zip_size ROW_FORMAT=COMPRESSED page size, or 0
|
||||
@param chain buf_pool.page_hash cell for page_id
|
||||
@retval DB_SUCCESS if the page was read and is not corrupted,
|
||||
@retval DB_SUCCESS_LOCKED_REC if the page was not read
|
||||
@retval DB_PAGE_CORRUPTED if page based on checksum check is corrupted,
|
||||
@retval DB_DECRYPTION_FAILED if page post encryption checksum matches but
|
||||
after decryption normal page checksum does not match.
|
||||
|
@ -403,22 +401,19 @@ dberr_t buf_read_page(const page_id_t page_id, ulint zip_size,
|
|||
return DB_TABLESPACE_DELETED;
|
||||
}
|
||||
|
||||
buf_block_t *block= zip_size
|
||||
? nullptr
|
||||
: buf_LRU_get_free_block(have_no_mutex);
|
||||
|
||||
/* Our caller should already have ensured that the page does not
|
||||
exist in buf_pool.page_hash. */
|
||||
dberr_t err;
|
||||
if (buf_read_page_low(page_id, zip_size, chain, &err, space, block, true))
|
||||
buf_block_t *block= nullptr;
|
||||
if (UNIV_LIKELY(!zip_size))
|
||||
{
|
||||
ut_ad(!block);
|
||||
srv_stats.buf_pool_reads.add(1);
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
buf_LRU_stat_inc_io();
|
||||
block= buf_LRU_get_free_block(have_mutex);
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
}
|
||||
else
|
||||
buf_read_release(block);
|
||||
|
||||
buf_LRU_stat_inc_io();
|
||||
dberr_t err= buf_read_page_low(page_id, zip_size, chain, space, block, true);
|
||||
buf_read_release(block);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -444,12 +439,9 @@ void buf_read_page_background(fil_space_t *space, const page_id_t page_id,
|
|||
if (!zip_size && !(block= buf_read_acquire()))
|
||||
goto skip;
|
||||
|
||||
dberr_t err;
|
||||
if (buf_read_page_low(page_id, zip_size, chain, &err, space, block))
|
||||
{
|
||||
if (buf_read_page_low(page_id, zip_size, chain, space, block) ==
|
||||
DB_SUCCESS)
|
||||
ut_ad(!block);
|
||||
srv_stats.buf_pool_reads.add(1);
|
||||
}
|
||||
else
|
||||
buf_read_release(block);
|
||||
|
||||
|
@ -601,9 +593,9 @@ failed:
|
|||
if (space->is_stopping())
|
||||
break;
|
||||
buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(new_low.fold());
|
||||
dberr_t err;
|
||||
space->reacquire();
|
||||
if (buf_read_page_low(new_low, zip_size, chain, &err, space, block))
|
||||
if (buf_read_page_low(new_low, zip_size, chain, space, block) ==
|
||||
DB_SUCCESS)
|
||||
{
|
||||
count++;
|
||||
ut_ad(!block);
|
||||
|
@ -613,17 +605,20 @@ failed:
|
|||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
DBUG_PRINT("ib_buf", ("random read-ahead %zu pages from %s: %u",
|
||||
count, space->chain.start->name,
|
||||
new_low.page_no()));
|
||||
mysql_mutex_lock(&buf_pool.mutex);
|
||||
/* Read ahead is considered one I/O operation for the purpose of
|
||||
LRU policy decision. */
|
||||
buf_LRU_stat_inc_io();
|
||||
buf_pool.stat.n_ra_pages_read+= count;
|
||||
mysql_mutex_unlock(&buf_pool.mutex);
|
||||
}
|
||||
|
||||
space->release();
|
||||
|
||||
/* Read ahead is considered one I/O operation for the purpose of
|
||||
LRU policy decision. */
|
||||
buf_LRU_stat_inc_io();
|
||||
buf_read_release(block);
|
||||
|
||||
buf_pool.stat.n_ra_pages_read+= count;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -679,20 +674,22 @@ void buf_read_recv_pages(uint32_t space_id, st_::span<uint32_t> page_nos)
|
|||
|
||||
buf_pool_t::hash_chain& chain =
|
||||
buf_pool.page_hash.cell_get(cur_page_id.fold());
|
||||
dberr_t err;
|
||||
space->reacquire();
|
||||
if (buf_read_page_low(cur_page_id, zip_size, chain, &err, space,
|
||||
block)) {
|
||||
switch (buf_read_page_low(cur_page_id, zip_size, chain, space,
|
||||
block)) {
|
||||
case DB_SUCCESS:
|
||||
ut_ad(!block);
|
||||
block = buf_LRU_get_free_block(have_no_mutex);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
break;
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
break;
|
||||
default:
|
||||
sql_print_error("InnoDB: Recovery failed to read page "
|
||||
UINT32PF " from %s",
|
||||
cur_page_id.page_no(),
|
||||
space->chain.start->name);
|
||||
}
|
||||
ut_ad(block);
|
||||
}
|
||||
|
||||
DBUG_PRINT("ib_buf", ("recovery read (%zu pages) for %s",
|
||||
|
|
|
@ -118,6 +118,9 @@ bool fil_space_t::try_to_close(bool print_info)
|
|||
}
|
||||
|
||||
node->close();
|
||||
|
||||
fil_system.move_closed_last_to_space_list(node->space);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -392,13 +395,7 @@ static bool fil_node_open_file_low(fil_node_t *node)
|
|||
|
||||
ut_ad(node->is_open());
|
||||
|
||||
if (UNIV_LIKELY(!fil_system.freeze_space_list))
|
||||
{
|
||||
/* Move the file last in fil_system.space_list, so that
|
||||
fil_space_t::try_to_close() should close it as a last resort. */
|
||||
fil_system.space_list.erase(space_list_t::iterator(node->space));
|
||||
fil_system.space_list.push_back(*node->space);
|
||||
}
|
||||
fil_system.move_opened_last_to_space_list(node->space);
|
||||
|
||||
fil_system.n_open++;
|
||||
return true;
|
||||
|
@ -797,7 +794,17 @@ pfs_os_file_t fil_system_t::detach(fil_space_t *space, bool detach_handle)
|
|||
space->is_in_default_encrypt= false;
|
||||
default_encrypt_tables.remove(*space);
|
||||
}
|
||||
space_list.erase(space_list_t::iterator(space));
|
||||
|
||||
{
|
||||
space_list_t::iterator s= space_list_t::iterator(space);
|
||||
if (space_list_last_opened == space)
|
||||
{
|
||||
space_list_t::iterator prev= s;
|
||||
space_list_last_opened= &*--prev;
|
||||
}
|
||||
space_list.erase(s);
|
||||
}
|
||||
|
||||
if (space == sys_space)
|
||||
sys_space= nullptr;
|
||||
else if (space == temp_space)
|
||||
|
@ -916,12 +923,14 @@ bool fil_space_free(uint32_t id, bool x_latched)
|
|||
@param purpose tablespace purpose
|
||||
@param crypt_data encryption information
|
||||
@param mode encryption mode
|
||||
@param opened true if space files are opened
|
||||
@return pointer to created tablespace, to be filled in with add()
|
||||
@retval nullptr on failure (such as when the same tablespace exists) */
|
||||
fil_space_t *fil_space_t::create(uint32_t id, uint32_t flags,
|
||||
fil_type_t purpose,
|
||||
fil_space_crypt_t *crypt_data,
|
||||
fil_encryption_t mode)
|
||||
fil_encryption_t mode,
|
||||
bool opened)
|
||||
{
|
||||
fil_space_t* space;
|
||||
|
||||
|
@ -974,7 +983,10 @@ fil_space_t *fil_space_t::create(uint32_t id, uint32_t flags,
|
|||
|
||||
HASH_INSERT(fil_space_t, hash, &fil_system.spaces, id, space);
|
||||
|
||||
fil_system.space_list.push_back(*space);
|
||||
if (opened)
|
||||
fil_system.add_opened_last_to_space_list(space);
|
||||
else
|
||||
fil_system.space_list.push_back(*space);
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
|
@ -1295,6 +1307,15 @@ void fil_system_t::close()
|
|||
#endif /* __linux__ */
|
||||
}
|
||||
|
||||
void fil_system_t::add_opened_last_to_space_list(fil_space_t *space)
|
||||
{
|
||||
if (UNIV_LIKELY(space_list_last_opened != nullptr))
|
||||
space_list.insert(space_list_t::iterator(space_list_last_opened), *space);
|
||||
else
|
||||
space_list.push_back(*space);
|
||||
space_list_last_opened= space;
|
||||
}
|
||||
|
||||
/** Extend all open data files to the recovered size */
|
||||
ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size()
|
||||
{
|
||||
|
@ -2028,7 +2049,7 @@ err_exit:
|
|||
|
||||
if (fil_space_t* space = fil_space_t::create(space_id, flags,
|
||||
FIL_TYPE_TABLESPACE,
|
||||
crypt_data, mode)) {
|
||||
crypt_data, mode, true)) {
|
||||
fil_node_t* node = space->add(path, file, size, false, true);
|
||||
IF_WIN(node->find_metadata(), node->find_metadata(file, true));
|
||||
mtr.start();
|
||||
|
|
|
@ -890,6 +890,8 @@ rtr_page_split_and_insert(
|
|||
int first_rec_group = 1;
|
||||
IF_DBUG(bool iterated = false,);
|
||||
|
||||
buf_pool.pages_split++;
|
||||
|
||||
if (!*heap) {
|
||||
*heap = mem_heap_create(1024);
|
||||
}
|
||||
|
@ -1197,8 +1199,6 @@ after_insert:
|
|||
|
||||
ut_ad(!rec || rec_offs_validate(rec, cursor->index(), *offsets));
|
||||
#endif
|
||||
MONITOR_INC(MONITOR_INDEX_SPLIT);
|
||||
|
||||
return(rec);
|
||||
}
|
||||
|
||||
|
|
|
@ -893,43 +893,37 @@ static SHOW_VAR innodb_status_variables[]= {
|
|||
(char*) &export_vars.innodb_buffer_pool_resize_status, SHOW_CHAR},
|
||||
{"buffer_pool_load_incomplete",
|
||||
&export_vars.innodb_buffer_pool_load_incomplete, SHOW_BOOL},
|
||||
{"buffer_pool_pages_data",
|
||||
&export_vars.innodb_buffer_pool_pages_data, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_data", &UT_LIST_GET_LEN(buf_pool.LRU), SHOW_SIZE_T},
|
||||
{"buffer_pool_bytes_data",
|
||||
&export_vars.innodb_buffer_pool_bytes_data, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_dirty",
|
||||
&export_vars.innodb_buffer_pool_pages_dirty, SHOW_SIZE_T},
|
||||
{"buffer_pool_bytes_dirty",
|
||||
&export_vars.innodb_buffer_pool_bytes_dirty, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_flushed", &buf_flush_page_count, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_free",
|
||||
&export_vars.innodb_buffer_pool_pages_free, SHOW_SIZE_T},
|
||||
&UT_LIST_GET_LEN(buf_pool.flush_list), SHOW_SIZE_T},
|
||||
{"buffer_pool_bytes_dirty", &buf_pool.flush_list_bytes, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_flushed", &buf_pool.stat.n_pages_written, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_free", &UT_LIST_GET_LEN(buf_pool.free), SHOW_SIZE_T},
|
||||
#ifdef UNIV_DEBUG
|
||||
{"buffer_pool_pages_latched",
|
||||
&export_vars.innodb_buffer_pool_pages_latched, SHOW_SIZE_T},
|
||||
#endif /* UNIV_DEBUG */
|
||||
{"buffer_pool_pages_made_not_young",
|
||||
&export_vars.innodb_buffer_pool_pages_made_not_young, SHOW_SIZE_T},
|
||||
&buf_pool.stat.n_pages_not_made_young, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_made_young",
|
||||
&export_vars.innodb_buffer_pool_pages_made_young, SHOW_SIZE_T},
|
||||
&buf_pool.stat.n_pages_made_young, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_misc",
|
||||
&export_vars.innodb_buffer_pool_pages_misc, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_old",
|
||||
&export_vars.innodb_buffer_pool_pages_old, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_old", &buf_pool.LRU_old_len, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_total",
|
||||
&export_vars.innodb_buffer_pool_pages_total, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_LRU_flushed", &buf_lru_flush_page_count, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_LRU_freed", &buf_lru_freed_page_count, SHOW_SIZE_T},
|
||||
{"buffer_pool_pages_split", &buf_pool.pages_split, SHOW_SIZE_T},
|
||||
{"buffer_pool_read_ahead_rnd",
|
||||
&export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_SIZE_T},
|
||||
{"buffer_pool_read_ahead",
|
||||
&export_vars.innodb_buffer_pool_read_ahead, SHOW_SIZE_T},
|
||||
&buf_pool.stat.n_ra_pages_read_rnd, SHOW_SIZE_T},
|
||||
{"buffer_pool_read_ahead", &buf_pool.stat.n_ra_pages_read, SHOW_SIZE_T},
|
||||
{"buffer_pool_read_ahead_evicted",
|
||||
&export_vars.innodb_buffer_pool_read_ahead_evicted, SHOW_SIZE_T},
|
||||
{"buffer_pool_read_requests",
|
||||
&export_vars.innodb_buffer_pool_read_requests, SHOW_SIZE_T},
|
||||
{"buffer_pool_reads",
|
||||
&export_vars.innodb_buffer_pool_reads, SHOW_SIZE_T},
|
||||
&buf_pool.stat.n_ra_pages_evicted, SHOW_SIZE_T},
|
||||
{"buffer_pool_read_requests", &buf_pool.stat.n_page_gets, SHOW_SIZE_T},
|
||||
{"buffer_pool_reads", &buf_pool.stat.n_pages_read, SHOW_SIZE_T},
|
||||
{"buffer_pool_wait_free", &buf_pool.stat.LRU_waits, SHOW_SIZE_T},
|
||||
{"buffer_pool_write_requests", &buf_pool.flush_list_requests, SHOW_SIZE_T},
|
||||
{"checkpoint_age", &export_vars.innodb_checkpoint_age, SHOW_SIZE_T},
|
||||
|
@ -4424,6 +4418,25 @@ innobase_commit_ordered(
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/** Mark the end of a statement.
|
||||
@param trx transaction
|
||||
@return whether an error occurred */
|
||||
static bool end_of_statement(trx_t *trx)
|
||||
{
|
||||
trx_mark_sql_stat_end(trx);
|
||||
if (UNIV_LIKELY(trx->error_state == DB_SUCCESS))
|
||||
return false;
|
||||
|
||||
trx_savept_t savept;
|
||||
savept.least_undo_no= 0;
|
||||
trx->rollback(&savept);
|
||||
/* MariaDB will roll back the entire transaction. */
|
||||
trx->bulk_insert= false;
|
||||
trx->last_sql_stat_start.least_undo_no= 0;
|
||||
trx->savepoints_discard();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Commits a transaction in an InnoDB database or marks an SQL statement
|
||||
ended.
|
||||
|
@ -4500,10 +4513,7 @@ innobase_commit(
|
|||
/* Store the current undo_no of the transaction so that we
|
||||
know where to roll back if we have to roll back the next
|
||||
SQL statement */
|
||||
|
||||
trx_mark_sql_stat_end(trx);
|
||||
if (UNIV_UNLIKELY(trx->error_state != DB_SUCCESS)) {
|
||||
trx_rollback_for_mysql(trx);
|
||||
if (UNIV_UNLIKELY(end_of_statement(trx))) {
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
@ -15070,16 +15080,26 @@ ha_innobase::check(
|
|||
}
|
||||
|
||||
if ((check_opt->flags & T_QUICK) || index->is_corrupted()) {
|
||||
} else if (btr_validate_index(index, m_prebuilt->trx)
|
||||
!= DB_SUCCESS) {
|
||||
is_ok = false;
|
||||
push_warning_printf(thd,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NOT_KEYFILE,
|
||||
"InnoDB: The B-tree of"
|
||||
" index %s is corrupted.",
|
||||
index->name());
|
||||
continue;
|
||||
} else if (trx_id_t bulk_trx_id =
|
||||
m_prebuilt->table->bulk_trx_id) {
|
||||
if (!m_prebuilt->trx->read_view.changes_visible(
|
||||
bulk_trx_id)) {
|
||||
is_ok = true;
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (btr_validate_index(index, m_prebuilt->trx)
|
||||
!= DB_SUCCESS) {
|
||||
is_ok = false;
|
||||
push_warning_printf(
|
||||
thd,
|
||||
Sql_condition::WARN_LEVEL_WARN,
|
||||
ER_NOT_KEYFILE,
|
||||
"InnoDB: The B-tree of"
|
||||
" index %s is corrupted.",
|
||||
index->name());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Instead of invoking change_active_index(), set up
|
||||
|
@ -15202,6 +15222,7 @@ ha_innobase::check(
|
|||
}
|
||||
# endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
|
||||
#endif /* BTR_CUR_HASH_ADAPT */
|
||||
func_exit:
|
||||
m_prebuilt->trx->op_info = "";
|
||||
|
||||
DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
|
||||
|
@ -16867,10 +16888,7 @@ innobase_xa_prepare(
|
|||
/* Store the current undo_no of the transaction so that we
|
||||
know where to roll back if we have to roll back the next
|
||||
SQL statement */
|
||||
|
||||
trx_mark_sql_stat_end(trx);
|
||||
if (UNIV_UNLIKELY(trx->error_state != DB_SUCCESS)) {
|
||||
trx_rollback_for_mysql(trx);
|
||||
if (UNIV_UNLIKELY(end_of_statement(trx))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6119,6 +6119,7 @@ func_exit:
|
|||
id, MTR_MEMO_PAGE_SX_FIX);
|
||||
|
||||
if (UNIV_UNLIKELY(!root)) {
|
||||
err = DB_CORRUPTION;
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -6130,8 +6130,13 @@ static int i_s_sys_tablespaces_fill(THD *thd, const fil_space_t &s, TABLE *t)
|
|||
OK(f->store(name.data(), name.size(), system_charset_info));
|
||||
f->set_notnull();
|
||||
}
|
||||
else
|
||||
f->set_notnull();
|
||||
else if (srv_is_undo_tablespace(s.id))
|
||||
{
|
||||
char name[15];
|
||||
snprintf(name, sizeof name, "innodb_undo%03u",
|
||||
(s.id - srv_undo_space_id_start + 1));
|
||||
OK(f->store(name, strlen(name), system_charset_info));
|
||||
} else f->set_notnull();
|
||||
}
|
||||
|
||||
fields[SYS_TABLESPACES_NAME]->set_null();
|
||||
|
|
|
@ -441,7 +441,7 @@ Gets the root node of a tree and x- or s-latches it.
|
|||
buf_block_t*
|
||||
btr_root_block_get(
|
||||
/*===============*/
|
||||
const dict_index_t* index, /*!< in: index tree */
|
||||
dict_index_t* index, /*!< in: index tree */
|
||||
rw_lock_type_t mode, /*!< in: either RW_S_LATCH
|
||||
or RW_X_LATCH */
|
||||
mtr_t* mtr, /*!< in: mtr */
|
||||
|
|
|
@ -87,6 +87,9 @@ enum btr_latch_mode {
|
|||
dict_index_t::lock is being held in non-exclusive mode. */
|
||||
BTR_MODIFY_LEAF_ALREADY_LATCHED = BTR_MODIFY_LEAF
|
||||
| BTR_ALREADY_S_LATCHED,
|
||||
/** Attempt to modify records in an x-latched tree. */
|
||||
BTR_MODIFY_TREE_ALREADY_LATCHED = BTR_MODIFY_TREE
|
||||
| BTR_ALREADY_S_LATCHED,
|
||||
/** U-latch root and X-latch a leaf page, assuming that
|
||||
dict_index_t::lock is being held in U mode. */
|
||||
BTR_MODIFY_ROOT_AND_LEAF_ALREADY_LATCHED = BTR_MODIFY_ROOT_AND_LEAF
|
||||
|
|
|
@ -691,13 +691,14 @@ public:
|
|||
ut_ad(s < prev_state + UNFIXED);
|
||||
}
|
||||
|
||||
void read_unfix(uint32_t s)
|
||||
uint32_t read_unfix(uint32_t s)
|
||||
{
|
||||
ut_ad(lock.is_write_locked());
|
||||
ut_ad(s == UNFIXED + 1 || s == REINIT + 1);
|
||||
ut_d(auto old_state=) zip.fix.fetch_add(s - READ_FIX);
|
||||
uint32_t old_state= zip.fix.fetch_add(s - READ_FIX);
|
||||
ut_ad(old_state >= READ_FIX);
|
||||
ut_ad(old_state < WRITE_FIX);
|
||||
return old_state + (s - READ_FIX);
|
||||
}
|
||||
|
||||
void set_freed(uint32_t prev_state, uint32_t count= 0)
|
||||
|
@ -748,11 +749,11 @@ public:
|
|||
it from buf_pool.flush_list */
|
||||
inline void write_complete(bool temporary);
|
||||
|
||||
/** Write a flushable page to a file. buf_pool.mutex must be held.
|
||||
@param lru true=buf_pool.LRU; false=buf_pool.flush_list
|
||||
/** Write a flushable page to a file or free a freeable block.
|
||||
@param evict whether to evict the page on write completion
|
||||
@param space tablespace
|
||||
@return whether the page was flushed and buf_pool.mutex was released */
|
||||
inline bool flush(bool lru, fil_space_t *space);
|
||||
@return whether a page write was initiated and buf_pool.mutex released */
|
||||
bool flush(bool evict, fil_space_t *space);
|
||||
|
||||
/** Notify that a page in a temporary tablespace has been modified. */
|
||||
void set_temp_modified()
|
||||
|
@ -822,8 +823,6 @@ public:
|
|||
/** @return whether the block is mapped to a data file */
|
||||
bool in_file() const { return state() >= FREED; }
|
||||
|
||||
/** @return whether the block is modified and ready for flushing */
|
||||
inline bool ready_for_flush() const;
|
||||
/** @return whether the block can be relocated in memory.
|
||||
The block can be dirty, but it must not be I/O-fixed or bufferfixed. */
|
||||
inline bool can_relocate() const;
|
||||
|
@ -996,10 +995,10 @@ Compute the hash fold value for blocks in buf_pool.zip_hash. */
|
|||
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
|
||||
/* @} */
|
||||
|
||||
/** A "Hazard Pointer" class used to iterate over page lists
|
||||
inside the buffer pool. A hazard pointer is a buf_page_t pointer
|
||||
/** A "Hazard Pointer" class used to iterate over buf_pool.LRU or
|
||||
buf_pool.flush_list. A hazard pointer is a buf_page_t pointer
|
||||
which we intend to iterate over next and we want it remain valid
|
||||
even after we release the buffer pool mutex. */
|
||||
even after we release the mutex that protects the list. */
|
||||
class HazardPointer
|
||||
{
|
||||
public:
|
||||
|
@ -1114,7 +1113,8 @@ struct buf_buddy_free_t {
|
|||
/*!< Node of zip_free list */
|
||||
};
|
||||
|
||||
/** @brief The buffer pool statistics structure. */
|
||||
/** @brief The buffer pool statistics structure;
|
||||
protected by buf_pool.mutex unless otherwise noted. */
|
||||
struct buf_pool_stat_t{
|
||||
/** Initialize the counters */
|
||||
void init() { memset((void*) this, 0, sizeof *this); }
|
||||
|
@ -1123,9 +1123,8 @@ struct buf_pool_stat_t{
|
|||
/*!< number of page gets performed;
|
||||
also successful searches through
|
||||
the adaptive hash index are
|
||||
counted as page gets; this field
|
||||
is NOT protected by the buffer
|
||||
pool mutex */
|
||||
counted as page gets;
|
||||
NOT protected by buf_pool.mutex */
|
||||
ulint n_pages_read; /*!< number read operations */
|
||||
ulint n_pages_written;/*!< number write operations */
|
||||
ulint n_pages_created;/*!< number of pages created
|
||||
|
@ -1143,10 +1142,9 @@ struct buf_pool_stat_t{
|
|||
young because the first access
|
||||
was not long enough ago, in
|
||||
buf_page_peek_if_too_old() */
|
||||
/** number of waits for eviction; writes protected by buf_pool.mutex */
|
||||
/** number of waits for eviction */
|
||||
ulint LRU_waits;
|
||||
ulint LRU_bytes; /*!< LRU size in bytes */
|
||||
ulint flush_list_bytes;/*!< flush_list size in bytes */
|
||||
};
|
||||
|
||||
/** Statistics of buddy blocks of a given size. */
|
||||
|
@ -1399,6 +1397,11 @@ public:
|
|||
n_chunks_new / 4 * chunks->size;
|
||||
}
|
||||
|
||||
/** @return whether the buffer pool has run out */
|
||||
TPOOL_SUPPRESS_TSAN
|
||||
bool ran_out() const
|
||||
{ return UNIV_UNLIKELY(!try_LRU_scan || !UT_LIST_GET_LEN(free)); }
|
||||
|
||||
/** @return whether the buffer pool is shrinking */
|
||||
inline bool is_shrinking() const
|
||||
{
|
||||
|
@ -1436,17 +1439,10 @@ public:
|
|||
|
||||
/** Buffer pool mutex */
|
||||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t mutex;
|
||||
/** Number of pending LRU flush; protected by mutex. */
|
||||
ulint n_flush_LRU_;
|
||||
/** broadcast when n_flush_LRU reaches 0; protected by mutex */
|
||||
pthread_cond_t done_flush_LRU;
|
||||
/** Number of pending flush_list flush; protected by mutex */
|
||||
ulint n_flush_list_;
|
||||
/** broadcast when n_flush_list reaches 0; protected by mutex */
|
||||
pthread_cond_t done_flush_list;
|
||||
|
||||
TPOOL_SUPPRESS_TSAN ulint n_flush_LRU() const { return n_flush_LRU_; }
|
||||
TPOOL_SUPPRESS_TSAN ulint n_flush_list() const { return n_flush_list_; }
|
||||
/** current statistics; protected by mutex */
|
||||
buf_pool_stat_t stat;
|
||||
/** old statistics; protected by mutex */
|
||||
buf_pool_stat_t old_stat;
|
||||
|
||||
/** @name General fields */
|
||||
/* @{ */
|
||||
|
@ -1607,11 +1603,12 @@ public:
|
|||
buf_buddy_stat_t buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
|
||||
/*!< Statistics of buddy system,
|
||||
indexed by block size */
|
||||
buf_pool_stat_t stat; /*!< current statistics */
|
||||
buf_pool_stat_t old_stat; /*!< old statistics */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** number of index page splits */
|
||||
Atomic_counter<ulint> pages_split;
|
||||
|
||||
/** @name Page flushing algorithm fields */
|
||||
/* @{ */
|
||||
|
||||
|
@ -1620,7 +1617,10 @@ public:
|
|||
alignas(CPU_LEVEL1_DCACHE_LINESIZE) mysql_mutex_t flush_list_mutex;
|
||||
/** "hazard pointer" for flush_list scans; protected by flush_list_mutex */
|
||||
FlushHp flush_hp;
|
||||
/** modified blocks (a subset of LRU) */
|
||||
/** flush_list size in bytes; protected by flush_list_mutex */
|
||||
ulint flush_list_bytes;
|
||||
/** possibly modified persistent pages (a subset of LRU);
|
||||
buf_dblwr.pending_writes() is approximately COUNT(is_write_fixed()) */
|
||||
UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
|
||||
/** number of blocks ever added to flush_list;
|
||||
sometimes protected by flush_list_mutex */
|
||||
|
@ -1629,28 +1629,70 @@ public:
|
|||
TPOOL_SUPPRESS_TSAN void add_flush_list_requests(size_t size)
|
||||
{ ut_ad(size); flush_list_requests+= size; }
|
||||
private:
|
||||
/** whether the page cleaner needs wakeup from indefinite sleep */
|
||||
bool page_cleaner_is_idle;
|
||||
static constexpr unsigned PAGE_CLEANER_IDLE= 1;
|
||||
static constexpr unsigned FLUSH_LIST_ACTIVE= 2;
|
||||
static constexpr unsigned LRU_FLUSH= 4;
|
||||
|
||||
/** Number of pending LRU flush * LRU_FLUSH +
|
||||
PAGE_CLEANER_IDLE + FLUSH_LIST_ACTIVE flags */
|
||||
unsigned page_cleaner_status;
|
||||
/** track server activity count for signaling idle flushing */
|
||||
ulint last_activity_count;
|
||||
public:
|
||||
/** signalled to wake up the page_cleaner; protected by flush_list_mutex */
|
||||
pthread_cond_t do_flush_list;
|
||||
/** broadcast when !n_flush(); protected by flush_list_mutex */
|
||||
pthread_cond_t done_flush_LRU;
|
||||
/** broadcast when a batch completes; protected by flush_list_mutex */
|
||||
pthread_cond_t done_flush_list;
|
||||
|
||||
/** @return number of pending LRU flush */
|
||||
unsigned n_flush() const
|
||||
{
|
||||
mysql_mutex_assert_owner(&flush_list_mutex);
|
||||
return page_cleaner_status / LRU_FLUSH;
|
||||
}
|
||||
|
||||
/** Increment the number of pending LRU flush */
|
||||
inline void n_flush_inc();
|
||||
|
||||
/** Decrement the number of pending LRU flush */
|
||||
inline void n_flush_dec();
|
||||
|
||||
/** @return whether flush_list flushing is active */
|
||||
bool flush_list_active() const
|
||||
{
|
||||
mysql_mutex_assert_owner(&flush_list_mutex);
|
||||
return page_cleaner_status & FLUSH_LIST_ACTIVE;
|
||||
}
|
||||
|
||||
void flush_list_set_active()
|
||||
{
|
||||
ut_ad(!flush_list_active());
|
||||
page_cleaner_status+= FLUSH_LIST_ACTIVE;
|
||||
}
|
||||
void flush_list_set_inactive()
|
||||
{
|
||||
ut_ad(flush_list_active());
|
||||
page_cleaner_status-= FLUSH_LIST_ACTIVE;
|
||||
}
|
||||
|
||||
/** @return whether the page cleaner must sleep due to being idle */
|
||||
bool page_cleaner_idle() const noexcept
|
||||
{
|
||||
mysql_mutex_assert_owner(&flush_list_mutex);
|
||||
return page_cleaner_is_idle;
|
||||
return page_cleaner_status & PAGE_CLEANER_IDLE;
|
||||
}
|
||||
/** Wake up the page cleaner if needed */
|
||||
void page_cleaner_wakeup();
|
||||
/** Wake up the page cleaner if needed.
|
||||
@param for_LRU whether to wake up for LRU eviction */
|
||||
void page_cleaner_wakeup(bool for_LRU= false);
|
||||
|
||||
/** Register whether an explicit wakeup of the page cleaner is needed */
|
||||
void page_cleaner_set_idle(bool deep_sleep)
|
||||
{
|
||||
mysql_mutex_assert_owner(&flush_list_mutex);
|
||||
page_cleaner_is_idle= deep_sleep;
|
||||
page_cleaner_status= (page_cleaner_status & ~PAGE_CLEANER_IDLE) |
|
||||
(PAGE_CLEANER_IDLE * deep_sleep);
|
||||
}
|
||||
|
||||
/** Update server last activity count */
|
||||
|
@ -1660,9 +1702,6 @@ public:
|
|||
last_activity_count= activity_count;
|
||||
}
|
||||
|
||||
// n_flush_LRU() + n_flush_list()
|
||||
// is approximately COUNT(is_write_fixed()) in flush_list
|
||||
|
||||
unsigned freed_page_clock;/*!< a sequence number used
|
||||
to count the number of buffer
|
||||
blocks removed from the end of
|
||||
|
@ -1672,16 +1711,10 @@ public:
|
|||
to read this for heuristic
|
||||
purposes without holding any
|
||||
mutex or latch */
|
||||
bool try_LRU_scan; /*!< Cleared when an LRU
|
||||
scan for free block fails. This
|
||||
flag is used to avoid repeated
|
||||
scans of LRU list when we know
|
||||
that there is no free block
|
||||
available in the scan depth for
|
||||
eviction. Set whenever
|
||||
we flush a batch from the
|
||||
buffer pool. Protected by the
|
||||
buf_pool.mutex */
|
||||
/** Cleared when buf_LRU_get_free_block() fails.
|
||||
Set whenever the free list grows, along with a broadcast of done_free.
|
||||
Protected by buf_pool.mutex. */
|
||||
Atomic_relaxed<bool> try_LRU_scan;
|
||||
/* @} */
|
||||
|
||||
/** @name LRU replacement algorithm fields */
|
||||
|
@ -1690,7 +1723,8 @@ public:
|
|||
UT_LIST_BASE_NODE_T(buf_page_t) free;
|
||||
/*!< base node of the free
|
||||
block list */
|
||||
/** signaled each time when the free list grows; protected by mutex */
|
||||
/** broadcast each time when the free list grows or try_LRU_scan is set;
|
||||
protected by mutex */
|
||||
pthread_cond_t done_free;
|
||||
|
||||
UT_LIST_BASE_NODE_T(buf_page_t) withdraw;
|
||||
|
@ -1747,29 +1781,16 @@ public:
|
|||
{
|
||||
if (n_pend_reads)
|
||||
return true;
|
||||
mysql_mutex_lock(&mutex);
|
||||
const bool any_pending{n_flush_LRU_ || n_flush_list_};
|
||||
mysql_mutex_unlock(&mutex);
|
||||
mysql_mutex_lock(&flush_list_mutex);
|
||||
const bool any_pending= page_cleaner_status > PAGE_CLEANER_IDLE ||
|
||||
buf_dblwr.pending_writes();
|
||||
mysql_mutex_unlock(&flush_list_mutex);
|
||||
return any_pending;
|
||||
}
|
||||
/** @return total amount of pending I/O */
|
||||
ulint io_pending() const
|
||||
{
|
||||
return n_pend_reads + n_flush_LRU() + n_flush_list();
|
||||
}
|
||||
|
||||
private:
|
||||
/** Remove a block from the flush list. */
|
||||
inline void delete_from_flush_list_low(buf_page_t *bpage) noexcept;
|
||||
/** Remove a block from flush_list.
|
||||
@param bpage buffer pool page
|
||||
@param clear whether to invoke buf_page_t::clear_oldest_modification() */
|
||||
void delete_from_flush_list(buf_page_t *bpage, bool clear) noexcept;
|
||||
public:
|
||||
/** Remove a block from flush_list.
|
||||
@param bpage buffer pool page */
|
||||
void delete_from_flush_list(buf_page_t *bpage) noexcept
|
||||
{ delete_from_flush_list(bpage, true); }
|
||||
void delete_from_flush_list(buf_page_t *bpage) noexcept;
|
||||
|
||||
/** Prepare to insert a modified blcok into flush_list.
|
||||
@param lsn start LSN of the mini-transaction
|
||||
|
@ -1784,7 +1805,7 @@ public:
|
|||
lsn_t lsn) noexcept;
|
||||
|
||||
/** Free a page whose underlying file page has been freed. */
|
||||
inline void release_freed_page(buf_page_t *bpage) noexcept;
|
||||
ATTRIBUTE_COLD void release_freed_page(buf_page_t *bpage) noexcept;
|
||||
|
||||
private:
|
||||
/** Temporary memory for page_compressed and encrypted I/O */
|
||||
|
@ -1795,34 +1816,12 @@ private:
|
|||
/** array of slots */
|
||||
buf_tmp_buffer_t *slots;
|
||||
|
||||
void create(ulint n_slots)
|
||||
{
|
||||
this->n_slots= n_slots;
|
||||
slots= static_cast<buf_tmp_buffer_t*>
|
||||
(ut_malloc_nokey(n_slots * sizeof *slots));
|
||||
memset((void*) slots, 0, n_slots * sizeof *slots);
|
||||
}
|
||||
void create(ulint n_slots);
|
||||
|
||||
void close()
|
||||
{
|
||||
for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++)
|
||||
{
|
||||
aligned_free(s->crypt_buf);
|
||||
aligned_free(s->comp_buf);
|
||||
}
|
||||
ut_free(slots);
|
||||
slots= nullptr;
|
||||
n_slots= 0;
|
||||
}
|
||||
void close();
|
||||
|
||||
/** Reserve a buffer */
|
||||
buf_tmp_buffer_t *reserve()
|
||||
{
|
||||
for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++)
|
||||
if (s->acquire())
|
||||
return s;
|
||||
return nullptr;
|
||||
}
|
||||
buf_tmp_buffer_t *reserve();
|
||||
} io_buf;
|
||||
|
||||
/** whether resize() is in the critical path */
|
||||
|
@ -1911,7 +1910,10 @@ inline void buf_page_t::set_oldest_modification(lsn_t lsn)
|
|||
/** Clear oldest_modification after removing from buf_pool.flush_list */
|
||||
inline void buf_page_t::clear_oldest_modification()
|
||||
{
|
||||
mysql_mutex_assert_owner(&buf_pool.flush_list_mutex);
|
||||
#ifdef SAFE_MUTEX
|
||||
if (oldest_modification() != 2)
|
||||
mysql_mutex_assert_owner(&buf_pool.flush_list_mutex);
|
||||
#endif /* SAFE_MUTEX */
|
||||
ut_d(const auto s= state());
|
||||
ut_ad(s >= REMOVE_HASH);
|
||||
ut_ad(oldest_modification());
|
||||
|
@ -1923,17 +1925,6 @@ inline void buf_page_t::clear_oldest_modification()
|
|||
oldest_modification_.store(0, std::memory_order_release);
|
||||
}
|
||||
|
||||
/** @return whether the block is modified and ready for flushing */
|
||||
inline bool buf_page_t::ready_for_flush() const
|
||||
{
|
||||
mysql_mutex_assert_owner(&buf_pool.mutex);
|
||||
ut_ad(in_LRU_list);
|
||||
const auto s= state();
|
||||
ut_a(s >= FREED);
|
||||
ut_ad(!fsp_is_system_temporary(id().space()) || oldest_modification() == 2);
|
||||
return s < READ_FIX;
|
||||
}
|
||||
|
||||
/** @return whether the block can be relocated in memory.
|
||||
The block can be dirty, but it must not be I/O-fixed or bufferfixed. */
|
||||
inline bool buf_page_t::can_relocate() const
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2022, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -54,9 +54,9 @@ class buf_dblwr_t
|
|||
};
|
||||
|
||||
/** the page number of the first doublewrite block (block_size() pages) */
|
||||
page_id_t block1= page_id_t(0, 0);
|
||||
page_id_t block1{0, 0};
|
||||
/** the page number of the second doublewrite block (block_size() pages) */
|
||||
page_id_t block2= page_id_t(0, 0);
|
||||
page_id_t block2{0, 0};
|
||||
|
||||
/** mutex protecting the data members below */
|
||||
mysql_mutex_t mutex;
|
||||
|
@ -72,11 +72,15 @@ class buf_dblwr_t
|
|||
ulint writes_completed;
|
||||
/** number of pages written by flush_buffered_writes_completed() */
|
||||
ulint pages_written;
|
||||
/** condition variable for !writes_pending */
|
||||
pthread_cond_t write_cond;
|
||||
/** number of pending page writes */
|
||||
size_t writes_pending;
|
||||
|
||||
slot slots[2];
|
||||
slot *active_slot= &slots[0];
|
||||
slot *active_slot;
|
||||
|
||||
/** Initialize the doublewrite buffer data structure.
|
||||
/** Initialise the persistent storage of the doublewrite buffer.
|
||||
@param header doublewrite page header in the TRX_SYS page */
|
||||
inline void init(const byte *header);
|
||||
|
||||
|
@ -84,6 +88,8 @@ class buf_dblwr_t
|
|||
bool flush_buffered_writes(const ulint size);
|
||||
|
||||
public:
|
||||
/** Initialise the doublewrite buffer data structures. */
|
||||
void init();
|
||||
/** Create or restore the doublewrite buffer in the TRX_SYS page.
|
||||
@return whether the operation succeeded */
|
||||
bool create();
|
||||
|
@ -118,7 +124,7 @@ public:
|
|||
void recover();
|
||||
|
||||
/** Update the doublewrite buffer on data page write completion. */
|
||||
void write_completed();
|
||||
void write_completed(bool with_doublewrite);
|
||||
/** Flush possible buffered writes to persistent storage.
|
||||
It is very important to call this function after a batch of writes has been
|
||||
posted, and also when we may have to wait for a page latch!
|
||||
|
@ -137,14 +143,14 @@ public:
|
|||
@param size payload size in bytes */
|
||||
void add_to_batch(const IORequest &request, size_t size);
|
||||
|
||||
/** Determine whether the doublewrite buffer is initialized */
|
||||
bool is_initialised() const
|
||||
/** Determine whether the doublewrite buffer has been created */
|
||||
bool is_created() const
|
||||
{ return UNIV_LIKELY(block1 != page_id_t(0, 0)); }
|
||||
|
||||
/** @return whether a page identifier is part of the doublewrite buffer */
|
||||
bool is_inside(const page_id_t id) const
|
||||
{
|
||||
if (!is_initialised())
|
||||
if (!is_created())
|
||||
return false;
|
||||
ut_ad(block1 < block2);
|
||||
if (id < block1)
|
||||
|
@ -156,13 +162,44 @@ public:
|
|||
/** Wait for flush_buffered_writes() to be fully completed */
|
||||
void wait_flush_buffered_writes()
|
||||
{
|
||||
if (is_initialised())
|
||||
{
|
||||
mysql_mutex_lock(&mutex);
|
||||
while (batch_running)
|
||||
my_cond_wait(&cond, &mutex.m_mutex);
|
||||
mysql_mutex_unlock(&mutex);
|
||||
}
|
||||
mysql_mutex_lock(&mutex);
|
||||
while (batch_running)
|
||||
my_cond_wait(&cond, &mutex.m_mutex);
|
||||
mysql_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
/** Register an unbuffered page write */
|
||||
void add_unbuffered()
|
||||
{
|
||||
mysql_mutex_lock(&mutex);
|
||||
writes_pending++;
|
||||
mysql_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
size_t pending_writes()
|
||||
{
|
||||
mysql_mutex_lock(&mutex);
|
||||
const size_t pending{writes_pending};
|
||||
mysql_mutex_unlock(&mutex);
|
||||
return pending;
|
||||
}
|
||||
|
||||
/** Wait for writes_pending to reach 0 */
|
||||
void wait_for_page_writes()
|
||||
{
|
||||
mysql_mutex_lock(&mutex);
|
||||
while (writes_pending)
|
||||
my_cond_wait(&write_cond, &mutex.m_mutex);
|
||||
mysql_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
/** Wait for writes_pending to reach 0 */
|
||||
void wait_for_page_writes(const timespec &abstime)
|
||||
{
|
||||
mysql_mutex_lock(&mutex);
|
||||
while (writes_pending)
|
||||
my_cond_timedwait(&write_cond, &mutex.m_mutex, &abstime);
|
||||
mysql_mutex_unlock(&mutex);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -30,10 +30,8 @@ Created 11/5/1995 Heikki Tuuri
|
|||
#include "log0log.h"
|
||||
#include "buf0buf.h"
|
||||
|
||||
/** Number of pages flushed. Protected by buf_pool.mutex. */
|
||||
extern ulint buf_flush_page_count;
|
||||
/** Number of pages flushed via LRU. Protected by buf_pool.mutex.
|
||||
Also included in buf_flush_page_count. */
|
||||
Also included in buf_pool.stat.n_pages_written. */
|
||||
extern ulint buf_lru_flush_page_count;
|
||||
/** Number of pages freed without flushing. Protected by buf_pool.mutex. */
|
||||
extern ulint buf_lru_freed_page_count;
|
||||
|
@ -86,15 +84,18 @@ buf_flush_init_for_writing(
|
|||
bool buf_flush_list_space(fil_space_t *space, ulint *n_flushed= nullptr)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Write out dirty blocks from buf_pool.LRU.
|
||||
/** Write out dirty blocks from buf_pool.LRU,
|
||||
and move clean blocks to buf_pool.free.
|
||||
The caller must invoke buf_dblwr.flush_buffered_writes()
|
||||
after releasing buf_pool.mutex.
|
||||
@param max_n wished maximum mumber of blocks flushed
|
||||
@return the number of processed pages
|
||||
@param evict whether to evict pages after flushing
|
||||
@return evict ? number of processed pages : number of pages written
|
||||
@retval 0 if a buf_pool.LRU batch is already running */
|
||||
ulint buf_flush_LRU(ulint max_n);
|
||||
ulint buf_flush_LRU(ulint max_n, bool evict);
|
||||
|
||||
/** Wait until a flush batch ends.
|
||||
@param lru true=buf_pool.LRU; false=buf_pool.flush_list */
|
||||
void buf_flush_wait_batch_end(bool lru);
|
||||
/** Wait until a LRU flush batch ends. */
|
||||
void buf_flush_wait_LRU_batch_end();
|
||||
/** Wait until all persistent pages are flushed up to a limit.
|
||||
@param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */
|
||||
ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn);
|
||||
|
@ -106,9 +107,6 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious);
|
|||
/** Initialize page_cleaner. */
|
||||
ATTRIBUTE_COLD void buf_flush_page_cleaner_init();
|
||||
|
||||
/** Wait for pending flushes to complete. */
|
||||
void buf_flush_wait_batch_end_acquiring_mutex(bool lru);
|
||||
|
||||
/** Flush the buffer pool on shutdown. */
|
||||
ATTRIBUTE_COLD void buf_flush_buffer_pool();
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ released by the i/o-handler thread.
|
|||
@param zip_size ROW_FORMAT=COMPRESSED page size, or 0
|
||||
@param chain buf_pool.page_hash cell for page_id
|
||||
@retval DB_SUCCESS if the page was read and is not corrupted,
|
||||
@retval DB_SUCCESS_LOCKED_REC if the page was not read
|
||||
@retval DB_PAGE_CORRUPTED if page based on checksum check is corrupted,
|
||||
@retval DB_DECRYPTION_FAILED if page post encryption checksum matches but
|
||||
after decryption normal page checksum does not match.
|
||||
|
|
|
@ -871,11 +871,13 @@ public:
|
|||
@param purpose tablespace purpose
|
||||
@param crypt_data encryption information
|
||||
@param mode encryption mode
|
||||
@param opened true if space files are opened
|
||||
@return pointer to created tablespace, to be filled in with add()
|
||||
@retval nullptr on failure (such as when the same tablespace exists) */
|
||||
static fil_space_t *create(uint32_t id, uint32_t flags,
|
||||
fil_type_t purpose, fil_space_crypt_t *crypt_data,
|
||||
fil_encryption_t mode= FIL_ENCRYPTION_DEFAULT);
|
||||
fil_encryption_t mode= FIL_ENCRYPTION_DEFAULT,
|
||||
bool opened= false);
|
||||
|
||||
MY_ATTRIBUTE((warn_unused_result))
|
||||
/** Acquire a tablespace reference.
|
||||
|
@ -1080,7 +1082,7 @@ private:
|
|||
inline bool fil_space_t::use_doublewrite() const
|
||||
{
|
||||
return !UT_LIST_GET_FIRST(chain)->atomic_write && srv_use_doublewrite_buf &&
|
||||
buf_dblwr.is_initialised();
|
||||
buf_dblwr.is_created();
|
||||
}
|
||||
|
||||
inline void fil_space_t::set_imported()
|
||||
|
@ -1357,6 +1359,11 @@ struct fil_system_t
|
|||
|
||||
private:
|
||||
bool m_initialised;
|
||||
|
||||
/** Points to the last opened space in space_list. Protected with
|
||||
fil_system.mutex. */
|
||||
fil_space_t *space_list_last_opened= nullptr;
|
||||
|
||||
#ifdef __linux__
|
||||
/** available block devices that reside on non-rotational storage */
|
||||
std::vector<dev_t> ssd;
|
||||
|
@ -1412,7 +1419,8 @@ public:
|
|||
/** nonzero if fil_node_open_file_low() should avoid moving the tablespace
|
||||
to the end of space_list, for FIFO policy of try_to_close() */
|
||||
ulint freeze_space_list;
|
||||
/** list of all tablespaces */
|
||||
/** List of all file spaces, opened spaces should be at the top of the list
|
||||
to optimize try_to_close() execution. Protected with fil_system.mutex. */
|
||||
ilist<fil_space_t, space_list_tag_t> space_list;
|
||||
/** list of all tablespaces for which a FILE_MODIFY record has been written
|
||||
since the latest redo log checkpoint.
|
||||
|
@ -1427,6 +1435,49 @@ public:
|
|||
potential space_id reuse */
|
||||
bool space_id_reuse_warned;
|
||||
|
||||
/** Add the file to the end of opened spaces list in
|
||||
fil_system.space_list, so that fil_space_t::try_to_close() should close
|
||||
it as a last resort.
|
||||
@param space space to add */
|
||||
void add_opened_last_to_space_list(fil_space_t *space);
|
||||
|
||||
/** Move the file to the end of opened spaces list in
|
||||
fil_system.space_list, so that fil_space_t::try_to_close() should close
|
||||
it as a last resort.
|
||||
@param space space to move */
|
||||
inline void move_opened_last_to_space_list(fil_space_t *space)
|
||||
{
|
||||
/* In the case when several files of the same space are added in a
|
||||
row, there is no need to remove and add a space to the same position
|
||||
in space_list. It can be for system or temporary tablespaces. */
|
||||
if (freeze_space_list || space_list_last_opened == space)
|
||||
return;
|
||||
|
||||
space_list.erase(space_list_t::iterator(space));
|
||||
add_opened_last_to_space_list(space);
|
||||
}
|
||||
|
||||
/** Move closed file last in fil_system.space_list, so that
|
||||
fil_space_t::try_to_close() iterates opened files first in FIFO order,
|
||||
i.e. first opened, first closed.
|
||||
@param space space to move */
|
||||
void move_closed_last_to_space_list(fil_space_t *space)
|
||||
{
|
||||
if (UNIV_UNLIKELY(freeze_space_list))
|
||||
return;
|
||||
|
||||
space_list_t::iterator s= space_list_t::iterator(space);
|
||||
|
||||
if (space_list_last_opened == space)
|
||||
{
|
||||
space_list_t::iterator prev= s;
|
||||
space_list_last_opened= &*--prev;
|
||||
}
|
||||
|
||||
space_list.erase(s);
|
||||
space_list.push_back(*space);
|
||||
}
|
||||
|
||||
/** Return the next tablespace from default_encrypt_tables list.
|
||||
@param space previous tablespace (nullptr to start from the start)
|
||||
@param recheck whether the removal condition needs to be rechecked after
|
||||
|
|
|
@ -333,6 +333,9 @@ public:
|
|||
/** Upgrade U locks on a block to X */
|
||||
void page_lock_upgrade(const buf_block_t &block);
|
||||
|
||||
/** Upgrade index U lock to X */
|
||||
ATTRIBUTE_COLD void index_lock_upgrade();
|
||||
|
||||
/** Check if we are holding tablespace latch
|
||||
@param space tablespace to search for
|
||||
@return whether space.latch is being held */
|
||||
|
|
|
@ -85,11 +85,6 @@ struct srv_stats_t
|
|||
|
||||
/** Count the amount of data written in total (in bytes) */
|
||||
ulint_ctr_1_t data_written;
|
||||
|
||||
/** Number of buffer pool reads that led to the reading of
|
||||
a disk page */
|
||||
ulint_ctr_1_t buf_pool_reads;
|
||||
|
||||
/** Number of bytes saved by page compression */
|
||||
ulint_ctr_n_t page_compression_saved;
|
||||
/* Number of pages compressed with page compression */
|
||||
|
@ -597,23 +592,11 @@ struct export_var_t{
|
|||
char innodb_buffer_pool_resize_status[512];/*!< Buf pool resize status */
|
||||
my_bool innodb_buffer_pool_load_incomplete;/*!< Buf pool load incomplete */
|
||||
ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
|
||||
ulint innodb_buffer_pool_pages_data; /*!< Data pages */
|
||||
ulint innodb_buffer_pool_bytes_data; /*!< File bytes used */
|
||||
ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
|
||||
ulint innodb_buffer_pool_bytes_dirty; /*!< File bytes modified */
|
||||
ulint innodb_buffer_pool_pages_misc; /*!< Miscellanous pages */
|
||||
ulint innodb_buffer_pool_pages_free; /*!< Free pages */
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint innodb_buffer_pool_pages_latched; /*!< Latched pages */
|
||||
#endif /* UNIV_DEBUG */
|
||||
ulint innodb_buffer_pool_pages_made_not_young;
|
||||
ulint innodb_buffer_pool_pages_made_young;
|
||||
ulint innodb_buffer_pool_pages_old;
|
||||
ulint innodb_buffer_pool_read_requests; /*!< buf_pool.stat.n_page_gets */
|
||||
ulint innodb_buffer_pool_reads; /*!< srv_buf_pool_reads */
|
||||
ulint innodb_buffer_pool_read_ahead_rnd;/*!< srv_read_ahead_rnd */
|
||||
ulint innodb_buffer_pool_read_ahead; /*!< srv_read_ahead */
|
||||
ulint innodb_buffer_pool_read_ahead_evicted;/*!< srv_read_ahead evicted*/
|
||||
ulint innodb_checkpoint_age;
|
||||
ulint innodb_checkpoint_max_age;
|
||||
ulint innodb_data_pending_reads; /*!< Pending reads */
|
||||
|
|
|
@ -925,14 +925,19 @@ public:
|
|||
/**
|
||||
Determine if the specified transaction or any older one might be active.
|
||||
|
||||
@param caller_trx used to get/set pins
|
||||
@param trx current transaction
|
||||
@param id transaction identifier
|
||||
@return whether any transaction not newer than id might be active
|
||||
*/
|
||||
|
||||
bool find_same_or_older(trx_t *caller_trx, trx_id_t id)
|
||||
bool find_same_or_older(trx_t *trx, trx_id_t id)
|
||||
{
|
||||
return rw_trx_hash.iterate(caller_trx, find_same_or_older_callback, &id);
|
||||
if (trx->max_inactive_id >= id)
|
||||
return false;
|
||||
bool found= rw_trx_hash.iterate(trx, find_same_or_older_callback, &id);
|
||||
if (!found)
|
||||
trx->max_inactive_id= id;
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -642,6 +642,10 @@ public:
|
|||
Cleared in commit_in_memory() after commit_state(),
|
||||
trx_sys_t::deregister_rw(), release_locks(). */
|
||||
trx_id_t id;
|
||||
/** The largest encountered transaction identifier for which no
|
||||
transaction was observed to be active. This is a cache to speed up
|
||||
trx_sys_t::find_same_or_older(). */
|
||||
trx_id_t max_inactive_id;
|
||||
|
||||
private:
|
||||
/** mutex protecting state and some of lock
|
||||
|
|
|
@ -1064,13 +1064,16 @@ lock_sec_rec_some_has_impl(
|
|||
|
||||
const trx_id_t max_trx_id= page_get_max_trx_id(page_align(rec));
|
||||
|
||||
if ((caller_trx->id > max_trx_id &&
|
||||
!trx_sys.find_same_or_older(caller_trx, max_trx_id)) ||
|
||||
/* Note: It is possible to have caller_trx->id == 0 in a locking read
|
||||
if caller_trx has not modified any persistent tables. */
|
||||
if (!trx_sys.find_same_or_older(caller_trx, max_trx_id) ||
|
||||
!lock_check_trx_id_sanity(max_trx_id, rec, index, offsets))
|
||||
return nullptr;
|
||||
|
||||
/* In this case it is possible that some transaction has an implicit
|
||||
x-lock. We have to look in the clustered index. */
|
||||
/* We checked above that some active (or XA PREPARE) transaction exists
|
||||
that is older than PAGE_MAX_TRX_ID. That is, some transaction may be
|
||||
holding an implicit lock on the record. We have to look up the
|
||||
clustered index record to find if it is (or was) the case. */
|
||||
return row_vers_impl_x_locked(caller_trx, rec, index, offsets);
|
||||
}
|
||||
|
||||
|
@ -5157,20 +5160,24 @@ has an implicit lock on the record. The transaction instance must have a
|
|||
reference count > 0 so that it can't be committed and freed before this
|
||||
function has completed. */
|
||||
static
|
||||
void
|
||||
bool
|
||||
lock_rec_convert_impl_to_expl_for_trx(
|
||||
/*==================================*/
|
||||
trx_t* trx, /*!< in/out: active transaction */
|
||||
const page_id_t id, /*!< in: page identifier */
|
||||
const rec_t* rec, /*!< in: user record on page */
|
||||
dict_index_t* index, /*!< in: index of record */
|
||||
trx_t* trx, /*!< in/out: active transaction */
|
||||
ulint heap_no)/*!< in: rec heap number to lock */
|
||||
dict_index_t* index) /*!< in: index of record */
|
||||
{
|
||||
if (!trx)
|
||||
return false;
|
||||
|
||||
ut_ad(trx->is_referenced());
|
||||
ut_ad(page_rec_is_leaf(rec));
|
||||
ut_ad(!rec_is_metadata(rec, *index));
|
||||
|
||||
DEBUG_SYNC_C("before_lock_rec_convert_impl_to_expl_for_trx");
|
||||
ulint heap_no= page_rec_get_heap_no(rec);
|
||||
|
||||
{
|
||||
LockGuard g{lock_sys.rec_hash, id};
|
||||
trx->mutex_lock();
|
||||
|
@ -5187,6 +5194,7 @@ lock_rec_convert_impl_to_expl_for_trx(
|
|||
trx->release_reference();
|
||||
|
||||
DEBUG_SYNC_C("after_lock_rec_convert_impl_to_expl_for_trx");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5260,7 +5268,6 @@ static void lock_rec_other_trx_holds_expl(trx_t *caller_trx, trx_t *trx,
|
|||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
|
||||
/** If an implicit x-lock exists on a record, convert it to an explicit one.
|
||||
|
||||
Often, this is called by a transaction that is about to enter a lock wait
|
||||
|
@ -5272,12 +5279,14 @@ This may also be called by the same transaction that is already holding
|
|||
an implicit exclusive lock on the record. In this case, no explicit lock
|
||||
should be created.
|
||||
|
||||
@tparam is_primary whether the index is the primary key
|
||||
@param[in,out] caller_trx current transaction
|
||||
@param[in] id index tree leaf page identifier
|
||||
@param[in] rec record on the leaf page
|
||||
@param[in] index the index of the record
|
||||
@param[in] offsets rec_get_offsets(rec,index)
|
||||
@return whether caller_trx already holds an exclusive lock on rec */
|
||||
template<bool is_primary>
|
||||
static
|
||||
bool
|
||||
lock_rec_convert_impl_to_expl(
|
||||
|
@ -5295,8 +5304,9 @@ lock_rec_convert_impl_to_expl(
|
|||
ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
|
||||
ut_ad(page_rec_is_leaf(rec));
|
||||
ut_ad(!rec_is_metadata(rec, *index));
|
||||
ut_ad(index->is_primary() == is_primary);
|
||||
|
||||
if (dict_index_is_clust(index)) {
|
||||
if (is_primary) {
|
||||
trx_id_t trx_id;
|
||||
|
||||
trx_id = lock_clust_rec_some_has_impl(rec, index, offsets);
|
||||
|
@ -5322,20 +5332,7 @@ lock_rec_convert_impl_to_expl(
|
|||
ut_d(lock_rec_other_trx_holds_expl(caller_trx, trx, rec, id));
|
||||
}
|
||||
|
||||
if (trx) {
|
||||
ulint heap_no = page_rec_get_heap_no(rec);
|
||||
|
||||
ut_ad(trx->is_referenced());
|
||||
|
||||
/* If the transaction is still active and has no
|
||||
explicit x-lock set on the record, set one for it.
|
||||
trx cannot be committed until the ref count is zero. */
|
||||
|
||||
lock_rec_convert_impl_to_expl_for_trx(
|
||||
id, rec, index, trx, heap_no);
|
||||
}
|
||||
|
||||
return false;
|
||||
return lock_rec_convert_impl_to_expl_for_trx(trx, id, rec, index);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -5374,8 +5371,9 @@ lock_clust_rec_modify_check_and_lock(
|
|||
/* If a transaction has no explicit x-lock set on the record, set one
|
||||
for it */
|
||||
|
||||
if (lock_rec_convert_impl_to_expl(thr_get_trx(thr), block->page.id(),
|
||||
rec, index, offsets)) {
|
||||
if (lock_rec_convert_impl_to_expl<true>(thr_get_trx(thr),
|
||||
block->page.id(),
|
||||
rec, index, offsets)) {
|
||||
/* We already hold an implicit exclusive lock. */
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
|
@ -5532,15 +5530,17 @@ lock_sec_rec_read_check_and_lock(
|
|||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
const page_id_t id{block->page.id()};
|
||||
|
||||
ut_ad(!rec_is_metadata(rec, *index));
|
||||
|
||||
trx_t *trx = thr_get_trx(thr);
|
||||
|
||||
if (lock_table_has(trx, index->table, mode)) {
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
|
||||
if (!page_rec_is_supremum(rec)
|
||||
&& !lock_table_has(trx, index->table, LOCK_X)
|
||||
&& lock_rec_convert_impl_to_expl(thr_get_trx(thr), id, rec,
|
||||
index, offsets)
|
||||
&& lock_rec_convert_impl_to_expl<false>(
|
||||
trx, block->page.id(), rec, index, offsets)
|
||||
&& gap_mode == LOCK_REC_NOT_GAP) {
|
||||
/* We already hold an implicit exclusive lock. */
|
||||
return DB_SUCCESS;
|
||||
|
@ -5565,7 +5565,8 @@ lock_sec_rec_read_check_and_lock(
|
|||
if (trx->wsrep == 3) trx->wsrep = 1;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
ut_ad(lock_rec_queue_validate(false, id, rec, index, offsets));
|
||||
ut_ad(lock_rec_queue_validate(false, block->page.id(),
|
||||
rec, index, offsets));
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
@ -5622,7 +5623,8 @@ lock_clust_rec_read_check_and_lock(
|
|||
trx_t *trx = thr_get_trx(thr);
|
||||
if (!lock_table_has(trx, index->table, LOCK_X)
|
||||
&& heap_no != PAGE_HEAP_NO_SUPREMUM
|
||||
&& lock_rec_convert_impl_to_expl(trx, id, rec, index, offsets)
|
||||
&& lock_rec_convert_impl_to_expl<true>(trx, id,
|
||||
rec, index, offsets)
|
||||
&& gap_mode == LOCK_REC_NOT_GAP) {
|
||||
/* We already hold an implicit exclusive lock. */
|
||||
return DB_SUCCESS;
|
||||
|
|
|
@ -1160,14 +1160,6 @@ wait_suspend_loop:
|
|||
|
||||
if (!buf_pool.is_initialised()) {
|
||||
ut_ad(!srv_was_started);
|
||||
} else if (ulint pending_io = buf_pool.io_pending()) {
|
||||
if (srv_print_verbose_log && count > 600) {
|
||||
ib::info() << "Waiting for " << pending_io << " buffer"
|
||||
" page I/Os to complete";
|
||||
count = 0;
|
||||
}
|
||||
|
||||
goto loop;
|
||||
} else {
|
||||
buf_flush_buffer_pool();
|
||||
}
|
||||
|
|
|
@ -3004,7 +3004,7 @@ set_start_lsn:
|
|||
/* The following is adapted from
|
||||
buf_pool_t::insert_into_flush_list() */
|
||||
mysql_mutex_lock(&buf_pool.flush_list_mutex);
|
||||
buf_pool.stat.flush_list_bytes+= block->physical_size();
|
||||
buf_pool.flush_list_bytes+= block->physical_size();
|
||||
block->page.set_oldest_modification(start_lsn);
|
||||
UT_LIST_ADD_FIRST(buf_pool.flush_list, &block->page);
|
||||
buf_pool.page_cleaner_wakeup();
|
||||
|
|
|
@ -140,9 +140,9 @@ inline void buf_pool_t::insert_into_flush_list(buf_page_t *prev,
|
|||
UT_LIST_REMOVE(flush_list, &block->page);
|
||||
}
|
||||
else
|
||||
stat.flush_list_bytes+= block->physical_size();
|
||||
flush_list_bytes+= block->physical_size();
|
||||
|
||||
ut_ad(stat.flush_list_bytes <= curr_pool_size);
|
||||
ut_ad(flush_list_bytes <= curr_pool_size);
|
||||
|
||||
if (prev)
|
||||
UT_LIST_INSERT_AFTER(flush_list, prev, &block->page);
|
||||
|
|
|
@ -217,14 +217,12 @@ rec_get_n_extern_new(
|
|||
stored in one byte for 0..127. The length
|
||||
will be encoded in two bytes when it is 128 or
|
||||
more, or when the field is stored externally. */
|
||||
if (DATA_BIG_COL(col)) {
|
||||
if (len & 0x80) {
|
||||
/* 1exxxxxxx xxxxxxxx */
|
||||
if (len & 0x40) {
|
||||
n_extern++;
|
||||
}
|
||||
lens--;
|
||||
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||
/* 1exxxxxxx xxxxxxxx */
|
||||
if (len & 0x40) {
|
||||
n_extern++;
|
||||
}
|
||||
lens--;
|
||||
}
|
||||
}
|
||||
} while (++i < n);
|
||||
|
@ -244,6 +242,10 @@ enum rec_leaf_format {
|
|||
REC_LEAF_INSTANT
|
||||
};
|
||||
|
||||
#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 11
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wconversion" /* GCC 5 to 10 need this */
|
||||
#endif
|
||||
/** Determine the offset to each field in a leaf-page record
|
||||
in ROW_FORMAT=COMPACT,DYNAMIC,COMPRESSED.
|
||||
This is a special case of rec_init_offsets() and rec_get_offsets_func().
|
||||
|
@ -361,8 +363,7 @@ start:
|
|||
do {
|
||||
if (mblob) {
|
||||
if (i == index->first_user_field()) {
|
||||
offs = static_cast<rec_offs>(offs
|
||||
+ FIELD_REF_SIZE);
|
||||
offs += FIELD_REF_SIZE;
|
||||
len = combine(offs, STORED_OFFPAGE);
|
||||
any |= REC_OFFS_EXTERNAL;
|
||||
field--;
|
||||
|
@ -433,27 +434,23 @@ start:
|
|||
stored in one byte for 0..127. The length
|
||||
will be encoded in two bytes when it is 128 or
|
||||
more, or when the field is stored externally. */
|
||||
if ((len & 0x80) && DATA_BIG_COL(col)) {
|
||||
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||
/* 1exxxxxxx xxxxxxxx */
|
||||
len = static_cast<rec_offs>(len << 8
|
||||
| *lens--);
|
||||
offs = static_cast<rec_offs>(offs
|
||||
+ get_value(len));
|
||||
if (UNIV_UNLIKELY(len & 0x4000)) {
|
||||
ut_ad(index->is_primary());
|
||||
any |= REC_OFFS_EXTERNAL;
|
||||
len = combine(offs, STORED_OFFPAGE);
|
||||
} else {
|
||||
len = offs;
|
||||
}
|
||||
|
||||
len <<= 8;
|
||||
len |= *lens--;
|
||||
static_assert(STORED_OFFPAGE == 0x4000, "");
|
||||
static_assert(REC_OFFS_EXTERNAL == 0x4000, "");
|
||||
const rec_offs ext = len & REC_OFFS_EXTERNAL;
|
||||
offs += get_value(len);
|
||||
len = offs | ext;
|
||||
any |= ext;
|
||||
ut_ad(!ext || index->is_primary());
|
||||
continue;
|
||||
}
|
||||
|
||||
len = offs = static_cast<rec_offs>(offs + len);
|
||||
len = offs += len;
|
||||
} else {
|
||||
len = offs = static_cast<rec_offs>(offs
|
||||
+ field->fixed_len);
|
||||
len = offs += field->fixed_len;
|
||||
}
|
||||
} while (field++, rec_offs_base(offsets)[++i] = len,
|
||||
i < rec_offs_n_fields(offsets));
|
||||
|
@ -679,8 +676,7 @@ rec_init_offsets(
|
|||
do {
|
||||
rec_offs len;
|
||||
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
|
||||
len = offs = static_cast<rec_offs>(
|
||||
offs + REC_NODE_PTR_SIZE);
|
||||
len = offs += REC_NODE_PTR_SIZE;
|
||||
goto resolved;
|
||||
}
|
||||
|
||||
|
@ -720,29 +716,25 @@ rec_init_offsets(
|
|||
encoded in two bytes when it is 128 or
|
||||
more, or when the field is stored
|
||||
externally. */
|
||||
if (DATA_BIG_COL(col)) {
|
||||
if (len & 0x80) {
|
||||
/* 1exxxxxxx xxxxxxxx */
|
||||
len = static_cast<rec_offs>(
|
||||
len << 8 | *lens--);
|
||||
if (UNIV_UNLIKELY(len & 0x80)
|
||||
&& DATA_BIG_COL(col)) {
|
||||
/* 1exxxxxxx xxxxxxxx */
|
||||
len <<= 8;
|
||||
len |= *lens--;
|
||||
|
||||
/* B-tree node pointers
|
||||
must not contain externally
|
||||
stored columns. Thus
|
||||
the "e" flag must be 0. */
|
||||
ut_a(!(len & 0x4000));
|
||||
offs = static_cast<rec_offs>(
|
||||
offs + get_value(len));
|
||||
len = offs;
|
||||
|
||||
goto resolved;
|
||||
}
|
||||
/* B-tree node pointers
|
||||
must not contain externally
|
||||
stored columns. Thus
|
||||
the "e" flag must be 0. */
|
||||
ut_a(!(len & 0x4000));
|
||||
offs += len & 0x3fff;
|
||||
len = offs;
|
||||
goto resolved;
|
||||
}
|
||||
|
||||
len = offs = static_cast<rec_offs>(offs + len);
|
||||
len = offs += len;
|
||||
} else {
|
||||
len = offs = static_cast<rec_offs>(
|
||||
offs + field->fixed_len);
|
||||
len = offs += field->fixed_len;
|
||||
}
|
||||
resolved:
|
||||
rec_offs_base(offsets)[i + 1] = len;
|
||||
|
@ -759,35 +751,30 @@ resolved:
|
|||
rec_offs any;
|
||||
|
||||
if (rec_get_1byte_offs_flag(rec)) {
|
||||
offs = static_cast<rec_offs>(offs + n_fields);
|
||||
offs += static_cast<rec_offs>(n_fields);
|
||||
any = offs;
|
||||
/* Determine offsets to fields */
|
||||
do {
|
||||
offs = rec_1_get_field_end_info(rec, i);
|
||||
if (offs & REC_1BYTE_SQL_NULL_MASK) {
|
||||
offs &= static_cast<rec_offs>(
|
||||
~REC_1BYTE_SQL_NULL_MASK);
|
||||
set_type(offs, SQL_NULL);
|
||||
offs ^= REC_1BYTE_SQL_NULL_MASK
|
||||
| SQL_NULL;
|
||||
}
|
||||
rec_offs_base(offsets)[1 + i] = offs;
|
||||
} while (++i < n);
|
||||
} else {
|
||||
offs = static_cast<rec_offs>(offs + 2 * n_fields);
|
||||
offs += static_cast<rec_offs>(2 * n_fields);
|
||||
any = offs;
|
||||
/* Determine offsets to fields */
|
||||
do {
|
||||
offs = rec_2_get_field_end_info(rec, i);
|
||||
if (offs & REC_2BYTE_SQL_NULL_MASK) {
|
||||
offs &= static_cast<rec_offs>(
|
||||
~REC_2BYTE_SQL_NULL_MASK);
|
||||
set_type(offs, SQL_NULL);
|
||||
}
|
||||
if (offs & REC_2BYTE_EXTERN_MASK) {
|
||||
offs &= static_cast<rec_offs>(
|
||||
~REC_2BYTE_EXTERN_MASK);
|
||||
set_type(offs, STORED_OFFPAGE);
|
||||
any |= REC_OFFS_EXTERNAL;
|
||||
}
|
||||
static_assert(REC_2BYTE_SQL_NULL_MASK
|
||||
== SQL_NULL, "");
|
||||
static_assert(REC_2BYTE_EXTERN_MASK
|
||||
== STORED_OFFPAGE, "");
|
||||
static_assert(REC_OFFS_EXTERNAL
|
||||
== STORED_OFFPAGE, "");
|
||||
any |= (offs & REC_OFFS_EXTERNAL);
|
||||
rec_offs_base(offsets)[1 + i] = offs;
|
||||
} while (++i < n);
|
||||
}
|
||||
|
@ -996,8 +983,7 @@ rec_get_offsets_reverse(
|
|||
do {
|
||||
rec_offs len;
|
||||
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
|
||||
len = offs = static_cast<rec_offs>(
|
||||
offs + REC_NODE_PTR_SIZE);
|
||||
len = offs += REC_NODE_PTR_SIZE;
|
||||
goto resolved;
|
||||
}
|
||||
|
||||
|
@ -1034,30 +1020,23 @@ rec_get_offsets_reverse(
|
|||
stored in one byte for 0..127. The length
|
||||
will be encoded in two bytes when it is 128 or
|
||||
more, or when the field is stored externally. */
|
||||
if (DATA_BIG_COL(col)) {
|
||||
if (len & 0x80) {
|
||||
/* 1exxxxxxx xxxxxxxx */
|
||||
len = static_cast<rec_offs>(
|
||||
len << 8 | *lens++);
|
||||
|
||||
offs = static_cast<rec_offs>(
|
||||
offs + get_value(len));
|
||||
if (UNIV_UNLIKELY(len & 0x4000)) {
|
||||
any_ext = REC_OFFS_EXTERNAL;
|
||||
len = combine(offs,
|
||||
STORED_OFFPAGE);
|
||||
} else {
|
||||
len = offs;
|
||||
}
|
||||
|
||||
goto resolved;
|
||||
}
|
||||
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||
/* 1exxxxxxx xxxxxxxx */
|
||||
len &= 0x7f;
|
||||
len <<= 8;
|
||||
len |= *lens++;
|
||||
static_assert(STORED_OFFPAGE == 0x4000, "");
|
||||
static_assert(REC_OFFS_EXTERNAL == 0x4000, "");
|
||||
rec_offs ext = len & REC_OFFS_EXTERNAL;
|
||||
offs += get_value(len);
|
||||
len = offs | ext;
|
||||
any_ext |= ext;
|
||||
goto resolved;
|
||||
}
|
||||
|
||||
len = offs = static_cast<rec_offs>(offs + len);
|
||||
len = offs += len;
|
||||
} else {
|
||||
len = offs = static_cast<rec_offs>(offs
|
||||
+ field->fixed_len);
|
||||
len = offs += field->fixed_len;
|
||||
}
|
||||
resolved:
|
||||
rec_offs_base(offsets)[i + 1] = len;
|
||||
|
@ -1097,7 +1076,7 @@ rec_get_nth_field_offs_old(
|
|||
return(os);
|
||||
}
|
||||
|
||||
next_os = next_os & ~REC_1BYTE_SQL_NULL_MASK;
|
||||
next_os &= ~REC_1BYTE_SQL_NULL_MASK;
|
||||
} else {
|
||||
os = rec_2_get_field_start_offs(rec, n);
|
||||
|
||||
|
@ -1109,8 +1088,7 @@ rec_get_nth_field_offs_old(
|
|||
return(os);
|
||||
}
|
||||
|
||||
next_os = next_os & ~(REC_2BYTE_SQL_NULL_MASK
|
||||
| REC_2BYTE_EXTERN_MASK);
|
||||
next_os &= ~(REC_2BYTE_SQL_NULL_MASK | REC_2BYTE_EXTERN_MASK);
|
||||
}
|
||||
|
||||
*len = next_os - os;
|
||||
|
@ -1263,7 +1241,8 @@ rec_get_converted_size_comp_prefix_low(
|
|||
} else if (dfield_is_ext(dfield)) {
|
||||
ut_ad(DATA_BIG_COL(field->col));
|
||||
extra_size += 2;
|
||||
} else if (len < 128 || !DATA_BIG_COL(field->col)) {
|
||||
} else if (UNIV_LIKELY(len < 128)
|
||||
|| !DATA_BIG_COL(field->col)) {
|
||||
extra_size++;
|
||||
} else {
|
||||
/* For variable-length columns, we look up the
|
||||
|
@ -1614,14 +1593,7 @@ start:
|
|||
|
||||
/* set the null flag if necessary */
|
||||
if (dfield_is_null(field)) {
|
||||
#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wconversion" /* GCC 5 may need this here */
|
||||
#endif
|
||||
*nulls |= static_cast<byte>(null_mask);
|
||||
#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
null_mask <<= 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -1730,6 +1702,9 @@ rec_convert_dtuple_to_rec_new(
|
|||
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
|
||||
return buf;
|
||||
}
|
||||
#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 11
|
||||
# pragma GCC diagnostic pop /* ignored "-Wconversion" */
|
||||
#endif
|
||||
|
||||
/*********************************************************//**
|
||||
Builds a physical record out of a data tuple and
|
||||
|
@ -2092,14 +2067,12 @@ rec_copy_prefix_to_buf(
|
|||
stored in one byte for 0..127. The length
|
||||
will be encoded in two bytes when it is 128 or
|
||||
more, or when the column is stored externally. */
|
||||
if (DATA_BIG_COL(col)) {
|
||||
if (len & 0x80) {
|
||||
/* 1exxxxxx */
|
||||
len &= 0x3f;
|
||||
len <<= 8;
|
||||
len |= *lens--;
|
||||
UNIV_PREFETCH_R(lens);
|
||||
}
|
||||
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||
/* 1exxxxxx */
|
||||
len &= 0x3f;
|
||||
len <<= 8;
|
||||
len |= *lens--;
|
||||
UNIV_PREFETCH_R(lens);
|
||||
}
|
||||
prefix_len += len;
|
||||
}
|
||||
|
|
|
@ -2252,7 +2252,7 @@ row_ins_duplicate_online(ulint n_uniq, const dtuple_t *entry,
|
|||
|
||||
ulint trx_id_len;
|
||||
|
||||
if (fields == n_uniq
|
||||
if (fields == n_uniq + 2
|
||||
&& memcmp(rec_get_nth_field(rec, offsets, n_uniq, &trx_id_len),
|
||||
reset_trx_id, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)) {
|
||||
ut_ad(trx_id_len == DATA_TRX_ID_LEN);
|
||||
|
|
|
@ -3042,6 +3042,9 @@ row_log_apply_op_low(
|
|||
mtr_start(&mtr);
|
||||
index->set_modified(mtr);
|
||||
cursor.page_cur.index = index;
|
||||
if (has_index_lock) {
|
||||
mtr_x_lock_index(index, &mtr);
|
||||
}
|
||||
|
||||
/* We perform the pessimistic variant of the operations if we
|
||||
already hold index->lock exclusively. First, search the
|
||||
|
@ -3049,7 +3052,8 @@ row_log_apply_op_low(
|
|||
depending on when the row in the clustered index was
|
||||
scanned. */
|
||||
*error = cursor.search_leaf(entry, PAGE_CUR_LE, has_index_lock
|
||||
? BTR_MODIFY_TREE : BTR_MODIFY_LEAF, &mtr);
|
||||
? BTR_MODIFY_TREE_ALREADY_LATCHED
|
||||
: BTR_MODIFY_LEAF, &mtr);
|
||||
if (UNIV_UNLIKELY(*error != DB_SUCCESS)) {
|
||||
goto func_exit;
|
||||
}
|
||||
|
|
|
@ -832,7 +832,7 @@ static monitor_info_t innodb_counter_info[] =
|
|||
MONITOR_DEFAULT_START, MONITOR_MODULE_INDEX},
|
||||
|
||||
{"index_page_splits", "index", "Number of index page splits",
|
||||
MONITOR_NONE,
|
||||
MONITOR_EXISTING,
|
||||
MONITOR_DEFAULT_START, MONITOR_INDEX_SPLIT},
|
||||
|
||||
{"index_page_merge_attempts", "index",
|
||||
|
@ -1240,10 +1240,12 @@ srv_mon_process_existing_counter(
|
|||
|
||||
/* Get the value from corresponding global variable */
|
||||
switch (monitor_id) {
|
||||
/* export_vars.innodb_buffer_pool_reads. Num Reads from
|
||||
disk (page not in buffer) */
|
||||
case MONITOR_INDEX_SPLIT:
|
||||
value = buf_pool.pages_split;
|
||||
break;
|
||||
|
||||
case MONITOR_OVLD_BUF_POOL_READS:
|
||||
value = srv_stats.buf_pool_reads;
|
||||
value = buf_pool.stat.n_pages_read;
|
||||
break;
|
||||
|
||||
/* innodb_buffer_pool_read_requests, the number of logical
|
||||
|
@ -1304,7 +1306,7 @@ srv_mon_process_existing_counter(
|
|||
|
||||
/* innodb_buffer_pool_bytes_dirty */
|
||||
case MONITOR_OVLD_BUF_POOL_BYTES_DIRTY:
|
||||
value = buf_pool.stat.flush_list_bytes;
|
||||
value = buf_pool.flush_list_bytes;
|
||||
break;
|
||||
|
||||
/* innodb_buffer_pool_pages_free */
|
||||
|
|
|
@ -628,6 +628,7 @@ void srv_boot()
|
|||
if (transactional_lock_enabled())
|
||||
sql_print_information("InnoDB: Using transactional memory");
|
||||
#endif
|
||||
buf_dblwr.init();
|
||||
srv_thread_pool_init();
|
||||
trx_pool_init();
|
||||
srv_init();
|
||||
|
@ -880,56 +881,19 @@ srv_export_innodb_status(void)
|
|||
|
||||
export_vars.innodb_data_writes = os_n_file_writes;
|
||||
|
||||
ulint dblwr = 0;
|
||||
|
||||
if (buf_dblwr.is_initialised()) {
|
||||
buf_dblwr.lock();
|
||||
dblwr = buf_dblwr.submitted();
|
||||
export_vars.innodb_dblwr_pages_written = buf_dblwr.written();
|
||||
export_vars.innodb_dblwr_writes = buf_dblwr.batches();
|
||||
buf_dblwr.unlock();
|
||||
}
|
||||
buf_dblwr.lock();
|
||||
ulint dblwr = buf_dblwr.submitted();
|
||||
export_vars.innodb_dblwr_pages_written = buf_dblwr.written();
|
||||
export_vars.innodb_dblwr_writes = buf_dblwr.batches();
|
||||
buf_dblwr.unlock();
|
||||
|
||||
export_vars.innodb_data_written = srv_stats.data_written + dblwr;
|
||||
|
||||
export_vars.innodb_buffer_pool_read_requests
|
||||
= buf_pool.stat.n_page_gets;
|
||||
|
||||
export_vars.innodb_buffer_pool_reads = srv_stats.buf_pool_reads;
|
||||
|
||||
export_vars.innodb_buffer_pool_read_ahead_rnd =
|
||||
buf_pool.stat.n_ra_pages_read_rnd;
|
||||
|
||||
export_vars.innodb_buffer_pool_read_ahead =
|
||||
buf_pool.stat.n_ra_pages_read;
|
||||
|
||||
export_vars.innodb_buffer_pool_read_ahead_evicted =
|
||||
buf_pool.stat.n_ra_pages_evicted;
|
||||
|
||||
export_vars.innodb_buffer_pool_pages_data =
|
||||
UT_LIST_GET_LEN(buf_pool.LRU);
|
||||
|
||||
export_vars.innodb_buffer_pool_bytes_data =
|
||||
buf_pool.stat.LRU_bytes
|
||||
+ (UT_LIST_GET_LEN(buf_pool.unzip_LRU)
|
||||
<< srv_page_size_shift);
|
||||
|
||||
export_vars.innodb_buffer_pool_pages_dirty =
|
||||
UT_LIST_GET_LEN(buf_pool.flush_list);
|
||||
|
||||
export_vars.innodb_buffer_pool_pages_made_young
|
||||
= buf_pool.stat.n_pages_made_young;
|
||||
export_vars.innodb_buffer_pool_pages_made_not_young
|
||||
= buf_pool.stat.n_pages_not_made_young;
|
||||
|
||||
export_vars.innodb_buffer_pool_pages_old = buf_pool.LRU_old_len;
|
||||
|
||||
export_vars.innodb_buffer_pool_bytes_dirty =
|
||||
buf_pool.stat.flush_list_bytes;
|
||||
|
||||
export_vars.innodb_buffer_pool_pages_free =
|
||||
UT_LIST_GET_LEN(buf_pool.free);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
export_vars.innodb_buffer_pool_pages_latched =
|
||||
buf_get_latched_pages_number();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue