Merge lp:~vlad-lesin/percona-server/5.6-logical-readahead into lp:percona-server/5.6
- 5.6-logical-readahead
- Merge into 5.6
Status: | Rejected |
---|---|
Rejected by: | Laurynas Biveinis |
Proposed branch: | lp:~vlad-lesin/percona-server/5.6-logical-readahead |
Merge into: | lp:percona-server/5.6 |
Diff against target: |
2278 lines (+1520/-71) 40 files modified
client/client_priv.h (+4/-1) client/mysqldump.c (+38/-0) mysql-test/include/have_native_aio.inc (+6/-0) mysql-test/suite/innodb/r/innodb_logical_read_ahead.result (+47/-0) mysql-test/suite/innodb/r/innodb_logical_read_ahead_correctness.result (+88/-0) mysql-test/suite/innodb/r/innodb_merge_read.result (+30/-0) mysql-test/suite/innodb/t/innodb_logical_read_ahead-master.opt (+2/-0) mysql-test/suite/innodb/t/innodb_logical_read_ahead.test (+55/-0) mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness-master.opt (+2/-0) mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness.test (+107/-0) mysql-test/suite/innodb/t/innodb_merge_read-master.opt (+1/-0) mysql-test/suite/innodb/t/innodb_merge_read.test (+42/-0) mysql-test/suite/sys_vars/r/innodb_lra_n_node_recs_before_sleep_basic.result (+28/-0) mysql-test/suite/sys_vars/r/innodb_lra_size_basic.result (+28/-0) mysql-test/suite/sys_vars/r/innodb_lra_sleep_basic.result (+30/-0) mysql-test/suite/sys_vars/r/innodb_lra_test_basic.result (+8/-0) mysql-test/suite/sys_vars/t/innodb_lra_n_node_recs_before_sleep_basic.test (+14/-0) mysql-test/suite/sys_vars/t/innodb_lra_size_basic-master.opt (+1/-0) mysql-test/suite/sys_vars/t/innodb_lra_size_basic.test (+14/-0) mysql-test/suite/sys_vars/t/innodb_lra_sleep_basic.test (+14/-0) mysql-test/suite/sys_vars/t/innodb_lra_test_basic-master.opt (+1/-0) mysql-test/suite/sys_vars/t/innodb_lra_test_basic.test (+8/-0) storage/innobase/btr/btr0cur.cc (+1/-0) storage/innobase/btr/btr0pcur.cc (+26/-18) storage/innobase/buf/buf0rea.cc (+33/-10) storage/innobase/fil/fil0fil.cc (+8/-3) storage/innobase/handler/ha_innodb.cc (+61/-0) storage/innobase/include/btr0pcur.h (+3/-2) storage/innobase/include/btr0pcur.ic (+51/-17) storage/innobase/include/buf0rea.h (+37/-0) storage/innobase/include/fil0fil.h (+5/-2) storage/innobase/include/os0file.h (+24/-6) storage/innobase/include/os0file.ic (+6/-2) storage/innobase/include/srv0srv.h (+42/-0) storage/innobase/include/trx0trx.h (+96/-1) storage/innobase/os/os0file.cc (+99/-9) storage/innobase/row/row0purge.cc (+9/-0) storage/innobase/row/row0sel.cc (+319/-0) storage/innobase/srv/srv0srv.cc (+9/-0) storage/innobase/trx/trx0trx.cc (+123/-0) |
To merge this branch: | bzr merge lp:~vlad-lesin/percona-server/5.6-logical-readahead |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Needs Resubmitting | ||
Review via email: mp+216857@code.launchpad.net |
Commit message
Description of the change
Porting logical readahead feature from Facebook branch. The original patches are here:
https:/
https:/
https:/
The main difference is multiple io's commit is enabled only for logical read-ahead in this branch in comparison with the original implementation where it is enabled by default for all operations. See explanation in commit comments.
Jenkins testing:
http://
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Review of commit 576. I think it will be easier if it will have its own MP (probably the other two commits too).
Code
- s/ibool/bool/g (in all three commits if applies)
- I'd add a defensive asserts at os_aio_free that for all arrays,
count[x] == 0. This would catch any unsubmitted buffered read
request, and any request buffered on the non-read array.
- s/ut_malloc+
- Why does buf_read_recv_pages call
os_
submit any buffered requests.
- fil_extend_
should_buffer == TRUE is a (benign) typo?
- The abstraction level for buffered request submitting seems to
be off. I'd rename os_aio_
os_
down to it.
- buf_read_page_low header comment @return tag: edit to "1 if
read request is issued or buffered" to clarify that the function
returns the same for both buffered and immediatelly issued read
requests.
- s/read/ready in the buf_read_page_low should_buffer
comment. (https:/
- Make sure the patch does not break the build with performance
schema configured out
- os_aio_
comment, os_aio_func should_buffer arg declaration is misaligned
</pedantic>
Testcase
- --disable_
is obsolete and should be removed. (in all three commits if
applies)
- innodb_
include/
is likely to differ for other page sizes.
- innodb_
-
include/
enough.
- newline at the end of have_native_aio.inc
- I'd extend the innodb_merge_read testcase to check that linear
read ahead read buffering works for compressed tablespaces too
(there is code if (zip_size) then read(... should_buffer) else
read(... should_buffer)). That would cause move of the testcase
to the innodb_zip suite as well.
- (wishlist) Consider submitting
https:/
for Percona Server so that we exercise AIO with MTR --mem.
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Work on this MP must continue on github.
Unmerged revisions
- 578. By Vlad Lesin
-
Add mysqldump support for logical read ahead
Summary:
Adds options to mysqldump:
--lra-size=X
--lra-sleep=X
--lra-n-node- recs-before- sleep=X These just inject SET statements to set these session variables.
The original implementation is here:
https://github. com/facebook/ mysql-5. 6/commit/ f69a4ea522bce24 e4cdcc7696d5fad 29587cf87a - 577. By Vlad Lesin
-
When the session variable innodb_lra_size is set to N, we issue async
read requests for the next M logical pages where the total size of the M
pages on disk is N megabytes. The max allowed value of innodb_lra_size
is is 16384 which corresponds to prefetching 16GB of data. We may choose
to use smaller values in production.The original implementation can be found here:
https://github. com/facebook/ mysql-5. 6/commit/ f8e361952612d00 979f7cf744f487e 48b15cb5a6 This implementation does not contain code for flashcahe.
- 576. By Vlad Lesin
-
Merge aio page read requests
Summary:
Tries to submit multiple aio page read requests together to improve read
performance.The original code and description can be found here:
https://github. com/facebook/ mysql-5. 6/commit/ f9d1a5332eb2c82 c028638d3b93b5a 3592a69ffa The difference between this and the original implementation is that fil_io()
macros invokes _fil_io() function with enabled io's buffering by default in
the original implementation, it can cause the errors connected with waiting
io finishing just after fil_io() invocation.For example log_archive_do() waits io's finishing on log_sys-
>archive_ lock
mutex, but the mutex is not being unlocked as io's were buffered and
uncommited and io_handler_thread() does not process io's completion in
fil_aio_wait(). Potentially there can be the same errors so io's buffering
is disabled by default and will be enabled only for logical readahead code.
Preview Diff
1 | === modified file 'client/client_priv.h' | |||
2 | --- client/client_priv.h 2014-02-25 17:05:01 +0000 | |||
3 | +++ client/client_priv.h 2014-04-23 10:58:56 +0000 | |||
4 | @@ -106,7 +106,10 @@ | |||
5 | 106 | OPT_INNODB_OPTIMIZE_KEYS, | 106 | OPT_INNODB_OPTIMIZE_KEYS, |
6 | 107 | OPT_REWRITE_DB, | 107 | OPT_REWRITE_DB, |
7 | 108 | OPT_LOCK_FOR_BACKUP, | 108 | OPT_LOCK_FOR_BACKUP, |
9 | 109 | OPT_MAX_CLIENT_OPTION | 109 | OPT_MAX_CLIENT_OPTION, |
10 | 110 | OPT_LRA_SIZE, | ||
11 | 111 | OPT_LRA_SLEEP, | ||
12 | 112 | OPT_LRA_N_NODE_RECS_BEFORE_SLEEP | ||
13 | 110 | }; | 113 | }; |
14 | 111 | 114 | ||
15 | 112 | /** | 115 | /** |
16 | 113 | 116 | ||
17 | === modified file 'client/mysqldump.c' | |||
18 | --- client/mysqldump.c 2014-03-03 17:51:33 +0000 | |||
19 | +++ client/mysqldump.c 2014-04-23 10:58:56 +0000 | |||
20 | @@ -133,6 +133,9 @@ | |||
21 | 133 | /* Server supports character_set_results session variable? */ | 133 | /* Server supports character_set_results session variable? */ |
22 | 134 | static my_bool server_supports_switching_charsets= TRUE; | 134 | static my_bool server_supports_switching_charsets= TRUE; |
23 | 135 | static ulong opt_compatible_mode= 0; | 135 | static ulong opt_compatible_mode= 0; |
24 | 136 | static ulong opt_lra_size = 0; | ||
25 | 137 | static ulong opt_lra_sleep = 0; | ||
26 | 138 | static ulong opt_lra_n_node_recs_before_sleep = 0; | ||
27 | 136 | #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 | 139 | #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1 |
28 | 137 | #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 | 140 | #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2 |
29 | 138 | #define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1 | 141 | #define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1 |
30 | @@ -567,6 +570,18 @@ | |||
31 | 567 | "Default authentication client-side plugin to use.", | 570 | "Default authentication client-side plugin to use.", |
32 | 568 | &opt_default_auth, &opt_default_auth, 0, | 571 | &opt_default_auth, &opt_default_auth, 0, |
33 | 569 | GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, | 572 | GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
34 | 573 | {"lra_size", OPT_LRA_SIZE, | ||
35 | 574 | "Set innodb_lra_size for the session of this dump.", | ||
36 | 575 | &opt_lra_size, &opt_lra_size, 0, | ||
37 | 576 | GET_ULONG, REQUIRED_ARG, 0, 0, 16384, 0, 0, 0}, | ||
38 | 577 | {"lra_sleep", OPT_LRA_SLEEP, | ||
39 | 578 | "Set innodb_lra_sleep for the session of this dump.", | ||
40 | 579 | &opt_lra_sleep, &opt_lra_sleep, 0, | ||
41 | 580 | GET_ULONG, REQUIRED_ARG, 0, 0, 1000, 0, 0, 0}, | ||
42 | 581 | {"lra_n_node_recs_before_sleep", OPT_LRA_N_NODE_RECS_BEFORE_SLEEP, | ||
43 | 582 | "Set innodb_lra_n_node_recs_before_sleep for the session of this dump.", | ||
44 | 583 | &opt_lra_n_node_recs_before_sleep, &opt_lra_n_node_recs_before_sleep, 0, | ||
45 | 584 | GET_ULONG, REQUIRED_ARG, 1024, 128, ULONG_MAX, 0, 0, 0}, | ||
46 | 570 | {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} | 585 | {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
47 | 571 | }; | 586 | }; |
48 | 572 | 587 | ||
49 | @@ -1611,6 +1626,29 @@ | |||
50 | 1611 | if (mysql_query_with_error_report(mysql, 0, buff)) | 1626 | if (mysql_query_with_error_report(mysql, 0, buff)) |
51 | 1612 | DBUG_RETURN(1); | 1627 | DBUG_RETURN(1); |
52 | 1613 | } | 1628 | } |
53 | 1629 | |||
54 | 1630 | if (opt_lra_size) | ||
55 | 1631 | { | ||
56 | 1632 | my_snprintf(buff, sizeof(buff), "SET innodb_lra_size=%lu", opt_lra_size); | ||
57 | 1633 | if (mysql_query_with_error_report(mysql, 0, buff)) | ||
58 | 1634 | DBUG_RETURN(1); | ||
59 | 1635 | if (opt_lra_sleep) | ||
60 | 1636 | { | ||
61 | 1637 | my_snprintf(buff, sizeof(buff), "SET innodb_lra_sleep=%lu", | ||
62 | 1638 | opt_lra_sleep); | ||
63 | 1639 | if (mysql_query_with_error_report(mysql, 0, buff)) | ||
64 | 1640 | DBUG_RETURN(1); | ||
65 | 1641 | } | ||
66 | 1642 | if (opt_lra_n_node_recs_before_sleep) | ||
67 | 1643 | { | ||
68 | 1644 | my_snprintf(buff, sizeof(buff), | ||
69 | 1645 | "SET innodb_lra_n_node_recs_before_sleep=%lu", | ||
70 | 1646 | opt_lra_n_node_recs_before_sleep); | ||
71 | 1647 | if (mysql_query_with_error_report(mysql, 0, buff)) | ||
72 | 1648 | DBUG_RETURN(1); | ||
73 | 1649 | } | ||
74 | 1650 | } | ||
75 | 1651 | |||
76 | 1614 | DBUG_RETURN(0); | 1652 | DBUG_RETURN(0); |
77 | 1615 | } /* connect_to_db */ | 1653 | } /* connect_to_db */ |
78 | 1616 | 1654 | ||
79 | 1617 | 1655 | ||
80 | === added file 'mysql-test/include/have_native_aio.inc' | |||
81 | --- mysql-test/include/have_native_aio.inc 1970-01-01 00:00:00 +0000 | |||
82 | +++ mysql-test/include/have_native_aio.inc 2014-04-23 10:58:56 +0000 | |||
83 | @@ -0,0 +1,6 @@ | |||
84 | 1 | --disable_query_log | ||
85 | 2 | if (`select @@global.innodb_use_native_aio != 1`) | ||
86 | 3 | { | ||
87 | 4 | --skip native AIO is not in use | ||
88 | 5 | } | ||
89 | 6 | --enable_query_log | ||
90 | 0 | \ No newline at end of file | 7 | \ No newline at end of file |
91 | 1 | 8 | ||
92 | === added file 'mysql-test/suite/innodb/r/innodb_logical_read_ahead.result' | |||
93 | --- mysql-test/suite/innodb/r/innodb_logical_read_ahead.result 1970-01-01 00:00:00 +0000 | |||
94 | +++ mysql-test/suite/innodb/r/innodb_logical_read_ahead.result 2014-04-23 10:58:56 +0000 | |||
95 | @@ -0,0 +1,47 @@ | |||
96 | 1 | DROP TABLE if exists t1; | ||
97 | 2 | CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
98 | 3 | INSERT INTO t1 VALUES (0, REPEAT('a',256)); | ||
99 | 4 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
100 | 5 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
101 | 6 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
102 | 7 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
103 | 8 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
104 | 9 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
105 | 10 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
106 | 11 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
107 | 12 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
108 | 13 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
109 | 14 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
110 | 15 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
111 | 16 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
112 | 17 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
113 | 18 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
114 | 19 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
115 | 20 | show global status like "innodb_buffered_aio_submitted"; | ||
116 | 21 | Variable_name Value | ||
117 | 22 | Innodb_buffered_aio_submitted 0 | ||
118 | 23 | show global status like "innodb_logical_read_ahead_misses"; | ||
119 | 24 | Variable_name Value | ||
120 | 25 | Innodb_logical_read_ahead_misses 0 | ||
121 | 26 | show global status like "innodb_logical_read_ahead_prefetched"; | ||
122 | 27 | Variable_name Value | ||
123 | 28 | Innodb_logical_read_ahead_prefetched 0 | ||
124 | 29 | show global status like "innodb_logical_read_ahead_in_buf_pool"; | ||
125 | 30 | Variable_name Value | ||
126 | 31 | Innodb_logical_read_ahead_in_buf_pool 0 | ||
127 | 32 | SET SESSION innodb_lra_size=1024; | ||
128 | 33 | SET SESSION innodb_lra_n_node_recs_before_sleep=128; | ||
129 | 34 | SET SESSION innodb_lra_sleep=100; | ||
130 | 35 | checksum table t1; | ||
131 | 36 | Table Checksum | ||
132 | 37 | test.t1 2920207201 | ||
133 | 38 | show global status like "innodb_logical_read_ahead_misses"; | ||
134 | 39 | Variable_name Value | ||
135 | 40 | Innodb_logical_read_ahead_misses 0 | ||
136 | 41 | select variable_value > 1000 from information_schema.global_status where variable_name="innodb_logical_read_ahead_prefetched"; | ||
137 | 42 | variable_value > 1000 | ||
138 | 43 | 1 | ||
139 | 44 | select variable_value < 100 from information_schema.global_status where variable_name="innodb_logical_read_ahead_in_buf_pool"; | ||
140 | 45 | variable_value < 100 | ||
141 | 46 | 1 | ||
142 | 47 | DROP TABLE t1; | ||
143 | 0 | 48 | ||
144 | === added file 'mysql-test/suite/innodb/r/innodb_logical_read_ahead_correctness.result' | |||
145 | --- mysql-test/suite/innodb/r/innodb_logical_read_ahead_correctness.result 1970-01-01 00:00:00 +0000 | |||
146 | +++ mysql-test/suite/innodb/r/innodb_logical_read_ahead_correctness.result 2014-04-23 10:58:56 +0000 | |||
147 | @@ -0,0 +1,88 @@ | |||
148 | 1 | DROP TABLE IF EXISTS t1_small; | ||
149 | 2 | DROP TABLE IF EXISTS t1; | ||
150 | 3 | DROP TABLE IF EXISTS t1_lra; | ||
151 | 4 | DROP TABLE IF EXISTS t2_small; | ||
152 | 5 | DROP TABLE IF EXISTS t3_small; | ||
153 | 6 | CREATE TABLE t1_small(a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
154 | 7 | SET SESSION innodb_lra_size=1; | ||
155 | 8 | SELECT * FROM t1_small; | ||
156 | 9 | a b | ||
157 | 10 | SET SESSION innodb_lra_size=0; | ||
158 | 11 | INSERT INTO t1_small(b) VALUES(REPEAT('a',256)); | ||
159 | 12 | SET SESSION innodb_lra_size=1; | ||
160 | 13 | SELECT a, LENGTH(b) FROM t1_small; | ||
161 | 14 | a LENGTH(b) | ||
162 | 15 | 1 256 | ||
163 | 16 | SET SESSION innodb_lra_size=0; | ||
164 | 17 | DROP TABLE t1_small; | ||
165 | 18 | CREATE TABLE `t2_small` ( | ||
166 | 19 | `id1` bigint(20) unsigned NOT NULL DEFAULT '0', | ||
167 | 20 | `time` bigint(20) unsigned NOT NULL DEFAULT '0', | ||
168 | 21 | `id2` bigint(20) unsigned NOT NULL DEFAULT '0', | ||
169 | 22 | `id2_type` int(10) unsigned DEFAULT NULL, | ||
170 | 23 | `data` text, | ||
171 | 24 | `status` tinyint(3) unsigned DEFAULT NULL, | ||
172 | 25 | PRIMARY KEY (`id1`,`time`,`id2`) | ||
173 | 26 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; | ||
174 | 27 | SET SESSION innodb_lra_size=1; | ||
175 | 28 | SELECT * FROM t2_small; | ||
176 | 29 | id1 time id2 id2_type data status | ||
177 | 30 | DROP TABLE t2_small; | ||
178 | 31 | CREATE TABLE `t3_small` ( | ||
179 | 32 | `id` bigint(20) NOT NULL, | ||
180 | 33 | `a` text, | ||
181 | 34 | `b` text, | ||
182 | 35 | `c` text, | ||
183 | 36 | `d` text, | ||
184 | 37 | `e` text, | ||
185 | 38 | `f` text, | ||
186 | 39 | `g` text, | ||
187 | 40 | PRIMARY KEY (`id`) | ||
188 | 41 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; | ||
189 | 42 | SET SESSION innodb_lra_size=1; | ||
190 | 43 | SELECT * FROM t3_small; | ||
191 | 44 | id a b c d e f g | ||
192 | 45 | DROP TABLE t3_small; | ||
193 | 46 | CREATE TABLE t1(a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
194 | 47 | CREATE TABLE t1_lra(a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
195 | 48 | INSERT INTO t1 VALUES (0, REPEAT('a',256)); | ||
196 | 49 | INSERT INTO t1(b) SELECT b FROM t1; | ||
197 | 50 | INSERT INTO t1(b) SELECT b FROM t1; | ||
198 | 51 | INSERT INTO t1(b) SELECT b FROM t1; | ||
199 | 52 | INSERT INTO t1(b) SELECT b FROM t1; | ||
200 | 53 | INSERT INTO t1(b) SELECT b FROM t1; | ||
201 | 54 | INSERT INTO t1(b) SELECT b FROM t1; | ||
202 | 55 | INSERT INTO t1(b) SELECT b FROM t1; | ||
203 | 56 | INSERT INTO t1(b) SELECT b FROM t1; | ||
204 | 57 | INSERT INTO t1(b) SELECT b FROM t1; | ||
205 | 58 | INSERT INTO t1(b) SELECT b FROM t1; | ||
206 | 59 | INSERT INTO t1(b) SELECT b FROM t1; | ||
207 | 60 | INSERT INTO t1(b) SELECT b FROM t1; | ||
208 | 61 | INSERT INTO t1(b) SELECT b FROM t1; | ||
209 | 62 | INSERT INTO t1(b) SELECT b FROM t1; | ||
210 | 63 | INSERT INTO t1_lra SELECT * FROM t1; | ||
211 | 64 | CHECKSUM TABLE t1; | ||
212 | 65 | Table Checksum | ||
213 | 66 | test.t1 2793042655 | ||
214 | 67 | SET SESSION innodb_lra_size=1; | ||
215 | 68 | SET SESSION innodb_lra_n_node_recs_before_sleep=128; | ||
216 | 69 | SET SESSION innodb_lra_sleep=100; | ||
217 | 70 | CHECKSUM TABLE t1_lra; | ||
218 | 71 | Table Checksum | ||
219 | 72 | test.t1_lra 2793042655 | ||
220 | 73 | DELETE FROM t1 WHERE a >= 5480 AND a < 5520; | ||
221 | 74 | DELETE FROM t1 WHERE a >= 5520 AND a < 5550; | ||
222 | 75 | CHECKSUM TABLE t1; | ||
223 | 76 | Table Checksum | ||
224 | 77 | test.t1 1005864202 | ||
225 | 78 | SET GLOBAL innodb_lra_test=1; | ||
226 | 79 | DELETE FROM t1_lra WHERE a >= 5480 AND a < 5520; | ||
227 | 80 | DELETE FROM t1_lra WHERE a >= 5520 AND a < 5550; | ||
228 | 81 | SET SESSION innodb_lra_size=1; | ||
229 | 82 | SET SESSION innodb_lra_n_node_recs_before_sleep=128; | ||
230 | 83 | SET SESSION innodb_lra_sleep=100; | ||
231 | 84 | CHECKSUM TABLE t1_lra; | ||
232 | 85 | Table Checksum | ||
233 | 86 | test.t1_lra 1005864202 | ||
234 | 87 | DROP TABLE t1; | ||
235 | 88 | DROP TABLE t1_lra; | ||
236 | 0 | 89 | ||
237 | === added file 'mysql-test/suite/innodb/r/innodb_merge_read.result' | |||
238 | --- mysql-test/suite/innodb/r/innodb_merge_read.result 1970-01-01 00:00:00 +0000 | |||
239 | +++ mysql-test/suite/innodb/r/innodb_merge_read.result 2014-04-23 10:58:56 +0000 | |||
240 | @@ -0,0 +1,30 @@ | |||
241 | 1 | DROP TABLE if exists t1; | ||
242 | 2 | CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
243 | 3 | INSERT INTO t1 VALUES (0, REPEAT('a',256)); | ||
244 | 4 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
245 | 5 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
246 | 6 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
247 | 7 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
248 | 8 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
249 | 9 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
250 | 10 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
251 | 11 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
252 | 12 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
253 | 13 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
254 | 14 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
255 | 15 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
256 | 16 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
257 | 17 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
258 | 18 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
259 | 19 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
260 | 20 | show global status like "innodb_buffered_aio_submitted"; | ||
261 | 21 | Variable_name Value | ||
262 | 22 | Innodb_buffered_aio_submitted 0 | ||
263 | 23 | select * from t1; | ||
264 | 24 | select count(*) from t1; | ||
265 | 25 | count(*) | ||
266 | 26 | 65536 | ||
267 | 27 | show global status like "innodb_buffered_aio_submitted"; | ||
268 | 28 | Variable_name Value | ||
269 | 29 | Innodb_buffered_aio_submitted 2397 | ||
270 | 30 | DROP TABLE t1; | ||
271 | 0 | 31 | ||
272 | === added file 'mysql-test/suite/innodb/t/innodb_logical_read_ahead-master.opt' | |||
273 | --- mysql-test/suite/innodb/t/innodb_logical_read_ahead-master.opt 1970-01-01 00:00:00 +0000 | |||
274 | +++ mysql-test/suite/innodb/t/innodb_logical_read_ahead-master.opt 2014-04-23 10:58:56 +0000 | |||
275 | @@ -0,0 +1,2 @@ | |||
276 | 1 | --innodb_use_native_aio=1 | ||
277 | 2 | --force-restart | ||
278 | 0 | 3 | ||
279 | === added file 'mysql-test/suite/innodb/t/innodb_logical_read_ahead.test' | |||
280 | --- mysql-test/suite/innodb/t/innodb_logical_read_ahead.test 1970-01-01 00:00:00 +0000 | |||
281 | +++ mysql-test/suite/innodb/t/innodb_logical_read_ahead.test 2014-04-23 10:58:56 +0000 | |||
282 | @@ -0,0 +1,55 @@ | |||
283 | 1 | --source include/have_innodb.inc | ||
284 | 2 | --source include/have_native_aio.inc | ||
285 | 3 | |||
286 | 4 | --disable_warnings | ||
287 | 5 | DROP TABLE if exists t1; | ||
288 | 6 | --enable_warnings | ||
289 | 7 | |||
290 | 8 | # Create table. | ||
291 | 9 | CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
292 | 10 | |||
293 | 11 | # Populate table. | ||
294 | 12 | INSERT INTO t1 VALUES (0, REPEAT('a',256)); | ||
295 | 13 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
296 | 14 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
297 | 15 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
298 | 16 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
299 | 17 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
300 | 18 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
301 | 19 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
302 | 20 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
303 | 21 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
304 | 22 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
305 | 23 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
306 | 24 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
307 | 25 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
308 | 26 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
309 | 27 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
310 | 28 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
311 | 29 | |||
312 | 30 | --source include/restart_mysqld.inc | ||
313 | 31 | |||
314 | 32 | show global status like "innodb_buffered_aio_submitted"; | ||
315 | 33 | show global status like "innodb_logical_read_ahead_misses"; | ||
316 | 34 | show global status like "innodb_logical_read_ahead_prefetched"; | ||
317 | 35 | show global status like "innodb_logical_read_ahead_in_buf_pool"; | ||
318 | 36 | |||
319 | 37 | # set the logical read ahead large enough to prefetch | ||
320 | 38 | # the entire table. | ||
321 | 39 | SET SESSION innodb_lra_size=1024; | ||
322 | 40 | SET SESSION innodb_lra_n_node_recs_before_sleep=128; | ||
323 | 41 | SET SESSION innodb_lra_sleep=100; | ||
324 | 42 | checksum table t1; | ||
325 | 43 | |||
326 | 44 | # there should be no misses, all pages must have been | ||
327 | 45 | # prefetched by the logical read ahead. | ||
328 | 46 | show global status like "innodb_logical_read_ahead_misses"; | ||
329 | 47 | # the total number of pages prefetched must be close to the number | ||
330 | 48 | # of leaf pages of the table. | ||
331 | 49 | select variable_value > 1000 from information_schema.global_status where variable_name="innodb_logical_read_ahead_prefetched"; | ||
332 | 50 | # innodb_logical_read_ahead_in_buf_pool is the number of pages | ||
333 | 51 | # of the table that were already in the buffer pool while doing the scan. | ||
334 | 52 | # This should be small. | ||
335 | 53 | select variable_value < 100 from information_schema.global_status where variable_name="innodb_logical_read_ahead_in_buf_pool"; | ||
336 | 54 | |||
337 | 55 | DROP TABLE t1; | ||
338 | 0 | 56 | ||
339 | === added file 'mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness-master.opt' | |||
340 | --- mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness-master.opt 1970-01-01 00:00:00 +0000 | |||
341 | +++ mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness-master.opt 2014-04-23 10:58:56 +0000 | |||
342 | @@ -0,0 +1,2 @@ | |||
343 | 1 | --innodb_use_native_aio=1 | ||
344 | 2 | --force-restart | ||
345 | 0 | 3 | ||
346 | === added file 'mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness.test' | |||
347 | --- mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness.test 1970-01-01 00:00:00 +0000 | |||
348 | +++ mysql-test/suite/innodb/t/innodb_logical_read_ahead_correctness.test 2014-04-23 10:58:56 +0000 | |||
349 | @@ -0,0 +1,107 @@ | |||
350 | 1 | --source include/have_debug.inc | ||
351 | 2 | --source include/have_innodb.inc | ||
352 | 3 | --source include/have_native_aio.inc | ||
353 | 4 | |||
354 | 5 | --disable_warnings | ||
355 | 6 | DROP TABLE IF EXISTS t1_small; | ||
356 | 7 | DROP TABLE IF EXISTS t1; | ||
357 | 8 | DROP TABLE IF EXISTS t1_lra; | ||
358 | 9 | DROP TABLE IF EXISTS t2_small; | ||
359 | 10 | DROP TABLE IF EXISTS t3_small; | ||
360 | 11 | --enable_warnings | ||
361 | 12 | |||
362 | 13 | # The small table is for checking against a bug where the table's only page is the | ||
363 | 14 | # root page. In such a case the function called for getting the parent page caused | ||
364 | 15 | # the server to crash. | ||
365 | 16 | CREATE TABLE t1_small(a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
366 | 17 | |||
367 | 18 | SET SESSION innodb_lra_size=1; | ||
368 | 19 | SELECT * FROM t1_small; | ||
369 | 20 | |||
370 | 21 | SET SESSION innodb_lra_size=0; | ||
371 | 22 | INSERT INTO t1_small(b) VALUES(REPEAT('a',256)); | ||
372 | 23 | SET SESSION innodb_lra_size=1; | ||
373 | 24 | SELECT a, LENGTH(b) FROM t1_small; | ||
374 | 25 | SET SESSION innodb_lra_size=0; | ||
375 | 26 | |||
376 | 27 | DROP TABLE t1_small; | ||
377 | 28 | |||
378 | 29 | CREATE TABLE `t2_small` ( | ||
379 | 30 | `id1` bigint(20) unsigned NOT NULL DEFAULT '0', | ||
380 | 31 | `time` bigint(20) unsigned NOT NULL DEFAULT '0', | ||
381 | 32 | `id2` bigint(20) unsigned NOT NULL DEFAULT '0', | ||
382 | 33 | `id2_type` int(10) unsigned DEFAULT NULL, | ||
383 | 34 | `data` text, | ||
384 | 35 | `status` tinyint(3) unsigned DEFAULT NULL, | ||
385 | 36 | PRIMARY KEY (`id1`,`time`,`id2`) | ||
386 | 37 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; | ||
387 | 38 | |||
388 | 39 | SET SESSION innodb_lra_size=1; | ||
389 | 40 | SELECT * FROM t2_small; | ||
390 | 41 | DROP TABLE t2_small; | ||
391 | 42 | |||
392 | 43 | CREATE TABLE `t3_small` ( | ||
393 | 44 | `id` bigint(20) NOT NULL, | ||
394 | 45 | `a` text, | ||
395 | 46 | `b` text, | ||
396 | 47 | `c` text, | ||
397 | 48 | `d` text, | ||
398 | 49 | `e` text, | ||
399 | 50 | `f` text, | ||
400 | 51 | `g` text, | ||
401 | 52 | PRIMARY KEY (`id`) | ||
402 | 53 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; | ||
403 | 54 | |||
404 | 55 | SET SESSION innodb_lra_size=1; | ||
405 | 56 | SELECT * FROM t3_small; | ||
406 | 57 | DROP TABLE t3_small; | ||
407 | 58 | |||
408 | 59 | CREATE TABLE t1(a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
409 | 60 | CREATE TABLE t1_lra(a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
410 | 61 | |||
411 | 62 | # Populate tables. | ||
412 | 63 | INSERT INTO t1 VALUES (0, REPEAT('a',256)); | ||
413 | 64 | INSERT INTO t1(b) SELECT b FROM t1; | ||
414 | 65 | INSERT INTO t1(b) SELECT b FROM t1; | ||
415 | 66 | INSERT INTO t1(b) SELECT b FROM t1; | ||
416 | 67 | INSERT INTO t1(b) SELECT b FROM t1; | ||
417 | 68 | INSERT INTO t1(b) SELECT b FROM t1; | ||
418 | 69 | INSERT INTO t1(b) SELECT b FROM t1; | ||
419 | 70 | INSERT INTO t1(b) SELECT b FROM t1; | ||
420 | 71 | INSERT INTO t1(b) SELECT b FROM t1; | ||
421 | 72 | INSERT INTO t1(b) SELECT b FROM t1; | ||
422 | 73 | INSERT INTO t1(b) SELECT b FROM t1; | ||
423 | 74 | INSERT INTO t1(b) SELECT b FROM t1; | ||
424 | 75 | INSERT INTO t1(b) SELECT b FROM t1; | ||
425 | 76 | INSERT INTO t1(b) SELECT b FROM t1; | ||
426 | 77 | INSERT INTO t1(b) SELECT b FROM t1; | ||
427 | 78 | |||
428 | 79 | INSERT INTO t1_lra SELECT * FROM t1; | ||
429 | 80 | |||
430 | 81 | --source include/restart_mysqld.inc | ||
431 | 82 | |||
432 | 83 | CHECKSUM TABLE t1; | ||
433 | 84 | |||
434 | 85 | SET SESSION innodb_lra_size=1; | ||
435 | 86 | SET SESSION innodb_lra_n_node_recs_before_sleep=128; | ||
436 | 87 | SET SESSION innodb_lra_sleep=100; | ||
437 | 88 | CHECKSUM TABLE t1_lra; | ||
438 | 89 | |||
439 | 90 | --source include/restart_mysqld.inc | ||
440 | 91 | |||
441 | 92 | DELETE FROM t1 WHERE a >= 5480 AND a < 5520; | ||
442 | 93 | DELETE FROM t1 WHERE a >= 5520 AND a < 5550; | ||
443 | 94 | |||
444 | 95 | CHECKSUM TABLE t1; | ||
445 | 96 | |||
446 | 97 | SET GLOBAL innodb_lra_test=1; | ||
447 | 98 | DELETE FROM t1_lra WHERE a >= 5480 AND a < 5520; | ||
448 | 99 | DELETE FROM t1_lra WHERE a >= 5520 AND a < 5550; | ||
449 | 100 | |||
450 | 101 | SET SESSION innodb_lra_size=1; | ||
451 | 102 | SET SESSION innodb_lra_n_node_recs_before_sleep=128; | ||
452 | 103 | SET SESSION innodb_lra_sleep=100; | ||
453 | 104 | CHECKSUM TABLE t1_lra; | ||
454 | 105 | |||
455 | 106 | DROP TABLE t1; | ||
456 | 107 | DROP TABLE t1_lra; | ||
457 | 0 | 108 | ||
458 | === added file 'mysql-test/suite/innodb/t/innodb_merge_read-master.opt' | |||
459 | --- mysql-test/suite/innodb/t/innodb_merge_read-master.opt 1970-01-01 00:00:00 +0000 | |||
460 | +++ mysql-test/suite/innodb/t/innodb_merge_read-master.opt 2014-04-23 10:58:56 +0000 | |||
461 | @@ -0,0 +1,1 @@ | |||
462 | 1 | --innodb-use-native-aio=1 | ||
463 | 0 | 2 | ||
464 | === added file 'mysql-test/suite/innodb/t/innodb_merge_read.test' | |||
465 | --- mysql-test/suite/innodb/t/innodb_merge_read.test 1970-01-01 00:00:00 +0000 | |||
466 | +++ mysql-test/suite/innodb/t/innodb_merge_read.test 2014-04-23 10:58:56 +0000 | |||
467 | @@ -0,0 +1,42 @@ | |||
468 | 1 | --source include/have_innodb.inc | ||
469 | 2 | --source include/have_native_aio.inc | ||
470 | 3 | |||
471 | 4 | --disable_warnings | ||
472 | 5 | DROP TABLE if exists t1; | ||
473 | 6 | --enable_warnings | ||
474 | 7 | |||
475 | 8 | # Create table. | ||
476 | 9 | CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256)) ENGINE=INNODB; | ||
477 | 10 | |||
478 | 11 | # Populate table. | ||
479 | 12 | INSERT INTO t1 VALUES (0, REPEAT('a',256)); | ||
480 | 13 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
481 | 14 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
482 | 15 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
483 | 16 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
484 | 17 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
485 | 18 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
486 | 19 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
487 | 20 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
488 | 21 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
489 | 22 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
490 | 23 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
491 | 24 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
492 | 25 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
493 | 26 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
494 | 27 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
495 | 28 | INSERT INTO t1 SELECT 0, b FROM t1; | ||
496 | 29 | |||
497 | 30 | --source include/restart_mysqld.inc | ||
498 | 31 | |||
499 | 32 | show global status like "innodb_buffered_aio_submitted"; | ||
500 | 33 | |||
501 | 34 | --disable_result_log | ||
502 | 35 | select * from t1; | ||
503 | 36 | --enable_result_log | ||
504 | 37 | |||
505 | 38 | select count(*) from t1; | ||
506 | 39 | |||
507 | 40 | show global status like "innodb_buffered_aio_submitted"; | ||
508 | 41 | |||
509 | 42 | DROP TABLE t1; | ||
510 | 0 | 43 | ||
511 | === added file 'mysql-test/suite/sys_vars/r/innodb_lra_n_node_recs_before_sleep_basic.result' | |||
512 | --- mysql-test/suite/sys_vars/r/innodb_lra_n_node_recs_before_sleep_basic.result 1970-01-01 00:00:00 +0000 | |||
513 | +++ mysql-test/suite/sys_vars/r/innodb_lra_n_node_recs_before_sleep_basic.result 2014-04-23 10:58:56 +0000 | |||
514 | @@ -0,0 +1,28 @@ | |||
515 | 1 | SET GLOBAL innodb_lra_n_node_recs_before_sleep = 128; | ||
516 | 2 | SELECT @@GLOBAL.innodb_lra_n_node_recs_before_sleep; | ||
517 | 3 | @@GLOBAL.innodb_lra_n_node_recs_before_sleep | ||
518 | 4 | 128 | ||
519 | 5 | SET SESSION innodb_lra_n_node_recs_before_sleep=1000000; | ||
520 | 6 | SELECT @@SESSION.innodb_lra_n_node_recs_before_sleep; | ||
521 | 7 | @@SESSION.innodb_lra_n_node_recs_before_sleep | ||
522 | 8 | 1000000 | ||
523 | 9 | SET SESSION innodb_lra_n_node_recs_before_sleep=0; | ||
524 | 10 | Warnings: | ||
525 | 11 | Warning 1292 Truncated incorrect innodb_lra_n_node_recs_before_sl value: '0' | ||
526 | 12 | SELECT @@SESSION.innodb_lra_n_node_recs_before_sleep; | ||
527 | 13 | @@SESSION.innodb_lra_n_node_recs_before_sleep | ||
528 | 14 | 128 | ||
529 | 15 | SET SESSION innodb_lra_n_node_recs_before_sleep=16384; | ||
530 | 16 | SELECT @@SESSION.innodb_lra_n_node_recs_before_sleep; | ||
531 | 17 | @@SESSION.innodb_lra_n_node_recs_before_sleep | ||
532 | 18 | 16384 | ||
533 | 19 | SET GLOBAL innodb_lra_n_node_recs_before_sleep=-1; | ||
534 | 20 | Warnings: | ||
535 | 21 | Warning 1292 Truncated incorrect innodb_lra_n_node_recs_before_sl value: '-1' | ||
536 | 22 | SELECT @@GLOBAL.innodb_lra_n_node_recs_before_sleep; | ||
537 | 23 | @@GLOBAL.innodb_lra_n_node_recs_before_sleep | ||
538 | 24 | 128 | ||
539 | 25 | SET GLOBAL innodb_lra_n_node_recs_before_sleep = default; | ||
540 | 26 | SELECT @@GLOBAL.innodb_lra_n_node_recs_before_sleep; | ||
541 | 27 | @@GLOBAL.innodb_lra_n_node_recs_before_sleep | ||
542 | 28 | 1024 | ||
543 | 0 | 29 | ||
544 | === added file 'mysql-test/suite/sys_vars/r/innodb_lra_size_basic.result' | |||
545 | --- mysql-test/suite/sys_vars/r/innodb_lra_size_basic.result 1970-01-01 00:00:00 +0000 | |||
546 | +++ mysql-test/suite/sys_vars/r/innodb_lra_size_basic.result 2014-04-23 10:58:56 +0000 | |||
547 | @@ -0,0 +1,28 @@ | |||
548 | 1 | SET GLOBAL innodb_lra_size = 128; | ||
549 | 2 | SELECT @@GLOBAL.innodb_lra_size; | ||
550 | 3 | @@GLOBAL.innodb_lra_size | ||
551 | 4 | 128 | ||
552 | 5 | SET SESSION innodb_lra_size=1000000; | ||
553 | 6 | Warnings: | ||
554 | 7 | Warning 1292 Truncated incorrect innodb_lra_size value: '1000000' | ||
555 | 8 | SELECT @@SESSION.innodb_lra_size; | ||
556 | 9 | @@SESSION.innodb_lra_size | ||
557 | 10 | 16384 | ||
558 | 11 | SET SESSION innodb_lra_size=0; | ||
559 | 12 | SELECT @@SESSION.innodb_lra_size; | ||
560 | 13 | @@SESSION.innodb_lra_size | ||
561 | 14 | 0 | ||
562 | 15 | SET SESSION innodb_lra_size=16384; | ||
563 | 16 | SELECT @@SESSION.innodb_lra_size; | ||
564 | 17 | @@SESSION.innodb_lra_size | ||
565 | 18 | 16384 | ||
566 | 19 | SET GLOBAL innodb_lra_size=-1; | ||
567 | 20 | Warnings: | ||
568 | 21 | Warning 1292 Truncated incorrect innodb_lra_size value: '-1' | ||
569 | 22 | SELECT @@GLOBAL.innodb_lra_size; | ||
570 | 23 | @@GLOBAL.innodb_lra_size | ||
571 | 24 | 0 | ||
572 | 25 | SET GLOBAL innodb_lra_size = default; | ||
573 | 26 | SELECT @@GLOBAL.innodb_lra_size; | ||
574 | 27 | @@GLOBAL.innodb_lra_size | ||
575 | 28 | 0 | ||
576 | 0 | 29 | ||
577 | === added file 'mysql-test/suite/sys_vars/r/innodb_lra_sleep_basic.result' | |||
578 | --- mysql-test/suite/sys_vars/r/innodb_lra_sleep_basic.result 1970-01-01 00:00:00 +0000 | |||
579 | +++ mysql-test/suite/sys_vars/r/innodb_lra_sleep_basic.result 2014-04-23 10:58:56 +0000 | |||
580 | @@ -0,0 +1,30 @@ | |||
581 | 1 | SET GLOBAL innodb_lra_sleep = 128; | ||
582 | 2 | SELECT @@GLOBAL.innodb_lra_sleep; | ||
583 | 3 | @@GLOBAL.innodb_lra_sleep | ||
584 | 4 | 128 | ||
585 | 5 | SET SESSION innodb_lra_sleep=1000000; | ||
586 | 6 | Warnings: | ||
587 | 7 | Warning 1292 Truncated incorrect innodb_lra_sleep value: '1000000' | ||
588 | 8 | SELECT @@SESSION.innodb_lra_sleep; | ||
589 | 9 | @@SESSION.innodb_lra_sleep | ||
590 | 10 | 1000 | ||
591 | 11 | SET SESSION innodb_lra_sleep=0; | ||
592 | 12 | SELECT @@SESSION.innodb_lra_sleep; | ||
593 | 13 | @@SESSION.innodb_lra_sleep | ||
594 | 14 | 0 | ||
595 | 15 | SET SESSION innodb_lra_sleep=16384; | ||
596 | 16 | Warnings: | ||
597 | 17 | Warning 1292 Truncated incorrect innodb_lra_sleep value: '16384' | ||
598 | 18 | SELECT @@SESSION.innodb_lra_sleep; | ||
599 | 19 | @@SESSION.innodb_lra_sleep | ||
600 | 20 | 1000 | ||
601 | 21 | SET GLOBAL innodb_lra_sleep=-1; | ||
602 | 22 | Warnings: | ||
603 | 23 | Warning 1292 Truncated incorrect innodb_lra_sleep value: '-1' | ||
604 | 24 | SELECT @@GLOBAL.innodb_lra_sleep; | ||
605 | 25 | @@GLOBAL.innodb_lra_sleep | ||
606 | 26 | 0 | ||
607 | 27 | SET GLOBAL innodb_lra_sleep = default; | ||
608 | 28 | SELECT @@GLOBAL.innodb_lra_sleep; | ||
609 | 29 | @@GLOBAL.innodb_lra_sleep | ||
610 | 30 | 50 | ||
611 | 0 | 31 | ||
612 | === added file 'mysql-test/suite/sys_vars/r/innodb_lra_test_basic.result' | |||
613 | --- mysql-test/suite/sys_vars/r/innodb_lra_test_basic.result 1970-01-01 00:00:00 +0000 | |||
614 | +++ mysql-test/suite/sys_vars/r/innodb_lra_test_basic.result 2014-04-23 10:58:56 +0000 | |||
615 | @@ -0,0 +1,8 @@ | |||
616 | 1 | set global innodb_lra_test=1; | ||
617 | 2 | select @@global.innodb_lra_test; | ||
618 | 3 | @@global.innodb_lra_test | ||
619 | 4 | 1 | ||
620 | 5 | set global innodb_lra_test=default; | ||
621 | 6 | select @@global.innodb_lra_test; | ||
622 | 7 | @@global.innodb_lra_test | ||
623 | 8 | 0 | ||
624 | 0 | 9 | ||
625 | === added file 'mysql-test/suite/sys_vars/t/innodb_lra_n_node_recs_before_sleep_basic.test' | |||
626 | --- mysql-test/suite/sys_vars/t/innodb_lra_n_node_recs_before_sleep_basic.test 1970-01-01 00:00:00 +0000 | |||
627 | +++ mysql-test/suite/sys_vars/t/innodb_lra_n_node_recs_before_sleep_basic.test 2014-04-23 10:58:56 +0000 | |||
628 | @@ -0,0 +1,14 @@ | |||
629 | 1 | --source include/have_innodb.inc | ||
630 | 2 | |||
631 | 3 | SET GLOBAL innodb_lra_n_node_recs_before_sleep = 128; | ||
632 | 4 | SELECT @@GLOBAL.innodb_lra_n_node_recs_before_sleep; | ||
633 | 5 | SET SESSION innodb_lra_n_node_recs_before_sleep=1000000; | ||
634 | 6 | SELECT @@SESSION.innodb_lra_n_node_recs_before_sleep; | ||
635 | 7 | SET SESSION innodb_lra_n_node_recs_before_sleep=0; | ||
636 | 8 | SELECT @@SESSION.innodb_lra_n_node_recs_before_sleep; | ||
637 | 9 | SET SESSION innodb_lra_n_node_recs_before_sleep=16384; | ||
638 | 10 | SELECT @@SESSION.innodb_lra_n_node_recs_before_sleep; | ||
639 | 11 | SET GLOBAL innodb_lra_n_node_recs_before_sleep=-1; | ||
640 | 12 | SELECT @@GLOBAL.innodb_lra_n_node_recs_before_sleep; | ||
641 | 13 | SET GLOBAL innodb_lra_n_node_recs_before_sleep = default; | ||
642 | 14 | SELECT @@GLOBAL.innodb_lra_n_node_recs_before_sleep; | ||
643 | 0 | 15 | ||
644 | === added file 'mysql-test/suite/sys_vars/t/innodb_lra_size_basic-master.opt' | |||
645 | --- mysql-test/suite/sys_vars/t/innodb_lra_size_basic-master.opt 1970-01-01 00:00:00 +0000 | |||
646 | +++ mysql-test/suite/sys_vars/t/innodb_lra_size_basic-master.opt 2014-04-23 10:58:56 +0000 | |||
647 | @@ -0,0 +1,1 @@ | |||
648 | 1 | --innodb-use-native-aio=1 | ||
649 | 0 | 2 | ||
650 | === added file 'mysql-test/suite/sys_vars/t/innodb_lra_size_basic.test' | |||
651 | --- mysql-test/suite/sys_vars/t/innodb_lra_size_basic.test 1970-01-01 00:00:00 +0000 | |||
652 | +++ mysql-test/suite/sys_vars/t/innodb_lra_size_basic.test 2014-04-23 10:58:56 +0000 | |||
653 | @@ -0,0 +1,14 @@ | |||
654 | 1 | --source include/have_innodb.inc | ||
655 | 2 | |||
656 | 3 | SET GLOBAL innodb_lra_size = 128; | ||
657 | 4 | SELECT @@GLOBAL.innodb_lra_size; | ||
658 | 5 | SET SESSION innodb_lra_size=1000000; | ||
659 | 6 | SELECT @@SESSION.innodb_lra_size; | ||
660 | 7 | SET SESSION innodb_lra_size=0; | ||
661 | 8 | SELECT @@SESSION.innodb_lra_size; | ||
662 | 9 | SET SESSION innodb_lra_size=16384; | ||
663 | 10 | SELECT @@SESSION.innodb_lra_size; | ||
664 | 11 | SET GLOBAL innodb_lra_size=-1; | ||
665 | 12 | SELECT @@GLOBAL.innodb_lra_size; | ||
666 | 13 | SET GLOBAL innodb_lra_size = default; | ||
667 | 14 | SELECT @@GLOBAL.innodb_lra_size; | ||
668 | 0 | 15 | ||
669 | === added file 'mysql-test/suite/sys_vars/t/innodb_lra_sleep_basic.test' | |||
670 | --- mysql-test/suite/sys_vars/t/innodb_lra_sleep_basic.test 1970-01-01 00:00:00 +0000 | |||
671 | +++ mysql-test/suite/sys_vars/t/innodb_lra_sleep_basic.test 2014-04-23 10:58:56 +0000 | |||
672 | @@ -0,0 +1,14 @@ | |||
673 | 1 | --source include/have_innodb.inc | ||
674 | 2 | |||
675 | 3 | SET GLOBAL innodb_lra_sleep = 128; | ||
676 | 4 | SELECT @@GLOBAL.innodb_lra_sleep; | ||
677 | 5 | SET SESSION innodb_lra_sleep=1000000; | ||
678 | 6 | SELECT @@SESSION.innodb_lra_sleep; | ||
679 | 7 | SET SESSION innodb_lra_sleep=0; | ||
680 | 8 | SELECT @@SESSION.innodb_lra_sleep; | ||
681 | 9 | SET SESSION innodb_lra_sleep=16384; | ||
682 | 10 | SELECT @@SESSION.innodb_lra_sleep; | ||
683 | 11 | SET GLOBAL innodb_lra_sleep=-1; | ||
684 | 12 | SELECT @@GLOBAL.innodb_lra_sleep; | ||
685 | 13 | SET GLOBAL innodb_lra_sleep = default; | ||
686 | 14 | SELECT @@GLOBAL.innodb_lra_sleep; | ||
687 | 0 | 15 | ||
688 | === added file 'mysql-test/suite/sys_vars/t/innodb_lra_test_basic-master.opt' | |||
689 | --- mysql-test/suite/sys_vars/t/innodb_lra_test_basic-master.opt 1970-01-01 00:00:00 +0000 | |||
690 | +++ mysql-test/suite/sys_vars/t/innodb_lra_test_basic-master.opt 2014-04-23 10:58:56 +0000 | |||
691 | @@ -0,0 +1,1 @@ | |||
692 | 1 | --innodb-use-native-aio=1 | ||
693 | 0 | 2 | ||
694 | === added file 'mysql-test/suite/sys_vars/t/innodb_lra_test_basic.test' | |||
695 | --- mysql-test/suite/sys_vars/t/innodb_lra_test_basic.test 1970-01-01 00:00:00 +0000 | |||
696 | +++ mysql-test/suite/sys_vars/t/innodb_lra_test_basic.test 2014-04-23 10:58:56 +0000 | |||
697 | @@ -0,0 +1,8 @@ | |||
698 | 1 | --source include/have_debug.inc | ||
699 | 2 | --source include/have_innodb.inc | ||
700 | 3 | --source include/have_native_aio.inc | ||
701 | 4 | |||
702 | 5 | set global innodb_lra_test=1; | ||
703 | 6 | select @@global.innodb_lra_test; | ||
704 | 7 | set global innodb_lra_test=default; | ||
705 | 8 | select @@global.innodb_lra_test; | ||
706 | 0 | \ No newline at end of file | 9 | \ No newline at end of file |
707 | 1 | 10 | ||
708 | === modified file 'storage/innobase/btr/btr0cur.cc' | |||
709 | --- storage/innobase/btr/btr0cur.cc 2014-03-03 17:51:33 +0000 | |||
710 | +++ storage/innobase/btr/btr0cur.cc 2014-04-23 10:58:56 +0000 | |||
711 | @@ -548,6 +548,7 @@ | |||
712 | 548 | btr_search_enabled below, and btr_search_guess_on_hash() | 548 | btr_search_enabled below, and btr_search_guess_on_hash() |
713 | 549 | will have to check it again. */ | 549 | will have to check it again. */ |
714 | 550 | && UNIV_LIKELY(btr_search_enabled) | 550 | && UNIV_LIKELY(btr_search_enabled) |
715 | 551 | && !level | ||
716 | 551 | && btr_search_guess_on_hash(index, info, tuple, mode, | 552 | && btr_search_guess_on_hash(index, info, tuple, mode, |
717 | 552 | latch_mode, cursor, | 553 | latch_mode, cursor, |
718 | 553 | has_search_latch, mtr)) { | 554 | has_search_latch, mtr)) { |
719 | 554 | 555 | ||
720 | === modified file 'storage/innobase/btr/btr0pcur.cc' | |||
721 | --- storage/innobase/btr/btr0pcur.cc 2014-03-03 17:51:33 +0000 | |||
722 | +++ storage/innobase/btr/btr0pcur.cc 2014-04-23 10:58:56 +0000 | |||
723 | @@ -227,6 +227,7 @@ | |||
724 | 227 | /*===========================*/ | 227 | /*===========================*/ |
725 | 228 | ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ | 228 | ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ |
726 | 229 | btr_pcur_t* cursor, /*!< in: detached persistent cursor */ | 229 | btr_pcur_t* cursor, /*!< in: detached persistent cursor */ |
727 | 230 | ulint level, | ||
728 | 230 | const char* file, /*!< in: file name */ | 231 | const char* file, /*!< in: file name */ |
729 | 231 | ulint line, /*!< in: line where called */ | 232 | ulint line, /*!< in: line where called */ |
730 | 232 | mtr_t* mtr) /*!< in: mtr */ | 233 | mtr_t* mtr) /*!< in: mtr */ |
731 | @@ -255,7 +256,7 @@ | |||
732 | 255 | btr_cur_open_at_index_side( | 256 | btr_cur_open_at_index_side( |
733 | 256 | cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE, | 257 | cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE, |
734 | 257 | index, latch_mode, | 258 | index, latch_mode, |
736 | 258 | btr_pcur_get_btr_cur(cursor), 0, mtr); | 259 | btr_pcur_get_btr_cur(cursor), level, mtr); |
737 | 259 | 260 | ||
738 | 260 | cursor->latch_mode = latch_mode; | 261 | cursor->latch_mode = latch_mode; |
739 | 261 | cursor->pos_state = BTR_PCUR_IS_POSITIONED; | 262 | cursor->pos_state = BTR_PCUR_IS_POSITIONED; |
740 | @@ -267,8 +268,12 @@ | |||
741 | 267 | ut_a(cursor->old_rec); | 268 | ut_a(cursor->old_rec); |
742 | 268 | ut_a(cursor->old_n_fields); | 269 | ut_a(cursor->old_n_fields); |
743 | 269 | 270 | ||
746 | 270 | if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF) | 271 | if (true |
747 | 271 | || UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) { | 272 | #ifdef UNIV_DEBUG |
748 | 273 | && !level | ||
749 | 274 | #endif | ||
750 | 275 | && (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF) | ||
751 | 276 | || UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF))) { | ||
752 | 272 | /* Try optimistic restoration. */ | 277 | /* Try optimistic restoration. */ |
753 | 273 | 278 | ||
754 | 274 | if (buf_page_optimistic_get(latch_mode, | 279 | if (buf_page_optimistic_get(latch_mode, |
755 | @@ -325,24 +330,27 @@ | |||
756 | 325 | 330 | ||
757 | 326 | /* Save the old search mode of the cursor */ | 331 | /* Save the old search mode of the cursor */ |
758 | 327 | old_mode = cursor->search_mode; | 332 | old_mode = cursor->search_mode; |
762 | 328 | 333 | if (level > 0) { | |
760 | 329 | switch (cursor->rel_pos) { | ||
761 | 330 | case BTR_PCUR_ON: | ||
763 | 331 | mode = PAGE_CUR_LE; | 334 | mode = PAGE_CUR_LE; |
774 | 332 | break; | 335 | } else { |
775 | 333 | case BTR_PCUR_AFTER: | 336 | switch (cursor->rel_pos) { |
776 | 334 | mode = PAGE_CUR_G; | 337 | case BTR_PCUR_ON: |
777 | 335 | break; | 338 | mode = PAGE_CUR_LE; |
778 | 336 | case BTR_PCUR_BEFORE: | 339 | break; |
779 | 337 | mode = PAGE_CUR_L; | 340 | case BTR_PCUR_AFTER: |
780 | 338 | break; | 341 | mode = PAGE_CUR_G; |
781 | 339 | default: | 342 | break; |
782 | 340 | ut_error; | 343 | case BTR_PCUR_BEFORE: |
783 | 341 | mode = 0; | 344 | mode = PAGE_CUR_L; |
784 | 345 | break; | ||
785 | 346 | default: | ||
786 | 347 | ut_error; | ||
787 | 348 | mode = 0; | ||
788 | 349 | } | ||
789 | 342 | } | 350 | } |
790 | 343 | 351 | ||
793 | 344 | btr_pcur_open_with_no_init_func(index, tuple, mode, latch_mode, | 352 | btr_pcur_open_with_no_init_func_low(index, tuple, mode, latch_mode, |
794 | 345 | cursor, 0, file, line, mtr); | 353 | cursor, level, 0, file, line, mtr); |
795 | 346 | 354 | ||
796 | 347 | /* Restore the old search mode */ | 355 | /* Restore the old search mode */ |
797 | 348 | cursor->search_mode = old_mode; | 356 | cursor->search_mode = old_mode; |
798 | 349 | 357 | ||
799 | === modified file 'storage/innobase/buf/buf0rea.cc' | |||
800 | --- storage/innobase/buf/buf0rea.cc 2013-10-23 08:48:28 +0000 | |||
801 | +++ storage/innobase/buf/buf0rea.cc 2014-04-23 10:58:56 +0000 | |||
802 | @@ -123,7 +123,12 @@ | |||
803 | 123 | use to stop dangling page reads from a tablespace | 123 | use to stop dangling page reads from a tablespace |
804 | 124 | which we have DISCARDed + IMPORTed back */ | 124 | which we have DISCARDed + IMPORTed back */ |
805 | 125 | ulint offset, /*!< in: page number */ | 125 | ulint offset, /*!< in: page number */ |
807 | 126 | trx_t* trx) | 126 | trx_t* trx, /*!< in: transaction object */ |
808 | 127 | ibool should_buffer) /*!< in: whether to buffer an aio request. | ||
809 | 128 | AIO read ahead uses this. If you plan to | ||
810 | 129 | use this parameter, make sure you remember | ||
811 | 130 | to call os_aio_linux_dispatch_read_array_submit | ||
812 | 131 | when you are read to commit all your requests.*/ | ||
813 | 127 | { | 132 | { |
814 | 128 | buf_page_t* bpage; | 133 | buf_page_t* bpage; |
815 | 129 | ulint wake_later; | 134 | ulint wake_later; |
816 | @@ -229,14 +234,16 @@ | |||
817 | 229 | *err = _fil_io(OS_FILE_READ | wake_later | 234 | *err = _fil_io(OS_FILE_READ | wake_later |
818 | 230 | | ignore_nonexistent_pages, | 235 | | ignore_nonexistent_pages, |
819 | 231 | sync, space, zip_size, offset, 0, zip_size, | 236 | sync, space, zip_size, offset, 0, zip_size, |
821 | 232 | bpage->zip.data, bpage, trx); | 237 | bpage->zip.data, bpage, trx, |
822 | 238 | should_buffer); | ||
823 | 233 | } else { | 239 | } else { |
824 | 234 | ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); | 240 | ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); |
825 | 235 | 241 | ||
826 | 236 | *err = _fil_io(OS_FILE_READ | wake_later | 242 | *err = _fil_io(OS_FILE_READ | wake_later |
827 | 237 | | ignore_nonexistent_pages, | 243 | | ignore_nonexistent_pages, |
828 | 238 | sync, space, 0, offset, 0, UNIV_PAGE_SIZE, | 244 | sync, space, 0, offset, 0, UNIV_PAGE_SIZE, |
830 | 239 | ((buf_block_t*) bpage)->frame, bpage, trx); | 245 | ((buf_block_t*) bpage)->frame, bpage, trx, |
831 | 246 | should_buffer); | ||
832 | 240 | } | 247 | } |
833 | 241 | 248 | ||
834 | 242 | if (sync) { | 249 | if (sync) { |
835 | @@ -395,7 +402,7 @@ | |||
836 | 395 | &err, false, | 402 | &err, false, |
837 | 396 | ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER, | 403 | ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER, |
838 | 397 | space, zip_size, FALSE, | 404 | space, zip_size, FALSE, |
840 | 398 | tablespace_version, i, trx); | 405 | tablespace_version, i, trx, FALSE); |
841 | 399 | if (err == DB_TABLESPACE_DELETED) { | 406 | if (err == DB_TABLESPACE_DELETED) { |
842 | 400 | ut_print_timestamp(stderr); | 407 | ut_print_timestamp(stderr); |
843 | 401 | fprintf(stderr, | 408 | fprintf(stderr, |
844 | @@ -459,7 +466,7 @@ | |||
845 | 459 | 466 | ||
846 | 460 | count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space, | 467 | count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space, |
847 | 461 | zip_size, FALSE, | 468 | zip_size, FALSE, |
849 | 462 | tablespace_version, offset, trx); | 469 | tablespace_version, offset, trx, FALSE); |
850 | 463 | srv_stats.buf_pool_reads.add(count); | 470 | srv_stats.buf_pool_reads.add(count); |
851 | 464 | if (err == DB_TABLESPACE_DELETED) { | 471 | if (err == DB_TABLESPACE_DELETED) { |
852 | 465 | ut_print_timestamp(stderr); | 472 | ut_print_timestamp(stderr); |
853 | @@ -507,7 +514,7 @@ | |||
854 | 507 | | OS_AIO_SIMULATED_WAKE_LATER | 514 | | OS_AIO_SIMULATED_WAKE_LATER |
855 | 508 | | BUF_READ_IGNORE_NONEXISTENT_PAGES, | 515 | | BUF_READ_IGNORE_NONEXISTENT_PAGES, |
856 | 509 | space, zip_size, FALSE, | 516 | space, zip_size, FALSE, |
858 | 510 | tablespace_version, offset, NULL); | 517 | tablespace_version, offset, NULL, FALSE); |
859 | 511 | srv_stats.buf_pool_reads.add(count); | 518 | srv_stats.buf_pool_reads.add(count); |
860 | 512 | 519 | ||
861 | 513 | /* We do not increment number of I/O operations used for LRU policy | 520 | /* We do not increment number of I/O operations used for LRU policy |
862 | @@ -584,6 +591,12 @@ | |||
863 | 584 | return(0); | 591 | return(0); |
864 | 585 | } | 592 | } |
865 | 586 | 593 | ||
866 | 594 | /* linear read ahead is disabled if user requested logical read ahead. | ||
867 | 595 | */ | ||
868 | 596 | if (trx && trx->lra_size) { | ||
869 | 597 | return(0); | ||
870 | 598 | } | ||
871 | 599 | |||
872 | 587 | low = (offset / buf_read_ahead_linear_area) | 600 | low = (offset / buf_read_ahead_linear_area) |
873 | 588 | * buf_read_ahead_linear_area; | 601 | * buf_read_ahead_linear_area; |
874 | 589 | high = (offset / buf_read_ahead_linear_area + 1) | 602 | high = (offset / buf_read_ahead_linear_area + 1) |
875 | @@ -773,7 +786,8 @@ | |||
876 | 773 | count += buf_read_page_low( | 786 | count += buf_read_page_low( |
877 | 774 | &err, false, | 787 | &err, false, |
878 | 775 | ibuf_mode, | 788 | ibuf_mode, |
880 | 776 | space, zip_size, FALSE, tablespace_version, i, trx); | 789 | space, zip_size, FALSE, tablespace_version, i, trx, |
881 | 790 | TRUE); | ||
882 | 777 | if (err == DB_TABLESPACE_DELETED) { | 791 | if (err == DB_TABLESPACE_DELETED) { |
883 | 778 | ut_print_timestamp(stderr); | 792 | ut_print_timestamp(stderr); |
884 | 779 | fprintf(stderr, | 793 | fprintf(stderr, |
885 | @@ -786,6 +800,10 @@ | |||
886 | 786 | } | 800 | } |
887 | 787 | } | 801 | } |
888 | 788 | } | 802 | } |
889 | 803 | #if defined(LINUX_NATIVE_AIO) | ||
890 | 804 | /* Tell aio to submit all buffered requests. */ | ||
891 | 805 | ut_a(os_aio_linux_dispatch_read_array_submit()); | ||
892 | 806 | #endif | ||
893 | 789 | 807 | ||
894 | 790 | /* In simulated aio we wake the aio handler threads only after | 808 | /* In simulated aio we wake the aio handler threads only after |
895 | 791 | queuing all aio requests, in native aio the following call does | 809 | queuing all aio requests, in native aio the following call does |
896 | @@ -863,7 +881,7 @@ | |||
897 | 863 | buf_read_page_low(&err, sync && (i + 1 == n_stored), | 881 | buf_read_page_low(&err, sync && (i + 1 == n_stored), |
898 | 864 | BUF_READ_ANY_PAGE, space_ids[i], | 882 | BUF_READ_ANY_PAGE, space_ids[i], |
899 | 865 | zip_size, TRUE, space_versions[i], | 883 | zip_size, TRUE, space_versions[i], |
901 | 866 | page_nos[i], NULL); | 884 | page_nos[i], NULL, FALSE); |
902 | 867 | 885 | ||
903 | 868 | if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) { | 886 | if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) { |
904 | 869 | tablespace_deleted: | 887 | tablespace_deleted: |
905 | @@ -1003,15 +1021,20 @@ | |||
906 | 1003 | if ((i + 1 == n_stored) && sync) { | 1021 | if ((i + 1 == n_stored) && sync) { |
907 | 1004 | buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space, | 1022 | buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space, |
908 | 1005 | zip_size, TRUE, tablespace_version, | 1023 | zip_size, TRUE, tablespace_version, |
910 | 1006 | page_nos[i], NULL); | 1024 | page_nos[i], NULL, FALSE); |
911 | 1007 | } else { | 1025 | } else { |
912 | 1008 | buf_read_page_low(&err, false, BUF_READ_ANY_PAGE | 1026 | buf_read_page_low(&err, false, BUF_READ_ANY_PAGE |
913 | 1009 | | OS_AIO_SIMULATED_WAKE_LATER, | 1027 | | OS_AIO_SIMULATED_WAKE_LATER, |
914 | 1010 | space, zip_size, TRUE, | 1028 | space, zip_size, TRUE, |
916 | 1011 | tablespace_version, page_nos[i], NULL); | 1029 | tablespace_version, page_nos[i], NULL, |
917 | 1030 | FALSE); | ||
918 | 1012 | } | 1031 | } |
919 | 1013 | } | 1032 | } |
920 | 1014 | 1033 | ||
921 | 1034 | #ifdef LINUX_NATIVE_AIO | ||
922 | 1035 | ut_a(os_aio_linux_dispatch_read_array_submit()); | ||
923 | 1036 | #endif | ||
924 | 1037 | |||
925 | 1015 | os_aio_simulated_wake_handler_threads(); | 1038 | os_aio_simulated_wake_handler_threads(); |
926 | 1016 | 1039 | ||
927 | 1017 | #ifdef UNIV_DEBUG | 1040 | #ifdef UNIV_DEBUG |
928 | 1018 | 1041 | ||
929 | === modified file 'storage/innobase/fil/fil0fil.cc' | |||
930 | --- storage/innobase/fil/fil0fil.cc 2014-03-05 11:54:14 +0000 | |||
931 | +++ storage/innobase/fil/fil0fil.cc 2014-04-23 10:58:56 +0000 | |||
932 | @@ -5168,7 +5168,7 @@ | |||
933 | 5168 | success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC, | 5168 | success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC, |
934 | 5169 | node->name, node->handle, buf, | 5169 | node->name, node->handle, buf, |
935 | 5170 | offset, page_size * n_pages, | 5170 | offset, page_size * n_pages, |
937 | 5171 | NULL, NULL, space_id, NULL); | 5171 | NULL, NULL, space_id, NULL, TRUE); |
938 | 5172 | #endif /* UNIV_HOTBACKUP */ | 5172 | #endif /* UNIV_HOTBACKUP */ |
939 | 5173 | if (success) { | 5173 | if (success) { |
940 | 5174 | os_has_said_disk_full = FALSE; | 5174 | os_has_said_disk_full = FALSE; |
941 | @@ -5545,7 +5545,12 @@ | |||
942 | 5545 | appropriately aligned */ | 5545 | appropriately aligned */ |
943 | 5546 | void* message, /*!< in: message for aio handler if non-sync | 5546 | void* message, /*!< in: message for aio handler if non-sync |
944 | 5547 | aio used, else ignored */ | 5547 | aio used, else ignored */ |
946 | 5548 | trx_t* trx) | 5548 | trx_t* trx, |
947 | 5549 | ibool should_buffer) /*!< in: whether to buffer an aio request. | ||
948 | 5550 | AIO read ahead uses this. If you plan to | ||
949 | 5551 | use this parameter, make sure you remember | ||
950 | 5552 | to call os_aio_linux_dispatch_read_array_submit | ||
951 | 5553 | when you are read to commit all your requests.*/ | ||
952 | 5549 | { | 5554 | { |
953 | 5550 | ulint mode; | 5555 | ulint mode; |
954 | 5551 | fil_space_t* space; | 5556 | fil_space_t* space; |
955 | @@ -5762,7 +5767,7 @@ | |||
956 | 5762 | 5767 | ||
957 | 5763 | /* Queue the aio request */ | 5768 | /* Queue the aio request */ |
958 | 5764 | ret = os_aio(type, mode | wake_later, node->name, node->handle, buf, | 5769 | ret = os_aio(type, mode | wake_later, node->name, node->handle, buf, |
960 | 5765 | offset, len, node, message, space_id, trx); | 5770 | offset, len, node, message, space_id, trx, should_buffer); |
961 | 5766 | 5771 | ||
962 | 5767 | #else | 5772 | #else |
963 | 5768 | /* In ibbackup do normal i/o, not aio */ | 5773 | /* In ibbackup do normal i/o, not aio */ |
964 | 5769 | 5774 | ||
965 | === modified file 'storage/innobase/handler/ha_innodb.cc' | |||
966 | --- storage/innobase/handler/ha_innodb.cc 2014-03-03 17:51:33 +0000 | |||
967 | +++ storage/innobase/handler/ha_innodb.cc 2014-04-23 10:58:56 +0000 | |||
968 | @@ -106,6 +106,11 @@ | |||
969 | 106 | #include "i_s.h" | 106 | #include "i_s.h" |
970 | 107 | #include "xtradb_i_s.h" | 107 | #include "xtradb_i_s.h" |
971 | 108 | 108 | ||
972 | 109 | #ifdef TARGET_OS_LINUX | ||
973 | 110 | #include <sys/syscall.h> | ||
974 | 111 | #include <sys/ioctl.h> | ||
975 | 112 | #endif /* TARGET_OS_LINUX */ | ||
976 | 113 | |||
977 | 109 | # ifndef MYSQL_PLUGIN_IMPORT | 114 | # ifndef MYSQL_PLUGIN_IMPORT |
978 | 110 | # define MYSQL_PLUGIN_IMPORT /* nothing */ | 115 | # define MYSQL_PLUGIN_IMPORT /* nothing */ |
979 | 111 | # endif /* MYSQL_PLUGIN_IMPORT */ | 116 | # endif /* MYSQL_PLUGIN_IMPORT */ |
980 | @@ -634,6 +639,30 @@ | |||
981 | 634 | "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.", | 639 | "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.", |
982 | 635 | NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0); | 640 | NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0); |
983 | 636 | 641 | ||
984 | 642 | static MYSQL_THDVAR_ULONG(lra_size, PLUGIN_VAR_OPCMDARG, | ||
985 | 643 | "The size (in MBs) of the total size of the pages that innodb will prefetch " | ||
986 | 644 | "while scanning a table during this session. This is meant to be used only " | ||
987 | 645 | "for table scans. The upper limit of this variable is 16384 which " | ||
988 | 646 | "corresponds to prefetching 16GB of data. When set to max, this algorithm " | ||
989 | 647 | "may use 100M memory.", NULL, NULL, 0, 0, 16384, 0); | ||
990 | 648 | |||
991 | 649 | static MYSQL_THDVAR_ULONG(lra_n_node_recs_before_sleep, PLUGIN_VAR_OPCMDARG, | ||
992 | 650 | "innodb_lra_n_node_recs_before_sleep is the number of node pointer records " | ||
993 | 651 | "traversed while holding the index lock before releasing the index lock " | ||
994 | 652 | "and sleeping for a short period of time so that the other threads get a " | ||
995 | 653 | "chance to x-latch the index lock. innodb_lra_sleep is the sleep time in " | ||
996 | 654 | "milliseconds.", | ||
997 | 655 | NULL, NULL, 1024, 128, ULINT_MAX, 0); | ||
998 | 656 | |||
999 | 657 | static MYSQL_THDVAR_ULONG(lra_sleep, PLUGIN_VAR_OPCMDARG, | ||
1000 | 658 | "innodb_lra_n_node_recs_before_sleep is the number of node pointer records " | ||
1001 | 659 | "traversed while holding the index lock before releasing the index lock " | ||
1002 | 660 | "and sleeping for a short period of time so that the other threads get a " | ||
1003 | 661 | "chance to x-latch the index lock. innodb_lra_sleep is the sleep time in " | ||
1004 | 662 | "milliseconds.", | ||
1005 | 663 | NULL, NULL, 50, 0, 1000, 0); | ||
1006 | 664 | |||
1007 | 665 | |||
1008 | 637 | static MYSQL_THDVAR_STR(ft_user_stopword_table, | 666 | static MYSQL_THDVAR_STR(ft_user_stopword_table, |
1009 | 638 | PLUGIN_VAR_OPCMDARG|PLUGIN_VAR_MEMALLOC, | 667 | PLUGIN_VAR_OPCMDARG|PLUGIN_VAR_MEMALLOC, |
1010 | 639 | "User supplied stopword table name, effective in the session level.", | 668 | "User supplied stopword table name, effective in the session level.", |
1011 | @@ -851,6 +880,14 @@ | |||
1012 | 851 | (char*) &export_vars.innodb_x_lock_spin_rounds, SHOW_LONGLONG}, | 880 | (char*) &export_vars.innodb_x_lock_spin_rounds, SHOW_LONGLONG}, |
1013 | 852 | {"x_lock_spin_waits", | 881 | {"x_lock_spin_waits", |
1014 | 853 | (char*) &export_vars.innodb_x_lock_spin_waits, SHOW_LONGLONG}, | 882 | (char*) &export_vars.innodb_x_lock_spin_waits, SHOW_LONGLONG}, |
1015 | 883 | {"buffered_aio_submitted", | ||
1016 | 884 | (char*) &export_vars.innodb_buffered_aio_submitted, SHOW_LONG}, | ||
1017 | 885 | {"logical_read_ahead_misses", | ||
1018 | 886 | (char*) &export_vars.innodb_logical_read_ahead_misses, SHOW_LONG}, | ||
1019 | 887 | {"logical_read_ahead_prefetched", | ||
1020 | 888 | (char*) &export_vars.innodb_logical_read_ahead_prefetched, SHOW_LONG}, | ||
1021 | 889 | {"logical_read_ahead_in_buf_pool", | ||
1022 | 890 | (char*) &export_vars.innodb_logical_read_ahead_in_buf_pool, SHOW_LONG}, | ||
1023 | 854 | {NullS, NullS, SHOW_LONG} | 891 | {NullS, NullS, SHOW_LONG} |
1024 | 855 | }; | 892 | }; |
1025 | 856 | 893 | ||
1026 | @@ -2294,6 +2331,10 @@ | |||
1027 | 2294 | thd, OPTION_RELAXED_UNIQUE_CHECKS); | 2331 | thd, OPTION_RELAXED_UNIQUE_CHECKS); |
1028 | 2295 | 2332 | ||
1029 | 2296 | trx->fake_changes = THDVAR(thd, fake_changes); | 2333 | trx->fake_changes = THDVAR(thd, fake_changes); |
1030 | 2334 | trx_lra_reset(trx, | ||
1031 | 2335 | THDVAR(thd, lra_size), | ||
1032 | 2336 | THDVAR(thd, lra_n_node_recs_before_sleep), | ||
1033 | 2337 | THDVAR(thd, lra_sleep)); | ||
1034 | 2297 | 2338 | ||
1035 | 2298 | #ifdef EXTENDED_SLOWLOG | 2339 | #ifdef EXTENDED_SLOWLOG |
1036 | 2299 | if (thd_log_slow_verbosity(thd) & (1ULL << SLOG_V_INNODB)) { | 2340 | if (thd_log_slow_verbosity(thd) & (1ULL << SLOG_V_INNODB)) { |
1037 | @@ -2326,6 +2367,10 @@ | |||
1038 | 2326 | trx = trx_allocate_for_mysql(); | 2367 | trx = trx_allocate_for_mysql(); |
1039 | 2327 | 2368 | ||
1040 | 2328 | trx->mysql_thd = thd; | 2369 | trx->mysql_thd = thd; |
1041 | 2370 | trx_lra_reset(trx, | ||
1042 | 2371 | THDVAR(thd, lra_size), | ||
1043 | 2372 | THDVAR(thd, lra_n_node_recs_before_sleep), | ||
1044 | 2373 | THDVAR(thd, lra_sleep)); | ||
1045 | 2329 | 2374 | ||
1046 | 2330 | innobase_trx_init(thd, trx); | 2375 | innobase_trx_init(thd, trx); |
1047 | 2331 | 2376 | ||
1048 | @@ -3860,6 +3905,7 @@ | |||
1049 | 3860 | /*================*/ | 3905 | /*================*/ |
1050 | 3861 | trx_t* trx) /*!< in: transaction handle */ | 3906 | trx_t* trx) /*!< in: transaction handle */ |
1051 | 3862 | { | 3907 | { |
1052 | 3908 | trx_lra_reset(trx, 0, 0, 0); | ||
1053 | 3863 | if (trx_is_started(trx)) { | 3909 | if (trx_is_started(trx)) { |
1054 | 3864 | 3910 | ||
1055 | 3865 | trx_commit_for_mysql(trx); | 3911 | trx_commit_for_mysql(trx); |
1056 | @@ -17573,6 +17619,17 @@ | |||
1057 | 17573 | "It is to create artificially the situation the purge view have been updated " | 17619 | "It is to create artificially the situation the purge view have been updated " |
1058 | 17574 | "but the each purges were not done yet.", | 17620 | "but the each purges were not done yet.", |
1059 | 17575 | NULL, NULL, FALSE); | 17621 | NULL, NULL, FALSE); |
1060 | 17622 | |||
1061 | 17623 | #ifdef UNIV_DEBUG | ||
1062 | 17624 | extern my_bool row_lra_test; | ||
1063 | 17625 | #endif | ||
1064 | 17626 | |||
1065 | 17627 | static MYSQL_SYSVAR_BOOL(lra_test, row_lra_test, | ||
1066 | 17628 | PLUGIN_VAR_NOCMDARG, | ||
1067 | 17629 | "When set to true, the purge thread stops until the logical read ahead " | ||
1068 | 17630 | "sets this variable to TRUE. Used for testing edge cases regarding the " | ||
1069 | 17631 | "purge thread and logical read ahead.", | ||
1070 | 17632 | NULL, NULL, FALSE); | ||
1071 | 17576 | #endif /* UNIV_DEBUG */ | 17633 | #endif /* UNIV_DEBUG */ |
1072 | 17577 | 17634 | ||
1073 | 17578 | const char *corrupt_table_action_names[]= | 17635 | const char *corrupt_table_action_names[]= |
1074 | @@ -17789,10 +17846,14 @@ | |||
1075 | 17789 | MYSQL_SYSVAR(trx_rseg_n_slots_debug), | 17846 | MYSQL_SYSVAR(trx_rseg_n_slots_debug), |
1076 | 17790 | MYSQL_SYSVAR(limit_optimistic_insert_debug), | 17847 | MYSQL_SYSVAR(limit_optimistic_insert_debug), |
1077 | 17791 | MYSQL_SYSVAR(trx_purge_view_update_only_debug), | 17848 | MYSQL_SYSVAR(trx_purge_view_update_only_debug), |
1078 | 17849 | MYSQL_SYSVAR(lra_test), | ||
1079 | 17792 | #endif /* UNIV_DEBUG */ | 17850 | #endif /* UNIV_DEBUG */ |
1080 | 17793 | MYSQL_SYSVAR(corrupt_table_action), | 17851 | MYSQL_SYSVAR(corrupt_table_action), |
1081 | 17794 | MYSQL_SYSVAR(fake_changes), | 17852 | MYSQL_SYSVAR(fake_changes), |
1082 | 17795 | MYSQL_SYSVAR(locking_fake_changes), | 17853 | MYSQL_SYSVAR(locking_fake_changes), |
1083 | 17854 | MYSQL_SYSVAR(lra_size), | ||
1084 | 17855 | MYSQL_SYSVAR(lra_n_node_recs_before_sleep), | ||
1085 | 17856 | MYSQL_SYSVAR(lra_sleep), | ||
1086 | 17796 | NULL | 17857 | NULL |
1087 | 17797 | }; | 17858 | }; |
1088 | 17798 | 17859 | ||
1089 | 17799 | 17860 | ||
1090 | === modified file 'storage/innobase/include/btr0pcur.h' | |||
1091 | --- storage/innobase/include/btr0pcur.h 2014-02-17 11:12:40 +0000 | |||
1092 | +++ storage/innobase/include/btr0pcur.h 2014-04-23 10:58:56 +0000 | |||
1093 | @@ -262,11 +262,12 @@ | |||
1094 | 262 | /*===========================*/ | 262 | /*===========================*/ |
1095 | 263 | ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ | 263 | ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */ |
1096 | 264 | btr_pcur_t* cursor, /*!< in: detached persistent cursor */ | 264 | btr_pcur_t* cursor, /*!< in: detached persistent cursor */ |
1097 | 265 | ulint level, | ||
1098 | 265 | const char* file, /*!< in: file name */ | 266 | const char* file, /*!< in: file name */ |
1099 | 266 | ulint line, /*!< in: line where called */ | 267 | ulint line, /*!< in: line where called */ |
1100 | 267 | mtr_t* mtr); /*!< in: mtr */ | 268 | mtr_t* mtr); /*!< in: mtr */ |
1103 | 268 | #define btr_pcur_restore_position(l,cur,mtr) \ | 269 | #define btr_pcur_restore_position(l, cur, mtr) \ |
1104 | 269 | btr_pcur_restore_position_func(l,cur,__FILE__,__LINE__,mtr) | 270 | btr_pcur_restore_position_func(l, cur, 0, __FILE__, __LINE__, mtr) |
1105 | 270 | /*********************************************************//** | 271 | /*********************************************************//** |
1106 | 271 | Gets the rel_pos field for a cursor whose position has been stored. | 272 | Gets the rel_pos field for a cursor whose position has been stored. |
1107 | 272 | @return BTR_PCUR_ON, ... */ | 273 | @return BTR_PCUR_ON, ... */ |
1108 | 273 | 274 | ||
1109 | === modified file 'storage/innobase/include/btr0pcur.ic' | |||
1110 | --- storage/innobase/include/btr0pcur.ic 2014-02-17 11:12:40 +0000 | |||
1111 | +++ storage/innobase/include/btr0pcur.ic 2014-04-23 10:58:56 +0000 | |||
1112 | @@ -448,6 +448,54 @@ | |||
1113 | 448 | cursor. */ | 448 | cursor. */ |
1114 | 449 | UNIV_INLINE | 449 | UNIV_INLINE |
1115 | 450 | void | 450 | void |
1116 | 451 | btr_pcur_open_with_no_init_func_low( | ||
1117 | 452 | /*============================*/ | ||
1118 | 453 | dict_index_t* index, /*!< in: index */ | ||
1119 | 454 | const dtuple_t* tuple, /*!< in: tuple on which search done */ | ||
1120 | 455 | ulint mode, /*!< in: PAGE_CUR_L, ...; | ||
1121 | 456 | NOTE that if the search is made using a unique | ||
1122 | 457 | prefix of a record, mode should be | ||
1123 | 458 | PAGE_CUR_LE, not PAGE_CUR_GE, as the latter | ||
1124 | 459 | may end up on the previous page of the | ||
1125 | 460 | record! */ | ||
1126 | 461 | ulint latch_mode,/*!< in: BTR_SEARCH_LEAF, ...; | ||
1127 | 462 | NOTE that if has_search_latch != 0 then | ||
1128 | 463 | we maybe do not acquire a latch on the cursor | ||
1129 | 464 | page, but assume that the caller uses his | ||
1130 | 465 | btr search latch to protect the record! */ | ||
1131 | 466 | btr_pcur_t* cursor, /*!< in: memory buffer for persistent cursor */ | ||
1132 | 467 | ulint level, | ||
1133 | 468 | ulint has_search_latch,/*!< in: latch mode the caller | ||
1134 | 469 | currently has on btr_search_latch: | ||
1135 | 470 | RW_S_LATCH, or 0 */ | ||
1136 | 471 | const char* file, /*!< in: file name */ | ||
1137 | 472 | ulint line, /*!< in: line where called */ | ||
1138 | 473 | mtr_t* mtr) /*!< in: mtr */ | ||
1139 | 474 | { | ||
1140 | 475 | btr_cur_t* btr_cursor; | ||
1141 | 476 | |||
1142 | 477 | cursor->latch_mode = latch_mode; | ||
1143 | 478 | cursor->search_mode = mode; | ||
1144 | 479 | |||
1145 | 480 | /* Search with the tree cursor */ | ||
1146 | 481 | |||
1147 | 482 | btr_cursor = btr_pcur_get_btr_cur(cursor); | ||
1148 | 483 | |||
1149 | 484 | btr_cur_search_to_nth_level(index, level, tuple, mode, latch_mode, | ||
1150 | 485 | btr_cursor, has_search_latch, | ||
1151 | 486 | file, line, mtr); | ||
1152 | 487 | cursor->pos_state = BTR_PCUR_IS_POSITIONED; | ||
1153 | 488 | |||
1154 | 489 | cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; | ||
1155 | 490 | |||
1156 | 491 | cursor->trx_if_known = NULL; | ||
1157 | 492 | } | ||
1158 | 493 | |||
1159 | 494 | /**************************************************************//** | ||
1160 | 495 | Opens an persistent cursor to an index tree without initializing the | ||
1161 | 496 | cursor. */ | ||
1162 | 497 | UNIV_INLINE | ||
1163 | 498 | void | ||
1164 | 451 | btr_pcur_open_with_no_init_func( | 499 | btr_pcur_open_with_no_init_func( |
1165 | 452 | /*============================*/ | 500 | /*============================*/ |
1166 | 453 | dict_index_t* index, /*!< in: index */ | 501 | dict_index_t* index, /*!< in: index */ |
1167 | @@ -471,23 +519,9 @@ | |||
1168 | 471 | ulint line, /*!< in: line where called */ | 519 | ulint line, /*!< in: line where called */ |
1169 | 472 | mtr_t* mtr) /*!< in: mtr */ | 520 | mtr_t* mtr) /*!< in: mtr */ |
1170 | 473 | { | 521 | { |
1188 | 474 | btr_cur_t* btr_cursor; | 522 | return btr_pcur_open_with_no_init_func_low( |
1189 | 475 | 523 | index, tuple, mode, latch_mode, cursor, | |
1190 | 476 | cursor->latch_mode = latch_mode; | 524 | 0, has_search_latch, file, line, mtr); |
1174 | 477 | cursor->search_mode = mode; | ||
1175 | 478 | |||
1176 | 479 | /* Search with the tree cursor */ | ||
1177 | 480 | |||
1178 | 481 | btr_cursor = btr_pcur_get_btr_cur(cursor); | ||
1179 | 482 | |||
1180 | 483 | btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, | ||
1181 | 484 | btr_cursor, has_search_latch, | ||
1182 | 485 | file, line, mtr); | ||
1183 | 486 | cursor->pos_state = BTR_PCUR_IS_POSITIONED; | ||
1184 | 487 | |||
1185 | 488 | cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; | ||
1186 | 489 | |||
1187 | 490 | cursor->trx_if_known = NULL; | ||
1191 | 491 | } | 525 | } |
1192 | 492 | 526 | ||
1193 | 493 | /*****************************************************************//** | 527 | /*****************************************************************//** |
1194 | 494 | 528 | ||
1195 | === modified file 'storage/innobase/include/buf0rea.h' | |||
1196 | --- storage/innobase/include/buf0rea.h 2013-10-23 08:48:28 +0000 | |||
1197 | +++ storage/innobase/include/buf0rea.h 2014-04-23 10:58:56 +0000 | |||
1198 | @@ -30,6 +30,43 @@ | |||
1199 | 30 | #include "buf0types.h" | 30 | #include "buf0types.h" |
1200 | 31 | 31 | ||
1201 | 32 | /********************************************************************//** | 32 | /********************************************************************//** |
1202 | 33 | Low-level function which reads a page asynchronously from a file to the | ||
1203 | 34 | buffer buf_pool if it is not already there, in which case does nothing. | ||
1204 | 35 | Sets the io_fix flag and sets an exclusive lock on the buffer frame. The | ||
1205 | 36 | flag is cleared and the x-lock released by an i/o-handler thread. | ||
1206 | 37 | @return 1 if a read request was queued, 0 if the page already resided | ||
1207 | 38 | in buf_pool, or if the page is in the doublewrite buffer blocks in | ||
1208 | 39 | which case it is never read into the pool, or if the tablespace does | ||
1209 | 40 | not exist or is being dropped | ||
1210 | 41 | @return 1 if read request is issued. 0 if it is not */ | ||
1211 | 42 | UNIV_INTERN | ||
1212 | 43 | ulint | ||
1213 | 44 | buf_read_page_low( | ||
1214 | 45 | /*==============*/ | ||
1215 | 46 | dberr_t* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED | ||
1216 | 47 | if we are trying to read from a non-existent | ||
1217 | 48 | tablespace, or a tablespace which is just now being | ||
1218 | 49 | dropped */ | ||
1219 | 50 | bool sync, /*!< in: TRUE if synchronous aio is desired */ | ||
1220 | 51 | ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ..., | ||
1221 | 52 | ORed to OS_AIO_SIMULATED_WAKE_LATER (see below | ||
1222 | 53 | at read-ahead functions) */ | ||
1223 | 54 | ulint space, /*!< in: space id */ | ||
1224 | 55 | ulint zip_size,/*!< in: compressed page size, or 0 */ | ||
1225 | 56 | ibool unzip, /*!< in: TRUE=request uncompressed page */ | ||
1226 | 57 | ib_int64_t tablespace_version, /*!< in: if the space memory object has | ||
1227 | 58 | this timestamp different from what we are giving here, | ||
1228 | 59 | treat the tablespace as dropped; this is a timestamp | ||
1229 | 60 | we use to stop dangling page reads from a tablespace | ||
1230 | 61 | which we have DISCARDed + IMPORTed back */ | ||
1231 | 62 | ulint offset, /*!< in: page number */ | ||
1232 | 63 | trx_t* trx, /*!< in: transaction object */ | ||
1233 | 64 | ibool should_buffer); /*!< in: whether to buffer an aio request. | ||
1234 | 65 | AIO read ahead uses this. If you plan to | ||
1235 | 66 | use this parameter, make sure you remember | ||
1236 | 67 | to call os_aio_linux_dispatch_read_array_submit | ||
1237 | 68 | when you are read to commit all your requests.*/ | ||
1238 | 69 | /********************************************************************//** | ||
1239 | 33 | High-level function which reads a page asynchronously from a file to the | 70 | High-level function which reads a page asynchronously from a file to the |
1240 | 34 | buffer buf_pool if it is not already there. Sets the io_fix flag and sets | 71 | buffer buf_pool if it is not already there. Sets the io_fix flag and sets |
1241 | 35 | an exclusive lock on the buffer frame. The flag is cleared and the x-lock | 72 | an exclusive lock on the buffer frame. The flag is cleared and the x-lock |
1242 | 36 | 73 | ||
1243 | === modified file 'storage/innobase/include/fil0fil.h' | |||
1244 | --- storage/innobase/include/fil0fil.h 2014-02-17 11:12:40 +0000 | |||
1245 | +++ storage/innobase/include/fil0fil.h 2014-04-23 10:58:56 +0000 | |||
1246 | @@ -724,7 +724,7 @@ | |||
1247 | 724 | @return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do | 724 | @return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do |
1248 | 725 | i/o on a tablespace which does not exist */ | 725 | i/o on a tablespace which does not exist */ |
1249 | 726 | #define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \ | 726 | #define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \ |
1251 | 727 | _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL) | 727 | _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL, FALSE) |
1252 | 728 | 728 | ||
1253 | 729 | UNIV_INTERN | 729 | UNIV_INTERN |
1254 | 730 | dberr_t | 730 | dberr_t |
1255 | @@ -755,7 +755,10 @@ | |||
1256 | 755 | appropriately aligned */ | 755 | appropriately aligned */ |
1257 | 756 | void* message, /*!< in: message for aio handler if non-sync | 756 | void* message, /*!< in: message for aio handler if non-sync |
1258 | 757 | aio used, else ignored */ | 757 | aio used, else ignored */ |
1260 | 758 | trx_t* trx) | 758 | trx_t* trx, |
1261 | 759 | ibool should_buffer /*!< in: whether to buffer an aio request. | ||
1262 | 760 | Only used by aio read ahead*/ | ||
1263 | 761 | ) | ||
1264 | 759 | __attribute__((nonnull(8))); | 762 | __attribute__((nonnull(8))); |
1265 | 760 | /**********************************************************************//** | 763 | /**********************************************************************//** |
1266 | 761 | Waits for an aio operation to complete. This function is used to write the | 764 | Waits for an aio operation to complete. This function is used to write the |
1267 | 762 | 765 | ||
1268 | === modified file 'storage/innobase/include/os0file.h' | |||
1269 | --- storage/innobase/include/os0file.h 2014-02-17 11:12:40 +0000 | |||
1270 | +++ storage/innobase/include/os0file.h 2014-04-23 10:58:56 +0000 | |||
1271 | @@ -321,10 +321,11 @@ | |||
1272 | 321 | pfs_os_file_close_func(file, __FILE__, __LINE__) | 321 | pfs_os_file_close_func(file, __FILE__, __LINE__) |
1273 | 322 | 322 | ||
1274 | 323 | # define os_aio(type, mode, name, file, buf, offset, \ | 323 | # define os_aio(type, mode, name, file, buf, offset, \ |
1276 | 324 | n, message1, message2, space_id, trx) \ | 324 | n, message1, message2, space_id, trx, \ |
1277 | 325 | should_buffer) \ | ||
1278 | 325 | pfs_os_aio_func(type, mode, name, file, buf, offset, \ | 326 | pfs_os_aio_func(type, mode, name, file, buf, offset, \ |
1279 | 326 | n, message1, message2, space_id, trx, \ | 327 | n, message1, message2, space_id, trx, \ |
1281 | 327 | __FILE__, __LINE__) | 328 | __FILE__, __LINE__, should_buffer) |
1282 | 328 | 329 | ||
1283 | 329 | # define os_file_read(file, buf, offset, n) \ | 330 | # define os_file_read(file, buf, offset, n) \ |
1284 | 330 | pfs_os_file_read_func(file, buf, offset, n, NULL, \ | 331 | pfs_os_file_read_func(file, buf, offset, n, NULL, \ |
1285 | @@ -371,9 +372,9 @@ | |||
1286 | 371 | # define os_file_close(file) os_file_close_func(file) | 372 | # define os_file_close(file) os_file_close_func(file) |
1287 | 372 | 373 | ||
1288 | 373 | # define os_aio(type, mode, name, file, buf, offset, n, message1, \ | 374 | # define os_aio(type, mode, name, file, buf, offset, n, message1, \ |
1290 | 374 | message2, space_id, trx) \ | 375 | message2, space_id, trx, should_buffer) \ |
1291 | 375 | os_aio_func(type, mode, name, file, buf, offset, n, \ | 376 | os_aio_func(type, mode, name, file, buf, offset, n, \ |
1293 | 376 | message1, message2, space_id, trx) | 377 | message1, message2, space_id, trx, should_buffer) |
1294 | 377 | 378 | ||
1295 | 378 | # define os_file_read(file, buf, offset, n) \ | 379 | # define os_file_read(file, buf, offset, n) \ |
1296 | 379 | os_file_read_func(file, buf, offset, n, NULL) | 380 | os_file_read_func(file, buf, offset, n, NULL) |
1297 | @@ -777,7 +778,13 @@ | |||
1298 | 777 | ulint space_id, | 778 | ulint space_id, |
1299 | 778 | trx_t* trx, | 779 | trx_t* trx, |
1300 | 779 | const char* src_file,/*!< in: file name where func invoked */ | 780 | const char* src_file,/*!< in: file name where func invoked */ |
1302 | 780 | ulint src_line);/*!< in: line where the func invoked */ | 781 | ulint src_line,/*!< in: line where the func invoked */ |
1303 | 782 | ibool should_buffer); | ||
1304 | 783 | /*!< in: Whether to buffer an aio request. | ||
1305 | 784 | AIO read ahead uses this. If you plan to | ||
1306 | 785 | use this parameter, make sure you remember | ||
1307 | 786 | to call os_aio_linux_dispatch_read_array_submit | ||
1308 | 787 | when you are read to commit all your requests.*/ | ||
1309 | 781 | /*******************************************************************//** | 788 | /*******************************************************************//** |
1310 | 782 | NOTE! Please use the corresponding macro os_file_write(), not directly | 789 | NOTE! Please use the corresponding macro os_file_write(), not directly |
1311 | 783 | this function! | 790 | this function! |
1312 | @@ -1148,7 +1155,12 @@ | |||
1313 | 1148 | aio operation); ignored if mode is | 1155 | aio operation); ignored if mode is |
1314 | 1149 | OS_AIO_SYNC */ | 1156 | OS_AIO_SYNC */ |
1315 | 1150 | ulint space_id, | 1157 | ulint space_id, |
1317 | 1151 | trx_t* trx); | 1158 | trx_t* trx, |
1318 | 1159 | ibool should_buffer); /*!< in: Whether to buffer an aio request. | ||
1319 | 1160 | AIO read ahead uses this. If you plan to | ||
1320 | 1161 | use this parameter, make sure you remember | ||
1321 | 1162 | to call os_aio_linux_dispatch_read_array_submit | ||
1322 | 1163 | when you are read to commit all your requests.*/ | ||
1323 | 1152 | /************************************************************************//** | 1164 | /************************************************************************//** |
1324 | 1153 | Wakes up all async i/o threads so that they know to exit themselves in | 1165 | Wakes up all async i/o threads so that they know to exit themselves in |
1325 | 1154 | shutdown. */ | 1166 | shutdown. */ |
1326 | @@ -1315,6 +1327,12 @@ | |||
1327 | 1315 | restart the operation. */ | 1327 | restart the operation. */ |
1328 | 1316 | ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ | 1328 | ulint* type, /*!< out: OS_FILE_WRITE or ..._READ */ |
1329 | 1317 | ulint* space_id); | 1329 | ulint* space_id); |
1330 | 1330 | /*******************************************************************//** | ||
1331 | 1331 | Submit buffered AIO requests on the given segment to the kernel. | ||
1332 | 1332 | @return TRUE on success. */ | ||
1333 | 1333 | UNIV_INTERN | ||
1334 | 1334 | ibool | ||
1335 | 1335 | os_aio_linux_dispatch_read_array_submit(); | ||
1336 | 1318 | #endif /* LINUX_NATIVE_AIO */ | 1336 | #endif /* LINUX_NATIVE_AIO */ |
1337 | 1319 | 1337 | ||
1338 | 1320 | #ifndef UNIV_NONINL | 1338 | #ifndef UNIV_NONINL |
1339 | 1321 | 1339 | ||
1340 | === modified file 'storage/innobase/include/os0file.ic' | |||
1341 | --- storage/innobase/include/os0file.ic 2013-10-23 08:48:28 +0000 | |||
1342 | +++ storage/innobase/include/os0file.ic 2014-04-23 10:58:56 +0000 | |||
1343 | @@ -213,7 +213,10 @@ | |||
1344 | 213 | ulint space_id, | 213 | ulint space_id, |
1345 | 214 | trx_t* trx, | 214 | trx_t* trx, |
1346 | 215 | const char* src_file,/*!< in: file name where func invoked */ | 215 | const char* src_file,/*!< in: file name where func invoked */ |
1348 | 216 | ulint src_line)/*!< in: line where the func invoked */ | 216 | ulint src_line,/*!< in: line where the func invoked */ |
1349 | 217 | ibool should_buffer) | ||
1350 | 218 | /*!< in: whether to buffer an aio request. | ||
1351 | 219 | Only used by aio read ahead*/ | ||
1352 | 217 | { | 220 | { |
1353 | 218 | ibool result; | 221 | ibool result; |
1354 | 219 | struct PSI_file_locker* locker = NULL; | 222 | struct PSI_file_locker* locker = NULL; |
1355 | @@ -227,7 +230,8 @@ | |||
1356 | 227 | src_file, src_line); | 230 | src_file, src_line); |
1357 | 228 | 231 | ||
1358 | 229 | result = os_aio_func(type, mode, name, file, buf, offset, | 232 | result = os_aio_func(type, mode, name, file, buf, offset, |
1360 | 230 | n, message1, message2, space_id, trx); | 233 | n, message1, message2, space_id, trx, |
1361 | 234 | should_buffer); | ||
1362 | 231 | 235 | ||
1363 | 232 | register_pfs_file_io_end(locker, n); | 236 | register_pfs_file_io_end(locker, n); |
1364 | 233 | 237 | ||
1365 | 234 | 238 | ||
1366 | === modified file 'storage/innobase/include/srv0srv.h' | |||
1367 | --- storage/innobase/include/srv0srv.h 2014-02-17 11:12:40 +0000 | |||
1368 | +++ storage/innobase/include/srv0srv.h 2014-04-23 10:58:56 +0000 | |||
1369 | @@ -129,6 +129,23 @@ | |||
1370 | 129 | ulint_ctr_1_t lock_deadlock_count; | 129 | ulint_ctr_1_t lock_deadlock_count; |
1371 | 130 | 130 | ||
1372 | 131 | ulint_ctr_1_t n_lock_max_wait_time; | 131 | ulint_ctr_1_t n_lock_max_wait_time; |
1373 | 132 | |||
1374 | 133 | /** Number of buffered aio requests submitted */ | ||
1375 | 134 | ulint_ctr_64_t n_aio_submitted; | ||
1376 | 135 | |||
1377 | 136 | /** total number of pages that logical-read-ahead missed while doing | ||
1378 | 137 | a table scan. The number is the total for all transactions that used a | ||
1379 | 138 | non-zero innodb_lra_size. */ | ||
1380 | 139 | ulint_ctr_64_t n_logical_read_ahead_misses; | ||
1381 | 140 | /** total number of pages that logical-read-ahead prefetched. The | ||
1382 | 141 | number is the total for all transactions that used a non-zero | ||
1383 | 142 | innodb_lra_size. */ | ||
1384 | 143 | ulint_ctr_64_t n_logical_read_ahead_prefetched; | ||
1385 | 144 | /** total number of pages that logical-read-ahead did not need to | ||
1386 | 145 | prefetch because these pages were already in the buffer pool. The | ||
1387 | 146 | number is the total for all transactions that used a non-zero | ||
1388 | 147 | innodb_lra_size. */ | ||
1389 | 148 | ulint_ctr_64_t n_logical_read_ahead_in_buf_pool; | ||
1390 | 132 | }; | 149 | }; |
1391 | 133 | 150 | ||
1392 | 134 | extern const char* srv_main_thread_op_info; | 151 | extern const char* srv_main_thread_op_info; |
1393 | @@ -1060,6 +1077,31 @@ | |||
1394 | 1060 | ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id | 1077 | ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id |
1395 | 1061 | - purged view's min trx_id */ | 1078 | - purged view's min trx_id */ |
1396 | 1062 | #endif /* UNIV_DEBUG */ | 1079 | #endif /* UNIV_DEBUG */ |
1397 | 1080 | ulint innodb_buffered_aio_submitted; | ||
1398 | 1081 | ulint innodb_logical_read_ahead_misses; /*!< total number of pages that | ||
1399 | 1082 | logical-read-ahead missed | ||
1400 | 1083 | during a table scan. | ||
1401 | 1084 | The number is the total for all | ||
1402 | 1085 | the transactions that used a | ||
1403 | 1086 | non-zero | ||
1404 | 1087 | innodb_lra_size. | ||
1405 | 1088 | */ | ||
1406 | 1089 | ulint innodb_logical_read_ahead_prefetched; /*!< total number of pages | ||
1407 | 1090 | that logical-read-ahead | ||
1408 | 1091 | prefetched. The number is the | ||
1409 | 1092 | total for all the transactions | ||
1410 | 1093 | that used a non-zero | ||
1411 | 1094 | innodb_lra_size. | ||
1412 | 1095 | */ | ||
1413 | 1096 | ulint innodb_logical_read_ahead_in_buf_pool; /*!< total number of pages | ||
1414 | 1097 | that logical-read-ahead did not | ||
1415 | 1098 | need to prefetch because these | ||
1416 | 1099 | pages were already in the | ||
1417 | 1100 | buffer pool. The number is the | ||
1418 | 1101 | total for all transactions that | ||
1419 | 1102 | used a non-zero | ||
1420 | 1103 | innodb_lra_size. | ||
1421 | 1104 | */ | ||
1422 | 1063 | }; | 1105 | }; |
1423 | 1064 | 1106 | ||
1424 | 1065 | /** Thread slot in the thread table. */ | 1107 | /** Thread slot in the thread table. */ |
1425 | 1066 | 1108 | ||
1426 | === modified file 'storage/innobase/include/trx0trx.h' | |||
1427 | --- storage/innobase/include/trx0trx.h 2014-02-17 11:12:40 +0000 | |||
1428 | +++ storage/innobase/include/trx0trx.h 2014-04-23 10:58:56 +0000 | |||
1429 | @@ -39,6 +39,13 @@ | |||
1430 | 39 | #include "trx0xa.h" | 39 | #include "trx0xa.h" |
1431 | 40 | #include "ut0vec.h" | 40 | #include "ut0vec.h" |
1432 | 41 | #include "fts0fts.h" | 41 | #include "fts0fts.h" |
1433 | 42 | #include "btr0types.h" | ||
1434 | 43 | |||
1435 | 44 | #ifdef TARGET_OS_LINUX | ||
1436 | 45 | #include <sys/syscall.h> | ||
1437 | 46 | #include <sys/ioctl.h> | ||
1438 | 47 | #endif /* TARGET_OS_LINUX */ | ||
1439 | 48 | |||
1440 | 42 | 49 | ||
1441 | 43 | /** Dummy session used currently in MySQL interface */ | 50 | /** Dummy session used currently in MySQL interface */ |
1442 | 44 | extern sess_t* trx_dummy_sess; | 51 | extern sess_t* trx_dummy_sess; |
1443 | @@ -135,7 +142,27 @@ | |||
1444 | 135 | #define trx_start_if_not_started_xa(t) \ | 142 | #define trx_start_if_not_started_xa(t) \ |
1445 | 136 | trx_start_if_not_started_xa_low((t)) | 143 | trx_start_if_not_started_xa_low((t)) |
1446 | 137 | #endif /* UNIV_DEBUG */ | 144 | #endif /* UNIV_DEBUG */ |
1448 | 138 | 145 | /*************************************************************//** | |
1449 | 146 | Creates or frees data structures related to logical-read-ahead. | ||
1450 | 147 | based on the value of lra_size. */ | ||
1451 | 148 | UNIV_INTERN | ||
1452 | 149 | void | ||
1453 | 150 | trx_lra_reset( | ||
1454 | 151 | trx_t* trx, /*!< in: transaction */ | ||
1455 | 152 | ulint lra_size, /*!< in: lra_size in MB. | ||
1456 | 153 | If 0, the fields that are releated | ||
1457 | 154 | to logical-read-ahead will be free'd | ||
1458 | 155 | if they were initialized. */ | ||
1459 | 156 | ulint lra_n_node_recs_before_sleep, | ||
1460 | 157 | /*!< in: lra_n_node_recs_before_sleep | ||
1461 | 158 | is the number of node pointer records | ||
1462 | 159 | traversed while holding the index lock | ||
1463 | 160 | before releasing the index lock and | ||
1464 | 161 | sleeping for a short period of time so | ||
1465 | 162 | that the other threads get a chance to | ||
1466 | 163 | x-latch the index lock. */ | ||
1467 | 164 | ulint lra_sleep); /* lra_sleep is the sleep time in | ||
1468 | 165 | milliseconds. */ | ||
1469 | 139 | /*************************************************************//** | 166 | /*************************************************************//** |
1470 | 140 | Starts the transaction if it is not yet started. */ | 167 | Starts the transaction if it is not yet started. */ |
1471 | 141 | UNIV_INTERN | 168 | UNIV_INTERN |
1472 | @@ -650,6 +677,15 @@ | |||
1473 | 650 | 677 | ||
1474 | 651 | #define TRX_MAGIC_N 91118598 | 678 | #define TRX_MAGIC_N 91118598 |
1475 | 652 | 679 | ||
1476 | 680 | /*******************************************************************//** | ||
1477 | 681 | Helper data structure to store page numbers in an internally-linked hash | ||
1478 | 682 | table. */ | ||
1479 | 683 | typedef struct page_no_holder_struct page_no_holder_t; | ||
1480 | 684 | struct page_no_holder_struct { | ||
1481 | 685 | ulint page_no; | ||
1482 | 686 | page_no_holder_t* hash; | ||
1483 | 687 | }; | ||
1484 | 688 | |||
1485 | 653 | /** The transaction handle | 689 | /** The transaction handle |
1486 | 654 | 690 | ||
1487 | 655 | Normally, there is a 1:1 relationship between a transaction handle | 691 | Normally, there is a 1:1 relationship between a transaction handle |
1488 | @@ -804,6 +840,65 @@ | |||
1489 | 804 | 150 bytes in the undo log size as then | 840 | 150 bytes in the undo log size as then |
1490 | 805 | we skip XA steps */ | 841 | we skip XA steps */ |
1491 | 806 | ulint fake_changes; | 842 | ulint fake_changes; |
1492 | 843 | ulint lra_size; /* Total size (in MBs) of the | ||
1493 | 844 | pages that will be prefetched by | ||
1494 | 845 | logical read ahead. */ | ||
1495 | 846 | ulint lra_n_pages; /* Number of pages that lra prefetches | ||
1496 | 847 | every time. This is computed using | ||
1497 | 848 | lra_size and the currently scanned | ||
1498 | 849 | table's block size */ | ||
1499 | 850 | ulint lra_space_id; /* The last space id that the scanning | ||
1500 | 851 | transaction accessed. If the scanning | ||
1501 | 852 | trx accesses multiple tables, we need | ||
1502 | 853 | to reset the data structures that lra | ||
1503 | 854 | uses. */ | ||
1504 | 855 | ulint lra_page_no; /* The last page that was visited | ||
1505 | 856 | by the trx. Used by the | ||
1506 | 857 | logical-read-ahead algorithm to | ||
1507 | 858 | determine if a new prefetch should be | ||
1508 | 859 | performed. */ | ||
1509 | 860 | hash_table_t* lra_ht1; | ||
1510 | 861 | hash_table_t* lra_ht2; /* Hash tables store the leaf page | ||
1511 | 862 | numbers for the already prefetched | ||
1512 | 863 | pages. Each hash table will typically | ||
1513 | 864 | have lra_n_pages pages and when the | ||
1514 | 865 | scanning trx visits all lra_n_pages | ||
1515 | 866 | pages in one of them, we will empty | ||
1516 | 867 | that one and prefetch another batch of | ||
1517 | 868 | lra_n_pages pages. */ | ||
1518 | 869 | hash_table_t* lra_ht; /* lra_ht points to lra_ht1 and lra_ht2 | ||
1519 | 870 | alternatingly. */ | ||
1520 | 871 | ulint lra_n_pages_since;/* number of leaf pages visited since | ||
1521 | 872 | the last prefetch operation. We require | ||
1522 | 873 | that no prefetch be done until the | ||
1523 | 874 | scanning trx scans lra_n_pages pages. | ||
1524 | 875 | */ | ||
1525 | 876 | ulint* lra_sort_arr; /* Array used for sorting the page | ||
1526 | 877 | numbers before issuing the read | ||
1527 | 878 | requests */ | ||
1528 | 879 | page_no_holder_t* lra_arr1; /* Pre-allocated array of | ||
1529 | 880 | page_no_holder objects which are used | ||
1530 | 881 | by the logical-read-ahead algorithm for | ||
1531 | 882 | lra_ht1. */ | ||
1532 | 883 | page_no_holder_t* lra_arr2; /* Pre-allocated array of | ||
1533 | 884 | page_no_holder objects which are used | ||
1534 | 885 | by the logical-read-ahead algorithm for | ||
1535 | 886 | lra_ht2. */ | ||
1536 | 887 | btr_pcur_t* lra_cur; /* The persistent cursor that points | ||
1537 | 888 | to the first node pointer record for | ||
1538 | 889 | which the associated leaf page is not | ||
1539 | 890 | prefetched by LRA. */ | ||
1540 | 891 | ulint lra_n_node_recs_before_sleep; | ||
1541 | 892 | /* lra_n_node_recs_before_sleep | ||
1542 | 893 | is the number of node pointer records | ||
1543 | 894 | traversed while holding the index lock | ||
1544 | 895 | before releasing the index lock and | ||
1545 | 896 | sleeping for a short period of time so | ||
1546 | 897 | that the other threads get a chance to | ||
1547 | 898 | x-latch the index lock. */ | ||
1548 | 899 | ulint lra_sleep; /* lra_sleep is the sleep time in | ||
1549 | 900 | milliseconds. */ | ||
1550 | 901 | ulint lra_tree_height; | ||
1551 | 807 | ulint flush_log_later;/* In 2PC, we hold the | 902 | ulint flush_log_later;/* In 2PC, we hold the |
1552 | 808 | prepare_commit mutex across | 903 | prepare_commit mutex across |
1553 | 809 | both phases. In that case, we | 904 | both phases. In that case, we |
1554 | 810 | 905 | ||
1555 | === modified file 'storage/innobase/os/os0file.cc' | |||
1556 | --- storage/innobase/os/os0file.cc 2014-03-03 17:51:33 +0000 | |||
1557 | +++ storage/innobase/os/os0file.cc 2014-04-23 10:58:56 +0000 | |||
1558 | @@ -245,6 +245,16 @@ | |||
1559 | 245 | There is one such event for each | 245 | There is one such event for each |
1560 | 246 | possible pending IO. The size of the | 246 | possible pending IO. The size of the |
1561 | 247 | array is equal to n_slots. */ | 247 | array is equal to n_slots. */ |
1562 | 248 | struct iocb** pending; | ||
1563 | 249 | /* Array to buffer the not-submitted aio | ||
1564 | 250 | requests. The array length is n_slots. | ||
1565 | 251 | It is divided into n_segments segments. | ||
1566 | 252 | pending requests on each segment are buffered | ||
1567 | 253 | separately.*/ | ||
1568 | 254 | ulint* count; | ||
1569 | 255 | /* Array of length n_segments. Each element | ||
1570 | 256 | counts the number of not-submitted aio request | ||
1571 | 257 | on that segment.*/ | ||
1572 | 248 | #endif /* LINUX_NATIV_AIO */ | 258 | #endif /* LINUX_NATIV_AIO */ |
1573 | 249 | }; | 259 | }; |
1574 | 250 | 260 | ||
1575 | @@ -3926,6 +3936,13 @@ | |||
1576 | 3926 | memset(io_event, 0x0, sizeof(*io_event) * n); | 3936 | memset(io_event, 0x0, sizeof(*io_event) * n); |
1577 | 3927 | array->aio_events = io_event; | 3937 | array->aio_events = io_event; |
1578 | 3928 | 3938 | ||
1579 | 3939 | array->pending = static_cast<struct iocb**>( | ||
1580 | 3940 | ut_malloc(n * sizeof(struct iocb*))); | ||
1581 | 3941 | memset(array->pending, 0x0, sizeof(struct iocb*) * n); | ||
1582 | 3942 | array->count = static_cast<ulint*>( | ||
1583 | 3943 | ut_malloc(n_segments * sizeof(ulint))); | ||
1584 | 3944 | memset(array->count, 0x0, sizeof(ulint) * n_segments); | ||
1585 | 3945 | |||
1586 | 3929 | skip_native_aio: | 3946 | skip_native_aio: |
1587 | 3930 | #endif /* LINUX_NATIVE_AIO */ | 3947 | #endif /* LINUX_NATIVE_AIO */ |
1588 | 3931 | for (ulint i = 0; i < n; i++) { | 3948 | for (ulint i = 0; i < n; i++) { |
1589 | @@ -3982,6 +3999,8 @@ | |||
1590 | 3982 | if (srv_use_native_aio) { | 3999 | if (srv_use_native_aio) { |
1591 | 3983 | ut_free(array->aio_events); | 4000 | ut_free(array->aio_events); |
1592 | 3984 | ut_free(array->aio_ctx); | 4001 | ut_free(array->aio_ctx); |
1593 | 4002 | ut_free(array->pending); | ||
1594 | 4003 | ut_free(array->count); | ||
1595 | 3985 | } | 4004 | } |
1596 | 3986 | #endif /* LINUX_NATIVE_AIO */ | 4005 | #endif /* LINUX_NATIVE_AIO */ |
1597 | 3987 | 4006 | ||
1598 | @@ -4605,6 +4624,49 @@ | |||
1599 | 4605 | 4624 | ||
1600 | 4606 | #if defined(LINUX_NATIVE_AIO) | 4625 | #if defined(LINUX_NATIVE_AIO) |
1601 | 4607 | /*******************************************************************//** | 4626 | /*******************************************************************//** |
1602 | 4627 | Submit buffered AIO requests on the given segment to the kernel. | ||
1603 | 4628 | @return TRUE on success. */ | ||
1604 | 4629 | UNIV_INTERN | ||
1605 | 4630 | ibool | ||
1606 | 4631 | os_aio_linux_dispatch_read_array_submit() | ||
1607 | 4632 | { | ||
1608 | 4633 | os_aio_array_t* array = os_aio_read_array; | ||
1609 | 4634 | ulint total_submitted = 0; | ||
1610 | 4635 | ulint total_count = 0; | ||
1611 | 4636 | if (!srv_use_native_aio) { | ||
1612 | 4637 | return TRUE; | ||
1613 | 4638 | } | ||
1614 | 4639 | os_mutex_enter(array->mutex); | ||
1615 | 4640 | /* Submit aio requests buffered on all segments. */ | ||
1616 | 4641 | for (ulint i = 0; i < array->n_segments; i++) { | ||
1617 | 4642 | ulint count = array->count[i]; | ||
1618 | 4643 | if (count > 0) { | ||
1619 | 4644 | ulint iocb_index = i * array->n_slots | ||
1620 | 4645 | / array->n_segments; | ||
1621 | 4646 | total_count += count; | ||
1622 | 4647 | total_submitted += io_submit(array->aio_ctx[i], count, | ||
1623 | 4648 | &(array->pending[iocb_index])); | ||
1624 | 4649 | } | ||
1625 | 4650 | } | ||
1626 | 4651 | /* Reset the aio request buffer. */ | ||
1627 | 4652 | memset(array->pending, 0x0, | ||
1628 | 4653 | sizeof(struct iocb*) * array->n_slots); | ||
1629 | 4654 | memset(array->count, 0x0, sizeof(ulint) * array->n_segments); | ||
1630 | 4655 | os_mutex_exit(array->mutex); | ||
1631 | 4656 | |||
1632 | 4657 | srv_stats.n_aio_submitted.add(total_count); | ||
1633 | 4658 | |||
1634 | 4659 | /* io_submit returns number of successfully | ||
1635 | 4660 | queued requests or -errno. */ | ||
1636 | 4661 | if (UNIV_UNLIKELY(total_count != total_submitted)) { | ||
1637 | 4662 | errno = -total_submitted; | ||
1638 | 4663 | return(FALSE); | ||
1639 | 4664 | } | ||
1640 | 4665 | |||
1641 | 4666 | return(TRUE); | ||
1642 | 4667 | } | ||
1643 | 4668 | |||
1644 | 4669 | /*******************************************************************//** | ||
1645 | 4608 | Dispatch an AIO request to the kernel. | 4670 | Dispatch an AIO request to the kernel. |
1646 | 4609 | @return TRUE on success. */ | 4671 | @return TRUE on success. */ |
1647 | 4610 | static | 4672 | static |
1648 | @@ -4612,24 +4674,46 @@ | |||
1649 | 4612 | os_aio_linux_dispatch( | 4674 | os_aio_linux_dispatch( |
1650 | 4613 | /*==================*/ | 4675 | /*==================*/ |
1651 | 4614 | os_aio_array_t* array, /*!< in: io request array. */ | 4676 | os_aio_array_t* array, /*!< in: io request array. */ |
1653 | 4615 | os_aio_slot_t* slot) /*!< in: an already reserved slot. */ | 4677 | os_aio_slot_t* slot, /*!< in: an already reserved slot. */ |
1654 | 4678 | ibool should_buffer) /*!< in: should buffer the request | ||
1655 | 4679 | rather than submit. */ | ||
1656 | 4616 | { | 4680 | { |
1657 | 4617 | int ret; | 4681 | int ret; |
1659 | 4618 | ulint io_ctx_index; | 4682 | ulint io_ctx_index = 0; |
1660 | 4619 | struct iocb* iocb; | 4683 | struct iocb* iocb; |
1661 | 4684 | ulint slots_per_segment; | ||
1662 | 4620 | 4685 | ||
1664 | 4621 | ut_ad(slot != NULL); | 4686 | ut_ad(slot); |
1665 | 4622 | ut_ad(array); | 4687 | ut_ad(array); |
1666 | 4623 | |||
1667 | 4624 | ut_a(slot->reserved); | 4688 | ut_a(slot->reserved); |
1668 | 4625 | 4689 | ||
1669 | 4626 | /* Find out what we are going to work with. | 4690 | /* Find out what we are going to work with. |
1670 | 4627 | The iocb struct is directly in the slot. | 4691 | The iocb struct is directly in the slot. |
1671 | 4628 | The io_context is one per segment. */ | 4692 | The io_context is one per segment. */ |
1672 | 4629 | 4693 | ||
1673 | 4694 | slots_per_segment = array->n_slots / array->n_segments; | ||
1674 | 4630 | iocb = &slot->control; | 4695 | iocb = &slot->control; |
1677 | 4631 | io_ctx_index = (slot->pos * array->n_segments) / array->n_slots; | 4696 | io_ctx_index = slot->pos / slots_per_segment; |
1678 | 4632 | 4697 | if (should_buffer) { | |
1679 | 4698 | ulint n; | ||
1680 | 4699 | os_mutex_enter(array->mutex); | ||
1681 | 4700 | /* There are array->n_slots elements in array->pending, | ||
1682 | 4701 | which is divided into array->n_segments area of equal size. | ||
1683 | 4702 | The iocb of each segment are buffered in its corresponding area | ||
1684 | 4703 | in the pending array consecutively as they come. | ||
1685 | 4704 | array->count[i] records the number of buffered aio requests | ||
1686 | 4705 | in the ith segment.*/ | ||
1687 | 4706 | n = io_ctx_index * slots_per_segment | ||
1688 | 4707 | + array->count[io_ctx_index]; | ||
1689 | 4708 | array->pending[n] = iocb; | ||
1690 | 4709 | array->count[io_ctx_index] ++; | ||
1691 | 4710 | os_mutex_exit(array->mutex); | ||
1692 | 4711 | if (array->count[io_ctx_index] == slots_per_segment) { | ||
1693 | 4712 | return os_aio_linux_dispatch_read_array_submit(); | ||
1694 | 4713 | } | ||
1695 | 4714 | return(TRUE); | ||
1696 | 4715 | } | ||
1697 | 4716 | /* Submit the given request. */ | ||
1698 | 4633 | ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb); | 4717 | ret = io_submit(array->aio_ctx[io_ctx_index], 1, &iocb); |
1699 | 4634 | 4718 | ||
1700 | 4635 | #if defined(UNIV_AIO_DEBUG) | 4719 | #if defined(UNIV_AIO_DEBUG) |
1701 | @@ -4689,7 +4773,12 @@ | |||
1702 | 4689 | aio operation); ignored if mode is | 4773 | aio operation); ignored if mode is |
1703 | 4690 | OS_AIO_SYNC */ | 4774 | OS_AIO_SYNC */ |
1704 | 4691 | ulint space_id, | 4775 | ulint space_id, |
1706 | 4692 | trx_t* trx) | 4776 | trx_t* trx, |
1707 | 4777 | ibool should_buffer) /*!< in: Whether to buffer an aio request. | ||
1708 | 4778 | AIO read ahead uses this. If you plan to | ||
1709 | 4779 | use this parameter, make sure you remember | ||
1710 | 4780 | to call os_aio_linux_dispatch_read_array_submit | ||
1711 | 4781 | when you are read to commit all your requests.*/ | ||
1712 | 4693 | { | 4782 | { |
1713 | 4694 | os_aio_array_t* array; | 4783 | os_aio_array_t* array; |
1714 | 4695 | os_aio_slot_t* slot; | 4784 | os_aio_slot_t* slot; |
1715 | @@ -4802,7 +4891,8 @@ | |||
1716 | 4802 | &(slot->control)); | 4891 | &(slot->control)); |
1717 | 4803 | 4892 | ||
1718 | 4804 | #elif defined(LINUX_NATIVE_AIO) | 4893 | #elif defined(LINUX_NATIVE_AIO) |
1720 | 4805 | if (!os_aio_linux_dispatch(array, slot)) { | 4894 | if (!os_aio_linux_dispatch(array, slot, |
1721 | 4895 | should_buffer)) { | ||
1722 | 4806 | goto err_exit; | 4896 | goto err_exit; |
1723 | 4807 | } | 4897 | } |
1724 | 4808 | #endif /* WIN_ASYNC_IO */ | 4898 | #endif /* WIN_ASYNC_IO */ |
1725 | @@ -4822,7 +4912,7 @@ | |||
1726 | 4822 | &(slot->control)); | 4912 | &(slot->control)); |
1727 | 4823 | 4913 | ||
1728 | 4824 | #elif defined(LINUX_NATIVE_AIO) | 4914 | #elif defined(LINUX_NATIVE_AIO) |
1730 | 4825 | if (!os_aio_linux_dispatch(array, slot)) { | 4915 | if (!os_aio_linux_dispatch(array, slot, FALSE)) { |
1731 | 4826 | goto err_exit; | 4916 | goto err_exit; |
1732 | 4827 | } | 4917 | } |
1733 | 4828 | #endif /* WIN_ASYNC_IO */ | 4918 | #endif /* WIN_ASYNC_IO */ |
1734 | 4829 | 4919 | ||
1735 | === modified file 'storage/innobase/row/row0purge.cc' | |||
1736 | --- storage/innobase/row/row0purge.cc 2013-06-20 15:16:00 +0000 | |||
1737 | +++ storage/innobase/row/row0purge.cc 2014-04-23 10:58:56 +0000 | |||
1738 | @@ -187,6 +187,10 @@ | |||
1739 | 187 | return(success); | 187 | return(success); |
1740 | 188 | } | 188 | } |
1741 | 189 | 189 | ||
1742 | 190 | #ifdef UNIV_DEBUG | ||
1743 | 191 | extern my_bool row_lra_test; | ||
1744 | 192 | #endif | ||
1745 | 193 | |||
1746 | 190 | /***********************************************************//** | 194 | /***********************************************************//** |
1747 | 191 | Removes a clustered index record if it has not been modified after the delete | 195 | Removes a clustered index record if it has not been modified after the delete |
1748 | 192 | marking. | 196 | marking. |
1749 | @@ -203,6 +207,11 @@ | |||
1750 | 203 | return(true); | 207 | return(true); |
1751 | 204 | } | 208 | } |
1752 | 205 | 209 | ||
1753 | 210 | #ifdef UNIV_DEBUG | ||
1754 | 211 | while (row_lra_test) { | ||
1755 | 212 | os_thread_sleep(300000); | ||
1756 | 213 | } | ||
1757 | 214 | #endif | ||
1758 | 206 | for (ulint n_tries = 0; | 215 | for (ulint n_tries = 0; |
1759 | 207 | n_tries < BTR_CUR_RETRY_DELETE_N_TIMES; | 216 | n_tries < BTR_CUR_RETRY_DELETE_N_TIMES; |
1760 | 208 | n_tries++) { | 217 | n_tries++) { |
1761 | 209 | 218 | ||
1762 | === modified file 'storage/innobase/row/row0sel.cc' | |||
1763 | --- storage/innobase/row/row0sel.cc 2014-03-03 17:51:33 +0000 | |||
1764 | +++ storage/innobase/row/row0sel.cc 2014-04-23 10:58:56 +0000 | |||
1765 | @@ -60,6 +60,8 @@ | |||
1766 | 60 | #include "srv0start.h" | 60 | #include "srv0start.h" |
1767 | 61 | #include "m_string.h" /* for my_sys.h */ | 61 | #include "m_string.h" /* for my_sys.h */ |
1768 | 62 | #include "my_sys.h" /* DEBUG_SYNC_C */ | 62 | #include "my_sys.h" /* DEBUG_SYNC_C */ |
1769 | 63 | #include "ut0sort.h" | ||
1770 | 64 | #include <algorithm> | ||
1771 | 63 | 65 | ||
1772 | 64 | #include "my_compare.h" /* enum icp_result */ | 66 | #include "my_compare.h" /* enum icp_result */ |
1773 | 65 | 67 | ||
1774 | @@ -3632,6 +3634,318 @@ | |||
1775 | 3632 | return(result); | 3634 | return(result); |
1776 | 3633 | } | 3635 | } |
1777 | 3634 | 3636 | ||
1778 | 3637 | /**********************************************************************//** | ||
1779 | 3638 | Determines the page numbers for the next batch of pages that will be | ||
1780 | 3639 | prefetched for logical read ahead and stores them in the hash_table and | ||
1781 | 3640 | page_no_array. Does not issue read requests. */ | ||
1782 | 3641 | static | ||
1783 | 3642 | void | ||
1784 | 3643 | row_read_ahead_logical_low( | ||
1785 | 3644 | hash_table_t* hash_table, /* in/out: This hash table is emptied and | ||
1786 | 3645 | then filled with the next batch of page | ||
1787 | 3646 | numbers that should be prefetched. */ | ||
1788 | 3647 | ulint* n_prefetched_ptr, /* in/out: the number that's pointed by | ||
1789 | 3648 | this pointer is incremented by the number | ||
1790 | 3649 | of pages that are added to the hash_table */ | ||
1791 | 3650 | ulint* page_no_array, /* out: the page numbers that will be | ||
1792 | 3651 | prefetched are stored in this array */ | ||
1793 | 3652 | dict_index_t* index, /* in: index object for the table */ | ||
1794 | 3653 | mtr_t* mtr, /* in: mini transaction object used for | ||
1795 | 3654 | acquiring and releasing the necessary locks */ | ||
1796 | 3655 | ulint* offsets, /* in/out: temporary storage for offsets */ | ||
1797 | 3656 | mem_heap_t* heap, /* in: temporary memory heap */ | ||
1798 | 3657 | trx_t *trx) | ||
1799 | 3658 | { | ||
1800 | 3659 | page_no_holder_t* page_no_holder; | ||
1801 | 3660 | page_no_holder_t* lra_arr; | ||
1802 | 3661 | ulint page_no; | ||
1803 | 3662 | ulint n_prefetched = 0; | ||
1804 | 3663 | rec_t* rec; | ||
1805 | 3664 | /* empty the hash table because we don't want it to grow to hold | ||
1806 | 3665 | all leaf page numbers of the table. The concern is not memory, but | ||
1807 | 3666 | the lookup time. */ | ||
1808 | 3667 | hash_table_clear(hash_table); | ||
1809 | 3668 | if (hash_table == trx->lra_ht1) { | ||
1810 | 3669 | lra_arr = trx->lra_arr1; | ||
1811 | 3670 | } else { | ||
1812 | 3671 | lra_arr = trx->lra_arr2; | ||
1813 | 3672 | } | ||
1814 | 3673 | while (!btr_pcur_is_after_last_in_tree(trx->lra_cur, mtr) | ||
1815 | 3674 | && n_prefetched < trx->lra_n_pages) { | ||
1816 | 3675 | if (UNIV_UNLIKELY(trx_is_interrupted(trx))) { | ||
1817 | 3676 | return; | ||
1818 | 3677 | } | ||
1819 | 3678 | rec = btr_pcur_get_rec(trx->lra_cur); | ||
1820 | 3679 | if (page_rec_is_supremum(rec) || page_rec_is_infimum(rec)) { | ||
1821 | 3680 | btr_pcur_move_to_next(trx->lra_cur, mtr); | ||
1822 | 3681 | continue; | ||
1823 | 3682 | } | ||
1824 | 3683 | offsets = rec_get_offsets(rec, index, offsets, | ||
1825 | 3684 | ULINT_UNDEFINED, &heap); | ||
1826 | 3685 | page_no = btr_node_ptr_get_child_page_no(rec, offsets); | ||
1827 | 3686 | page_no_holder = &lra_arr[n_prefetched]; | ||
1828 | 3687 | page_no_holder->page_no = page_no; | ||
1829 | 3688 | page_no_holder->hash = NULL; | ||
1830 | 3689 | HASH_INSERT(page_no_holder_t, hash, hash_table, | ||
1831 | 3690 | page_no, page_no_holder); | ||
1832 | 3691 | btr_pcur_move_to_next(trx->lra_cur, mtr); | ||
1833 | 3692 | page_no_array[n_prefetched] = page_no; | ||
1834 | 3693 | ++n_prefetched; | ||
1835 | 3694 | if (trx->lra_n_node_recs_before_sleep | ||
1836 | 3695 | && trx->lra_sleep | ||
1837 | 3696 | && | ||
1838 | 3697 | ((n_prefetched % trx->lra_n_node_recs_before_sleep) == 0)) | ||
1839 | 3698 | { | ||
1840 | 3699 | btr_pcur_store_position(trx->lra_cur, mtr); | ||
1841 | 3700 | mtr_commit(mtr); | ||
1842 | 3701 | os_thread_sleep(trx->lra_sleep * 1000); | ||
1843 | 3702 | mtr_start(mtr); | ||
1844 | 3703 | btr_pcur_restore_position_func( | ||
1845 | 3704 | BTR_SEARCH_LEAF, trx->lra_cur, 1, | ||
1846 | 3705 | __FILE__, __LINE__, mtr); | ||
1847 | 3706 | } | ||
1848 | 3707 | } | ||
1849 | 3708 | *n_prefetched_ptr += n_prefetched; | ||
1850 | 3709 | } | ||
1851 | 3710 | |||
1852 | 3711 | /*********************************************************************//** | ||
1853 | 3712 | Returns TRUE if the page specified by page_no was prefetched. | ||
1854 | 3713 | @return: TRUE if the page was prefetched before. */ | ||
1855 | 3714 | UNIV_INLINE | ||
1856 | 3715 | ibool | ||
1857 | 3716 | row_lra_is_prefetched( | ||
1858 | 3717 | const trx_t* trx, /* in: trx->lra_ht1 and trx->lra_ht2 are | ||
1859 | 3718 | probed to see if page page_no was prefetched */ | ||
1860 | 3719 | ulint page_no) /* in: page no for the page that is being checked */ | ||
1861 | 3720 | { | ||
1862 | 3721 | page_no_holder_t* page_no_holder = NULL; | ||
1863 | 3722 | hash_table_t* other_table; | ||
1864 | 3723 | HASH_SEARCH(hash, trx->lra_ht, page_no, page_no_holder_t*, | ||
1865 | 3724 | page_no_holder, ut_a(1), | ||
1866 | 3725 | page_no_holder->page_no == page_no); | ||
1867 | 3726 | if (page_no_holder) { | ||
1868 | 3727 | return TRUE; | ||
1869 | 3728 | } | ||
1870 | 3729 | other_table = trx->lra_ht == trx->lra_ht1 ? trx->lra_ht2 | ||
1871 | 3730 | : trx->lra_ht1; | ||
1872 | 3731 | HASH_SEARCH(hash, other_table, page_no, page_no_holder_t*, | ||
1873 | 3732 | page_no_holder, ut_a(1), | ||
1874 | 3733 | page_no_holder->page_no == page_no); | ||
1875 | 3734 | if (page_no_holder) { | ||
1876 | 3735 | return TRUE; | ||
1877 | 3736 | } | ||
1878 | 3737 | return FALSE; | ||
1879 | 3738 | } | ||
1880 | 3739 | |||
1881 | 3740 | #ifdef UNIV_DEBUG | ||
1882 | 3741 | my_bool row_lra_test = FALSE; | ||
1883 | 3742 | #endif | ||
1884 | 3743 | |||
1885 | 3744 | /*********************************************************************//** | ||
1886 | 3745 | This function submits io requests for pages that are logical successors to | ||
1887 | 3746 | the page that is pointed by pcur. It is meant to be called during sequential | ||
1888 | 3747 | scan to prefetch pages and speed-up the scan. The number of pages that are | ||
1889 | 3748 | prefetched is determined by the session variable innodb_logical_readahead_size | ||
1890 | 3749 | divided by the block size of the table. It is ok to call this function | ||
1891 | 3750 | successively even if pcur did not move to the next page because this function | ||
1892 | 3751 | keeps track of the page numbers it prefetched and won't duplicate io requests. | ||
1893 | 3752 | This function may temporarily release the block latches held by pcur and | ||
1894 | 3753 | re-acquire them. | ||
1895 | 3754 | @return: TRUE if the function released the block latch and re-acquired it and | ||
1896 | 3755 | now the cursor pcur points to a new record that must be processed by the | ||
1897 | 3756 | caller. */ | ||
1898 | 3757 | static | ||
1899 | 3758 | ibool | ||
1900 | 3759 | row_read_ahead_logical( | ||
1901 | 3760 | btr_pcur_t* pcur, /* in/out: Cursor from which the current page | ||
1902 | 3761 | number is obtained. Cursor's position may change | ||
1903 | 3762 | and this is indicated in the return value. */ | ||
1904 | 3763 | dict_index_t* index, /* in: index object for the table */ | ||
1905 | 3764 | mtr_t* mtr, /* in: mini-transaction. May be committed and | ||
1906 | 3765 | restarted */ | ||
1907 | 3766 | ulint* offsets, /* in: temporary storage for offsets */ | ||
1908 | 3767 | mem_heap_t** heap_ptr, /* in/out: If *heap_ptr is not NULL then this | ||
1909 | 3768 | heap is used for memory allocations, otherwise | ||
1910 | 3769 | a new heap is created and stored in *heap_ptr. | ||
1911 | 3770 | The caller is responsible for freeing the heap */ | ||
1912 | 3771 | trx_t *trx) | ||
1913 | 3772 | { | ||
1914 | 3773 | buf_block_t* block = btr_cur_get_block(&pcur->btr_cur); | ||
1915 | 3774 | ibool same_user_rec; | ||
1916 | 3775 | mem_heap_t* heap; | ||
1917 | 3776 | ib_int64_t tablespace_version; | ||
1918 | 3777 | ulint page_no = buf_block_get_page_no(block); | ||
1919 | 3778 | ulint space = buf_block_get_space(block); | ||
1920 | 3779 | ulint zip_size = buf_block_get_zip_size(block); | ||
1921 | 3780 | rec_t* rec; | ||
1922 | 3781 | dtuple_t* tuple; | ||
1923 | 3782 | dberr_t err; | ||
1924 | 3783 | ulint num_prefetched = 0; | ||
1925 | 3784 | ulint num_read_requests = 0; | ||
1926 | 3785 | ulint i; | ||
1927 | 3786 | ulint root_page_no; | ||
1928 | 3787 | buf_block_t* root_block; | ||
1929 | 3788 | |||
1930 | 3789 | if (!trx->lra_size) { | ||
1931 | 3790 | return FALSE; | ||
1932 | 3791 | } | ||
1933 | 3792 | if (trx->lra_space_id == space && trx->lra_tree_height <= 1) { | ||
1934 | 3793 | return FALSE; | ||
1935 | 3794 | } | ||
1936 | 3795 | if (trx->lra_space_id == space && trx->lra_page_no == page_no) { | ||
1937 | 3796 | /* the cursor is on the same page as the last time this | ||
1938 | 3797 | function was called. */ | ||
1939 | 3798 | return FALSE; | ||
1940 | 3799 | } | ||
1941 | 3800 | |||
1942 | 3801 | /* Set the last page number to page_no only if we are scanning the | ||
1943 | 3802 | same table. */ | ||
1944 | 3803 | if (trx->lra_space_id == space) { | ||
1945 | 3804 | trx->lra_page_no = page_no; | ||
1946 | 3805 | } | ||
1947 | 3806 | |||
1948 | 3807 | /* In order not to prefetch extraneously, we do not issue prefetches | ||
1949 | 3808 | until the scan processes lra_n_pages pages. This may cause misses if | ||
1950 | 3809 | there are too many splits/merges going on but in such a case it | ||
1951 | 3810 | would be hard to guess which pages to prefetch anyway | ||
1952 | 3811 | because it is equivalent to guessing which pages would split | ||
1953 | 3812 | (or merge). */ | ||
1954 | 3813 | if (trx->lra_space_id == space | ||
1955 | 3814 | && ++trx->lra_n_pages_since <= trx->lra_n_pages) { | ||
1956 | 3815 | if (!row_lra_is_prefetched(trx, page_no)) { | ||
1957 | 3816 | srv_stats.n_logical_read_ahead_misses.add(1); | ||
1958 | 3817 | } | ||
1959 | 3818 | return FALSE; | ||
1960 | 3819 | } | ||
1961 | 3820 | rec = page_rec_get_next(page_get_infimum_rec( | ||
1962 | 3821 | buf_block_get_frame(block))); | ||
1963 | 3822 | if (!rec || page_rec_is_supremum(rec)) { | ||
1964 | 3823 | /* Do not start prefetching because we can not get the | ||
1965 | 3824 | parent page of an empty page */ | ||
1966 | 3825 | trx->lra_page_no = 0; | ||
1967 | 3826 | return FALSE; | ||
1968 | 3827 | } | ||
1969 | 3828 | tablespace_version = fil_space_get_version(space); | ||
1970 | 3829 | |||
1971 | 3830 | if (!*heap_ptr) { | ||
1972 | 3831 | *heap_ptr = mem_heap_create(100); | ||
1973 | 3832 | } | ||
1974 | 3833 | heap = *heap_ptr; | ||
1975 | 3834 | tuple = dict_index_build_node_ptr(index, rec, 0, heap, 1); | ||
1976 | 3835 | trx->lra_n_pages_since = 0; | ||
1977 | 3836 | |||
1978 | 3837 | btr_pcur_store_position(pcur, mtr); | ||
1979 | 3838 | mtr_commit(mtr); | ||
1980 | 3839 | #ifdef UNIV_DEBUG | ||
1981 | 3840 | if (row_lra_test && trx->lra_space_id == space) { | ||
1982 | 3841 | row_lra_test = FALSE; | ||
1983 | 3842 | os_thread_sleep(1000000); | ||
1984 | 3843 | } | ||
1985 | 3844 | #endif | ||
1986 | 3845 | mtr_start(mtr); | ||
1987 | 3846 | |||
1988 | 3847 | if (UNIV_LIKELY(trx->lra_space_id == space)) { | ||
1989 | 3848 | #ifdef UNIV_DEBUG | ||
1990 | 3849 | memset(trx->lra_sort_arr, 0, | ||
1991 | 3850 | 2 * trx->lra_n_pages * sizeof(ulint)); | ||
1992 | 3851 | #endif | ||
1993 | 3852 | btr_pcur_restore_position_func( | ||
1994 | 3853 | BTR_SEARCH_LEAF, trx->lra_cur, 1, | ||
1995 | 3854 | __FILE__, __LINE__, mtr); | ||
1996 | 3855 | row_read_ahead_logical_low( | ||
1997 | 3856 | trx->lra_ht, &num_prefetched, | ||
1998 | 3857 | trx->lra_sort_arr, index, mtr, | ||
1999 | 3858 | offsets, heap, trx); | ||
2000 | 3859 | if (trx->lra_ht == trx->lra_ht1) { | ||
2001 | 3860 | trx->lra_ht = trx->lra_ht2; | ||
2002 | 3861 | } else { | ||
2003 | 3862 | trx->lra_ht = trx->lra_ht1; | ||
2004 | 3863 | } | ||
2005 | 3864 | } else { | ||
2006 | 3865 | /* The transaction started to scan a new table, set | ||
2007 | 3866 | the values for lra_space_id and lra_n_pages based on the | ||
2008 | 3867 | new table */ | ||
2009 | 3868 | trx_lra_reset(trx, | ||
2010 | 3869 | trx->lra_size, | ||
2011 | 3870 | trx->lra_n_node_recs_before_sleep, | ||
2012 | 3871 | trx->lra_sleep); | ||
2013 | 3872 | trx->lra_space_id = space; | ||
2014 | 3873 | trx->lra_n_pages = (trx->lra_size << 20L) | ||
2015 | 3874 | / (zip_size ? zip_size : UNIV_PAGE_SIZE); | ||
2016 | 3875 | trx->lra_page_no = page_no; | ||
2017 | 3876 | mtr_s_lock(dict_index_get_lock(index), mtr); | ||
2018 | 3877 | /* Get root page to get the B-tree depth */ | ||
2019 | 3878 | root_page_no = dict_index_get_page(index); | ||
2020 | 3879 | root_block = buf_page_get_gen(space, zip_size, root_page_no, | ||
2021 | 3880 | RW_NO_LATCH, NULL, BUF_GET, | ||
2022 | 3881 | __FILE__, __LINE__, mtr); | ||
2023 | 3882 | trx->lra_tree_height = btr_page_get_level( | ||
2024 | 3883 | buf_block_get_frame(root_block), | ||
2025 | 3884 | mtr) + 1; | ||
2026 | 3885 | if (trx->lra_tree_height > 1) { | ||
2027 | 3886 | #ifdef UNIV_DEBUG | ||
2028 | 3887 | memset(trx->lra_sort_arr, 0, | ||
2029 | 3888 | 2 * trx->lra_n_pages * sizeof(ulint)); | ||
2030 | 3889 | #endif | ||
2031 | 3890 | mtr_commit(mtr); | ||
2032 | 3891 | mtr_start(mtr); | ||
2033 | 3892 | btr_pcur_open_low(index, 1, tuple, PAGE_CUR_LE, | ||
2034 | 3893 | BTR_SEARCH_LEAF, trx->lra_cur, | ||
2035 | 3894 | __FILE__, __LINE__, mtr); | ||
2036 | 3895 | row_read_ahead_logical_low( | ||
2037 | 3896 | trx->lra_ht1, &num_prefetched, | ||
2038 | 3897 | trx->lra_sort_arr, index, mtr, | ||
2039 | 3898 | offsets, heap, trx); | ||
2040 | 3899 | row_read_ahead_logical_low( | ||
2041 | 3900 | trx->lra_ht2, &num_prefetched, | ||
2042 | 3901 | &trx->lra_sort_arr[num_prefetched], index, mtr, | ||
2043 | 3902 | offsets, heap, trx); | ||
2044 | 3903 | } | ||
2045 | 3904 | trx->lra_ht = trx->lra_ht1; | ||
2046 | 3905 | } | ||
2047 | 3906 | if (trx->lra_tree_height > 1) | ||
2048 | 3907 | btr_pcur_store_position(trx->lra_cur, mtr); | ||
2049 | 3908 | mtr_commit(mtr); | ||
2050 | 3909 | if (num_prefetched) { | ||
2051 | 3910 | /* We sort the page numbers before issuing read requests for two | ||
2052 | 3911 | reasons: | ||
2053 | 3912 | 1- The block layer in linux kernel currently sorts the read | ||
2054 | 3913 | requests and merges them but there is a possibility that | ||
2055 | 3914 | this algorithm does not detect the sequential read and | ||
2056 | 3915 | coalesce the iops. | ||
2057 | 3916 | 2- Even if the block layer algorithm is perfect, the | ||
2058 | 3917 | asynchrounous read array size may be small in which case we | ||
2059 | 3918 | the read requests will have a lower chance of being | ||
2060 | 3919 | coalesced by the block layer. | ||
2061 | 3920 | |||
2062 | 3921 | Sorting is cheap in comparison to the iops that are about to | ||
2063 | 3922 | be done so we always sort. */ | ||
2064 | 3923 | std::sort(trx->lra_sort_arr, trx->lra_sort_arr + num_prefetched); | ||
2065 | 3924 | /* TODO(nizamordulu): Here we call buf_read_page_low() which | ||
2066 | 3925 | acquires the related buffer pool shard lock and checks if the | ||
2067 | 3926 | page is in that shard for each page. This could be made more | ||
2068 | 3927 | efficient if we checked for all pages at once or batched the | ||
2069 | 3928 | check for multiple pages after acquiring the related latch. */ | ||
2070 | 3929 | for (i = 0; i < num_prefetched; ++i) { | ||
2071 | 3930 | num_read_requests += buf_read_page_low( | ||
2072 | 3931 | &err, FALSE, | ||
2073 | 3932 | BUF_READ_ANY_PAGE | OS_AIO_SIMULATED_WAKE_LATER, | ||
2074 | 3933 | space, zip_size, FALSE, tablespace_version, | ||
2075 | 3934 | trx->lra_sort_arr[i], trx, TRUE); | ||
2076 | 3935 | } | ||
2077 | 3936 | #ifdef LINUX_NATIVE_AIO | ||
2078 | 3937 | os_aio_linux_dispatch_read_array_submit(); | ||
2079 | 3938 | #endif | ||
2080 | 3939 | srv_stats.n_logical_read_ahead_prefetched.add( | ||
2081 | 3940 | num_read_requests); | ||
2082 | 3941 | srv_stats.n_logical_read_ahead_in_buf_pool.add( | ||
2083 | 3942 | num_prefetched - num_read_requests); | ||
2084 | 3943 | } | ||
2085 | 3944 | mtr_start(mtr); | ||
2086 | 3945 | return sel_restore_position_for_mysql(&same_user_rec, BTR_SEARCH_LEAF, | ||
2087 | 3946 | pcur, TRUE, mtr); | ||
2088 | 3947 | } | ||
2089 | 3948 | |||
2090 | 3635 | /********************************************************************//** | 3949 | /********************************************************************//** |
2091 | 3636 | Searches for rows in the database. This is used in the interface to | 3950 | Searches for rows in the database. This is used in the interface to |
2092 | 3637 | MySQL. This function opens a cursor, and also implements fetch next | 3951 | MySQL. This function opens a cursor, and also implements fetch next |
2093 | @@ -5014,6 +5328,11 @@ | |||
2094 | 5014 | } | 5328 | } |
2095 | 5015 | 5329 | ||
2096 | 5016 | if (moves_up) { | 5330 | if (moves_up) { |
2097 | 5331 | if (trx | ||
2098 | 5332 | && row_read_ahead_logical( | ||
2099 | 5333 | pcur, index, &mtr, offsets, &heap, trx)) { | ||
2100 | 5334 | goto rec_loop; | ||
2101 | 5335 | } | ||
2102 | 5017 | if (UNIV_UNLIKELY(!btr_pcur_move_to_next(pcur, &mtr))) { | 5336 | if (UNIV_UNLIKELY(!btr_pcur_move_to_next(pcur, &mtr))) { |
2103 | 5018 | not_moved: | 5337 | not_moved: |
2104 | 5019 | btr_pcur_store_position(pcur, &mtr); | 5338 | btr_pcur_store_position(pcur, &mtr); |
2105 | 5020 | 5339 | ||
2106 | === modified file 'storage/innobase/srv/srv0srv.cc' | |||
2107 | --- storage/innobase/srv/srv0srv.cc 2014-03-03 17:51:33 +0000 | |||
2108 | +++ storage/innobase/srv/srv0srv.cc 2014-04-23 10:58:56 +0000 | |||
2109 | @@ -1863,6 +1863,15 @@ | |||
2110 | 1863 | } | 1863 | } |
2111 | 1864 | #endif /* UNIV_DEBUG */ | 1864 | #endif /* UNIV_DEBUG */ |
2112 | 1865 | 1865 | ||
2113 | 1866 | export_vars.innodb_buffered_aio_submitted = | ||
2114 | 1867 | srv_stats.n_aio_submitted; | ||
2115 | 1868 | export_vars.innodb_logical_read_ahead_misses = | ||
2116 | 1869 | srv_stats.n_logical_read_ahead_misses; | ||
2117 | 1870 | export_vars.innodb_logical_read_ahead_prefetched = | ||
2118 | 1871 | srv_stats.n_logical_read_ahead_prefetched; | ||
2119 | 1872 | export_vars.innodb_logical_read_ahead_in_buf_pool = | ||
2120 | 1873 | srv_stats.n_logical_read_ahead_in_buf_pool; | ||
2121 | 1874 | |||
2122 | 1866 | mutex_exit(&srv_innodb_monitor_mutex); | 1875 | mutex_exit(&srv_innodb_monitor_mutex); |
2123 | 1867 | } | 1876 | } |
2124 | 1868 | 1877 | ||
2125 | 1869 | 1878 | ||
2126 | === modified file 'storage/innobase/trx/trx0trx.cc' | |||
2127 | --- storage/innobase/trx/trx0trx.cc 2014-02-17 11:12:40 +0000 | |||
2128 | +++ storage/innobase/trx/trx0trx.cc 2014-04-23 10:58:56 +0000 | |||
2129 | @@ -48,6 +48,7 @@ | |||
2130 | 48 | #include "ha_prototypes.h" | 48 | #include "ha_prototypes.h" |
2131 | 49 | #include "srv0mon.h" | 49 | #include "srv0mon.h" |
2132 | 50 | #include "ut0vec.h" | 50 | #include "ut0vec.h" |
2133 | 51 | #include "btr0pcur.h" | ||
2134 | 51 | 52 | ||
2135 | 52 | #include<set> | 53 | #include<set> |
2136 | 53 | 54 | ||
2137 | @@ -212,6 +213,121 @@ | |||
2138 | 212 | trx_sys->descr_n_used--; | 213 | trx_sys->descr_n_used--; |
2139 | 213 | } | 214 | } |
2140 | 214 | 215 | ||
2141 | 216 | /*************************************************************//** | ||
2142 | 217 | Creates or frees data structures related to logical-read-ahead. | ||
2143 | 218 | based on the value of lra_size. */ | ||
2144 | 219 | UNIV_INTERN | ||
2145 | 220 | void | ||
2146 | 221 | trx_lra_reset( | ||
2147 | 222 | trx_t* trx, /*!< in: transaction */ | ||
2148 | 223 | ulint lra_size, /*!< in: lra_size in MB. | ||
2149 | 224 | If 0, the fields that are releated | ||
2150 | 225 | to logical-read-ahead will be free'd | ||
2151 | 226 | if they were initialized. */ | ||
2152 | 227 | ulint lra_n_node_recs_before_sleep, | ||
2153 | 228 | /*!< in: lra_n_node_recs_before_sleep | ||
2154 | 229 | is the number of node pointer records | ||
2155 | 230 | traversed while holding the index lock | ||
2156 | 231 | before releasing the index lock and | ||
2157 | 232 | sleeping for a short period of time so | ||
2158 | 233 | that the other threads get a chance to | ||
2159 | 234 | x-latch the index lock. */ | ||
2160 | 235 | ulint lra_sleep) /* lra_sleep is the sleep time in | ||
2161 | 236 | milliseconds. */ | ||
2162 | 237 | { | ||
2163 | 238 | #ifndef TARGET_OS_LINUX | ||
2164 | 239 | if (lra_size) { | ||
2165 | 240 | ib_logf(IB_LOG_LEVEL_WARN, | ||
2166 | 241 | "Logical read ahead is supported only on linux."); | ||
2167 | 242 | lra_size = 0; | ||
2168 | 243 | } | ||
2169 | 244 | #else /* TARGET_OS_LINUX */ | ||
2170 | 245 | if (!srv_use_native_aio && lra_size) { | ||
2171 | 246 | ib_logf(IB_LOG_LEVEL_WARN, | ||
2172 | 247 | "In order to use logical read ahead please enable " | ||
2173 | 248 | "native aio by setting innodb_use_native_aio=1 in " | ||
2174 | 249 | "my.cnf and restarting the server."); | ||
2175 | 250 | lra_size = 0; | ||
2176 | 251 | } | ||
2177 | 252 | #endif /* TARGET_OS_LINUX */ | ||
2178 | 253 | trx->lra_size = lra_size; | ||
2179 | 254 | trx->lra_space_id = 0; | ||
2180 | 255 | trx->lra_n_pages = 0; | ||
2181 | 256 | trx->lra_n_pages_since = 0; | ||
2182 | 257 | trx->lra_page_no = 0; | ||
2183 | 258 | trx->lra_n_node_recs_before_sleep = lra_n_node_recs_before_sleep; | ||
2184 | 259 | trx->lra_sleep = lra_sleep; | ||
2185 | 260 | trx->lra_tree_height = 0; | ||
2186 | 261 | if (lra_size) { | ||
2187 | 262 | ulint n_pages_max = | ||
2188 | 263 | (lra_size << 20L) / UNIV_ZIP_SIZE_MIN; | ||
2189 | 264 | ulint mem = n_pages_max * (2 * sizeof(ulint) | ||
2190 | 265 | + 2 * sizeof(page_no_holder_t)) | ||
2191 | 266 | + sizeof(btr_pcur_t); | ||
2192 | 267 | if (trx->lra_ht) { | ||
2193 | 268 | ut_a(trx->lra_ht1); | ||
2194 | 269 | ut_a(trx->lra_ht2); | ||
2195 | 270 | ut_a(trx->lra_sort_arr); | ||
2196 | 271 | ut_a(trx->lra_cur); | ||
2197 | 272 | hash_table_clear(trx->lra_ht1); | ||
2198 | 273 | hash_table_clear(trx->lra_ht2); | ||
2199 | 274 | trx->lra_ht = trx->lra_ht1; | ||
2200 | 275 | #ifdef UNIV_DEBUG | ||
2201 | 276 | /* following resets lra_sort_arr, | ||
2202 | 277 | * lra_arr1, lra_arr2, and lra_cursor. | ||
2203 | 278 | */ | ||
2204 | 279 | memset(trx->lra_sort_arr, 0, mem); | ||
2205 | 280 | #endif | ||
2206 | 281 | btr_pcur_init(trx->lra_cur); | ||
2207 | 282 | } else { | ||
2208 | 283 | byte* alloc; | ||
2209 | 284 | ut_a(!trx->lra_ht1); | ||
2210 | 285 | ut_a(!trx->lra_ht2); | ||
2211 | 286 | ut_a(!trx->lra_sort_arr); | ||
2212 | 287 | trx->lra_ht1 = hash_create(16384); | ||
2213 | 288 | trx->lra_ht2 = hash_create(16384); | ||
2214 | 289 | trx->lra_ht = trx->lra_ht1; | ||
2215 | 290 | alloc = (byte*)ut_malloc(mem); | ||
2216 | 291 | #ifdef UNIV_DEBUG | ||
2217 | 292 | memset(alloc, 0, mem); | ||
2218 | 293 | #endif | ||
2219 | 294 | trx->lra_sort_arr = (ulint*)alloc; | ||
2220 | 295 | alloc += 2 * sizeof(ulint) * n_pages_max; | ||
2221 | 296 | trx->lra_arr1 = (page_no_holder_t*) alloc; | ||
2222 | 297 | alloc += sizeof(page_no_holder_t) * n_pages_max; | ||
2223 | 298 | trx->lra_arr2 = (page_no_holder_t*) alloc; | ||
2224 | 299 | alloc += sizeof(page_no_holder_t) * n_pages_max; | ||
2225 | 300 | trx->lra_cur = (btr_pcur_t*) alloc; | ||
2226 | 301 | btr_pcur_init(trx->lra_cur); | ||
2227 | 302 | |||
2228 | 303 | } | ||
2229 | 304 | } else { | ||
2230 | 305 | if (trx->lra_ht) { | ||
2231 | 306 | ut_a(trx->lra_ht1); | ||
2232 | 307 | ut_a(trx->lra_ht2); | ||
2233 | 308 | ut_a(trx->lra_sort_arr); | ||
2234 | 309 | hash_table_free(trx->lra_ht1); | ||
2235 | 310 | hash_table_free(trx->lra_ht2); | ||
2236 | 311 | btr_pcur_close(trx->lra_cur); | ||
2237 | 312 | ut_free(trx->lra_sort_arr); | ||
2238 | 313 | trx->lra_sort_arr = NULL; | ||
2239 | 314 | trx->lra_ht = NULL; | ||
2240 | 315 | trx->lra_ht1 = NULL; | ||
2241 | 316 | trx->lra_ht2 = NULL; | ||
2242 | 317 | trx->lra_arr1 = NULL; | ||
2243 | 318 | trx->lra_arr2 = NULL; | ||
2244 | 319 | trx->lra_cur = NULL; | ||
2245 | 320 | } else { | ||
2246 | 321 | ut_a(!trx->lra_ht1); | ||
2247 | 322 | ut_a(!trx->lra_ht2); | ||
2248 | 323 | ut_a(!trx->lra_sort_arr); | ||
2249 | 324 | ut_a(!trx->lra_cur); | ||
2250 | 325 | ut_a(!trx->lra_arr1); | ||
2251 | 326 | ut_a(!trx->lra_arr2); | ||
2252 | 327 | } | ||
2253 | 328 | } | ||
2254 | 329 | } | ||
2255 | 330 | |||
2256 | 215 | /****************************************************************//** | 331 | /****************************************************************//** |
2257 | 216 | Creates and initializes a transaction object. It must be explicitly | 332 | Creates and initializes a transaction object. It must be explicitly |
2258 | 217 | started with trx_start_if_not_started() before using it. The default | 333 | started with trx_start_if_not_started() before using it. The default |
2259 | @@ -294,6 +410,12 @@ | |||
2260 | 294 | trx->lock.table_locks = ib_vector_create( | 410 | trx->lock.table_locks = ib_vector_create( |
2261 | 295 | heap_alloc, sizeof(void**), 32); | 411 | heap_alloc, sizeof(void**), 32); |
2262 | 296 | 412 | ||
2263 | 413 | trx->lra_ht = NULL; | ||
2264 | 414 | trx->lra_cur = NULL; | ||
2265 | 415 | trx->lra_ht1 = NULL; | ||
2266 | 416 | trx->lra_ht2 = NULL; | ||
2267 | 417 | trx_lra_reset(trx, 0, 0, 0); | ||
2268 | 418 | |||
2269 | 297 | return(trx); | 419 | return(trx); |
2270 | 298 | } | 420 | } |
2271 | 299 | 421 | ||
2272 | @@ -388,6 +510,7 @@ | |||
2273 | 388 | } | 510 | } |
2274 | 389 | 511 | ||
2275 | 390 | mutex_free(&trx->mutex); | 512 | mutex_free(&trx->mutex); |
2276 | 513 | trx_lra_reset(trx, 0, 0, 0); | ||
2277 | 391 | 514 | ||
2278 | 392 | read_view_free(trx->prebuilt_view); | 515 | read_view_free(trx->prebuilt_view); |
2279 | 393 | 516 |
This is not a full review, but addressing this bit can happen in parallel with the rest of the review: the MP needs a blueprint, or even several blueprints, corresponding to each commit (the commits IMHO are well-split). The blueprints must be self-contained.