Merge lp:~laurynas-biveinis/percona-server/tokudb-prepare-scans into lp:percona-server/5.6

Proposed by Laurynas Biveinis on 2014-03-24
Status: Merged
Approved by: Alexey Kopytov on 2014-03-28
Approved revision: 566
Merged at revision: 573
Proposed branch: lp:~laurynas-biveinis/percona-server/tokudb-prepare-scans
Merge into: lp:percona-server/5.6
Diff against target: 137 lines (+69/-2)
4 files modified
sql/handler.h (+38/-0)
sql/opt_range.cc (+12/-0)
sql/records.cc (+12/-2)
sql/sql_executor.cc (+7/-0)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/tokudb-prepare-scans
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) 2014-03-24 Approve on 2014-03-28
Review via email: mp+212349@code.launchpad.net

Description of the change

Handler extensions to notify SE of incoming index/range scan. Although ideally any required preparation actions should be added to existing methods (ha_index_init, read_range_first), or perhaps by exploiting ICP better, that's not trivial (e.g. cannot add TokuDB prelocking to ha_index_init if it is expensive, because ha_index_init is called to read few rows too). Investigating such changes is on Tokutek's TODO.

Add new handler methods for notifying storage engine of imminent index
scans, both for reading whole table and ranges. Implements
https://blueprints.launchpad.net/percona-server/+spec/prepare-index-range-scan.

The new handler methods added, no-ops in default implementations:
- prepare_index_scan for imminent index (range-less) scan, called in
rr_index_first, rr_index_last in records.cc, and
join_read_first/join_read_last.
- prepare_range_scan for imminent index range scan, called in
QUICK_SELECT_DESC::get_next.
- prepare_index_key_scan_map and prepare_index_key_scan for imminent
index (range-less) scan with used key part information, called in
join_read_always_key in sql_executor.cc.

http://jenkins.percona.com/job/percona-server-5.6-param/562/

To post a comment you must log in.
Alexey Kopytov (akopytov) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'sql/handler.h'
2--- sql/handler.h 2014-02-27 12:29:47 +0000
3+++ sql/handler.h 2014-03-24 06:21:13 +0000
4@@ -2311,6 +2311,44 @@
5 return index_read_last(buf, key, key_len);
6 }
7 public:
8+
9+ /**
10+ Notify storage engine about imminent index scan where a large number of
11+ rows is expected to be returned. Does not replace nor call index_init.
12+ */
13+ virtual int prepare_index_scan(void) { return 0; }
14+
15+ /**
16+ Notify storage engine about imminent index range scan.
17+ */
18+ virtual int prepare_range_scan(const key_range *start_key,
19+ const key_range *end_key)
20+ {
21+ return 0;
22+ }
23+
24+ /**
25+ Notify storage engine about imminent index read with a bitmap of used key
26+ parts.
27+ */
28+ int prepare_index_key_scan_map(const uchar *key, key_part_map keypart_map)
29+ {
30+ uint key_len= calculate_key_len(table, active_index, key, keypart_map);
31+ return prepare_index_key_scan(key, key_len);
32+ }
33+
34+protected:
35+
36+ /**
37+ Notify storage engine about imminent index read with key length.
38+ */
39+ virtual int prepare_index_key_scan(const uchar *key, uint key_len)
40+ {
41+ return 0;
42+ }
43+
44+public:
45+
46 virtual int read_range_first(const key_range *start_key,
47 const key_range *end_key,
48 bool eq_range, bool sorted);
49
50=== modified file 'sql/opt_range.cc'
51--- sql/opt_range.cc 2014-03-03 17:51:33 +0000
52+++ sql/opt_range.cc 2014-03-24 06:21:13 +0000
53@@ -10867,6 +10867,18 @@
54 }
55 }
56
57+ key_range prepare_range_start;
58+ key_range prepare_range_end;
59+
60+ last_range->make_min_endpoint(&prepare_range_start);
61+ last_range->make_max_endpoint(&prepare_range_end);
62+ result = file->prepare_range_scan((last_range->flag & NO_MIN_RANGE)
63+ ? NULL : &prepare_range_start,
64+ (last_range->flag & NO_MAX_RANGE)
65+ ? NULL : &prepare_range_end);
66+ if (result)
67+ DBUG_RETURN(result);
68+
69 if (last_range->flag & NO_MAX_RANGE) // Read last record
70 {
71 int local_error;
72
73=== modified file 'sql/records.cc'
74--- sql/records.cc 2013-08-14 03:57:21 +0000
75+++ sql/records.cc 2014-03-24 06:21:13 +0000
76@@ -391,8 +391,13 @@
77
78 static int rr_index_first(READ_RECORD *info)
79 {
80- int tmp= info->table->file->ha_index_first(info->record);
81+ int tmp= info->table->file->prepare_index_scan();
82 info->read_record= rr_index;
83+ if (tmp) {
84+ tmp= rr_handle_error(info, tmp);
85+ return tmp;
86+ }
87+ tmp= info->table->file->ha_index_first(info->record);
88 if (tmp)
89 tmp= rr_handle_error(info, tmp);
90 return tmp;
91@@ -414,8 +419,13 @@
92
93 static int rr_index_last(READ_RECORD *info)
94 {
95- int tmp= info->table->file->ha_index_last(info->record);
96+ int tmp= info->table->file->prepare_index_scan();
97 info->read_record= rr_index_desc;
98+ if (tmp) {
99+ tmp= rr_handle_error(info, tmp);
100+ return tmp;
101+ }
102+ tmp= info->table->file->ha_index_last(info->record);
103 if (tmp)
104 tmp= rr_handle_error(info, tmp);
105 return tmp;
106
107=== modified file 'sql/sql_executor.cc'
108--- sql/sql_executor.cc 2014-02-17 11:12:40 +0000
109+++ sql/sql_executor.cc 2014-03-24 06:21:13 +0000
110@@ -2203,6 +2203,9 @@
111
112 if (cp_buffer_from_ref(tab->join->thd, table, ref))
113 return -1;
114+ if ((error= table->file->prepare_index_key_scan_map(tab->ref.key_buff,
115+ make_prev_keypart_map(tab->ref.key_parts))))
116+ return report_handler_error(table, error);
117 if ((error= table->file->ha_index_read_map(table->record[0],
118 tab->ref.key_buff,
119 make_prev_keypart_map(tab->ref.key_parts),
120@@ -2529,6 +2532,8 @@
121 (void) report_handler_error(table, error);
122 return 1;
123 }
124+ if ((error= tab->table->file->prepare_index_scan()))
125+ return 1;
126 if ((error= tab->table->file->ha_index_first(tab->table->record[0])))
127 {
128 if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
129@@ -2567,6 +2572,8 @@
130 (void) report_handler_error(table, error);
131 return 1;
132 }
133+ if ((error= table->file->prepare_index_scan()))
134+ return report_handler_error(table, error);
135 if ((error= tab->table->file->ha_index_last(tab->table->record[0])))
136 return report_handler_error(table, error);
137 return 0;

Subscribers

People subscribed via source and target branches