Commit 178540b9 authored by Alexander Barkov's avatar Alexander Barkov

Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext

parents 3a9ee22b a237a920
......@@ -117,6 +117,7 @@ xb_mysql_connect()
mysql_options(connection, MYSQL_PLUGIN_DIR, xb_plugin_dir);
}
mysql_options(connection, MYSQL_OPT_PROTOCOL, &opt_protocol);
mysql_options(connection,MYSQL_SET_CHARSET_NAME, "utf8");
msg_ts("Connecting to MySQL server host: %s, user: %s, password: %s, "
"port: %s, socket: %s\n", opt_host ? opt_host : "localhost",
......@@ -1629,3 +1630,96 @@ backup_cleanup()
mysql_close(mysql_connection);
}
}
static pthread_mutex_t mdl_lock_con_mutex;
static MYSQL *mdl_con = NULL;
void
mdl_lock_init()
{
pthread_mutex_init(&mdl_lock_con_mutex, NULL);
mdl_con = xb_mysql_connect();
if (mdl_con)
{
xb_mysql_query(mdl_con, "BEGIN", false, true);
}
}
#ifndef DBUF_OFF
/* Test that table is really locked, if lock_ddl_per_table is set.
The test is executed in DBUG_EXECUTE_IF block inside mdl_lock_table().
*/
static void check_mdl_lock_works(const char *table_name)
{
MYSQL *test_con= xb_mysql_connect();
char *query;
xb_a(asprintf(&query,
"SET STATEMENT max_statement_time=1 FOR ALTER TABLE %s"
" ADD COLUMN mdl_lock_column int", table_name));
int err = mysql_query(test_con, query);
DBUG_ASSERT(err);
int err_no = mysql_errno(test_con);
DBUG_ASSERT(err_no == ER_STATEMENT_TIMEOUT);
mysql_close(test_con);
}
#endif
extern void
dict_fs2utf8(const char*, char*, size_t, char*, size_t);
void
mdl_lock_table(ulint space_id)
{
char *query;
pthread_mutex_lock(&mdl_lock_con_mutex);
xb_a(asprintf(&query,
"SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES "
"WHERE SPACE = %llu AND NAME LIKE '%%/%%'", (ulonglong)space_id));
xb_mysql_query(mdl_con, query, true, true);
MYSQL_RES *mysql_result = xb_mysql_query(mdl_con, query, true);
MYSQL_ROW row;
while ((row = mysql_fetch_row(mysql_result))) {
char full_table_name[2*FN_REFLEN +2];
char db_utf8[FN_REFLEN];
char table_utf8[FN_REFLEN];
dict_fs2utf8(row[0], db_utf8, sizeof(db_utf8),table_utf8,sizeof(table_utf8));
snprintf(full_table_name,sizeof(full_table_name),"`%s`.`%s`",db_utf8,table_utf8);
char *lock_query;
msg_ts("Locking MDL for %s\n", full_table_name);
xb_a(asprintf(&lock_query,
"SELECT * FROM %s LIMIT 0",
full_table_name));
xb_mysql_query(mdl_con, lock_query, false, false);
free(lock_query);
DBUG_EXECUTE_IF("check_mdl_lock_works",
check_mdl_lock_works(full_table_name););
}
mysql_free_result(mysql_result);
free(query);
pthread_mutex_unlock(&mdl_lock_con_mutex);
}
void
mdl_unlock_all()
{
msg_ts("Unlocking MDL for all tables");
xb_mysql_query(mdl_con, "COMMIT", false, true);
mysql_close(mdl_con);
pthread_mutex_destroy(&mdl_lock_con_mutex);
}
......@@ -296,6 +296,8 @@ my_bool opt_noversioncheck = FALSE;
my_bool opt_no_backup_locks = FALSE;
my_bool opt_decompress = FALSE;
my_bool opt_lock_ddl_per_table = FALSE;
static const char *binlog_info_values[] = {"off", "lockless", "on", "auto",
NullS};
static TYPELIB binlog_info_typelib = {array_elements(binlog_info_values)-1, "",
......@@ -537,7 +539,8 @@ enum options_xtrabackup
OPT_XTRA_TABLES_EXCLUDE,
OPT_XTRA_DATABASES_EXCLUDE,
OPT_PROTOCOL
OPT_PROTOCOL,
OPT_LOCK_DDL_PER_TABLE
};
struct my_option xb_client_options[] =
......@@ -1072,6 +1075,11 @@ struct my_option xb_server_options[] =
(G_PTR*) &xb_open_files_limit, (G_PTR*) &xb_open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
{"lock-ddl-per-table", OPT_LOCK_DDL_PER_TABLE, "Lock DDL for each table "
"before xtrabackup starts to copy it and until the backup is completed.",
(uchar*) &opt_lock_ddl_per_table, (uchar*) &opt_lock_ddl_per_table, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
......@@ -2205,6 +2213,10 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
return(FALSE);
}
if (opt_lock_ddl_per_table) {
mdl_lock_table(node->space->id);
}
if (!changed_page_bitmap) {
read_filter = &rf_pass_through;
}
......@@ -2347,10 +2359,18 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn)
scanned_checkpoint = checkpoint;
ulint data_len = log_block_get_data_len(log_block);
scanned_lsn += data_len;
if (data_len != OS_FILE_LOG_BLOCK_SIZE) {
/* The current end of the log was reached. */
if (data_len == OS_FILE_LOG_BLOCK_SIZE) {
/* We got a full log block. */
scanned_lsn += data_len;
} else if (data_len
>= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE
|| data_len <= LOG_BLOCK_HDR_SIZE) {
/* We got a garbage block (abrupt end of the log). */
break;
} else {
/* We got a partial block (abrupt end of the log). */
scanned_lsn += data_len;
break;
}
}
......@@ -2363,7 +2383,7 @@ xtrabackup_copy_log(copy_logfile copy, lsn_t start_lsn, lsn_t end_lsn)
if (ulint write_size = ulint(end_lsn - start_lsn)) {
if (srv_encrypt_log) {
log_crypt(log_sys->buf, write_size);
log_crypt(log_sys->buf, start_lsn, write_size);
}
if (ds_write(dst_log_file, log_sys->buf, write_size)) {
......@@ -3552,6 +3572,10 @@ xtrabackup_backup_func()
"or RENAME TABLE during the backup, inconsistent backup will be "
"produced.\n");
if (opt_lock_ddl_per_table) {
mdl_lock_init();
}
/* initialize components */
if(innodb_init_param()) {
fail:
......@@ -3741,10 +3765,10 @@ xtrabackup_backup_func()
const byte* buf = log_sys->checkpoint_buf;
checkpoint_lsn_start = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
checkpoint_no_start = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
reread_log_header:
checkpoint_lsn_start = log_sys->log.lsn;
checkpoint_no_start = log_sys->next_checkpoint_no;
err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
......@@ -3758,10 +3782,9 @@ xtrabackup_backup_func()
ut_ad(!((log_sys->log.format ^ LOG_HEADER_FORMAT_CURRENT)
& ~LOG_HEADER_FORMAT_ENCRYPTED));
if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) {
log_group_header_read(&log_sys->log, max_cp_field);
checkpoint_lsn_start = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
checkpoint_no_start = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) {
goto reread_log_header;
}
......@@ -3930,6 +3953,10 @@ xtrabackup_backup_func()
goto fail;
}
if (opt_lock_ddl_per_table) {
mdl_unlock_all();
}
xtrabackup_destroy_datasinks();
msg("xtrabackup: Redo log (from LSN " LSN_PF " to " LSN_PF
......
......@@ -193,4 +193,8 @@ xb_get_one_option(int optid,
const char*
xb_get_copy_action(const char *dflt = "Copying");
void mdl_lock_init();
void mdl_lock_table(ulint space_id);
void mdl_unlock_all();
#endif /* XB_XTRABACKUP_H */
......@@ -669,6 +669,36 @@ JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"')
"\u00f6"
select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo');
JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo')
NULL
Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_extract' at position 15
SELECT JSON_OBJECT('foo', '`');
JSON_OBJECT('foo', '`')
{"foo": "`"}
SELECT JSON_OBJECT("foo", "bar`bar");
JSON_OBJECT("foo", "bar`bar")
{"foo": "bar`bar"}
SELECT JSON_SET('{}', '$.age', 87);
JSON_SET('{}', '$.age', 87)
{"age": 87}
SELECT JSON_MERGE('[]', '{"c":"d"}');
JSON_MERGE('[]', '{"c":"d"}')
[{"c": "d"}]
SET @str = "{\"\\u00e4\\u00f6\":\"yes\"}";
SET @path = "$.\"\\u00e4\\u00f6\"";
select @str, @path, JSON_EXTRACT(@str, @path);
@str @path JSON_EXTRACT(@str, @path)
{"\u00e4\u00f6":"yes"} $."\u00e4\u00f6" "yes"
SET @str = "{\"\\u00e4\":\"yes\"}";
SET @path = "$.\"\\u00e4\"";
select @str, @path, JSON_EXTRACT(@str, @path);
@str @path JSON_EXTRACT(@str, @path)
{"\u00e4":"yes"} $."\u00e4" "yes"
select json_array(5,json_query('[1,2]','$'));
json_array(5,json_query('[1,2]','$'))
[5, [1,2]]
#
# Start of 10.3 tests
#
......
......@@ -6638,6 +6638,29 @@ drop table procViewTable;
use test;
drop database bugTest;
#
# MDEV-13436: PREPARE doesn't work as expected & throws errors but
# MySQL is working fine
#
create table t1 (a int);
insert into t1 values (1),(2);
SET @sql_query = "
CREATE VIEW v1 AS
SELECT * FROM (
SELECT CASE WHEN 1 IN (SELECT a from t1 where a < 2) THEN TRUE END AS testcase
) testalias
";
PREPARE stmt FROM @sql_query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `testalias`.`testcase` AS `testcase` from (select case when 1 in (select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` < 2) then 1 end AS `testcase`) `testalias` latin1 latin1_swedish_ci
SELECT * FROM v1;
testcase
1
drop view v1;
drop table t1;
#
# End of 10.2 tests
#
#
......
......@@ -56,6 +56,7 @@ INSERT INTO t1 VALUES("left3", ST_GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1
SET @p = ST_GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))');
SELECT name, ST_AsText(square) from t1 where MBRContains(@p, square);
name ST_AsText(square)
small POLYGON((0 0,0 1,1 1,1 0,0 0))
SELECT name, ST_AsText(square) from t1 where MBRDisjoint(@p, square);
name ST_AsText(square)
up3 POLYGON((0 3,0 5,2 5,2 3,0 3))
......@@ -90,6 +91,7 @@ down2 POLYGON((0 -2,0 0,2 0,2 -2,0 -2))
left2 POLYGON((-2 0,-2 2,0 2,0 0,-2 0))
SELECT name, ST_AsText(square) from t1 where MBRWithin(@p, square);
name ST_AsText(square)
big POLYGON((0 0,0 3,3 3,3 0,0 0))
SET @vert1 = ST_GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))');
SET @horiz1 = ST_GeomFromText('POLYGON ((-2 0, 2 0, -2 0))');
SET @horiz2 = ST_GeomFromText('POLYGON ((-1 0, 3 0, -1 0))');
......@@ -217,7 +219,7 @@ SELECT COUNT(*)
FROM t1
WHERE ST_CONTAINS(ST_GeomFromText('POLYGON((2 2,4 2, 4 4, 2 4, 2 2))'),way);
COUNT(*)
0
9
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
......@@ -226,7 +228,7 @@ SELECT COUNT(*)
FROM t1
WHERE ST_CONTAINS(ST_GeomFromText('POLYGON((2 2,4 2, 4 4, 2 4, 2 2))'),way);
COUNT(*)
0
9
DROP TABLE t1;
CREATE TABLE t1( i INT, g GEOMETRY NOT NULL, SPATIAL INDEX (g)) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, LINESTRING(POINT(1,1), POINT(4, 4)));
......
CREATE TABLE t(i INT) ENGINE INNODB;
INSERT INTO t VALUES(1);
# xtrabackup backup
DROP TABLE t;
--source include/have_debug.inc
CREATE TABLE t(i INT) ENGINE INNODB;
INSERT INTO t VALUES(1);
echo # xtrabackup backup;
let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --lock-ddl-per-table=1 --dbug=+d,check_mdl_lock_works;
--enable_result_log
DROP TABLE t;
rmdir $targetdir;
\ No newline at end of file
--innodb --loose-changed_page_bitmaps --innodb-file-format=Barracuda
\ No newline at end of file
--innodb --loose-changed_page_bitmaps --innodb-file-format=Barracuda --innodb-sys-tables
\ No newline at end of file
......@@ -317,6 +317,44 @@ select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false;
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1;
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
#
# MDEV-129892 JSON_EXTRACT returns data for invalid JSON
#
select JSON_EXTRACT('{"foo": "bar" foobar foo invalid ', '$.foo');
#
# MDEV-13138 JSON_OBJECT returns null with strings containing backticks.
#
SELECT JSON_OBJECT('foo', '`');
SELECT JSON_OBJECT("foo", "bar`bar");
#
# MDEV-13324 JSON_SET returns NULL instead of object.
#
SELECT JSON_SET('{}', '$.age', 87);
#
# MDEV-13104 Json functions.
#
SELECT JSON_MERGE('[]', '{"c":"d"}');
#
# MDEV-12774 JSON_EXTRACT fails with some escaped unicode as key.
#
SET @str = "{\"\\u00e4\\u00f6\":\"yes\"}";
SET @path = "$.\"\\u00e4\\u00f6\"";
select @str, @path, JSON_EXTRACT(@str, @path);
SET @str = "{\"\\u00e4\":\"yes\"}";
SET @path = "$.\"\\u00e4\"";
select @str, @path, JSON_EXTRACT(@str, @path);
#
# MDEV-12877 Wrong result from JSON native function.
#
select json_array(5,json_query('[1,2]','$'));
--echo #
--echo # Start of 10.3 tests
--echo #
......
......@@ -6350,6 +6350,27 @@ drop table procViewTable;
use test;
drop database bugTest;
--echo #
--echo # MDEV-13436: PREPARE doesn't work as expected & throws errors but
--echo # MySQL is working fine
--echo #
create table t1 (a int);
insert into t1 values (1),(2);
SET @sql_query = "
CREATE VIEW v1 AS
SELECT * FROM (
SELECT CASE WHEN 1 IN (SELECT a from t1 where a < 2) THEN TRUE END AS testcase
) testalias
";
PREPARE stmt FROM @sql_query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
show create view v1;
SELECT * FROM v1;
drop view v1;
drop table t1;
--echo #
--echo # End of 10.2 tests
--echo #
......
......@@ -550,7 +550,18 @@ class Item_func_spatial_rel: public Item_bool_func2_with_rev
maybe_null= true;
}
enum Functype functype() const { return spatial_rel; }
enum Functype rev_functype() const { return spatial_rel; }
enum Functype rev_functype() const
{
switch (spatial_rel)
{
case SP_CONTAINS_FUNC:
return SP_WITHIN_FUNC;
case SP_WITHIN_FUNC:
return SP_CONTAINS_FUNC;
default:
return spatial_rel;
}
}
bool is_null() { (void) val_int(); return null_value; }
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
uint *and_level, table_map usable_tables,
......
......@@ -650,6 +650,7 @@ static int alloc_tmp_paths(THD *thd, uint n_paths,
if (*tmp_paths == 0)
{
MEM_ROOT *root= thd->stmt_arena->mem_root;
*paths= (json_path_with_flags *) alloc_root(root,
sizeof(json_path_with_flags) * n_paths);
*tmp_paths= (String *) alloc_root(root, sizeof(String) * n_paths);
......@@ -657,6 +658,8 @@ static int alloc_tmp_paths(THD *thd, uint n_paths,
return 1;
bzero(*tmp_paths, sizeof(String) * n_paths);
for (uint c_path=0; c_path < n_paths; c_path++)
(*tmp_paths)[c_path].set_charset(&my_charset_utf8_general_ci);
}
return 0;
......@@ -821,7 +824,11 @@ String *Item_func_json_extract::read_json(String *str,
not_first_value= 1;
if (!possible_multiple_values)
{
/* Loop to the end of the JSON just to make sure it's valid. */
while (json_get_path_next(&je, &p) == 0) {}
break;
}
}
if (je.s.error)
......@@ -869,7 +876,7 @@ longlong Item_func_json_extract::val_int()
json_value_types type;
char *value;
int value_len;
longlong i;
longlong i= 0;
if (read_json(NULL, &type, &value, &value_len) != NULL)
{
......@@ -1968,14 +1975,25 @@ static int do_merge(String *str, json_engine_t *je1, json_engine_t *je2)
else
{
const uchar *end1, *beg1, *end2, *beg2;
int empty_array= 0;
beg1= je1->value_begin;
/* Merge as a single array. */
if (je1->value_type == JSON_VALUE_ARRAY)
{
if (json_skip_level(je1))
int cur_level= je1->stack_p;
empty_array= 1;
while (json_scan_next(je1) == 0)
{
if (je1->stack_p < cur_level)
break;
empty_array= 0;
}
if (je1->s.error)
return 1;
end1= je1->s.c_str - je1->sav_c_len;
}
else
......@@ -1992,8 +2010,8 @@ static int do_merge(String *str, json_engine_t *je1, json_engine_t *je2)
end1= je1->value_end;
}
if (str->append((const char*) beg1, end1 - beg1),
str->append(", ", 2))
if (str->append((const char*) beg1, end1 - beg1) ||
(!empty_array && str->append(", ", 2)))
return 3;
if (json_value_scalar(je2))
......@@ -2449,6 +2467,8 @@ String *Item_func_json_insert::val_str(String *str)
}
else /*JSON_PATH_KEY*/
{
uint n_key= 0;
if (je.value_type != JSON_VALUE_OBJECT)
continue;
......@@ -2460,6 +2480,7 @@ String *Item_func_json_insert::val_str(String *str)
json_string_set_str(&key_name, lp->key, lp->key_end);
if (json_key_matches(&je, &key_name))
goto v_found;
n_key++;
if (json_skip_key(&je))
goto js_error;
break;
......@@ -2477,7 +2498,8 @@ String *Item_func_json_insert::val_str(String *str)
v_to= (const char *) (je.s.c_str - je.sav_c_len);
str->length(0);
if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
str->append(", \"", 3) ||
(n_key > 0 && str->append(", ", 2)) ||
str->append("\"", 1) ||
append_simple(str, lp->key, lp->key_end - lp->key) ||
str->append("\":", 2) ||
append_json_value(str, args[n_arg+1], &tmp_val) ||
......
......@@ -99,6 +99,7 @@ class Item_func_json_query: public Item_func_json_value
public:
Item_func_json_query(THD *thd, Item *js, Item *i_path):
Item_func_json_value(thd, js, i_path) {}
bool is_json_type() { return true; }
const char *func_name() const { return "json_query"; }
bool check_and_get_value(json_engine_t *je, String *res, int *error);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
......
......@@ -2085,11 +2085,11 @@ static bool mysql_test_create_view(Prepared_statement *stmt)
if (thd->open_temporary_tables(tables))
goto err;
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_PREPARE))
goto err;
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
res= select_like_stmt_test(stmt, 0, 0);
err:
......
......@@ -32,7 +32,11 @@ MDEV-11782: Rewritten for MariaDB 10.2 by Marko Mäkelä, MariaDB Corporation.
/** innodb_encrypt_log: whether to encrypt the redo log */
extern my_bool srv_encrypt_log;
/** Initialize the redo log encryption key.
/** Initialize the redo log encryption key and random parameters
when creating a new redo log.
The random parameters will be persisted in the log checkpoint pages.
@see log_crypt_write_checkpoint_buf()
@see log_crypt_read_checkpoint_buf()
@return whether the operation succeeded */
UNIV_INTERN
bool
......@@ -71,10 +75,11 @@ log_crypt_read_checkpoint_buf(const byte* buf);
/** Encrypt or decrypt log blocks.
@param[in,out] buf log blocks to encrypt or decrypt
@param[in] lsn log sequence number of the start of the buffer
@param[in] size size of the buffer, in bytes
@param[in] decrypt whether to decrypt instead of encrypting */
UNIV_INTERN
void
log_crypt(byte* buf, ulint size, bool decrypt = false);
log_crypt(byte* buf, lsn_t lsn, ulint size, bool decrypt = false);
#endif // log0crypt.h
......@@ -103,11 +103,12 @@ get_crypt_info(ulint checkpoint_no)
/** Encrypt or decrypt log blocks.
@param[in,out] buf log blocks to encrypt or decrypt
@param[in] lsn log sequence number of the start of the buffer
@param[in] size size of the buffer, in bytes
@param[in] decrypt whether to decrypt instead of encrypting */
UNIV_INTERN
void
log_crypt(byte* buf, ulint size, bool decrypt)
log_crypt(byte* buf, lsn_t lsn, ulint size, bool decrypt)
{
ut_ad(size % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a(info.key_version);
......@@ -117,12 +118,12 @@ log_crypt(byte* buf, ulint size, bool decrypt)
compile_time_assert(sizeof(uint32_t) == 4);
#define LOG_CRYPT_HDR_SIZE 4
lsn &= ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1);
for (const byte* const end = buf + size; buf != end;
buf += OS_FILE_LOG_BLOCK_SIZE) {
buf += OS_FILE_LOG_BLOCK_SIZE, lsn += OS_FILE_LOG_BLOCK_SIZE) {
uint32_t dst[(OS_FILE_LOG_BLOCK_SIZE - LOG_CRYPT_HDR_SIZE)
/ sizeof(uint32_t)];
const ulint log_block_no = log_block_get_hdr_no(buf);
/* The log block number is not encrypted. */
*aes_ctr_iv =
......@@ -137,10 +138,10 @@ log_crypt(byte* buf, ulint size, bool decrypt)
# error "LOG_BLOCK_HDR_NO has been moved; redo log format affected!"
#endif
aes_ctr_iv[1] = info.crypt_nonce.word;
mach_write_to_8(reinterpret_cast<byte*>(aes_ctr_iv + 2),
log_block_get_start_lsn(
decrypt ? srv_start_lsn : log_sys->lsn,
log_block_no));
mach_write_to_8(reinterpret_cast<byte*>(aes_ctr_iv + 2), lsn);
ut_ad(log_block_get_start_lsn(lsn,
log_block_get_hdr_no(buf))
== lsn);
int rc = encryption_crypt(
buf + LOG_CRYPT_HDR_SIZE, sizeof dst,
......@@ -206,7 +207,11 @@ init_crypt_key(crypt_info_t* info, bool upgrade = false)
return true;
}
/** Initialize the redo log encryption key.
/** Initialize the redo log encryption key and random parameters
when creating a new redo log.
The random parameters will be persisted in the log checkpoint pages.
@see log_crypt_write_checkpoint_buf()
@see log_crypt_read_checkpoint_buf()
@return whether the operation succeeded */
UNIV_INTERN
bool
......
......@@ -997,10 +997,6 @@ log_group_write_buf(
|| log_block_get_hdr_no(buf)
== log_block_convert_lsn_to_no(start_lsn));
if (log_sys->is_encrypted()) {
log_crypt(buf, write_len);
}
/* Calculate the checksums for each log block and write them to
the trailer fields of the log blocks */
......@@ -1264,6 +1260,12 @@ log_write_up_to(
::memset(write_buf + area_end, 0, pad_size);
}
}
if (log_sys->is_encrypted()) {
log_crypt(write_buf + area_start, log_sys->write_lsn,
area_end - area_start);
}
/* Do the write to the log files */
log_group_write_buf(
&log_sys->log, write_buf + area_start,
......
......@@ -715,7 +715,8 @@ log_group_read_log_seg(
}
if (group->is_encrypted()) {
log_crypt(buf, OS_FILE_LOG_BLOCK_SIZE, true);
log_crypt(buf, start_lsn,
OS_FILE_LOG_BLOCK_SIZE, true);
}
}
}
......@@ -1016,6 +1017,7 @@ recv_find_max_checkpoint(ulint* max_field)
buf + LOG_CHECKPOINT_LSN);
group->lsn_offset = mach_read_from_8(
buf + LOG_CHECKPOINT_OFFSET);
log_sys->next_checkpoint_no = checkpoint_no;
}
}
......
......@@ -2223,14 +2223,6 @@ innobase_start_or_create_for_mysql()
recv_sys->dblwr.pages.clear();
if (err == DB_SUCCESS && !srv_read_only_mode) {
log_mutex_enter();
if (log_sys->is_encrypted() && !log_crypt_init()) {
err = DB_ERROR;
}
log_mutex_exit();
}
if (err == DB_SUCCESS) {
/* Initialize the change buffer. */
err = dict_boot();
......@@ -2733,13 +2725,6 @@ innobase_start_or_create_for_mysql()
fil_crypt_threads_init();
fil_system_exit();
/*
Create a checkpoint before logging anything new, so that
the current encryption key in use is definitely logged
before any log blocks encrypted with that key.
*/
log_make_checkpoint_at(LSN_MAX, TRUE);
/* Initialize online defragmentation. */
btr_defragment_init();
btr_defragment_thread_active = true;
......
......@@ -619,6 +619,7 @@ trx_free_prepared(
|| (trx_state_eq(trx, TRX_STATE_ACTIVE)
&& trx->is_recovered
&& (!srv_was_started
|| srv_operation == SRV_OPERATION_RESTORE
|| srv_read_only_mode
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)));
ut_a(trx->magic_n == TRX_MAGIC_N);
......
......@@ -402,12 +402,20 @@ analyze table t1;
-- enable_query_log
# index_merge on first table in join
if ($index_merge_random_rows_in_EXPLAIN)
{
--replace_column 9 #
}
explain select * from t0 left join t1 on (t0.key1=t1.key1)
where t0.key1=3 or t0.key2=4;
select * from t0 left join t1 on (t0.key1=t1.key1)
where t0.key1=3 or t0.key2=4;
if ($index_merge_random_rows_in_EXPLAIN)
{
--replace_column 9 #
}
explain
select * from t0,t1 where (t0.key1=t1.key1) and ( t0.key1=3 or t0.key2=4);
......
......@@ -250,8 +250,8 @@ insert into t1 select * from t0;
explain select * from t0 left join t1 on (t0.key1=t1.key1)
where t0.key1=3 or t0.key2=4;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 2
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using union(i1,i2); Using where
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 #
select * from t0 left join t1 on (t0.key1=t1.key1)
where t0.key1=3 or t0.key2=4;
key1 key2 key3 key4 key5 key6 key7 key8 key1 key2 key3 key4 key5 key6 key7 key8
......@@ -260,8 +260,8 @@ key1 key2 key3 key4 key5 key6 key7 key8 key1 key2 key3 key4 key5 key6 key7 key8
explain
select * from t0,t1 where (t0.key1=t1.key1) and ( t0.key1=3 or t0.key2=4);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 2
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL # Using union(i1,i2); Using where
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 #
explain
select * from t0,t1 where (t0.key1=t1.key1) and
(t0.key1=3 or t0.key2<4) and t1.key1=2;
......
......@@ -1586,7 +1586,7 @@ int json_escape(CHARSET_INFO *str_cs,
enum json_esc_char_classes c_class;
str+= c_len;
if (c_chr > 0x60 || (c_class= json_escape_chr_map[c_chr]) == ESC_)
if (c_chr >= 0x60 || (c_class= json_escape_chr_map[c_chr]) == ESC_)
{
if ((c_len= json_cs->cset->wc_mb(json_cs, c_chr, json, json_end)) > 0)
{
......
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