Merge XtraDB from Percona-Server 5.1.66-rel14.1 into MariaDB 5.1.
This commit is contained in:
commit
43293b7a51
@ -54,9 +54,13 @@ EVENTS
|
||||
FILES
|
||||
GLOBAL_STATUS
|
||||
GLOBAL_VARIABLES
|
||||
INNODB_BUFFER_PAGE
|
||||
INNODB_BUFFER_PAGE_LRU
|
||||
INNODB_BUFFER_POOL_PAGES
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX
|
||||
INNODB_BUFFER_POOL_STATS
|
||||
INNODB_CHANGED_PAGES
|
||||
INNODB_CMP
|
||||
INNODB_CMPMEM
|
||||
INNODB_CMPMEM_RESET
|
||||
@ -89,7 +93,6 @@ TRIGGERS
|
||||
USER_PRIVILEGES
|
||||
VIEWS
|
||||
XTRADB_ADMIN_COMMAND
|
||||
XTRADB_ENHANCEMENTS
|
||||
columns_priv
|
||||
db
|
||||
event
|
||||
@ -860,6 +863,8 @@ TABLE_NAME COLUMN_NAME PRIVILEGES
|
||||
COLUMNS TABLE_NAME select
|
||||
COLUMN_PRIVILEGES TABLE_NAME select
|
||||
FILES TABLE_NAME select
|
||||
INNODB_BUFFER_PAGE TABLE_NAME select
|
||||
INNODB_BUFFER_PAGE_LRU TABLE_NAME select
|
||||
INNODB_INDEX_STATS table_name select
|
||||
INNODB_TABLE_STATS table_name select
|
||||
KEY_COLUMN_USAGE TABLE_NAME select
|
||||
@ -1245,12 +1250,12 @@ DROP PROCEDURE p1;
|
||||
DROP USER mysql_bug20230@localhost;
|
||||
SELECT MAX(table_name) FROM information_schema.tables WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test');
|
||||
MAX(table_name)
|
||||
XTRADB_ENHANCEMENTS
|
||||
XTRADB_ADMIN_COMMAND
|
||||
SELECT table_name from information_schema.tables
|
||||
WHERE table_name=(SELECT MAX(table_name)
|
||||
FROM information_schema.tables WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test'));
|
||||
table_name
|
||||
XTRADB_ENHANCEMENTS
|
||||
XTRADB_ADMIN_COMMAND
|
||||
DROP TABLE IF EXISTS bug23037;
|
||||
DROP FUNCTION IF EXISTS get_value;
|
||||
SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037';
|
||||
|
@ -33,13 +33,13 @@ INNODB_BUFFER_POOL_PAGES
|
||||
PBXT_STATISTICS
|
||||
INNODB_CMP
|
||||
INNODB_RSEG
|
||||
XTRADB_ENHANCEMENTS
|
||||
INNODB_INDEX_STATS
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX
|
||||
XTRADB_ADMIN_COMMAND
|
||||
INNODB_TRX
|
||||
INNODB_SYS_TABLES
|
||||
INNODB_LOCK_WAITS
|
||||
INNODB_SYS_STATS
|
||||
INNODB_BUFFER_POOL_STATS
|
||||
INNODB_LOCKS
|
||||
INNODB_CMPMEM
|
||||
INNODB_TABLE_STATS
|
||||
@ -47,7 +47,10 @@ INNODB_SYS_INDEXES
|
||||
INNODB_CMP_RESET
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB
|
||||
INNODB_CMPMEM_RESET
|
||||
INNODB_INDEX_STATS
|
||||
INNODB_BUFFER_PAGE
|
||||
INNODB_CHANGED_PAGES
|
||||
INNODB_SYS_STATS
|
||||
INNODB_BUFFER_PAGE_LRU
|
||||
SELECT t.table_name, c1.column_name
|
||||
FROM information_schema.tables t
|
||||
INNER JOIN
|
||||
@ -95,13 +98,13 @@ INNODB_BUFFER_POOL_PAGES page_type
|
||||
PBXT_STATISTICS ID
|
||||
INNODB_CMP page_size
|
||||
INNODB_RSEG rseg_id
|
||||
XTRADB_ENHANCEMENTS name
|
||||
INNODB_INDEX_STATS table_schema
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX index_id
|
||||
XTRADB_ADMIN_COMMAND result_message
|
||||
INNODB_TRX trx_id
|
||||
INNODB_SYS_TABLES SCHEMA
|
||||
INNODB_LOCK_WAITS requesting_trx_id
|
||||
INNODB_SYS_STATS INDEX_ID
|
||||
INNODB_BUFFER_POOL_STATS POOL_SIZE
|
||||
INNODB_LOCKS lock_id
|
||||
INNODB_CMPMEM page_size
|
||||
INNODB_TABLE_STATS table_schema
|
||||
@ -109,7 +112,10 @@ INNODB_SYS_INDEXES TABLE_ID
|
||||
INNODB_CMP_RESET page_size
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB space_id
|
||||
INNODB_CMPMEM_RESET page_size
|
||||
INNODB_INDEX_STATS table_schema
|
||||
INNODB_BUFFER_PAGE BLOCK_ID
|
||||
INNODB_CHANGED_PAGES space_id
|
||||
INNODB_SYS_STATS INDEX_ID
|
||||
INNODB_BUFFER_PAGE_LRU LRU_POSITION
|
||||
SELECT t.table_name, c1.column_name
|
||||
FROM information_schema.tables t
|
||||
INNER JOIN
|
||||
@ -157,13 +163,13 @@ INNODB_BUFFER_POOL_PAGES page_type
|
||||
PBXT_STATISTICS ID
|
||||
INNODB_CMP page_size
|
||||
INNODB_RSEG rseg_id
|
||||
XTRADB_ENHANCEMENTS name
|
||||
INNODB_INDEX_STATS table_schema
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX index_id
|
||||
XTRADB_ADMIN_COMMAND result_message
|
||||
INNODB_TRX trx_id
|
||||
INNODB_SYS_TABLES SCHEMA
|
||||
INNODB_LOCK_WAITS requesting_trx_id
|
||||
INNODB_SYS_STATS INDEX_ID
|
||||
INNODB_BUFFER_POOL_STATS POOL_SIZE
|
||||
INNODB_LOCKS lock_id
|
||||
INNODB_CMPMEM page_size
|
||||
INNODB_TABLE_STATS table_schema
|
||||
@ -171,7 +177,10 @@ INNODB_SYS_INDEXES TABLE_ID
|
||||
INNODB_CMP_RESET page_size
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB space_id
|
||||
INNODB_CMPMEM_RESET page_size
|
||||
INNODB_INDEX_STATS table_schema
|
||||
INNODB_BUFFER_PAGE BLOCK_ID
|
||||
INNODB_CHANGED_PAGES space_id
|
||||
INNODB_SYS_STATS INDEX_ID
|
||||
INNODB_BUFFER_PAGE_LRU LRU_POSITION
|
||||
select 1 as f1 from information_schema.tables where "CHARACTER_SETS"=
|
||||
(select cast(table_name as char) from information_schema.tables
|
||||
order by table_name limit 1) limit 1;
|
||||
@ -203,9 +212,13 @@ EVENTS information_schema.EVENTS 1
|
||||
FILES information_schema.FILES 1
|
||||
GLOBAL_STATUS information_schema.GLOBAL_STATUS 1
|
||||
GLOBAL_VARIABLES information_schema.GLOBAL_VARIABLES 1
|
||||
INNODB_BUFFER_PAGE information_schema.INNODB_BUFFER_PAGE 1
|
||||
INNODB_BUFFER_PAGE_LRU information_schema.INNODB_BUFFER_PAGE_LRU 1
|
||||
INNODB_BUFFER_POOL_PAGES information_schema.INNODB_BUFFER_POOL_PAGES 1
|
||||
INNODB_BUFFER_POOL_PAGES_BLOB information_schema.INNODB_BUFFER_POOL_PAGES_BLOB 1
|
||||
INNODB_BUFFER_POOL_PAGES_INDEX information_schema.INNODB_BUFFER_POOL_PAGES_INDEX 1
|
||||
INNODB_BUFFER_POOL_STATS information_schema.INNODB_BUFFER_POOL_STATS 1
|
||||
INNODB_CHANGED_PAGES information_schema.INNODB_CHANGED_PAGES 1
|
||||
INNODB_CMP information_schema.INNODB_CMP 1
|
||||
INNODB_CMPMEM information_schema.INNODB_CMPMEM 1
|
||||
INNODB_CMPMEM_RESET information_schema.INNODB_CMPMEM_RESET 1
|
||||
@ -238,7 +251,6 @@ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
|
||||
TRIGGERS information_schema.TRIGGERS 1
|
||||
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
|
||||
VIEWS information_schema.VIEWS 1
|
||||
XTRADB_ENHANCEMENTS information_schema.XTRADB_ENHANCEMENTS 1
|
||||
Database: information_schema
|
||||
+---------------------------------------+
|
||||
| Tables |
|
||||
@ -275,13 +287,13 @@ Database: information_schema
|
||||
| PBXT_STATISTICS |
|
||||
| INNODB_CMP |
|
||||
| INNODB_RSEG |
|
||||
| XTRADB_ENHANCEMENTS |
|
||||
| INNODB_INDEX_STATS |
|
||||
| INNODB_BUFFER_POOL_PAGES_INDEX |
|
||||
| XTRADB_ADMIN_COMMAND |
|
||||
| INNODB_TRX |
|
||||
| INNODB_SYS_TABLES |
|
||||
| INNODB_LOCK_WAITS |
|
||||
| INNODB_SYS_STATS |
|
||||
| INNODB_BUFFER_POOL_STATS |
|
||||
| INNODB_LOCKS |
|
||||
| INNODB_CMPMEM |
|
||||
| INNODB_TABLE_STATS |
|
||||
@ -289,7 +301,10 @@ Database: information_schema
|
||||
| INNODB_CMP_RESET |
|
||||
| INNODB_BUFFER_POOL_PAGES_BLOB |
|
||||
| INNODB_CMPMEM_RESET |
|
||||
| INNODB_INDEX_STATS |
|
||||
| INNODB_BUFFER_PAGE |
|
||||
| INNODB_CHANGED_PAGES |
|
||||
| INNODB_SYS_STATS |
|
||||
| INNODB_BUFFER_PAGE_LRU |
|
||||
+---------------------------------------+
|
||||
Database: INFORMATION_SCHEMA
|
||||
+---------------------------------------+
|
||||
@ -327,13 +342,13 @@ Database: INFORMATION_SCHEMA
|
||||
| PBXT_STATISTICS |
|
||||
| INNODB_CMP |
|
||||
| INNODB_RSEG |
|
||||
| XTRADB_ENHANCEMENTS |
|
||||
| INNODB_INDEX_STATS |
|
||||
| INNODB_BUFFER_POOL_PAGES_INDEX |
|
||||
| XTRADB_ADMIN_COMMAND |
|
||||
| INNODB_TRX |
|
||||
| INNODB_SYS_TABLES |
|
||||
| INNODB_LOCK_WAITS |
|
||||
| INNODB_SYS_STATS |
|
||||
| INNODB_BUFFER_POOL_STATS |
|
||||
| INNODB_LOCKS |
|
||||
| INNODB_CMPMEM |
|
||||
| INNODB_TABLE_STATS |
|
||||
@ -341,7 +356,10 @@ Database: INFORMATION_SCHEMA
|
||||
| INNODB_CMP_RESET |
|
||||
| INNODB_BUFFER_POOL_PAGES_BLOB |
|
||||
| INNODB_CMPMEM_RESET |
|
||||
| INNODB_INDEX_STATS |
|
||||
| INNODB_BUFFER_PAGE |
|
||||
| INNODB_CHANGED_PAGES |
|
||||
| INNODB_SYS_STATS |
|
||||
| INNODB_BUFFER_PAGE_LRU |
|
||||
+---------------------------------------+
|
||||
Wildcard: inf_rmation_schema
|
||||
+--------------------+
|
||||
@ -351,5 +369,5 @@ Wildcard: inf_rmation_schema
|
||||
+--------------------+
|
||||
SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
|
||||
table_schema count(*)
|
||||
information_schema 47
|
||||
information_schema 50
|
||||
mysql 22
|
||||
|
@ -3198,7 +3198,7 @@ c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
|
||||
c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
|
||||
c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
|
||||
) ENGINE = InnoDB;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
|
@ -1096,7 +1096,7 @@ PRIMARY KEY (b(10), a), INDEX (c(10))
|
||||
INSERT INTO bug12547647 VALUES (5,repeat('khdfo5AlOq',1900),repeat('g',7731));
|
||||
COMMIT;
|
||||
UPDATE bug12547647 SET c = REPEAT('b',16928);
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
|
||||
DROP TABLE bug12547647;
|
||||
SET @r=REPEAT('a',500);
|
||||
CREATE TABLE t1(a INT,
|
||||
|
@ -125,12 +125,12 @@ CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2 CHARSET=ASCII;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
|
||||
CREATE TABLE t1(
|
||||
c TEXT NOT NULL, d TEXT NOT NULL,
|
||||
PRIMARY KEY (c(767),d(767)))
|
||||
@ -138,7 +138,7 @@ ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4 CHARSET=ASCII;
|
||||
drop table t1;
|
||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(440)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
|
||||
CREATE TABLE t1(c TEXT, PRIMARY KEY (c(438)))
|
||||
ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1 CHARSET=ASCII;
|
||||
INSERT INTO t1 VALUES(REPEAT('A',512)),(REPEAT('B',512));
|
||||
|
@ -3151,7 +3151,7 @@ c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
|
||||
c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
|
||||
c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
|
||||
) ENGINE = InnoDB;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
|
@ -8,7 +8,7 @@ ERROR HY000: Too big row
|
||||
SHOW WARNINGS;
|
||||
Level Code Message
|
||||
Error 139 Too big row
|
||||
Error 1118 Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
Error 1118 Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
|
||||
DROP TABLE bug53591;
|
||||
SET GLOBAL innodb_file_format=Antelope;
|
||||
SET GLOBAL innodb_file_per_table=0;
|
||||
|
@ -774,7 +774,7 @@ c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
|
||||
c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
|
||||
c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
|
||||
) ENGINE = InnoDB;
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
ERROR 42000: Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
|
||||
SET innodb_strict_mode=OFF;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
|
@ -62,7 +62,7 @@ SET(XTRADB_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
|
||||
ibuf/ibuf0ibuf.c
|
||||
pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
|
||||
lock/lock0lock.c lock/lock0iter.c
|
||||
log/log0log.c log/log0recv.c
|
||||
log/log0log.c log/log0recv.c log/log0online.c
|
||||
mach/mach0data.c
|
||||
mem/mem0mem.c mem/mem0pool.c
|
||||
mtr/mtr0log.c mtr/mtr0mtr.c
|
||||
|
@ -1,3 +1,32 @@
|
||||
2012-08-29 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, page/page0cur.c, page/page0page.c:
|
||||
Fix Bug#14554000 CRASH IN PAGE_REC_GET_NTH_CONST(NTH=0)
|
||||
DURING COMPRESSED PAGE SPLIT
|
||||
|
||||
2012-08-16 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c:
|
||||
Fix Bug#12595091 POSSIBLY INVALID ASSERTION IN
|
||||
BTR_CUR_PESSIMISTIC_UPDATE()
|
||||
|
||||
2012-08-16 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, btr/btr0cur.c:
|
||||
Fix Bug#12845774 OPTIMISTIC INSERT/UPDATE USES WRONG HEURISTICS FOR
|
||||
COMPRESSED PAGE SIZE
|
||||
|
||||
2012-08-16 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, page/page0page.c:
|
||||
Fix Bug#13523839 ASSERTION FAILURES ON COMPRESSED INNODB TABLES
|
||||
|
||||
2012-08-07 The InnoDB Team
|
||||
|
||||
* btr/btr0pcur.c, row/row0merge.c:
|
||||
Fix Bug#14399148 INNODB TABLES UNDER LOAD PRODUCE DUPLICATE COPIES
|
||||
OF ROWS IN QUERIES
|
||||
|
||||
2012-03-15 The InnoDB Team
|
||||
|
||||
* fil/fil0fil.c, ibuf/ibuf0ibuf.c, include/fil0fil.h,
|
||||
|
@ -101,6 +101,7 @@ noinst_HEADERS= \
|
||||
include/lock0types.h \
|
||||
include/log0log.h \
|
||||
include/log0log.ic \
|
||||
include/log0online.h \
|
||||
include/log0recv.h \
|
||||
include/log0recv.ic \
|
||||
include/mach0data.h \
|
||||
@ -226,7 +227,6 @@ noinst_HEADERS= \
|
||||
include/ut0vec.h \
|
||||
include/ut0vec.ic \
|
||||
include/ut0wqueue.h \
|
||||
handler/innodb_patch_info.h \
|
||||
mem/mem0dbg.c
|
||||
|
||||
noinst_LTLIBRARIES= @plugin_xtradb_static_target@
|
||||
@ -265,6 +265,7 @@ libxtradb_la_SOURCES= \
|
||||
lock/lock0iter.c \
|
||||
lock/lock0lock.c \
|
||||
log/log0log.c \
|
||||
log/log0online.c \
|
||||
log/log0recv.c \
|
||||
mach/mach0data.c \
|
||||
mem/mem0mem.c \
|
||||
|
@ -664,6 +664,12 @@ btr_root_fseg_validate(
|
||||
{
|
||||
ulint offset = mach_read_from_2(seg_header + FSEG_HDR_OFFSET);
|
||||
|
||||
if (UNIV_UNLIKELY(srv_pass_corrupt_table)) {
|
||||
return (mach_read_from_4(seg_header + FSEG_HDR_SPACE) == space)
|
||||
&& (offset >= FIL_PAGE_DATA)
|
||||
&& (offset <= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
|
||||
}
|
||||
|
||||
ut_a(mach_read_from_4(seg_header + FSEG_HDR_SPACE) == space);
|
||||
ut_a(offset >= FIL_PAGE_DATA);
|
||||
ut_a(offset <= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
|
||||
@ -704,6 +710,17 @@ btr_root_block_get(
|
||||
if (!dict_index_is_ibuf(index)) {
|
||||
const page_t* root = buf_block_get_frame(block);
|
||||
|
||||
if (UNIV_UNLIKELY(srv_pass_corrupt_table)) {
|
||||
if (!btr_root_fseg_validate(FIL_PAGE_DATA
|
||||
+ PAGE_BTR_SEG_LEAF
|
||||
+ root, space))
|
||||
return(NULL);
|
||||
if (!btr_root_fseg_validate(FIL_PAGE_DATA
|
||||
+ PAGE_BTR_SEG_TOP
|
||||
+ root, space))
|
||||
return(NULL);
|
||||
return(block);
|
||||
}
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, space));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
@ -1852,6 +1869,7 @@ btr_root_raise_and_insert(
|
||||
root = btr_cur_get_page(cursor);
|
||||
root_block = btr_cur_get_block(cursor);
|
||||
root_page_zip = buf_block_get_page_zip(root_block);
|
||||
ut_ad(page_get_n_recs(root) > 0);
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(!root_page_zip || page_zip_validate(root_page_zip, root));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
@ -2332,12 +2350,20 @@ btr_insert_on_non_leaf_level_func(
|
||||
BTR_CONT_MODIFY_TREE,
|
||||
&cursor, 0, file, line, mtr);
|
||||
|
||||
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
|
||||
| BTR_KEEP_SYS_FLAG
|
||||
| BTR_NO_UNDO_LOG_FLAG,
|
||||
&cursor, tuple, &rec,
|
||||
&dummy_big_rec, 0, NULL, mtr);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
ut_ad(cursor.flag == BTR_CUR_BINARY);
|
||||
|
||||
err = btr_cur_optimistic_insert(
|
||||
BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG
|
||||
| BTR_NO_UNDO_LOG_FLAG, &cursor, tuple, &rec,
|
||||
&dummy_big_rec, 0, NULL, mtr);
|
||||
|
||||
if (err == DB_FAIL) {
|
||||
err = btr_cur_pessimistic_insert(
|
||||
BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG
|
||||
| BTR_NO_UNDO_LOG_FLAG,
|
||||
&cursor, tuple, &rec, &dummy_big_rec, 0, NULL, mtr);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************//**
|
||||
@ -3262,6 +3288,7 @@ btr_compress(
|
||||
|
||||
if (adjust) {
|
||||
nth_rec = page_rec_get_n_recs_before(btr_cur_get_rec(cursor));
|
||||
ut_ad(nth_rec > 0);
|
||||
}
|
||||
|
||||
/* Decide the page to which we try to merge and which will inherit
|
||||
@ -3497,6 +3524,7 @@ func_exit:
|
||||
mem_heap_free(heap);
|
||||
|
||||
if (adjust) {
|
||||
ut_ad(nth_rec > 0);
|
||||
btr_cur_position(
|
||||
index,
|
||||
page_rec_get_nth(merge_block->frame, nth_rec),
|
||||
@ -4009,8 +4037,22 @@ btr_index_page_validate(
|
||||
{
|
||||
page_cur_t cur;
|
||||
ibool ret = TRUE;
|
||||
#ifndef DBUG_OFF
|
||||
ulint nth = 1;
|
||||
#endif /* !DBUG_OFF */
|
||||
|
||||
page_cur_set_before_first(block, &cur);
|
||||
|
||||
/* Directory slot 0 should only contain the infimum record. */
|
||||
DBUG_EXECUTE_IF("check_table_rec_next",
|
||||
ut_a(page_rec_get_nth_const(
|
||||
page_cur_get_page(&cur), 0)
|
||||
== cur.rec);
|
||||
ut_a(page_dir_slot_get_n_owned(
|
||||
page_dir_get_nth_slot(
|
||||
page_cur_get_page(&cur), 0))
|
||||
== 1););
|
||||
|
||||
page_cur_move_to_next(&cur);
|
||||
|
||||
for (;;) {
|
||||
@ -4024,6 +4066,16 @@ btr_index_page_validate(
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* Verify that page_rec_get_nth_const() is correctly
|
||||
retrieving each record. */
|
||||
DBUG_EXECUTE_IF("check_table_rec_next",
|
||||
ut_a(cur.rec == page_rec_get_nth_const(
|
||||
page_cur_get_page(&cur),
|
||||
page_rec_get_n_recs_before(
|
||||
cur.rec)));
|
||||
ut_a(nth++ == page_rec_get_n_recs_before(
|
||||
cur.rec)););
|
||||
|
||||
page_cur_move_to_next(&cur);
|
||||
}
|
||||
|
||||
@ -4435,6 +4487,12 @@ btr_validate_index(
|
||||
mtr_x_lock(dict_index_get_lock(index), &mtr);
|
||||
|
||||
root = btr_root_get(index, &mtr);
|
||||
|
||||
if (UNIV_UNLIKELY(srv_pass_corrupt_table && !root)) {
|
||||
mtr_commit(&mtr);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
n = btr_page_get_level(root, &mtr);
|
||||
|
||||
for (i = 0; i <= n && !trx_is_interrupted(trx); i++) {
|
||||
|
@ -1307,7 +1307,12 @@ fail_err:
|
||||
|
||||
if (UNIV_UNLIKELY(reorg)) {
|
||||
ut_a(zip_size);
|
||||
ut_a(*rec);
|
||||
/* It's possible for rec to be NULL if the
|
||||
page is compressed. This is because a
|
||||
reorganized page may become incompressible. */
|
||||
if (!*rec) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1443,20 +1448,9 @@ btr_cur_pessimistic_insert(
|
||||
ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, btr_cur_get_block(cursor),
|
||||
MTR_MEMO_PAGE_X_FIX));
|
||||
|
||||
/* Try first an optimistic insert; reset the cursor flag: we do not
|
||||
assume anything of how it was positioned */
|
||||
|
||||
cursor->flag = BTR_CUR_BINARY;
|
||||
|
||||
err = btr_cur_optimistic_insert(flags, cursor, entry, rec,
|
||||
big_rec, n_ext, thr, mtr);
|
||||
if (err != DB_FAIL) {
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
/* Retry with a pessimistic insert. Check locks and write to undo log,
|
||||
if specified */
|
||||
/* Check locks and write to undo log, if specified */
|
||||
|
||||
err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
|
||||
thr, mtr, &dummy_inh);
|
||||
@ -2083,8 +2077,12 @@ any_extern:
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
max_size = old_rec_size
|
||||
+ page_get_max_insert_size_after_reorganize(page, 1);
|
||||
/* We do not attempt to reorganize if the page is compressed.
|
||||
This is because the page may fail to compress after reorganization. */
|
||||
max_size = page_zip
|
||||
? page_get_max_insert_size(page, 1)
|
||||
: (old_rec_size
|
||||
+ page_get_max_insert_size_after_reorganize(page, 1));
|
||||
|
||||
if (!(((max_size >= BTR_CUR_PAGE_REORGANIZE_LIMIT)
|
||||
&& (max_size >= new_rec_size))
|
||||
@ -2452,7 +2450,12 @@ make_external:
|
||||
err = DB_SUCCESS;
|
||||
goto return_after_reservations;
|
||||
} else {
|
||||
ut_a(optim_err != DB_UNDERFLOW);
|
||||
/* If the page is compressed and it initially
|
||||
compresses very well, and there is a subsequent insert
|
||||
of a badly-compressing record, it is possible for
|
||||
btr_cur_optimistic_update() to return DB_UNDERFLOW and
|
||||
btr_cur_insert_if_possible() to return FALSE. */
|
||||
ut_a(page_zip || optim_err != DB_UNDERFLOW);
|
||||
|
||||
/* Out of space: reset the free bits. */
|
||||
if (!dict_index_is_clust(index)
|
||||
@ -2480,8 +2483,10 @@ make_external:
|
||||
record on its page? */
|
||||
was_first = page_cur_is_before_first(page_cursor);
|
||||
|
||||
/* The first parameter means that no lock checking and undo logging
|
||||
is made in the insert */
|
||||
/* Lock checks and undo logging were already performed by
|
||||
btr_cur_upd_lock_and_undo(). We do not try
|
||||
btr_cur_optimistic_insert() because
|
||||
btr_cur_insert_if_possible() already failed above. */
|
||||
|
||||
err = btr_cur_pessimistic_insert(BTR_NO_UNDO_LOG_FLAG
|
||||
| BTR_NO_LOCKING_FLAG
|
||||
@ -3483,6 +3488,8 @@ btr_estimate_n_rows_in_range(
|
||||
n_rows = n_rows * 2;
|
||||
}
|
||||
|
||||
DBUG_EXECUTE_IF("bug14007649", return(n_rows););
|
||||
|
||||
/* Do not estimate the number of rows in the range
|
||||
to over 1 / 2 of the estimated rows in the whole
|
||||
table */
|
||||
@ -3582,9 +3589,9 @@ btr_record_not_null_field_in_rec(
|
||||
|
||||
for (i = 0; i < n_unique; i++) {
|
||||
if (rec_offs_nth_sql_null(offsets, i)) {
|
||||
/* Break if we hit the first NULL value */
|
||||
break;
|
||||
}
|
||||
|
||||
n_not_null[i]++;
|
||||
}
|
||||
}
|
||||
|
@ -342,44 +342,39 @@ btr_pcur_restore_position_func(
|
||||
/* Restore the old search mode */
|
||||
cursor->search_mode = old_mode;
|
||||
|
||||
if (btr_pcur_is_on_user_rec(cursor)) {
|
||||
switch (cursor->rel_pos) {
|
||||
case BTR_PCUR_ON:
|
||||
if (!cmp_dtuple_rec(
|
||||
tuple, btr_pcur_get_rec(cursor),
|
||||
rec_get_offsets(btr_pcur_get_rec(cursor),
|
||||
index, NULL,
|
||||
ULINT_UNDEFINED, &heap))) {
|
||||
switch (cursor->rel_pos) {
|
||||
case BTR_PCUR_ON:
|
||||
if (btr_pcur_is_on_user_rec(cursor)
|
||||
&& !cmp_dtuple_rec(
|
||||
tuple, btr_pcur_get_rec(cursor),
|
||||
rec_get_offsets(btr_pcur_get_rec(cursor),
|
||||
index, NULL,
|
||||
ULINT_UNDEFINED, &heap))) {
|
||||
|
||||
/* We have to store the NEW value for
|
||||
the modify clock, since the cursor can
|
||||
now be on a different page! But we can
|
||||
retain the value of old_rec */
|
||||
/* We have to store the NEW value for
|
||||
the modify clock, since the cursor can
|
||||
now be on a different page! But we can
|
||||
retain the value of old_rec */
|
||||
|
||||
cursor->block_when_stored =
|
||||
btr_pcur_get_block(cursor);
|
||||
cursor->modify_clock =
|
||||
buf_block_get_modify_clock(
|
||||
cursor->block_when_stored);
|
||||
cursor->old_stored = BTR_PCUR_OLD_STORED;
|
||||
cursor->block_when_stored =
|
||||
btr_pcur_get_block(cursor);
|
||||
cursor->modify_clock =
|
||||
buf_block_get_modify_clock(
|
||||
cursor->block_when_stored);
|
||||
cursor->old_stored = BTR_PCUR_OLD_STORED;
|
||||
|
||||
mem_heap_free(heap);
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
break;
|
||||
case BTR_PCUR_BEFORE:
|
||||
page_cur_move_to_next(btr_pcur_get_page_cur(cursor));
|
||||
break;
|
||||
case BTR_PCUR_AFTER:
|
||||
page_cur_move_to_prev(btr_pcur_get_page_cur(cursor));
|
||||
break;
|
||||
#ifdef UNIV_DEBUG
|
||||
default:
|
||||
ut_error;
|
||||
#endif /* UNIV_DEBUG */
|
||||
return(TRUE);
|
||||
}
|
||||
#ifdef UNIV_DEBUG
|
||||
/* fall through */
|
||||
case BTR_PCUR_BEFORE:
|
||||
case BTR_PCUR_AFTER:
|
||||
break;
|
||||
default:
|
||||
ut_error;
|
||||
#endif /* UNIV_DEBUG */
|
||||
}
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
@ -2123,6 +2123,7 @@ wait_until_unfixed:
|
||||
if (mode == BUF_GET_IF_IN_POOL && ibuf_debug) {
|
||||
/* Try to evict the block from the buffer pool, to use the
|
||||
insert buffer as much as possible. */
|
||||
ulint page_no = buf_block_get_page_no(block);
|
||||
|
||||
if (buf_LRU_free_block(&block->page, TRUE, FALSE)) {
|
||||
//buf_pool_mutex_exit();
|
||||
@ -2131,6 +2132,18 @@ wait_until_unfixed:
|
||||
"innodb_change_buffering_debug evict %u %u\n",
|
||||
(unsigned) space, (unsigned) offset);
|
||||
return(NULL);
|
||||
} else if (UNIV_UNLIKELY(buf_block_get_state(block)
|
||||
!= BUF_BLOCK_FILE_PAGE
|
||||
|| (buf_block_get_page_no(block) != page_no)
|
||||
|| (buf_block_get_space(block) != space))) {
|
||||
|
||||
/* buf_LRU_free_block temporarily releases the
|
||||
block mutex, and now block points to something
|
||||
else. */
|
||||
mutex_exit(block_mutex);
|
||||
block = NULL;
|
||||
goto loop2;
|
||||
|
||||
} else if (buf_flush_page_try(block)) {
|
||||
fprintf(stderr,
|
||||
"innodb_change_buffering_debug flush %u %u\n",
|
||||
@ -4078,6 +4091,133 @@ buf_get_free_list_len(void)
|
||||
|
||||
return(len);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Collect buffer pool stats information for a buffer pool. Also
|
||||
record aggregated stats if there are more than one buffer pool
|
||||
in the server */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_stats_get_pool_info(
|
||||
/*====================*/
|
||||
buf_pool_info_t* pool_info) /*!< in/out: buffer pool info
|
||||
to fill */
|
||||
{
|
||||
time_t current_time;
|
||||
double time_elapsed;
|
||||
|
||||
buf_pool_mutex_enter();
|
||||
|
||||
pool_info->pool_size = buf_pool->curr_size;
|
||||
|
||||
pool_info->lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
|
||||
|
||||
pool_info->old_lru_len = buf_pool->LRU_old_len;
|
||||
|
||||
pool_info->free_list_len = UT_LIST_GET_LEN(buf_pool->free);
|
||||
|
||||
pool_info->flush_list_len = UT_LIST_GET_LEN(buf_pool->flush_list);
|
||||
|
||||
pool_info->n_pend_unzip = UT_LIST_GET_LEN(buf_pool->unzip_LRU);
|
||||
|
||||
pool_info->n_pend_reads = buf_pool->n_pend_reads;
|
||||
|
||||
pool_info->n_pending_flush_lru =
|
||||
(buf_pool->n_flush[BUF_FLUSH_LRU]
|
||||
+ buf_pool->init_flush[BUF_FLUSH_LRU]);
|
||||
|
||||
pool_info->n_pending_flush_list =
|
||||
(buf_pool->n_flush[BUF_FLUSH_LIST]
|
||||
+ buf_pool->init_flush[BUF_FLUSH_LIST]);
|
||||
|
||||
pool_info->n_pending_flush_single_page =
|
||||
(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]
|
||||
+ buf_pool->init_flush[BUF_FLUSH_SINGLE_PAGE]);
|
||||
|
||||
current_time = time(NULL);
|
||||
time_elapsed = 0.001 + difftime(current_time,
|
||||
buf_pool->last_printout_time);
|
||||
|
||||
pool_info->n_pages_made_young = buf_pool->stat.n_pages_made_young;
|
||||
|
||||
pool_info->n_pages_not_made_young =
|
||||
buf_pool->stat.n_pages_not_made_young;
|
||||
|
||||
pool_info->n_pages_read = buf_pool->stat.n_pages_read;
|
||||
|
||||
pool_info->n_pages_created = buf_pool->stat.n_pages_created;
|
||||
|
||||
pool_info->n_pages_written = buf_pool->stat.n_pages_written;
|
||||
|
||||
pool_info->n_page_gets = buf_pool->stat.n_page_gets;
|
||||
|
||||
pool_info->n_ra_pages_read_rnd = buf_pool->stat.n_ra_pages_read_rnd;
|
||||
pool_info->n_ra_pages_read = buf_pool->stat.n_ra_pages_read;
|
||||
|
||||
pool_info->n_ra_pages_evicted = buf_pool->stat.n_ra_pages_evicted;
|
||||
|
||||
pool_info->page_made_young_rate =
|
||||
(buf_pool->stat.n_pages_made_young
|
||||
- buf_pool->old_stat.n_pages_made_young) / time_elapsed;
|
||||
|
||||
pool_info->page_not_made_young_rate =
|
||||
(buf_pool->stat.n_pages_not_made_young
|
||||
- buf_pool->old_stat.n_pages_not_made_young) / time_elapsed;
|
||||
|
||||
pool_info->pages_read_rate =
|
||||
(buf_pool->stat.n_pages_read
|
||||
- buf_pool->old_stat.n_pages_read) / time_elapsed;
|
||||
|
||||
pool_info->pages_created_rate =
|
||||
(buf_pool->stat.n_pages_created
|
||||
- buf_pool->old_stat.n_pages_created) / time_elapsed;
|
||||
|
||||
pool_info->pages_written_rate =
|
||||
(buf_pool->stat.n_pages_written
|
||||
- buf_pool->old_stat.n_pages_written) / time_elapsed;
|
||||
|
||||
pool_info->n_page_get_delta = buf_pool->stat.n_page_gets
|
||||
- buf_pool->old_stat.n_page_gets;
|
||||
|
||||
if (pool_info->n_page_get_delta) {
|
||||
pool_info->page_read_delta = buf_pool->stat.n_pages_read
|
||||
- buf_pool->old_stat.n_pages_read;
|
||||
|
||||
pool_info->young_making_delta =
|
||||
buf_pool->stat.n_pages_made_young
|
||||
- buf_pool->old_stat.n_pages_made_young;
|
||||
|
||||
pool_info->not_young_making_delta =
|
||||
buf_pool->stat.n_pages_not_made_young
|
||||
- buf_pool->old_stat.n_pages_not_made_young;
|
||||
}
|
||||
pool_info->pages_readahead_rnd_rate =
|
||||
(buf_pool->stat.n_ra_pages_read_rnd
|
||||
- buf_pool->old_stat.n_ra_pages_read_rnd) / time_elapsed;
|
||||
|
||||
|
||||
pool_info->pages_readahead_rate =
|
||||
(buf_pool->stat.n_ra_pages_read
|
||||
- buf_pool->old_stat.n_ra_pages_read) / time_elapsed;
|
||||
|
||||
pool_info->pages_evicted_rate =
|
||||
(buf_pool->stat.n_ra_pages_evicted
|
||||
- buf_pool->old_stat.n_ra_pages_evicted) / time_elapsed;
|
||||
|
||||
pool_info->unzip_lru_len = UT_LIST_GET_LEN(buf_pool->unzip_LRU);
|
||||
|
||||
pool_info->io_sum = buf_LRU_stat_sum.io;
|
||||
|
||||
pool_info->io_cur = buf_LRU_stat_cur.io;
|
||||
|
||||
pool_info->unzip_sum = buf_LRU_stat_sum.unzip;
|
||||
|
||||
pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
|
||||
|
||||
buf_refresh_io_stats();
|
||||
buf_pool_mutex_exit();
|
||||
}
|
||||
|
||||
#else /* !UNIV_HOTBACKUP */
|
||||
/********************************************************************//**
|
||||
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
|
||||
@ -4108,3 +4248,5 @@ buf_page_init_for_backup_restore(
|
||||
}
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
|
||||
|
@ -48,6 +48,7 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#include "page0zip.h"
|
||||
#include "log0recv.h"
|
||||
#include "srv0srv.h"
|
||||
#include "srv0start.h"
|
||||
|
||||
/** The number of blocks from the LRU_old pointer onward, including
|
||||
the block pointed to, must be buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
|
||||
@ -1428,13 +1429,12 @@ buf_LRU_make_block_old(
|
||||
Try to free a block. If bpage is a descriptor of a compressed-only
|
||||
page, the descriptor object will be freed as well.
|
||||
|
||||
NOTE: If this function returns TRUE, it will temporarily
|
||||
release buf_pool_mutex. Furthermore, the page frame will no longer be
|
||||
accessible via bpage.
|
||||
NOTE: This will temporarily release buf_pool_mutex. Furthermore, the
|
||||
page frame will no longer be accessible via bpage.
|
||||
|
||||
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
|
||||
release these two mutexes after the call. No other
|
||||
buf_page_get_mutex() may be held when calling this function.
|
||||
The caller must hold buf_page_get_mutex(bpage) and release this mutex
|
||||
after the call. No other buf_page_get_mutex() may be held when
|
||||
calling this function.
|
||||
@return TRUE if freed, FALSE otherwise. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
@ -2098,6 +2098,12 @@ func_exit:
|
||||
/********************************************************************//**
|
||||
Dump the LRU page list to the specific file. */
|
||||
#define LRU_DUMP_FILE "ib_lru_dump"
|
||||
#define LRU_DUMP_TEMP_FILE "ib_lru_dump.tmp"
|
||||
#define LRU_OS_FILE_WRITE() \
|
||||
os_file_write(LRU_DUMP_FILE, dump_file, buffer, \
|
||||
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL, \
|
||||
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)), \
|
||||
UNIV_PAGE_SIZE)
|
||||
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
@ -2109,17 +2115,19 @@ buf_LRU_file_dump(void)
|
||||
byte* buffer_base = NULL;
|
||||
byte* buffer = NULL;
|
||||
buf_page_t* bpage;
|
||||
buf_page_t* first_bpage;
|
||||
ulint buffers;
|
||||
ulint offset;
|
||||
ibool ret = FALSE;
|
||||
ulint pages_written;
|
||||
ulint i;
|
||||
ulint total_pages;
|
||||
|
||||
for (i = 0; i < srv_n_data_files; i++) {
|
||||
if (strstr(srv_data_file_names[i], LRU_DUMP_FILE) != NULL) {
|
||||
fprintf(stderr,
|
||||
" InnoDB: The name '%s' seems to be used for"
|
||||
" innodb_data_file_path. Dumping LRU list is not"
|
||||
" done for safeness.\n", LRU_DUMP_FILE);
|
||||
" innodb_data_file_path. Dumping LRU list is"
|
||||
" not done for safeness.\n", LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
@ -2132,7 +2140,7 @@ buf_LRU_file_dump(void)
|
||||
goto end;
|
||||
}
|
||||
|
||||
dump_file = os_file_create(LRU_DUMP_FILE, OS_FILE_OVERWRITE,
|
||||
dump_file = os_file_create(LRU_DUMP_TEMP_FILE, OS_FILE_OVERWRITE,
|
||||
OS_FILE_NORMAL, OS_DATA_FILE, &success);
|
||||
if (!success) {
|
||||
os_file_get_last_error(TRUE);
|
||||
@ -2142,12 +2150,21 @@ buf_LRU_file_dump(void)
|
||||
}
|
||||
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
bpage = first_bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
|
||||
total_pages = UT_LIST_GET_LEN(buf_pool->LRU);
|
||||
|
||||
buffers = offset = 0;
|
||||
while (bpage != NULL) {
|
||||
if (offset == 0) {
|
||||
memset(buffer, 0, UNIV_PAGE_SIZE);
|
||||
buffers = offset = pages_written = 0;
|
||||
while (bpage != NULL && (pages_written++ < total_pages)) {
|
||||
|
||||
buf_page_t* next_bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
||||
|
||||
if (next_bpage == first_bpage) {
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
success = FALSE;
|
||||
fprintf(stderr,
|
||||
"InnoDB: detected cycle in LRU, skipping "
|
||||
"dump\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
mach_write_to_4(buffer + offset * 4, bpage->space);
|
||||
@ -2156,50 +2173,79 @@ buf_LRU_file_dump(void)
|
||||
offset++;
|
||||
|
||||
if (offset == UNIV_PAGE_SIZE/4) {
|
||||
success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
|
||||
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
|
||||
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
|
||||
UNIV_PAGE_SIZE);
|
||||
mutex_t *next_block_mutex = NULL;
|
||||
|
||||
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
success = FALSE;
|
||||
fprintf(stderr,
|
||||
" InnoDB: stopped dumping lru pages"
|
||||
" because of server shutdown.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* while writing file, release buffer pool mutex but
|
||||
keep the next page fixed so we don't worry about
|
||||
our list iterator becoming invalid */
|
||||
if (next_bpage) {
|
||||
next_block_mutex = buf_page_get_mutex(
|
||||
next_bpage);
|
||||
|
||||
mutex_enter(next_block_mutex);
|
||||
next_bpage->buf_fix_count++;
|
||||
mutex_exit(next_block_mutex);
|
||||
}
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
|
||||
success = LRU_OS_FILE_WRITE();
|
||||
|
||||
/* grab this again here so that next_bpage
|
||||
can't be purged when we drop the fix_count */
|
||||
mutex_enter(&LRU_list_mutex);
|
||||
|
||||
if (next_bpage) {
|
||||
mutex_enter(next_block_mutex);
|
||||
next_bpage->buf_fix_count--;
|
||||
mutex_exit(next_block_mutex);
|
||||
}
|
||||
if (!success) {
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot write page %lu of %s\n",
|
||||
" InnoDB: cannot write page"
|
||||
" %lu of %s\n",
|
||||
buffers, LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
buffers++;
|
||||
offset = 0;
|
||||
bpage = next_bpage;
|
||||
} else {
|
||||
bpage = UT_LIST_GET_NEXT(LRU, bpage);
|
||||
}
|
||||
|
||||
bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
}
|
||||
} /* while(bpage ...) */
|
||||
mutex_exit(&LRU_list_mutex);
|
||||
|
||||
if (offset == 0) {
|
||||
memset(buffer, 0, UNIV_PAGE_SIZE);
|
||||
}
|
||||
|
||||
mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
|
||||
offset++;
|
||||
mach_write_to_4(buffer + offset * 4, 0xFFFFFFFFUL);
|
||||
offset++;
|
||||
|
||||
success = os_file_write(LRU_DUMP_FILE, dump_file, buffer,
|
||||
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
|
||||
(buffers >> (32 - UNIV_PAGE_SIZE_SHIFT)),
|
||||
UNIV_PAGE_SIZE);
|
||||
if (!success) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
success = LRU_OS_FILE_WRITE();
|
||||
end:
|
||||
if (dump_file != (os_file_t) -1)
|
||||
if (dump_file != (os_file_t) -1) {
|
||||
if (success) {
|
||||
success = os_file_flush(dump_file, TRUE);
|
||||
}
|
||||
os_file_close(dump_file);
|
||||
}
|
||||
if (success) {
|
||||
success = os_file_rename(LRU_DUMP_TEMP_FILE,
|
||||
LRU_DUMP_FILE);
|
||||
}
|
||||
if (buffer_base)
|
||||
ut_free(buffer_base);
|
||||
|
||||
return(ret);
|
||||
return(success);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -2241,6 +2287,7 @@ buf_LRU_file_restore(void)
|
||||
dump_record_t* records = NULL;
|
||||
ulint size;
|
||||
ulint size_high;
|
||||
ulint recsize = sizeof(dump_record_t);
|
||||
ulint length;
|
||||
|
||||
dump_file = os_file_create_simple_no_error_handling(
|
||||
@ -2248,7 +2295,15 @@ buf_LRU_file_restore(void)
|
||||
if (!success || !os_file_get_size(dump_file, &size, &size_high)) {
|
||||
os_file_get_last_error(TRUE);
|
||||
fprintf(stderr,
|
||||
" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
|
||||
" InnoDB: cannot open %s,"
|
||||
" buffer pool preload not done\n",
|
||||
LRU_DUMP_FILE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (size == 0 || size_high > 0 || size % recsize) {
|
||||
fprintf(stderr, " InnoDB: broken LRU dump file,"
|
||||
" buffer pool preload not done\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
@ -2332,6 +2387,14 @@ buf_LRU_file_restore(void)
|
||||
if (offset % 16 == 15) {
|
||||
os_aio_simulated_wake_handler_threads();
|
||||
buf_flush_free_margin(FALSE);
|
||||
/* skip loading of the rest of the file if we are
|
||||
terminating anyway*/
|
||||
if (srv_shutdown_state != SRV_SHUTDOWN_NONE) {
|
||||
fprintf(stderr,
|
||||
" InnoDB: stopped loading LRU pages"
|
||||
" because of server shutdown.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zip_size = fil_space_get_zip_size(space_id);
|
||||
|
@ -236,6 +236,166 @@ dict_hdr_create(
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Verifies the SYS_STATS table by scanning its clustered index. This
|
||||
function may only be called at InnoDB startup time.
|
||||
|
||||
@return TRUE if SYS_STATS was verified successfully */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
dict_verify_xtradb_sys_stats(void)
|
||||
/*==============================*/
|
||||
{
|
||||
dict_index_t* sys_stats_index;
|
||||
ulint saved_srv_pass_corrupt_table = srv_pass_corrupt_table;
|
||||
ibool result;
|
||||
|
||||
sys_stats_index = dict_table_get_first_index(dict_sys->sys_stats);
|
||||
|
||||
/* Since this may be called only during server startup, avoid hitting
|
||||
various asserts by using XtraDB pass_corrupt_table option. */
|
||||
srv_pass_corrupt_table = 1;
|
||||
result = btr_validate_index(sys_stats_index, NULL);
|
||||
srv_pass_corrupt_table = saved_srv_pass_corrupt_table;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Creates the B-tree for the SYS_STATS clustered index, adds the XtraDB
|
||||
mark and the id of the index to the dictionary header page. Rewrites
|
||||
both passed args. */
|
||||
static
|
||||
void
|
||||
dict_create_xtradb_sys_stats(
|
||||
/*=========================*/
|
||||
dict_hdr_t** dict_hdr, /*!< in/out: dictionary header */
|
||||
mtr_t* mtr) /*!< in/out: mtr */
|
||||
{
|
||||
ulint root_page_no;
|
||||
|
||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||
DICT_HDR_SPACE, 0, DICT_STATS_ID,
|
||||
dict_ind_redundant, mtr);
|
||||
if (root_page_no == FIL_NULL) {
|
||||
fprintf(stderr, "InnoDB: Warning: failed to create SYS_STATS btr.\n");
|
||||
srv_use_sys_stats_table = FALSE;
|
||||
} else {
|
||||
mlog_write_ulint(*dict_hdr + DICT_HDR_STATS, root_page_no,
|
||||
MLOG_4BYTES, mtr);
|
||||
mlog_write_dulint(*dict_hdr + DICT_HDR_XTRADB_MARK,
|
||||
DICT_HDR_XTRADB_FLAG, mtr);
|
||||
}
|
||||
mtr_commit(mtr);
|
||||
/* restart mtr */
|
||||
mtr_start(mtr);
|
||||
*dict_hdr = dict_hdr_get(mtr);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Create the table and index structure of SYS_STATS for the dictionary
|
||||
cache and add it there. If called for the first time, also support
|
||||
wrong root page id injection for testing purposes. */
|
||||
static
|
||||
void
|
||||
dict_add_to_cache_xtradb_sys_stats(
|
||||
/*===============================*/
|
||||
ibool first_time __attribute__((unused)),
|
||||
/*!< in: first invocation flag. If
|
||||
TRUE, optionally inject wrong root page
|
||||
id */
|
||||
mem_heap_t* heap, /*!< in: memory heap for table/index
|
||||
allocation */
|
||||
dict_hdr_t* dict_hdr, /*!< in: dictionary header */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
dict_table_t* table;
|
||||
dict_index_t* index;
|
||||
ulint root_page_id;
|
||||
ulint error;
|
||||
|
||||
table = dict_mem_table_create("SYS_STATS", DICT_HDR_SPACE, 4, 0);
|
||||
table->n_mysql_handles_opened = 1; /* for pin */
|
||||
|
||||
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
|
||||
dict_mem_table_add_col(table, heap, "KEY_COLS", DATA_INT, 0, 4);
|
||||
dict_mem_table_add_col(table, heap, "DIFF_VALS", DATA_BINARY, 0, 0);
|
||||
dict_mem_table_add_col(table, heap, "NON_NULL_VALS", DATA_BINARY, 0, 0);
|
||||
|
||||
/* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
|
||||
#if DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2
|
||||
#error "DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2"
|
||||
#endif
|
||||
#if DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2
|
||||
#error "DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2"
|
||||
#endif
|
||||
|
||||
table->id = DICT_STATS_ID;
|
||||
dict_table_add_to_cache(table, heap);
|
||||
dict_sys->sys_stats = table;
|
||||
mem_heap_empty(heap);
|
||||
|
||||
index = dict_mem_index_create("SYS_STATS", "CLUST_IND",
|
||||
DICT_HDR_SPACE,
|
||||
DICT_UNIQUE | DICT_CLUSTERED, 2);
|
||||
|
||||
dict_mem_index_add_field(index, "INDEX_ID", 0);
|
||||
dict_mem_index_add_field(index, "KEY_COLS", 0);
|
||||
|
||||
index->id = DICT_STATS_ID;
|
||||
|
||||
root_page_id = mtr_read_ulint(dict_hdr + DICT_HDR_STATS, MLOG_4BYTES,
|
||||
mtr);
|
||||
#ifdef UNIV_DEBUG
|
||||
if ((srv_sys_stats_root_page != 0) && first_time)
|
||||
root_page_id = srv_sys_stats_root_page;
|
||||
#endif
|
||||
error = dict_index_add_to_cache(table, index, root_page_id, FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
mem_heap_empty(heap);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Discard the existing dictionary cache SYS_STATS information, create and
|
||||
add it there anew. Does not touch the old SYS_STATS tablespace page
|
||||
under the assumption that they are corrupted or overwritten for other
|
||||
purposes. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_recreate_xtradb_sys_stats(void)
|
||||
/*================================*/
|
||||
{
|
||||
mtr_t mtr;
|
||||
dict_hdr_t* dict_hdr;
|
||||
dict_index_t* sys_stats_clust_idx;
|
||||
mem_heap_t* heap;
|
||||
|
||||
heap = mem_heap_create(450);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
sys_stats_clust_idx = dict_table_get_first_index(dict_sys->sys_stats);
|
||||
dict_index_remove_from_cache(dict_sys->sys_stats, sys_stats_clust_idx);
|
||||
|
||||
dict_table_remove_from_cache(dict_sys->sys_stats);
|
||||
|
||||
dict_sys->sys_stats = NULL;
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
dict_hdr = dict_hdr_get(&mtr);
|
||||
|
||||
dict_create_xtradb_sys_stats(&dict_hdr, &mtr);
|
||||
dict_add_to_cache_xtradb_sys_stats(FALSE, heap, dict_hdr, &mtr);
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
mutex_exit(&(dict_sys->mutex));
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Initializes the data dictionary memory structures when the database is
|
||||
started. This function is also called when the data dictionary is created. */
|
||||
@ -251,39 +411,23 @@ dict_boot(void)
|
||||
mtr_t mtr;
|
||||
ulint error;
|
||||
|
||||
heap = mem_heap_create(450);
|
||||
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* Create the hash tables etc. */
|
||||
dict_init();
|
||||
|
||||
heap = mem_heap_create(450);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
|
||||
/* Get the dictionary header */
|
||||
dict_hdr = dict_hdr_get(&mtr);
|
||||
|
||||
if (ut_dulint_cmp(mtr_read_dulint(dict_hdr + DICT_HDR_XTRADB_MARK, &mtr),
|
||||
DICT_HDR_XTRADB_FLAG) != 0) {
|
||||
/* not extended yet by XtraDB, need to be extended */
|
||||
ulint root_page_no;
|
||||
if (ut_dulint_cmp(mtr_read_dulint(dict_hdr + DICT_HDR_XTRADB_MARK,
|
||||
&mtr), DICT_HDR_XTRADB_FLAG) != 0) {
|
||||
|
||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||
DICT_HDR_SPACE, 0, DICT_STATS_ID,
|
||||
dict_ind_redundant, &mtr);
|
||||
if (root_page_no == FIL_NULL) {
|
||||
fprintf(stderr, "InnoDB: Warning: failed to create SYS_STATS btr.\n");
|
||||
srv_use_sys_stats_table = FALSE;
|
||||
} else {
|
||||
mlog_write_ulint(dict_hdr + DICT_HDR_STATS, root_page_no,
|
||||
MLOG_4BYTES, &mtr);
|
||||
mlog_write_dulint(dict_hdr + DICT_HDR_XTRADB_MARK,
|
||||
DICT_HDR_XTRADB_FLAG, &mtr);
|
||||
}
|
||||
mtr_commit(&mtr);
|
||||
/* restart mtr */
|
||||
mtr_start(&mtr);
|
||||
dict_hdr = dict_hdr_get(&mtr);
|
||||
/* not extended yet by XtraDB, need to be extended */
|
||||
dict_create_xtradb_sys_stats(&dict_hdr, &mtr);
|
||||
}
|
||||
|
||||
/* Because we only write new row ids to disk-based data structure
|
||||
@ -464,42 +608,7 @@ dict_boot(void)
|
||||
FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
|
||||
/*-------------------------*/
|
||||
table = dict_mem_table_create("SYS_STATS", DICT_HDR_SPACE, 4, 0);
|
||||
table->n_mysql_handles_opened = 1; /* for pin */
|
||||
|
||||
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
|
||||
dict_mem_table_add_col(table, heap, "KEY_COLS", DATA_INT, 0, 4);
|
||||
dict_mem_table_add_col(table, heap, "DIFF_VALS", DATA_BINARY, 0, 0);
|
||||
dict_mem_table_add_col(table, heap, "NON_NULL_VALS", DATA_BINARY, 0, 0);
|
||||
|
||||
/* The '+ 2' below comes from the fields DB_TRX_ID, DB_ROLL_PTR */
|
||||
#if DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2
|
||||
#error "DICT_SYS_STATS_DIFF_VALS_FIELD != 2 + 2"
|
||||
#endif
|
||||
#if DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2
|
||||
#error "DICT_SYS_STATS_NON_NULL_VALS_FIELD != 3 + 2"
|
||||
#endif
|
||||
|
||||
table->id = DICT_STATS_ID;
|
||||
dict_table_add_to_cache(table, heap);
|
||||
dict_sys->sys_stats = table;
|
||||
mem_heap_empty(heap);
|
||||
|
||||
index = dict_mem_index_create("SYS_STATS", "CLUST_IND",
|
||||
DICT_HDR_SPACE,
|
||||
DICT_UNIQUE | DICT_CLUSTERED, 2);
|
||||
|
||||
dict_mem_index_add_field(index, "INDEX_ID", 0);
|
||||
dict_mem_index_add_field(index, "KEY_COLS", 0);
|
||||
|
||||
index->id = DICT_STATS_ID;
|
||||
error = dict_index_add_to_cache(table, index,
|
||||
mtr_read_ulint(dict_hdr
|
||||
+ DICT_HDR_STATS,
|
||||
MLOG_4BYTES, &mtr),
|
||||
FALSE);
|
||||
ut_a(error == DB_SUCCESS);
|
||||
dict_add_to_cache_xtradb_sys_stats(TRUE, heap, dict_hdr, &mtr);
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
||||
|
@ -4622,12 +4622,6 @@ next_rec:
|
||||
}
|
||||
btr_pcur_close(&pcur);
|
||||
mtr_commit(&mtr);
|
||||
|
||||
if (rests) {
|
||||
fprintf(stderr, "InnoDB: Warning: failed to store %lu stats entries"
|
||||
" of %s/%s to SYS_STATS system table.\n",
|
||||
rests, index->table_name, index->name);
|
||||
}
|
||||
}
|
||||
/*===========================================*/
|
||||
|
||||
@ -5394,6 +5388,28 @@ dict_table_replace_index_in_foreign_list(
|
||||
foreign->foreign_index = new_index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
foreign;
|
||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
||||
|
||||
dict_index_t* new_index;
|
||||
|
||||
if (foreign->referenced_index == index) {
|
||||
ut_ad(foreign->referenced_table == index->table);
|
||||
|
||||
new_index = dict_foreign_find_index(
|
||||
foreign->referenced_table,
|
||||
foreign->referenced_col_names,
|
||||
foreign->n_fields, index,
|
||||
/*check_charsets=*/TRUE, /*check_null=*/FALSE);
|
||||
ut_ad(new_index || !trx->check_foreigns);
|
||||
ut_ad(!new_index || new_index->table == index->table);
|
||||
|
||||
foreign->referenced_index = new_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
|
@ -165,7 +165,7 @@ dict_print(void)
|
||||
monitor printout */
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
|
||||
srv_fatal_semaphore_wait_threshold += SRV_SEMAPHORE_WAIT_EXTENSION;
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
mutex_enter(&(dict_sys->mutex));
|
||||
@ -193,7 +193,7 @@ loop:
|
||||
/* Restore the fatal semaphore wait timeout */
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
|
||||
srv_fatal_semaphore_wait_threshold -= SRV_SEMAPHORE_WAIT_EXTENSION;
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
return;
|
||||
|
@ -1876,7 +1876,7 @@ fil_inc_pending_ops(
|
||||
|
||||
if (space == NULL) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to do ibuf merge to a"
|
||||
"InnoDB: Error: trying to do an operation on a"
|
||||
" dropped tablespace %lu\n",
|
||||
(ulong) id);
|
||||
}
|
||||
@ -3375,6 +3375,7 @@ skip_info:
|
||||
for (offset = 0; offset < free_limit_bytes;
|
||||
offset += zip_size ? zip_size : UNIV_PAGE_SIZE) {
|
||||
ibool page_is_corrupt;
|
||||
ibool is_descr_page = FALSE;
|
||||
|
||||
success = os_file_read(file, page,
|
||||
(ulint)(offset & 0xFFFFFFFFUL),
|
||||
@ -3413,6 +3414,7 @@ skip_info:
|
||||
|
||||
/* store as descr page */
|
||||
memcpy(descr_page, page, (zip_size ? zip_size : UNIV_PAGE_SIZE));
|
||||
is_descr_page = TRUE;
|
||||
|
||||
} else if (descr_is_corrupt) {
|
||||
/* unknown state of the page */
|
||||
@ -3489,7 +3491,8 @@ skip_info:
|
||||
}
|
||||
}
|
||||
|
||||
if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
|
||||
if (fil_page_get_type(page) ==
|
||||
FIL_PAGE_INDEX && !is_descr_page) {
|
||||
dulint tmp = mach_read_from_8(page + (PAGE_HEADER + PAGE_INDEX_ID));
|
||||
|
||||
for (i = 0; i < n_index; i++) {
|
||||
|
@ -195,6 +195,9 @@ static my_bool innobase_rollback_on_timeout = FALSE;
|
||||
static my_bool innobase_create_status_file = FALSE;
|
||||
static my_bool innobase_stats_on_metadata = TRUE;
|
||||
static my_bool innobase_use_sys_stats_table = FALSE;
|
||||
#ifdef UNIV_DEBUG
|
||||
static ulong innobase_sys_stats_root_page = 0;
|
||||
#endif
|
||||
static my_bool innobase_buffer_pool_shm_checksum = TRUE;
|
||||
static uint innobase_buffer_pool_shm_key = 0;
|
||||
|
||||
@ -939,11 +942,23 @@ convert_error_code_to_mysql(
|
||||
case DB_TABLE_NOT_FOUND:
|
||||
return(HA_ERR_NO_SUCH_TABLE);
|
||||
|
||||
case DB_TOO_BIG_RECORD:
|
||||
my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
|
||||
page_get_free_space_of_empty(flags
|
||||
& DICT_TF_COMPACT) / 2);
|
||||
case DB_TOO_BIG_RECORD: {
|
||||
/* If prefix is true then a 768-byte prefix is stored
|
||||
locally for BLOB fields. Refer to dict_table_get_format() */
|
||||
bool prefix = ((flags & DICT_TF_FORMAT_MASK)
|
||||
>> DICT_TF_FORMAT_SHIFT) < UNIV_FORMAT_B;
|
||||
my_printf_error(ER_TOO_BIG_ROWSIZE,
|
||||
"Row size too large (> %lu). Changing some columns "
|
||||
"to TEXT or BLOB %smay help. In current row "
|
||||
"format, BLOB prefix of %d bytes is stored inline.",
|
||||
MYF(0),
|
||||
page_get_free_space_of_empty(flags &
|
||||
DICT_TF_COMPACT) / 2,
|
||||
prefix ? "or using ROW_FORMAT=DYNAMIC "
|
||||
"or ROW_FORMAT=COMPRESSED ": "",
|
||||
prefix ? DICT_MAX_INDEX_COL_LEN : 0);
|
||||
return(HA_ERR_TO_BIG_ROW);
|
||||
}
|
||||
|
||||
case DB_NO_SAVEPOINT:
|
||||
return(HA_ERR_NO_SAVEPOINT);
|
||||
@ -2369,6 +2384,10 @@ mem_free_and_error:
|
||||
|
||||
srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
srv_sys_stats_root_page = innobase_sys_stats_root_page;
|
||||
#endif
|
||||
|
||||
/* -------------- Log files ---------------------------*/
|
||||
|
||||
/* The default dir for log files is the datadir of MySQL */
|
||||
@ -4267,6 +4286,27 @@ table_opened:
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
UNIV_INTERN
|
||||
handler*
|
||||
ha_innobase::clone(
|
||||
/*===============*/
|
||||
const char* name, /*!< in: table name */
|
||||
MEM_ROOT* mem_root) /*!< in: memory context */
|
||||
{
|
||||
ha_innobase* new_handler;
|
||||
|
||||
DBUG_ENTER("ha_innobase::clone");
|
||||
|
||||
new_handler = static_cast<ha_innobase*>(handler::clone(name,
|
||||
mem_root));
|
||||
if (new_handler) {
|
||||
new_handler->prebuilt->select_lock_type
|
||||
= prebuilt->select_lock_type;
|
||||
}
|
||||
|
||||
DBUG_RETURN(new_handler);
|
||||
}
|
||||
|
||||
UNIV_INTERN
|
||||
uint
|
||||
ha_innobase::max_supported_key_part_length() const
|
||||
@ -8684,7 +8724,7 @@ ha_innobase::check(
|
||||
|
||||
/* Enlarge the fatal lock wait timeout during CHECK TABLE. */
|
||||
mutex_enter(&kernel_mutex);
|
||||
srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
|
||||
srv_fatal_semaphore_wait_threshold += SRV_SEMAPHORE_WAIT_EXTENSION;
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
for (index = dict_table_get_first_index(prebuilt->table);
|
||||
@ -8780,7 +8820,7 @@ ha_innobase::check(
|
||||
|
||||
/* Restore the fatal lock wait timeout after CHECK TABLE. */
|
||||
mutex_enter(&kernel_mutex);
|
||||
srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
|
||||
srv_fatal_semaphore_wait_threshold -= SRV_SEMAPHORE_WAIT_EXTENSION;
|
||||
mutex_exit(&kernel_mutex);
|
||||
|
||||
prebuilt->trx->op_info = "";
|
||||
@ -11751,6 +11791,13 @@ static MYSQL_SYSVAR_BOOL(use_sys_stats_table, innobase_use_sys_stats_table,
|
||||
"So you should use ANALYZE TABLE command intentionally.",
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
static MYSQL_SYSVAR_ULONG(persistent_stats_root_page,
|
||||
innobase_sys_stats_root_page, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Override the SYS_STATS root page id, 0 = no override (for testing only)",
|
||||
NULL, NULL, 0, 0, ULONG_MAX, 0);
|
||||
#endif
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
"Enable InnoDB adaptive hash index (enabled by default). "
|
||||
@ -11934,6 +11981,18 @@ static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method,
|
||||
"NULLS_UNEQUAL and NULLS_IGNORED",
|
||||
NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(track_changed_pages, srv_track_changed_pages,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Track the redo log for changed pages and output a changed page bitmap",
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
static MYSQL_SYSVAR_ULONGLONG(changed_pages_limit, srv_changed_pages_limit,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"The maximum number of rows for "
|
||||
"INFORMATION_SCHEMA.INNODB_CHANGED_PAGES table, "
|
||||
"0 - unlimited",
|
||||
NULL, NULL, 1000000, 0, ~0ULL, 0);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
@ -12070,7 +12129,7 @@ static MYSQL_SYSVAR_UINT(auto_lru_dump, srv_auto_lru_dump,
|
||||
NULL, NULL, 0, 0, UINT_MAX32, 0);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(blocking_lru_restore, innobase_blocking_lru_restore,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Block XtraDB startup process until buffer pool is full restored from a "
|
||||
"dump file (if present). Disabled by default.",
|
||||
NULL, NULL, FALSE);
|
||||
@ -12149,6 +12208,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(stats_auto_update),
|
||||
MYSQL_SYSVAR(stats_update_need_lock),
|
||||
MYSQL_SYSVAR(use_sys_stats_table),
|
||||
#ifdef UNIV_DEBUG
|
||||
MYSQL_SYSVAR(persistent_stats_root_page),
|
||||
#endif
|
||||
MYSQL_SYSVAR(stats_sample_pages),
|
||||
MYSQL_SYSVAR(adaptive_hash_index),
|
||||
MYSQL_SYSVAR(stats_method),
|
||||
@ -12180,6 +12242,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
||||
MYSQL_SYSVAR(dict_size_limit),
|
||||
MYSQL_SYSVAR(use_sys_malloc),
|
||||
MYSQL_SYSVAR(change_buffering),
|
||||
MYSQL_SYSVAR(track_changed_pages),
|
||||
MYSQL_SYSVAR(changed_pages_limit),
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
MYSQL_SYSVAR(change_buffering_debug),
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
@ -12230,7 +12294,10 @@ i_s_innodb_admin_command,
|
||||
i_s_innodb_sys_tables,
|
||||
i_s_innodb_sys_indexes,
|
||||
i_s_innodb_sys_stats,
|
||||
i_s_innodb_patches
|
||||
i_s_innodb_changed_pages,
|
||||
i_s_innodb_buffer_page,
|
||||
i_s_innodb_buffer_page_lru,
|
||||
i_s_innodb_buffer_stats
|
||||
mysql_declare_plugin_end;
|
||||
|
||||
/** @brief Initialize the default value of innodb_commit_concurrency.
|
||||
|
@ -133,6 +133,7 @@ class ha_innobase: public handler
|
||||
const key_map* keys_to_use_for_scanning();
|
||||
|
||||
int open(const char *name, int mode, uint test_if_locked);
|
||||
handler* clone(const char *name, MEM_ROOT *mem_root);
|
||||
int close(void);
|
||||
double scan_time();
|
||||
double read_time(uint index, uint ranges, ha_rows rows);
|
||||
|
@ -668,6 +668,10 @@ ha_innobase::add_index(
|
||||
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
|
||||
}
|
||||
|
||||
if (innodb_table->tablespace_discarded) {
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
/* Check that index keys are sensible */
|
||||
error = innobase_check_index_keys(key_info, num_of_keys, innodb_table);
|
||||
|
||||
@ -823,6 +827,8 @@ ha_innobase::add_index(
|
||||
innodb_table, indexed_table,
|
||||
index, num_of_idx, table);
|
||||
|
||||
DBUG_EXECUTE_IF("crash_innodb_add_index_after", DBUG_SUICIDE(););
|
||||
|
||||
error_handling:
|
||||
/* After an error, remove all those index definitions from the
|
||||
dictionary which were defined. */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,7 +36,6 @@ extern struct st_mysql_plugin i_s_innodb_cmp;
|
||||
extern struct st_mysql_plugin i_s_innodb_cmp_reset;
|
||||
extern struct st_mysql_plugin i_s_innodb_cmpmem;
|
||||
extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
|
||||
extern struct st_mysql_plugin i_s_innodb_patches;
|
||||
extern struct st_mysql_plugin i_s_innodb_rseg;
|
||||
extern struct st_mysql_plugin i_s_innodb_table_stats;
|
||||
extern struct st_mysql_plugin i_s_innodb_index_stats;
|
||||
@ -44,5 +43,9 @@ extern struct st_mysql_plugin i_s_innodb_admin_command;
|
||||
extern struct st_mysql_plugin i_s_innodb_sys_tables;
|
||||
extern struct st_mysql_plugin i_s_innodb_sys_indexes;
|
||||
extern struct st_mysql_plugin i_s_innodb_sys_stats;
|
||||
extern struct st_mysql_plugin i_s_innodb_changed_pages;
|
||||
extern struct st_mysql_plugin i_s_innodb_buffer_page;
|
||||
extern struct st_mysql_plugin i_s_innodb_buffer_page_lru;
|
||||
extern struct st_mysql_plugin i_s_innodb_buffer_stats;
|
||||
|
||||
#endif /* i_s_h */
|
||||
|
@ -1,51 +0,0 @@
|
||||
/* Copyright (C) 2002-2006 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#ifdef USE_PRAGMA_INTERFACE
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
struct innodb_enhancement {
|
||||
const char *file;
|
||||
const char *name;
|
||||
const char *comment;
|
||||
const char *link;
|
||||
}innodb_enhancements[] = {
|
||||
{"xtradb_show_enhancements","I_S.XTRADB_ENHANCEMENTS","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_show_status","Improvements to SHOW INNODB STATUS","Memory information and lock info fixes","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"},
|
||||
{"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""},
|
||||
{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_stats","Additional features about InnoDB statistics/optimizer","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_recovery_patches","Bugfixes and adjustments about recovery process","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_purge_thread","Enable to use purge devoted thread","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_admin_command_base","XtraDB specific command interface through i_s","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_show_lock_name","Show mutex/lock name instead of crated file/line","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_separate_doublewrite","Add option 'innodb_doublewrite_file' to separate doublewrite dedicated tablespace","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{"innodb_sys_tables_sys_indexes","Expose InnoDB SYS_TABLES and SYS_INDEXES schema tables","","http://www.percona.com/docs/wiki/percona-xtradb"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
@ -2759,11 +2759,19 @@ ibuf_insert_low(
|
||||
|
||||
root = ibuf_tree_root_get(&mtr);
|
||||
|
||||
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
|
||||
| BTR_NO_UNDO_LOG_FLAG,
|
||||
cursor,
|
||||
ibuf_entry, &ins_rec,
|
||||
&dummy_big_rec, 0, thr, &mtr);
|
||||
err = btr_cur_optimistic_insert(
|
||||
BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG,
|
||||
cursor, ibuf_entry, &ins_rec,
|
||||
&dummy_big_rec, 0, thr, &mtr);
|
||||
|
||||
if (err == DB_FAIL) {
|
||||
err = btr_cur_pessimistic_insert(
|
||||
BTR_NO_LOCKING_FLAG
|
||||
| BTR_NO_UNDO_LOG_FLAG,
|
||||
cursor, ibuf_entry, &ins_rec,
|
||||
&dummy_big_rec, 0, thr, &mtr);
|
||||
}
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
/* Update the page max trx id field */
|
||||
page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
|
||||
|
@ -103,6 +103,81 @@ enum buf_page_state {
|
||||
before putting to the free list */
|
||||
};
|
||||
|
||||
/** This structure defines information we will fetch from each buffer pool. It
|
||||
will be used to print table IO stats */
|
||||
struct buf_pool_info_struct{
|
||||
/* General buffer pool info */
|
||||
ulint pool_size; /*!< Buffer Pool size in pages */
|
||||
ulint lru_len; /*!< Length of buf_pool->LRU */
|
||||
ulint old_lru_len; /*!< buf_pool->LRU_old_len */
|
||||
ulint free_list_len; /*!< Length of buf_pool->free list */
|
||||
ulint flush_list_len; /*!< Length of buf_pool->flush_list */
|
||||
ulint n_pend_unzip; /*!< buf_pool->n_pend_unzip, pages
|
||||
pending decompress */
|
||||
ulint n_pend_reads; /*!< buf_pool->n_pend_reads, pages
|
||||
pending read */
|
||||
ulint n_pending_flush_lru; /*!< Pages pending flush in LRU */
|
||||
ulint n_pending_flush_single_page;/*!< Pages pending to be
|
||||
flushed as part of single page
|
||||
flushes issued by various user
|
||||
threads */
|
||||
ulint n_pending_flush_list; /*!< Pages pending flush in FLUSH
|
||||
LIST */
|
||||
ulint n_pages_made_young; /*!< number of pages made young */
|
||||
ulint n_pages_not_made_young; /*!< number of pages not made young */
|
||||
ulint n_pages_read; /*!< buf_pool->n_pages_read */
|
||||
ulint n_pages_created; /*!< buf_pool->n_pages_created */
|
||||
ulint n_pages_written; /*!< buf_pool->n_pages_written */
|
||||
ulint n_page_gets; /*!< buf_pool->n_page_gets */
|
||||
ulint n_ra_pages_read_rnd; /*!< buf_pool->n_ra_pages_read_rnd,
|
||||
number of pages readahead */
|
||||
ulint n_ra_pages_read; /*!< buf_pool->n_ra_pages_read, number
|
||||
of pages readahead */
|
||||
ulint n_ra_pages_evicted; /*!< buf_pool->n_ra_pages_evicted,
|
||||
number of readahead pages evicted
|
||||
without access */
|
||||
ulint n_page_get_delta; /*!< num of buffer pool page gets since
|
||||
last printout */
|
||||
|
||||
/* Buffer pool access stats */
|
||||
double page_made_young_rate; /*!< page made young rate in pages
|
||||
per second */
|
||||
double page_not_made_young_rate;/*!< page not made young rate
|
||||
in pages per second */
|
||||
double pages_read_rate; /*!< num of pages read per second */
|
||||
double pages_created_rate; /*!< num of pages create per second */
|
||||
double pages_written_rate; /*!< num of pages written per second */
|
||||
ulint page_read_delta; /*!< num of pages read since last
|
||||
printout */
|
||||
ulint young_making_delta; /*!< num of pages made young since
|
||||
last printout */
|
||||
ulint not_young_making_delta; /*!< num of pages not make young since
|
||||
last printout */
|
||||
|
||||
/* Statistics about read ahead algorithm. */
|
||||
double pages_readahead_rnd_rate;/*!< random readahead rate in pages per
|
||||
second */
|
||||
double pages_readahead_rate; /*!< readahead rate in pages per
|
||||
second */
|
||||
double pages_evicted_rate; /*!< rate of readahead page evicted
|
||||
without access, in pages per second */
|
||||
|
||||
/* Stats about LRU eviction */
|
||||
ulint unzip_lru_len; /*!< length of buf_pool->unzip_LRU
|
||||
list */
|
||||
/* Counters for LRU policy */
|
||||
ulint io_sum; /*!< buf_LRU_stat_sum.io */
|
||||
ulint io_cur; /*!< buf_LRU_stat_cur.io, num of IO
|
||||
for current interval */
|
||||
ulint unzip_sum; /*!< buf_LRU_stat_sum.unzip */
|
||||
ulint unzip_cur; /*!< buf_LRU_stat_cur.unzip, num
|
||||
pages decompressed in current
|
||||
interval */
|
||||
};
|
||||
|
||||
typedef struct buf_pool_info_struct buf_pool_info_t;
|
||||
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/********************************************************************//**
|
||||
Creates the buffer pool.
|
||||
@ -623,6 +698,16 @@ void
|
||||
buf_print_io(
|
||||
/*=========*/
|
||||
FILE* file); /*!< in: file where to print */
|
||||
/*******************************************************************//**
|
||||
Collect buffer pool stats information for a buffer pool. Also
|
||||
record aggregated stats if there are more than one buffer pool
|
||||
in the server */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_stats_get_pool_info(
|
||||
/*====================*/
|
||||
buf_pool_info_t* pool_info); /*!< in/out: buffer pool info
|
||||
to fill */
|
||||
/*********************************************************************//**
|
||||
Returns the ratio in percents of modified pages in the buffer pool /
|
||||
database pages in the buffer pool.
|
||||
@ -1051,12 +1136,27 @@ UNIV_INTERN
|
||||
ulint
|
||||
buf_get_free_list_len(void);
|
||||
/*=======================*/
|
||||
|
||||
/*********************************************************************//**
|
||||
Get the nth chunk's buffer block in the specified buffer pool.
|
||||
@return the nth chunk's buffer block. */
|
||||
UNIV_INLINE
|
||||
buf_block_t*
|
||||
buf_get_nth_chunk_block(
|
||||
/*====================*/
|
||||
const buf_pool_t* buf_pool, /*!< in: buffer pool instance */
|
||||
ulint n, /*!< in: nth chunk in the buffer pool */
|
||||
ulint* chunk_size); /*!< in: chunk size */
|
||||
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
|
||||
/** The common buffer control block structure
|
||||
for compressed and uncompressed frames */
|
||||
|
||||
/** Number of bits used for buffer page states. */
|
||||
#define BUF_PAGE_STATE_BITS 3
|
||||
|
||||
struct buf_page_struct{
|
||||
/** @name General fields
|
||||
None of these bit-fields must be modified without holding
|
||||
@ -1071,7 +1171,8 @@ struct buf_page_struct{
|
||||
unsigned offset:32; /*!< page number; also protected
|
||||
by buf_pool_mutex. */
|
||||
|
||||
unsigned state:3; /*!< state of the control block; also
|
||||
unsigned state:BUF_PAGE_STATE_BITS;
|
||||
/*!< state of the control block; also
|
||||
protected by buf_pool_mutex.
|
||||
State transitions from
|
||||
BUF_BLOCK_READY_FOR_USE to
|
||||
|
@ -36,6 +36,7 @@ Created 11/5/1995 Heikki Tuuri
|
||||
#include "buf0lru.h"
|
||||
#include "buf0rea.h"
|
||||
#include "srv0srv.h"
|
||||
|
||||
/********************************************************************//**
|
||||
Reads the freed_page_clock of a buffer block.
|
||||
@return freed_page_clock */
|
||||
@ -1154,4 +1155,23 @@ buf_block_dbg_add_level(
|
||||
sync_thread_add_level(&block->lock, level, FALSE);
|
||||
}
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
/*********************************************************************//**
|
||||
Get the nth chunk's buffer block in the specified buffer pool.
|
||||
@return the nth chunk's buffer block. */
|
||||
UNIV_INLINE
|
||||
buf_block_t*
|
||||
buf_get_nth_chunk_block(
|
||||
/*====================*/
|
||||
const buf_pool_t* buf_pool, /*!< in: buffer pool instance */
|
||||
ulint n, /*!< in: nth chunk in the buffer pool */
|
||||
ulint* chunk_size) /*!< in: chunk size */
|
||||
{
|
||||
const buf_chunk_t* chunk;
|
||||
|
||||
chunk = buf_pool->chunks + n;
|
||||
*chunk_size = chunk->size;
|
||||
return(chunk->blocks);
|
||||
}
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
|
@ -93,13 +93,12 @@ buf_LRU_insert_zip_clean(
|
||||
Try to free a block. If bpage is a descriptor of a compressed-only
|
||||
page, the descriptor object will be freed as well.
|
||||
|
||||
NOTE: If this function returns TRUE, it will temporarily
|
||||
release buf_pool_mutex. Furthermore, the page frame will no longer be
|
||||
accessible via bpage.
|
||||
NOTE: This will temporarily release buf_pool_mutex. Furthermore, the
|
||||
page frame will no longer be accessible via bpage.
|
||||
|
||||
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
|
||||
release these two mutexes after the call. No other
|
||||
buf_page_get_mutex() may be held when calling this function.
|
||||
The caller must hold buf_page_get_mutex(bpage) and release this mutex
|
||||
after the call. No other buf_page_get_mutex() may be held when
|
||||
calling this function.
|
||||
@return TRUE if freed, FALSE otherwise. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
|
@ -91,6 +91,26 @@ void
|
||||
dict_create(void);
|
||||
/*=============*/
|
||||
|
||||
/*****************************************************************//**
|
||||
Verifies the SYS_STATS table by scanning its clustered index. This
|
||||
function may only be called at InnoDB startup time.
|
||||
|
||||
@return TRUE if SYS_STATS was verified successfully */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
dict_verify_xtradb_sys_stats(void);
|
||||
/*==============================*/
|
||||
|
||||
/*****************************************************************//**
|
||||
Discard the existing dictionary cache SYS_STATS information, create and
|
||||
add it there anew. Does not touch the old SYS_STATS tablespace page
|
||||
under the assumption that they are corrupted or overwritten for other
|
||||
purposes. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
dict_recreate_xtradb_sys_stats(void);
|
||||
/*================================*/
|
||||
|
||||
|
||||
/* Space id and page no where the dictionary header resides */
|
||||
#define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */
|
||||
|
@ -142,6 +142,8 @@ extern fil_addr_t fil_addr_null;
|
||||
#define FIL_PAGE_TYPE_BLOB 10 /*!< Uncompressed BLOB page */
|
||||
#define FIL_PAGE_TYPE_ZBLOB 11 /*!< First compressed BLOB page */
|
||||
#define FIL_PAGE_TYPE_ZBLOB2 12 /*!< Subsequent compressed BLOB page */
|
||||
#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_ZBLOB2
|
||||
/*!< Last page type */
|
||||
/* @} */
|
||||
|
||||
/** Space types @{ */
|
||||
|
@ -41,6 +41,9 @@ Created 12/9/1995 Heikki Tuuri
|
||||
#include "sync0rw.h"
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/* Type used for all log sequence number storage and arithmetics */
|
||||
typedef ib_uint64_t lsn_t;
|
||||
|
||||
/** Redo log buffer */
|
||||
typedef struct log_struct log_t;
|
||||
/** Redo log group */
|
||||
@ -953,6 +956,11 @@ struct log_struct{
|
||||
become signaled */
|
||||
/* @} */
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
ib_uint64_t tracked_lsn; /*!< log tracking has advanced to this
|
||||
lsn. Field accessed atomically where
|
||||
64-bit atomic ops are supported,
|
||||
protected by the log sys mutex
|
||||
otherwise. */
|
||||
};
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
|
111
storage/xtradb/include/log0online.h
Normal file
111
storage/xtradb/include/log0online.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2011-2012, Percona Inc. All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
/**************************************************//**
|
||||
@file include/log0online.h
|
||||
Online database log parsing for changed page tracking
|
||||
*******************************************************/
|
||||
|
||||
#ifndef log0online_h
|
||||
#define log0online_h
|
||||
|
||||
#include "univ.i"
|
||||
#include "os0file.h"
|
||||
|
||||
/*********************************************************************//**
|
||||
Initializes the online log following subsytem. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_online_read_init();
|
||||
/*===================*/
|
||||
|
||||
/*********************************************************************//**
|
||||
Shuts down the online log following subsystem. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_online_read_shutdown();
|
||||
/*=======================*/
|
||||
|
||||
/*********************************************************************//**
|
||||
Reads and parses the redo log up to last checkpoint LSN to build the changed
|
||||
page bitmap which is then written to disk. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_online_follow_redo_log();
|
||||
/*=========================*/
|
||||
|
||||
/** The iterator through all bits of changed pages bitmap blocks */
|
||||
struct log_bitmap_iterator_struct
|
||||
{
|
||||
char in_name[FN_REFLEN]; /*!< the file name for bitmap
|
||||
input */
|
||||
os_file_t in; /*!< the bitmap input file */
|
||||
ib_uint64_t in_offset; /*!< the next write position in the
|
||||
bitmap output file */
|
||||
ib_uint32_t bit_offset; /*!< bit offset inside of bitmap
|
||||
block*/
|
||||
ib_uint64_t start_lsn; /*!< Start lsn of the block */
|
||||
ib_uint64_t end_lsn; /*!< End lsn of the block */
|
||||
ib_uint32_t space_id; /*!< Block space id */
|
||||
ib_uint32_t first_page_id; /*!< First block page id */
|
||||
ibool changed; /*!< true if current page was changed */
|
||||
byte* page; /*!< Bitmap block */
|
||||
};
|
||||
|
||||
typedef struct log_bitmap_iterator_struct log_bitmap_iterator_t;
|
||||
|
||||
#define LOG_BITMAP_ITERATOR_START_LSN(i) \
|
||||
((i).start_lsn)
|
||||
#define LOG_BITMAP_ITERATOR_END_LSN(i) \
|
||||
((i).end_lsn)
|
||||
#define LOG_BITMAP_ITERATOR_SPACE_ID(i) \
|
||||
((i).space_id)
|
||||
#define LOG_BITMAP_ITERATOR_PAGE_NUM(i) \
|
||||
((i).first_page_id + (i).bit_offset)
|
||||
#define LOG_BITMAP_ITERATOR_PAGE_CHANGED(i) \
|
||||
((i).changed)
|
||||
|
||||
/*********************************************************************//**
|
||||
Initializes log bitmap iterator.
|
||||
@return TRUE if the iterator is initialized OK, FALSE otherwise. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
log_online_bitmap_iterator_init(
|
||||
/*============================*/
|
||||
log_bitmap_iterator_t *i); /*!<in/out: iterator */
|
||||
|
||||
/*********************************************************************//**
|
||||
Releases log bitmap iterator. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
log_online_bitmap_iterator_release(
|
||||
/*===============================*/
|
||||
log_bitmap_iterator_t *i); /*!<in/out: iterator */
|
||||
|
||||
/*********************************************************************//**
|
||||
Iterates through bits of saved bitmap blocks.
|
||||
Sequentially reads blocks from bitmap file(s) and interates through
|
||||
their bits. Ignores blocks with wrong checksum.
|
||||
@return TRUE if iteration is successful, FALSE if all bits are iterated. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
log_online_bitmap_iterator_next(
|
||||
/*============================*/
|
||||
log_bitmap_iterator_t *i); /*!<in/out: iterator */
|
||||
|
||||
#endif
|
@ -32,6 +32,28 @@ Created 9/20/1997 Heikki Tuuri
|
||||
#include "hash0hash.h"
|
||||
#include "log0log.h"
|
||||
|
||||
/******************************************************//**
|
||||
Checks the 4-byte checksum to the trailer checksum field of a log
|
||||
block. We also accept a log block in the old format before
|
||||
InnoDB-3.23.52 where the checksum field contains the log block number.
|
||||
@return TRUE if ok, or if the log block may be in the format of InnoDB
|
||||
version predating 3.23.52 */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
log_block_checksum_is_ok_or_old_format(
|
||||
/*===================================*/
|
||||
const byte* block); /*!< in: pointer to a log block */
|
||||
|
||||
/*******************************************************//**
|
||||
Calculates the new value for lsn when more data is added to the log. */
|
||||
UNIV_INTERN
|
||||
ib_uint64_t
|
||||
recv_calc_lsn_on_data_add(
|
||||
/*======================*/
|
||||
ib_uint64_t lsn, /*!< in: old lsn */
|
||||
ib_uint64_t len); /*!< in: this many bytes of data is
|
||||
added, log block headers not included */
|
||||
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
extern ibool recv_replay_file_ops;
|
||||
|
||||
@ -182,6 +204,21 @@ UNIV_INTERN
|
||||
void
|
||||
recv_recovery_rollback_active(void);
|
||||
/*===============================*/
|
||||
|
||||
/*******************************************************************//**
|
||||
Tries to parse a single log record and returns its length.
|
||||
@return length of the record, or 0 if the record was not complete */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
recv_parse_log_rec(
|
||||
/*===============*/
|
||||
byte* ptr, /*!< in: pointer to a buffer */
|
||||
byte* end_ptr,/*!< in: pointer to the buffer end */
|
||||
byte* type, /*!< out: type */
|
||||
ulint* space, /*!< out: space id */
|
||||
ulint* page_no,/*!< out: page number */
|
||||
byte** body); /*!< out: log record body start */
|
||||
|
||||
/*******************************************************//**
|
||||
Scans log from a buffer and stores new log data to the parsing buffer.
|
||||
Parses and hashes the log records if new data found. Unless
|
||||
|
@ -463,6 +463,14 @@ os_file_set_eof(
|
||||
/*============*/
|
||||
FILE* file); /*!< in: file to be truncated */
|
||||
/***********************************************************************//**
|
||||
Truncates a file at the specified position.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_file_set_eof_at(
|
||||
os_file_t file, /*!< in: handle to a file */
|
||||
ib_uint64_t new_len);/*!< in: new file length */
|
||||
/***********************************************************************//**
|
||||
Flushes the write buffers of a given file to the disk.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
|
@ -287,7 +287,11 @@ Atomic compare-and-swap and increment for InnoDB. */
|
||||
|
||||
#if defined(HAVE_IB_GCC_ATOMIC_BUILTINS)
|
||||
|
||||
#define HAVE_ATOMIC_BUILTINS
|
||||
# define HAVE_ATOMIC_BUILTINS
|
||||
|
||||
# ifdef HAVE_IB_GCC_ATOMIC_BUILTINS_64
|
||||
# define HAVE_ATOMIC_BUILTINS_64
|
||||
# endif
|
||||
|
||||
/**********************************************************//**
|
||||
Returns true if swapped, ptr is pointer to target, old_val is value to
|
||||
@ -326,6 +330,9 @@ amount of increment. */
|
||||
# define os_atomic_increment_ulint(ptr, amount) \
|
||||
os_atomic_increment(ptr, amount)
|
||||
|
||||
# define os_atomic_increment_uint64(ptr, amount) \
|
||||
os_atomic_increment(ptr, amount)
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||
|
||||
@ -334,12 +341,13 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||
|
||||
#elif defined(HAVE_IB_SOLARIS_ATOMICS)
|
||||
|
||||
#define HAVE_ATOMIC_BUILTINS
|
||||
# define HAVE_ATOMIC_BUILTINS
|
||||
# define HAVE_ATOMIC_BUILTINS_64
|
||||
|
||||
/* If not compiling with GCC or GCC doesn't support the atomic
|
||||
intrinsics and running on Solaris >= 10 use Solaris atomics */
|
||||
|
||||
#include <atomic.h>
|
||||
# include <atomic.h>
|
||||
|
||||
/**********************************************************//**
|
||||
Returns true if swapped, ptr is pointer to target, old_val is value to
|
||||
@ -379,6 +387,9 @@ amount of increment. */
|
||||
# define os_atomic_increment_ulint(ptr, amount) \
|
||||
atomic_add_long_nv(ptr, amount)
|
||||
|
||||
# define os_atomic_increment_uint64(ptr, amount) \
|
||||
atomic_add_64_nv(ptr, amount)
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||
|
||||
@ -387,7 +398,11 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
|
||||
|
||||
#elif defined(HAVE_WINDOWS_ATOMICS)
|
||||
|
||||
#define HAVE_ATOMIC_BUILTINS
|
||||
# define HAVE_ATOMIC_BUILTINS
|
||||
|
||||
# ifndef _WIN32
|
||||
# define HAVE_ATOMIC_BUILTINS_64
|
||||
# endif
|
||||
|
||||
/* On Windows, use Windows atomics / interlocked */
|
||||
# ifdef _WIN64
|
||||
@ -425,6 +440,11 @@ amount of increment. */
|
||||
# define os_atomic_increment_ulint(ptr, amount) \
|
||||
((ulint) (win_xchg_and_add(ptr, amount) + amount))
|
||||
|
||||
# define os_atomic_increment_uint64(ptr, amount) \
|
||||
((ib_uint64_t) (InterlockedExchangeAdd64( \
|
||||
(ib_int64_t*) ptr, \
|
||||
(ib_int64_t) amount) + amount))
|
||||
|
||||
/**********************************************************//**
|
||||
Returns the old value of *ptr, atomically sets *ptr to new_val.
|
||||
InterlockedExchange() operates on LONG, and the LONG will be
|
||||
|
@ -60,6 +60,14 @@ extern os_event_t srv_lock_timeout_thread_event;
|
||||
/* This event is set at shutdown to wakeup threads from sleep */
|
||||
extern os_event_t srv_shutdown_event;
|
||||
|
||||
/* This event is set on checkpoint completion to wake the redo log parser
|
||||
thread */
|
||||
extern os_event_t srv_checkpoint_completed_event;
|
||||
|
||||
/* This event is set on the online redo log following thread exit to signal
|
||||
that the (slow) shutdown may proceed */
|
||||
extern os_event_t srv_redo_log_thread_finished_event;
|
||||
|
||||
/* If the last data file is auto-extended, we add this many pages to it
|
||||
at a time */
|
||||
#define SRV_AUTO_EXTEND_INCREMENT \
|
||||
@ -126,6 +134,11 @@ extern ibool srv_recovery_stats;
|
||||
|
||||
extern ulint srv_use_purge_thread;
|
||||
|
||||
extern my_bool srv_track_changed_pages;
|
||||
|
||||
extern
|
||||
ulonglong srv_changed_pages_limit;
|
||||
|
||||
extern ibool srv_auto_extend_last_data_file;
|
||||
extern ulint srv_last_file_size_max;
|
||||
extern char** srv_log_group_home_dirs;
|
||||
@ -213,6 +226,9 @@ extern unsigned long long srv_stats_sample_pages;
|
||||
extern ulong srv_stats_auto_update;
|
||||
extern ulint srv_stats_update_need_lock;
|
||||
extern ibool srv_use_sys_stats_table;
|
||||
#ifdef UNIV_DEBUG
|
||||
extern ulong srv_sys_stats_root_page;
|
||||
#endif
|
||||
|
||||
extern ibool srv_use_doublewrite_buf;
|
||||
extern ibool srv_use_checksums;
|
||||
@ -284,6 +300,7 @@ extern ibool srv_print_latch_waits;
|
||||
|
||||
extern ulint srv_activity_count;
|
||||
extern ulint srv_fatal_semaphore_wait_threshold;
|
||||
#define SRV_SEMAPHORE_WAIT_EXTENSION 7200
|
||||
extern ulint srv_dml_needed_delay;
|
||||
extern long long srv_kill_idle_transaction;
|
||||
|
||||
@ -644,6 +661,15 @@ srv_LRU_dump_restore_thread(
|
||||
void* arg); /*!< in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
/******************************************************************//**
|
||||
A thread which follows the redo log and outputs the changed page bitmap.
|
||||
@return a dummy value */
|
||||
UNIV_INTERN
|
||||
os_thread_ret_t
|
||||
srv_redo_log_follow_thread(
|
||||
/*=======================*/
|
||||
void* arg); /*!< in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
/******************************************************************//**
|
||||
Outputs to a file the output of the InnoDB Monitor.
|
||||
@return FALSE if not all information printed
|
||||
due to failure to obtain necessary mutex */
|
||||
|
@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri
|
||||
#define INNODB_VERSION_MAJOR 1
|
||||
#define INNODB_VERSION_MINOR 0
|
||||
#define INNODB_VERSION_BUGFIX 17
|
||||
#define PERCONA_INNODB_VERSION 13.0
|
||||
#define PERCONA_INNODB_VERSION 14.1
|
||||
|
||||
/* The following is the InnoDB version as shown in
|
||||
SELECT plugin_version FROM information_schema.plugins;
|
||||
@ -270,6 +270,24 @@ management to ensure correct alignment for doubles etc. */
|
||||
========================
|
||||
*/
|
||||
|
||||
/** There are currently two InnoDB file formats which are used to group
|
||||
features with similar restrictions and dependencies. Using an enum allows
|
||||
switch statements to give a compiler warning when a new one is introduced. */
|
||||
enum innodb_file_formats_enum {
|
||||
/** Antelope File Format: InnoDB/MySQL up to 5.1.
|
||||
This format includes REDUNDANT and COMPACT row formats */
|
||||
UNIV_FORMAT_A = 0,
|
||||
|
||||
/** Barracuda File Format: Introduced in InnoDB plugin for 5.1:
|
||||
This format includes COMPRESSED and DYNAMIC row formats. It
|
||||
includes the ability to create secondary indexes from data that
|
||||
is not on the clustered index page and the ability to store more
|
||||
data off the clustered index page. */
|
||||
UNIV_FORMAT_B = 1
|
||||
};
|
||||
|
||||
typedef enum innodb_file_formats_enum innodb_file_formats_t;
|
||||
|
||||
/* The 2-logarithm of UNIV_PAGE_SIZE: */
|
||||
/* #define UNIV_PAGE_SIZE_SHIFT 14 */
|
||||
#define UNIV_PAGE_SIZE_SHIFT_MAX 14
|
||||
|
@ -110,6 +110,10 @@ struct ib_rbt_bound_struct {
|
||||
/* Compare a key with the node value (t is tree, k is key, n is node)*/
|
||||
#define rbt_compare(t, k, n) (t->compare(k, n->value))
|
||||
|
||||
/* Node size. FIXME: name might clash, but currently it does not, so for easier
|
||||
maintenance do not rename it for now. */
|
||||
#define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1)
|
||||
|
||||
/****************************************************************//**
|
||||
Free an instance of a red black tree */
|
||||
UNIV_INTERN
|
||||
@ -181,6 +185,18 @@ rbt_add_node(
|
||||
const void* value); /*!< in: this value is copied
|
||||
to the node */
|
||||
/****************************************************************//**
|
||||
Add a new caller-provided node to tree at the specified position.
|
||||
The node must have its key fields initialized correctly.
|
||||
@return added node */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_add_preallocated_node(
|
||||
/*======================*/
|
||||
ib_rbt_t* tree, /*!< in: rb tree */
|
||||
ib_rbt_bound_t* parent, /*!< in: parent */
|
||||
ib_rbt_node_t* node); /*!< in: node */
|
||||
|
||||
/****************************************************************//**
|
||||
Return the left most data node in the tree
|
||||
@return left most node */
|
||||
UNIV_INTERN
|
||||
@ -267,6 +283,13 @@ rbt_clear(
|
||||
/*======*/
|
||||
ib_rbt_t* tree); /*!< in: rb tree */
|
||||
/****************************************************************//**
|
||||
Clear the tree without deleting and freeing its nodes. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
rbt_reset(
|
||||
/*======*/
|
||||
ib_rbt_t* tree); /*!< in: rb tree */
|
||||
/****************************************************************//**
|
||||
Merge the node from dst into src. Return the number of nodes merged.
|
||||
@return no. of recs merged */
|
||||
UNIV_INTERN
|
||||
|
@ -201,6 +201,54 @@ log_buf_pool_get_oldest_modification(void)
|
||||
return(lsn);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Safely reads the log_sys->tracked_lsn value. Uses atomic operations
|
||||
if available, otherwise this field is protected with the log system
|
||||
mutex. The writer counterpart function is log_set_tracked_lsn() in
|
||||
log0online.c.
|
||||
|
||||
@return log_sys->tracked_lsn value. */
|
||||
UNIV_INLINE
|
||||
ib_uint64_t
|
||||
log_get_tracked_lsn()
|
||||
{
|
||||
#ifdef HAVE_ATOMIC_BUILTINS_64
|
||||
return os_atomic_increment_uint64(&log_sys->tracked_lsn, 0);
|
||||
#else
|
||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
||||
return log_sys->tracked_lsn;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Checks if the log groups have a big enough margin of free space in
|
||||
so that a new log entry can be written without overwriting log data
|
||||
that is not read by the changed page bitmap thread.
|
||||
@return TRUE if there is not enough free space. */
|
||||
static
|
||||
ibool
|
||||
log_check_tracking_margin(
|
||||
ulint lsn_advance) /*!< in: an upper limit on how much log data we
|
||||
plan to write. If zero, the margin will be
|
||||
checked for the already-written log. */
|
||||
{
|
||||
ib_uint64_t tracked_lsn;
|
||||
ulint tracked_lsn_age;
|
||||
|
||||
if (!srv_track_changed_pages) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
||||
|
||||
tracked_lsn = log_get_tracked_lsn();
|
||||
tracked_lsn_age = log_sys->lsn - tracked_lsn;
|
||||
|
||||
/* The overwrite would happen when log_sys->log_group_capacity is
|
||||
exceeded, but we use max_checkpoint_age for an extra safety margin. */
|
||||
return tracked_lsn_age + lsn_advance > log_sys->max_checkpoint_age;
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Opens the log for log_write_low. The log must be closed with log_close and
|
||||
released with log_release.
|
||||
@ -217,9 +265,7 @@ log_reserve_and_open(
|
||||
ulint archived_lsn_age;
|
||||
ulint dummy;
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint count = 0;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
ut_a(len < log->buf_size / 2);
|
||||
loop:
|
||||
@ -247,6 +293,19 @@ loop:
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if (log_check_tracking_margin(len_upper_limit) && (++count < 50)) {
|
||||
|
||||
/* This log write would violate the untracked LSN free space
|
||||
margin. Limit this to 50 retries as there might be situations
|
||||
where we have no choice but to proceed anyway, i.e. if the log
|
||||
is about to be overflown, log tracking or not. */
|
||||
mutex_exit(&(log->mutex));
|
||||
|
||||
os_thread_sleep(10000);
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
if (log->archiving_state != LOG_ARCH_OFF) {
|
||||
|
||||
@ -385,6 +444,8 @@ log_close(void)
|
||||
ulint first_rec_group;
|
||||
ib_uint64_t oldest_lsn;
|
||||
ib_uint64_t lsn;
|
||||
ib_uint64_t tracked_lsn;
|
||||
ulint tracked_lsn_age;
|
||||
log_t* log = log_sys;
|
||||
ib_uint64_t checkpoint_age;
|
||||
|
||||
@ -411,6 +472,19 @@ log_close(void)
|
||||
log->check_flush_or_checkpoint = TRUE;
|
||||
}
|
||||
|
||||
if (srv_track_changed_pages) {
|
||||
|
||||
tracked_lsn = log_get_tracked_lsn();
|
||||
tracked_lsn_age = lsn - tracked_lsn;
|
||||
|
||||
if (tracked_lsn_age >= log->log_group_capacity) {
|
||||
|
||||
fprintf(stderr, " InnoDB: Error: the age of the "
|
||||
"oldest untracked record exceeds the log "
|
||||
"group capacity!\n");
|
||||
}
|
||||
}
|
||||
|
||||
checkpoint_age = lsn - log->last_checkpoint_lsn;
|
||||
|
||||
if (checkpoint_age >= log->log_group_capacity) {
|
||||
@ -872,6 +946,8 @@ log_init(void)
|
||||
log_sys->archiving_on = os_event_create(NULL);
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
log_sys->tracked_lsn = 0;
|
||||
|
||||
/*----------------------------*/
|
||||
|
||||
log_block_init(log_sys->buf, log_sys->lsn);
|
||||
@ -1721,6 +1797,12 @@ log_io_complete_checkpoint(void)
|
||||
}
|
||||
|
||||
mutex_exit(&(log_sys->mutex));
|
||||
|
||||
/* Wake the redo log watching thread to parse the log up to this
|
||||
checkpoint. */
|
||||
if (srv_track_changed_pages) {
|
||||
os_event_set(srv_checkpoint_completed_event);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
@ -3065,6 +3147,15 @@ loop:
|
||||
|
||||
log_checkpoint_margin();
|
||||
|
||||
mutex_enter(&(log_sys->mutex));
|
||||
if (log_check_tracking_margin(0)) {
|
||||
|
||||
mutex_exit(&(log_sys->mutex));
|
||||
os_thread_sleep(10000);
|
||||
goto loop;
|
||||
}
|
||||
mutex_exit(&(log_sys->mutex));
|
||||
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
log_archive_margin();
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
@ -3093,6 +3184,7 @@ logs_empty_and_mark_files_at_shutdown(void)
|
||||
/*=======================================*/
|
||||
{
|
||||
ib_uint64_t lsn;
|
||||
ib_uint64_t tracked_lsn;
|
||||
ulint arch_log_no;
|
||||
|
||||
if (srv_print_verbose_log) {
|
||||
@ -3198,9 +3290,12 @@ loop:
|
||||
|
||||
mutex_enter(&(log_sys->mutex));
|
||||
|
||||
tracked_lsn = log_get_tracked_lsn();
|
||||
|
||||
lsn = log_sys->lsn;
|
||||
|
||||
if (lsn != log_sys->last_checkpoint_lsn
|
||||
|| (srv_track_changed_pages && (tracked_lsn != log_sys->last_checkpoint_lsn))
|
||||
#ifdef UNIV_LOG_ARCHIVE
|
||||
|| (srv_log_archive_on
|
||||
&& lsn != log_sys->archived_lsn + LOG_BLOCK_HDR_SIZE)
|
||||
@ -3255,6 +3350,11 @@ loop:
|
||||
|
||||
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
|
||||
|
||||
/* Signal the log following thread to quit */
|
||||
if (srv_track_changed_pages) {
|
||||
os_event_set(srv_checkpoint_completed_event);
|
||||
}
|
||||
|
||||
/* Make some checks that the server really is quiet */
|
||||
ut_a(srv_n_threads_active[SRV_MASTER] == 0);
|
||||
ut_a(buf_all_freed());
|
||||
@ -3274,6 +3374,10 @@ loop:
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
|
||||
if (srv_track_changed_pages) {
|
||||
os_event_wait(srv_redo_log_thread_finished_event);
|
||||
}
|
||||
|
||||
fil_close_all_files();
|
||||
|
||||
/* Make some checks that the server really is quiet */
|
||||
@ -3399,6 +3503,18 @@ log_print(
|
||||
((log_sys->n_log_ios - log_sys->n_log_ios_old)
|
||||
/ time_elapsed));
|
||||
|
||||
if (srv_track_changed_pages) {
|
||||
|
||||
/* The maximum tracked LSN age is equal to the maximum
|
||||
checkpoint age */
|
||||
fprintf(file,
|
||||
"Log tracking enabled\n"
|
||||
"Log tracked up to %llu\n"
|
||||
"Max tracked LSN age %lu\n",
|
||||
log_get_tracked_lsn(),
|
||||
log_sys->max_checkpoint_age);
|
||||
}
|
||||
|
||||
log_sys->n_log_ios_old = log_sys->n_log_ios;
|
||||
log_sys->last_printout_time = current_time;
|
||||
|
||||
|
1085
storage/xtradb/log/log0online.c
Normal file
1085
storage/xtradb/log/log0online.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -840,7 +840,7 @@ block. We also accept a log block in the old format before
|
||||
InnoDB-3.23.52 where the checksum field contains the log block number.
|
||||
@return TRUE if ok, or if the log block may be in the format of InnoDB
|
||||
version predating 3.23.52 */
|
||||
static
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
log_block_checksum_is_ok_or_old_format(
|
||||
/*===================================*/
|
||||
@ -2084,7 +2084,7 @@ skip_this_recv_addr:
|
||||
/*******************************************************************//**
|
||||
Tries to parse a single log record and returns its length.
|
||||
@return length of the record, or 0 if the record was not complete */
|
||||
static
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
recv_parse_log_rec(
|
||||
/*===============*/
|
||||
@ -2155,7 +2155,7 @@ recv_parse_log_rec(
|
||||
|
||||
/*******************************************************//**
|
||||
Calculates the new value for lsn when more data is added to the log. */
|
||||
static
|
||||
UNIV_INTERN
|
||||
ib_uint64_t
|
||||
recv_calc_lsn_on_data_add(
|
||||
/*======================*/
|
||||
@ -3542,6 +3542,8 @@ recv_reset_logs(
|
||||
log_sys->archived_lsn = log_sys->lsn;
|
||||
#endif /* UNIV_LOG_ARCHIVE */
|
||||
|
||||
log_sys->tracked_lsn = log_sys->lsn;
|
||||
|
||||
log_block_init(log_sys->buf, log_sys->lsn);
|
||||
log_block_set_first_rec_group(log_sys->buf, LOG_BLOCK_HDR_SIZE);
|
||||
|
||||
|
@ -1939,6 +1939,25 @@ os_file_set_eof(
|
||||
#endif /* __WIN__ */
|
||||
}
|
||||
|
||||
/***********************************************************************//**
|
||||
Truncates a file at the specified position.
|
||||
@return TRUE if success */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
os_file_set_eof_at(
|
||||
os_file_t file, /*!< in: handle to a file */
|
||||
ib_uint64_t new_len)/*!< in: new file length */
|
||||
{
|
||||
#ifdef __WIN__
|
||||
/* TODO: untested! */
|
||||
return(!_chsize_s(file, new_len));
|
||||
#else
|
||||
/* TODO: works only with -D_FILE_OFFSET_BITS=64 ? */
|
||||
return(!ftruncate(file, new_len));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef __WIN__
|
||||
/***********************************************************************//**
|
||||
Wrapper to fsync(2) that retries the call on some errors.
|
||||
|
@ -1902,6 +1902,7 @@ page_cur_delete_rec(
|
||||
|
||||
/* Save to local variables some data associated with current_rec */
|
||||
cur_slot_no = page_dir_find_owner_slot(current_rec);
|
||||
ut_ad(cur_slot_no > 0);
|
||||
cur_dir_slot = page_dir_get_nth_slot(page, cur_slot_no);
|
||||
cur_n_owned = page_dir_slot_get_n_owned(cur_dir_slot);
|
||||
|
||||
|
@ -780,17 +780,23 @@ page_copy_rec_list_start(
|
||||
if (UNIV_LIKELY_NULL(new_page_zip)) {
|
||||
mtr_set_log_mode(mtr, log_mode);
|
||||
|
||||
DBUG_EXECUTE_IF("page_copy_rec_list_start_compress_fail",
|
||||
goto zip_reorganize;);
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
(!page_zip_compress(new_page_zip, new_page, index, mtr))) {
|
||||
ulint ret_pos;
|
||||
#ifndef DBUG_OFF
|
||||
zip_reorganize:
|
||||
#endif /* DBUG_OFF */
|
||||
/* Before trying to reorganize the page,
|
||||
store the number of preceding records on the page. */
|
||||
ulint ret_pos
|
||||
= page_rec_get_n_recs_before(ret);
|
||||
ret_pos = page_rec_get_n_recs_before(ret);
|
||||
/* Before copying, "ret" was the predecessor
|
||||
of the predefined supremum record. If it was
|
||||
the predefined infimum record, then it would
|
||||
still be the infimum. Thus, the assertion
|
||||
ut_a(ret_pos > 0) would fail here. */
|
||||
still be the infimum, and we would have
|
||||
ret_pos == 0. */
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
(!page_zip_reorganize(new_block, index, mtr))) {
|
||||
@ -806,15 +812,10 @@ page_copy_rec_list_start(
|
||||
btr_blob_dbg_add(new_page, index,
|
||||
"copy_start_reorg_fail");
|
||||
return(NULL);
|
||||
} else {
|
||||
/* The page was reorganized:
|
||||
Seek to ret_pos. */
|
||||
ret = new_page + PAGE_NEW_INFIMUM;
|
||||
|
||||
do {
|
||||
ret = rec_get_next_ptr(ret, TRUE);
|
||||
} while (--ret_pos);
|
||||
}
|
||||
|
||||
/* The page was reorganized: Seek to ret_pos. */
|
||||
ret = page_rec_get_nth(new_page, ret_pos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,6 +1051,7 @@ page_delete_rec_list_end(
|
||||
|
||||
n_owned = rec_get_n_owned_new(rec2) - count;
|
||||
slot_index = page_dir_find_owner_slot(rec2);
|
||||
ut_ad(slot_index > 0);
|
||||
slot = page_dir_get_nth_slot(page, slot_index);
|
||||
} else {
|
||||
rec_t* rec2 = rec;
|
||||
@ -1065,6 +1067,7 @@ page_delete_rec_list_end(
|
||||
|
||||
n_owned = rec_get_n_owned_old(rec2) - count;
|
||||
slot_index = page_dir_find_owner_slot(rec2);
|
||||
ut_ad(slot_index > 0);
|
||||
slot = page_dir_get_nth_slot(page, slot_index);
|
||||
}
|
||||
|
||||
@ -1491,6 +1494,10 @@ page_rec_get_nth_const(
|
||||
ulint n_owned;
|
||||
const rec_t* rec;
|
||||
|
||||
if (nth == 0) {
|
||||
return(page_get_infimum_rec(page));
|
||||
}
|
||||
|
||||
ut_ad(nth < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
|
||||
|
||||
for (i = 0;; i++) {
|
||||
@ -1584,7 +1591,7 @@ page_rec_get_n_recs_before(
|
||||
n--;
|
||||
|
||||
ut_ad(n >= 0);
|
||||
ut_ad(n < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
|
||||
ut_ad((ulint) n < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
|
||||
|
||||
return((ulint) n);
|
||||
}
|
||||
|
@ -93,7 +93,6 @@ MYSQL_PLUGIN_ACTIONS(xtradb, [
|
||||
if (res != 10 || c != 123) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
],
|
||||
@ -107,6 +106,42 @@ MYSQL_PLUGIN_ACTIONS(xtradb, [
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(whether GCC 64-bit atomic builtins are available)
|
||||
# either define HAVE_IB_GCC_ATOMIC_BUILTINS_64 or not
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#include <stdint.h>
|
||||
int main()
|
||||
{
|
||||
int64_t x, y, res;
|
||||
|
||||
x = 10;
|
||||
y = 123;
|
||||
res = __sync_bool_compare_and_swap(&x, x, y);
|
||||
if (!res || x != y) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
x = 10;
|
||||
y = 123;
|
||||
res = __sync_add_and_fetch(&x, y);
|
||||
if (res != 123 + 10 || x != 123 + 10) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
],
|
||||
[
|
||||
AC_DEFINE([HAVE_IB_GCC_ATOMIC_BUILTINS_64], [1],
|
||||
[GCC 64-bit atomic builtins are available])
|
||||
AC_MSG_RESULT(yes)
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(whether pthread_t can be used by GCC atomic builtins)
|
||||
# either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not
|
||||
AC_TRY_RUN(
|
||||
|
@ -1296,7 +1296,8 @@ run_again:
|
||||
check_index = foreign->foreign_index;
|
||||
}
|
||||
|
||||
if (check_table == NULL || check_table->ibd_file_missing) {
|
||||
if (check_table == NULL || check_table->ibd_file_missing
|
||||
|| check_index == NULL) {
|
||||
if (check_ref) {
|
||||
FILE* ef = dict_foreign_err_file;
|
||||
|
||||
@ -1331,9 +1332,6 @@ run_again:
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
ut_a(check_table);
|
||||
ut_a(check_index);
|
||||
|
||||
if (check_table != table) {
|
||||
/* We already have a LOCK_IX on table, but not necessarily
|
||||
on check_table */
|
||||
@ -2194,9 +2192,16 @@ row_ins_index_entry_low(
|
||||
|
||||
goto function_exit;
|
||||
}
|
||||
err = btr_cur_pessimistic_insert(
|
||||
|
||||
err = btr_cur_optimistic_insert(
|
||||
0, &cursor, entry, &insert_rec, &big_rec,
|
||||
n_ext, thr, &mtr);
|
||||
|
||||
if (err == DB_FAIL) {
|
||||
err = btr_cur_pessimistic_insert(
|
||||
0, &cursor, entry, &insert_rec,
|
||||
&big_rec, n_ext, thr, &mtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1214,11 +1214,25 @@ row_merge_read_clustered_index(
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
/* Store the cursor position on the last user
|
||||
record on the page. */
|
||||
btr_pcur_move_to_prev_on_page(&pcur);
|
||||
/* Leaf pages must never be empty, unless
|
||||
this is the only page in the index tree. */
|
||||
ut_ad(btr_pcur_is_on_user_rec(&pcur)
|
||||
|| buf_block_get_page_no(
|
||||
btr_pcur_get_block(&pcur))
|
||||
== clust_index->page);
|
||||
|
||||
btr_pcur_store_position(&pcur, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
mtr_start(&mtr);
|
||||
/* Restore position on the record, or its
|
||||
predecessor if the record was purged
|
||||
meanwhile. */
|
||||
btr_pcur_restore_position(BTR_SEARCH_LEAF,
|
||||
&pcur, &mtr);
|
||||
/* Move to the successor of the original record. */
|
||||
has_next = btr_pcur_move_to_next_user_rec(&pcur, &mtr);
|
||||
}
|
||||
|
||||
|
@ -3636,7 +3636,7 @@ row_mysql_drop_temp_tables(void)
|
||||
btr_pcur_store_position(&pcur, &mtr);
|
||||
btr_pcur_commit_specify_mtr(&pcur, &mtr);
|
||||
|
||||
table = dict_load_table(table_name);
|
||||
table = dict_table_get_low(table_name);
|
||||
|
||||
if (table) {
|
||||
row_drop_table_for_mysql(table_name, trx, FALSE);
|
||||
|
@ -208,18 +208,6 @@ row_vers_impl_x_locked_off_kernel(
|
||||
vers_del = rec_get_deleted_flag(prev_version, comp);
|
||||
prev_trx_id = row_get_rec_trx_id(prev_version, clust_index,
|
||||
clust_offsets);
|
||||
|
||||
/* If the trx_id and prev_trx_id are different and if
|
||||
the prev_version is marked deleted then the
|
||||
prev_trx_id must have already committed for the trx_id
|
||||
to be able to modify the row. Therefore, prev_trx_id
|
||||
cannot hold any implicit lock. */
|
||||
if (vers_del && 0 != ut_dulint_cmp(trx_id, prev_trx_id)) {
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The stack of versions is locked by mtr. Thus, it
|
||||
is safe to fetch the prefixes for externally stored
|
||||
columns. */
|
||||
|
@ -7,3 +7,6 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_innodb.so';
|
||||
INSTALL PLUGIN innodb_cmp_reset SONAME 'ha_innodb.so';
|
||||
INSTALL PLUGIN innodb_cmpmem SONAME 'ha_innodb.so';
|
||||
INSTALL PLUGIN innodb_cmpmem_reset SONAME 'ha_innodb.so';
|
||||
INSTALL PLUGIN innodb_buffer_pool_stats SONAME 'ha_innodb.so';
|
||||
INSTALL PLUGIN innodb_buffer_page SONAME 'ha_innodb.so';
|
||||
INSTALL PLUGIN innodb_buffer_page_lru SONAME 'ha_innodb.so';
|
||||
|
@ -7,3 +7,6 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_innodb.dll';
|
||||
INSTALL PLUGIN innodb_cmp_reset SONAME 'ha_innodb.dll';
|
||||
INSTALL PLUGIN innodb_cmpmem SONAME 'ha_innodb.dll';
|
||||
INSTALL PLUGIN innodb_cmpmem_reset SONAME 'ha_innodb.dll';
|
||||
INSTALL PLUGIN innodb_buffer_pool_stats SONAME 'ha_innodb.dll';
|
||||
INSTALL PLUGIN innodb_buffer_page SONAME 'ha_innodb.dll';
|
||||
INSTALL PLUGIN innodb_buffer_page_lru SONAME 'ha_innodb.dll';
|
||||
|
@ -69,6 +69,7 @@ Created 10/8/1995 Heikki Tuuri
|
||||
#include "thr0loc.h"
|
||||
#include "que0que.h"
|
||||
#include "srv0que.h"
|
||||
#include "log0online.h"
|
||||
#include "log0recv.h"
|
||||
#include "pars0pars.h"
|
||||
#include "usr0sess.h"
|
||||
@ -161,6 +162,10 @@ UNIV_INTERN ibool srv_recovery_stats = FALSE;
|
||||
|
||||
UNIV_INTERN ulint srv_use_purge_thread = 0;
|
||||
|
||||
UNIV_INTERN my_bool srv_track_changed_pages = TRUE;
|
||||
|
||||
UNIV_INTERN ulonglong srv_changed_pages_limit = 0;
|
||||
|
||||
/* if TRUE, then we auto-extend the last data file */
|
||||
UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
|
||||
/* if != 0, this tells the max size auto-extending may increase the
|
||||
@ -405,6 +410,9 @@ UNIV_INTERN unsigned long long srv_stats_sample_pages = 8;
|
||||
UNIV_INTERN ulong srv_stats_auto_update = 1;
|
||||
UNIV_INTERN ulint srv_stats_update_need_lock = 1;
|
||||
UNIV_INTERN ibool srv_use_sys_stats_table = FALSE;
|
||||
#ifdef UNIV_DEBUG
|
||||
UNIV_INTERN ulong srv_sys_stats_root_page = 0;
|
||||
#endif
|
||||
|
||||
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
|
||||
UNIV_INTERN ibool srv_use_checksums = TRUE;
|
||||
@ -724,6 +732,10 @@ UNIV_INTERN os_event_t srv_lock_timeout_thread_event;
|
||||
|
||||
UNIV_INTERN os_event_t srv_shutdown_event;
|
||||
|
||||
UNIV_INTERN os_event_t srv_checkpoint_completed_event;
|
||||
|
||||
UNIV_INTERN os_event_t srv_redo_log_thread_finished_event;
|
||||
|
||||
UNIV_INTERN srv_sys_t* srv_sys = NULL;
|
||||
|
||||
/* padding to prevent other memory update hotspots from residing on
|
||||
@ -1031,6 +1043,9 @@ srv_init(void)
|
||||
srv_lock_timeout_thread_event = os_event_create(NULL);
|
||||
srv_shutdown_event = os_event_create(NULL);
|
||||
|
||||
srv_checkpoint_completed_event = os_event_create(NULL);
|
||||
srv_redo_log_thread_finished_event = os_event_create(NULL);
|
||||
|
||||
for (i = 0; i < SRV_MASTER + 1; i++) {
|
||||
srv_n_threads_active[i] = 0;
|
||||
srv_n_threads[i] = 0;
|
||||
@ -1178,7 +1193,7 @@ retry:
|
||||
static void
|
||||
srv_conc_exit_innodb_timer_based(trx_t* trx)
|
||||
{
|
||||
(void) os_atomic_increment_lint(&srv_conc_n_threads, -1);
|
||||
(void) os_atomic_increment_lint(&srv_conc_n_threads, -1);
|
||||
trx->declared_to_be_inside_innodb = FALSE;
|
||||
trx->n_tickets_to_enter_innodb = 0;
|
||||
return;
|
||||
@ -1385,7 +1400,7 @@ srv_conc_force_enter_innodb(
|
||||
ut_ad(srv_conc_n_threads >= 0);
|
||||
#ifdef HAVE_ATOMIC_BUILTINS
|
||||
if (srv_thread_concurrency_timer_based) {
|
||||
(void) os_atomic_increment_lint(&srv_conc_n_threads, 1);
|
||||
(void) os_atomic_increment_lint(&srv_conc_n_threads, 1);
|
||||
trx->declared_to_be_inside_innodb = TRUE;
|
||||
trx->n_tickets_to_enter_innodb = 1;
|
||||
return;
|
||||
@ -2674,6 +2689,41 @@ exit_func:
|
||||
OS_THREAD_DUMMY_RETURN;
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
A thread which follows the redo log and outputs the changed page bitmap.
|
||||
@return a dummy value */
|
||||
UNIV_INTERN
|
||||
os_thread_ret_t
|
||||
srv_redo_log_follow_thread(
|
||||
/*=======================*/
|
||||
void* arg __attribute__((unused))) /*!< in: a dummy parameter
|
||||
required by
|
||||
os_thread_create */
|
||||
{
|
||||
#ifdef UNIV_DEBUG_THREAD_CREATION
|
||||
fprintf(stderr, "Redo log follower thread starts, id %lu\n",
|
||||
os_thread_pf(os_thread_get_curr_id()));
|
||||
#endif
|
||||
my_thread_init();
|
||||
|
||||
do {
|
||||
os_event_wait(srv_checkpoint_completed_event);
|
||||
os_event_reset(srv_checkpoint_completed_event);
|
||||
|
||||
log_online_follow_redo_log();
|
||||
|
||||
} while (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE);
|
||||
|
||||
log_online_read_shutdown();
|
||||
os_event_set(srv_redo_log_thread_finished_event);
|
||||
|
||||
my_thread_end();
|
||||
os_thread_exit(NULL);
|
||||
|
||||
OS_THREAD_DUMMY_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************//**
|
||||
Tells the InnoDB server that there has been activity in the database
|
||||
and wakes up the master thread if it is suspended (not sleeping). Used
|
||||
|
@ -51,6 +51,7 @@ Created 2/16/1996 Heikki Tuuri
|
||||
#include "rem0rec.h"
|
||||
#include "mtr0mtr.h"
|
||||
#include "log0log.h"
|
||||
#include "log0online.h"
|
||||
#include "log0recv.h"
|
||||
#include "page0page.h"
|
||||
#include "page0cur.h"
|
||||
@ -127,9 +128,9 @@ static mutex_t ios_mutex;
|
||||
static ulint ios;
|
||||
|
||||
/** io_handler_thread parameters for thread identification */
|
||||
static ulint n[SRV_MAX_N_IO_THREADS + 7 + UNIV_MAX_PARALLELISM];
|
||||
static ulint n[SRV_MAX_N_IO_THREADS + 8 + UNIV_MAX_PARALLELISM];
|
||||
/** io_handler_thread identifiers */
|
||||
static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 7 + UNIV_MAX_PARALLELISM];
|
||||
static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 8 + UNIV_MAX_PARALLELISM];
|
||||
|
||||
/** We use this mutex to test the return value of pthread_mutex_trylock
|
||||
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
|
||||
@ -1823,6 +1824,12 @@ innobase_start_or_create_for_mysql(void)
|
||||
|
||||
trx_sys_dummy_create(TRX_DOUBLEWRITE_SPACE);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(!dict_verify_xtradb_sys_stats())) {
|
||||
fprintf(stderr, "InnoDB: Warning: "
|
||||
"SYS_STATS table corrupted, recreating\n");
|
||||
dict_recreate_xtradb_sys_stats();
|
||||
}
|
||||
}
|
||||
|
||||
if (!create_new_db && sum_of_new_sizes > 0) {
|
||||
@ -1885,6 +1892,19 @@ innobase_start_or_create_for_mysql(void)
|
||||
if (srv_auto_lru_dump && srv_blocking_lru_restore)
|
||||
buf_LRU_file_restore();
|
||||
|
||||
if (srv_track_changed_pages) {
|
||||
|
||||
/* Initialize the log tracking subsystem here to block
|
||||
server startup until it's completed due to the potential
|
||||
need to re-read previous server run's log. */
|
||||
log_online_read_init();
|
||||
|
||||
/* Create the thread that follows the redo log to output the
|
||||
changed page bitmap */
|
||||
os_thread_create(&srv_redo_log_follow_thread, NULL,
|
||||
thread_ids + 5 + SRV_MAX_N_IO_THREADS);
|
||||
}
|
||||
|
||||
srv_is_being_started = FALSE;
|
||||
|
||||
if (trx_doublewrite == NULL) {
|
||||
|
@ -926,6 +926,11 @@ sync_array_print_long_waits(
|
||||
ibool fatal = FALSE;
|
||||
double longest_diff = 0;
|
||||
|
||||
/* For huge tables, skip the check during CHECK TABLE etc... */
|
||||
if (fatal_timeout > SRV_SEMAPHORE_WAIT_EXTENSION) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
|
||||
|
||||
double diff;
|
||||
|
@ -48,7 +48,6 @@ red-black properties:
|
||||
#endif
|
||||
|
||||
#define ROOT(t) (t->root->left)
|
||||
#define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1)
|
||||
|
||||
/****************************************************************//**
|
||||
Print out the sub-tree recursively. */
|
||||
@ -829,6 +828,21 @@ rbt_add_node(
|
||||
node = (ib_rbt_node_t*) ut_malloc(SIZEOF_NODE(tree));
|
||||
|
||||
memcpy(node->value, value, tree->sizeof_value);
|
||||
return(rbt_add_preallocated_node(tree, parent, node));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Add a new caller-provided node to tree at the specified position.
|
||||
The node must have its key fields initialized correctly.
|
||||
@return added node */
|
||||
UNIV_INTERN
|
||||
const ib_rbt_node_t*
|
||||
rbt_add_preallocated_node(
|
||||
/*======================*/
|
||||
ib_rbt_t* tree, /*!< in: rb tree */
|
||||
ib_rbt_bound_t* parent, /*!< in: parent */
|
||||
ib_rbt_node_t* node) /*!< in: node */
|
||||
{
|
||||
node->parent = node->left = node->right = tree->nil;
|
||||
|
||||
/* If tree is empty */
|
||||
@ -1137,7 +1151,17 @@ rbt_clear(
|
||||
ib_rbt_t* tree) /*!< in: rb tree */
|
||||
{
|
||||
rbt_free_node(ROOT(tree), tree->nil);
|
||||
rbt_reset(tree);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Clear the tree without deleting and freeing its nodes. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
rbt_reset(
|
||||
/*======*/
|
||||
ib_rbt_t* tree) /*!< in: rb tree */
|
||||
{
|
||||
tree->n_nodes = 0;
|
||||
tree->root->left = tree->root->right = tree->nil;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user