mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Merge 10.1 into 10.2
This should also fix the MariaDB 10.2.2 bug MDEV-13826 CREATE FULLTEXT INDEX on encrypted table fails. MDEV-12634 FIXME: Modify innodb-index-online, innodb-table-online so that they will write and read merge sort files. InnoDB 5.7 introduced some optimizations to avoid using the files for small tables. Many collation test results have been adjusted for MDEV-10191.
This commit is contained in:
commit
d9277732d7
67 changed files with 2156 additions and 1392 deletions
|
|
@ -37,6 +37,7 @@ Completed by Sunny Bains and Marko Makela
|
|||
#include "row0log.h"
|
||||
#include "row0ins.h"
|
||||
#include "row0sel.h"
|
||||
#include "log0crypt.h"
|
||||
#include "dict0crea.h"
|
||||
#include "trx0purge.h"
|
||||
#include "lock0lock.h"
|
||||
|
|
@ -270,92 +271,6 @@ private:
|
|||
/* Maximum pending doc memory limit in bytes for a fts tokenization thread */
|
||||
#define FTS_PENDING_DOC_MEMORY_LIMIT 1000000
|
||||
|
||||
/******************************************************//**
|
||||
Encrypt a merge block. */
|
||||
static
|
||||
void
|
||||
row_merge_encrypt_buf(
|
||||
/*==================*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
|
||||
ulint offset, /*!< in: offset where to
|
||||
write */
|
||||
ulint space, /*!< in: tablespace id */
|
||||
const byte* input_buf, /*!< in: input buffer */
|
||||
byte* crypted_buf) /*!< out: crypted buffer */
|
||||
{
|
||||
uint key_version;
|
||||
uint dstlen=0;
|
||||
uint ofs = (uint)(srv_sort_buf_size * offset);
|
||||
|
||||
key_version = encryption_key_get_latest_version(crypt_data->key_id);
|
||||
|
||||
/* Store key_version at the beginning of the input buffer */
|
||||
mach_write_to_4((byte *)crypted_buf, key_version);
|
||||
|
||||
int rc = encryption_scheme_encrypt(input_buf+ROW_MERGE_RESERVE_SIZE,
|
||||
srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE,
|
||||
crypted_buf+ROW_MERGE_RESERVE_SIZE, &dstlen,
|
||||
crypt_data, key_version,
|
||||
space, ofs, 0);
|
||||
|
||||
if (! ((rc == MY_AES_OK) && ((ulint)dstlen == srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE))) {
|
||||
ib::fatal()
|
||||
<< "Unable to encrypt data-block "
|
||||
" src: " << static_cast<const void*>(input_buf)
|
||||
<< " srclen: " << srv_sort_buf_size
|
||||
<< " buf: " << static_cast<const void*>(crypted_buf)
|
||||
<< " buflen: " << dstlen
|
||||
<< ". return-code: " << rc << ". Can't continue!";
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************//**
|
||||
Decrypt a merge block. */
|
||||
static
|
||||
bool
|
||||
row_merge_decrypt_buf(
|
||||
/*==================*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
|
||||
ulint offset, /*!< in: offset where to
|
||||
write */
|
||||
ulint space, /*!< in: tablespace id */
|
||||
const byte* input_buf, /*!< in: input buffer */
|
||||
byte* crypted_buf) /*!< out: crypted buffer */
|
||||
{
|
||||
uint key_version;
|
||||
uint dstlen=0;
|
||||
uint ofs = (uint)(srv_sort_buf_size * offset);
|
||||
|
||||
/* Read key_version from beginning of the buffer */
|
||||
key_version = mach_read_from_4((byte *)input_buf);
|
||||
|
||||
if (key_version == 0) {
|
||||
/* block not encrypted */
|
||||
return false;
|
||||
}
|
||||
|
||||
int rc = encryption_scheme_decrypt(input_buf+ROW_MERGE_RESERVE_SIZE,
|
||||
srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE,
|
||||
crypted_buf+ROW_MERGE_RESERVE_SIZE, &dstlen,
|
||||
crypt_data, key_version,
|
||||
space, ofs, 0);
|
||||
|
||||
if (! ((rc == MY_AES_OK) && ((ulint)dstlen == srv_sort_buf_size-ROW_MERGE_RESERVE_SIZE))) {
|
||||
ib::fatal()
|
||||
<< "Unable to decrypt data-block "
|
||||
<< " src: " << static_cast<const void*>(input_buf)
|
||||
<< " srclen: " << srv_sort_buf_size
|
||||
<< " buf: " << static_cast<const void*>(crypted_buf)
|
||||
<< " buflen: " << dstlen
|
||||
<< ". return-code: " << rc << ". Can't continue!";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Maximum pending doc memory limit in bytes for a fts tokenization thread */
|
||||
#define FTS_PENDING_DOC_MEMORY_LIMIT 1000000
|
||||
|
||||
/** Insert sorted data tuples to the index.
|
||||
@param[in] trx_id transaction identifier
|
||||
@param[in] index index to be inserted
|
||||
|
|
@ -384,7 +299,6 @@ row_merge_insert_index_tuples(
|
|||
percent until now */
|
||||
const double pct_cost, /*!< in: current progress percent
|
||||
*/
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space, /*!< in: space id */
|
||||
ut_stage_alter_t* stage = NULL);
|
||||
|
|
@ -469,7 +383,7 @@ row_merge_buf_create(
|
|||
ulint buf_size;
|
||||
mem_heap_t* heap;
|
||||
|
||||
max_tuples = (srv_sort_buf_size - ROW_MERGE_RESERVE_SIZE)
|
||||
max_tuples = srv_sort_buf_size
|
||||
/ ut_max(static_cast<ulint>(1),
|
||||
dict_index_get_min_size(index));
|
||||
|
||||
|
|
@ -917,7 +831,7 @@ row_merge_buf_add(
|
|||
ut_ad(data_size < srv_sort_buf_size);
|
||||
|
||||
/* Reserve bytes for the end marker of row_merge_block_t. */
|
||||
if (buf->total_size + data_size >= (srv_sort_buf_size - ROW_MERGE_RESERVE_SIZE)) {
|
||||
if (buf->total_size + data_size >= srv_sort_buf_size) {
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
|
@ -1039,7 +953,7 @@ respectively */
|
|||
|
||||
/**********************************************************************//**
|
||||
Merge sort the tuple buffer in main memory. */
|
||||
static MY_ATTRIBUTE((nonnull(4,5)))
|
||||
static
|
||||
void
|
||||
row_merge_tuple_sort(
|
||||
/*=================*/
|
||||
|
|
@ -1090,7 +1004,7 @@ row_merge_buf_write(
|
|||
{
|
||||
const dict_index_t* index = buf->index;
|
||||
ulint n_fields= dict_index_get_n_fields(index);
|
||||
byte* b = &block[ROW_MERGE_RESERVE_SIZE];
|
||||
byte* b = &block[0];
|
||||
|
||||
DBUG_ENTER("row_merge_buf_write");
|
||||
|
||||
|
|
@ -1109,7 +1023,7 @@ row_merge_buf_write(
|
|||
|
||||
/* Write an "end-of-chunk" marker. */
|
||||
ut_a(b < &block[srv_sort_buf_size]);
|
||||
ut_a(b == &block[0] + buf->total_size + ROW_MERGE_RESERVE_SIZE);
|
||||
ut_a(b == &block[0] + buf->total_size);
|
||||
*b++ = 0;
|
||||
#ifdef UNIV_DEBUG_VALGRIND
|
||||
/* The rest of the block is uninitialized. Initialize it
|
||||
|
|
@ -1154,7 +1068,7 @@ row_merge_heap_create(
|
|||
}
|
||||
|
||||
/** Read a merge block from the file system.
|
||||
@return whether the request was successful */
|
||||
@return whether the request was completed successfully */
|
||||
bool
|
||||
row_merge_read(
|
||||
/*===========*/
|
||||
|
|
@ -1163,9 +1077,8 @@ row_merge_read(
|
|||
in number of row_merge_block_t
|
||||
elements */
|
||||
row_merge_block_t* buf, /*!< out: data */
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_buf, /*!< in: crypt buf or NULL */
|
||||
ulint space) /*!< in: space id */
|
||||
ulint space) /*!< in: space id */
|
||||
{
|
||||
os_offset_t ofs = ((os_offset_t) offset) * srv_sort_buf_size;
|
||||
|
||||
|
|
@ -1178,10 +1091,14 @@ row_merge_read(
|
|||
request, fd, buf, ofs, srv_sort_buf_size);
|
||||
|
||||
/* For encrypted tables, decrypt data after reading and copy data */
|
||||
if (crypt_data && crypt_buf) {
|
||||
if (row_merge_decrypt_buf(crypt_data, offset, space, buf, crypt_buf)) {
|
||||
memcpy(buf, crypt_buf, srv_sort_buf_size);
|
||||
if (log_tmp_is_encrypted()) {
|
||||
if (!log_tmp_block_decrypt(buf, srv_sort_buf_size,
|
||||
crypt_buf, ofs, space)) {
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
srv_stats.n_merge_blocks_decrypted.inc();
|
||||
memcpy(buf, crypt_buf, srv_sort_buf_size);
|
||||
}
|
||||
|
||||
#ifdef POSIX_FADV_DONTNEED
|
||||
|
|
@ -1198,15 +1115,15 @@ row_merge_read(
|
|||
|
||||
/********************************************************************//**
|
||||
Write a merge block to the file system.
|
||||
@return TRUE if request was successful, FALSE if fail */
|
||||
ibool
|
||||
@return whether the request was completed successfully */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
row_merge_write(
|
||||
/*============*/
|
||||
int fd, /*!< in: file descriptor */
|
||||
ulint offset, /*!< in: offset where to write,
|
||||
in number of row_merge_block_t elements */
|
||||
const void* buf, /*!< in: data */
|
||||
fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
|
||||
void* crypt_buf, /*!< in: crypt buf or NULL */
|
||||
ulint space) /*!< in: space id */
|
||||
{
|
||||
|
|
@ -1218,12 +1135,17 @@ row_merge_write(
|
|||
DBUG_LOG("ib_merge_sort", "fd=" << fd << " ofs=" << ofs);
|
||||
DBUG_EXECUTE_IF("row_merge_write_failure", DBUG_RETURN(FALSE););
|
||||
|
||||
if (crypt_data && crypt_buf) {
|
||||
row_merge_encrypt_buf(crypt_data, offset, space, (const byte *)buf, (byte *)crypt_buf);
|
||||
/* For encrypted tables, encrypt data before writing */
|
||||
if (log_tmp_is_encrypted()) {
|
||||
if (!log_tmp_block_encrypt(static_cast<const byte*>(buf),
|
||||
buf_len,
|
||||
static_cast<byte*>(crypt_buf),
|
||||
ofs, space)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
srv_stats.n_merge_blocks_encrypted.inc();
|
||||
out_buf = crypt_buf;
|
||||
} else {
|
||||
/* Mark block unencrypted */
|
||||
mach_write_to_4((byte *)out_buf, 0);
|
||||
}
|
||||
|
||||
IORequest request(IORequest::WRITE);
|
||||
|
|
@ -1255,9 +1177,8 @@ row_merge_read_rec(
|
|||
or NULL on end of list
|
||||
(non-NULL on I/O error) */
|
||||
ulint* offsets,/*!< out: offsets of mrec */
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space) /*!< in: space id */
|
||||
ulint space) /*!< in: space id */
|
||||
{
|
||||
ulint extra_size;
|
||||
ulint data_size;
|
||||
|
|
@ -1271,10 +1192,6 @@ row_merge_read_rec(
|
|||
|
||||
DBUG_ENTER("row_merge_read_rec");
|
||||
|
||||
if (b == &block[0]) {
|
||||
b+= ROW_MERGE_RESERVE_SIZE;
|
||||
}
|
||||
|
||||
extra_size = *b++;
|
||||
|
||||
if (UNIV_UNLIKELY(!extra_size)) {
|
||||
|
|
@ -1292,7 +1209,8 @@ row_merge_read_rec(
|
|||
|
||||
if (UNIV_UNLIKELY(b >= &block[srv_sort_buf_size])) {
|
||||
if (!row_merge_read(fd, ++(*foffs), block,
|
||||
crypt_data, crypt_block, space)) {
|
||||
crypt_block,
|
||||
space)) {
|
||||
err_exit:
|
||||
/* Signal I/O error. */
|
||||
*mrec = b;
|
||||
|
|
@ -1300,7 +1218,7 @@ err_exit:
|
|||
}
|
||||
|
||||
/* Wrap around to the beginning of the buffer. */
|
||||
b = &block[ROW_MERGE_RESERVE_SIZE];
|
||||
b = &block[0];
|
||||
}
|
||||
|
||||
extra_size = (extra_size & 0x7f) << 8;
|
||||
|
|
@ -1322,13 +1240,14 @@ err_exit:
|
|||
memcpy(*buf, b, avail_size);
|
||||
|
||||
if (!row_merge_read(fd, ++(*foffs), block,
|
||||
crypt_data, crypt_block, space)) {
|
||||
crypt_block,
|
||||
space)) {
|
||||
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
/* Wrap around to the beginning of the buffer. */
|
||||
b = &block[ROW_MERGE_RESERVE_SIZE];
|
||||
b = &block[0];
|
||||
|
||||
/* Copy the record. */
|
||||
memcpy(*buf + avail_size, b, extra_size - avail_size);
|
||||
|
|
@ -1383,13 +1302,14 @@ err_exit:
|
|||
ut_d(offsets[3] = (ulint) index);
|
||||
|
||||
if (!row_merge_read(fd, ++(*foffs), block,
|
||||
crypt_data, crypt_block, space)) {
|
||||
crypt_block,
|
||||
space)) {
|
||||
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
/* Wrap around to the beginning of the buffer. */
|
||||
b = &block[ROW_MERGE_RESERVE_SIZE];
|
||||
b = &block[0];
|
||||
|
||||
/* Copy the rest of the record. */
|
||||
memcpy(*buf + avail_size, b, extra_size + data_size - avail_size);
|
||||
|
|
@ -1461,7 +1381,6 @@ row_merge_write_rec(
|
|||
ulint* foffs, /*!< in/out: file offset */
|
||||
const mrec_t* mrec, /*!< in: record to write */
|
||||
const ulint* offsets,/*!< in: offsets of mrec */
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space) /*!< in: space id */
|
||||
{
|
||||
|
|
@ -1484,10 +1403,6 @@ row_merge_write_rec(
|
|||
size = extra_size + (extra_size >= 0x80)
|
||||
+ rec_offs_data_size(offsets);
|
||||
|
||||
if (b == &block[0]) {
|
||||
b+= ROW_MERGE_RESERVE_SIZE;
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(b + size >= &block[srv_sort_buf_size])) {
|
||||
/* The record spans two blocks.
|
||||
Copy it to the temporary buffer first. */
|
||||
|
|
@ -1503,14 +1418,15 @@ row_merge_write_rec(
|
|||
memcpy(b, buf[0], avail_size);
|
||||
|
||||
if (!row_merge_write(fd, (*foffs)++, block,
|
||||
crypt_data, crypt_block, space)) {
|
||||
crypt_block,
|
||||
space)) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
|
||||
|
||||
/* Copy the rest. */
|
||||
b = &block[ROW_MERGE_RESERVE_SIZE];
|
||||
b = &block[0];
|
||||
memcpy(b, buf[0] + avail_size, size - avail_size);
|
||||
b += size - avail_size;
|
||||
} else {
|
||||
|
|
@ -1533,7 +1449,6 @@ row_merge_write_eof(
|
|||
byte* b, /*!< in: pointer to end of block */
|
||||
int fd, /*!< in: file descriptor */
|
||||
ulint* foffs, /*!< in/out: file offset */
|
||||
fil_space_crypt_t* crypt_data, /*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space) /*!< in: space id */
|
||||
{
|
||||
|
|
@ -1548,10 +1463,6 @@ row_merge_write_eof(
|
|||
reinterpret_cast<const void*>(block) <<
|
||||
",fd=" << fd << ',' << *foffs);
|
||||
|
||||
if (b == &block[0]) {
|
||||
b+= ROW_MERGE_RESERVE_SIZE;
|
||||
}
|
||||
|
||||
*b++ = 0;
|
||||
UNIV_MEM_ASSERT_RW(&block[0], b - &block[0]);
|
||||
UNIV_MEM_ASSERT_W(&block[0], srv_sort_buf_size);
|
||||
|
|
@ -1562,8 +1473,7 @@ row_merge_write_eof(
|
|||
memset(b, 0xff, &block[srv_sort_buf_size] - b);
|
||||
#endif /* UNIV_DEBUG_VALGRIND */
|
||||
|
||||
if (!row_merge_write(fd, (*foffs)++, block,
|
||||
crypt_data, crypt_block, space)) {
|
||||
if (!row_merge_write(fd, (*foffs)++, block, crypt_block, space)) {
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1763,6 +1673,8 @@ existing order
|
|||
@param[in,out] stage performance schema accounting object, used by
|
||||
ALTER TABLE. stage->n_pk_recs_inc() will be called for each record read and
|
||||
stage->inc() will be called for each page read.
|
||||
@param[in] pct_cost percent of task weight out of total alter job
|
||||
@param[in,out] crypt_block crypted file buffer
|
||||
@param[in] eval_table mysql table used to evaluate virtual column
|
||||
value, see innobase_get_computed_value().
|
||||
@return DB_SUCCESS or error */
|
||||
|
|
@ -1790,10 +1702,8 @@ row_merge_read_clustered_index(
|
|||
int* tmpfd,
|
||||
ut_stage_alter_t* stage,
|
||||
double pct_cost,
|
||||
fil_space_crypt_t* crypt_data,
|
||||
row_merge_block_t* crypt_block,
|
||||
struct TABLE* eval_table)
|
||||
|
||||
{
|
||||
dict_index_t* clust_index; /* Clustered index */
|
||||
mem_heap_t* row_heap; /* Heap memory to create
|
||||
|
|
@ -2490,8 +2400,7 @@ write_buffers:
|
|||
table_total_rows,
|
||||
curr_progress,
|
||||
pct_cost,
|
||||
NULL,
|
||||
NULL,
|
||||
crypt_block,
|
||||
new_table->space);
|
||||
|
||||
if (row == NULL) {
|
||||
|
|
@ -2602,8 +2511,7 @@ write_buffers:
|
|||
table_total_rows,
|
||||
curr_progress,
|
||||
pct_cost,
|
||||
NULL,
|
||||
NULL,
|
||||
crypt_block,
|
||||
new_table->space);
|
||||
|
||||
err = btr_bulk.finish(err);
|
||||
|
|
@ -2635,8 +2543,10 @@ write_buffers:
|
|||
|
||||
row_merge_buf_write(buf, file, block);
|
||||
|
||||
if (!row_merge_write(file->fd, file->offset++, block,
|
||||
crypt_data, crypt_block, new_table->space)) {
|
||||
if (!row_merge_write(
|
||||
file->fd, file->offset++,
|
||||
block, crypt_block,
|
||||
new_table->space)) {
|
||||
err = DB_TEMP_FILE_WRITE_FAIL;
|
||||
trx->error_key_num = i;
|
||||
break;
|
||||
|
|
@ -2689,7 +2599,7 @@ write_buffers:
|
|||
if(read_rows % 1000 == 0) {
|
||||
/* Update progress for each 1000 rows */
|
||||
curr_progress = (read_rows >= table_total_rows) ?
|
||||
pct_cost :
|
||||
pct_cost :
|
||||
((pct_cost * read_rows) / table_total_rows);
|
||||
/* presenting 10.12% as 1012 integer */
|
||||
onlineddl_pct_progress = (ulint) (curr_progress * 100);
|
||||
|
|
@ -2845,9 +2755,8 @@ wait_again:
|
|||
&buf[2], b2, \
|
||||
of->fd, &of->offset, \
|
||||
mrec##N, offsets##N, \
|
||||
crypt_data, \
|
||||
crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL , \
|
||||
space); \
|
||||
space); \
|
||||
if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
|
||||
goto corrupt; \
|
||||
} \
|
||||
|
|
@ -2855,7 +2764,6 @@ wait_again:
|
|||
&buf[N], b##N, INDEX, \
|
||||
file->fd, foffs##N, \
|
||||
&mrec##N, offsets##N, \
|
||||
crypt_data, \
|
||||
crypt_block ? &crypt_block[N * srv_sort_buf_size] : NULL, \
|
||||
space); \
|
||||
\
|
||||
|
|
@ -2888,6 +2796,8 @@ wait_again:
|
|||
@param[in,out] foffs1 offset of second source list in the file
|
||||
@param[in,out] of output file
|
||||
@param[in,out] stage performance schema accounting object, used by
|
||||
@param[in,out] crypt_block encryption buffer
|
||||
@param[in] space tablespace ID for encryption
|
||||
ALTER TABLE. If not NULL stage->inc() will be called for each record
|
||||
processed.
|
||||
@return DB_SUCCESS or error code */
|
||||
|
|
@ -2901,10 +2811,8 @@ row_merge_blocks(
|
|||
ulint* foffs1,
|
||||
merge_file_t* of,
|
||||
ut_stage_alter_t* stage,
|
||||
fil_space_crypt_t* crypt_data,/*!< in: crypt data or NULL */
|
||||
row_merge_block_t* crypt_block,/*!< in: in/out: crypted file
|
||||
buffer */
|
||||
ulint space) /*!< in: space id */
|
||||
row_merge_block_t* crypt_block,
|
||||
ulint space)
|
||||
{
|
||||
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
|
||||
|
||||
|
|
@ -2930,9 +2838,11 @@ row_merge_blocks(
|
|||
file in two halves, which can be merged on the following pass. */
|
||||
|
||||
if (!row_merge_read(file->fd, *foffs0, &block[0],
|
||||
crypt_data, crypt_block ? &crypt_block[0] : NULL, space)
|
||||
|| !row_merge_read(file->fd, *foffs1, &block[srv_sort_buf_size],
|
||||
crypt_data, crypt_block ? &crypt_block[srv_sort_buf_size] : NULL, space)) {
|
||||
crypt_block ? &crypt_block[0] : NULL,
|
||||
space) ||
|
||||
!row_merge_read(file->fd, *foffs1, &block[srv_sort_buf_size],
|
||||
crypt_block ? &crypt_block[srv_sort_buf_size] : NULL,
|
||||
space)) {
|
||||
corrupt:
|
||||
mem_heap_free(heap);
|
||||
DBUG_RETURN(DB_CORRUPTION);
|
||||
|
|
@ -2945,13 +2855,15 @@ corrupt:
|
|||
b0 = row_merge_read_rec(
|
||||
&block[0], &buf[0], b0, dup->index,
|
||||
file->fd, foffs0, &mrec0, offsets0,
|
||||
crypt_data, crypt_block ? &crypt_block[0] : NULL, space);
|
||||
crypt_block ? &crypt_block[0] : NULL,
|
||||
space);
|
||||
|
||||
b1 = row_merge_read_rec(
|
||||
&block[srv_sort_buf_size],
|
||||
&buf[srv_sort_buf_size], b1, dup->index,
|
||||
file->fd, foffs1, &mrec1, offsets1,
|
||||
crypt_data, crypt_block ? &crypt_block[srv_sort_buf_size] : NULL, space);
|
||||
crypt_block ? &crypt_block[srv_sort_buf_size] : NULL,
|
||||
space);
|
||||
|
||||
if (UNIV_UNLIKELY(!b0 && mrec0)
|
||||
|| UNIV_UNLIKELY(!b1 && mrec1)) {
|
||||
|
|
@ -2991,11 +2903,12 @@ done1:
|
|||
|
||||
mem_heap_free(heap);
|
||||
|
||||
b2 = row_merge_write_eof(&block[2 * srv_sort_buf_size],
|
||||
b2 = row_merge_write_eof(
|
||||
&block[2 * srv_sort_buf_size],
|
||||
b2, of->fd, &of->offset,
|
||||
crypt_data, crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space);
|
||||
crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL,
|
||||
space);
|
||||
DBUG_RETURN(b2 ? DB_SUCCESS : DB_CORRUPTION);
|
||||
|
||||
}
|
||||
|
||||
/** Copy a block of index entries.
|
||||
|
|
@ -3005,6 +2918,8 @@ done1:
|
|||
@param[in,out] foffs0 input file offset
|
||||
@param[in,out] of output file
|
||||
@param[in,out] stage performance schema accounting object, used by
|
||||
@param[in,out] crypt_block encryption buffer
|
||||
@param[in] space tablespace ID for encryption
|
||||
ALTER TABLE. If not NULL stage->inc() will be called for each record
|
||||
processed.
|
||||
@return TRUE on success, FALSE on failure */
|
||||
|
|
@ -3017,9 +2932,8 @@ row_merge_blocks_copy(
|
|||
ulint* foffs0,
|
||||
merge_file_t* of,
|
||||
ut_stage_alter_t* stage,
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space) /*!< in: space id */
|
||||
row_merge_block_t* crypt_block,
|
||||
ulint space)
|
||||
{
|
||||
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
|
||||
|
||||
|
|
@ -3042,7 +2956,8 @@ row_merge_blocks_copy(
|
|||
file in two halves, which can be merged on the following pass. */
|
||||
|
||||
if (!row_merge_read(file->fd, *foffs0, &block[0],
|
||||
crypt_data, crypt_block ? &crypt_block[0] : NULL, space)) {
|
||||
crypt_block ? &crypt_block[0] : NULL,
|
||||
space)) {
|
||||
corrupt:
|
||||
mem_heap_free(heap);
|
||||
DBUG_RETURN(FALSE);
|
||||
|
|
@ -3054,7 +2969,8 @@ corrupt:
|
|||
|
||||
b0 = row_merge_read_rec(&block[0], &buf[0], b0, index,
|
||||
file->fd, foffs0, &mrec0, offsets0,
|
||||
crypt_data, crypt_block ? &crypt_block[0] : NULL, space);
|
||||
crypt_block ? &crypt_block[0] : NULL,
|
||||
space);
|
||||
|
||||
if (UNIV_UNLIKELY(!b0 && mrec0)) {
|
||||
|
||||
|
|
@ -3075,10 +2991,12 @@ done0:
|
|||
|
||||
mem_heap_free(heap);
|
||||
|
||||
DBUG_RETURN(row_merge_write_eof(&block[2 * srv_sort_buf_size],
|
||||
b2, of->fd, &of->offset,
|
||||
crypt_data,
|
||||
crypt_block ? &crypt_block[2 * srv_sort_buf_size] : NULL, space)
|
||||
DBUG_RETURN(row_merge_write_eof(
|
||||
&block[2 * srv_sort_buf_size],
|
||||
b2, of->fd, &of->offset,
|
||||
crypt_block
|
||||
? &crypt_block[2 * srv_sort_buf_size]
|
||||
: NULL, space)
|
||||
!= NULL);
|
||||
}
|
||||
|
||||
|
|
@ -3092,6 +3010,8 @@ done0:
|
|||
@param[in,out] run_offset Array that contains the first offset number
|
||||
for each merge run
|
||||
@param[in,out] stage performance schema accounting object, used by
|
||||
@param[in,out] crypt_block encryption buffer
|
||||
@param[in] space tablespace ID for encryption
|
||||
ALTER TABLE. If not NULL stage->inc() will be called for each record
|
||||
processed.
|
||||
@return DB_SUCCESS or error code */
|
||||
|
|
@ -3106,9 +3026,8 @@ row_merge(
|
|||
ulint* num_run,
|
||||
ulint* run_offset,
|
||||
ut_stage_alter_t* stage,
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space) /*!< in: space id */
|
||||
row_merge_block_t* crypt_block,
|
||||
ulint space)
|
||||
{
|
||||
ulint foffs0; /*!< first input offset */
|
||||
ulint foffs1; /*!< second input offset */
|
||||
|
|
@ -3156,7 +3075,7 @@ row_merge(
|
|||
|
||||
error = row_merge_blocks(dup, file, block,
|
||||
&foffs0, &foffs1, &of, stage,
|
||||
crypt_data, crypt_block, space);
|
||||
crypt_block, space);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
return(error);
|
||||
|
|
@ -3177,7 +3096,7 @@ row_merge(
|
|||
|
||||
if (!row_merge_blocks_copy(dup->index, file, block,
|
||||
&foffs0, &of, stage,
|
||||
crypt_data, crypt_block, space)) {
|
||||
crypt_block, space)) {
|
||||
return(DB_CORRUPTION);
|
||||
}
|
||||
}
|
||||
|
|
@ -3195,7 +3114,7 @@ row_merge(
|
|||
|
||||
if (!row_merge_blocks_copy(dup->index, file, block,
|
||||
&foffs1, &of, stage,
|
||||
crypt_data, crypt_block, space)) {
|
||||
crypt_block, space)) {
|
||||
return(DB_CORRUPTION);
|
||||
}
|
||||
}
|
||||
|
|
@ -3253,7 +3172,6 @@ row_merge_sort(
|
|||
/*!< in: total progress percent
|
||||
until now */
|
||||
const double pct_cost, /*!< in: current progress percent */
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space, /*!< in: space id */
|
||||
ut_stage_alter_t* stage)
|
||||
|
|
@ -3328,7 +3246,7 @@ row_merge_sort(
|
|||
|
||||
error = row_merge(trx, dup, file, block, tmpfd,
|
||||
&num_runs, run_offset, stage,
|
||||
crypt_data, crypt_block, space);
|
||||
crypt_block, space);
|
||||
|
||||
if(update_progress) {
|
||||
merge_count++;
|
||||
|
|
@ -3471,7 +3389,6 @@ row_merge_insert_index_tuples(
|
|||
percent until now */
|
||||
const double pct_cost, /*!< in: current progress percent
|
||||
*/
|
||||
fil_space_crypt_t* crypt_data,/*!< in: table crypt data */
|
||||
row_merge_block_t* crypt_block, /*!< in: crypt buf or NULL */
|
||||
ulint space, /*!< in: space id */
|
||||
ut_stage_alter_t* stage)
|
||||
|
|
@ -3532,8 +3449,7 @@ row_merge_insert_index_tuples(
|
|||
b = block;
|
||||
dtuple = NULL;
|
||||
|
||||
if (!row_merge_read(fd, foffs, block,
|
||||
crypt_data, crypt_block, space)) {
|
||||
if (!row_merge_read(fd, foffs, block, crypt_block, space)) {
|
||||
error = DB_CORRUPTION;
|
||||
goto err_exit;
|
||||
} else {
|
||||
|
|
@ -3542,7 +3458,6 @@ row_merge_insert_index_tuples(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (stage != NULL) {
|
||||
|
|
@ -3566,7 +3481,9 @@ row_merge_insert_index_tuples(
|
|||
} else {
|
||||
b = row_merge_read_rec(block, buf, b, index,
|
||||
fd, &foffs, &mrec, offsets,
|
||||
crypt_data, crypt_block, space);
|
||||
crypt_block,
|
||||
space);
|
||||
|
||||
if (UNIV_UNLIKELY(!b)) {
|
||||
/* End of list, or I/O error */
|
||||
if (mrec) {
|
||||
|
|
@ -4665,7 +4582,6 @@ row_merge_build_indexes(
|
|||
fts_psort_t* merge_info = NULL;
|
||||
int64_t sig_count = 0;
|
||||
bool fts_psort_initiated = false;
|
||||
fil_space_crypt_t * crypt_data = NULL;
|
||||
|
||||
double total_static_cost = 0;
|
||||
double total_dynamic_cost = 0;
|
||||
|
|
@ -4696,28 +4612,14 @@ row_merge_build_indexes(
|
|||
DBUG_RETURN(DB_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
/* Get crypt data from tablespace if present. We should be protected
|
||||
from concurrent DDL (e.g. drop table) by MDL-locks. */
|
||||
FilSpace space(new_table->space);
|
||||
|
||||
if (const fil_space_t* fs = space()) {
|
||||
crypt_data = fs->crypt_data;
|
||||
} else {
|
||||
DBUG_RETURN(DB_TABLESPACE_NOT_FOUND);
|
||||
}
|
||||
|
||||
/* If tablespace is encrypted, allocate additional buffer for
|
||||
encryption/decryption. */
|
||||
if (crypt_data && crypt_data->should_encrypt()) {
|
||||
if (log_tmp_is_encrypted()) {
|
||||
crypt_block = static_cast<row_merge_block_t*>(
|
||||
alloc.allocate_large(3 * srv_sort_buf_size, &crypt_pfx));
|
||||
alloc.allocate_large(3 * srv_sort_buf_size,
|
||||
&crypt_pfx));
|
||||
|
||||
if (crypt_block == NULL) {
|
||||
DBUG_RETURN(DB_OUT_OF_MEMORY);
|
||||
}
|
||||
} else {
|
||||
/* Not needed */
|
||||
crypt_data = NULL;
|
||||
}
|
||||
|
||||
trx_start_if_not_started_xa(trx, true);
|
||||
|
|
@ -4824,11 +4726,11 @@ row_merge_build_indexes(
|
|||
/* Read clustered index of the table and create files for
|
||||
secondary index entries for merge sort */
|
||||
error = row_merge_read_clustered_index(
|
||||
trx, table, old_table, new_table, online, indexes,
|
||||
fts_sort_idx, psort_info, merge_files, key_numbers,
|
||||
n_indexes, add_cols, add_v, col_map, add_autoinc,
|
||||
sequence, block, skip_pk_sort, &tmpfd, stage,
|
||||
pct_cost, crypt_data, crypt_block, eval_table);
|
||||
trx, table, old_table, new_table, online, indexes,
|
||||
fts_sort_idx, psort_info, merge_files, key_numbers,
|
||||
n_indexes, add_cols, add_v, col_map, add_autoinc,
|
||||
sequence, block, skip_pk_sort, &tmpfd, stage,
|
||||
pct_cost, crypt_block, eval_table);
|
||||
|
||||
stage->end_phase_read_pk();
|
||||
|
||||
|
|
@ -4853,10 +4755,6 @@ row_merge_build_indexes(
|
|||
/* Now we have files containing index entries ready for
|
||||
sorting and inserting. */
|
||||
|
||||
DBUG_EXECUTE_IF(
|
||||
"ib_merge_wait_after_read",
|
||||
os_thread_sleep(20000000);); /* 20 sec */
|
||||
|
||||
for (i = 0; i < n_indexes; i++) {
|
||||
dict_index_t* sort_idx = indexes[i];
|
||||
|
||||
|
|
@ -4969,7 +4867,7 @@ wait_again:
|
|||
trx, &dup, &merge_files[i],
|
||||
block, &tmpfd, true,
|
||||
pct_progress, pct_cost,
|
||||
crypt_data, crypt_block, new_table->space, stage);
|
||||
crypt_block, new_table->space, stage);
|
||||
|
||||
pct_progress += pct_cost;
|
||||
|
||||
|
|
@ -5012,7 +4910,7 @@ wait_again:
|
|||
merge_files[i].fd, block, NULL,
|
||||
&btr_bulk,
|
||||
merge_files[i].n_rec, pct_progress, pct_cost,
|
||||
crypt_data, crypt_block, new_table->space, stage);
|
||||
crypt_block, new_table->space, stage);
|
||||
|
||||
error = btr_bulk.finish(error);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue