Commit b46cf33a authored by Marko Mäkelä's avatar Marko Mäkelä
Browse files

Merge 10.2 into 10.3

parents 9fc1ef93 1cb218c3
......@@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
#include "common.h"
#include "datasink.h"
#include "ds_compress.h"
#include "ds_archive.h"
#include "ds_xbstream.h"
#include "ds_local.h"
#include "ds_stdout.h"
......@@ -45,13 +44,6 @@ ds_create(const char *root, ds_type_t type)
case DS_TYPE_LOCAL:
ds = &datasink_local;
break;
case DS_TYPE_ARCHIVE:
#ifdef HAVE_LIBARCHIVE
ds = &datasink_archive;
#else
die("mariabackup was built without libarchive support");
#endif
break;
case DS_TYPE_XBSTREAM:
ds = &datasink_xbstream;
break;
......
......@@ -63,7 +63,6 @@ static inline int dummy_remove(const char *) {
typedef enum {
DS_TYPE_STDOUT,
DS_TYPE_LOCAL,
DS_TYPE_ARCHIVE,
DS_TYPE_XBSTREAM,
DS_TYPE_COMPRESS,
DS_TYPE_ENCRYPT,
......
/******************************************************
Copyright (c) 2013 Percona LLC and/or its affiliates.
Streaming implementation for XtraBackup.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*******************************************************/
#include <my_global.h>
#include <my_base.h>
#include <archive.h>
#include <archive_entry.h>
#include "common.h"
#include "datasink.h"
#if ARCHIVE_VERSION_NUMBER < 3000000
#define archive_write_add_filter_none(X) archive_write_set_compression_none(X)
#define archive_write_free(X) archive_write_finish(X)
#endif
typedef struct {
struct archive *archive;
ds_file_t *dest_file;
pthread_mutex_t mutex;
} ds_archive_ctxt_t;
typedef struct {
struct archive_entry *entry;
ds_archive_ctxt_t *archive_ctxt;
} ds_archive_file_t;
/***********************************************************************
General archive interface */
static ds_ctxt_t *archive_init(const char *root);
static ds_file_t *archive_open(ds_ctxt_t *ctxt, const char *path,
MY_STAT *mystat);
static int archive_write(ds_file_t *file, const void *buf, size_t len);
static int archive_close(ds_file_t *file);
static void archive_deinit(ds_ctxt_t *ctxt);
datasink_t datasink_archive = {
&archive_init,
&archive_open,
&archive_write,
&archive_close,
&dummy_remove,
&archive_deinit
};
static
int
my_archive_open_callback(struct archive *a __attribute__((unused)),
void *data __attribute__((unused)))
{
return ARCHIVE_OK;
}
static
ssize_t
my_archive_write_callback(struct archive *a __attribute__((unused)),
void *data, const void *buffer, size_t length)
{
ds_archive_ctxt_t *archive_ctxt;
archive_ctxt = (ds_archive_ctxt_t *) data;
xb_ad(archive_ctxt != NULL);
xb_ad(archive_ctxt->dest_file != NULL);
if (!ds_write(archive_ctxt->dest_file, buffer, length)) {
return length;
}
return -1;
}
static
int
my_archive_close_callback(struct archive *a __attribute__((unused)),
void *data __attribute__((unused)))
{
return ARCHIVE_OK;
}
static
ds_ctxt_t *
archive_init(const char *root __attribute__((unused)))
{
ds_ctxt_t *ctxt;
ds_archive_ctxt_t *archive_ctxt;
struct archive *a;
ctxt = my_malloc(sizeof(ds_ctxt_t) + sizeof(ds_archive_ctxt_t),
MYF(MY_FAE));
archive_ctxt = (ds_archive_ctxt_t *)(ctxt + 1);
if (pthread_mutex_init(&archive_ctxt->mutex, NULL)) {
msg("archive_init: pthread_mutex_init() failed.\n");
goto err;
}
a = archive_write_new();
if (a == NULL) {
msg("archive_write_new() failed.\n");
goto err;
}
archive_ctxt->archive = a;
archive_ctxt->dest_file = NULL;
if(archive_write_add_filter_none(a) != ARCHIVE_OK ||
archive_write_set_format_pax_restricted(a) != ARCHIVE_OK ||
/* disable internal buffering so we don't have to flush the
output in xtrabackup */
archive_write_set_bytes_per_block(a, 0) != ARCHIVE_OK) {
msg("failed to set libarchive archive options: %s\n",
archive_error_string(a));
archive_write_free(a);
goto err;
}
if (archive_write_open(a, archive_ctxt, my_archive_open_callback,
my_archive_write_callback,
my_archive_close_callback) != ARCHIVE_OK) {
msg("cannot open output archive.\n");
return NULL;
}
ctxt->ptr = archive_ctxt;
return ctxt;
err:
my_free(ctxt);
return NULL;
}
static
ds_file_t *
archive_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat)
{
ds_archive_ctxt_t *archive_ctxt;
ds_ctxt_t *dest_ctxt;
ds_file_t *file;
ds_archive_file_t *archive_file;
struct archive *a;
struct archive_entry *entry;
xb_ad(ctxt->pipe_ctxt != NULL);
dest_ctxt = ctxt->pipe_ctxt;
archive_ctxt = (ds_archive_ctxt_t *) ctxt->ptr;
pthread_mutex_lock(&archive_ctxt->mutex);
if (archive_ctxt->dest_file == NULL) {
archive_ctxt->dest_file = ds_open(dest_ctxt, path, mystat);
if (archive_ctxt->dest_file == NULL) {
return NULL;
}
}
pthread_mutex_unlock(&archive_ctxt->mutex);
file = (ds_file_t *) my_malloc(sizeof(ds_file_t) +
sizeof(ds_archive_file_t),
MYF(MY_FAE));
archive_file = (ds_archive_file_t *) (file + 1);
a = archive_ctxt->archive;
entry = archive_entry_new();
if (entry == NULL) {
msg("archive_entry_new() failed.\n");
goto err;
}
archive_entry_set_size(entry, mystat->st_size);
archive_entry_set_mode(entry, 0660);
archive_entry_set_filetype(entry, AE_IFREG);
archive_entry_set_pathname(entry, path);
archive_entry_set_mtime(entry, mystat->st_mtime, 0);
archive_file->entry = entry;
archive_file->archive_ctxt = archive_ctxt;
if (archive_write_header(a, entry) != ARCHIVE_OK) {
msg("archive_write_header() failed.\n");
archive_entry_free(entry);
goto err;
}
file->ptr = archive_file;
file->path = archive_ctxt->dest_file->path;
return file;
err:
if (archive_ctxt->dest_file) {
ds_close(archive_ctxt->dest_file);
archive_ctxt->dest_file = NULL;
}
my_free(file);
return NULL;
}
static
int
archive_write(ds_file_t *file, const void *buf, size_t len)
{
ds_archive_file_t *archive_file;
struct archive *a;
archive_file = (ds_archive_file_t *) file->ptr;
a = archive_file->archive_ctxt->archive;
xb_ad(archive_file->archive_ctxt->dest_file != NULL);
if (archive_write_data(a, buf, len) < 0) {
msg("archive_write_data() failed: %s (errno = %d)\n",
archive_error_string(a), archive_errno(a));
return 1;
}
return 0;
}
static
int
archive_close(ds_file_t *file)
{
ds_archive_file_t *archive_file;
int rc = 0;
archive_file = (ds_archive_file_t *)file->ptr;
archive_entry_free(archive_file->entry);
my_free(file);
return rc;
}
static
void
archive_deinit(ds_ctxt_t *ctxt)
{
struct archive *a;
ds_archive_ctxt_t *archive_ctxt;
archive_ctxt = (ds_archive_ctxt_t *) ctxt->ptr;
a = archive_ctxt->archive;
if (archive_write_close(a) != ARCHIVE_OK) {
msg("archive_write_close() failed.\n");
}
archive_write_free(a);
if (archive_ctxt->dest_file) {
ds_close(archive_ctxt->dest_file);
archive_ctxt->dest_file = NULL;
}
pthread_mutex_destroy(&archive_ctxt->mutex);
my_free(ctxt);
}
/******************************************************
Copyright (c) 2013 Percona LLC and/or its affiliates.
Streaming interface for XtraBackup.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
*******************************************************/
#ifndef DS_ARCHIVE_H
#define DS_ARCHIVE_H
#include "datasink.h"
extern datasink_t datasink_archive;
#endif
......@@ -126,15 +126,19 @@ xbstream_open(ds_ctxt_t *ctxt, const char *path, MY_STAT *mystat)
pthread_mutex_lock(&stream_ctxt->mutex);
if (stream_ctxt->dest_file == NULL) {
stream_ctxt->dest_file = ds_open(dest_ctxt, path, mystat);
if (stream_ctxt->dest_file == NULL) {
return NULL;
}
}
pthread_mutex_unlock(&stream_ctxt->mutex);
if (stream_ctxt->dest_file == NULL) {
return NULL;
}
file = (ds_file_t *) my_malloc(sizeof(ds_file_t) +
sizeof(ds_stream_file_t),
MYF(MY_FAE));
if (!file) {
msg("my_malloc() failed.");
goto err;
}
stream_file = (ds_stream_file_t *) (file + 1);
xbstream = stream_ctxt->xbstream;
......
......@@ -2261,7 +2261,7 @@ servers \- remote (federated) servers as \fBCREATE SERVER\fR\&.
.sp -1
.IP \(bu 2.3
.\}
stats \- statistics tables, InnoDB and Engine Independent Table Statistics (EITS), are dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-into\fR is specified) statements without (re)creating tables\&.
stats \- statistics tables, InnoDB and Engine Independent Table Statistics (EITS), are dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-ignore\fR is specified) statements without (re)creating tables\&.
.RE
.RS 4
.ie n \{\
......@@ -2271,17 +2271,17 @@ stats \- statistics tables, InnoDB and Engine Independent Table Statistics (EITS
.sp -1
.IP \(bu 2.3
.\}
timezones \- timezone related system tables dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-into\fR is specified) statements without (re)creating tables\&.
timezones \- timezone related system tables dumped as \fBREPLACE INTO\fR (or \fBINSERT IGNORE\fR if \fB\-\-insert\-ignore\fR is specified) statements without (re)creating tables\&.
.RE
.sp
The format of the output is affected by \fB\-\-replace\fR and \fB\-\-insert\-into\fR\&. The \fB\-\-replace\fR option will output \fBCREATE OR REPLACE\fR
The format of the output is affected by \fB\-\-replace\fR and \fB\-\-insert\-ignore\fR\&. The \fB\-\-replace\fR option will output \fBCREATE OR REPLACE\fR
forms of SQL, and also \fBDROP IF EXISTS\fR prior to \fBCREATE\fR, if a \fBCREATE OR REPLACE\fR option isn't available.
.sp
With \fB\-\-system=user\fR (or \fBall\fR), and \fB\-\-replace\fR, SQL is generated to generate an error if attempting to import the dump with a connection user that is being replaced within the dump\&.
.sp
The \fB\-\-insert\-into\fR option will cause \fBCREATE IF NOT EXIST\fR forms of SQL to generated if available.
The \fB\-\-insert\-ignore\fR option will cause \fBCREATE IF NOT EXIST\fR forms of SQL to generated if available.
.sp
For stats, and timezones, \fB\-\-replace\fR and \fB\-\-insert\-into\fR have the usual effects.
For stats, and timezones, \fB\-\-replace\fR and \fB\-\-insert\-ignore\fR have the usual effects.
.sp
Enabling specific options here will cause the relevant tables in the mysql database to be ignored when dumping the mysql database or \fB\-\-all\-databases\fR\&.
.sp
......
......@@ -5,7 +5,7 @@
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
LOCK TABLE t1 READ;
connect con1,localhost,root,,test;
SET SESSION max_session_mem_used= 65536;
SET SESSION max_session_mem_used= 45500;
LOCK TABLE t1 WRITE;
connection default;
SELECT * FROM t1;
......@@ -13,7 +13,7 @@ a
UNLOCK TABLES;
connection con1;
TRUNCATE TABLE t1;
ERROR HY000: The MariaDB server is running with the --max-thread-mem-used=65536 option so it cannot execute this statement
ERROR HY000: The MariaDB server is running with the --max-thread-mem-used=45500 option so it cannot execute this statement
disconnect con1;
connection default;
DROP TABLE t1;
......
......@@ -9,7 +9,7 @@ CREATE TABLE t1 (a INT) ENGINE=MyISAM;
LOCK TABLE t1 READ;
--connect (con1,localhost,root,,test)
SET SESSION max_session_mem_used= 65536;
SET SESSION max_session_mem_used= 45500;
--send
LOCK TABLE t1 WRITE;
......
......@@ -19,7 +19,7 @@ innodb_system
# Success!
# Now turn off encryption and wait for threads to decrypt everything
SET GLOBAL innodb_encrypt_tables = off;
# Wait max 10 min for key encryption threads to encrypt all spaces
# Wait max 10 min for key encryption threads to decrypt all spaces
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0
AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry';
NAME
......
......@@ -14,7 +14,9 @@ SHOW VARIABLES LIKE 'innodb_encrypt%';
SET GLOBAL innodb_encrypt_tables = ON;
--let $tables_count= `select count(*) + 1 from information_schema.tables where engine = 'InnoDB'`
let $undo_count= `select @@global.innodb_undo_tablespaces`;
--let $tables_count= `select count(*) + 1 + $undo_count from information_schema.tables where engine = 'InnoDB'`
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
--let $wait_timeout= 600
......@@ -33,7 +35,7 @@ AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NA
--echo # Now turn off encryption and wait for threads to decrypt everything
SET GLOBAL innodb_encrypt_tables = off;
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
--echo # Wait max 10 min for key encryption threads to decrypt all spaces
--let $wait_timeout= 600
--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
--source include/wait_condition.inc
......
DROP TABLE if exists t1;
select @@global.innodb_stats_persistent;
@@global.innodb_stats_persistent
0
set global innodb_defragment_stats_accuracy = 20;
SET GLOBAL innodb_defragment_stats_accuracy = 20;
DELETE FROM mysql.innodb_index_stats;
# Create table.
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB;
# Populate data
INSERT INTO t1 VALUES(1, REPEAT('A', 256));
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
# Not enough page splits to trigger persistent stats write yet.
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
count(stat_value) = 0
......@@ -27,7 +13,7 @@ count(stat_value) = 0
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
count(stat_value) = 0
1
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
# Persistent stats recorded.
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
count(stat_value) > 0
......@@ -39,6 +25,7 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like
count(stat_value) > 0
1
# Delete some rows.
BEGIN;
delete from t1 where a between 100 * 20 and 100 * 20 + 30;
delete from t1 where a between 100 * 19 and 100 * 19 + 30;
delete from t1 where a between 100 * 18 and 100 * 18 + 30;
......@@ -59,8 +46,7 @@ delete from t1 where a between 100 * 4 and 100 * 4 + 30;
delete from t1 where a between 100 * 3 and 100 * 3 + 30;
delete from t1 where a between 100 * 2 and 100 * 2 + 30;
delete from t1 where a between 100 * 1 and 100 * 1 + 30;
# Server Restarted
# Confirm persistent stats still there after restart.
COMMIT;
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
count(stat_value) > 0
1
......@@ -73,9 +59,6 @@ count(stat_value) > 0
optimize table t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
select sleep(2);
sleep(2)
0
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
count(stat_value) > 0
1
......@@ -108,9 +91,6 @@ count(stat_value) > 0
1
# Table rename should cause stats rename.
rename table t1 to t2;
select sleep(1);
sleep(1)
0
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
count(stat_value) = 0
1
......@@ -129,47 +109,36 @@ count(stat_value) > 0
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
count(stat_value) > 0
1
# Drop index should cause stats drop.
# Drop index should cause stats drop, but will not.
drop index SECOND on t2;
select sleep(3);
sleep(3)
0
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_page_split');
count(stat_value) > 0
1
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_pages_freed');
count(stat_value) > 0
1
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_leaf_pages_defrag');
count(stat_value) > 0
1
Server Restarted
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
count(stat_value) = 0
1
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
count(stat_value) = 0
1
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
count(stat_value) = 0
1
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
count(stat_value) > 0
1
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
count(stat_value) > 0
1
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
count(stat_value) > 0
1
SELECT stat_name, stat_value>0 FROM mysql.innodb_index_stats
WHERE table_name like '%t2%' AND index_name='SECOND';
stat_name stat_value>0
n_leaf_pages_defrag 1
n_leaf_pages_reserved 1
n_page_split 1
n_pages_freed 1
#
# MDEV-26636: Statistics must not be written for temporary tables
#
SET GLOBAL innodb_defragment_stats_accuracy = 1;
CREATE TEMPORARY TABLE t (a INT PRIMARY KEY, c CHAR(255) NOT NULL)
ENGINE=InnoDB;
INSERT INTO t SELECT seq, '' FROM seq_1_to_100;
SELECT * FROM mysql.innodb_index_stats where table_name like '%t1%';
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
SELECT table_name, index_name, stat_name, stat_value>0
FROM mysql.innodb_index_stats;
table_name index_name stat_name stat_value>0
t2 PRIMARY n_leaf_pages_defrag 1
t2 PRIMARY n_leaf_pages_reserved 1
t2 PRIMARY n_page_split 1
t2 PRIMARY n_pages_freed 1
t2 SECOND n_leaf_pages_defrag 1
t2 SECOND n_leaf_pages_reserved 1
t2 SECOND n_page_split 1
t2 SECOND n_pages_freed 1
# Clean up
DROP TABLE t2;
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
count(stat_value) = 0
1
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
count(stat_value) = 0
1
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
count(stat_value) = 0
1
SELECT * FROM mysql.innodb_index_stats;
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
......@@ -9,28 +9,12 @@ SET @trunc_start=
WHERE variable_name = 'innodb_undo_truncations');
create table t1(keyc int primary key, c char(100)) engine = innodb;
create table t2(keyc int primary key, c char(100)) engine = innodb;
CREATE PROCEDURE populate_t1()
BEGIN
DECLARE i INT DEFAULT 1;
while (i <= 20000) DO
insert into t1 values (i, 'a');
SET i = i + 1;
END WHILE;
END |
CREATE PROCEDURE populate_t2()
BEGIN
DECLARE i INT DEFAULT 1;
while (i <= 20000) DO
insert into t2 values (i, 'a');
SET i = i + 1;
END WHILE;
END |
connect con1,localhost,root,,;
begin;
call populate_t1();
insert into t1 select seq,'a' from seq_1_to_20000;
connect con2,localhost,root,,;
begin;
call populate_t2();
insert into t2 select seq,'a' from seq_1_to_20000;
connection con1;
update t1 set c = 'mysql';
connection con2;
......@@ -52,8 +36,6 @@ commit;
disconnect con2;
connection default;
drop table t1, t2;
drop PROCEDURE populate_t1;
drop PROCEDURE populate_t2;
InnoDB 0 transactions not purged
SET GLOBAL innodb_undo_logs = @save_undo_logs;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
......
--source include/have_innodb.inc
--source include/big_test.inc
--source include/not_valgrind.inc
--source include/not_embedded.inc
--source include/have_sequence.inc
--disable_warnings
DROP TABLE if exists t1;
--enable_warnings
SET GLOBAL innodb_defragment_stats_accuracy = 20;
--disable_query_log
let $innodb_defragment_stats_accuracy_orig=`select @@innodb_defragment_stats_accuracy`;
--enable_query_log
select @@global.innodb_stats_persistent;
set global innodb_defragment_stats_accuracy = 20;
DELETE FROM mysql.innodb_index_stats;
--echo # Create table.
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB;
--echo # Populate data
INSERT INTO t1 VALUES(1, REPEAT('A', 256));
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
--echo # Not enough page splits to trigger persistent stats write yet.
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
INSERT INTO t1 (b) SELECT b from t1;
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
--echo # Persistent stats recorded.
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
......@@ -43,6 +25,7 @@ select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
--echo # Delete some rows.
BEGIN;
let $num_delete = 20;
while ($num_delete)
{
......@@ -50,17 +33,13 @@ while ($num_delete)
eval delete from t1 where a between $j and $j + 30;
dec $num_delete;
}
COMMIT;
--source include/restart_mysqld.inc
--echo # Server Restarted
--echo # Confirm persistent stats still there after restart.
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
optimize table t1;
select sleep(2);
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
......@@ -84,7 +63,6 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like
--echo # Table rename should cause stats rename.
rename table t1 to t2;
select sleep(1);
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
......@@ -94,32 +72,30 @@ select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
--echo # Drop index should cause stats drop.
--echo # Drop index should cause stats drop, but will not.
drop index SECOND on t2;
select sleep(3);
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_page_split');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_leaf_pages_defrag');
--sorted_result
SELECT stat_name, stat_value>0 FROM mysql.innodb_index_stats
WHERE table_name like '%t2%' AND index_name='SECOND';
--echo #
--echo # MDEV-26636: Statistics must not be written for temporary tables
--echo #
SET GLOBAL innodb_defragment_stats_accuracy = 1;
CREATE TEMPORARY TABLE t (a INT PRIMARY KEY, c CHAR(255) NOT NULL)
ENGINE=InnoDB;
INSERT INTO t SELECT seq, '' FROM seq_1_to_100;
--source include/restart_mysqld.inc
--echo Server Restarted
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
SELECT * FROM mysql.innodb_index_stats where table_name like '%t1%';
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
--sorted_result
SELECT table_name, index_name, stat_name, stat_value>0
FROM mysql.innodb_index_stats;
--echo # Clean up
DROP TABLE t2;
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
--disable_query_log
EVAL SET GLOBAL innodb_defragment_stats_accuracy = $innodb_defragment_stats_accuracy_orig;
--enable_query_log
SELECT * FROM mysql.innodb_index_stats;
......@@ -5,6 +5,7 @@
# --source include/innodb_page_size.inc
--source include/innodb_page_size_small.inc
--source include/have_undo_tablespaces.inc
--source include/have_sequence.inc
SET @save_undo_logs = @@GLOBAL.innodb_undo_logs;
SET @save_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
......@@ -25,37 +26,14 @@ WHERE variable_name = 'innodb_undo_truncations');
create table t1(keyc int primary key, c char(100)) engine = innodb;
create table t2(keyc int primary key, c char(100)) engine = innodb;
#
delimiter |;
CREATE PROCEDURE populate_t1()
BEGIN
DECLARE i INT DEFAULT 1;
while (i <= 20000) DO
insert into t1 values (i, 'a');
SET i = i + 1;
END WHILE;
END |
delimiter ;|
#
delimiter |;
CREATE PROCEDURE populate_t2()
BEGIN
DECLARE i INT DEFAULT 1;
while (i <= 20000) DO
insert into t2 values (i, 'a');
SET i = i + 1;
END WHILE;
END |
delimiter ;|
#
#
let DATADIR = `select @@datadir`;
connect (con1,localhost,root,,);
begin;
send call populate_t1();
send insert into t1 select seq,'a' from seq_1_to_20000;
connect (con2,localhost,root,,);
begin;
send call populate_t2();
send insert into t2 select seq,'a' from seq_1_to_20000;
connection con1; reap; send update t1 set c = 'mysql';
connection con2; reap; send update t2 set c = 'mysql';
......@@ -65,25 +43,12 @@ connection con1; reap; send delete from t1;
connection con2; reap; delete from t2;
connection con1; reap;
let CHECKFILE = $MYSQL_TMP_DIR/check.txt;
perl;
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
= stat("$ENV{DATADIR}/undo001");
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
= stat("$ENV{DATADIR}/undo002");
open(OUT, ">$ENV{CHECKFILE}") || die;
print OUT "let \$size1='$size1,$size2';\n";
close(OUT);
EOF
SET GLOBAL innodb_undo_log_truncate = 1;
commit; disconnect con1;
connection con2; commit; disconnect con2;
connection default;
drop table t1, t2;
drop PROCEDURE populate_t1;
drop PROCEDURE populate_t2;
--source include/wait_all_purged.inc
......@@ -98,29 +63,6 @@ if (`select @@innodb_page_size IN (4096,8192,16384)`)
source include/wait_condition.inc;
}
--source $CHECKFILE
perl;
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size1)
= stat("$ENV{DATADIR}/undo001");
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size2)
= stat("$ENV{DATADIR}/undo002");
open(OUT, ">$ENV{CHECKFILE}") || die;
print OUT "let \$size2='$size1,$size2';\n";
close(OUT);
EOF
--source $CHECKFILE
--remove_file $CHECKFILE
if ($size1 == $size2)
{
# This fails for innodb_page_size=64k, occasionally also for 32k.
if (`select @@innodb_page_size IN (4096,8192,16384)`)
{
echo Truncation did not happen: $size1;
}
}
SET GLOBAL innodb_undo_logs = @save_undo_logs;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
SET GLOBAL innodb_undo_log_truncate = @save_truncate;
......@@ -949,8 +949,10 @@ then
tmpdir=$(parse_cnf "$encgroups" 'tmpdir')
if [ -z "$tmpdir" ]; then
xtmpdir="$(mktemp -d)"
else
elif [ "$OS" = 'Linux' ]; then
xtmpdir=$(mktemp '-d' "--tmpdir=$tmpdir")
else
xtmpdir=$(TMPDIR="$tmpdir"; mktemp '-d')
fi
wsrep_log_info "Using '$xtmpdir' as mariabackup temporary directory"
......
......@@ -725,8 +725,10 @@ EOF
tmpdir=$(parse_cnf '--mysqld|sst' 'tmpdir')
if [ -z "$tmpdir" ]; then
tmpfile="$(mktemp)"
else
elif [ "$OS" = 'Linux' ]; then
tmpfile=$(mktemp "--tmpdir=$tmpdir")
else
tmpfile=$(TMPDIR="$tmpdir"; mktemp '-d')
fi
wsrep_log_info "Extracting binlog files:"
......
......@@ -74,6 +74,9 @@
/* warning C4065: switch statement contains 'default' but no 'case' labels */
#pragma warning (disable : 4065)
#endif
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-label" /* yyexhaustedlab: */
#endif
 
int yylex(void *yylval, void *yythd);
 
......
......@@ -74,6 +74,9 @@
/* warning C4065: switch statement contains 'default' but no 'case' labels */
#pragma warning (disable : 4065)
#endif
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-label" /* yyexhaustedlab: */
#endif
 
int yylex(void *yylval, void *yythd);
 
......
......@@ -309,6 +309,7 @@ btr_defragment_save_defrag_stats_if_needed(
{
if (srv_defragment_stats_accuracy != 0 // stats tracking disabled
&& index->table->space_id != 0 // do not track system tables
&& !index->table->is_temporary()
&& index->stat_defrag_modified_counter
>= srv_defragment_stats_accuracy) {
dict_stats_defrag_pool_add(index);
......
......@@ -858,11 +858,13 @@ fsp_try_extend_data_file(fil_space_t* space, fsp_header_t* header, mtr_t* mtr)
return(0);
}
/* We ignore any fragments of a full megabyte when storing the size
to the space header */
/* For the system tablespace, we ignore any fragments of a
full megabyte when storing the size to the space header */
space->size_in_header = ut_2pow_round(
space->size, (1024 * 1024) / page_size.physical());
space->size_in_header = space->id
? space->size
: ut_2pow_round(space->size,
(1024 * 1024) / page_size.physical());
mlog_write_ulint(
header + FSP_SIZE, space->size_in_header, MLOG_4BYTES, mtr);
......@@ -1294,7 +1296,7 @@ fsp_alloc_free_page(
/* It must be that we are extending a single-table tablespace
whose size is still < 64 pages */
ut_a(!is_system_tablespace(space_id));
ut_a(!is_predefined_tablespace(space_id));
if (page_no >= FSP_EXTENT_SIZE) {
ib::error() << "Trying to extend a single-table"
" tablespace " << space->name << " , by single"
......@@ -2381,14 +2383,14 @@ fseg_alloc_free_page_low(
return(NULL);
}
if (space->size <= ret_page && !is_system_tablespace(space_id)) {
if (space->size <= ret_page && !is_predefined_tablespace(space_id)) {
/* It must be that we are extending a single-table
tablespace whose size is still < 64 pages */
if (ret_page >= FSP_EXTENT_SIZE) {
ib::error() << "Error (2): trying to extend"
" a single-table tablespace " << space_id
<< " by single page(s) though the"
ib::error() << "Trying to extend '"
<< space->chain.start->name
<< "' by single page(s) though the"
<< " space size " << space->size
<< ". Page no " << ret_page << ".";
ut_ad(!has_done_reservation);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment