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

Merge 11.0 into 11.1

This commit is contained in:
Marko Mäkelä
2023-07-04 08:20:55 +03:00
47 changed files with 401 additions and 141 deletions

View File

@@ -2068,9 +2068,16 @@ get_one_option(const struct my_option *opt, const char *argument,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
case 'I': case 'I':
case '?': case '?':

View File

@@ -321,9 +321,16 @@ get_one_option(const struct my_option *opt, const char *argument,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
} }
return 0; return 0;

View File

@@ -2162,9 +2162,16 @@ get_one_option(const struct my_option *opt, const char *argument,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
case 'v': case 'v':
if (argument == disabled_my_option) if (argument == disabled_my_option)

View File

@@ -379,9 +379,16 @@ get_one_option(const struct my_option *opt,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
} }

View File

@@ -1073,9 +1073,16 @@ get_one_option(const struct my_option *opt,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
} }
return 0; return 0;

View File

@@ -264,9 +264,16 @@ get_one_option(const struct my_option *opt, const char *argument,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
case '#': case '#':
DBUG_PUSH(argument ? argument : "d:t:o"); DBUG_PUSH(argument ? argument : "d:t:o");

View File

@@ -339,9 +339,16 @@ get_one_option(const struct my_option *opt, const char *argument,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
break; break;
case '#': case '#':

View File

@@ -777,9 +777,16 @@ get_one_option(const struct my_option *opt, const char *argument,
case 'S': case 'S':
if (filename[0] == '\0') if (filename[0] == '\0')
{ {
/* Socket given on command line, switch protocol to use SOCKETSt */ /*
Socket given on command line, switch protocol to use SOCKETSt
Except on Windows if 'protocol= pipe' has been provided in
the config file or command line.
*/
if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET; opt_protocol= MYSQL_PROTOCOL_SOCKET;
} }
}
break; break;
case '#': case '#':
DBUG_PUSH(argument ? argument : default_dbug_option); DBUG_PUSH(argument ? argument : default_dbug_option);

View File

@@ -57,10 +57,17 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version))); void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version)))) if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1; return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1)); res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
d2-= d1;
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2)); res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;

View File

@@ -57,10 +57,17 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version))); void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version)))) if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1; return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1)); res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
d2-= d1;
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2)); res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;

View File

@@ -57,10 +57,17 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version))); void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version)))) if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1; return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1)); res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
d2-= d1;
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2)); res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;

View File

@@ -96,8 +96,11 @@ struct st_mariadb_encryption
/** /**
processes (encrypts or decrypts) a chunk of data processes (encrypts or decrypts) a chunk of data
writes the output to th dst buffer. note that it might write writes the output to the dst buffer. note that it might write
more bytes that were in the input. or less. or none at all. more bytes that were in the input. or less. or none at all.
dlen points to the starting lenght of the output buffer. Upon return, it
should be set to the number of bytes written.
*/ */
int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen, int (*crypt_ctx_update)(void *ctx, const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen); unsigned char* dst, unsigned int* dlen);
@@ -123,4 +126,3 @@ struct st_mariadb_encryption
} }
#endif #endif
#endif #endif

View File

@@ -57,10 +57,17 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version))); void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version)))) if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1; return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1)); res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
d2-= d1;
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2)); res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;

View File

@@ -57,10 +57,17 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version))); void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version)))) if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1; return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1)); res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
d2-= d1;
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2)); res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;

View File

@@ -57,10 +57,17 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version))); void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version)))) if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1; return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1)); res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
d2-= d1;
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2)); res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;

View File

@@ -57,10 +57,17 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version))); void *ctx= alloca(encryption_handler.encryption_ctx_size_func((key_id),(key_version)));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version)))) if ((res1= encryption_handler.encryption_ctx_init_func((ctx),(key),(klen),(iv),(ivlen),(flags),(key_id),(key_version))))
return res1; return res1;
res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1)); res1= encryption_handler.encryption_ctx_update_func((ctx),(src),(slen),(dst),(&d1));
d2-= d1;
res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2)); res2= encryption_handler.encryption_ctx_finish_func((ctx),(dst + d1),(&d2));
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;

View File

@@ -36,6 +36,9 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#ifndef MYSQL_ABI_CHECK
#include <assert.h>
#endif
/* returned from encryption_key_get_latest_version() */ /* returned from encryption_key_get_latest_version() */
#define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0) #define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0)
@@ -101,6 +104,11 @@ static inline unsigned int encryption_key_version_exists(unsigned int id, unsign
return encryption_key_get(id, version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID; return encryption_key_get(id, version, NULL, &unused) != ENCRYPTION_KEY_VERSION_INVALID;
} }
/** main entrypoint to perform encryption or decryption
* @invariant `src` is valid for `slen`
* @invariant `dst` is valid for `*dlen`, `*dlen` is initialized
* @invariant `src` and `dst` do not overlap
*/
static inline int encryption_crypt(const unsigned char* src, unsigned int slen, static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen, unsigned char* dst, unsigned int* dlen,
const unsigned char* key, unsigned int klen, const unsigned char* key, unsigned int klen,
@@ -109,11 +117,23 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
{ {
void *ctx= alloca(encryption_ctx_size(key_id, key_version)); void *ctx= alloca(encryption_ctx_size(key_id, key_version));
int res1, res2; int res1, res2;
unsigned int d1, d2; unsigned int d1, d2= *dlen;
// Verify dlen is initialized properly. See MDEV-30389
assert(*dlen >= slen);
assert((dst[*dlen - 1]= 1));
// Verify buffers do not overlap
if (src < dst)
assert(src + slen <= dst);
else
assert(dst + *dlen <= src);
if ((res1= encryption_ctx_init(ctx, key, klen, iv, ivlen, flags, key_id, key_version))) if ((res1= encryption_ctx_init(ctx, key, klen, iv, ivlen, flags, key_id, key_version)))
return res1; return res1;
res1= encryption_ctx_update(ctx, src, slen, dst, &d1); res1= encryption_ctx_update(ctx, src, slen, dst, &d1);
d2-= d1;
res2= encryption_ctx_finish(ctx, dst + d1, &d2); res2= encryption_ctx_finish(ctx, dst + d1, &d2);
*dlen= d1 + d2; *dlen= d1 + d2;
return res1 ? res1 : res2; return res1 ? res1 : res2;
} }
@@ -124,4 +144,3 @@ static inline int encryption_crypt(const unsigned char* src, unsigned int slen,
#define MYSQL_SERVICE_ENCRYPTION_INCLUDED #define MYSQL_SERVICE_ENCRYPTION_INCLUDED
#endif #endif

View File

@@ -12,6 +12,12 @@ Connection: localhost via named pipe
# exec MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:" # exec MYSQL --host=localhost -W -e "status" 2>&1 | findstr /c:"Connection:"
Connection: localhost via named pipe Connection: localhost via named pipe
# exec MYSQL --host=localhost -W --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" # exec MYSQL --host=localhost -W --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:"
Connection: localhost via TCP/IP Connection: localhost via named pipe
# exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" # exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:"
Connection: localhost via TCP/IP Connection: localhost via TCP/IP
#
# MDEV-30639: Upgrade to 10.8 and later does not work on Windows
# due to connection protocol overwrite
#
# exec MYSQL --host=localhost --protocol=pipe --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:"
Connection: localhost via named pipe

View File

@@ -25,3 +25,10 @@
--echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" --echo # exec MYSQL --host=localhost --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:"
--exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:" --exec $MYSQL --host=localhost --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:"
--echo #
--echo # MDEV-30639: Upgrade to 10.8 and later does not work on Windows
--echo # due to connection protocol overwrite
--echo #
--echo # exec MYSQL --host=localhost --protocol=pipe --socket=MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:"
--exec $MYSQL --host=localhost --protocol=pipe --socket=$MASTER_MYSOCK -e "status" 2>&1 | findstr /c:"Connection:"

View File

@@ -1,18 +1,22 @@
SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB; CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000))
ENGINE=InnoDB STATS_PERSISTENT=0;
INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023; INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023;
connect con1,localhost,root,,; connect con1,localhost,root,,;
InnoDB 0 transactions not purged InnoDB 0 transactions not purged
START TRANSACTION WITH CONSISTENT SNAPSHOT; START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection default; connection default;
DELETE FROM t1 WHERE id=1788; DELETE FROM t1 WHERE id=1788;
SET @saved_dbug = @@GLOBAL.debug_dbug;
SET @@GLOBAL.debug_dbug="d,enable_row_purge_del_mark_exit_sync_point";
BEGIN; BEGIN;
SELECT * FROM t1 WHERE id=1788 FOR UPDATE; SELECT * FROM t1 WHERE id=1788 FOR UPDATE;
id val id val
connection con1; connection con1;
COMMIT; COMMIT;
InnoDB 0 transactions not purged SET DEBUG_SYNC = 'now WAIT_FOR row_purge_del_mark_finished';
SET @@GLOBAL.debug_dbug = @saved_dbug;
connection default; connection default;
INSERT INTO t1 (id,val) VALUES (1787, REPEAT('x',2000)); INSERT INTO t1 (id,val) VALUES (1787, REPEAT('x',2000));
connection con1; connection con1;

View File

@@ -14,7 +14,6 @@ WHERE TABLE_NAME LIKE '%infoschema_buffer_test%' AND PAGE_TYPE='index';
POOL_ID BLOCK_ID SPACE PAGE_NUMBER PAGE_TYPE FLUSH_TYPE FIX_COUNT IS_HASHED NEWEST_MODIFICATION OLDEST_MODIFICATION ACCESS_TIME TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE COMPRESSED_SIZE PAGE_STATE IO_FIX IS_OLD FREE_PAGE_CLOCK POOL_ID BLOCK_ID SPACE PAGE_NUMBER PAGE_TYPE FLUSH_TYPE FIX_COUNT IS_HASHED NEWEST_MODIFICATION OLDEST_MODIFICATION ACCESS_TIME TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE COMPRESSED_SIZE PAGE_STATE IO_FIX IS_OLD FREE_PAGE_CLOCK
0 # # 3 INDEX 0 FIX AHI LSN LSN TIME `test`.`infoschema_buffer_test` GEN_CLUST_INDEX 2 58 0 FILE_PAGE IO_FIX OLD # 0 # # 3 INDEX 0 FIX AHI LSN LSN TIME `test`.`infoschema_buffer_test` GEN_CLUST_INDEX 2 58 0 FILE_PAGE IO_FIX OLD #
0 # # 4 INDEX 0 FIX AHI LSN LSN TIME `test`.`infoschema_buffer_test` idx 2 32 0 FILE_PAGE IO_FIX OLD # 0 # # 4 INDEX 0 FIX AHI LSN LSN TIME `test`.`infoschema_buffer_test` idx 2 32 0 FILE_PAGE IO_FIX OLD #
0 # # 5 INDEX 0 FIX AHI LSN LSN TIME `test`.`infoschema_buffer_test` idx 2 32 0 FILE_PAGE IO_FIX OLD #
DROP TABLE infoschema_buffer_test; DROP TABLE infoschema_buffer_test;
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME LIKE '%infoschema_buffer_test%'; WHERE TABLE_NAME LIKE '%infoschema_buffer_test%';

View File

@@ -460,3 +460,10 @@ ERROR HY000: Got error 1 "Operation not permitted" during COMMIT
COMMIT; COMMIT;
DROP TABLE t1; DROP TABLE t1;
# End of 10.8 tests # End of 10.8 tests
#
# MDEV-31537 Bulk insert operation aborts the server
# for redundant table
#
CREATE TABLE t (a CHAR CHARACTER SET utf8) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT t SELECT left(seq,1) FROM seq_1_to_43691;
DROP TABLE t;

View File

@@ -1,11 +1,13 @@
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_sequence.inc --source include/have_sequence.inc
--source include/have_debug.inc --source include/have_debug.inc
--source include/have_debug_sync.inc
SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency; SET @save_frequency=@@GLOBAL.innodb_purge_rseg_truncate_frequency;
SET GLOBAL innodb_purge_rseg_truncate_frequency=1; SET GLOBAL innodb_purge_rseg_truncate_frequency=1;
CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000)) ENGINE=InnoDB; CREATE TABLE t1(id INT PRIMARY key, val VARCHAR(16000))
ENGINE=InnoDB STATS_PERSISTENT=0;
INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023; INSERT INTO t1 (id,val) SELECT 2*seq,'x' FROM seq_0_to_1023;
connect(con1,localhost,root,,); connect(con1,localhost,root,,);
@@ -16,13 +18,18 @@ connection default;
DELETE FROM t1 WHERE id=1788; DELETE FROM t1 WHERE id=1788;
SET @saved_dbug = @@GLOBAL.debug_dbug;
SET @@GLOBAL.debug_dbug="d,enable_row_purge_del_mark_exit_sync_point";
BEGIN; BEGIN;
# This will return no result, but should acquire a gap lock. # This will return no result, but should acquire a gap lock.
SELECT * FROM t1 WHERE id=1788 FOR UPDATE; SELECT * FROM t1 WHERE id=1788 FOR UPDATE;
connection con1; connection con1;
COMMIT; COMMIT;
source include/wait_all_purged.inc; SET DEBUG_SYNC = 'now WAIT_FOR row_purge_del_mark_finished';
SET @@GLOBAL.debug_dbug = @saved_dbug;
connection default; connection default;
INSERT INTO t1 (id,val) VALUES (1787, REPEAT('x',2000)); INSERT INTO t1 (id,val) VALUES (1787, REPEAT('x',2000));

View File

@@ -479,3 +479,11 @@ INSERT INTO t1 VALUES
COMMIT; COMMIT;
DROP TABLE t1; DROP TABLE t1;
--echo # End of 10.8 tests --echo # End of 10.8 tests
--echo #
--echo # MDEV-31537 Bulk insert operation aborts the server
--echo # for redundant table
--echo #
CREATE TABLE t (a CHAR CHARACTER SET utf8) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT t SELECT left(seq,1) FROM seq_1_to_43691;
DROP TABLE t;

View File

@@ -248,3 +248,17 @@ SELECT NEXTVAL(s);
NEXTVAL(s) NEXTVAL(s)
1 1
DROP SEQUENCE s; DROP SEQUENCE s;
#
# MDEV-31607 ER_DUP_KEY in mysql.table_stats upon REANME on sequence
#
CREATE SEQUENCE s1 ENGINE=InnoDB;
CREATE SEQUENCE s2 ENGINE=InnoDB;
SHOW CREATE SEQUENCE s1;
Table Create Table
s1 CREATE SEQUENCE `s1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB
SHOW CREATE SEQUENCE s2;
Table Create Table
s2 CREATE SEQUENCE `s2` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB
DROP SEQUENCE s2;
RENAME TABLE s1 TO s2;
DROP SEQUENCE s2;

View File

@@ -161,3 +161,15 @@ CREATE SEQUENCE s;
ALTER TABLE s ORDER BY cache_size; ALTER TABLE s ORDER BY cache_size;
SELECT NEXTVAL(s); SELECT NEXTVAL(s);
DROP SEQUENCE s; DROP SEQUENCE s;
--echo #
--echo # MDEV-31607 ER_DUP_KEY in mysql.table_stats upon REANME on sequence
--echo #
CREATE SEQUENCE s1 ENGINE=InnoDB;
CREATE SEQUENCE s2 ENGINE=InnoDB;
SHOW CREATE SEQUENCE s1;
SHOW CREATE SEQUENCE s2;
DROP SEQUENCE s2;
RENAME TABLE s1 TO s2;
DROP SEQUENCE s2;

View File

@@ -187,6 +187,10 @@ ret:
return rc; return rc;
} }
/** Run encryption or decryption on a block.
* `i32_1`, `i32_2`, and `i64` are used to create the initialization vector
* @invariant `src` and `dst` invariants are the same as in `encryption_crypt`
*/
int do_crypt(const unsigned char* src, unsigned int slen, int do_crypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen, unsigned char* dst, unsigned int* dlen,
struct st_encryption_scheme *scheme, struct st_encryption_scheme *scheme,
@@ -224,6 +228,10 @@ int do_crypt(const unsigned char* src, unsigned int slen,
iv, sizeof(iv), flag, scheme->key_id, key_version); iv, sizeof(iv), flag, scheme->key_id, key_version);
} }
/** Encrypt a block.
* `i32_1`, `i32_2`, and `i64` are used to create the initialization vector
* @invariant `src` and `dst` invariants are the same as in `encryption_crypt`
*/
int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen, int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen, unsigned char* dst, unsigned int* dlen,
struct st_encryption_scheme *scheme, struct st_encryption_scheme *scheme,
@@ -234,7 +242,10 @@ int encryption_scheme_encrypt(const unsigned char* src, unsigned int slen,
i32_2, i64, ENCRYPTION_FLAG_NOPAD | ENCRYPTION_FLAG_ENCRYPT); i32_2, i64, ENCRYPTION_FLAG_NOPAD | ENCRYPTION_FLAG_ENCRYPT);
} }
/** Decrypt a block.
* `i32_1`, `i32_2`, and `i64` are used to create the initialization vector
* @invariant `src` and `dst` invariants are the same as in `encryption_crypt`
*/
int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen, int encryption_scheme_decrypt(const unsigned char* src, unsigned int slen,
unsigned char* dst, unsigned int* dlen, unsigned char* dst, unsigned int* dlen,
struct st_encryption_scheme *scheme, struct st_encryption_scheme *scheme,

View File

@@ -5662,7 +5662,7 @@ bool MYSQL_BIN_LOG::write_event_buffer(uchar* buf, uint len)
{ {
DBUG_ASSERT(crypto.scheme == 1); DBUG_ASSERT(crypto.scheme == 1);
uint elen; uint elen= len - 4;
uchar iv[BINLOG_IV_LENGTH]; uchar iv[BINLOG_IV_LENGTH];
ebuf= (uchar*)my_safe_alloca(len); ebuf= (uchar*)my_safe_alloca(len);

View File

@@ -838,7 +838,7 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet,
DBUG_RETURN(LOG_READ_MEM); DBUG_RETURN(LOG_READ_MEM);
memcpy(newpkt, packet->ptr(), ev_offset); memcpy(newpkt, packet->ptr(), ev_offset);
uint dstlen; uint dstlen= (uint) sz - ev_offset - 4;
uchar *src= (uchar*)packet->ptr() + ev_offset; uchar *src= (uchar*)packet->ptr() + ev_offset;
uchar *dst= (uchar*)newpkt + ev_offset; uchar *dst= (uchar*)newpkt + ev_offset;
memcpy(src + EVENT_LEN_OFFSET, src, 4); memcpy(src + EVENT_LEN_OFFSET, src, 4);

View File

@@ -85,7 +85,8 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
do do
{ {
uint elength, wlength, length; uint elength, wlength;
uint length= static_cast<uint>(info->buffer_length);
uchar iv[MY_AES_BLOCK_SIZE]= {0}; uchar iv[MY_AES_BLOCK_SIZE]= {0};
DBUG_ASSERT(pos_in_file % info->buffer_length == 0); DBUG_ASSERT(pos_in_file % info->buffer_length == 0);
@@ -102,6 +103,7 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count)
} }
elength= wlength - (uint)(ebuffer - wbuffer); elength= wlength - (uint)(ebuffer - wbuffer);
length= elength;
set_iv(iv, pos_in_file, crypt_data->inbuf_counter); set_iv(iv, pos_in_file, crypt_data->inbuf_counter);
if (encryption_crypt(ebuffer, elength, info->buffer, &length, if (encryption_crypt(ebuffer, elength, info->buffer, &length,
@@ -181,8 +183,9 @@ static int my_b_encr_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
do do
{ {
uint wlength;
size_t length= MY_MIN(info->buffer_length, Count); size_t length= MY_MIN(info->buffer_length, Count);
uint elength, wlength; uint elength= static_cast<uint>(length);
uchar iv[MY_AES_BLOCK_SIZE]= {0}; uchar iv[MY_AES_BLOCK_SIZE]= {0};
crypt_data->inbuf_counter= crypt_data->counter; crypt_data->inbuf_counter= crypt_data->counter;
@@ -272,4 +275,3 @@ int init_io_cache_encryption()
_my_b_encr_write= 0; _my_b_encr_write= 0;
return 0; return 0;
} }

View File

@@ -4673,8 +4673,6 @@ class btr_est_cur_t
page_id_t m_page_id; page_id_t m_page_id;
/** Current block */ /** Current block */
buf_block_t *m_block; buf_block_t *m_block;
/** mtr savepoint of the current block */
ulint m_savepoint;
/** Page search mode, can differ from m_mode for non-leaf pages, see c-tor /** Page search mode, can differ from m_mode for non-leaf pages, see c-tor
comments for details */ comments for details */
page_cur_mode_t m_page_mode; page_cur_mode_t m_page_mode;
@@ -4733,7 +4731,6 @@ public:
bool fetch_child(ulint level, mtr_t &mtr, const buf_block_t *right_parent) bool fetch_child(ulint level, mtr_t &mtr, const buf_block_t *right_parent)
{ {
buf_block_t *parent_block= m_block; buf_block_t *parent_block= m_block;
ulint parent_savepoint= m_savepoint;
m_block= btr_block_get(*index(), m_page_id.page_no(), RW_S_LATCH, m_block= btr_block_get(*index(), m_page_id.page_no(), RW_S_LATCH,
&mtr, nullptr); &mtr, nullptr);
@@ -4741,9 +4738,10 @@ public:
return false; return false;
if (parent_block && parent_block != right_parent) if (parent_block && parent_block != right_parent)
mtr.rollback_to_savepoint(parent_savepoint, parent_savepoint + 1); {
ut_ad(mtr.get_savepoint() >= 2);
m_savepoint= mtr.get_savepoint() - 1; mtr.rollback_to_savepoint(1, 2);
}
return level == ULINT_UNDEFINED || return level == ULINT_UNDEFINED ||
btr_page_get_level(m_block->page.frame) == level; btr_page_get_level(m_block->page.frame) == level;
@@ -4805,10 +4803,10 @@ public:
return true; return true;
} }
/** Gets page id of the current record child. /** Read page id of the current record child.
@param offsets offsets array. @param offsets offsets array.
@param heap heap for offsets array */ @param heap heap for offsets array */
void get_child(rec_offs **offsets, mem_heap_t **heap) void read_child_page_id(rec_offs **offsets, mem_heap_t **heap)
{ {
const rec_t *node_ptr= page_cur_get_rec(&m_page_cur); const rec_t *node_ptr= page_cur_get_rec(&m_page_cur);
@@ -4878,11 +4876,7 @@ public:
/** Copies block pointer and savepoint from another btr_est_cur_t in the case /** Copies block pointer and savepoint from another btr_est_cur_t in the case
if both left and right border cursors point to the same block. if both left and right border cursors point to the same block.
@param o reference to the other btr_est_cur_t object. */ @param o reference to the other btr_est_cur_t object. */
void set_block(const btr_est_cur_t &o) void set_block(const btr_est_cur_t &o) { m_block= o.m_block; }
{
m_block= o.m_block;
m_savepoint= o.m_savepoint;
}
/** @return current record number. */ /** @return current record number. */
ulint nth_rec() const { return m_nth_rec; } ulint nth_rec() const { return m_nth_rec; }
@@ -4921,7 +4915,6 @@ static ha_rows btr_estimate_n_rows_in_range_on_level(
pages before reaching right_page_no, then we estimate the average from the pages before reaching right_page_no, then we estimate the average from the
pages scanned so far. */ pages scanned so far. */
static constexpr uint n_pages_read_limit= 9; static constexpr uint n_pages_read_limit= 9;
ulint savepoint= 0;
buf_block_t *block= nullptr; buf_block_t *block= nullptr;
const dict_index_t *index= left_cur.index(); const dict_index_t *index= left_cur.index();
@@ -4951,18 +4944,17 @@ static ha_rows btr_estimate_n_rows_in_range_on_level(
{ {
page_t *page; page_t *page;
buf_block_t *prev_block= block; buf_block_t *prev_block= block;
ulint prev_savepoint= savepoint;
savepoint= mtr.get_savepoint();
/* Fetch the page. */ /* Fetch the page. */
block= btr_block_get(*index, page_id.page_no(), RW_S_LATCH, &mtr, nullptr); block= btr_block_get(*index, page_id.page_no(), RW_S_LATCH, &mtr, nullptr);
if (prev_block) if (prev_block)
{ {
mtr.rollback_to_savepoint(prev_savepoint, prev_savepoint + 1); ulint savepoint = mtr.get_savepoint();
if (block) /* Index s-lock, p1, p2 latches, can also be p1 and p2 parent latch if
savepoint--; they are not diverged */
ut_ad(savepoint >= 3);
mtr.rollback_to_savepoint(savepoint - 2, savepoint - 1);
} }
if (!block || btr_page_get_level(buf_block_get_frame(block)) != level) if (!block || btr_page_get_level(buf_block_get_frame(block)) != level)
@@ -4993,8 +4985,8 @@ static ha_rows btr_estimate_n_rows_in_range_on_level(
if (block) if (block)
{ {
ut_ad(block == mtr.at_savepoint(savepoint)); ut_ad(block == mtr.at_savepoint(mtr.get_savepoint() - 1));
mtr.rollback_to_savepoint(savepoint, savepoint + 1); mtr.rollback_to_savepoint(mtr.get_savepoint() - 1);
} }
return (n_rows); return (n_rows);
@@ -5003,8 +4995,8 @@ inexact:
if (block) if (block)
{ {
ut_ad(block == mtr.at_savepoint(savepoint)); ut_ad(block == mtr.at_savepoint(mtr.get_savepoint() - 1));
mtr.rollback_to_savepoint(savepoint, savepoint + 1); mtr.rollback_to_savepoint(mtr.get_savepoint() - 1);
} }
is_n_rows_exact= false; is_n_rows_exact= false;
@@ -5198,8 +5190,12 @@ search_loop:
{ {
ut_ad(height > 0); ut_ad(height > 0);
height--; height--;
p1.get_child(&offsets, &heap); ut_ad(mtr.memo_contains(p1.index()->lock, MTR_MEMO_S_LOCK));
p2.get_child(&offsets, &heap); ut_ad(mtr.memo_contains_flagged(p1.block(), MTR_MEMO_PAGE_S_FIX));
p1.read_child_page_id(&offsets, &heap);
ut_ad(mtr.memo_contains(p2.index()->lock, MTR_MEMO_S_LOCK));
ut_ad(mtr.memo_contains_flagged(p2.block(), MTR_MEMO_PAGE_S_FIX));
p2.read_child_page_id(&offsets, &heap);
goto search_loop; goto search_loop;
} }

View File

@@ -2105,14 +2105,13 @@ static bool ha_validate(const hash_table_t *table,
} }
/** Validates the search system for given hash table. /** Validates the search system for given hash table.
@param[in] hash_table_id hash table to validate @param thd connection, for checking if CHECK TABLE has been killed
@return TRUE if ok */ @param hash_table_id hash table to validate
static @return true if ok */
ibool static bool btr_search_hash_table_validate(THD *thd, ulint hash_table_id)
btr_search_hash_table_validate(ulint hash_table_id)
{ {
ha_node_t* node; ha_node_t* node;
ibool ok = TRUE; bool ok = true;
ulint i; ulint i;
ulint cell_count; ulint cell_count;
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
@@ -2120,9 +2119,15 @@ btr_search_hash_table_validate(ulint hash_table_id)
rec_offs* offsets = offsets_; rec_offs* offsets = offsets_;
btr_search_x_lock_all(); btr_search_x_lock_all();
if (!btr_search_enabled) { if (!btr_search_enabled || (thd && thd_kill_level(thd))) {
func_exit:
btr_search_x_unlock_all(); btr_search_x_unlock_all();
return(TRUE);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return ok;
} }
/* How many cells to check before temporarily releasing /* How many cells to check before temporarily releasing
@@ -2149,8 +2154,8 @@ btr_search_hash_table_validate(ulint hash_table_id)
btr_search_x_lock_all(); btr_search_x_lock_all();
if (!btr_search_enabled) { if (!btr_search_enabled
ok = true; || (thd && thd_kill_level(thd))) {
goto func_exit; goto func_exit;
} }
@@ -2256,8 +2261,8 @@ state_ok:
btr_search_x_lock_all(); btr_search_x_lock_all();
if (!btr_search_enabled) { if (!btr_search_enabled
ok = true; || (thd && thd_kill_level(thd))) {
goto func_exit; goto func_exit;
} }
@@ -2278,33 +2283,23 @@ state_ok:
ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1); ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1);
if (!ha_validate(&part.table, i, end_index)) { if (!ha_validate(&part.table, i, end_index)) {
ok = FALSE; ok = false;
} }
} }
mysql_mutex_unlock(&buf_pool.mutex); mysql_mutex_unlock(&buf_pool.mutex);
func_exit: goto func_exit;
btr_search_x_unlock_all();
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(ok);
} }
/** Validate the search system. /** Validates the search system.
@return true if ok. */ @param thd connection, for checking if CHECK TABLE has been killed
bool @return true if ok */
btr_search_validate() bool btr_search_validate(THD *thd)
{ {
for (ulint i = 0; i < btr_ahi_parts; ++i) { for (ulint i= 0; i < btr_ahi_parts; ++i)
if (!btr_search_hash_table_validate(i)) { if (!btr_search_hash_table_validate(thd, i))
return(false); return(false);
} return true;
}
return(true);
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG

View File

@@ -1863,8 +1863,7 @@ inline void log_t::write_checkpoint(lsn_t end_lsn) noexcept
ib::info() << "Resized log to " << ib::bytes_iec{resizing_completed} ib::info() << "Resized log to " << ib::bytes_iec{resizing_completed}
<< "; start LSN=" << resizing; << "; start LSN=" << resizing;
else else
sql_print_error("InnoDB: Resize of log failed at " LSN_PF, buf_flush_ahead(end_lsn + 1, false);
get_flushed_lsn());
} }
/** Initiate a log checkpoint, discarding the start of the log. /** Initiate a log checkpoint, discarding the start of the log.

View File

@@ -445,11 +445,11 @@ static byte* fil_encrypt_buf_for_non_full_checksum(
uint srclen = size - unencrypted_bytes; uint srclen = size - unencrypted_bytes;
const byte* src = src_frame + header_len; const byte* src = src_frame + header_len;
byte* dst = dst_frame + header_len; byte* dst = dst_frame + header_len;
uint32 dstlen = 0;
if (page_compressed) { if (page_compressed) {
srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA); srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA);
} }
uint dstlen = srclen;
int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen, int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen,
crypt_data, key_version, crypt_data, key_version,
@@ -516,7 +516,7 @@ static byte* fil_encrypt_buf_for_full_crc32(
+ FIL_PAGE_FCRC32_CHECKSUM); + FIL_PAGE_FCRC32_CHECKSUM);
const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
byte* dst = dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; byte* dst = dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
uint dstlen = 0; uint dstlen = srclen;
ut_a(key_version != ENCRYPTION_KEY_VERSION_INVALID); ut_a(key_version != ENCRYPTION_KEY_VERSION_INVALID);
@@ -647,7 +647,6 @@ static dberr_t fil_space_decrypt_full_crc32(
/* Calculate the offset where decryption starts */ /* Calculate the offset where decryption starts */
const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
byte* dst = tmp_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION; byte* dst = tmp_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
uint dstlen = 0;
bool corrupted = false; bool corrupted = false;
uint size = buf_page_full_crc32_size(src_frame, NULL, &corrupted); uint size = buf_page_full_crc32_size(src_frame, NULL, &corrupted);
if (UNIV_UNLIKELY(corrupted)) { if (UNIV_UNLIKELY(corrupted)) {
@@ -656,6 +655,7 @@ static dberr_t fil_space_decrypt_full_crc32(
uint srclen = size - (FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION uint srclen = size - (FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ FIL_PAGE_FCRC32_CHECKSUM); + FIL_PAGE_FCRC32_CHECKSUM);
uint dstlen = srclen;
int rc = encryption_scheme_decrypt(src, srclen, dst, &dstlen, int rc = encryption_scheme_decrypt(src, srclen, dst, &dstlen,
crypt_data, key_version, crypt_data, key_version,
@@ -711,8 +711,8 @@ static dberr_t fil_space_decrypt_for_non_full_checksum(
/* Calculate the offset where decryption starts */ /* Calculate the offset where decryption starts */
const byte* src = src_frame + header_len; const byte* src = src_frame + header_len;
byte* dst = tmp_frame + header_len; byte* dst = tmp_frame + header_len;
uint32 dstlen = 0;
uint srclen = uint(physical_size) - header_len - FIL_PAGE_DATA_END; uint srclen = uint(physical_size) - header_len - FIL_PAGE_DATA_END;
uint dstlen = srclen;
if (page_compressed) { if (page_compressed) {
srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA); srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA);

View File

@@ -13635,13 +13635,12 @@ err_exit:
} }
if (!table->no_rollback()) if (!table->no_rollback())
{
err= trx->drop_table_foreign(table->name); err= trx->drop_table_foreign(table->name);
if (err == DB_SUCCESS && table_stats && index_stats) if (err == DB_SUCCESS && table_stats && index_stats)
err= trx->drop_table_statistics(table->name); err= trx->drop_table_statistics(table->name);
if (err != DB_SUCCESS) if (err != DB_SUCCESS)
goto err_exit; goto err_exit;
}
err= trx->drop_table(*table); err= trx->drop_table(*table);
if (err != DB_SUCCESS) if (err != DB_SUCCESS)
@@ -15256,7 +15255,8 @@ ha_innobase::check(
/* We validate the whole adaptive hash index for all tables /* We validate the whole adaptive hash index for all tables
at every CHECK TABLE only when QUICK flag is not present. */ at every CHECK TABLE only when QUICK flag is not present. */
if (!(check_opt->flags & T_QUICK) && !btr_search_validate()) { if (!(check_opt->flags & T_QUICK)
&& !btr_search_validate(m_prebuilt->trx->mysql_thd)) {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NOT_KEYFILE, ER_NOT_KEYFILE,
"InnoDB: The adaptive hash index is corrupted."); "InnoDB: The adaptive hash index is corrupted.");

View File

@@ -3870,7 +3870,7 @@ i_s_innodb_buffer_page_get_info(
page_info->state = bpage->state(); page_info->state = bpage->state();
if (page_info->state < buf_page_t::FREED) { if (page_info->state < buf_page_t::UNFIXED) {
page_info->page_type = I_S_PAGE_TYPE_UNKNOWN; page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
page_info->compressed_only = false; page_info->compressed_only = false;
} else { } else {

View File

@@ -127,8 +127,9 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor,
void btr_search_update_hash_on_delete(btr_cur_t *cursor); void btr_search_update_hash_on_delete(btr_cur_t *cursor);
/** Validates the search system. /** Validates the search system.
@param thd connection, for checking if CHECK TABLE has been killed
@return true if ok */ @return true if ok */
bool btr_search_validate(); bool btr_search_validate(THD *thd);
/** Lock all search latches in exclusive mode. */ /** Lock all search latches in exclusive mode. */
static inline void btr_search_x_lock_all(); static inline void btr_search_x_lock_all();

View File

@@ -84,7 +84,7 @@ void log_decrypt_buf(const byte *iv, byte *buf, const byte *const end);
/** Encrypt or decrypt a temporary file block. /** Encrypt or decrypt a temporary file block.
@param[in] src block to encrypt or decrypt @param[in] src block to encrypt or decrypt
@param[in] size size of the block @param[in] size length of both src and dst in bytes
@param[out] dst destination block @param[out] dst destination block
@param[in] offs offset to block @param[in] offs offset to block
@param[in] encrypt true=encrypt; false=decrypt @param[in] encrypt true=encrypt; false=decrypt
@@ -99,7 +99,7 @@ bool log_tmp_block_encrypt(
/** Decrypt a temporary file block. /** Decrypt a temporary file block.
@param[in] src block to decrypt @param[in] src block to decrypt
@param[in] size size of the block @param[in] size length of both src and dst in bytes
@param[out] dst destination block @param[out] dst destination block
@param[in] offs offset to block @param[in] offs offset to block
@return whether the operation succeeded */ @return whether the operation succeeded */

View File

@@ -221,9 +221,9 @@ ATTRIBUTE_COLD bool log_decrypt(byte* buf, lsn_t lsn, ulint size)
ut_ad(LOG_CRYPT_HDR_SIZE + dst_size ut_ad(LOG_CRYPT_HDR_SIZE + dst_size
== 512 - LOG_BLOCK_CHECKSUM - LOG_BLOCK_KEY); == 512 - LOG_BLOCK_CHECKSUM - LOG_BLOCK_KEY);
uint dst_len; uint dst_len = static_cast<uint>(dst_size);
int rc = encryption_crypt( int rc = encryption_crypt(
buf + LOG_CRYPT_HDR_SIZE, static_cast<uint>(dst_size), buf + LOG_CRYPT_HDR_SIZE, dst_len,
reinterpret_cast<byte*>(dst), &dst_len, reinterpret_cast<byte*>(dst), &dst_len,
const_cast<byte*>(info.crypt_key), const_cast<byte*>(info.crypt_key),
MY_AES_BLOCK_SIZE, MY_AES_BLOCK_SIZE,
@@ -332,10 +332,10 @@ ATTRIBUTE_COLD bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn)
} }
found: found:
byte dst[512]; byte dst[512];
uint dst_len;
byte aes_ctr_iv[MY_AES_BLOCK_SIZE]; byte aes_ctr_iv[MY_AES_BLOCK_SIZE];
const uint src_len = 512 - LOG_BLOCK_HDR_SIZE; const uint src_len = 512 - LOG_BLOCK_HDR_SIZE;
uint dst_len = src_len;
ulint log_block_no = log_block_get_hdr_no(buf); ulint log_block_no = log_block_get_hdr_no(buf);
@@ -429,7 +429,7 @@ ATTRIBUTE_COLD bool log_crypt_read_checkpoint_buf(const byte* buf)
/** Encrypt or decrypt a temporary file block. /** Encrypt or decrypt a temporary file block.
@param[in] src block to encrypt or decrypt @param[in] src block to encrypt or decrypt
@param[in] size size of the block @param[in] size length of both src and dst blocks in bytes
@param[out] dst destination block @param[out] dst destination block
@param[in] offs offset to block @param[in] offs offset to block
@param[in] encrypt true=encrypt; false=decrypt @param[in] encrypt true=encrypt; false=decrypt
@@ -441,7 +441,7 @@ bool log_tmp_block_encrypt(
uint64_t offs, uint64_t offs,
bool encrypt) bool encrypt)
{ {
uint dst_len; uint dst_len = static_cast<uint>(size);
uint64_t iv[MY_AES_BLOCK_SIZE / sizeof(uint64_t)]; uint64_t iv[MY_AES_BLOCK_SIZE / sizeof(uint64_t)];
iv[0] = offs; iv[0] = offs;
memcpy(iv + 1, tmp_iv, sizeof iv - sizeof *iv); memcpy(iv + 1, tmp_iv, sizeof iv - sizeof *iv);

View File

@@ -523,7 +523,14 @@ log_t::resize_start_status log_t::resize_start(os_offset_t size) noexcept
log_resize_release(); log_resize_release();
if (start_lsn) if (start_lsn)
{
mysql_mutex_lock(&buf_pool.flush_list_mutex);
lsn_t target_lsn= buf_pool.get_oldest_modification(0);
if (start_lsn < target_lsn)
start_lsn= target_lsn + 1;
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
buf_flush_ahead(start_lsn, false); buf_flush_ahead(start_lsn, false);
}
return status; return status;
} }

View File

@@ -239,6 +239,7 @@ struct fil_iterator_t {
byte* io_buffer; /*!< Buffer to use for IO */ byte* io_buffer; /*!< Buffer to use for IO */
fil_space_crypt_t *crypt_data; /*!< Crypt data (if encrypted) */ fil_space_crypt_t *crypt_data; /*!< Crypt data (if encrypted) */
byte* crypt_io_buffer; /*!< IO buffer when encrypted */ byte* crypt_io_buffer; /*!< IO buffer when encrypted */
byte* crypt_tmp_buffer; /*!< Temporary buffer for crypt use */
}; };
/** Use the page cursor to iterate over records in a block. */ /** Use the page cursor to iterate over records in a block. */
@@ -2985,17 +2986,25 @@ row_import_read_meta_data(
/* decrypt and decompress page if needed */ /* decrypt and decompress page if needed */
static dberr_t decrypt_decompress(fil_space_crypt_t *space_crypt, static dberr_t decrypt_decompress(fil_space_crypt_t *space_crypt,
uint32_t space_flags, span<byte> page, uint32_t space_flags, span<byte> page,
uint32_t space_id, byte *page_compress_buf) uint32_t space_id, byte *page_compress_buf,
byte *tmp_frame)
{ {
auto *data= page.data(); auto *data= page.data();
if (space_crypt && space_crypt->should_encrypt()) if (space_crypt && space_crypt->should_encrypt())
{ {
uint page_size= static_cast<uint>(page.size());
if (!buf_page_verify_crypt_checksum(data, space_flags)) if (!buf_page_verify_crypt_checksum(data, space_flags))
return DB_CORRUPTION; return DB_CORRUPTION;
if (dberr_t err= fil_space_decrypt(space_id, space_flags, space_crypt, dberr_t err=
data, page.size(), data)) fil_space_decrypt(space_id, space_flags, space_crypt,
tmp_frame, page_size, data);
memcpy(data, tmp_frame, page_size);
if (err)
return err; return err;
} }
@@ -3115,11 +3124,16 @@ static dberr_t handle_instant_metadata(dict_table_t *table,
return err; return err;
std::unique_ptr<byte[]> page_compress_buf(new byte[get_buf_size()]); std::unique_ptr<byte[]> page_compress_buf(new byte[get_buf_size()]);
std::unique_ptr<byte[], decltype(&aligned_free)> crypt_tmp_frame(
static_cast<byte *>(
aligned_malloc(physical_size, CPU_LEVEL1_DCACHE_LINESIZE)),
&aligned_free);
if (dberr_t err= decrypt_decompress(space_crypt, space_flags, if (dberr_t err= decrypt_decompress(space_crypt, space_flags,
{page.get(), static_cast<size_t> {page.get(), static_cast<size_t>
(physical_size)}, (physical_size)},
space_id, page_compress_buf.get())) space_id, page_compress_buf.get(),
crypt_tmp_frame.get()))
return err; return err;
if (table->supports_instant()) if (table->supports_instant())
@@ -3173,7 +3187,8 @@ static dberr_t handle_instant_metadata(dict_table_t *table,
if (dberr_t err= decrypt_decompress(space_crypt, space_flags, if (dberr_t err= decrypt_decompress(space_crypt, space_flags,
{page.get(), static_cast<size_t> {page.get(), static_cast<size_t>
(physical_size)}, space_id, (physical_size)}, space_id,
page_compress_buf.get())) page_compress_buf.get(),
crypt_tmp_frame.get()))
return err; return err;
} }
@@ -3255,7 +3270,8 @@ static dberr_t handle_instant_metadata(dict_table_t *table,
if (dberr_t err= decrypt_decompress(space_crypt, space_flags, if (dberr_t err= decrypt_decompress(space_crypt, space_flags,
{second_page.get(), {second_page.get(),
static_cast<size_t>(physical_size)}, static_cast<size_t>(physical_size)},
space_id, page_compress_buf.get())) space_id, page_compress_buf.get(),
crypt_tmp_frame.get()))
return err; return err;
if (fil_page_get_type(second_page.get()) != FIL_PAGE_TYPE_BLOB || if (fil_page_get_type(second_page.get()) != FIL_PAGE_TYPE_BLOB ||
@@ -3697,8 +3713,14 @@ page_corrupted:
if (!buf_page_verify_crypt_checksum(readptr, m_space_flags)) if (!buf_page_verify_crypt_checksum(readptr, m_space_flags))
goto page_corrupted; goto page_corrupted;
if ((err= fil_space_decrypt(get_space_id(), m_space_flags, iter.crypt_data, dberr_t err= fil_space_decrypt(get_space_id(), m_space_flags,
readptr, size, readptr))) iter.crypt_data, iter.crypt_tmp_buffer,
size, readptr);
memcpy_aligned<CPU_LEVEL1_DCACHE_LINESIZE>(readptr, iter.crypt_tmp_buffer,
size);
if (err)
goto func_exit; goto func_exit;
} }
@@ -4155,17 +4177,21 @@ fil_tablespace_iterate(
iter.file_size = file_size; iter.file_size = file_size;
iter.n_io_buffers = n_io_buffers; iter.n_io_buffers = n_io_buffers;
size_t buf_size = (1 + iter.n_io_buffers) * srv_page_size;
/* Add an extra page for compressed page scratch area. */ /* Add an extra page for compressed page scratch area. */
iter.io_buffer = static_cast<byte*>( iter.io_buffer = static_cast<byte*>(
aligned_malloc((1 + iter.n_io_buffers) aligned_malloc(buf_size, srv_page_size));
<< srv_page_size_shift, srv_page_size));
iter.crypt_io_buffer = iter.crypt_data if (iter.crypt_data) {
? static_cast<byte*>( iter.crypt_io_buffer = static_cast<byte *>(
aligned_malloc((1 + iter.n_io_buffers) aligned_malloc(buf_size, srv_page_size));
<< srv_page_size_shift, iter.crypt_tmp_buffer = static_cast<byte *>(
srv_page_size)) aligned_malloc(buf_size, CPU_LEVEL1_DCACHE_LINESIZE));
: NULL; } else {
iter.crypt_io_buffer = NULL;
iter.crypt_tmp_buffer = NULL;
}
if (block->page.zip.ssize) { if (block->page.zip.ssize) {
ut_ad(iter.n_io_buffers == 1); ut_ad(iter.n_io_buffers == 1);
@@ -4180,6 +4206,7 @@ fil_tablespace_iterate(
fil_space_destroy_crypt_data(&iter.crypt_data); fil_space_destroy_crypt_data(&iter.crypt_data);
} }
aligned_free(iter.crypt_tmp_buffer);
aligned_free(iter.crypt_io_buffer); aligned_free(iter.crypt_io_buffer);
aligned_free(iter.io_buffer); aligned_free(iter.io_buffer);
} }

View File

@@ -481,6 +481,13 @@ static ulint row_merge_bulk_buf_add(row_merge_buf_t* buf,
ulint fixed_len= ifield->fixed_len; ulint fixed_len= ifield->fixed_len;
/* CHAR in ROW_FORMAT=REDUNDANT is always
fixed-length, but in the temporary file it is
variable-length for variable-length character sets. */
if (fixed_len && !index->table->not_redundant() &&
col->mbminlen != col->mbmaxlen)
fixed_len= 0;
if (fixed_len); if (fixed_len);
else if (len < 128 || (!DATA_BIG_COL(col))) else if (len < 128 || (!DATA_BIG_COL(col)))
extra_size++; extra_size++;

View File

@@ -459,7 +459,7 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
uint *key_version) uint *key_version)
{ {
int rc; int rc;
uint32 dstlen= 0; /* Must be set because of error message */ uint32 dstlen= size;
*key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id); *key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id);
if (*key_version == ENCRYPTION_KEY_VERSION_INVALID) if (*key_version == ENCRYPTION_KEY_VERSION_INVALID)
@@ -486,6 +486,9 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
DBUG_ASSERT(!my_assert_on_error || dstlen == size); DBUG_ASSERT(!my_assert_on_error || dstlen == size);
if (! (rc == MY_AES_OK && dstlen == size)) if (! (rc == MY_AES_OK && dstlen == size))
{ {
if (rc != MY_AES_OK)
dstlen= 0; /* reset dstlen if failed, to match expected message */
my_errno= HA_ERR_DECRYPTION_FAILED; my_errno= HA_ERR_DECRYPTION_FAILED;
my_printf_error(HA_ERR_DECRYPTION_FAILED, my_printf_error(HA_ERR_DECRYPTION_FAILED,
"failed to encrypt '%s' rc: %d dstlen: %u size: %u\n", "failed to encrypt '%s' rc: %d dstlen: %u size: %u\n",
@@ -503,7 +506,7 @@ static int ma_decrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
uint key_version) uint key_version)
{ {
int rc; int rc;
uint32 dstlen= 0; /* Must be set because of error message */ uint32 dstlen= size;
rc= encryption_scheme_decrypt(src, size, dst, &dstlen, rc= encryption_scheme_decrypt(src, size, dst, &dstlen,
&crypt_data->scheme, key_version, &crypt_data->scheme, key_version,
@@ -513,6 +516,8 @@ static int ma_decrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
DBUG_ASSERT(!my_assert_on_error || dstlen == size); DBUG_ASSERT(!my_assert_on_error || dstlen == size);
if (! (rc == MY_AES_OK && dstlen == size)) if (! (rc == MY_AES_OK && dstlen == size))
{ {
if (rc != MY_AES_OK)
dstlen= 0; /* reset dstlen if failed, to match expected message */
my_errno= HA_ERR_DECRYPTION_FAILED; my_errno= HA_ERR_DECRYPTION_FAILED;
if (!share->silence_encryption_errors) if (!share->silence_encryption_errors)
my_printf_error(HA_ERR_DECRYPTION_FAILED, my_printf_error(HA_ERR_DECRYPTION_FAILED,

View File

@@ -12,6 +12,10 @@
--source include/default_optimizer_switch.inc --source include/default_optimizer_switch.inc
set
@rgmm_hist_type=@@histogram_type,
histogram_type=double_prec_hb;
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
@@ -1436,3 +1440,5 @@ SHOW SESSION STATUS LIKE 'Handler_read%';
DROP TABLE t1; DROP TABLE t1;
--echo # End of test for Bug#18109609 --echo # End of test for Bug#18109609
set histogram_type=@rgmm_hist_type;

View File

@@ -1,5 +1,8 @@
set @debug_tmp= @@debug_dbug; set @debug_tmp= @@debug_dbug;
set global debug_dbug="+d,force_group_by"; set global debug_dbug="+d,force_group_by";
set
@rgmm_hist_type=@@histogram_type,
histogram_type=double_prec_hb;
drop table if exists t1; drop table if exists t1;
create table t1 ( create table t1 (
a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(248) default ' ' a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(248) default ' '
@@ -3523,4 +3526,5 @@ Handler_read_rnd_deleted 0
Handler_read_rnd_next 0 Handler_read_rnd_next 0
DROP TABLE t1; DROP TABLE t1;
# End of test for Bug#18109609 # End of test for Bug#18109609
set histogram_type=@rgmm_hist_type;
set global debug_dbug=@debug_tmp; set global debug_dbug=@debug_tmp;

View File

@@ -4,7 +4,7 @@
for master_1 for master_1
for child2 for child2
for child3 for child3
CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE SERVER IF NOT EXISTS $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
SET @old_wait_timeout = @@global.wait_timeout; SET @old_wait_timeout = @@global.wait_timeout;
SET GLOBAL wait_timeout=1; SET GLOBAL wait_timeout=1;
CREATE TABLE t (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv_mdev_31463"'; CREATE TABLE t (c INT KEY,c1 BLOB,c2 TEXT) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv_mdev_31463"';
@@ -15,7 +15,7 @@ SELECT SLEEP (1);
SLEEP (1) SLEEP (1)
0 0
INSERT INTO t VALUES (1,2,3),(4,5,6),(7,8,9); INSERT INTO t VALUES (1,2,3),(4,5,6),(7,8,9);
ERROR 08S01: Got an error writing communication packets Got one of the listed errors
SELECT * FROM information_schema.key_column_usage; SELECT * FROM information_schema.key_column_usage;
XA END 'a'; XA END 'a';
XA PREPARE 'a'; XA PREPARE 'a';

View File

@@ -9,7 +9,9 @@
--enable_query_log --enable_query_log
--let $srv=srv_mdev_31463 --let $srv=srv_mdev_31463
evalp CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); --disable_warnings
evalp CREATE SERVER IF NOT EXISTS $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
--enable_warnings
SET @old_wait_timeout = @@global.wait_timeout; SET @old_wait_timeout = @@global.wait_timeout;
SET GLOBAL wait_timeout=1; SET GLOBAL wait_timeout=1;
@@ -18,9 +20,17 @@ XA START 'a';
--error ER_WRONG_VALUE_COUNT_ON_ROW --error ER_WRONG_VALUE_COUNT_ON_ROW
INSERT INTO t VALUES (0,0,0,0); INSERT INTO t VALUES (0,0,0,0);
SELECT SLEEP (1); SELECT SLEEP (1);
--error ER_NET_ERROR_ON_WRITE # MDEV-31586: The error code is non-deterministic, presumably due to
# some race condition from the SLEEP statement above. The correct
# error should be 12701 ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM as it is
# the last failure. Nevertheless, this contrived test is needed to
# cover the error reporting when setting lock wait timeout, until we
# find a better one and/or fixing the non-deterministic error
# reporting
--error 12701,ER_NET_ERROR_ON_WRITE,ER_XAER_DUPID
INSERT INTO t VALUES (1,2,3),(4,5,6),(7,8,9); INSERT INTO t VALUES (1,2,3),(4,5,6),(7,8,9);
--disable_result_log --disable_result_log
--error 0,12701,ER_XAER_DUPID
SELECT * FROM information_schema.key_column_usage; SELECT * FROM information_schema.key_column_usage;
--enable_result_log --enable_result_log