Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
1eb2d8f6
Commit
1eb2d8f6
authored
Aug 16, 2018
by
Marko Mäkelä
Browse files
Options
Browse Files
Download
Plain Diff
Merge 10.2 into 10.3
parents
197aa0d8
05153a67
Changes
43
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
1438 additions
and
469 deletions
+1438
-469
extra/mariabackup/backup_copy.cc
extra/mariabackup/backup_copy.cc
+30
-0
extra/mariabackup/backup_mysql.cc
extra/mariabackup/backup_mysql.cc
+6
-1
extra/mariabackup/datasink.c
extra/mariabackup/datasink.c
+3
-0
extra/mariabackup/fil_cur.cc
extra/mariabackup/fil_cur.cc
+29
-9
extra/mariabackup/fil_cur.h
extra/mariabackup/fil_cur.h
+3
-2
extra/mariabackup/xtrabackup.cc
extra/mariabackup/xtrabackup.cc
+522
-48
mysql-test/suite/mariabackup/create_during_backup.result
mysql-test/suite/mariabackup/create_during_backup.result
+10
-0
mysql-test/suite/mariabackup/create_during_backup.test
mysql-test/suite/mariabackup/create_during_backup.test
+26
-0
mysql-test/suite/mariabackup/create_with_data_directory_during_backup.result
...riabackup/create_with_data_directory_during_backup.result
+10
-0
mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test
...mariabackup/create_with_data_directory_during_backup.test
+24
-0
mysql-test/suite/mariabackup/disabled.def
mysql-test/suite/mariabackup/disabled.def
+1
-1
mysql-test/suite/mariabackup/drop_table_during_backup.result
mysql-test/suite/mariabackup/drop_table_during_backup.result
+13
-0
mysql-test/suite/mariabackup/drop_table_during_backup.test
mysql-test/suite/mariabackup/drop_table_during_backup.test
+24
-0
mysql-test/suite/mariabackup/incremental_ddl_during_backup.result
...st/suite/mariabackup/incremental_ddl_during_backup.result
+22
-0
mysql-test/suite/mariabackup/incremental_ddl_during_backup.test
...test/suite/mariabackup/incremental_ddl_during_backup.test
+52
-0
mysql-test/suite/mariabackup/mlog_index_load.result
mysql-test/suite/mariabackup/mlog_index_load.result
+15
-0
mysql-test/suite/mariabackup/mlog_index_load.test
mysql-test/suite/mariabackup/mlog_index_load.test
+27
-0
mysql-test/suite/mariabackup/recreate_table_during_backup.result
...est/suite/mariabackup/recreate_table_during_backup.result
+23
-0
mysql-test/suite/mariabackup/recreate_table_during_backup.test
...-test/suite/mariabackup/recreate_table_during_backup.test
+37
-0
mysql-test/suite/mariabackup/rename_during_backup.result
mysql-test/suite/mariabackup/rename_during_backup.result
+53
-0
mysql-test/suite/mariabackup/rename_during_backup.test
mysql-test/suite/mariabackup/rename_during_backup.test
+86
-0
mysql-test/suite/mariabackup/rename_during_mdl_lock.result
mysql-test/suite/mariabackup/rename_during_mdl_lock.result
+9
-1
mysql-test/suite/mariabackup/rename_during_mdl_lock.test
mysql-test/suite/mariabackup/rename_during_mdl_lock.test
+14
-6
mysql-test/suite/mariabackup/suite.opt
mysql-test/suite/mariabackup/suite.opt
+1
-1
mysql-test/suite/mariabackup/xb_aws_key_management.result
mysql-test/suite/mariabackup/xb_aws_key_management.result
+2
-0
storage/innobase/fil/fil0fil.cc
storage/innobase/fil/fil0fil.cc
+21
-28
storage/innobase/include/fil0fil.h
storage/innobase/include/fil0fil.h
+3
-0
storage/innobase/include/lock0lock.h
storage/innobase/include/lock0lock.h
+0
-63
storage/innobase/include/lock0priv.h
storage/innobase/include/lock0priv.h
+3
-136
storage/innobase/include/lock0priv.ic
storage/innobase/include/lock0priv.ic
+3
-9
storage/innobase/include/lock0types.h
storage/innobase/include/lock0types.h
+191
-1
storage/innobase/include/log0recv.h
storage/innobase/include/log0recv.h
+15
-3
storage/innobase/include/trx0sys.h
storage/innobase/include/trx0sys.h
+5
-2
storage/innobase/include/trx0trx.h
storage/innobase/include/trx0trx.h
+15
-7
storage/innobase/include/ut0pool.h
storage/innobase/include/ut0pool.h
+10
-10
storage/innobase/lock/lock0lock.cc
storage/innobase/lock/lock0lock.cc
+18
-67
storage/innobase/log/log0recv.cc
storage/innobase/log/log0recv.cc
+60
-33
storage/innobase/mtr/mtr0log.cc
storage/innobase/mtr/mtr0log.cc
+5
-1
storage/innobase/page/page0cur.cc
storage/innobase/page/page0cur.cc
+4
-1
storage/innobase/trx/trx0trx.cc
storage/innobase/trx/trx0trx.cc
+11
-36
storage/rocksdb/build_rocksdb.cmake
storage/rocksdb/build_rocksdb.cmake
+24
-2
storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug-master.opt
...age/rocksdb/mysql-test/rocksdb/t/autoinc_debug-master.opt
+1
-1
storage/rocksdb/mysql-test/rocksdb/t/bulk_load_errors.test
storage/rocksdb/mysql-test/rocksdb/t/bulk_load_errors.test
+7
-0
No files found.
extra/mariabackup/backup_copy.cc
View file @
1eb2d8f6
...
...
@@ -1384,6 +1384,30 @@ backup_files(const char *from, bool prep_mode)
return
(
ret
);
}
void
backup_fix_ddl
(
void
);
#define LSN_PREFIX_IN_SHOW_STATUS "\nLog sequence number "
static
lsn_t
get_current_lsn
(
MYSQL
*
connection
)
{
MYSQL_RES
*
res
=
xb_mysql_query
(
connection
,
"SHOW ENGINE INNODB STATUS"
,
true
,
false
);
if
(
!
res
)
return
0
;
MYSQL_ROW
row
=
mysql_fetch_row
(
res
);
DBUG_ASSERT
(
row
);
if
(
row
)
{
const
char
*
p
=
strstr
(
row
[
2
],
LSN_PREFIX_IN_SHOW_STATUS
);
DBUG_ASSERT
(
p
);
if
(
p
)
{
p
+=
sizeof
(
LSN_PREFIX_IN_SHOW_STATUS
)
-
1
;
return
(
lsn_t
)
strtoll
(
p
,
NULL
,
10
);
}
}
mysql_free_result
(
res
);
return
0
;
}
lsn_t
server_lsn_after_lock
;
extern
void
backup_wait_for_lsn
(
lsn_t
lsn
);
/** Start --backup */
bool
backup_start
()
{
...
...
@@ -1403,6 +1427,7 @@ bool backup_start()
if
(
!
lock_tables
(
mysql_connection
))
{
return
(
false
);
}
server_lsn_after_lock
=
get_current_lsn
(
mysql_connection
);
}
if
(
!
backup_files
(
fil_path_to_mysql_datadir
,
false
))
{
...
...
@@ -1417,6 +1442,10 @@ bool backup_start()
rocksdb_create_checkpoint
();
}
msg_ts
(
"Waiting for log copy thread to read lsn %llu
\n
"
,
(
ulonglong
)
server_lsn_after_lock
);
backup_wait_for_lsn
(
server_lsn_after_lock
);
backup_fix_ddl
();
// There is no need to stop slave thread before coping non-Innodb data when
// --no-lock option is used because --no-lock option requires that no DDL or
// DML to non-transaction tables can occur.
...
...
@@ -2226,6 +2255,7 @@ static void rocksdb_lock_checkpoint()
msg_ts
(
"Could not obtain rocksdb checkpont lock
\n
"
);
exit
(
EXIT_FAILURE
);
}
mysql_free_result
(
res
);
}
static
void
rocksdb_unlock_checkpoint
()
...
...
extra/mariabackup/backup_mysql.cc
View file @
1eb2d8f6
...
...
@@ -1795,7 +1795,12 @@ mdl_lock_table(ulint space_id)
std
::
ostringstream
lock_query
;
lock_query
<<
"SELECT 1 FROM "
<<
full_table_name
<<
" LIMIT 0"
;
msg_ts
(
"Locking MDL for %s
\n
"
,
full_table_name
.
c_str
());
xb_mysql_query
(
mdl_con
,
lock_query
.
str
().
c_str
(),
false
,
true
);
if
(
mysql_query
(
mdl_con
,
lock_query
.
str
().
c_str
()))
{
msg_ts
(
"Warning : locking MDL failed for space id %zu, name %s
\n
"
,
space_id
,
full_table_name
.
c_str
());
}
else
{
MYSQL_RES
*
r
=
mysql_store_result
(
mdl_con
);
mysql_free_result
(
r
);
}
}
pthread_mutex_unlock
(
&
mdl_lock_con_mutex
);
...
...
extra/mariabackup/datasink.c
View file @
1eb2d8f6
...
...
@@ -109,6 +109,9 @@ Write to a datasink file.
int
ds_write
(
ds_file_t
*
file
,
const
void
*
buf
,
size_t
len
)
{
if
(
len
==
0
)
{
return
0
;
}
return
file
->
datasink
->
write
(
file
,
(
const
uchar
*
)
buf
,
len
);
}
...
...
extra/mariabackup/fil_cur.cc
View file @
1eb2d8f6
...
...
@@ -130,14 +130,15 @@ Open a source file cursor and initialize the associated read filter.
be skipped and XB_FIL_CUR_ERROR on error. */
xb_fil_cur_result_t
xb_fil_cur_open
(
/*============*/
/*============*/
xb_fil_cur_t
*
cursor
,
/*!< out: source file cursor */
xb_read_filt_t
*
read_filter
,
/*!< in/out: the read filter */
fil_node_t
*
node
,
/*!< in: source tablespace node */
uint
thread_n
)
/*!< thread number for diagnostics */
uint
thread_n
,
/*!< thread number for diagnostics */
ulonglong
max_file_size
)
{
bool
success
;
int
err
;
/* Initialize these first so xb_fil_cur_close() handles them correctly
in case of error */
cursor
->
orig_buf
=
NULL
;
...
...
@@ -172,7 +173,7 @@ xb_fil_cur_open(
"tablespace %s
\n
"
,
thread_n
,
cursor
->
abs_path
);
return
(
XB_FIL_CUR_
ERROR
);
return
(
XB_FIL_CUR_
SKIP
);
}
mutex_enter
(
&
fil_system
.
mutex
);
...
...
@@ -193,14 +194,31 @@ xb_fil_cur_open(
cursor
->
node
=
node
;
cursor
->
file
=
node
->
handle
;
if
(
stat
(
cursor
->
abs_path
,
&
cursor
->
statinfo
))
{
msg
(
"[%02u] mariabackup: error: cannot stat %s
\n
"
,
#ifdef _WIN32
HANDLE
hDup
;
DuplicateHandle
(
GetCurrentProcess
(),
cursor
->
file
.
m_file
,
GetCurrentProcess
(),
&
hDup
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
);
int
filenr
=
_open_osfhandle
((
intptr_t
)
hDup
,
0
);
if
(
filenr
<
0
)
{
err
=
EINVAL
;
}
else
{
err
=
_fstat64
(
filenr
,
&
cursor
->
statinfo
);
close
(
filenr
);
}
#else
err
=
fstat
(
cursor
->
file
.
m_file
,
&
cursor
->
statinfo
);
#endif
if
(
max_file_size
<
(
ulonglong
)
cursor
->
statinfo
.
st_size
)
{
cursor
->
statinfo
.
st_size
=
(
ulonglong
)
max_file_size
;
}
if
(
err
)
{
msg
(
"[%02u] mariabackup: error: cannot fstat %s
\n
"
,
thread_n
,
cursor
->
abs_path
);
xb_fil_cur_close
(
cursor
);
return
(
XB_FIL_CUR_
ERROR
);
return
(
XB_FIL_CUR_
SKIP
);
}
if
(
srv_file_flush_method
==
SRV_O_DIRECT
...
...
@@ -373,7 +391,9 @@ xb_fil_cur_close(
/*=============*/
xb_fil_cur_t
*
cursor
)
/*!< in/out: source file cursor */
{
cursor
->
read_filter
->
deinit
(
&
cursor
->
read_filter_ctxt
);
if
(
cursor
->
read_filter
)
{
cursor
->
read_filter
->
deinit
(
&
cursor
->
read_filter_ctxt
);
}
free
(
cursor
->
orig_buf
);
...
...
extra/mariabackup/fil_cur.h
View file @
1eb2d8f6
...
...
@@ -58,7 +58,7 @@ struct xb_fil_cur_t {
ulint
space_size
;
/*!< space size in pages */
/** TODO: remove this default constructor */
xb_fil_cur_t
()
:
page_size
(
0
),
read_filter_ctxt
()
{}
xb_fil_cur_t
()
:
page_size
(
0
),
read_filter
(
0
),
read_filter
_ctxt
()
{}
/** @return whether this is not a file-per-table tablespace */
bool
is_system
()
const
...
...
@@ -87,7 +87,8 @@ xb_fil_cur_open(
xb_fil_cur_t
*
cursor
,
/*!< out: source file cursor */
xb_read_filt_t
*
read_filter
,
/*!< in/out: the read filter */
fil_node_t
*
node
,
/*!< in: source tablespace node */
uint
thread_n
);
/*!< thread number for diagnostics */
uint
thread_n
,
/*!< thread number for diagnostics */
ulonglong
max_file_size
=
ULLONG_MAX
);
/************************************************************************
Reads and verifies the next block of pages from the source
...
...
extra/mariabackup/xtrabackup.cc
View file @
1eb2d8f6
This diff is collapsed.
Click to expand it.
mysql-test/suite/mariabackup/create_during_backup.result
0 → 100644
View file @
1eb2d8f6
# xtrabackup backup
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT COUNT(*) from t1;
COUNT(*)
10000
DROP TABLE t1;
mysql-test/suite/mariabackup/create_during_backup.test
0 → 100644
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
mkdir
$targetdir
;
# this will table and populate it, after backup has list of tables to be copied
--
let
after_load_tablespaces
=
CREATE
TABLE
test
.
t1
ENGINE
=
INNODB
SELECT
UUID
()
from
test
.
seq_1_to_10000
echo
# xtrabackup backup;
--
disable_result_log
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
dbug
=+
d
,
mariabackup_events
;
--
enable_result_log
--
let
after_load_tables
=
echo
# xtrabackup prepare;
--
disable_result_log
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$targetdir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
# Check that new table is there after restore.
SELECT
COUNT
(
*
)
from
t1
;
DROP
TABLE
t1
;
rmdir
$targetdir
;
mysql-test/suite/mariabackup/create_with_data_directory_during_backup.result
0 → 100644
View file @
1eb2d8f6
# xtrabackup backup
# xtrabackup prepare
DROP TABLE t;
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT * FROM t;
i
DROP TABLE t;
mysql-test/suite/mariabackup/create_with_data_directory_during_backup.test
0 → 100644
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
let
$table_data_dir
=
$MYSQLTEST_VARDIR
/
tmp
/
ddir
;
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
mkdir
$table_data_dir
;
--
replace_result
$table_data_dir
table_data_dir
--
let
after_load_tablespaces
=
CREATE
TABLE
test
.
t
(
i
int
)
ENGINE
=
INNODB
DATA
DIRECTORY
=
'$table_data_dir'
echo
# xtrabackup backup;
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
--
disable_result_log
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
dbug
=+
d
,
mariabackup_events
;
--
enable_result_log
--
source
include
/
shutdown_mysqld
.
inc
echo
# xtrabackup prepare;
--
disable_result_log
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$targetdir
;
--
source
include
/
start_mysqld
.
inc
DROP
TABLE
t
;
rmdir
$table_data_dir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
SELECT
*
FROM
t
;
DROP
TABLE
t
;
rmdir
$targetdir
;
rmdir
$table_data_dir
;
mysql-test/suite/mariabackup/disabled.def
View file @
1eb2d8f6
unsupported_redo : MDEV-16791 allows optimized redo
\ No newline at end of file
mysql-test/suite/mariabackup/drop_table_during_backup.result
0 → 100644
View file @
1eb2d8f6
CREATE TABLE t1 (i int) ENGINE=INNODB;
CREATE TABLE t2 (i int) ENGINE=INNODB;
CREATE TABLE t3 (i int) ENGINE=INNODB;
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
CREATE TABLE t2(i int);
DROP TABLE t2;
DROP TABLE t3;
mysql-test/suite/mariabackup/drop_table_during_backup.test
0 → 100644
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
CREATE
TABLE
t1
(
i
int
)
ENGINE
=
INNODB
;
CREATE
TABLE
t2
(
i
int
)
ENGINE
=
INNODB
;
CREATE
TABLE
t3
(
i
int
)
ENGINE
=
INNODB
;
--
let
before_copy_test_t1
=
DROP
TABLE
test
.
t1
--
let
after_copy_test_t2
=
DROP
TABLE
test
.
t2
;
--
disable_result_log
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
dbug
=+
d
,
mariabackup_events
;
--
enable_result_log
echo
# xtrabackup prepare;
--
disable_result_log
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$targetdir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
#check that the table t1 does not exist in backup
CREATE
TABLE
t1
(
i
int
);
DROP
TABLE
t1
;
CREATE
TABLE
t2
(
i
int
);
DROP
TABLE
t2
;
DROP
TABLE
t3
;
rmdir
$targetdir
;
mysql-test/suite/mariabackup/incremental_ddl_during_backup.result
0 → 100644
View file @
1eb2d8f6
call mtr.add_suppression("InnoDB: New log files created");
CREATE TABLE t1(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
CREATE TABLE t3(i INT) ENGINE INNODB;
# Create full backup , modify table, then create incremental/differential backup
INSERT into t1 values(1);
# Prepare full backup, apply incremental one
# Restore and check results
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t1_renamed;
i
1
DROP TABLE t1_renamed;
CREATE TABLE t2(i INT PRIMARY KEY) ENGINE INNODB;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
mysql-test/suite/mariabackup/incremental_ddl_during_backup.test
0 → 100644
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
call
mtr
.
add_suppression
(
"InnoDB: New log files created"
);
let
$basedir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
let
$incremental_dir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup_inc1
;
CREATE
TABLE
t1
(
i
INT
PRIMARY
KEY
)
ENGINE
INNODB
;
CREATE
TABLE
t2
(
i
INT
PRIMARY
KEY
)
ENGINE
INNODB
;
CREATE
TABLE
t3
(
i
INT
)
ENGINE
INNODB
;
echo
# Create full backup , modify table, then create incremental/differential backup;
--
disable_result_log
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$basedir
;
--
enable_result_log
INSERT
into
t1
values
(
1
);
--
let
after_load_tablespaces
=
CREATE
TABLE
test
.
t4
ENGINE
=
INNODB
SELECT
UUID
()
from
test
.
seq_1_to_10000
--
let
after_copy_test_t1
=
RENAME
TABLE
test
.
t1
TO
test
.
t1_renamed
--
let
after_copy_test_t2
=
DROP
TABLE
test
.
t2
--
let
after_copy_test_t3
=
CREATE
INDEX
a_i
ON
test
.
t3
(
i
);
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$incremental_dir
--
incremental
-
basedir
=
$basedir
--
dbug
=+
d
,
mariabackup_events
;
--
let
after_load_tablespaces
=
--
disable_result_log
echo
# Prepare full backup, apply incremental one;
exec
$XTRABACKUP
--
apply
-
log
-
only
--
prepare
--
target
-
dir
=
$basedir
;
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$basedir
--
incremental
-
dir
=
$incremental_dir
;
echo
# Restore and check results;
let
$targetdir
=
$basedir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
# Test that t1 does not exist, but t1_renamed does
CREATE
TABLE
t1
(
i
int
);
DROP
TABLE
t1
;
SELECT
*
from
t1_renamed
;
DROP
TABLE
t1_renamed
;
# Test that t2 does not exist;
CREATE
TABLE
t2
(
i
INT
PRIMARY
KEY
)
ENGINE
INNODB
;
DROP
TABLE
t2
;
DROP
TABLE
t3
;
DROP
TABLE
t4
;
# Cleanup
rmdir
$basedir
;
rmdir
$incremental_dir
;
mysql-test/suite/mariabackup/mlog_index_load.result
0 → 100644
View file @
1eb2d8f6
CREATE TABLE t1(i INT PRIMARY KEY auto_increment, a int) ENGINE INNODB;
INSERT INTO t1(a) SELECT * from seq_1_to_10000;
# xtrabackup backup
t1.frm
t1.ibd
t1.new
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT COUNT(*) from t1;
COUNT(*)
10000
DROP TABLE t1;
mysql-test/suite/mariabackup/mlog_index_load.test
0 → 100644
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
CREATE
TABLE
t1
(
i
INT
PRIMARY
KEY
auto_increment
,
a
int
)
ENGINE
INNODB
;
INSERT
INTO
t1
(
a
)
SELECT
*
from
seq_1_to_10000
;
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
let
after_copy_test_t1
=
CREATE
INDEX
a_ind
ON
test
.
t1
(
a
)
ALGORITHM
=
INPLACE
;
echo
# xtrabackup backup;
--
disable_result_log
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
dbug
=+
d
,
mariabackup_events
;
--
enable_result_log
--
list_files
$targetdir
/
test
t1
*
--
let
before_copy_test_t1
=
echo
# xtrabackup prepare;
--
disable_result_log
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$targetdir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
# Check that new table is there after restore.
SELECT
COUNT
(
*
)
from
t1
;
DROP
TABLE
t1
;
rmdir
$targetdir
;
mysql-test/suite/mariabackup/recreate_table_during_backup.result
0 → 100644
View file @
1eb2d8f6
CREATE TABLE t1(i int) ENGINE=INNODB;
CREATE TABLE t2(i int) ENGINE=INNODB;
CREATE TABLE t3(a CHAR(36)) ENGINE INNODB;
INSERT INTO t3 SELECT UUID() FROM seq_1_to_1000;
# xtrabackup backup
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT COUNT(*) from t1;
COUNT(*)
100
SELECT COUNT(*) from t2;
COUNT(*)
1000
SELECT COUNT(*) from t3;
COUNT(*)
1000
DROP INDEX index_a ON t3;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
mysql-test/suite/mariabackup/recreate_table_during_backup.test
0 → 100644
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
mkdir
$targetdir
;
CREATE
TABLE
t1
(
i
int
)
ENGINE
=
INNODB
;
CREATE
TABLE
t2
(
i
int
)
ENGINE
=
INNODB
;
CREATE
TABLE
t3
(
a
CHAR
(
36
))
ENGINE
INNODB
;
INSERT
INTO
t3
SELECT
UUID
()
FROM
seq_1_to_1000
;
# this will table and populate it, after backup has list of tables to be copied
--
let
before_copy_test_t1
=
BEGIN
NOT
ATOMIC
DROP
TABLE
test
.
t1
;
CREATE
TABLE
test
.
t1
ENGINE
=
INNODB
SELECT
UUID
()
from
test
.
seq_1_to_100
;
END
--
let
after_copy_test_t2
=
BEGIN
NOT
ATOMIC
DROP
TABLE
test
.
t2
;
CREATE
TABLE
test
.
t2
ENGINE
=
INNODB
SELECT
UUID
()
from
test
.
seq_1_to_1000
;
END
--
let
after_copy_test_t3
=
ALTER
TABLE
test
.
t3
ADD
INDEX
index_a
(
a
),
ALGORITHM
=
COPY
echo
# xtrabackup backup;
--
disable_result_log
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
close
-
files
--
dbug
=+
d
,
mariabackup_events
;
--
enable_result_log
--
let
after_load_tables
=
echo
# xtrabackup prepare;
--
disable_result_log
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$targetdir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
# Check that new table is there after restore.
SELECT
COUNT
(
*
)
from
t1
;
SELECT
COUNT
(
*
)
from
t2
;
SELECT
COUNT
(
*
)
from
t3
;
DROP
INDEX
index_a
ON
t3
;
DROP
TABLE
t1
;
DROP
TABLE
t2
;
DROP
TABLE
t3
;
rmdir
$targetdir
;
mysql-test/suite/mariabackup/rename_during_backup.result
0 → 100644
View file @
1eb2d8f6
CREATE TABLE t1(i int) ENGINE INNODB;
INSERT into t1 values(1);
CREATE TABLE t2(i int) ENGINE INNODB;
INSERT INTO t2 values(2);
CREATE TABLE t3(i int) ENGINE INNODB;
CREATE TABLE t4(i int) ENGINE INNODB;
CREATE TABLE a(a int) ENGINE INNODB;
INSERT INTO a values(1);
CREATE TABLE b(b CHAR(1)) ENGINE INNODB;
INSERT INTO b VALUES('b');
CREATE TABLE a1(a1 int) ENGINE INNODB;
INSERT INTO a1 VALUES(1);
CREATE TABLE b1(b1 CHAR(2)) ENGINE INNODB;
INSERT INTO b1 VALUES('b1');
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t1_renamed;
i
1
DROP TABLE t1_renamed;
CREATE TABLE t2(i int);
DROP TABLE t2;
SELECT * from t2_renamed;
i
2
DROP TABLE t2_renamed;
SELECT * from t3;
i
3
DROP TABLE t3;
SELECT * from t4;
i
DROP TABLE t4;
CREATE TABLE tmp(i int);
DROP TABLE tmp;
SELECT * FROM a;
b
b
SELECT * FROM b;
a
1
SELECT * FROM a1;
b1
b1
SELECT * FROM b1;
a1
1
DROP TABLE a,b,a1,b1;
mysql-test/suite/mariabackup/rename_during_backup.test
0 → 100644
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
mkdir
$targetdir
;
CREATE
TABLE
t1
(
i
int
)
ENGINE
INNODB
;
INSERT
into
t1
values
(
1
);
CREATE
TABLE
t2
(
i
int
)
ENGINE
INNODB
;
INSERT
INTO
t2
values
(
2
);
CREATE
TABLE
t3
(
i
int
)
ENGINE
INNODB
;
CREATE
TABLE
t4
(
i
int
)
ENGINE
INNODB
;
CREATE
TABLE
a
(
a
int
)
ENGINE
INNODB
;
INSERT
INTO
a
values
(
1
);
CREATE
TABLE
b
(
b
CHAR
(
1
))
ENGINE
INNODB
;
INSERT
INTO
b
VALUES
(
'b'
);
CREATE
TABLE
a1
(
a1
int
)
ENGINE
INNODB
;
INSERT
INTO
a1
VALUES
(
1
);
CREATE
TABLE
b1
(
b1
CHAR
(
2
))
ENGINE
INNODB
;
INSERT
INTO
b1
VALUES
(
'b1'
);
# Test renames before of after copying tablespaces
--
let
before_copy_test_t1
=
RENAME
TABLE
test
.
t1
TO
test
.
t1_renamed
--
let
after_copy_test_t2
=
RENAME
TABLE
test
.
t2
TO
test
.
t2_renamed
--
let
after_copy_test_t3
=
BEGIN
NOT
ATOMIC
RENAME
TABLE
test
.
t3
TO
test
.
t3_tmp
;
INSERT
INTO
test
.
t3_tmp
VALUES
(
3
);
RENAME
TABLE
test
.
t3_tmp
TO
test
.
t3
;
END
--
let
before_copy_test_t4
=
RENAME
TABLE
test
.
t4
TO
test
.
t4_tmp
--
let
after_copy_test_t4
=
RENAME
TABLE
test
.
t4_tmp
TO
test
.
t4
# Test circular renames
--
let
before_copy_test_b
=
RENAME
TABLE
test
.
a
to
test
.
tmp
,
test
.
b
to
test
.
a
,
test
.
tmp
to
test
.
b
--
let
after_copy_test_b1
=
RENAME
TABLE
test
.
a1
to
test
.
tmp
,
test
.
b1
to
test
.
a1
,
test
.
tmp
to
test
.
b1
--
disable_result_log
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
dbug
=+
d
,
mariabackup_events
;
--
enable_result_log
--
let
before_copy_test_t1
=
''
--
let
after_copy_test_t2
=
''
--
let
before_copy_test_a
=
''
--
let
after_copy_test_a1
=
''
echo
# xtrabackup prepare;
--
disable_result_log
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$targetdir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
# the table was renamed from t1 to t1_renamed
# make sure t1 does not exist, and t1_renamed does.
CREATE
TABLE
t1
(
i
int
);
DROP
TABLE
t1
;
SELECT
*
from
t1_renamed
;
DROP
TABLE
t1_renamed
;
CREATE
TABLE
t2
(
i
int
);
DROP
TABLE
t2
;
SELECT
*
from
t2_renamed
;
DROP
TABLE
t2_renamed
;
#rename to itself
SELECT
*
from
t3
;
DROP
TABLE
t3
;
SELECT
*
from
t4
;
DROP
TABLE
t4
;
# For circular renames , make sure intermediate tables do not exist
CREATE
TABLE
tmp
(
i
int
);
DROP
TABLE
tmp
;
SELECT
*
FROM
a
;
SELECT
*
FROM
b
;
SELECT
*
FROM
a1
;
SELECT
*
FROM
b1
;
DROP
TABLE
a
,
b
,
a1
,
b1
;
rmdir
$targetdir
;
mysql-test/suite/mariabackup/rename_during_mdl_lock.result
View file @
1eb2d8f6
CREATE TABLE t1(i int) ENGINE INNODB;
FOUND 1 /failed to execute query SELECT 1 FROM/ in backup.log
# xtrabackup prepare
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
CREATE TABLE t1(i int);
DROP TABLE t1;
SELECT * from t2;
i
DROP TABLE t2;
mysql-test/suite/mariabackup/rename_during_mdl_lock.test
View file @
1eb2d8f6
--
source
include
/
have_debug
.
inc
let
$targetdir
=
$MYSQLTEST_VARDIR
/
backup
;
let
$targetdir
=
$MYSQLTEST_VARDIR
/
tmp
/
backup
;
mkdir
$targetdir
;
CREATE
TABLE
t1
(
i
int
)
ENGINE
INNODB
;
--
error
1
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
lock
-
ddl
-
per
-
table
--
dbug
=+
d
,
rename_during_mdl_lock_table
2
>
$targetdir
/
backup
.
log
;
exec
$XTRABACKUP
--
defaults
-
file
=
$MYSQLTEST_VARDIR
/
my
.
cnf
--
backup
--
target
-
dir
=
$targetdir
--
lock
-
ddl
-
per
-
table
--
dbug
=+
d
,
rename_during_mdl_lock_table
;
let
SEARCH_FILE
=
$targetdir
/
backup
.
log
;
let
SEARCH_PATTERN
=
failed
to
execute
query
SELECT
1
FROM
;
source
include
/
search_pattern_in_file
.
inc
;
echo
# xtrabackup prepare;
--
disable_result_log
exec
$XTRABACKUP
--
prepare
--
target
-
dir
=
$targetdir
;
--
source
include
/
restart_and_restore
.
inc
--
enable_result_log
# the table was renamed from t1 to t2
# make sure t1 does not exist, and t2 does
CREATE
TABLE
t1
(
i
int
);
DROP
TABLE
t1
;
SELECT
*
from
t2
;
DROP
TABLE
t2
;
rmdir
$targetdir
;
mysql-test/suite/mariabackup/suite.opt
View file @
1eb2d8f6
--innodb --loose-changed_page_bitmaps --innodb-sys-tables --innodb-flush-log-at-trx-commit=2
--innodb --loose-changed_page_bitmaps --innodb-sys-tables --innodb-flush-log-at-trx-commit=2
--sequence
mysql-test/suite/mariabackup/xb_aws_key_management.result
View file @
1eb2d8f6
...
...
@@ -11,4 +11,6 @@ INSERT INTO t VALUES('foobar1');
SELECT * from t;
c
foobar1
Warnings:
Note 1105 AWS KMS plugin: loaded key 1, version 1, key length 128 bit
DROP TABLE t;
storage/innobase/fil/fil0fil.cc
View file @
1eb2d8f6
...
...
@@ -739,42 +739,35 @@ fil_node_open_file(
return
(
true
);
}
/** Close a file node.
@param[in,out] node File node */
static
void
fil_node_close_file
(
fil_node_t
*
node
)
/** Close the file handle. */
void
fil_node_t
::
close
()
{
bool
ret
;
ut_ad
(
mutex_own
(
&
(
fil_system
.
mutex
)
));
ut_a
(
node
->
is_open
());
ut_a
(
n
ode
->
n
_pending
==
0
);
ut_a
(
n
ode
->
n
_pending_flushes
==
0
);
ut_a
(
!
node
->
being_extended
);
ut_a
(
node
->
modification_counter
==
node
->
flush_counter
||
node
->
space
->
purpose
==
FIL_TYPE_TEMPORARY
ut_ad
(
mutex_own
(
&
fil_system
.
mutex
));
ut_a
(
is_open
());
ut_a
(
n_pending
==
0
);
ut_a
(
n_pending_flushes
==
0
);
ut_a
(
!
being_extended
);
ut_a
(
modification_counter
==
flush_counter
||
space
->
purpose
==
FIL_TYPE_TEMPORARY
||
srv_fast_shutdown
==
2
||
!
srv_was_started
);
ret
=
os_file_close
(
node
->
handle
);
ret
=
os_file_close
(
handle
);
ut_a
(
ret
);
/* printf("Closing file %s\n", n
ode->n
ame); */
/* printf("Closing file %s\n", name); */
node
->
handle
=
OS_FILE_CLOSED
;
ut_ad
(
!
node
->
is_open
());
handle
=
OS_FILE_CLOSED
;
ut_ad
(
!
is_open
());
ut_a
(
fil_system
.
n_open
>
0
);
fil_system
.
n_open
--
;
fil_n_file_opened
--
;
if
(
fil_space_belongs_in_lru
(
node
->
space
))
{
if
(
fil_space_belongs_in_lru
(
space
))
{
ut_a
(
UT_LIST_GET_LEN
(
fil_system
.
LRU
)
>
0
);
/* The node is in the LRU list, remove it */
UT_LIST_REMOVE
(
fil_system
.
LRU
,
node
);
UT_LIST_REMOVE
(
fil_system
.
LRU
,
this
);
}
}
...
...
@@ -810,7 +803,7 @@ fil_try_to_close_file_in_LRU(
&&
node
->
n_pending_flushes
==
0
&&
!
node
->
being_extended
)
{
fil_node_close_file
(
node
);
node
->
close
(
);
return
(
true
);
}
...
...
@@ -1240,7 +1233,7 @@ fil_node_close_to_free(
ut_a
(
!
node
->
being_extended
);
if
(
node
->
is_open
())
{
/* We fool the assertion in fil_node_
close_fil
e() to think
/* We fool the assertion in fil_node_
t::clos
e() to think
there are no unflushed modifications in the file */
node
->
modification_counter
=
node
->
flush_counter
;
...
...
@@ -1259,7 +1252,7 @@ fil_node_close_to_free(
UT_LIST_REMOVE
(
fil_system
.
unflushed_spaces
,
space
);
}
fil_node_close_file
(
node
);
node
->
close
(
);
}
}
...
...
@@ -1750,7 +1743,7 @@ void fil_space_t::close()
node
!=
NULL
;
node
=
UT_LIST_GET_NEXT
(
chain
,
node
))
{
if
(
node
->
is_open
())
{
fil_node_close_file
(
node
);
node
->
close
(
);
}
}
...
...
@@ -1911,7 +1904,7 @@ fil_close_all_files(void)
node
=
UT_LIST_GET_NEXT
(
chain
,
node
))
{
if
(
node
->
is_open
())
{
fil_node_close_file
(
node
);
node
->
close
(
);
}
}
...
...
@@ -1958,7 +1951,7 @@ fil_close_log_files(
node
=
UT_LIST_GET_NEXT
(
chain
,
node
))
{
if
(
node
->
is_open
())
{
fil_node_close_file
(
node
);
node
->
close
(
);
}
}
...
...
storage/innobase/include/fil0fil.h
View file @
1eb2d8f6
...
...
@@ -327,6 +327,9 @@ struct fil_node_t {
{
return
(
handle
!=
OS_FILE_CLOSED
);
}
/** Close the file handle. */
void
close
();
};
/** Value of fil_node_t::magic_n */
...
...
storage/innobase/include/lock0lock.h
View file @
1eb2d8f6
...
...
@@ -806,69 +806,6 @@ lock_trx_has_expl_x_lock(
MY_ATTRIBUTE
((
nonnull
,
warn_unused_result
));
#endif
/* UNIV_DEBUG */
/**
Allocate cached locks for the transaction.
@param trx allocate cached record locks for this transaction */
void
lock_trx_alloc_locks
(
trx_t
*
trx
);
/** Lock modes and types */
/* @{ */
#define LOCK_MODE_MASK 0xFUL
/*!< mask used to extract mode from the
type_mode field in a lock */
/** Lock types */
/* @{ */
#define LOCK_TABLE 16U
/*!< table lock */
#define LOCK_REC 32U
/*!< record lock */
#define LOCK_TYPE_MASK 0xF0UL
/*!< mask used to extract lock type from the
type_mode field in a lock */
#if LOCK_MODE_MASK & LOCK_TYPE_MASK
# error "LOCK_MODE_MASK & LOCK_TYPE_MASK"
#endif
#define LOCK_WAIT 256U
/*!< Waiting lock flag; when set, it
means that the lock has not yet been
granted, it is just waiting for its
turn in the wait queue */
/* Precise modes */
#define LOCK_ORDINARY 0
/*!< this flag denotes an ordinary
next-key lock in contrast to LOCK_GAP
or LOCK_REC_NOT_GAP */
#define LOCK_GAP 512U
/*!< when this bit is set, it means that the
lock holds only on the gap before the record;
for instance, an x-lock on the gap does not
give permission to modify the record on which
the bit is set; locks of this type are created
when records are removed from the index chain
of records */
#define LOCK_REC_NOT_GAP 1024U
/*!< this bit means that the lock is only on
the index record and does NOT block inserts
to the gap before the index record; this is
used in the case when we retrieve a record
with a unique key, and is also used in
locking plain SELECTs (not part of UPDATE
or DELETE) when the user has set the READ
COMMITTED isolation level */
#define LOCK_INSERT_INTENTION 2048U
/*!< this bit is set when we place a waiting
gap type record lock request in order to let
an insert of an index record to wait until
there are no conflicting locks by other
transactions on the gap; note that this flag
remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring
record */
#define LOCK_PREDICATE 8192U
/*!< Predicate lock */
#define LOCK_PRDT_PAGE 16384U
/*!< Page lock */
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_PREDICATE|LOCK_PRDT_PAGE)&LOCK_MODE_MASK
# error
#endif
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_PREDICATE|LOCK_PRDT_PAGE)&LOCK_TYPE_MASK
# error
#endif
/* @} */
/** Lock operation struct */
struct
lock_op_t
{
dict_table_t
*
table
;
/*!< table to be locked */
...
...
storage/innobase/include/lock0priv.h
View file @
1eb2d8f6
...
...
@@ -42,19 +42,6 @@ those functions in lock/ */
#define UINT32_MAX (4294967295U)
#endif
/** A table lock */
struct
lock_table_t
{
dict_table_t
*
table
;
/*!< database table in dictionary
cache */
UT_LIST_NODE_T
(
lock_t
)
locks
;
/*!< list of locks on the same
table */
/** Print the table lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
std
::
ostream
&
print
(
std
::
ostream
&
out
)
const
;
};
/** Print the table lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
...
...
@@ -77,131 +64,11 @@ operator<<(std::ostream& out, const lock_table_t& lock)
return
(
lock
.
print
(
out
));
}
/** Record lock for a page */
struct
lock_rec_t
{
ib_uint32_t
space
;
/*!< space id */
ib_uint32_t
page_no
;
/*!< page number */
ib_uint32_t
n_bits
;
/*!< number of bits in the lock
bitmap; NOTE: the lock bitmap is
placed immediately after the
lock struct */
/** Print the record lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
std
::
ostream
&
print
(
std
::
ostream
&
out
)
const
;
};
/** Print the record lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
inline
std
::
ostream
&
lock_rec_t
::
print
(
std
::
ostream
&
out
)
const
{
out
<<
"[lock_rec_t: space="
<<
space
<<
", page_no="
<<
page_no
<<
", n_bits="
<<
n_bits
<<
"]"
;
return
(
out
);
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
lock_rec_t
&
lock
)
{
return
(
lock
.
print
(
out
));
}
/** Lock struct; protected by lock_sys.mutex */
struct
lock_t
{
trx_t
*
trx
;
/*!< transaction owning the
lock */
UT_LIST_NODE_T
(
lock_t
)
trx_locks
;
/*!< list of the locks of the
transaction */
dict_index_t
*
index
;
/*!< index for a record lock */
lock_t
*
hash
;
/*!< hash chain node for a record
lock. The link node in a singly linked
list, used during hashing. */
/* Statistics for how long lock has been held and time
how long this lock had to be waited before it was granted */
time_t
requested_time
;
/*!< Lock request time */
ulint
wait_time
;
/*!< Time waited this lock or 0 */
union
{
lock_table_t
tab_lock
;
/*!< table lock */
lock_rec_t
rec_lock
;
/*!< record lock */
}
un_member
;
/*!< lock details */
ib_uint32_t
type_mode
;
/*!< lock type, mode, LOCK_GAP or
LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION,
wait flag, ORed */
/** Determine if the lock object is a record lock.
@return true if record lock, false otherwise. */
bool
is_record_lock
()
const
{
return
(
type
()
==
LOCK_REC
);
}
bool
is_waiting
()
const
{
return
(
type_mode
&
LOCK_WAIT
);
}
bool
is_gap
()
const
{
return
(
type_mode
&
LOCK_GAP
);
}
bool
is_record_not_gap
()
const
{
return
(
type_mode
&
LOCK_REC_NOT_GAP
);
}
bool
is_insert_intention
()
const
{
return
(
type_mode
&
LOCK_INSERT_INTENTION
);
}
ulint
type
()
const
{
return
(
type_mode
&
LOCK_TYPE_MASK
);
}
enum
lock_mode
mode
()
const
{
return
(
static_cast
<
enum
lock_mode
>
(
type_mode
&
LOCK_MODE_MASK
));
}
/** Print the lock object into the given output stream.
@param[in,out] out the output stream
@return the given output stream. */
std
::
ostream
&
print
(
std
::
ostream
&
out
)
const
;
/** Convert the member 'type_mode' into a human readable string.
@return human readable string */
std
::
string
type_mode_string
()
const
;
const
char
*
type_string
()
const
{
switch
(
type_mode
&
LOCK_TYPE_MASK
)
{
case
LOCK_REC
:
return
(
"LOCK_REC"
);
case
LOCK_TABLE
:
return
(
"LOCK_TABLE"
);
default:
ut_error
;
}
}
};
/** Convert the member 'type_mode' into a human readable string.
@return human readable string */
inline
std
::
string
lock_t
::
type_mode_string
()
const
ib_
lock_t
::
type_mode_string
()
const
{
std
::
ostringstream
sout
;
sout
<<
type_string
();
...
...
@@ -227,7 +94,7 @@ lock_t::type_mode_string() const
inline
std
::
ostream
&
lock_t
::
print
(
std
::
ostream
&
out
)
const
ib_
lock_t
::
print
(
std
::
ostream
&
out
)
const
{
out
<<
"[lock_t: type_mode="
<<
type_mode
<<
"("
<<
type_mode_string
()
<<
")"
;
...
...
@@ -244,7 +111,7 @@ lock_t::print(std::ostream& out) const
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
lock_t
&
lock
)
operator
<<
(
std
::
ostream
&
out
,
const
ib_
lock_t
&
lock
)
{
return
(
lock
.
print
(
out
));
}
...
...
storage/innobase/include/lock0priv.ic
View file @
1eb2d8f6
/*****************************************************************************
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -388,17 +389,10 @@ lock_table_has(
const
dict_table_t
*
table
,
/*!< in: table */
lock_mode
in_mode
)
/*!< in: lock mode */
{
if
(
trx
->
lock
.
table_locks
.
empty
())
{
return
(
NULL
);
}
typedef
lock_pool_t
::
const_reverse_iterator
iterator
;
iterator
end
=
trx
->
lock
.
table_locks
.
rend
();
/* Look for stronger locks the same trx already has on the table */
for
(
iterator
it
=
trx
->
lock
.
table_locks
.
rbegin
();
it
!=
end
;
++
it
)
{
for
(
lock_list
::
const_iterator
it
=
trx
->
lock
.
table_locks
.
begin
(),
end
=
trx
->
lock
.
table_locks
.
end
();
it
!=
end
;
++
it
)
{
const
lock_t
*
lock
=
*
it
;
...
...
storage/innobase/include/lock0types.h
View file @
1eb2d8f6
/*****************************************************************************
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
...
...
@@ -72,6 +73,195 @@ const char* lock_mode_string(enum lock_mode mode)
}
}
typedef
UT_LIST_BASE_NODE_T
(
lock_t
)
trx_lock_list_t
;
/** A table lock */
struct
lock_table_t
{
dict_table_t
*
table
;
/*!< database table in dictionary
cache */
UT_LIST_NODE_T
(
ib_lock_t
)
locks
;
/*!< list of locks on the same
table */
/** Print the table lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
std
::
ostream
&
print
(
std
::
ostream
&
out
)
const
;
};
/** Record lock for a page */
struct
lock_rec_t
{
ib_uint32_t
space
;
/*!< space id */
ib_uint32_t
page_no
;
/*!< page number */
ib_uint32_t
n_bits
;
/*!< number of bits in the lock
bitmap; NOTE: the lock bitmap is
placed immediately after the
lock struct */
/** Print the record lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
std
::
ostream
&
print
(
std
::
ostream
&
out
)
const
;
};
/** Print the record lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
inline
std
::
ostream
&
lock_rec_t
::
print
(
std
::
ostream
&
out
)
const
{
out
<<
"[lock_rec_t: space="
<<
space
<<
", page_no="
<<
page_no
<<
", n_bits="
<<
n_bits
<<
"]"
;
return
(
out
);
}
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
lock_rec_t
&
lock
)
{
return
(
lock
.
print
(
out
));
}
#define LOCK_MODE_MASK 0xFUL
/*!< mask used to extract mode from the
type_mode field in a lock */
/** Lock types */
/* @{ */
#define LOCK_TABLE 16U
/*!< table lock */
#define LOCK_REC 32U
/*!< record lock */
#define LOCK_TYPE_MASK 0xF0UL
/*!< mask used to extract lock type from the
type_mode field in a lock */
#if LOCK_MODE_MASK & LOCK_TYPE_MASK
# error "LOCK_MODE_MASK & LOCK_TYPE_MASK"
#endif
#define LOCK_WAIT 256U
/*!< Waiting lock flag; when set, it
means that the lock has not yet been
granted, it is just waiting for its
turn in the wait queue */
/* Precise modes */
#define LOCK_ORDINARY 0
/*!< this flag denotes an ordinary
next-key lock in contrast to LOCK_GAP
or LOCK_REC_NOT_GAP */
#define LOCK_GAP 512U
/*!< when this bit is set, it means that the
lock holds only on the gap before the record;
for instance, an x-lock on the gap does not
give permission to modify the record on which
the bit is set; locks of this type are created
when records are removed from the index chain
of records */
#define LOCK_REC_NOT_GAP 1024U
/*!< this bit means that the lock is only on
the index record and does NOT block inserts
to the gap before the index record; this is
used in the case when we retrieve a record
with a unique key, and is also used in
locking plain SELECTs (not part of UPDATE
or DELETE) when the user has set the READ
COMMITTED isolation level */
#define LOCK_INSERT_INTENTION 2048U
/*!< this bit is set when we place a waiting
gap type record lock request in order to let
an insert of an index record to wait until
there are no conflicting locks by other
transactions on the gap; note that this flag
remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring
record */
#define LOCK_PREDICATE 8192U
/*!< Predicate lock */
#define LOCK_PRDT_PAGE 16384U
/*!< Page lock */
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_PREDICATE|LOCK_PRDT_PAGE)&LOCK_MODE_MASK
# error
#endif
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_PREDICATE|LOCK_PRDT_PAGE)&LOCK_TYPE_MASK
# error
#endif
/* @} */
/** Lock struct; protected by lock_sys.mutex */
struct
ib_lock_t
{
trx_t
*
trx
;
/*!< transaction owning the
lock */
UT_LIST_NODE_T
(
ib_lock_t
)
trx_locks
;
/*!< list of the locks of the
transaction */
dict_index_t
*
index
;
/*!< index for a record lock */
ib_lock_t
*
hash
;
/*!< hash chain node for a record
lock. The link node in a singly linked
list, used during hashing. */
/* Statistics for how long lock has been held and time
how long this lock had to be waited before it was granted */
time_t
requested_time
;
/*!< Lock request time */
ulint
wait_time
;
/*!< Time waited this lock or 0 */
union
{
lock_table_t
tab_lock
;
/*!< table lock */
lock_rec_t
rec_lock
;
/*!< record lock */
}
un_member
;
/*!< lock details */
ib_uint32_t
type_mode
;
/*!< lock type, mode, LOCK_GAP or
LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION,
wait flag, ORed */
/** Determine if the lock object is a record lock.
@return true if record lock, false otherwise. */
bool
is_record_lock
()
const
{
return
(
type
()
==
LOCK_REC
);
}
bool
is_waiting
()
const
{
return
(
type_mode
&
LOCK_WAIT
);
}
bool
is_gap
()
const
{
return
(
type_mode
&
LOCK_GAP
);
}
bool
is_record_not_gap
()
const
{
return
(
type_mode
&
LOCK_REC_NOT_GAP
);
}
bool
is_insert_intention
()
const
{
return
(
type_mode
&
LOCK_INSERT_INTENTION
);
}
ulint
type
()
const
{
return
(
type_mode
&
LOCK_TYPE_MASK
);
}
enum
lock_mode
mode
()
const
{
return
(
static_cast
<
enum
lock_mode
>
(
type_mode
&
LOCK_MODE_MASK
));
}
/** Print the lock object into the given output stream.
@param[in,out] out the output stream
@return the given output stream. */
std
::
ostream
&
print
(
std
::
ostream
&
out
)
const
;
/** Convert the member 'type_mode' into a human readable string.
@return human readable string */
std
::
string
type_mode_string
()
const
;
const
char
*
type_string
()
const
{
switch
(
type_mode
&
LOCK_TYPE_MASK
)
{
case
LOCK_REC
:
return
(
"LOCK_REC"
);
case
LOCK_TABLE
:
return
(
"LOCK_TABLE"
);
default:
ut_error
;
}
}
};
typedef
UT_LIST_BASE_NODE_T
(
ib_lock_t
)
trx_lock_list_t
;
#endif
/* lock0types_h */
storage/innobase/include/log0recv.h
View file @
1eb2d8f6
...
...
@@ -139,9 +139,21 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply);
/** Moves the parsing buffer data left to the buffer start. */
void
recv_sys_justify_left_parsing_buf
();
/** Backup function checks whether the space id belongs to
the skip table list given in the mariabackup option. */
extern
bool
(
*
check_if_backup_includes
)(
ulint
space_id
);
/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
@param[in] space_id tablespace identifier
*/
extern
void
(
*
log_optimized_ddl_op
)(
ulint
space_id
);
/** Report an operation to create, delete, or rename a file during backup.
@param[in] space_id tablespace identifier
@param[in] flags tablespace flags (NULL if not create)
@param[in] name file name (not NUL-terminated)
@param[in] len length of name, in bytes
@param[in] new_name new file name (NULL if not rename)
@param[in] new_len length of new_name, in bytes (0 if NULL) */
extern
void
(
*
log_file_op
)(
ulint
space_id
,
const
byte
*
flags
,
const
byte
*
name
,
ulint
len
,
const
byte
*
new_name
,
ulint
new_len
);
/** Block of log record data */
struct
recv_data_t
{
...
...
storage/innobase/include/trx0sys.h
View file @
1eb2d8f6
...
...
@@ -646,8 +646,11 @@ class rw_trx_hash_t
{
mutex_enter
(
&
element
->
mutex
);
lf_hash_search_unpin
(
pins
);
if
((
trx
=
element
->
trx
))
{
trx
=
element
->
trx
;
if
(
!
trx
);
else
if
(
UNIV_UNLIKELY
(
trx_id
!=
trx
->
id
))
trx
=
NULL
;
else
{
if
(
do_ref_count
)
trx
->
reference
();
ut_d
(
validate_element
(
trx
));
...
...
storage/innobase/include/trx0trx.h
View file @
1eb2d8f6
...
...
@@ -476,7 +476,9 @@ Check transaction state */
@param t transaction handle */
#define assert_trx_is_free(t) do { \
ut_ad(trx_state_eq((t), TRX_STATE_NOT_STARTED)); \
ut_ad(!trx->has_logged()); \
ut_ad(!(t)->id); \
ut_ad(!(t)->has_logged()); \
ut_ad(!(t)->is_referenced()); \
ut_ad(!(t)->read_view.is_open()); \
ut_ad((t)->lock.wait_thr == NULL); \
ut_ad(UT_LIST_GET_LEN((t)->lock.trx_locks) == 0); \
...
...
@@ -517,7 +519,7 @@ The transaction must have mysql_thd assigned. */
# define assert_trx_nonlocking_or_in_list(trx) ((void)0)
#endif
/* UNIV_DEBUG */
typedef
std
::
vector
<
ib_lock_t
*
,
ut_allocator
<
ib_lock_t
*>
>
lock_
pool_
t
;
typedef
std
::
vector
<
ib_lock_t
*
,
ut_allocator
<
ib_lock_t
*>
>
lock_
lis
t
;
/*******************************************************************//**
Latching protocol for trx_lock_t::que_state. trx_lock_t::que_state
...
...
@@ -579,13 +581,19 @@ struct trx_lock_t {
only be modified by the thread that is
serving the running transaction. */
lock_pool_t
rec_pool
;
/*!< Pre-allocated record locks */
/** Pre-allocated record locks */
struct
{
ib_lock_t
lock
;
byte
pad
[
256
];
}
rec_pool
[
8
];
lock_pool_t
table_pool
;
/*!< Pre-allocated table locks */
/** Pre-allocated table locks */
ib_lock_t
table_pool
[
8
];
ulint
rec_cached
;
/*!< Next free rec lock in pool */
/** Next available rec_pool[] entry */
unsigned
rec_cached
;
ulint
table_cached
;
/*!< Next free table lock in pool */
/** Next available table_pool[] entry */
unsigned
table_cached
;
mem_heap_t
*
lock_heap
;
/*!< memory heap for trx_locks;
protected by lock_sys.mutex */
...
...
@@ -595,7 +603,7 @@ struct trx_lock_t {
and lock_sys.mutex; removals are
protected by lock_sys.mutex */
lock_
pool_
t
table_locks
;
/*!< All table locks requested by this
lock_
lis
t
table_locks
;
/*!< All table locks requested by this
transaction, including AUTOINC locks */
bool
cancel
;
/*!< true if the transaction is being
...
...
storage/innobase/include/ut0pool.h
View file @
1eb2d8f6
...
...
@@ -125,8 +125,7 @@ struct Pool {
elem
=
NULL
;
}
m_lock_strategy
.
exit
();
#if defined HAVE_valgrind || defined __SANITIZE_ADDRESS__
if
(
elem
)
{
/* Unpoison the memory for AddressSanitizer */
MEM_UNDEFINED
(
&
elem
->
m_type
,
sizeof
elem
->
m_type
);
...
...
@@ -135,10 +134,11 @@ struct Pool {
actually initialized; we checked that by
UNIV_MEM_ASSERT_RW() in mem_free() below. */
UNIV_MEM_VALID
(
&
elem
->
m_type
,
sizeof
elem
->
m_type
);
return
&
elem
->
m_type
;
}
#endif
return
NULL
;
m_lock_strategy
.
exit
();
return
elem
?
&
elem
->
m_type
:
NULL
;
}
/** Add the object to the pool.
...
...
@@ -151,8 +151,12 @@ struct Pool {
elem
=
reinterpret_cast
<
Element
*>
(
p
-
sizeof
(
*
elem
));
UNIV_MEM_ASSERT_RW
(
&
elem
->
m_type
,
sizeof
elem
->
m_type
);
elem
->
m_pool
->
put
(
elem
);
elem
->
m_pool
->
m_lock_strategy
.
enter
();
elem
->
m_pool
->
putl
(
elem
);
MEM_NOACCESS
(
&
elem
->
m_type
,
sizeof
elem
->
m_type
);
elem
->
m_pool
->
m_lock_strategy
.
exit
();
}
protected:
...
...
@@ -170,17 +174,13 @@ struct Pool {
/** Release the object to the free pool
@param elem element to free */
void
put
(
Element
*
elem
)
void
put
l
(
Element
*
elem
)
{
m_lock_strategy
.
enter
();
ut_ad
(
elem
>=
m_start
&&
elem
<
m_last
);
ut_ad
(
Factory
::
debug
(
&
elem
->
m_type
));
m_pqueue
.
push
(
elem
);
m_lock_strategy
.
exit
();
}
/** Initialise the elements.
...
...
storage/innobase/lock/lock0lock.cc
View file @
1eb2d8f6
...
...
@@ -59,18 +59,6 @@ ulong innodb_lock_schedule_algorithm;
/** The value of innodb_deadlock_detect */
my_bool
innobase_deadlock_detect
;
/** Total number of cached record locks */
static
const
ulint
REC_LOCK_CACHE
=
8
;
/** Maximum record lock size in bytes */
static
const
ulint
REC_LOCK_SIZE
=
sizeof
(
ib_lock_t
)
+
256
;
/** Total number of cached table locks */
static
const
ulint
TABLE_LOCK_CACHE
=
8
;
/** Size in bytes, of the table lock instance */
static
const
ulint
TABLE_LOCK_SIZE
=
sizeof
(
ib_lock_t
);
/*********************************************************************//**
Checks if a waiting record lock request still has to wait in a queue.
@return lock that is causing the wait */
...
...
@@ -1409,13 +1397,13 @@ lock_rec_create_low(
}
}
if
(
trx
->
lock
.
rec_cached
>=
trx
->
lock
.
rec_pool
.
size
(
)
||
sizeof
*
lock
+
n_bytes
>
REC_LOCK_SIZE
)
{
if
(
trx
->
lock
.
rec_cached
>=
UT_ARR_SIZE
(
trx
->
lock
.
rec_pool
)
||
sizeof
*
lock
+
n_bytes
>
sizeof
*
trx
->
lock
.
rec_pool
)
{
lock
=
static_cast
<
lock_t
*>
(
mem_heap_alloc
(
trx
->
lock
.
lock_heap
,
sizeof
*
lock
+
n_bytes
));
}
else
{
lock
=
trx
->
lock
.
rec_pool
[
trx
->
lock
.
rec_cached
++
]
;
lock
=
&
trx
->
lock
.
rec_pool
[
trx
->
lock
.
rec_cached
++
].
lock
;
}
lock
->
trx
=
trx
;
...
...
@@ -3520,8 +3508,9 @@ lock_table_create(
ib_vector_push
(
trx
->
autoinc_locks
,
&
lock
);
}
else
if
(
trx
->
lock
.
table_cached
<
trx
->
lock
.
table_pool
.
size
())
{
lock
=
trx
->
lock
.
table_pool
[
trx
->
lock
.
table_cached
++
];
}
else
if
(
trx
->
lock
.
table_cached
<
UT_ARR_SIZE
(
trx
->
lock
.
table_pool
))
{
lock
=
&
trx
->
lock
.
table_pool
[
trx
->
lock
.
table_cached
++
];
}
else
{
lock
=
static_cast
<
lock_t
*>
(
...
...
@@ -4373,24 +4362,15 @@ lock_trx_table_locks_remove(
ut_ad
(
trx_mutex_own
(
trx
));
}
typedef
lock_pool_t
::
reverse_iterator
iterator
;
iterator
end
=
trx
->
lock
.
table_locks
.
rend
();
for
(
iterator
it
=
trx
->
lock
.
table_locks
.
rbegin
();
it
!=
end
;
++
it
)
{
for
(
lock_list
::
iterator
it
=
trx
->
lock
.
table_locks
.
begin
(),
end
=
trx
->
lock
.
table_locks
.
end
();
it
!=
end
;
++
it
)
{
const
lock_t
*
lock
=
*
it
;
if
(
lock
==
NULL
)
{
continue
;
}
ut_a
(
trx
==
lock
->
trx
);
ut_a
(
lock_get_type_low
(
lock
)
&
LOCK_TABLE
);
ut_a
(
lock
->
un_member
.
tab_lock
.
table
!=
NULL
);
ut_ad
(
!
lock
||
trx
==
lock
->
trx
);
ut_ad
(
!
lock
||
lock_get_type_low
(
lock
)
&
LOCK_TABLE
);
ut_ad
(
!
lock
||
lock
->
un_member
.
tab_lock
.
table
);
if
(
lock
==
lock_to_remove
)
{
*
it
=
NULL
;
if
(
!
trx
->
lock
.
cancel
)
{
...
...
@@ -4807,11 +4787,8 @@ lock_trx_table_locks_find(
trx_mutex_enter
(
trx
);
typedef
lock_pool_t
::
const_reverse_iterator
iterator
;
iterator
end
=
trx
->
lock
.
table_locks
.
rend
();
for
(
iterator
it
=
trx
->
lock
.
table_locks
.
rbegin
();
it
!=
end
;
++
it
)
{
for
(
lock_list
::
const_iterator
it
=
trx
->
lock
.
table_locks
.
begin
(),
end
=
trx
->
lock
.
table_locks
.
end
();
it
!=
end
;
++
it
)
{
const
lock_t
*
lock
=
*
it
;
...
...
@@ -6337,6 +6314,9 @@ lock_trx_release_locks(
/*--------------------------------------*/
trx_mutex_enter
(
trx
);
trx
->
state
=
TRX_STATE_COMMITTED_IN_MEMORY
;
/* Ensure that rw_trx_hash_t::find() will no longer find
this transaction. */
trx
->
id
=
0
;
trx_mutex_exit
(
trx
);
/*--------------------------------------*/
...
...
@@ -6547,10 +6527,8 @@ lock_trx_has_sys_table_locks(
lock_mutex_enter
();
typedef
lock_pool_t
::
const_reverse_iterator
iterator
;
iterator
end
=
trx
->
lock
.
table_locks
.
rend
();
iterator
it
=
trx
->
lock
.
table_locks
.
rbegin
();
const
lock_list
::
const_iterator
end
=
trx
->
lock
.
table_locks
.
end
();
lock_list
::
const_iterator
it
=
trx
->
lock
.
table_locks
.
begin
();
/* Find a valid mode. Note: ib_vector_size() can be 0. */
...
...
@@ -7102,33 +7080,6 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx)
return
(
victim_trx
);
}
/**
Allocate cached locks for the transaction.
@param trx allocate cached record locks for this transaction */
void
lock_trx_alloc_locks
(
trx_t
*
trx
)
{
ulint
sz
=
REC_LOCK_SIZE
*
REC_LOCK_CACHE
;
byte
*
ptr
=
reinterpret_cast
<
byte
*>
(
ut_malloc_nokey
(
sz
));
/* We allocate one big chunk and then distribute it among
the rest of the elements. The allocated chunk pointer is always
at index 0. */
for
(
ulint
i
=
0
;
i
<
REC_LOCK_CACHE
;
++
i
,
ptr
+=
REC_LOCK_SIZE
)
{
trx
->
lock
.
rec_pool
.
push_back
(
reinterpret_cast
<
ib_lock_t
*>
(
ptr
));
}
sz
=
TABLE_LOCK_SIZE
*
TABLE_LOCK_CACHE
;
ptr
=
reinterpret_cast
<
byte
*>
(
ut_malloc_nokey
(
sz
));
for
(
ulint
i
=
0
;
i
<
TABLE_LOCK_CACHE
;
++
i
,
ptr
+=
TABLE_LOCK_SIZE
)
{
trx
->
lock
.
table_pool
.
push_back
(
reinterpret_cast
<
ib_lock_t
*>
(
ptr
));
}
}
/*************************************************************//**
Updates the lock table when a page is split and merged to
two pages. */
...
...
storage/innobase/log/log0recv.cc
View file @
1eb2d8f6
...
...
@@ -169,9 +169,21 @@ typedef std::map<
static
recv_spaces_t
recv_spaces
;
/** Backup function checks whether the space id belongs to
the skip table list given in the mariabackup option. */
bool
(
*
check_if_backup_includes
)(
ulint
space_id
);
/** Report optimized DDL operation (without redo log), corresponding to MLOG_INDEX_LOAD.
@param[in] space_id tablespace identifier
*/
void
(
*
log_optimized_ddl_op
)(
ulint
space_id
);
/** Report an operation to create, delete, or rename a file during backup.
@param[in] space_id tablespace identifier
@param[in] flags tablespace flags (NULL if not create)
@param[in] name file name (not NUL-terminated)
@param[in] len length of name, in bytes
@param[in] new_name new file name (NULL if not rename)
@param[in] new_len length of new_name, in bytes (0 if NULL) */
void
(
*
log_file_op
)(
ulint
space_id
,
const
byte
*
flags
,
const
byte
*
name
,
ulint
len
,
const
byte
*
new_name
,
ulint
new_len
);
/** Process a file name from a MLOG_FILE_* record.
@param[in,out] name file name
...
...
@@ -381,9 +393,13 @@ fil_name_parse(
fil_name_process
(
reinterpret_cast
<
char
*>
(
ptr
),
len
,
space_id
,
true
);
break
;
/* fall through */
case
MLOG_FILE_CREATE2
:
if
(
log_file_op
)
{
log_file_op
(
space_id
,
type
==
MLOG_FILE_CREATE2
?
ptr
-
4
:
NULL
,
ptr
,
len
,
NULL
,
0
);
}
break
;
case
MLOG_FILE_RENAME2
:
if
(
corrupt
)
{
...
...
@@ -424,6 +440,11 @@ fil_name_parse(
reinterpret_cast
<
char
*>
(
new_name
),
new_len
,
space_id
,
false
);
if
(
log_file_op
)
{
log_file_op
(
space_id
,
NULL
,
ptr
,
len
,
new_name
,
new_len
);
}
if
(
!
apply
)
{
break
;
}
...
...
@@ -716,6 +737,15 @@ bool log_t::files::read_log_seg(lsn_t* start_lsn, lsn_t end_lsn)
OS_FILE_LOG_BLOCK_SIZE
,
true
);
}
}
ulint
dl
=
log_block_get_data_len
(
buf
);
if
(
dl
<
LOG_BLOCK_HDR_SIZE
||
(
dl
>
OS_FILE_LOG_BLOCK_SIZE
-
LOG_BLOCK_TRL_SIZE
&&
dl
!=
OS_FILE_LOG_BLOCK_SIZE
))
{
recv_sys
->
found_corrupt_log
=
true
;
end_lsn
=
*
start_lsn
;
break
;
}
}
if
(
recv_sys
->
report
(
ut_time
()))
{
...
...
@@ -2125,7 +2155,8 @@ recv_parse_log_rec(
case
MLOG_MULTI_REC_END
|
MLOG_SINGLE_REC_FLAG
:
case
MLOG_DUMMY_RECORD
|
MLOG_SINGLE_REC_FLAG
:
case
MLOG_CHECKPOINT
|
MLOG_SINGLE_REC_FLAG
:
ib
::
error
()
<<
"Incorrect log record type:"
<<
*
ptr
;
ib
::
error
()
<<
"Incorrect log record type "
<<
ib
::
hex
(
unsigned
(
*
ptr
));
recv_sys
->
found_corrupt_log
=
true
;
return
(
0
);
}
...
...
@@ -2144,7 +2175,6 @@ recv_parse_log_rec(
*
type
,
new_ptr
,
end_ptr
,
*
space
,
*
page_no
,
apply
,
NULL
,
NULL
);
if
(
UNIV_UNLIKELY
(
new_ptr
==
NULL
))
{
return
(
0
);
}
...
...
@@ -2201,30 +2231,30 @@ recv_report_corrupt_log(
ib
::
error
()
<<
"############### CORRUPT LOG RECORD FOUND ##################"
;
const
ulint
ptr_offset
=
ulint
(
ptr
-
recv_sys
->
buf
);
ib
::
info
()
<<
"Log record type "
<<
type
<<
", page "
<<
space
<<
":"
<<
page_no
<<
". Log parsing proceeded successfully up to "
<<
recv_sys
->
recovered_lsn
<<
". Previous log record type "
<<
recv_previous_parsed_rec_type
<<
", is multi "
<<
recv_previous_parsed_rec_is_multi
<<
" Recv offset "
<<
(
ptr
-
recv_sys
->
buf
)
<<
", prev "
<<
ptr_offset
<<
", prev "
<<
recv_previous_parsed_rec_offset
;
ut_ad
(
ptr
<=
recv_sys
->
buf
+
recv_sys
->
len
);
const
ulint
limit
=
100
;
const
ulint
before
=
std
::
min
(
recv_previous_parsed_rec_offset
,
limi
t
);
const
ulint
after
=
std
::
min
(
recv_sys
->
len
-
ulint
(
ptr
-
recv_sys
->
buf
)
,
limit
);
const
ulint
prev_offset
=
std
::
min
(
recv_previous_parsed_rec_offset
,
ptr_offse
t
);
const
ulint
before
=
std
::
min
(
prev_offset
,
limit
);
const
ulint
after
=
std
::
min
(
recv_sys
->
len
-
ptr_offset
,
limit
);
ib
::
info
()
<<
"Hex dump starting "
<<
before
<<
" bytes before and"
" ending "
<<
after
<<
" bytes after the corrupted record:"
;
ut_print_buf
(
stderr
,
recv_sys
->
buf
+
recv_previous_parsed_rec_offset
-
before
,
ulint
(
ptr
-
recv_sys
->
buf
)
+
before
+
after
-
recv_previous_parsed_rec_offset
);
const
byte
*
start
=
recv_sys
->
buf
+
prev_offset
-
before
;
ut_print_buf
(
stderr
,
start
,
ulint
(
ptr
-
start
)
+
after
);
putc
(
'\n'
,
stderr
);
if
(
!
srv_force_recovery
)
{
...
...
@@ -2295,13 +2325,8 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
len
=
recv_parse_log_rec
(
&
type
,
ptr
,
end_ptr
,
&
space
,
&
page_no
,
apply
,
&
body
);
if
(
len
==
0
)
{
return
(
false
);
}
if
(
recv_sys
->
found_corrupt_log
)
{
recv_report_corrupt_log
(
ptr
,
type
,
space
,
page_no
);
recv_report_corrupt_log
(
ptr
,
type
,
space
,
page_no
);
return
(
true
);
}
...
...
@@ -2309,6 +2334,10 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
return
(
true
);
}
if
(
len
==
0
)
{
return
(
false
);
}
new_recovered_lsn
=
recv_calc_lsn_on_data_add
(
old_lsn
,
len
);
if
(
new_recovered_lsn
>
recv_sys
->
scanned_lsn
)
{
...
...
@@ -2396,11 +2425,8 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
/* fall through */
case
MLOG_INDEX_LOAD
:
if
(
type
==
MLOG_INDEX_LOAD
)
{
if
(
check_if_backup_includes
&&
!
check_if_backup_includes
(
space
))
{
ut_ad
(
srv_operation
==
SRV_OPERATION_BACKUP
);
return
true
;
if
(
log_optimized_ddl_op
)
{
log_optimized_ddl_op
(
space
);
}
}
/* fall through */
...
...
@@ -2433,13 +2459,10 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
&
type
,
ptr
,
end_ptr
,
&
space
,
&
page_no
,
false
,
&
body
);
if
(
len
==
0
)
{
return
(
false
);
}
if
(
recv_sys
->
found_corrupt_log
||
type
==
MLOG_CHECKPOINT
||
(
*
ptr
&
MLOG_SINGLE_REC_FLAG
))
{
||
(
ptr
!=
end_ptr
&&
(
*
ptr
&
MLOG_SINGLE_REC_FLAG
)))
{
recv_sys
->
found_corrupt_log
=
true
;
recv_report_corrupt_log
(
ptr
,
type
,
space
,
page_no
);
...
...
@@ -2450,6 +2473,10 @@ bool recv_parse_log_recs(lsn_t checkpoint_lsn, store_t store, bool apply)
return
(
true
);
}
if
(
len
==
0
)
{
return
(
false
);
}
recv_previous_parsed_rec_type
=
type
;
recv_previous_parsed_rec_offset
=
recv_sys
->
recovered_offset
+
total_len
;
...
...
storage/innobase/mtr/mtr0log.cc
View file @
1eb2d8f6
...
...
@@ -98,7 +98,11 @@ mlog_parse_initial_log_record(
}
*
type
=
mlog_id_t
(
*
ptr
&
~
MLOG_SINGLE_REC_FLAG
);
ut_ad
(
*
type
<=
MLOG_BIGGEST_TYPE
||
EXTRA_CHECK_MLOG_NUMBER
(
*
type
));
if
(
UNIV_UNLIKELY
(
*
type
>
MLOG_BIGGEST_TYPE
&&
!
EXTRA_CHECK_MLOG_NUMBER
(
*
type
)))
{
recv_sys
->
found_corrupt_log
=
true
;
return
NULL
;
}
ptr
++
;
...
...
storage/innobase/page/page0cur.cc
View file @
1eb2d8f6
...
...
@@ -2256,7 +2256,10 @@ page_cur_parse_delete_rec(
offset
=
mach_read_from_2
(
ptr
);
ptr
+=
2
;
ut_a
(
offset
<=
srv_page_size
);
if
(
UNIV_UNLIKELY
(
offset
>=
srv_page_size
))
{
recv_sys
->
found_corrupt_log
=
true
;
return
NULL
;
}
if
(
block
)
{
page_t
*
page
=
buf_block_get_frame
(
block
);
...
...
storage/innobase/trx/trx0trx.cc
View file @
1eb2d8f6
...
...
@@ -118,8 +118,6 @@ trx_init(
/*=====*/
trx_t
*
trx
)
{
trx
->
id
=
0
;
trx
->
no
=
TRX_ID_MAX
;
trx
->
state
=
TRX_STATE_NOT_STARTED
;
...
...
@@ -197,11 +195,7 @@ struct TrxFactory {
the constructors of the trx_t members. */
new
(
&
trx
->
mod_tables
)
trx_mod_tables_t
();
new
(
&
trx
->
lock
.
rec_pool
)
lock_pool_t
();
new
(
&
trx
->
lock
.
table_pool
)
lock_pool_t
();
new
(
&
trx
->
lock
.
table_locks
)
lock_pool_t
();
new
(
&
trx
->
lock
.
table_locks
)
lock_list
();
new
(
&
trx
->
read_view
)
ReadView
();
...
...
@@ -225,8 +219,6 @@ struct TrxFactory {
&
trx_named_savept_t
::
trx_savepoints
);
mutex_create
(
LATCH_ID_TRX
,
&
trx
->
mutex
);
lock_trx_alloc_locks
(
trx
);
}
/** Release resources held by the transaction object.
...
...
@@ -256,27 +248,7 @@ struct TrxFactory {
ut_ad
(
!
trx
->
read_view
.
is_open
());
if
(
!
trx
->
lock
.
rec_pool
.
empty
())
{
/* See lock_trx_alloc_locks() why we only free
the first element. */
ut_free
(
trx
->
lock
.
rec_pool
[
0
]);
}
if
(
!
trx
->
lock
.
table_pool
.
empty
())
{
/* See lock_trx_alloc_locks() why we only free
the first element. */
ut_free
(
trx
->
lock
.
table_pool
[
0
]);
}
trx
->
lock
.
rec_pool
.
~
lock_pool_t
();
trx
->
lock
.
table_pool
.
~
lock_pool_t
();
trx
->
lock
.
table_locks
.
~
lock_pool_t
();
trx
->
lock
.
table_locks
.
~
lock_list
();
trx
->
read_view
.
~
ReadView
();
}
...
...
@@ -412,7 +384,12 @@ trx_t *trx_create()
/* Should have been either just initialized or .clear()ed by
trx_free(). */
ut_a
(
trx
->
mod_tables
.
size
()
==
0
);
ut_ad
(
trx
->
mod_tables
.
empty
());
ut_ad
(
trx
->
lock
.
table_locks
.
empty
());
ut_ad
(
UT_LIST_GET_LEN
(
trx
->
lock
.
trx_locks
)
==
0
);
ut_ad
(
trx
->
lock
.
n_rec_locks
==
0
);
ut_ad
(
trx
->
lock
.
table_cached
==
0
);
ut_ad
(
trx
->
lock
.
rec_cached
==
0
);
#ifdef WITH_WSREP
trx
->
wsrep_event
=
NULL
;
...
...
@@ -993,8 +970,6 @@ trx_start_low(
trx_sys
.
register_rw
(
trx
);
}
else
{
trx
->
id
=
0
;
if
(
!
trx_is_autocommit_non_locking
(
trx
))
{
/* If this is a read-only transaction that is writing
...
...
@@ -1250,9 +1225,6 @@ trx_update_mod_tables_timestamp(
/*============================*/
trx_t
*
trx
)
/*!< in: transaction */
{
ut_ad
(
trx
->
id
!=
0
);
/* consider using trx->start_time if calling time() is too
expensive here */
time_t
now
=
ut_time
();
...
...
@@ -1325,7 +1297,10 @@ trx_commit_in_memory(
trx_sys
.
deregister_rw
(
trx
);
}
/* trx->id will be cleared in lock_trx_release_locks(trx). */
ut_ad
(
trx
->
read_only
||
!
trx
->
rsegs
.
m_redo
.
rseg
||
trx
->
id
);
lock_trx_release_locks
(
trx
);
ut_ad
(
trx
->
id
==
0
);
/* Remove the transaction from the list of active
transactions now that it no longer holds any user locks. */
...
...
storage/rocksdb/build_rocksdb.cmake
View file @
1eb2d8f6
...
...
@@ -376,9 +376,31 @@ SET(SOURCES)
FOREACH
(
s
${
ROCKSDB_SOURCES
}
)
list
(
APPEND SOURCES
${
ROCKSDB_SOURCE_DIR
}
/
${
s
}
)
ENDFOREACH
()
IF
(
MSVC
)
if
(
MSVC
)
add_definitions
(
-DHAVE_SSE42 -DHAVE_PCLMUL
)
ENDIF
()
else
()
set
(
CMAKE_REQUIRED_FLAGS
"-msse4.2 -mpclmul
${
CXX11_FLAGS
}
"
)
CHECK_CXX_SOURCE_COMPILES
(
"
#include <cstdint>
#include <nmmintrin.h>
#include <wmmintrin.h>
int main() {
volatile uint32_t x = _mm_crc32_u32(0, 0);
const auto a = _mm_set_epi64x(0, 0);
const auto b = _mm_set_epi64x(0, 0);
const auto c = _mm_clmulepi64_si128(a, b, 0x00);
auto d = _mm_cvtsi128_si64(c);
}
"
HAVE_SSE42
)
if
(
HAVE_SSE42
)
set_source_files_properties
(
${
ROCKSDB_SOURCE_DIR
}
/util/crc32c.cc
PROPERTIES COMPILE_FLAGS
"-DHAVE_SSE42 -DHAVE_PCLMUL -msse4.2 -mpclmul"
)
endif
()
unset
(
CMAKE_REQUIRED_FLAGS
)
endif
()
IF
(
CMAKE_VERSION VERSION_GREATER
"2.8.10"
)
STRING
(
TIMESTAMP GIT_DATE_TIME
"%Y-%m-%d %H:%M:%S"
)
ENDIF
()
...
...
storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug-master.opt
View file @
1eb2d8f6
--binlog-format=row
--binlog-format=row
--rocksdb-flush-log-at-trx-commit=1
storage/rocksdb/mysql-test/rocksdb/t/bulk_load_errors.test
View file @
1eb2d8f6
...
...
@@ -60,6 +60,13 @@ SELECT * FROM t1;
--
source
include
/
wait_until_count_sessions
.
inc
# Note: in MariaDB, session count will be decremented *before*
# myrocks::rocksdb_close_connection is called. This causes a race condition:
# we may grep the error log before bulk load is finalized.
# To prevent that, do a soft restart of the server (I wasnt able to find
# any other reliable way)
--
source
include
/
restart_mysqld_with_option
.
inc
--
let
SEARCH_FILE
=
$LOG2
--
let
SEARCH_PATTERN
=
RocksDB
:
Error
[
0
-
9
]
+
finalizing
last
SST
file
while
disconnecting
--
source
include
/
search_pattern_in_file
.
inc
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment