Merge lp:~stewart/percona-server/5.1.67 into lp:percona-server/5.1
- 5.1.67
- Merge into 5.1
Proposed by
Stewart Smith
Status: | Merged |
---|---|
Approved by: | Laurynas Biveinis |
Approved revision: | no longer in the source branch. |
Merged at revision: | 542 |
Proposed branch: | lp:~stewart/percona-server/5.1.67 |
Merge into: | lp:percona-server/5.1 |
Prerequisite: | lp:~percona-core/percona-server/release-5.1.66-14.2 |
Diff against target: |
3724 lines (+1320/-575) 69 files modified
Percona-Server/client/mysql.cc (+89/-2) Percona-Server/configure.in (+1/-1) Percona-Server/libmysql/libmysql.c (+1/-1) Percona-Server/mysql-test/r/ctype_ucs.result (+26/-0) Percona-Server/mysql-test/r/loaddata.result (+0/-29) Percona-Server/mysql-test/r/sp_notembedded.result (+1/-1) Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test (+1/-1) Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_myisam.test (+1/-1) Percona-Server/mysql-test/suite/innodb/r/innodb_bug14704286.result (+53/-0) Percona-Server/mysql-test/suite/innodb/t/innodb_bug14704286.test (+95/-0) Percona-Server/mysql-test/t/ctype_ucs.test (+32/-0) Percona-Server/mysql-test/t/loaddata.test (+34/-30) Percona-Server/mysql-test/t/sp_notembedded.test (+10/-10) Percona-Server/scripts/mysql_install_db.pl.in (+18/-3) Percona-Server/scripts/mysqld_multi.sh (+22/-0) Percona-Server/scripts/mysqld_safe.sh (+34/-1) Percona-Server/sql/hostname.cc (+9/-0) Percona-Server/sql/item_cmpfunc.cc (+20/-1) Percona-Server/sql/item_func.cc (+2/-1) Percona-Server/sql/item_func.h (+1/-0) Percona-Server/sql/log.cc (+6/-0) Percona-Server/sql/log_event.cc (+55/-4) Percona-Server/sql/log_event.h (+3/-3) Percona-Server/sql/mysql_priv.h (+35/-0) Percona-Server/sql/mysqld.cc (+1/-1) Percona-Server/sql/sp_head.cc (+27/-21) Percona-Server/sql/sql_acl.cc (+169/-93) Percona-Server/sql/sql_connect.cc (+60/-8) Percona-Server/sql/sql_lex.cc (+1/-0) Percona-Server/sql/sql_list.h (+9/-2) Percona-Server/sql/sql_profile.cc (+19/-10) Percona-Server/sql/sql_profile.h (+4/-2) Percona-Server/sql/sql_select.cc (+13/-13) Percona-Server/storage/innobase/btr/btr0cur.c (+6/-5) Percona-Server/storage/innobase/dict/dict0dict.c (+15/-3) Percona-Server/storage/innobase/handler/ha_innodb.cc (+2/-2) Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c (+25/-3) Percona-Server/storage/innobase/include/btr0cur.h (+5/-4) Percona-Server/storage/innobase/include/dict0mem.h (+6/-1) Percona-Server/storage/innobase/include/row0undo.h (+2/-7) Percona-Server/storage/innobase/os/os0file.c (+15/-0) Percona-Server/storage/innobase/row/row0sel.c (+17/-8) Percona-Server/storage/innobase/row/row0umod.c (+0/-54) Percona-Server/storage/innobase/row/row0undo.c (+0/-19) Percona-Server/storage/innodb_plugin/ChangeLog (+37/-0) Percona-Server/storage/innodb_plugin/btr/btr0btr.c (+17/-15) Percona-Server/storage/innodb_plugin/btr/btr0cur.c (+22/-18) Percona-Server/storage/innodb_plugin/buf/buf0buf.c (+4/-3) Percona-Server/storage/innodb_plugin/buf/buf0lru.c (+3/-1) Percona-Server/storage/innodb_plugin/dict/dict0dict.c (+60/-31) Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc (+2/-2) Percona-Server/storage/innodb_plugin/handler/handler0alter.cc (+6/-2) Percona-Server/storage/innodb_plugin/ibuf/ibuf0ibuf.c (+26/-3) Percona-Server/storage/innodb_plugin/include/btr0cur.h (+6/-5) Percona-Server/storage/innodb_plugin/include/dict0dict.h (+12/-0) Percona-Server/storage/innodb_plugin/include/dict0mem.h (+6/-1) Percona-Server/storage/innodb_plugin/include/page0zip.h (+5/-3) Percona-Server/storage/innodb_plugin/include/row0undo.h (+0/-7) Percona-Server/storage/innodb_plugin/log/log0recv.c (+2/-3) Percona-Server/storage/innodb_plugin/os/os0file.c (+15/-0) Percona-Server/storage/innodb_plugin/page/page0cur.c (+3/-3) Percona-Server/storage/innodb_plugin/page/page0page.c (+8/-6) Percona-Server/storage/innodb_plugin/page/page0zip.c (+111/-46) Percona-Server/storage/innodb_plugin/row/row0mysql.c (+4/-1) Percona-Server/storage/innodb_plugin/row/row0sel.c (+17/-7) Percona-Server/storage/innodb_plugin/row/row0umod.c (+0/-53) Percona-Server/storage/innodb_plugin/row/row0undo.c (+0/-19) Percona-Server/storage/myisam/myisamchk.c (+8/-1) Percona-Server/tests/mysql_client_test.c (+1/-0) |
To merge this branch: | bzr merge lp:~stewart/percona-server/5.1.67 |
Related bugs: | |
Related blueprints: |
Rebase on MySQL 5.1.67
(Essential)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Approve | ||
Review via email: mp+142635@code.launchpad.net |
Commit message
Description of the change
Merge MySQL 5.1.67.
This will seemingly have to wait for MySQL 5.5.30 to be properly merged in as there are (again) changesets in 5.1 that aren't in 5.5.
This was mostly auto merge, apart from binlog quoting (which I reverted in the MySQL branch before merging) and minor bit in sql/log_event.cc
http://
To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) : | # |
review:
Approve
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Percona-Server/client/mysql.cc' |
2 | --- Percona-Server/client/mysql.cc 2013-01-10 04:35:31 +0000 |
3 | +++ Percona-Server/client/mysql.cc 2013-01-10 04:35:33 +0000 |
4 | @@ -250,6 +250,8 @@ |
5 | static char *get_arg(char *line, my_bool get_next_arg); |
6 | static void init_username(); |
7 | static void add_int_to_prompt(int toadd); |
8 | +static int normalize_dbname(const char *line, char *buff, uint buff_size); |
9 | +static int get_quote_count(const char *line); |
10 | |
11 | /* A structure which contains information on the commands this program |
12 | can understand. */ |
13 | @@ -4172,8 +4174,23 @@ |
14 | int select_db; |
15 | |
16 | bzero(buff, sizeof(buff)); |
17 | - strmake(buff, line, sizeof(buff) - 1); |
18 | - tmp= get_arg(buff, 0); |
19 | + |
20 | + /* |
21 | + In case number of quotes exceed 2, we try to get |
22 | + the normalized db name. |
23 | + */ |
24 | + if (get_quote_count(line) > 2) |
25 | + { |
26 | + if (normalize_dbname(line, buff, sizeof(buff))) |
27 | + return put_error(&mysql); |
28 | + tmp= buff; |
29 | + } |
30 | + else |
31 | + { |
32 | + strmake(buff, line, sizeof(buff) - 1); |
33 | + tmp= get_arg(buff, 0); |
34 | + } |
35 | + |
36 | if (!tmp || !*tmp) |
37 | { |
38 | put_info("USE must be followed by a database name", INFO_ERROR); |
39 | @@ -4239,6 +4256,62 @@ |
40 | return 0; |
41 | } |
42 | |
43 | +/** |
44 | + Normalize database name. |
45 | + |
46 | + @param line [IN] The command. |
47 | + @param buff [OUT] Normalized db name. |
48 | + @param buff_size [IN] Buffer size. |
49 | + |
50 | + @return Operation status |
51 | + @retval 0 Success |
52 | + @retval 1 Failure |
53 | + |
54 | + @note Sometimes server normilizes the database names |
55 | + & APIs like mysql_select_db() expect normalized |
56 | + database names. Since it is difficult to perform |
57 | + the name conversion/normalization on the client |
58 | + side, this function tries to get the normalized |
59 | + dbname (indirectly) from the server. |
60 | +*/ |
61 | + |
62 | +static int |
63 | +normalize_dbname(const char *line, char *buff, uint buff_size) |
64 | +{ |
65 | + MYSQL_RES *res= NULL; |
66 | + |
67 | + /* Send the "USE db" commmand to the server. */ |
68 | + if (mysql_query(&mysql, line)) |
69 | + return 1; |
70 | + |
71 | + /* |
72 | + Now, get the normalized database name and store it |
73 | + into the buff. |
74 | + */ |
75 | + if (!mysql_query(&mysql, "SELECT DATABASE()") && |
76 | + (res= mysql_use_result(&mysql))) |
77 | + { |
78 | + MYSQL_ROW row= mysql_fetch_row(res); |
79 | + if (row && row[0]) |
80 | + { |
81 | + size_t len= strlen(row[0]); |
82 | + /* Make sure there is enough room to store the dbname. */ |
83 | + if ((len > buff_size) || ! memcpy(buff, row[0], len)) |
84 | + { |
85 | + mysql_free_result(res); |
86 | + return 1; |
87 | + } |
88 | + } |
89 | + mysql_free_result(res); |
90 | + } |
91 | + |
92 | + /* Restore the original database. */ |
93 | + if (current_db && mysql_select_db(&mysql, current_db)) |
94 | + return 1; |
95 | + |
96 | + return 0; |
97 | +} |
98 | + |
99 | static int |
100 | com_warnings(String *buffer __attribute__((unused)), |
101 | char *line __attribute__((unused))) |
102 | @@ -4318,6 +4391,20 @@ |
103 | return valid_arg ? start : NullS; |
104 | } |
105 | |
106 | +/* |
107 | + Number of quotes present in the command's argument. |
108 | +*/ |
109 | +static int |
110 | +get_quote_count(const char *line) |
111 | +{ |
112 | + int quote_count; |
113 | + const char *ptr= line; |
114 | + |
115 | + for(quote_count= 0; ptr ++ && *ptr; ptr= strpbrk(ptr, "\"\'`")) |
116 | + quote_count ++; |
117 | + |
118 | + return quote_count; |
119 | +} |
120 | |
121 | static int |
122 | sql_real_connect(char *host,char *database,char *user,char *password, |
123 | |
124 | === modified file 'Percona-Server/configure.in' |
125 | --- Percona-Server/configure.in 2013-01-10 04:35:31 +0000 |
126 | +++ Percona-Server/configure.in 2013-01-10 04:35:33 +0000 |
127 | @@ -12,7 +12,7 @@ |
128 | dnl When changing the major version number please also check the switch |
129 | dnl statement in mysqlbinlog::check_master_version(). You may also need |
130 | dnl to update version.c in ndb. |
131 | -AC_INIT([MySQL Server], [5.1.66], [], [mysql]) |
132 | +AC_INIT([MySQL Server], [5.1.67], [], [mysql]) |
133 | |
134 | AC_CONFIG_SRCDIR([sql/mysqld.cc]) |
135 | AC_CANONICAL_SYSTEM |
136 | |
137 | === modified file 'Percona-Server/libmysql/libmysql.c' |
138 | --- Percona-Server/libmysql/libmysql.c 2012-08-20 00:29:22 +0000 |
139 | +++ Percona-Server/libmysql/libmysql.c 2013-01-10 04:35:33 +0000 |
140 | @@ -4653,7 +4653,7 @@ |
141 | if ((int) stmt->state < (int) MYSQL_STMT_FETCH_DONE) |
142 | { |
143 | set_stmt_error(stmt, CR_NO_DATA, unknown_sqlstate, NULL); |
144 | - return 1; |
145 | + DBUG_RETURN(1); |
146 | } |
147 | if (column >= stmt->field_count) |
148 | { |
149 | |
150 | === renamed file 'Percona-Server/mysql-test/include/mysqlbinlog_row_engine.inc' => 'Percona-Server/mysql-test/extra/binlog_tests/mysqlbinlog_row_engine.inc' |
151 | === modified file 'Percona-Server/mysql-test/r/ctype_ucs.result' |
152 | --- Percona-Server/mysql-test/r/ctype_ucs.result 2011-03-03 15:39:26 +0000 |
153 | +++ Percona-Server/mysql-test/r/ctype_ucs.result 2013-01-10 04:35:33 +0000 |
154 | @@ -191,6 +191,32 @@ |
155 | `r` varchar(10) CHARACTER SET ucs2 NOT NULL DEFAULT '' |
156 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
157 | DROP TABLE t1; |
158 | +# |
159 | +# Bug #51876 : crash/memory underrun when loading data with ucs2 |
160 | +# and reverse() function |
161 | +# |
162 | +# Problem # 1 (original report): wrong parsing of ucs2 data |
163 | +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; |
164 | +CREATE TABLE t1(a INT); |
165 | +LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 |
166 | +(@b) SET a=REVERSE(@b); |
167 | +# should return 2 zeroes (as the value is truncated) |
168 | +SELECT * FROM t1; |
169 | +a |
170 | +0 |
171 | +1 |
172 | +DROP TABLE t1; |
173 | +# Problem # 2 : if you write and read ucs2 data to a file they're lost |
174 | +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; |
175 | +CREATE TABLE t1(a INT); |
176 | +LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 |
177 | +(@b) SET a=REVERSE(@b); |
178 | +# should return 0 and 1 (10 reversed) |
179 | +SELECT * FROM t1; |
180 | +a |
181 | +0 |
182 | +1 |
183 | +DROP TABLE t1; |
184 | create table t2(f1 Char(30)); |
185 | insert into t2 values ("103000"), ("22720000"), ("3401200"), ("78000"); |
186 | select lpad(f1, 12, "-o-/") from t2; |
187 | |
188 | === modified file 'Percona-Server/mysql-test/r/loaddata.result' |
189 | --- Percona-Server/mysql-test/r/loaddata.result 2011-05-10 13:57:40 +0000 |
190 | +++ Percona-Server/mysql-test/r/loaddata.result 2013-01-10 04:35:33 +0000 |
191 | @@ -504,35 +504,6 @@ |
192 | LOAD DATA LOCAL INFILE 'tb.txt' INTO TABLE t1; |
193 | DROP TABLE t1; |
194 | # |
195 | -# Bug #51876 : crash/memory underrun when loading data with ucs2 |
196 | -# and reverse() function |
197 | -# |
198 | -# Problem # 1 (original report): wrong parsing of ucs2 data |
199 | -SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; |
200 | -CREATE TABLE t1(a INT); |
201 | -LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 |
202 | -(@b) SET a=REVERSE(@b); |
203 | -Warnings: |
204 | -Warning 1366 Incorrect integer value: '00' for column 'a' at row 1 |
205 | -Warning 1366 Incorrect integer value: '10' for column 'a' at row 2 |
206 | -# should return 2 zeroes (as the value is truncated) |
207 | -SELECT * FROM t1; |
208 | -a |
209 | -0 |
210 | -0 |
211 | -DROP TABLE t1; |
212 | -# Problem # 2 : if you write and read ucs2 data to a file they're lost |
213 | -SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; |
214 | -CREATE TABLE t1(a INT); |
215 | -LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 |
216 | -(@b) SET a=REVERSE(@b); |
217 | -# should return 0 and 1 (10 reversed) |
218 | -SELECT * FROM t1; |
219 | -a |
220 | -0 |
221 | -1 |
222 | -DROP TABLE t1; |
223 | -# |
224 | # Bug#11765139 58069: LOAD DATA INFILE: VALGRIND REPORTS INVALID MEMORY READS AND WRITES WITH U |
225 | # |
226 | CREATE TABLE t1(f1 INT); |
227 | |
228 | === modified file 'Percona-Server/mysql-test/r/sp_notembedded.result' |
229 | --- Percona-Server/mysql-test/r/sp_notembedded.result 2012-03-28 06:35:31 +0000 |
230 | +++ Percona-Server/mysql-test/r/sp_notembedded.result 2013-01-10 04:35:33 +0000 |
231 | @@ -248,7 +248,6 @@ |
232 | DROP PROCEDURE p1; |
233 | DELETE FROM mysql.user WHERE User='mysqltest_1'; |
234 | FLUSH PRIVILEGES; |
235 | -set @@global.concurrent_insert= @old_concurrent_insert; |
236 | # |
237 | # Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al. |
238 | # |
239 | @@ -302,3 +301,4 @@ |
240 | # ------------------------------------------------------------------ |
241 | # -- End of 5.1 tests |
242 | # ------------------------------------------------------------------ |
243 | +set @@global.concurrent_insert= @old_concurrent_insert; |
244 | |
245 | === renamed file 'Percona-Server/mysql-test/r/mysqlbinlog-cp932.result' => 'Percona-Server/mysql-test/suite/binlog/r/binlog_mysqlbinlog-cp932.result' |
246 | === renamed file 'Percona-Server/mysql-test/r/mysqlbinlog2.result' => 'Percona-Server/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result' |
247 | === renamed file 'Percona-Server/mysql-test/r/mysqlbinlog_base64.result' => 'Percona-Server/mysql-test/suite/binlog/r/binlog_mysqlbinlog_base64.result' |
248 | === renamed file 'Percona-Server/mysql-test/r/mysqlbinlog_row.result' => 'Percona-Server/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result' |
249 | === renamed file 'Percona-Server/mysql-test/r/mysqlbinlog_row_innodb.result' => 'Percona-Server/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result' |
250 | === renamed file 'Percona-Server/mysql-test/r/mysqlbinlog_row_myisam.result' => 'Percona-Server/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result' |
251 | === renamed file 'Percona-Server/mysql-test/r/mysqlbinlog_row_trans.result' => 'Percona-Server/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result' |
252 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog-cp932-master.opt' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog-cp932-master.opt' |
253 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog-cp932.test' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog-cp932.test' |
254 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog2.test' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog2.test' |
255 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog_base64.test' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_base64.test' |
256 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog_row.test' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test' |
257 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog_row_innodb.test' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test' |
258 | --- Percona-Server/mysql-test/t/mysqlbinlog_row_innodb.test 2008-08-20 14:06:31 +0000 |
259 | +++ Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_innodb.test 2013-01-10 04:35:33 +0000 |
260 | @@ -20,5 +20,5 @@ |
261 | --source include/have_binlog_format_row.inc |
262 | --source include/have_ucs2.inc |
263 | |
264 | ---source include/mysqlbinlog_row_engine.inc |
265 | +--source extra/binlog_tests/mysqlbinlog_row_engine.inc |
266 | |
267 | |
268 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog_row_myisam.test' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_myisam.test' |
269 | --- Percona-Server/mysql-test/t/mysqlbinlog_row_myisam.test 2008-08-20 14:06:31 +0000 |
270 | +++ Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_myisam.test 2013-01-10 04:35:33 +0000 |
271 | @@ -20,4 +20,4 @@ |
272 | --source include/have_binlog_format_row.inc |
273 | --source include/have_ucs2.inc |
274 | |
275 | ---source include/mysqlbinlog_row_engine.inc |
276 | +--source extra/binlog_tests/mysqlbinlog_row_engine.inc |
277 | |
278 | === renamed file 'Percona-Server/mysql-test/t/mysqlbinlog_row_trans.test' => 'Percona-Server/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_trans.test' |
279 | === added file 'Percona-Server/mysql-test/suite/innodb/r/innodb_bug14704286.result' |
280 | --- Percona-Server/mysql-test/suite/innodb/r/innodb_bug14704286.result 1970-01-01 00:00:00 +0000 |
281 | +++ Percona-Server/mysql-test/suite/innodb/r/innodb_bug14704286.result 2013-01-10 04:35:33 +0000 |
282 | @@ -0,0 +1,53 @@ |
283 | +use test; |
284 | +drop table if exists t1; |
285 | +create table t1 (id int primary key, value int, value2 int, |
286 | +value3 int, index(value,value2)) engine=innodb; |
287 | +insert into t1 values |
288 | +(10,10,10,10),(11,11,11,11),(12,12,12,12),(13,13,13,13),(14,14,14,14), |
289 | +(15,15,15,15),(16,16,16,16),(17,17,17,17),(18,18,18,18),(19,19,19,19), |
290 | +(20,20,20,20); |
291 | +use test; |
292 | +start transaction with consistent snapshot; |
293 | +use test; |
294 | +CREATE PROCEDURE update_t1() |
295 | +BEGIN |
296 | +DECLARE i INT DEFAULT 1; |
297 | +while (i <= 5000) DO |
298 | +update test.t1 set value2=value2+1, value3=value3+1 where id=12; |
299 | +SET i = i + 1; |
300 | +END WHILE; |
301 | +END| |
302 | +set autocommit=0; |
303 | +CALL update_t1(); |
304 | +select * from t1; |
305 | +id value value2 value3 |
306 | +10 10 10 10 |
307 | +11 11 11 11 |
308 | +12 12 5012 5012 |
309 | +13 13 13 13 |
310 | +14 14 14 14 |
311 | +15 15 15 15 |
312 | +16 16 16 16 |
313 | +17 17 17 17 |
314 | +18 18 18 18 |
315 | +19 19 19 19 |
316 | +20 20 20 20 |
317 | +set autocommit=1; |
318 | +select * from t1; |
319 | +id value value2 value3 |
320 | +10 10 10 10 |
321 | +11 11 11 11 |
322 | +12 12 5012 5012 |
323 | +13 13 13 13 |
324 | +14 14 14 14 |
325 | +15 15 15 15 |
326 | +16 16 16 16 |
327 | +17 17 17 17 |
328 | +18 18 18 18 |
329 | +19 19 19 19 |
330 | +20 20 20 20 |
331 | +select * from t1 force index(value) where value=12; |
332 | +kill query @id; |
333 | +ERROR 70100: Query execution was interrupted |
334 | +drop procedure if exists update_t1; |
335 | +drop table if exists t1; |
336 | |
337 | === added file 'Percona-Server/mysql-test/suite/innodb/t/innodb_bug14704286.test' |
338 | --- Percona-Server/mysql-test/suite/innodb/t/innodb_bug14704286.test 1970-01-01 00:00:00 +0000 |
339 | +++ Percona-Server/mysql-test/suite/innodb/t/innodb_bug14704286.test 2013-01-10 04:35:33 +0000 |
340 | @@ -0,0 +1,95 @@ |
341 | +--source include/have_innodb.inc |
342 | + |
343 | +# |
344 | +# create test-bed to run test |
345 | +# |
346 | +use test; |
347 | +--disable_warnings |
348 | +drop table if exists t1; |
349 | +--enable_warnings |
350 | +create table t1 (id int primary key, value int, value2 int, |
351 | +value3 int, index(value,value2)) engine=innodb; |
352 | + |
353 | +insert into t1 values |
354 | +(10,10,10,10),(11,11,11,11),(12,12,12,12),(13,13,13,13),(14,14,14,14), |
355 | +(15,15,15,15),(16,16,16,16),(17,17,17,17),(18,18,18,18),(19,19,19,19), |
356 | +(20,20,20,20); |
357 | +let $ID= `SELECT @id := CONNECTION_ID()`; |
358 | + |
359 | +# |
360 | +# we need multiple connections as we need to keep one connection |
361 | +# active with trx requesting consistent read. |
362 | +# |
363 | +connect (conn1, localhost, root,,); |
364 | +connect (conn2, localhost, root,,); |
365 | +connect (conn3, localhost, root,,); |
366 | + |
367 | +# |
368 | +# start trx with consistent read |
369 | +# |
370 | +connection conn1; |
371 | +use test; |
372 | + |
373 | +start transaction with consistent snapshot; |
374 | + |
375 | +# |
376 | +# update table such that secondary index is updated. |
377 | +# |
378 | +connection conn2; |
379 | +use test; |
380 | +delimiter |; |
381 | +CREATE PROCEDURE update_t1() |
382 | +BEGIN |
383 | + DECLARE i INT DEFAULT 1; |
384 | + while (i <= 5000) DO |
385 | + update test.t1 set value2=value2+1, value3=value3+1 where id=12; |
386 | + SET i = i + 1; |
387 | + END WHILE; |
388 | +END| |
389 | + |
390 | +delimiter ;| |
391 | +set autocommit=0; |
392 | +CALL update_t1(); |
393 | +select * from t1; |
394 | +set autocommit=1; |
395 | +select * from t1; |
396 | + |
397 | +# |
398 | +# Now try to fire select query from connection-1 enforcing |
399 | +# use of secondary index. |
400 | +# |
401 | +connection conn1; |
402 | +let $ID= `SELECT @id := CONNECTION_ID()`; |
403 | +#--error ER_QUERY_INTERRUPTED |
404 | +--send |
405 | +select * from t1 force index(value) where value=12; |
406 | + |
407 | +# |
408 | +# select is going to take good time so let's kill query. |
409 | +# |
410 | +connection conn3; |
411 | +let $wait_condition= |
412 | + select * from information_schema.processlist where state = 'Sending data' and |
413 | + info = 'select * from t1 force index(value) where value=12'; |
414 | +--source include/wait_condition.inc |
415 | +let $ignore= `SELECT @id := $ID`; |
416 | +kill query @id; |
417 | + |
418 | +# |
419 | +# reap the value of connection-1 |
420 | +# |
421 | +connection conn1; |
422 | +--error ER_QUERY_INTERRUPTED |
423 | +reap; |
424 | + |
425 | +# |
426 | +# clean test-bed. |
427 | +# |
428 | +connection default; |
429 | +disconnect conn1; |
430 | +disconnect conn2; |
431 | +disconnect conn3; |
432 | +drop procedure if exists update_t1; |
433 | +drop table if exists t1; |
434 | + |
435 | + |
436 | |
437 | === modified file 'Percona-Server/mysql-test/t/ctype_ucs.test' |
438 | --- Percona-Server/mysql-test/t/ctype_ucs.test 2011-03-03 15:39:26 +0000 |
439 | +++ Percona-Server/mysql-test/t/ctype_ucs.test 2013-01-10 04:35:33 +0000 |
440 | @@ -68,6 +68,38 @@ |
441 | SHOW CREATE TABLE t1; |
442 | DROP TABLE t1; |
443 | |
444 | +--echo # |
445 | +--echo # Bug #51876 : crash/memory underrun when loading data with ucs2 |
446 | +--echo # and reverse() function |
447 | +--echo # |
448 | + |
449 | +--echo # Problem # 1 (original report): wrong parsing of ucs2 data |
450 | +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; |
451 | +CREATE TABLE t1(a INT); |
452 | +LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 |
453 | +(@b) SET a=REVERSE(@b); |
454 | +--echo # should return 2 zeroes (as the value is truncated) |
455 | +SELECT * FROM t1; |
456 | + |
457 | +DROP TABLE t1; |
458 | +let $MYSQLD_DATADIR= `select @@datadir`; |
459 | +remove_file $MYSQLD_DATADIR/test/tmpp.txt; |
460 | + |
461 | + |
462 | +--echo # Problem # 2 : if you write and read ucs2 data to a file they're lost |
463 | +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; |
464 | +CREATE TABLE t1(a INT); |
465 | +LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 |
466 | +(@b) SET a=REVERSE(@b); |
467 | +--echo # should return 0 and 1 (10 reversed) |
468 | +SELECT * FROM t1; |
469 | + |
470 | +DROP TABLE t1; |
471 | +let $MYSQLD_DATADIR= `select @@datadir`; |
472 | +remove_file $MYSQLD_DATADIR/test/tmpp2.txt; |
473 | + |
474 | + |
475 | + |
476 | # |
477 | # BUG3946 |
478 | # |
479 | |
480 | === modified file 'Percona-Server/mysql-test/t/loaddata.test' |
481 | --- Percona-Server/mysql-test/t/loaddata.test 2011-11-24 02:00:56 +0000 |
482 | +++ Percona-Server/mysql-test/t/loaddata.test 2013-01-10 04:35:33 +0000 |
483 | @@ -580,36 +580,40 @@ |
484 | connection default; |
485 | disconnect con1; |
486 | |
487 | - |
488 | ---echo # |
489 | ---echo # Bug #51876 : crash/memory underrun when loading data with ucs2 |
490 | ---echo # and reverse() function |
491 | ---echo # |
492 | - |
493 | ---echo # Problem # 1 (original report): wrong parsing of ucs2 data |
494 | -SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; |
495 | -CREATE TABLE t1(a INT); |
496 | -LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 |
497 | -(@b) SET a=REVERSE(@b); |
498 | ---echo # should return 2 zeroes (as the value is truncated) |
499 | -SELECT * FROM t1; |
500 | - |
501 | -DROP TABLE t1; |
502 | -let $MYSQLD_DATADIR= `select @@datadir`; |
503 | -remove_file $MYSQLD_DATADIR/test/tmpp.txt; |
504 | - |
505 | - |
506 | ---echo # Problem # 2 : if you write and read ucs2 data to a file they're lost |
507 | -SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; |
508 | -CREATE TABLE t1(a INT); |
509 | -LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 |
510 | -(@b) SET a=REVERSE(@b); |
511 | ---echo # should return 0 and 1 (10 reversed) |
512 | -SELECT * FROM t1; |
513 | - |
514 | -DROP TABLE t1; |
515 | -let $MYSQLD_DATADIR= `select @@datadir`; |
516 | -remove_file $MYSQLD_DATADIR/test/tmpp2.txt; |
517 | +############################################################################# |
518 | +# The below protion is moved to ctype_ucs.test # |
519 | +############################################################################# |
520 | +#--echo # |
521 | +#--echo # Bug #51876 : crash/memory underrun when loading data with ucs2 |
522 | +#--echo # and reverse() function |
523 | +#--echo # |
524 | + |
525 | +#--echo # Problem # 1 (original report): wrong parsing of ucs2 data |
526 | +#SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; |
527 | +#CREATE TABLE t1(a INT); |
528 | +#LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 |
529 | +#(@b) SET a=REVERSE(@b); |
530 | +#--echo # should return 2 zeroes (as the value is truncated) |
531 | +#SELECT * FROM t1; |
532 | + |
533 | +#DROP TABLE t1; |
534 | +#let $MYSQLD_DATADIR= `select @@datadir`; |
535 | +#remove_file $MYSQLD_DATADIR/test/tmpp.txt; |
536 | + |
537 | + |
538 | +#--echo # Problem # 2 : if you write and read ucs2 data to a file they're lost |
539 | +#SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; |
540 | +#CREATE TABLE t1(a INT); |
541 | +#LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 |
542 | +#(@b) SET a=REVERSE(@b); |
543 | +#--echo # should return 0 and 1 (10 reversed) |
544 | +#SELECT * FROM t1; |
545 | + |
546 | +#DROP TABLE t1; |
547 | +#let $MYSQLD_DATADIR= `select @@datadir`; |
548 | +#remove_file $MYSQLD_DATADIR/test/tmpp2.txt; |
549 | +###################################################################################### |
550 | + |
551 | |
552 | --echo # |
553 | --echo # Bug#11765139 58069: LOAD DATA INFILE: VALGRIND REPORTS INVALID MEMORY READS AND WRITES WITH U |
554 | |
555 | === modified file 'Percona-Server/mysql-test/t/sp_notembedded.test' |
556 | --- Percona-Server/mysql-test/t/sp_notembedded.test 2012-03-28 06:35:31 +0000 |
557 | +++ Percona-Server/mysql-test/t/sp_notembedded.test 2013-01-10 04:35:33 +0000 |
558 | @@ -371,16 +371,6 @@ |
559 | FLUSH PRIVILEGES; |
560 | |
561 | |
562 | -# |
563 | -# Restore global concurrent_insert value. Keep in the end of the test file. |
564 | -# |
565 | - |
566 | -set @@global.concurrent_insert= @old_concurrent_insert; |
567 | - |
568 | -# Wait till all disconnects are completed |
569 | ---source include/wait_until_count_sessions.inc |
570 | - |
571 | - |
572 | --echo # |
573 | --echo # Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al. |
574 | --echo # |
575 | @@ -476,3 +466,13 @@ |
576 | --echo # ------------------------------------------------------------------ |
577 | --echo # -- End of 5.1 tests |
578 | --echo # ------------------------------------------------------------------ |
579 | + |
580 | + |
581 | +# |
582 | +# Restore global concurrent_insert value. Keep in the end of the test file. |
583 | +# |
584 | + |
585 | +set @@global.concurrent_insert= @old_concurrent_insert; |
586 | + |
587 | +# Wait till all disconnects are completed |
588 | +--source include/wait_until_count_sessions.inc |
589 | |
590 | === modified file 'Percona-Server/scripts/mysql_install_db.pl.in' |
591 | --- Percona-Server/scripts/mysql_install_db.pl.in 2012-02-15 16:21:38 +0000 |
592 | +++ Percona-Server/scripts/mysql_install_db.pl.in 2013-01-10 04:35:33 +0000 |
593 | @@ -423,10 +423,11 @@ |
594 | "--bootstrap", |
595 | "--basedir=$opt->{basedir}", |
596 | "--datadir=$opt->{ldata}", |
597 | - "--skip-innodb", |
598 | - "--skip-bdb", |
599 | - "--skip-ndbcluster", |
600 | + "--log-warnings=0", |
601 | + "--loose-skip-innodb", |
602 | + "--loose-skip-ndbcluster", |
603 | "--max_allowed_packet=8M", |
604 | + "--default-storage-engine=MyISAM", |
605 | "--net_buffer_length=16K", |
606 | @args, |
607 | ); |
608 | @@ -439,6 +440,8 @@ |
609 | |
610 | open(SQL, $create_system_tables) |
611 | or error($opt,"can't open $create_system_tables for reading: $!"); |
612 | +open(SQL2, $fill_system_tables) |
613 | + or error($opt,"can't open $fill_system_tables for reading: $!"); |
614 | # FIXME > /dev/null ? |
615 | if ( open(PIPE, "| $mysqld_install_cmd_line") ) |
616 | { |
617 | @@ -452,8 +455,20 @@ |
618 | |
619 | print PIPE $_; |
620 | } |
621 | + while ( <SQL2> ) |
622 | + { |
623 | + # TODO: make it similar to the above condition when we're sure |
624 | + # @@hostname returns a fqdn |
625 | + # When doing a "cross bootstrap" install, no reference to the current |
626 | + # host should be added to the system tables. So we filter out any |
627 | + # lines which contain the current host name. |
628 | + next if /\@current_hostname/; |
629 | + |
630 | + print PIPE $_; |
631 | + } |
632 | close PIPE; |
633 | close SQL; |
634 | + close SQL2; |
635 | |
636 | report_verbose($opt,"OK"); |
637 | |
638 | |
639 | === modified file 'Percona-Server/scripts/mysqld_multi.sh' |
640 | --- Percona-Server/scripts/mysqld_multi.sh 2011-06-30 15:37:13 +0000 |
641 | +++ Percona-Server/scripts/mysqld_multi.sh 2013-01-10 04:35:33 +0000 |
642 | @@ -47,6 +47,28 @@ |
643 | $my_progname = $0; |
644 | $my_progname =~ s/.*[\/]//; |
645 | |
646 | + |
647 | +if (defined($ENV{UMASK})) { |
648 | + my $UMASK = $ENV{UMASK}; |
649 | + my $m; |
650 | + my $fmode = "0640"; |
651 | + |
652 | + if(($UMASK =~ m/[^0246]/) || ($UMASK =~ m/^[^0]/) || (length($UMASK) != 4)) { |
653 | + printf("UMASK must be a 3-digit mode with an additional leading 0 to indicate octal.\n"); |
654 | + printf("The first digit will be corrected to 6, the others may be 0, 2, 4, or 6.\n"); } |
655 | + else { |
656 | + $fmode= substr $UMASK, 2, 2; |
657 | + $fmode= "06${fmode}"; } |
658 | + |
659 | + if($fmode != $UMASK) { |
660 | + printf("UMASK corrected from $UMASK to $fmode ...\n"); } |
661 | + |
662 | + $fmode= oct($fmode); |
663 | + |
664 | + umask($fmode); |
665 | +} |
666 | + |
667 | + |
668 | main(); |
669 | |
670 | #### |
671 | |
672 | === modified file 'Percona-Server/scripts/mysqld_safe.sh' |
673 | --- Percona-Server/scripts/mysqld_safe.sh 2010-04-09 11:47:18 +0000 |
674 | +++ Percona-Server/scripts/mysqld_safe.sh 2013-01-10 04:35:33 +0000 |
675 | @@ -27,7 +27,28 @@ |
676 | |
677 | trap '' 1 2 3 15 # we shouldn't let anyone kill us |
678 | |
679 | -umask 007 |
680 | +# MySQL-specific environment variable. First off, it's not really a umask, |
681 | +# it's the desired mode. Second, it follows umask(2), not umask(3) in that |
682 | +# octal needs to be explicit. Our shell might be a proper sh without printf, |
683 | +# multiple-base arithmetic, and binary arithmetic, so this will get ugly. |
684 | +# We reject decimal values to keep things at least half-sane. |
685 | +umask 007 # fallback |
686 | +UMASK="${UMASK-0640}" |
687 | +fmode=`echo "$UMASK" | sed -e 's/[^0246]//g'` |
688 | +octalp=`echo "$fmode"|cut -c1` |
689 | +fmlen=`echo "$fmode"|wc -c|sed -e 's/ //g'` |
690 | +if [ "x$octalp" != "x0" -o "x$UMASK" != "x$fmode" -o "x$fmlen" != "x5" ] |
691 | +then |
692 | + fmode=0640 |
693 | + echo "UMASK must be a 3-digit mode with an additional leading 0 to indicate octal." >&2 |
694 | + echo "The first digit will be corrected to 6, the others may be 0, 2, 4, or 6." >&2 |
695 | +fi |
696 | +fmode=`echo "$fmode"|cut -c3-4` |
697 | +fmode="6$fmode" |
698 | +if [ "x$UMASK" != "x0$fmode" ] |
699 | +then |
700 | + echo "UMASK corrected from $UMASK to 0$fmode ..." |
701 | +fi |
702 | |
703 | defaults= |
704 | case "$1" in |
705 | @@ -371,6 +392,12 @@ |
706 | # Log to err_log file |
707 | log_notice "Logging to '$err_log'." |
708 | logging=file |
709 | + |
710 | + if [ ! -e "$err_log" ]; then # if error log already exists, |
711 | + touch "$err_log" # we just append. otherwise, |
712 | + chmod "$fmode" "$err_log" # fix the permissions here! |
713 | + fi |
714 | + |
715 | else |
716 | if [ -n "$syslog_tag" ] |
717 | then |
718 | @@ -572,6 +599,12 @@ |
719 | |
720 | eval_log_error "$cmd" |
721 | |
722 | + if [ $want_syslog -eq 0 -a ! -e "$err_log" ]; then |
723 | + touch "$err_log" # hypothetical: log was renamed but not |
724 | + chown $user "$err_log" # flushed yet. we'd recreate it with |
725 | + chmod "$fmode" "$err_log" # wrong owner next time we log, so set |
726 | + fi # it up correctly while we can! |
727 | + |
728 | if test ! -f "$pid_file" # This is removed if normal shutdown |
729 | then |
730 | break |
731 | |
732 | === modified file 'Percona-Server/sql/hostname.cc' |
733 | --- Percona-Server/sql/hostname.cc 2012-06-19 07:26:40 +0000 |
734 | +++ Percona-Server/sql/hostname.cc 2013-01-10 04:35:33 +0000 |
735 | @@ -214,6 +214,15 @@ |
736 | } |
737 | my_gethostbyname_r_free(); |
738 | #else |
739 | + |
740 | + DBUG_EXECUTE_IF("addr_fake_ipv4", |
741 | + { |
742 | + const char* fake_host= "santa.claus.ipv4.example.com"; |
743 | + name=my_strdup(fake_host, MYF(0)); |
744 | + add_hostname(in,name); |
745 | + DBUG_RETURN(name); |
746 | + };); |
747 | + |
748 | VOID(pthread_mutex_lock(&LOCK_hostname)); |
749 | if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET))) |
750 | { |
751 | |
752 | === modified file 'Percona-Server/sql/item_cmpfunc.cc' |
753 | --- Percona-Server/sql/item_cmpfunc.cc 2011-07-03 15:47:37 +0000 |
754 | +++ Percona-Server/sql/item_cmpfunc.cc 2013-01-10 04:35:33 +0000 |
755 | @@ -1,4 +1,4 @@ |
756 | -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. |
757 | +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
758 | |
759 | This program is free software; you can redistribute it and/or modify |
760 | it under the terms of the GNU General Public License as published by |
761 | @@ -3045,6 +3045,15 @@ |
762 | return; |
763 | } |
764 | } |
765 | + /* |
766 | + Set cmp_context of all WHEN arguments. This prevents |
767 | + Item_field::equal_fields_propagator() from transforming a |
768 | + zerofill argument into a string constant. Such a change would |
769 | + require rebuilding cmp_items. |
770 | + */ |
771 | + for (i= 0; i < ncases; i+= 2) |
772 | + args[i]->cmp_context= item_cmp_type(left_result_type, |
773 | + args[i]->result_type()); |
774 | } |
775 | |
776 | if (else_expr_num == -1 || args[else_expr_num]->maybe_null) |
777 | @@ -4032,6 +4041,16 @@ |
778 | } |
779 | } |
780 | } |
781 | + /* |
782 | + Set cmp_context of all arguments. This prevents |
783 | + Item_field::equal_fields_propagator() from transforming a zerofill integer |
784 | + argument into a string constant. Such a change would require rebuilding |
785 | + cmp_itmes. |
786 | + */ |
787 | + for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++) |
788 | + { |
789 | + arg[0]->cmp_context= item_cmp_type(left_result_type, arg[0]->result_type()); |
790 | + } |
791 | max_length= 1; |
792 | } |
793 | |
794 | |
795 | === modified file 'Percona-Server/sql/item_func.cc' |
796 | --- Percona-Server/sql/item_func.cc 2012-10-05 07:20:04 +0000 |
797 | +++ Percona-Server/sql/item_func.cc 2013-01-10 04:35:33 +0000 |
798 | @@ -3596,7 +3596,8 @@ |
799 | thd->first_successful_insert_id_in_prev_stmt= value; |
800 | return value; |
801 | } |
802 | - return thd->read_first_successful_insert_id_in_prev_stmt(); |
803 | + return |
804 | + static_cast<longlong>(thd->read_first_successful_insert_id_in_prev_stmt()); |
805 | } |
806 | |
807 | |
808 | |
809 | === modified file 'Percona-Server/sql/item_func.h' |
810 | --- Percona-Server/sql/item_func.h 2012-10-05 07:20:04 +0000 |
811 | +++ Percona-Server/sql/item_func.h 2013-01-10 04:35:33 +0000 |
812 | @@ -1043,6 +1043,7 @@ |
813 | const char *func_name() const { return "last_insert_id"; } |
814 | void fix_length_and_dec() |
815 | { |
816 | + unsigned_flag= TRUE; |
817 | if (arg_count) |
818 | max_length= args[0]->max_length; |
819 | } |
820 | |
821 | === modified file 'Percona-Server/sql/log.cc' |
822 | --- Percona-Server/sql/log.cc 2013-01-03 00:03:10 +0000 |
823 | +++ Percona-Server/sql/log.cc 2013-01-10 04:35:33 +0000 |
824 | @@ -4448,10 +4448,16 @@ |
825 | /* |
826 | Write pending event to log file or transaction cache |
827 | */ |
828 | + DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending", |
829 | + {DBUG_SET("+d,simulate_file_write_error");}); |
830 | if (pending->write(file)) |
831 | { |
832 | pthread_mutex_unlock(&LOCK_log); |
833 | set_write_error(thd); |
834 | + delete pending; |
835 | + trx_data->set_pending(NULL); |
836 | + DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending", |
837 | + {DBUG_SET("-d,simulate_file_write_error");}); |
838 | DBUG_RETURN(1); |
839 | } |
840 | |
841 | |
842 | === modified file 'Percona-Server/sql/log_event.cc' |
843 | --- Percona-Server/sql/log_event.cc 2012-12-30 12:35:56 +0000 |
844 | +++ Percona-Server/sql/log_event.cc 2013-01-10 04:35:33 +0000 |
845 | @@ -54,6 +54,22 @@ |
846 | */ |
847 | #define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1) |
848 | |
849 | +/* |
850 | + Explicit instantiation to unsigned int of template available_buffer |
851 | + function. |
852 | +*/ |
853 | +template unsigned int available_buffer<unsigned int>(const char*, |
854 | + const char*, |
855 | + unsigned int); |
856 | + |
857 | +/* |
858 | + Explicit instantiation to unsigned int of template valid_buffer_range |
859 | + function. |
860 | +*/ |
861 | +template bool valid_buffer_range<unsigned int>(unsigned int, |
862 | + const char*, |
863 | + const char*, |
864 | + unsigned int); |
865 | |
866 | #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) |
867 | static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd); |
868 | @@ -1286,7 +1302,7 @@ |
869 | ev = new Rand_log_event(buf, description_event); |
870 | break; |
871 | case USER_VAR_EVENT: |
872 | - ev = new User_var_log_event(buf, description_event); |
873 | + ev = new User_var_log_event(buf, event_len, description_event); |
874 | break; |
875 | case FORMAT_DESCRIPTION_EVENT: |
876 | ev = new Format_description_log_event(buf, event_len, description_event); |
877 | @@ -5755,18 +5771,34 @@ |
878 | |
879 | |
880 | User_var_log_event:: |
881 | -User_var_log_event(const char* buf, |
882 | +User_var_log_event(const char* buf, uint event_len, |
883 | const Format_description_log_event* description_event) |
884 | :Log_event(buf, description_event) |
885 | #ifndef MYSQL_CLIENT |
886 | , deferred(false) |
887 | #endif |
888 | { |
889 | + bool error= false; |
890 | + const char* buf_start= buf; |
891 | /* The Post-Header is empty. The Variable Data part begins immediately. */ |
892 | buf+= description_event->common_header_len + |
893 | description_event->post_header_len[USER_VAR_EVENT-1]; |
894 | name_len= uint4korr(buf); |
895 | name= (char *) buf + UV_NAME_LEN_SIZE; |
896 | + |
897 | + /* |
898 | + We don't know yet is_null value, so we must assume that name_len |
899 | + may have the bigger value possible, is_null= True and there is no |
900 | + payload for val. |
901 | + */ |
902 | + if (0 == name_len || |
903 | + !valid_buffer_range<uint>(name_len, buf_start, name, |
904 | + event_len - UV_VAL_IS_NULL)) |
905 | + { |
906 | + error= true; |
907 | + goto err; |
908 | + } |
909 | + |
910 | buf+= UV_NAME_LEN_SIZE + name_len; |
911 | is_null= (bool) *buf; |
912 | if (is_null) |
913 | @@ -5778,13 +5810,31 @@ |
914 | } |
915 | else |
916 | { |
917 | + if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE |
918 | + + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE, |
919 | + buf_start, buf, event_len)) |
920 | + { |
921 | + error= true; |
922 | + goto err; |
923 | + } |
924 | + |
925 | type= (Item_result) buf[UV_VAL_IS_NULL]; |
926 | charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE); |
927 | val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + |
928 | UV_CHARSET_NUMBER_SIZE); |
929 | val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + |
930 | UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE); |
931 | + |
932 | + if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len)) |
933 | + { |
934 | + error= true; |
935 | + goto err; |
936 | + } |
937 | } |
938 | + |
939 | +err: |
940 | + if (error) |
941 | + name= 0; |
942 | } |
943 | |
944 | |
945 | @@ -5931,8 +5981,9 @@ |
946 | char *hex_str; |
947 | CHARSET_INFO *cs; |
948 | |
949 | - if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte |
950 | - break; // no error, as we are 'void' |
951 | + hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte |
952 | + if (!hex_str) |
953 | + return; |
954 | str_to_hex(hex_str, val, val_len); |
955 | /* |
956 | For proper behaviour when mysqlbinlog|mysql, we need to explicitely |
957 | |
958 | === modified file 'Percona-Server/sql/log_event.h' |
959 | --- Percona-Server/sql/log_event.h 2013-01-10 04:35:31 +0000 |
960 | +++ Percona-Server/sql/log_event.h 2013-01-10 04:35:33 +0000 |
961 | @@ -2517,7 +2517,7 @@ |
962 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
963 | #endif |
964 | |
965 | - User_var_log_event(const char* buf, |
966 | + User_var_log_event(const char* buf, uint event_len, |
967 | const Format_description_log_event *description_event); |
968 | ~User_var_log_event() {} |
969 | Log_event_type get_type_code() { return USER_VAR_EVENT;} |
970 | @@ -2529,9 +2529,9 @@ |
971 | and which case the applier adjusts execution path. |
972 | */ |
973 | bool is_deferred() { return deferred; } |
974 | - void set_deferred() { deferred= val; } |
975 | + void set_deferred() { deferred= true; } |
976 | #endif |
977 | - bool is_valid() const { return 1; } |
978 | + bool is_valid() const { return name != 0; } |
979 | |
980 | private: |
981 | #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) |
982 | |
983 | === modified file 'Percona-Server/sql/mysql_priv.h' |
984 | --- Percona-Server/sql/mysql_priv.h 2012-10-05 07:20:04 +0000 |
985 | +++ Percona-Server/sql/mysql_priv.h 2013-01-10 04:35:33 +0000 |
986 | @@ -505,6 +505,41 @@ |
987 | */ |
988 | #define MAX_TIME_ZONE_NAME_LENGTH (NAME_LEN + 1) |
989 | |
990 | +/* |
991 | + Check how many bytes are available on buffer. |
992 | + |
993 | + @param buf_start Pointer to buffer start. |
994 | + @param buf_current Pointer to the current position on buffer. |
995 | + @param buf_len Buffer length. |
996 | + |
997 | + @return Number of bytes available on event buffer. |
998 | +*/ |
999 | +template <class T> T available_buffer(const char* buf_start, |
1000 | + const char* buf_current, |
1001 | + T buf_len) |
1002 | +{ |
1003 | + return buf_len - (buf_current - buf_start); |
1004 | +} |
1005 | + |
1006 | +/* |
1007 | + Check if jump value is within buffer limits. |
1008 | + |
1009 | + @param jump Number of positions we want to advance. |
1010 | + @param buf_start Pointer to buffer start |
1011 | + @param buf_current Pointer to the current position on buffer. |
1012 | + @param buf_len Buffer length. |
1013 | + |
1014 | + @return True If jump value is within buffer limits. |
1015 | + False Otherwise. |
1016 | +*/ |
1017 | +template <class T> bool valid_buffer_range(T jump, |
1018 | + const char* buf_start, |
1019 | + const char* buf_current, |
1020 | + T buf_len) |
1021 | +{ |
1022 | + return (jump <= available_buffer(buf_start, buf_current, buf_len)); |
1023 | +} |
1024 | + |
1025 | /* The rest of the file is included in the server only */ |
1026 | #ifndef MYSQL_CLIENT |
1027 | |
1028 | |
1029 | === modified file 'Percona-Server/sql/mysqld.cc' |
1030 | --- Percona-Server/sql/mysqld.cc 2013-01-10 04:35:31 +0000 |
1031 | +++ Percona-Server/sql/mysqld.cc 2013-01-10 04:35:33 +0000 |
1032 | @@ -4981,7 +4981,7 @@ |
1033 | if (cached_thread_count > wake_thread) |
1034 | { |
1035 | /* Get thread from cache */ |
1036 | - thread_cache.append(thd); |
1037 | + thread_cache.push_back(thd); |
1038 | wake_thread++; |
1039 | pthread_cond_signal(&COND_thread_cache); |
1040 | } |
1041 | |
1042 | === modified file 'Percona-Server/sql/sp_head.cc' |
1043 | --- Percona-Server/sql/sp_head.cc 2012-10-15 15:08:07 +0000 |
1044 | +++ Percona-Server/sql/sp_head.cc 2013-01-10 04:35:33 +0000 |
1045 | @@ -3860,8 +3860,6 @@ |
1046 | Multi-set key: |
1047 | db_name\0table_name\0alias\0 - for normal tables |
1048 | db_name\0table_name\0 - for temporary tables |
1049 | - Note that in both cases we don't take last '\0' into account when |
1050 | - we count length of key. |
1051 | */ |
1052 | LEX_STRING qname; |
1053 | uint db_length, table_name_length; |
1054 | @@ -3918,19 +3916,26 @@ |
1055 | for (; table ; table= table->next_global) |
1056 | if (!table->derived && !table->schema_table) |
1057 | { |
1058 | - char tname[(NAME_LEN + 1) * 3]; // db\0table\0alias\0 |
1059 | - uint tlen, alen; |
1060 | + /* |
1061 | + Structure of key for the multi-set is "db\0table\0alias\0". |
1062 | + Since "alias" part can have arbitrary length we use String |
1063 | + object to construct the key. By default String will use |
1064 | + buffer allocated on stack with NAME_LEN bytes reserved for |
1065 | + alias, since in most cases it is going to be smaller than |
1066 | + NAME_LEN bytes. |
1067 | + */ |
1068 | + char tname_buff[(NAME_LEN + 1) * 3]; |
1069 | + String tname(tname_buff, sizeof(tname_buff), &my_charset_bin); |
1070 | + uint temp_table_key_length; |
1071 | |
1072 | - tlen= table->db_length; |
1073 | - memcpy(tname, table->db, tlen); |
1074 | - tname[tlen++]= '\0'; |
1075 | - memcpy(tname+tlen, table->table_name, table->table_name_length); |
1076 | - tlen+= table->table_name_length; |
1077 | - tname[tlen++]= '\0'; |
1078 | - alen= strlen(table->alias); |
1079 | - memcpy(tname+tlen, table->alias, alen); |
1080 | - tlen+= alen; |
1081 | - tname[tlen]= '\0'; |
1082 | + tname.length(0); |
1083 | + tname.append(table->db, table->db_length); |
1084 | + tname.append('\0'); |
1085 | + tname.append(table->table_name, table->table_name_length); |
1086 | + tname.append('\0'); |
1087 | + temp_table_key_length= tname.length(); |
1088 | + tname.append(table->alias); |
1089 | + tname.append('\0'); |
1090 | |
1091 | /* |
1092 | Upgrade the lock type because this table list will be used |
1093 | @@ -3945,9 +3950,10 @@ |
1094 | (and therefore should not be prelocked). Otherwise we will erroneously |
1095 | treat table with same name but with different alias as non-temporary. |
1096 | */ |
1097 | - if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, tlen)) || |
1098 | - ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, |
1099 | - tlen - alen - 1)) && |
1100 | + if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(), |
1101 | + tname.length())) || |
1102 | + ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(), |
1103 | + temp_table_key_length)) && |
1104 | tab->temp)) |
1105 | { |
1106 | if (tab->lock_type < table->lock_type) |
1107 | @@ -3966,11 +3972,11 @@ |
1108 | lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE) |
1109 | { |
1110 | tab->temp= TRUE; |
1111 | - tab->qname.length= tlen - alen - 1; |
1112 | + tab->qname.length= temp_table_key_length; |
1113 | } |
1114 | else |
1115 | - tab->qname.length= tlen; |
1116 | - tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1); |
1117 | + tab->qname.length= tname.length(); |
1118 | + tab->qname.str= (char*) thd->memdup(tname.ptr(), tab->qname.length); |
1119 | if (!tab->qname.str) |
1120 | return FALSE; |
1121 | tab->table_name_length= table->table_name_length; |
1122 | @@ -4039,7 +4045,7 @@ |
1123 | if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) * |
1124 | stab->lock_count)) || |
1125 | !(key_buff= (char*)thd->memdup(stab->qname.str, |
1126 | - stab->qname.length + 1))) |
1127 | + stab->qname.length))) |
1128 | DBUG_RETURN(FALSE); |
1129 | |
1130 | for (uint j= 0; j < stab->lock_count; j++) |
1131 | |
1132 | === modified file 'Percona-Server/sql/sql_acl.cc' |
1133 | --- Percona-Server/sql/sql_acl.cc 2012-11-28 22:39:45 +0000 |
1134 | +++ Percona-Server/sql/sql_acl.cc 2013-01-10 04:35:33 +0000 |
1135 | @@ -195,7 +195,17 @@ |
1136 | static my_bool acl_load(THD *thd, TABLE_LIST *tables); |
1137 | static my_bool grant_load(THD *thd, TABLE_LIST *tables); |
1138 | static inline void get_grantor(THD *thd, char* grantor); |
1139 | - |
1140 | +/* |
1141 | + Enumeration of various ACL's and Hashes used in handle_grant_struct() |
1142 | +*/ |
1143 | +enum enum_acl_lists |
1144 | +{ |
1145 | + USER_ACL= 0, |
1146 | + DB_ACL, |
1147 | + COLUMN_PRIVILEGES_HASH, |
1148 | + PROC_PRIVILEGES_HASH, |
1149 | + FUNC_PRIVILEGES_HASH |
1150 | +}; |
1151 | /* |
1152 | Convert scrambled password to binary form, according to scramble type, |
1153 | Binary form is stored in user.salt. |
1154 | @@ -1346,10 +1356,19 @@ |
1155 | { |
1156 | ulong host_access= ~(ulong)0, db_access= 0; |
1157 | uint i; |
1158 | - size_t key_length; |
1159 | + size_t key_length, copy_length; |
1160 | char key[ACL_KEY_LENGTH],*tmp_db,*end; |
1161 | acl_entry *entry; |
1162 | DBUG_ENTER("acl_get"); |
1163 | + |
1164 | + copy_length= (size_t) (strlen(ip ? ip : "") + |
1165 | + strlen(user ? user : "") + |
1166 | + strlen(db ? db : "")); |
1167 | + /* |
1168 | + Make sure that strmov() operations do not result in buffer overflow. |
1169 | + */ |
1170 | + if (copy_length >= ACL_KEY_LENGTH) |
1171 | + DBUG_RETURN(0); |
1172 | |
1173 | tmp_db= strmov(strmov(key, ip ? ip : "") + 1, user) + 1; |
1174 | end= strnmov(tmp_db, db, key + sizeof(key) - tmp_db); |
1175 | @@ -4336,6 +4355,16 @@ |
1176 | char helping [NAME_LEN+USERNAME_LENGTH+2], *end; |
1177 | uint len; |
1178 | bool error= TRUE; |
1179 | + size_t copy_length; |
1180 | + |
1181 | + copy_length= (size_t) (strlen(sctx->priv_user ? sctx->priv_user : "") + |
1182 | + strlen(db ? db : "")); |
1183 | + |
1184 | + /* |
1185 | + Make sure that strmov() operations do not result in buffer overflow. |
1186 | + */ |
1187 | + if (copy_length >= (NAME_LEN+USERNAME_LENGTH+2)) |
1188 | + return 1; |
1189 | |
1190 | end= strmov(helping, sctx->priv_user) + 1; |
1191 | end= strnmov(end, db, helping + sizeof(helping) - end); |
1192 | @@ -5402,19 +5431,19 @@ |
1193 | Delete from grant structure if drop is true. |
1194 | Update in grant structure if drop is false and user_to is not NULL. |
1195 | Search in grant structure if drop is false and user_to is NULL. |
1196 | - Structures are numbered as follows: |
1197 | - 0 acl_users |
1198 | - 1 acl_dbs |
1199 | - 2 column_priv_hash |
1200 | - 3 proc_priv_hash |
1201 | - 4 func_priv_hash |
1202 | + Structures are enumerated as follows: |
1203 | + 0 ACL_USER |
1204 | + 1 ACL_DB |
1205 | + 2 COLUMN_PRIVILEGES_HASH |
1206 | + 3 PROC_PRIVILEGES_HASH |
1207 | + 4 FUNC_PRIVILEGES_HASH |
1208 | |
1209 | @retval > 0 At least one element matched. |
1210 | @retval 0 OK, but no element matched. |
1211 | - @retval -1 Wrong arguments to function. |
1212 | + @retval -1 Wrong arguments to function or Out of Memory |
1213 | */ |
1214 | |
1215 | -static int handle_grant_struct(uint struct_no, bool drop, |
1216 | +static int handle_grant_struct(enum enum_acl_lists struct_no, bool drop, |
1217 | LEX_USER *user_from, LEX_USER *user_to) |
1218 | { |
1219 | int result= 0; |
1220 | @@ -5425,6 +5454,11 @@ |
1221 | ACL_USER *acl_user= NULL; |
1222 | ACL_DB *acl_db= NULL; |
1223 | GRANT_NAME *grant_name= NULL; |
1224 | + /* |
1225 | + Dynamic array acl_grant_name used to store pointers to all |
1226 | + GRANT_NAME objects |
1227 | + */ |
1228 | + Dynamic_array<GRANT_NAME *> acl_grant_name; |
1229 | HASH *grant_name_hash= NULL; |
1230 | DBUG_ENTER("handle_grant_struct"); |
1231 | DBUG_PRINT("info",("scan struct: %u search: '%s'@'%s'", |
1232 | @@ -5437,21 +5471,21 @@ |
1233 | |
1234 | /* Get the number of elements in the in-memory structure. */ |
1235 | switch (struct_no) { |
1236 | - case 0: |
1237 | + case USER_ACL: |
1238 | elements= acl_users.elements; |
1239 | break; |
1240 | - case 1: |
1241 | + case DB_ACL: |
1242 | elements= acl_dbs.elements; |
1243 | break; |
1244 | - case 2: |
1245 | + case COLUMN_PRIVILEGES_HASH: |
1246 | elements= column_priv_hash.records; |
1247 | grant_name_hash= &column_priv_hash; |
1248 | break; |
1249 | - case 3: |
1250 | + case PROC_PRIVILEGES_HASH: |
1251 | elements= proc_priv_hash.records; |
1252 | grant_name_hash= &proc_priv_hash; |
1253 | break; |
1254 | - case 4: |
1255 | + case FUNC_PRIVILEGES_HASH: |
1256 | elements= func_priv_hash.records; |
1257 | grant_name_hash= &func_priv_hash; |
1258 | break; |
1259 | @@ -5470,21 +5504,21 @@ |
1260 | Get a pointer to the element. |
1261 | */ |
1262 | switch (struct_no) { |
1263 | - case 0: |
1264 | + case USER_ACL: |
1265 | acl_user= dynamic_element(&acl_users, idx, ACL_USER*); |
1266 | user= acl_user->user; |
1267 | host= acl_user->host.hostname; |
1268 | break; |
1269 | |
1270 | - case 1: |
1271 | + case DB_ACL: |
1272 | acl_db= dynamic_element(&acl_dbs, idx, ACL_DB*); |
1273 | user= acl_db->user; |
1274 | host= acl_db->host.hostname; |
1275 | break; |
1276 | |
1277 | - case 2: |
1278 | - case 3: |
1279 | - case 4: |
1280 | + case COLUMN_PRIVILEGES_HASH: |
1281 | + case PROC_PRIVILEGES_HASH: |
1282 | + case FUNC_PRIVILEGES_HASH: |
1283 | grant_name= (GRANT_NAME*) hash_element(grant_name_hash, idx); |
1284 | user= grant_name->user; |
1285 | host= grant_name->host.hostname; |
1286 | @@ -5510,86 +5544,60 @@ |
1287 | if ( drop ) |
1288 | { |
1289 | switch ( struct_no ) { |
1290 | - case 0: |
1291 | + case USER_ACL: |
1292 | delete_dynamic_element(&acl_users, idx); |
1293 | - break; |
1294 | - |
1295 | - case 1: |
1296 | - delete_dynamic_element(&acl_dbs, idx); |
1297 | - break; |
1298 | - |
1299 | - case 2: |
1300 | - case 3: |
1301 | - case 4: |
1302 | - hash_delete(grant_name_hash, (uchar*) grant_name); |
1303 | - break; |
1304 | - } |
1305 | - elements--; |
1306 | - /* |
1307 | + elements--; |
1308 | + /* |
1309 | - If we are iterating through an array then we just have moved all |
1310 | elements after the current element one position closer to its head. |
1311 | This means that we have to take another look at the element at |
1312 | current position as it is a new element from the array's tail. |
1313 | - - If we are iterating through a hash the current element was replaced |
1314 | - with one of elements from the tail. So we also have to take a look |
1315 | - at the new element in current position. |
1316 | - Note that in our HASH implementation hash_delete() won't move any |
1317 | - elements with position after current one to position before the |
1318 | - current (i.e. from the tail to the head), so it is safe to continue |
1319 | - iteration without re-starting. |
1320 | - */ |
1321 | - idx--; |
1322 | + - This is valid for USER_ACL, DB_ACL. |
1323 | + */ |
1324 | + idx--; |
1325 | + break; |
1326 | + |
1327 | + case DB_ACL: |
1328 | + delete_dynamic_element(&acl_dbs, idx); |
1329 | + elements--; |
1330 | + idx--; |
1331 | + break; |
1332 | + |
1333 | + case COLUMN_PRIVILEGES_HASH: |
1334 | + case PROC_PRIVILEGES_HASH: |
1335 | + case FUNC_PRIVILEGES_HASH: |
1336 | + /* |
1337 | + Deleting while traversing a hash table is not valid procedure and |
1338 | + hence we save pointers to GRANT_NAME objects for later processing. |
1339 | + */ |
1340 | + if (acl_grant_name.append(grant_name)) |
1341 | + DBUG_RETURN(-1); |
1342 | + break; |
1343 | + } |
1344 | } |
1345 | else if ( user_to ) |
1346 | { |
1347 | switch ( struct_no ) { |
1348 | - case 0: |
1349 | + case USER_ACL: |
1350 | acl_user->user= strdup_root(&mem, user_to->user.str); |
1351 | acl_user->host.hostname= strdup_root(&mem, user_to->host.str); |
1352 | break; |
1353 | |
1354 | - case 1: |
1355 | + case DB_ACL: |
1356 | acl_db->user= strdup_root(&mem, user_to->user.str); |
1357 | acl_db->host.hostname= strdup_root(&mem, user_to->host.str); |
1358 | break; |
1359 | |
1360 | - case 2: |
1361 | - case 3: |
1362 | - case 4: |
1363 | - { |
1364 | - /* |
1365 | - Save old hash key and its length to be able properly update |
1366 | - element position in hash. |
1367 | - */ |
1368 | - char *old_key= grant_name->hash_key; |
1369 | - size_t old_key_length= grant_name->key_length; |
1370 | - |
1371 | - /* |
1372 | - Update the grant structure with the new user name and host name. |
1373 | - */ |
1374 | - grant_name->set_user_details(user_to->host.str, grant_name->db, |
1375 | - user_to->user.str, grant_name->tname, |
1376 | - TRUE); |
1377 | - |
1378 | - /* |
1379 | - Since username is part of the hash key, when the user name |
1380 | - is renamed, the hash key is changed. Update the hash to |
1381 | - ensure that the position matches the new hash key value |
1382 | - */ |
1383 | - hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key, |
1384 | - old_key_length); |
1385 | - /* |
1386 | - hash_update() operation could have moved element from the tail |
1387 | - of the hash to the current position. So we need to take a look |
1388 | - at the element in current position once again. |
1389 | - Thanks to the fact that hash_update() for our HASH implementation |
1390 | - won't move any elements from the tail of the hash to the positions |
1391 | - before the current one (a.k.a. head) it is safe to continue |
1392 | - iteration without restarting. |
1393 | - */ |
1394 | - idx--; |
1395 | - break; |
1396 | - } |
1397 | + case COLUMN_PRIVILEGES_HASH: |
1398 | + case PROC_PRIVILEGES_HASH: |
1399 | + case FUNC_PRIVILEGES_HASH: |
1400 | + /* |
1401 | + Updating while traversing a hash table is not valid procedure and |
1402 | + hence we save pointers to GRANT_NAME objects for later processing. |
1403 | + */ |
1404 | + if (acl_grant_name.append(grant_name)) |
1405 | + DBUG_RETURN(-1); |
1406 | + break; |
1407 | } |
1408 | } |
1409 | else |
1410 | @@ -5598,6 +5606,48 @@ |
1411 | break; |
1412 | } |
1413 | } |
1414 | + |
1415 | + if (drop || user_to) |
1416 | + { |
1417 | + /* |
1418 | + Traversing the elements stored in acl_grant_name dynamic array |
1419 | + to either delete or update them. |
1420 | + */ |
1421 | + for (int i= 0; i < acl_grant_name.elements(); ++i) |
1422 | + { |
1423 | + grant_name= acl_grant_name.at(i); |
1424 | + |
1425 | + if (drop) |
1426 | + { |
1427 | + my_hash_delete(grant_name_hash, (uchar *) grant_name); |
1428 | + } |
1429 | + else |
1430 | + { |
1431 | + /* |
1432 | + Save old hash key and its length to be able properly update |
1433 | + element position in hash. |
1434 | + */ |
1435 | + char *old_key= grant_name->hash_key; |
1436 | + size_t old_key_length= grant_name->key_length; |
1437 | + |
1438 | + /* |
1439 | + Update the grant structure with the new user name and host name. |
1440 | + */ |
1441 | + grant_name->set_user_details(user_to->host.str, grant_name->db, |
1442 | + user_to->user.str, grant_name->tname, |
1443 | + TRUE); |
1444 | + |
1445 | + /* |
1446 | + Since username is part of the hash key, when the user name |
1447 | + is renamed, the hash key is changed. Update the hash to |
1448 | + ensure that the position matches the new hash key value |
1449 | + */ |
1450 | + my_hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key, |
1451 | + old_key_length); |
1452 | + } |
1453 | + } |
1454 | + } |
1455 | + |
1456 | #ifdef EXTRA_DEBUG |
1457 | DBUG_PRINT("loop",("scan struct: %u result %d", struct_no, result)); |
1458 | #endif |
1459 | @@ -5635,6 +5685,7 @@ |
1460 | { |
1461 | int result= 0; |
1462 | int found; |
1463 | + int ret; |
1464 | DBUG_ENTER("handle_grant_data"); |
1465 | |
1466 | /* Handle user table. */ |
1467 | @@ -5646,14 +5697,19 @@ |
1468 | else |
1469 | { |
1470 | /* Handle user array. */ |
1471 | - if ((handle_grant_struct(0, drop, user_from, user_to) && ! result) || |
1472 | - found) |
1473 | + if (((ret= handle_grant_struct(USER_ACL, drop, user_from, user_to) > 0) && |
1474 | + ! result) || found) |
1475 | { |
1476 | result= 1; /* At least one record/element found. */ |
1477 | /* If search is requested, we do not need to search further. */ |
1478 | if (! drop && ! user_to) |
1479 | goto end; |
1480 | } |
1481 | + else if (ret < 0) |
1482 | + { |
1483 | + result= -1; |
1484 | + goto end; |
1485 | + } |
1486 | } |
1487 | |
1488 | /* Handle db table. */ |
1489 | @@ -5665,14 +5721,19 @@ |
1490 | else |
1491 | { |
1492 | /* Handle db array. */ |
1493 | - if (((handle_grant_struct(1, drop, user_from, user_to) && ! result) || |
1494 | - found) && ! result) |
1495 | + if ((((ret= handle_grant_struct(DB_ACL, drop, user_from, user_to) > 0) && |
1496 | + ! result) || found) && ! result) |
1497 | { |
1498 | result= 1; /* At least one record/element found. */ |
1499 | /* If search is requested, we do not need to search further. */ |
1500 | if (! drop && ! user_to) |
1501 | goto end; |
1502 | } |
1503 | + else if (ret < 0) |
1504 | + { |
1505 | + result= -1; |
1506 | + goto end; |
1507 | + } |
1508 | } |
1509 | |
1510 | /* Handle stored routines table. */ |
1511 | @@ -5684,23 +5745,35 @@ |
1512 | else |
1513 | { |
1514 | /* Handle procs array. */ |
1515 | - if (((handle_grant_struct(3, drop, user_from, user_to) && ! result) || |
1516 | - found) && ! result) |
1517 | + if ((((ret= handle_grant_struct(PROC_PRIVILEGES_HASH, drop, user_from, |
1518 | + user_to) > 0) && ! result) || found) && |
1519 | + ! result) |
1520 | { |
1521 | result= 1; /* At least one record/element found. */ |
1522 | /* If search is requested, we do not need to search further. */ |
1523 | if (! drop && ! user_to) |
1524 | goto end; |
1525 | } |
1526 | + else if (ret < 0) |
1527 | + { |
1528 | + result= -1; |
1529 | + goto end; |
1530 | + } |
1531 | /* Handle funcs array. */ |
1532 | - if (((handle_grant_struct(4, drop, user_from, user_to) && ! result) || |
1533 | - found) && ! result) |
1534 | + if ((((ret= handle_grant_struct(FUNC_PRIVILEGES_HASH, drop, user_from, |
1535 | + user_to) > 0) && ! result) || found) && |
1536 | + ! result) |
1537 | { |
1538 | result= 1; /* At least one record/element found. */ |
1539 | /* If search is requested, we do not need to search further. */ |
1540 | if (! drop && ! user_to) |
1541 | goto end; |
1542 | } |
1543 | + else if (ret < 0) |
1544 | + { |
1545 | + result= -1; |
1546 | + goto end; |
1547 | + } |
1548 | } |
1549 | |
1550 | /* Handle tables table. */ |
1551 | @@ -5728,9 +5801,12 @@ |
1552 | else |
1553 | { |
1554 | /* Handle columns hash. */ |
1555 | - if (((handle_grant_struct(2, drop, user_from, user_to) && ! result) || |
1556 | - found) && ! result) |
1557 | + if ((((ret= handle_grant_struct(COLUMN_PRIVILEGES_HASH, drop, user_from, |
1558 | + user_to) > 0) && ! result) || found) && |
1559 | + ! result) |
1560 | result= 1; /* At least one record/element found. */ |
1561 | + else if (ret < 0) |
1562 | + result= -1; |
1563 | } |
1564 | } |
1565 | end: |
1566 | |
1567 | === modified file 'Percona-Server/sql/sql_connect.cc' |
1568 | --- Percona-Server/sql/sql_connect.cc 2012-08-20 03:14:02 +0000 |
1569 | +++ Percona-Server/sql/sql_connect.cc 2013-01-10 04:35:33 +0000 |
1570 | @@ -914,6 +914,7 @@ |
1571 | |
1572 | USER_RESOURCES ur; |
1573 | int res= acl_getroot(thd, &ur, passwd, passwd_len); |
1574 | + DBUG_EXECUTE_IF("password_format_mismatch",{res= -1;};); |
1575 | #ifndef EMBEDDED_LIBRARY |
1576 | if (res == -1) |
1577 | { |
1578 | @@ -924,6 +925,12 @@ |
1579 | in old format. |
1580 | */ |
1581 | NET *net= &thd->net; |
1582 | + DBUG_EXECUTE_IF("password_format_mismatch", |
1583 | + { |
1584 | + inc_host_errors(&thd->remote.sin_addr); |
1585 | + my_error(ER_HANDSHAKE_ERROR, MYF(0)); |
1586 | + DBUG_RETURN(1); |
1587 | + };); |
1588 | if (opt_secure_auth_local) |
1589 | { |
1590 | my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0), |
1591 | @@ -1395,6 +1402,8 @@ |
1592 | size_t passwd_len; |
1593 | char *user; |
1594 | size_t user_len; |
1595 | + uint charset_code= 0; |
1596 | + size_t bytes_remaining_in_packet= 0; |
1597 | |
1598 | DBUG_PRINT("info", |
1599 | ("New connection received on %s", vio_description(net->vio))); |
1600 | @@ -1411,6 +1420,19 @@ |
1601 | my_error(ER_BAD_HOST_ERROR, MYF(0)); |
1602 | return 1; |
1603 | } |
1604 | + /* BEGIN : DEBUG */ |
1605 | + DBUG_EXECUTE_IF("addr_fake_ipv4", |
1606 | + { |
1607 | + struct sockaddr *sa= (sockaddr *) &net->vio->remote; |
1608 | + sa->sa_family= AF_INET; |
1609 | + struct in_addr *ip4= &((struct sockaddr_in *)sa)->sin_addr; |
1610 | + /* See RFC 5737, 192.0.2.0/23 is reserved */ |
1611 | + const char* fake= "192.0.2.4"; |
1612 | + ip4->s_addr= inet_addr(fake); |
1613 | + strcpy(ip, fake); |
1614 | + };); |
1615 | + /* END : DEBUG */ |
1616 | + |
1617 | if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME)))) |
1618 | return 1; /* The error is set by my_strdup(). */ |
1619 | thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip; |
1620 | @@ -1506,32 +1528,31 @@ |
1621 | (uchar*) buff, (size_t) (end-buff)) || |
1622 | (pkt_len= my_net_read(net)) == packet_error) |
1623 | { |
1624 | - inc_host_errors(&thd->remote.sin_addr); |
1625 | - my_error(ER_HANDSHAKE_ERROR, MYF(0)); |
1626 | - return 1; |
1627 | + goto error; |
1628 | } |
1629 | } |
1630 | #ifdef _CUSTOMCONFIG_ |
1631 | #include "_cust_sql_parse.h" |
1632 | #endif |
1633 | - if (connect_errors) |
1634 | - reset_host_errors(&thd->remote.sin_addr); |
1635 | if (thd->packet.alloc(thd->variables.net_buffer_length)) |
1636 | return 1; /* The error is set by alloc(). */ |
1637 | |
1638 | - uint charset_code= 0; |
1639 | end= (char *)net->read_pos; |
1640 | /* |
1641 | In order to safely scan a head for '\0' string terminators |
1642 | we must keep track of how many bytes remain in the allocated |
1643 | buffer or we might read past the end of the buffer. |
1644 | */ |
1645 | - size_t bytes_remaining_in_packet= pkt_len; |
1646 | + bytes_remaining_in_packet= pkt_len; |
1647 | |
1648 | /* |
1649 | Peek ahead on the client capability packet and determine which version of |
1650 | the protocol should be used. |
1651 | */ |
1652 | + DBUG_EXECUTE_IF("host_error_packet_length", |
1653 | + { |
1654 | + bytes_remaining_in_packet= 0; |
1655 | + };); |
1656 | if (bytes_remaining_in_packet < 2) |
1657 | goto error; |
1658 | |
1659 | @@ -1590,6 +1611,10 @@ |
1660 | |
1661 | skip_to_ssl: |
1662 | |
1663 | + DBUG_EXECUTE_IF("host_error_charset", |
1664 | + { |
1665 | + goto error; |
1666 | + };); |
1667 | DBUG_PRINT("info", ("client_character_set: %u", charset_code)); |
1668 | if (thd_init_client_charset(thd, charset_code)) |
1669 | goto error; |
1670 | @@ -1658,6 +1683,10 @@ |
1671 | bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40; |
1672 | } |
1673 | |
1674 | + DBUG_EXECUTE_IF("host_error_SSL_layering", |
1675 | + { |
1676 | + packet_has_required_size= 0; |
1677 | + };); |
1678 | if (!packet_has_required_size) |
1679 | goto error; |
1680 | } |
1681 | @@ -1683,6 +1712,11 @@ |
1682 | get_string= get_40_protocol_string; |
1683 | |
1684 | user= get_string(&end, &bytes_remaining_in_packet, &user_len); |
1685 | + DBUG_EXECUTE_IF("host_error_user", |
1686 | + { |
1687 | + user= NULL; |
1688 | + };); |
1689 | + |
1690 | if (user == NULL) |
1691 | goto error; |
1692 | |
1693 | @@ -1710,6 +1744,11 @@ |
1694 | passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len); |
1695 | } |
1696 | |
1697 | + DBUG_EXECUTE_IF("host_error_password", |
1698 | + { |
1699 | + passwd= NULL; |
1700 | + };); |
1701 | + |
1702 | if (passwd == NULL) |
1703 | goto error; |
1704 | |
1705 | @@ -1770,7 +1809,20 @@ |
1706 | |
1707 | if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME)))) |
1708 | return 1; /* The error is set by my_strdup(). */ |
1709 | - return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE); |
1710 | + |
1711 | + if (!check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE)) |
1712 | + { |
1713 | + /* |
1714 | + Call to reset_host_errors() should be made only when all sanity checks |
1715 | + are done and connection is going to be a successful. |
1716 | + */ |
1717 | + reset_host_errors(&thd->remote.sin_addr); |
1718 | + return 0; |
1719 | + } |
1720 | + else |
1721 | + { |
1722 | + return 1; |
1723 | + } |
1724 | |
1725 | error: |
1726 | inc_host_errors(&thd->remote.sin_addr); |
1727 | |
1728 | === modified file 'Percona-Server/sql/sql_lex.cc' |
1729 | --- Percona-Server/sql/sql_lex.cc 2012-08-20 03:14:02 +0000 |
1730 | +++ Percona-Server/sql/sql_lex.cc 2013-01-10 04:35:33 +0000 |
1731 | @@ -1621,6 +1621,7 @@ |
1732 | ref_pointer_array= 0; |
1733 | select_n_where_fields= 0; |
1734 | select_n_having_items= 0; |
1735 | + n_child_sum_items= 0; |
1736 | subquery_in_having= explicit_limit= 0; |
1737 | is_item_list_lookup= 0; |
1738 | first_execution= 1; |
1739 | |
1740 | === modified file 'Percona-Server/sql/sql_list.h' |
1741 | --- Percona-Server/sql/sql_list.h 2011-06-30 15:37:13 +0000 |
1742 | +++ Percona-Server/sql/sql_list.h 2013-01-10 04:35:33 +0000 |
1743 | @@ -1,7 +1,6 @@ |
1744 | #ifndef INCLUDES_MYSQL_SQL_LIST_H |
1745 | #define INCLUDES_MYSQL_SQL_LIST_H |
1746 | -/* |
1747 | - Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
1748 | +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
1749 | |
1750 | This program is free software; you can redistribute it and/or modify |
1751 | it under the terms of the GNU General Public License as published by |
1752 | @@ -165,6 +164,14 @@ |
1753 | public: |
1754 | uint elements; |
1755 | |
1756 | + bool operator==(const base_list &rhs) const |
1757 | + { |
1758 | + return |
1759 | + elements == rhs.elements && |
1760 | + first == rhs.first && |
1761 | + last == rhs.last; |
1762 | + } |
1763 | + |
1764 | inline void empty() { elements=0; first= &end_of_list; last=&first;} |
1765 | inline base_list() { empty(); } |
1766 | /** |
1767 | |
1768 | === modified file 'Percona-Server/sql/sql_profile.cc' |
1769 | --- Percona-Server/sql/sql_profile.cc 2012-08-20 03:14:02 +0000 |
1770 | +++ Percona-Server/sql/sql_profile.cc 2013-01-10 04:35:33 +0000 |
1771 | @@ -39,6 +39,7 @@ |
1772 | #define TIME_I_S_DECIMAL_SIZE (TIME_FLOAT_DIGITS*100)+(TIME_FLOAT_DIGITS-3) |
1773 | |
1774 | #define MAX_QUERY_LENGTH 300 |
1775 | +#define MAX_QUERY_HISTORY 101 |
1776 | |
1777 | /* Reserved for systems that can't record the function name in source. */ |
1778 | const char * const _unknown_func_ = "<unknown>"; |
1779 | @@ -247,9 +248,12 @@ |
1780 | QUERY_PROFILE::QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg) |
1781 | :profiling(profiling_arg), profiling_query_id(0), query_source(NULL) |
1782 | { |
1783 | - profile_start= new PROF_MEASUREMENT(this, status_arg); |
1784 | - entries.push_back(profile_start); |
1785 | - profile_end= profile_start; |
1786 | + m_seq_counter= 1; |
1787 | + PROF_MEASUREMENT *prof= new PROF_MEASUREMENT(this, status_arg); |
1788 | + prof->m_seq= m_seq_counter++; |
1789 | + m_start_time_usecs= prof->time_usecs; |
1790 | + m_end_time_usecs= m_start_time_usecs; |
1791 | + entries.push_back(prof); |
1792 | } |
1793 | |
1794 | QUERY_PROFILE::~QUERY_PROFILE() |
1795 | @@ -289,9 +293,14 @@ |
1796 | else |
1797 | prof= new PROF_MEASUREMENT(this, status_arg); |
1798 | |
1799 | - profile_end= prof; |
1800 | + prof->m_seq= m_seq_counter++; |
1801 | + m_end_time_usecs= prof->time_usecs; |
1802 | entries.push_back(prof); |
1803 | |
1804 | + /* Maintain the query history size. */ |
1805 | + while (entries.elements > MAX_QUERY_HISTORY) |
1806 | + delete entries.pop(); |
1807 | + |
1808 | DBUG_VOID_RETURN; |
1809 | } |
1810 | |
1811 | @@ -452,8 +461,7 @@ |
1812 | |
1813 | String elapsed; |
1814 | |
1815 | - PROF_MEASUREMENT *ps= prof->profile_start; |
1816 | - PROF_MEASUREMENT *pe= prof->profile_end; |
1817 | + double query_time_usecs= prof->m_end_time_usecs - prof->m_start_time_usecs; |
1818 | |
1819 | if (++idx <= unit->offset_limit_cnt) |
1820 | continue; |
1821 | @@ -462,7 +470,7 @@ |
1822 | |
1823 | protocol->prepare_for_resend(); |
1824 | protocol->store((uint32)(prof->profiling_query_id)); |
1825 | - protocol->store((double)(pe->time_usecs - ps->time_usecs)/(1000.0*1000), |
1826 | + protocol->store((double)(query_time_usecs/(1000.0*1000)), |
1827 | (uint32) TIME_FLOAT_DIGITS-1, &elapsed); |
1828 | if (prof->query_source != NULL) |
1829 | protocol->store(prof->query_source, strlen(prof->query_source), |
1830 | @@ -634,17 +642,18 @@ |
1831 | us also include a numbering of each state per query. The query_id and |
1832 | the "seq" together are unique. |
1833 | */ |
1834 | - ulonglong seq; |
1835 | + ulong seq; |
1836 | |
1837 | void *entry_iterator; |
1838 | PROF_MEASUREMENT *entry, *previous= NULL; |
1839 | /* ...and for each query, go through all its state-change steps. */ |
1840 | - for (seq= 0, entry_iterator= query->entries.new_iterator(); |
1841 | + for (entry_iterator= query->entries.new_iterator(); |
1842 | entry_iterator != NULL; |
1843 | entry_iterator= query->entries.iterator_next(entry_iterator), |
1844 | - seq++, previous=entry, row_number++) |
1845 | + previous=entry, row_number++) |
1846 | { |
1847 | entry= query->entries.iterator_value(entry_iterator); |
1848 | + seq= entry->m_seq; |
1849 | |
1850 | /* Skip the first. We count spans of fence, not fence-posts. */ |
1851 | if (previous == NULL) continue; |
1852 | |
1853 | === modified file 'Percona-Server/sql/sql_profile.h' |
1854 | --- Percona-Server/sql/sql_profile.h 2011-11-24 01:59:44 +0000 |
1855 | +++ Percona-Server/sql/sql_profile.h 2013-01-10 04:35:33 +0000 |
1856 | @@ -186,6 +186,7 @@ |
1857 | char *file; |
1858 | unsigned int line; |
1859 | |
1860 | + ulong m_seq; |
1861 | double time_usecs; |
1862 | double cpu_time_usecs; |
1863 | PROF_MEASUREMENT(); |
1864 | @@ -212,8 +213,9 @@ |
1865 | query_id_t profiling_query_id; /* Session-specific id. */ |
1866 | char *query_source; |
1867 | |
1868 | - PROF_MEASUREMENT *profile_start; |
1869 | - PROF_MEASUREMENT *profile_end; |
1870 | + double m_start_time_usecs; |
1871 | + double m_end_time_usecs; |
1872 | + ulong m_seq_counter; |
1873 | Queue<PROF_MEASUREMENT> entries; |
1874 | |
1875 | |
1876 | |
1877 | === modified file 'Percona-Server/sql/sql_select.cc' |
1878 | --- Percona-Server/sql/sql_select.cc 2013-01-10 04:35:31 +0000 |
1879 | +++ Percona-Server/sql/sql_select.cc 2013-01-10 04:35:33 +0000 |
1880 | @@ -1,4 +1,4 @@ |
1881 | -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. |
1882 | +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
1883 | |
1884 | This program is free software; you can redistribute it and/or modify |
1885 | it under the terms of the GNU General Public License as published by |
1886 | @@ -1699,6 +1699,8 @@ |
1887 | */ |
1888 | void JOIN::restore_tmp() |
1889 | { |
1890 | + DBUG_PRINT("info", ("restore_tmp this %p tmp_join %p", this, tmp_join)); |
1891 | + DBUG_ASSERT(tmp_join != this); |
1892 | memcpy(tmp_join, this, (size_t) sizeof(JOIN)); |
1893 | } |
1894 | |
1895 | @@ -7116,21 +7118,19 @@ |
1896 | } |
1897 | } |
1898 | } |
1899 | - /* |
1900 | - We are not using tables anymore |
1901 | - Unlock all tables. We may be in an INSERT .... SELECT statement. |
1902 | - */ |
1903 | if (full) |
1904 | { |
1905 | - if (tmp_join) |
1906 | - tmp_table_param.copy_field= 0; |
1907 | + /* |
1908 | + Ensure that the following delete_elements() would not be called |
1909 | + twice for the same list. |
1910 | + */ |
1911 | + if (tmp_join && tmp_join != this && |
1912 | + tmp_join->group_fields == this->group_fields) |
1913 | + tmp_join->group_fields.empty(); |
1914 | + |
1915 | + // Run Cached_item DTORs! |
1916 | group_fields.delete_elements(); |
1917 | - /* |
1918 | - Ensure that the above delete_elements() would not be called |
1919 | - twice for the same list. |
1920 | - */ |
1921 | - if (tmp_join && tmp_join != this) |
1922 | - tmp_join->group_fields= group_fields; |
1923 | + |
1924 | /* |
1925 | We can't call delete_elements() on copy_funcs as this will cause |
1926 | problems in free_elements() as some of the elements are then deleted. |
1927 | |
1928 | === modified file 'Percona-Server/storage/innobase/btr/btr0cur.c' |
1929 | --- Percona-Server/storage/innobase/btr/btr0cur.c 2012-08-20 00:29:22 +0000 |
1930 | +++ Percona-Server/storage/innobase/btr/btr0cur.c 2013-01-10 04:35:33 +0000 |
1931 | @@ -2377,21 +2377,22 @@ |
1932 | } |
1933 | |
1934 | /*************************************************************** |
1935 | -Sets a secondary index record delete mark to FALSE. This function is only |
1936 | +Sets a secondary index record delete mark. This function is only |
1937 | used by the insert buffer insert merge mechanism. */ |
1938 | |
1939 | void |
1940 | -btr_cur_del_unmark_for_ibuf( |
1941 | -/*========================*/ |
1942 | +btr_cur_set_deleted_flag_for_ibuf( |
1943 | +/*==============================*/ |
1944 | rec_t* rec, /* in: record to delete unmark */ |
1945 | + ibool val, /* in: value to set */ |
1946 | mtr_t* mtr) /* in: mtr */ |
1947 | { |
1948 | /* We do not need to reserve btr_search_latch, as the page has just |
1949 | been read to the buffer pool and there cannot be a hash index to it. */ |
1950 | |
1951 | - rec_set_deleted_flag(rec, page_is_comp(buf_frame_align(rec)), FALSE); |
1952 | + rec_set_deleted_flag(rec, page_is_comp(buf_frame_align(rec)), val); |
1953 | |
1954 | - btr_cur_del_mark_set_sec_rec_log(rec, FALSE, mtr); |
1955 | + btr_cur_del_mark_set_sec_rec_log(rec, val, mtr); |
1956 | } |
1957 | |
1958 | /*==================== B-TREE RECORD REMOVE =========================*/ |
1959 | |
1960 | === modified file 'Percona-Server/storage/innobase/dict/dict0dict.c' |
1961 | --- Percona-Server/storage/innobase/dict/dict0dict.c 2012-03-01 05:35:51 +0000 |
1962 | +++ Percona-Server/storage/innobase/dict/dict0dict.c 2013-01-10 04:35:33 +0000 |
1963 | @@ -1629,7 +1629,6 @@ |
1964 | { |
1965 | dict_index_t* new_index; |
1966 | dict_field_t* field; |
1967 | - ulint fixed_size; |
1968 | ulint trx_id_pos; |
1969 | ulint i; |
1970 | ibool* indexed; |
1971 | @@ -1706,7 +1705,7 @@ |
1972 | |
1973 | for (i = 0; i < trx_id_pos; i++) { |
1974 | |
1975 | - fixed_size = dict_col_get_fixed_size( |
1976 | + ulint fixed_size = dict_col_get_fixed_size( |
1977 | dict_index_get_nth_col(new_index, i)); |
1978 | |
1979 | if (fixed_size == 0) { |
1980 | @@ -1722,7 +1721,20 @@ |
1981 | break; |
1982 | } |
1983 | |
1984 | - new_index->trx_id_offset += (unsigned int) fixed_size; |
1985 | + /* Add fixed_size to new_index->trx_id_offset. |
1986 | + Because the latter is a bit-field, an overflow |
1987 | + can theoretically occur. Check for it. */ |
1988 | + fixed_size += new_index->trx_id_offset; |
1989 | + |
1990 | + new_index->trx_id_offset = fixed_size; |
1991 | + |
1992 | + if (new_index->trx_id_offset != fixed_size) { |
1993 | + /* Overflow. Pretend that this is a |
1994 | + variable-length PRIMARY KEY. */ |
1995 | + ut_ad(0); |
1996 | + new_index->trx_id_offset = 0; |
1997 | + break; |
1998 | + } |
1999 | } |
2000 | |
2001 | } |
2002 | |
2003 | === modified file 'Percona-Server/storage/innobase/handler/ha_innodb.cc' |
2004 | --- Percona-Server/storage/innobase/handler/ha_innodb.cc 2013-01-10 04:35:31 +0000 |
2005 | +++ Percona-Server/storage/innobase/handler/ha_innodb.cc 2013-01-10 04:35:33 +0000 |
2006 | @@ -9274,8 +9274,8 @@ |
2007 | #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG |
2008 | static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, |
2009 | PLUGIN_VAR_RQCMDARG, |
2010 | - "Debug flags for InnoDB change buffering (0=none)", |
2011 | - NULL, NULL, 0, 0, 1, 0); |
2012 | + "Debug flags for InnoDB change buffering (0=none, 2=crash at merge)", |
2013 | + NULL, NULL, 0, 0, 2, 0); |
2014 | #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ |
2015 | |
2016 | #ifdef UNIV_DEBUG |
2017 | |
2018 | === modified file 'Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c' |
2019 | --- Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c 2012-01-16 12:22:03 +0000 |
2020 | +++ Percona-Server/storage/innobase/ibuf/ibuf0ibuf.c 2013-01-10 04:35:33 +0000 |
2021 | @@ -2978,7 +2978,7 @@ |
2022 | /* The records only differ in the delete-mark. |
2023 | Clear the delete-mark, like we did before |
2024 | Bug #56680 was fixed. */ |
2025 | - btr_cur_del_unmark_for_ibuf(rec, mtr); |
2026 | + btr_cur_set_deleted_flag_for_ibuf(rec, FALSE, mtr); |
2027 | updated_in_place: |
2028 | mem_heap_free(heap); |
2029 | return; |
2030 | @@ -3058,6 +3058,22 @@ |
2031 | |
2032 | ut_ad(ibuf_inside()); |
2033 | |
2034 | +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG |
2035 | + if (ibuf_debug == 2) { |
2036 | + /* Inject a fault (crash). We do this before trying |
2037 | + optimistic delete, because a pessimistic delete in the |
2038 | + change buffer would require a larger test case. */ |
2039 | + |
2040 | + /* Flag the buffered record as processed, to avoid |
2041 | + an assertion failure after crash recovery. */ |
2042 | + btr_cur_set_deleted_flag_for_ibuf( |
2043 | + btr_pcur_get_rec(pcur), TRUE, mtr); |
2044 | + mtr_commit(mtr); |
2045 | + log_make_checkpoint_at(ut_dulint_max, TRUE); |
2046 | + DBUG_SUICIDE(); |
2047 | + } |
2048 | +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ |
2049 | + |
2050 | success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr); |
2051 | |
2052 | if (success) { |
2053 | @@ -3072,7 +3088,13 @@ |
2054 | return(FALSE); |
2055 | } |
2056 | |
2057 | - /* We have to resort to a pessimistic delete from ibuf */ |
2058 | + /* We have to resort to a pessimistic delete from ibuf. |
2059 | + Delete-mark the record so that it will not be applied again, |
2060 | + in case the server crashes before the pessimistic delete is |
2061 | + made persistent. */ |
2062 | + btr_cur_set_deleted_flag_for_ibuf( |
2063 | + btr_pcur_get_rec(pcur), TRUE, mtr); |
2064 | + |
2065 | btr_pcur_store_position(pcur, mtr); |
2066 | |
2067 | btr_pcur_commit_specify_mtr(pcur, mtr); |
2068 | @@ -3343,7 +3365,7 @@ |
2069 | fputs("InnoDB: Discarding record\n ", stderr); |
2070 | rec_print_old(stderr, ibuf_rec); |
2071 | fputs("\n from the insert buffer!\n\n", stderr); |
2072 | - } else if (page) { |
2073 | + } else if (page && !rec_get_deleted_flag(ibuf_rec, 0)) { |
2074 | /* Now we have at pcur a record which should be |
2075 | inserted to the index page; NOTE that the call below |
2076 | copies pointers to fields in ibuf_rec, and we must |
2077 | |
2078 | === modified file 'Percona-Server/storage/innobase/include/btr0cur.h' |
2079 | --- Percona-Server/storage/innobase/include/btr0cur.h 2011-10-26 09:23:57 +0000 |
2080 | +++ Percona-Server/storage/innobase/include/btr0cur.h 2013-01-10 04:35:33 +0000 |
2081 | @@ -277,13 +277,14 @@ |
2082 | que_thr_t* thr, /* in: query thread */ |
2083 | mtr_t* mtr); /* in: mtr */ |
2084 | /*************************************************************** |
2085 | -Sets a secondary index record delete mark to FALSE. This function is |
2086 | -only used by the insert buffer insert merge mechanism. */ |
2087 | +Sets a secondary index record delete mark. This function is only |
2088 | +used by the insert buffer insert merge mechanism. */ |
2089 | |
2090 | void |
2091 | -btr_cur_del_unmark_for_ibuf( |
2092 | -/*========================*/ |
2093 | +btr_cur_set_deleted_flag_for_ibuf( |
2094 | +/*==============================*/ |
2095 | rec_t* rec, /* in: record to delete unmark */ |
2096 | + ibool val, /* in: value to set */ |
2097 | mtr_t* mtr); /* in: mtr */ |
2098 | /***************************************************************** |
2099 | Tries to compress a page of the tree on the leaf level. It is assumed |
2100 | |
2101 | === modified file 'Percona-Server/storage/innobase/include/dict0mem.h' |
2102 | --- Percona-Server/storage/innobase/include/dict0mem.h 2011-01-14 17:02:28 +0000 |
2103 | +++ Percona-Server/storage/innobase/include/dict0mem.h 2013-01-10 04:35:33 +0000 |
2104 | @@ -196,10 +196,15 @@ |
2105 | unsigned space:32; |
2106 | /* space where the index tree is placed */ |
2107 | unsigned page:32;/* index tree root page number */ |
2108 | - unsigned trx_id_offset:10;/* position of the the trx id column |
2109 | +#define MAX_KEY_LENGTH_BITS 12 |
2110 | + unsigned trx_id_offset:MAX_KEY_LENGTH_BITS; |
2111 | + /* position of the trx id column |
2112 | in a clustered index record, if the fields |
2113 | before it are known to be of a fixed size, |
2114 | 0 otherwise */ |
2115 | +#if (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH |
2116 | +# error (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH |
2117 | +#endif |
2118 | unsigned n_user_defined_cols:10; |
2119 | /* number of columns the user defined to |
2120 | be in the index: in the internal |
2121 | |
2122 | === modified file 'Percona-Server/storage/innobase/include/row0undo.h' |
2123 | --- Percona-Server/storage/innobase/include/row0undo.h 2006-08-28 17:42:45 +0000 |
2124 | +++ Percona-Server/storage/innobase/include/row0undo.h 2013-01-10 04:35:33 +0000 |
2125 | @@ -78,8 +78,6 @@ |
2126 | dulint undo_no;/* undo number of the record */ |
2127 | ulint rec_type;/* undo log record type: TRX_UNDO_INSERT_REC, |
2128 | ... */ |
2129 | - dulint new_roll_ptr; /* roll ptr to restore to clustered index |
2130 | - record */ |
2131 | dulint new_trx_id; /* trx id to restore to clustered index |
2132 | record */ |
2133 | btr_pcur_t pcur; /* persistent cursor used in searching the |
2134 | @@ -101,11 +99,8 @@ |
2135 | /* Execution states for an undo node */ |
2136 | #define UNDO_NODE_FETCH_NEXT 1 /* we should fetch the next undo log |
2137 | record */ |
2138 | -#define UNDO_NODE_PREV_VERS 2 /* the roll ptr to previous version of |
2139 | - a row is stored in node, and undo |
2140 | - should be done based on it */ |
2141 | -#define UNDO_NODE_INSERT 3 |
2142 | -#define UNDO_NODE_MODIFY 4 |
2143 | +#define UNDO_NODE_INSERT 2 |
2144 | +#define UNDO_NODE_MODIFY 3 |
2145 | |
2146 | |
2147 | #ifndef UNIV_NONINL |
2148 | |
2149 | === modified file 'Percona-Server/storage/innobase/os/os0file.c' |
2150 | --- Percona-Server/storage/innobase/os/os0file.c 2010-10-28 04:18:59 +0000 |
2151 | +++ Percona-Server/storage/innobase/os/os0file.c 2013-01-10 04:35:33 +0000 |
2152 | @@ -1215,6 +1215,14 @@ |
2153 | DWORD create_flag; |
2154 | DWORD attributes; |
2155 | ibool retry; |
2156 | + |
2157 | + DBUG_EXECUTE_IF( |
2158 | + "ib_create_table_fail_disk_full", |
2159 | + *success = FALSE; |
2160 | + SetLastError(ERROR_DISK_FULL); |
2161 | + return((os_file_t) -1); |
2162 | + ); |
2163 | + |
2164 | try_again: |
2165 | ut_a(name); |
2166 | |
2167 | @@ -1318,6 +1326,13 @@ |
2168 | ibool retry; |
2169 | const char* mode_str = NULL; |
2170 | |
2171 | + DBUG_EXECUTE_IF( |
2172 | + "ib_create_table_fail_disk_full", |
2173 | + *success = FALSE; |
2174 | + errno = ENOSPC; |
2175 | + return((os_file_t) -1); |
2176 | + ); |
2177 | + |
2178 | try_again: |
2179 | ut_a(name); |
2180 | |
2181 | |
2182 | === modified file 'Percona-Server/storage/innobase/row/row0sel.c' |
2183 | --- Percona-Server/storage/innobase/row/row0sel.c 2011-12-22 10:55:44 +0000 |
2184 | +++ Percona-Server/storage/innobase/row/row0sel.c 2013-01-10 04:35:33 +0000 |
2185 | @@ -3758,9 +3758,13 @@ |
2186 | } |
2187 | |
2188 | rec_loop: |
2189 | + if (trx_is_interrupted(trx)) { |
2190 | + err = DB_INTERRUPTED; |
2191 | + goto normal_return; |
2192 | + } |
2193 | + |
2194 | /*-------------------------------------------------------------*/ |
2195 | /* PHASE 4: Look for matching records in a loop */ |
2196 | - |
2197 | rec = btr_pcur_get_rec(pcur); |
2198 | ut_ad(!!page_rec_is_comp(rec) == comp); |
2199 | #ifdef UNIV_SEARCH_DEBUG |
2200 | @@ -4656,14 +4660,18 @@ |
2201 | /* TODO: We have to cast away the const of rec for now. This needs |
2202 | to be fixed later.*/ |
2203 | offsets = rec_get_offsets( |
2204 | - (rec_t*) rec, index, offsets, ULINT_UNDEFINED, &heap); |
2205 | + (rec_t*) rec, index, offsets, col_no + 1, &heap); |
2206 | + |
2207 | + if (rec_offs_nth_sql_null(offsets, col_no)) { |
2208 | + /* There is no non-NULL value in the auto-increment column. */ |
2209 | + value = 0; |
2210 | + goto func_exit; |
2211 | + } |
2212 | |
2213 | /* TODO: We have to cast away the const of rec for now. This needs |
2214 | to be fixed later.*/ |
2215 | data = rec_get_nth_field((rec_t*)rec, offsets, col_no, &len); |
2216 | |
2217 | - ut_a(len != UNIV_SQL_NULL); |
2218 | - |
2219 | switch (mtype) { |
2220 | case DATA_INT: |
2221 | ut_a(len <= sizeof value); |
2222 | @@ -4684,15 +4692,16 @@ |
2223 | ut_error; |
2224 | } |
2225 | |
2226 | - if (UNIV_LIKELY_NULL(heap)) { |
2227 | - mem_heap_free(heap); |
2228 | - } |
2229 | - |
2230 | /* We assume that the autoinc counter can't be negative. */ |
2231 | if (!unsigned_type && (ib_longlong) value < 0) { |
2232 | value = 0; |
2233 | } |
2234 | |
2235 | +func_exit: |
2236 | + if (UNIV_LIKELY_NULL(heap)) { |
2237 | + mem_heap_free(heap); |
2238 | + } |
2239 | + |
2240 | return(value); |
2241 | } |
2242 | |
2243 | |
2244 | === modified file 'Percona-Server/storage/innobase/row/row0umod.c' |
2245 | --- Percona-Server/storage/innobase/row/row0umod.c 2011-10-26 09:23:57 +0000 |
2246 | +++ Percona-Server/storage/innobase/row/row0umod.c 2013-01-10 04:35:33 +0000 |
2247 | @@ -42,37 +42,6 @@ |
2248 | version has become obsolete at the time the undo is started. */ |
2249 | |
2250 | /*************************************************************** |
2251 | -Checks if also the previous version of the clustered index record was |
2252 | -modified or inserted by the same transaction, and its undo number is such |
2253 | -that it should be undone in the same rollback. */ |
2254 | -UNIV_INLINE |
2255 | -ibool |
2256 | -row_undo_mod_undo_also_prev_vers( |
2257 | -/*=============================*/ |
2258 | - /* out: TRUE if also previous modify or |
2259 | - insert of this row should be undone */ |
2260 | - undo_node_t* node, /* in: row undo node */ |
2261 | - dulint* undo_no)/* out: the undo number */ |
2262 | -{ |
2263 | - trx_undo_rec_t* undo_rec; |
2264 | - trx_t* trx; |
2265 | - |
2266 | - trx = node->trx; |
2267 | - |
2268 | - if (0 != ut_dulint_cmp(node->new_trx_id, trx->id)) { |
2269 | - |
2270 | - *undo_no = ut_dulint_zero; |
2271 | - return(FALSE); |
2272 | - } |
2273 | - |
2274 | - undo_rec = trx_undo_get_undo_rec_low(node->new_roll_ptr, node->heap); |
2275 | - |
2276 | - *undo_no = trx_undo_rec_get_undo_no(undo_rec); |
2277 | - |
2278 | - return(ut_dulint_cmp(trx->roll_limit, *undo_no) <= 0); |
2279 | -} |
2280 | - |
2281 | -/*************************************************************** |
2282 | Undoes a modify in a clustered index record. */ |
2283 | static |
2284 | ulint |
2285 | @@ -202,17 +171,9 @@ |
2286 | btr_pcur_t* pcur; |
2287 | mtr_t mtr; |
2288 | ulint err; |
2289 | - ibool success; |
2290 | - ibool more_vers; |
2291 | - dulint new_undo_no; |
2292 | |
2293 | ut_ad(node && thr); |
2294 | |
2295 | - /* Check if also the previous version of the clustered index record |
2296 | - should be undone in this same rollback operation */ |
2297 | - |
2298 | - more_vers = row_undo_mod_undo_also_prev_vers(node, &new_undo_no); |
2299 | - |
2300 | pcur = &(node->pcur); |
2301 | |
2302 | mtr_start(&mtr); |
2303 | @@ -260,20 +221,6 @@ |
2304 | |
2305 | trx_undo_rec_release(node->trx, node->undo_no); |
2306 | |
2307 | - if (more_vers && err == DB_SUCCESS) { |
2308 | - |
2309 | - /* Reserve the undo log record to the prior version after |
2310 | - committing &mtr: this is necessary to comply with the latching |
2311 | - order, as &mtr may contain the fsp latch which is lower in |
2312 | - the latch hierarchy than trx->undo_mutex. */ |
2313 | - |
2314 | - success = trx_undo_rec_reserve(node->trx, new_undo_no); |
2315 | - |
2316 | - if (success) { |
2317 | - node->state = UNDO_NODE_PREV_VERS; |
2318 | - } |
2319 | - } |
2320 | - |
2321 | return(err); |
2322 | } |
2323 | |
2324 | @@ -702,7 +649,6 @@ |
2325 | trx_undo_update_rec_get_update(ptr, clust_index, type, trx_id, |
2326 | roll_ptr, info_bits, trx, |
2327 | node->heap, &(node->update)); |
2328 | - node->new_roll_ptr = roll_ptr; |
2329 | node->new_trx_id = trx_id; |
2330 | node->cmpl_info = cmpl_info; |
2331 | } |
2332 | |
2333 | === modified file 'Percona-Server/storage/innobase/row/row0undo.c' |
2334 | --- Percona-Server/storage/innobase/row/row0undo.c 2010-06-25 08:18:41 +0000 |
2335 | +++ Percona-Server/storage/innobase/row/row0undo.c 2013-01-10 04:35:33 +0000 |
2336 | @@ -242,25 +242,6 @@ |
2337 | } else { |
2338 | node->state = UNDO_NODE_MODIFY; |
2339 | } |
2340 | - |
2341 | - } else if (node->state == UNDO_NODE_PREV_VERS) { |
2342 | - |
2343 | - /* Undo should be done to the same clustered index record |
2344 | - again in this same rollback, restoring the previous version */ |
2345 | - |
2346 | - roll_ptr = node->new_roll_ptr; |
2347 | - |
2348 | - node->undo_rec = trx_undo_get_undo_rec_low(roll_ptr, |
2349 | - node->heap); |
2350 | - node->roll_ptr = roll_ptr; |
2351 | - node->undo_no = trx_undo_rec_get_undo_no(node->undo_rec); |
2352 | - |
2353 | - if (trx_undo_roll_ptr_is_insert(roll_ptr)) { |
2354 | - |
2355 | - node->state = UNDO_NODE_INSERT; |
2356 | - } else { |
2357 | - node->state = UNDO_NODE_MODIFY; |
2358 | - } |
2359 | } |
2360 | |
2361 | /* Prevent DROP TABLE etc. while we are rolling back this row. |
2362 | |
2363 | === modified file 'Percona-Server/storage/innodb_plugin/ChangeLog' |
2364 | --- Percona-Server/storage/innodb_plugin/ChangeLog 2013-01-10 04:35:31 +0000 |
2365 | +++ Percona-Server/storage/innodb_plugin/ChangeLog 2013-01-10 04:35:33 +0000 |
2366 | @@ -1,3 +1,40 @@ |
2367 | +2012-10-18 The InnoDB Team |
2368 | + |
2369 | + * row/row0sel.c: |
2370 | + Fix Bug#14758405: ALTER TABLE: ADDING SERIAL NULL DATATYPE: ASSERTION: |
2371 | + LEN <= SIZEOF(ULONGLONG) |
2372 | + |
2373 | +2012-10-16 The InnoDB Team |
2374 | + |
2375 | + * dict/dict0dict.c, handler/handler0alter.cc, include/dict0dict.h: |
2376 | + Fix Bug#14729221 IN-PLACE ALTER TABLE REPORTS '' INSTEAD OF REAL |
2377 | + DUPLICATE VALUE FOR PREFIX KEYS |
2378 | + |
2379 | +2012-10-09 The InnoDB Team |
2380 | + |
2381 | + * row/row0mysql.c: |
2382 | + Fix Bug#14708715 CREATE TABLE MEMORY LEAK ON DB_OUT_OF_FILE_SPACE |
2383 | + |
2384 | +2012-09-28 The InnoDB Team |
2385 | + |
2386 | + * include/row0undo.h, row/row0umod.c, row/row0undo.c: |
2387 | + Fix Bug#13249921 ASSERT !BPAGE->FILE_PAGE_WAS_FREED, USUALLY |
2388 | + IN TRANSACTION ROLLBACK. This patch will ensure that the |
2389 | + undo logs will be applied in proper reverse order. |
2390 | + |
2391 | +2012-09-18 The InnoDB Team |
2392 | + |
2393 | + * btr/btr0cur.c, handler/ha_innodb.cc, ibuf/ibuf0ibuf.c, |
2394 | + include/btr0cur.h: |
2395 | + Fix Bug#14636528 INNODB CHANGE BUFFERING IS NOT ENTIRELY CRASH-SAFE |
2396 | + |
2397 | +2012-09-17 The InnoDB Team |
2398 | + |
2399 | + * btr/btr0btr.c, btr/btr0cur.c, buf/buf0lru.c, |
2400 | + include/page0zip.h, log/log0recv.c, page/page0cur.c, |
2401 | + page/page0page.c, page/page0zip.c: |
2402 | + Fix Bug#12701488 ASSERT PAGE_ZIP_VALIDATE, UNIV_ZIP_DEBUG |
2403 | + |
2404 | 2012-08-29 The InnoDB Team |
2405 | |
2406 | * btr/btr0btr.c, page/page0cur.c, page/page0page.c: |
2407 | |
2408 | === modified file 'Percona-Server/storage/innodb_plugin/btr/btr0btr.c' |
2409 | --- Percona-Server/storage/innodb_plugin/btr/btr0btr.c 2013-01-10 04:35:31 +0000 |
2410 | +++ Percona-Server/storage/innodb_plugin/btr/btr0btr.c 2013-01-10 04:35:33 +0000 |
2411 | @@ -1620,7 +1620,7 @@ |
2412 | ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); |
2413 | ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table)); |
2414 | #ifdef UNIV_ZIP_DEBUG |
2415 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2416 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2417 | #endif /* UNIV_ZIP_DEBUG */ |
2418 | data_size1 = page_get_data_size(page); |
2419 | max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1); |
2420 | @@ -1738,7 +1738,7 @@ |
2421 | |
2422 | func_exit: |
2423 | #ifdef UNIV_ZIP_DEBUG |
2424 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2425 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2426 | #endif /* UNIV_ZIP_DEBUG */ |
2427 | #ifndef UNIV_HOTBACKUP |
2428 | buf_block_free(temp_block); |
2429 | @@ -1813,7 +1813,7 @@ |
2430 | ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); |
2431 | ut_ad(page_zip == buf_block_get_page_zip(block)); |
2432 | #ifdef UNIV_ZIP_DEBUG |
2433 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2434 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2435 | #endif /* UNIV_ZIP_DEBUG */ |
2436 | |
2437 | btr_search_drop_page_hash_index(block); |
2438 | @@ -1870,10 +1870,10 @@ |
2439 | root_block = btr_cur_get_block(cursor); |
2440 | root_page_zip = buf_block_get_page_zip(root_block); |
2441 | ut_ad(page_get_n_recs(root) > 0); |
2442 | + index = btr_cur_get_index(cursor); |
2443 | #ifdef UNIV_ZIP_DEBUG |
2444 | - ut_a(!root_page_zip || page_zip_validate(root_page_zip, root)); |
2445 | + ut_a(!root_page_zip || page_zip_validate(root_page_zip, root, index)); |
2446 | #endif /* UNIV_ZIP_DEBUG */ |
2447 | - index = btr_cur_get_index(cursor); |
2448 | #ifdef UNIV_BTR_DEBUG |
2449 | if (!dict_index_is_ibuf(index)) { |
2450 | ulint space = dict_index_get_space(index); |
2451 | @@ -2803,8 +2803,8 @@ |
2452 | |
2453 | #ifdef UNIV_ZIP_DEBUG |
2454 | if (UNIV_LIKELY_NULL(page_zip)) { |
2455 | - ut_a(page_zip_validate(page_zip, page)); |
2456 | - ut_a(page_zip_validate(new_page_zip, new_page)); |
2457 | + ut_a(page_zip_validate(page_zip, page, cursor->index)); |
2458 | + ut_a(page_zip_validate(new_page_zip, new_page, cursor->index)); |
2459 | } |
2460 | #endif /* UNIV_ZIP_DEBUG */ |
2461 | |
2462 | @@ -2838,7 +2838,8 @@ |
2463 | = buf_block_get_page_zip(insert_block); |
2464 | |
2465 | ut_a(!insert_page_zip |
2466 | - || page_zip_validate(insert_page_zip, insert_page)); |
2467 | + || page_zip_validate(insert_page_zip, insert_page, |
2468 | + cursor->index)); |
2469 | } |
2470 | #endif /* UNIV_ZIP_DEBUG */ |
2471 | |
2472 | @@ -3203,7 +3204,7 @@ |
2473 | |
2474 | btr_page_set_level(page, page_zip, page_level, mtr); |
2475 | #ifdef UNIV_ZIP_DEBUG |
2476 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2477 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2478 | #endif /* UNIV_ZIP_DEBUG */ |
2479 | } |
2480 | |
2481 | @@ -3379,8 +3380,8 @@ |
2482 | const page_zip_des_t* page_zip |
2483 | = buf_block_get_page_zip(block); |
2484 | ut_a(page_zip); |
2485 | - ut_a(page_zip_validate(merge_page_zip, merge_page)); |
2486 | - ut_a(page_zip_validate(page_zip, page)); |
2487 | + ut_a(page_zip_validate(merge_page_zip, merge_page, index)); |
2488 | + ut_a(page_zip_validate(page_zip, page, index)); |
2489 | } |
2490 | #endif /* UNIV_ZIP_DEBUG */ |
2491 | |
2492 | @@ -3513,7 +3514,8 @@ |
2493 | |
2494 | ut_ad(page_validate(merge_page, index)); |
2495 | #ifdef UNIV_ZIP_DEBUG |
2496 | - ut_a(!merge_page_zip || page_zip_validate(merge_page_zip, merge_page)); |
2497 | + ut_a(!merge_page_zip || page_zip_validate(merge_page_zip, merge_page, |
2498 | + index)); |
2499 | #endif /* UNIV_ZIP_DEBUG */ |
2500 | |
2501 | /* Free the file page */ |
2502 | @@ -3696,7 +3698,7 @@ |
2503 | page_zip_des_t* merge_page_zip |
2504 | = buf_block_get_page_zip(merge_block); |
2505 | ut_a(!merge_page_zip |
2506 | - || page_zip_validate(merge_page_zip, merge_page)); |
2507 | + || page_zip_validate(merge_page_zip, merge_page, index)); |
2508 | } |
2509 | #endif /* UNIV_ZIP_DEBUG */ |
2510 | |
2511 | @@ -4173,7 +4175,7 @@ |
2512 | ut_a(space == page_get_space_id(page)); |
2513 | #ifdef UNIV_ZIP_DEBUG |
2514 | page_zip = buf_block_get_page_zip(block); |
2515 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2516 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2517 | #endif /* UNIV_ZIP_DEBUG */ |
2518 | ut_a(!page_is_leaf(page)); |
2519 | |
2520 | @@ -4201,7 +4203,7 @@ |
2521 | |
2522 | #ifdef UNIV_ZIP_DEBUG |
2523 | page_zip = buf_block_get_page_zip(block); |
2524 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2525 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2526 | #endif /* UNIV_ZIP_DEBUG */ |
2527 | |
2528 | /* Check ordering etc. of records */ |
2529 | |
2530 | === modified file 'Percona-Server/storage/innodb_plugin/btr/btr0cur.c' |
2531 | --- Percona-Server/storage/innodb_plugin/btr/btr0cur.c 2013-01-10 04:35:31 +0000 |
2532 | +++ Percona-Server/storage/innodb_plugin/btr/btr0cur.c 2013-01-10 04:35:33 +0000 |
2533 | @@ -651,7 +651,8 @@ |
2534 | #ifdef UNIV_ZIP_DEBUG |
2535 | const page_zip_des_t* page_zip |
2536 | = buf_block_get_page_zip(block); |
2537 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2538 | + ut_a(!page_zip |
2539 | + || page_zip_validate(page_zip, page, index)); |
2540 | #endif /* UNIV_ZIP_DEBUG */ |
2541 | |
2542 | buf_block_dbg_add_level( |
2543 | @@ -2084,7 +2085,7 @@ |
2544 | |
2545 | page_zip = buf_block_get_page_zip(block); |
2546 | #ifdef UNIV_ZIP_DEBUG |
2547 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2548 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2549 | #endif /* UNIV_ZIP_DEBUG */ |
2550 | |
2551 | if (page_zip |
2552 | @@ -2299,7 +2300,7 @@ |
2553 | MTR_MEMO_X_LOCK)); |
2554 | ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); |
2555 | #ifdef UNIV_ZIP_DEBUG |
2556 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2557 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2558 | #endif /* UNIV_ZIP_DEBUG */ |
2559 | /* The insert buffer tree should never be updated in place. */ |
2560 | ut_ad(!dict_index_is_ibuf(index)); |
2561 | @@ -2454,7 +2455,7 @@ |
2562 | btr_search_update_hash_on_delete(cursor); |
2563 | |
2564 | #ifdef UNIV_ZIP_DEBUG |
2565 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2566 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2567 | #endif /* UNIV_ZIP_DEBUG */ |
2568 | page_cursor = btr_cur_get_page_cur(cursor); |
2569 | |
2570 | @@ -2561,7 +2562,7 @@ |
2571 | buf_block_t* rec_block = btr_cur_get_block(cursor); |
2572 | |
2573 | #ifdef UNIV_ZIP_DEBUG |
2574 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2575 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2576 | page = buf_block_get_frame(rec_block); |
2577 | #endif /* UNIV_ZIP_DEBUG */ |
2578 | page_zip = buf_block_get_page_zip(rec_block); |
2579 | @@ -2587,7 +2588,7 @@ |
2580 | |
2581 | return_after_reservations: |
2582 | #ifdef UNIV_ZIP_DEBUG |
2583 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2584 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2585 | #endif /* UNIV_ZIP_DEBUG */ |
2586 | |
2587 | if (n_extents > 0) { |
2588 | @@ -2946,19 +2947,20 @@ |
2589 | return(DB_SUCCESS); |
2590 | } |
2591 | |
2592 | -/***********************************************************//** |
2593 | -Clear a secondary index record's delete mark. This function is only |
2594 | +/*************************************************************** |
2595 | +Sets a secondary index record delete mark. This function is only |
2596 | used by the insert buffer insert merge mechanism. */ |
2597 | UNIV_INTERN |
2598 | void |
2599 | -btr_cur_del_unmark_for_ibuf( |
2600 | -/*========================*/ |
2601 | +btr_cur_set_deleted_flag_for_ibuf( |
2602 | +/*==============================*/ |
2603 | rec_t* rec, /*!< in/out: record to delete unmark */ |
2604 | page_zip_des_t* page_zip, /*!< in/out: compressed page |
2605 | corresponding to rec, or NULL |
2606 | when the tablespace is |
2607 | uncompressed */ |
2608 | - mtr_t* mtr) /*!< in: mtr */ |
2609 | + ibool val, /*!< in: value to set */ |
2610 | + mtr_t* mtr) /*!< in/out: mini-transaction */ |
2611 | { |
2612 | /* We do not need to reserve btr_search_latch, as the page |
2613 | has just been read to the buffer pool and there cannot be |
2614 | @@ -2966,9 +2968,9 @@ |
2615 | updated in place and the adaptive hash index does not depend |
2616 | on it. */ |
2617 | |
2618 | - btr_rec_set_deleted_flag(rec, page_zip, FALSE); |
2619 | + btr_rec_set_deleted_flag(rec, page_zip, val); |
2620 | |
2621 | - btr_cur_del_mark_set_sec_rec_log(rec, FALSE, mtr); |
2622 | + btr_cur_del_mark_set_sec_rec_log(rec, val, mtr); |
2623 | } |
2624 | |
2625 | /*==================== B-TREE RECORD REMOVE =========================*/ |
2626 | @@ -3063,12 +3065,14 @@ |
2627 | page, 1); |
2628 | } |
2629 | #ifdef UNIV_ZIP_DEBUG |
2630 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2631 | + ut_a(!page_zip |
2632 | + || page_zip_validate(page_zip, page, cursor->index)); |
2633 | #endif /* UNIV_ZIP_DEBUG */ |
2634 | page_cur_delete_rec(btr_cur_get_page_cur(cursor), |
2635 | cursor->index, offsets, mtr); |
2636 | #ifdef UNIV_ZIP_DEBUG |
2637 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2638 | + ut_a(!page_zip |
2639 | + || page_zip_validate(page_zip, page, cursor->index)); |
2640 | #endif /* UNIV_ZIP_DEBUG */ |
2641 | |
2642 | if (dict_index_is_clust(cursor->index) |
2643 | @@ -3165,7 +3169,7 @@ |
2644 | rec = btr_cur_get_rec(cursor); |
2645 | page_zip = buf_block_get_page_zip(block); |
2646 | #ifdef UNIV_ZIP_DEBUG |
2647 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2648 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2649 | #endif /* UNIV_ZIP_DEBUG */ |
2650 | |
2651 | offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); |
2652 | @@ -3175,7 +3179,7 @@ |
2653 | rec, offsets, page_zip, |
2654 | rb_ctx, mtr); |
2655 | #ifdef UNIV_ZIP_DEBUG |
2656 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2657 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2658 | #endif /* UNIV_ZIP_DEBUG */ |
2659 | } |
2660 | |
2661 | @@ -3236,7 +3240,7 @@ |
2662 | |
2663 | page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, offsets, mtr); |
2664 | #ifdef UNIV_ZIP_DEBUG |
2665 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
2666 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
2667 | #endif /* UNIV_ZIP_DEBUG */ |
2668 | |
2669 | ut_ad(btr_check_node_ptr(index, block, mtr)); |
2670 | |
2671 | === modified file 'Percona-Server/storage/innodb_plugin/buf/buf0buf.c' |
2672 | --- Percona-Server/storage/innodb_plugin/buf/buf0buf.c 2013-01-10 04:35:31 +0000 |
2673 | +++ Percona-Server/storage/innodb_plugin/buf/buf0buf.c 2013-01-10 04:35:33 +0000 |
2674 | @@ -278,7 +278,7 @@ |
2675 | |
2676 | #ifndef UNIV_HOTBACKUP |
2677 | /** Value in microseconds */ |
2678 | -static const int WAIT_FOR_READ = 5000; |
2679 | +static const int WAIT_FOR_READ = 100; |
2680 | /** Number of attemtps made to read in a page in the buffer pool */ |
2681 | static const ulint BUF_PAGE_READ_MAX_RETRIES = 100; |
2682 | |
2683 | @@ -2202,8 +2202,9 @@ |
2684 | mutex_exit(&block->mutex); |
2685 | |
2686 | if (io_fix == BUF_IO_READ) { |
2687 | - |
2688 | - os_thread_sleep(WAIT_FOR_READ); |
2689 | + /* wait by temporaly s-latch */ |
2690 | + rw_lock_s_lock(&(block->lock)); |
2691 | + rw_lock_s_unlock(&(block->lock)); |
2692 | } else { |
2693 | break; |
2694 | } |
2695 | |
2696 | === modified file 'Percona-Server/storage/innodb_plugin/buf/buf0lru.c' |
2697 | --- Percona-Server/storage/innodb_plugin/buf/buf0lru.c 2012-11-23 11:15:06 +0000 |
2698 | +++ Percona-Server/storage/innodb_plugin/buf/buf0lru.c 2013-01-10 04:35:33 +0000 |
2699 | @@ -1839,7 +1839,9 @@ |
2700 | break; |
2701 | case FIL_PAGE_INDEX: |
2702 | #ifdef UNIV_ZIP_DEBUG |
2703 | - ut_a(page_zip_validate(&bpage->zip, page)); |
2704 | + ut_a(page_zip_validate( |
2705 | + &bpage->zip, page, |
2706 | + ((buf_block_t*) bpage)->index)); |
2707 | #endif /* UNIV_ZIP_DEBUG */ |
2708 | break; |
2709 | default: |
2710 | |
2711 | === modified file 'Percona-Server/storage/innodb_plugin/dict/dict0dict.c' |
2712 | --- Percona-Server/storage/innodb_plugin/dict/dict0dict.c 2012-08-20 03:14:02 +0000 |
2713 | +++ Percona-Server/storage/innodb_plugin/dict/dict0dict.c 2013-01-10 04:35:33 +0000 |
2714 | @@ -1,6 +1,6 @@ |
2715 | /***************************************************************************** |
2716 | |
2717 | -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. |
2718 | +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. |
2719 | |
2720 | This program is free software; you can redistribute it and/or modify it under |
2721 | the terms of the GNU General Public License as published by the Free Software |
2722 | @@ -498,38 +498,55 @@ |
2723 | ULINT_UNDEFINED if not contained */ |
2724 | UNIV_INTERN |
2725 | ulint |
2726 | +dict_index_get_nth_col_or_prefix_pos( |
2727 | +/*=================================*/ |
2728 | + const dict_index_t* index, /*!< in: index */ |
2729 | + ulint n, /*!< in: column number */ |
2730 | + ibool inc_prefix) /*!< in: TRUE=consider |
2731 | + column prefixes too */ |
2732 | +{ |
2733 | + const dict_field_t* field; |
2734 | + const dict_col_t* col; |
2735 | + ulint pos; |
2736 | + ulint n_fields; |
2737 | + |
2738 | + ut_ad(index); |
2739 | + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); |
2740 | + |
2741 | + col = dict_table_get_nth_col(index->table, n); |
2742 | + |
2743 | + if (dict_index_is_clust(index)) { |
2744 | + |
2745 | + return(dict_col_get_clust_pos(col, index)); |
2746 | + } |
2747 | + |
2748 | + n_fields = dict_index_get_n_fields(index); |
2749 | + |
2750 | + for (pos = 0; pos < n_fields; pos++) { |
2751 | + field = dict_index_get_nth_field(index, pos); |
2752 | + |
2753 | + if (col == field->col |
2754 | + && (inc_prefix || field->prefix_len == 0)) { |
2755 | + |
2756 | + return(pos); |
2757 | + } |
2758 | + } |
2759 | + |
2760 | + return(ULINT_UNDEFINED); |
2761 | +} |
2762 | + |
2763 | +/********************************************************************//** |
2764 | +Looks for column n in an index. |
2765 | +@return position in internal representation of the index; |
2766 | +ULINT_UNDEFINED if not contained */ |
2767 | +UNIV_INTERN |
2768 | +ulint |
2769 | dict_index_get_nth_col_pos( |
2770 | /*=======================*/ |
2771 | const dict_index_t* index, /*!< in: index */ |
2772 | ulint n) /*!< in: column number */ |
2773 | { |
2774 | - const dict_field_t* field; |
2775 | - const dict_col_t* col; |
2776 | - ulint pos; |
2777 | - ulint n_fields; |
2778 | - |
2779 | - ut_ad(index); |
2780 | - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); |
2781 | - |
2782 | - col = dict_table_get_nth_col(index->table, n); |
2783 | - |
2784 | - if (dict_index_is_clust(index)) { |
2785 | - |
2786 | - return(dict_col_get_clust_pos(col, index)); |
2787 | - } |
2788 | - |
2789 | - n_fields = dict_index_get_n_fields(index); |
2790 | - |
2791 | - for (pos = 0; pos < n_fields; pos++) { |
2792 | - field = dict_index_get_nth_field(index, pos); |
2793 | - |
2794 | - if (col == field->col && field->prefix_len == 0) { |
2795 | - |
2796 | - return(pos); |
2797 | - } |
2798 | - } |
2799 | - |
2800 | - return(ULINT_UNDEFINED); |
2801 | + return(dict_index_get_nth_col_or_prefix_pos(index, n, FALSE)); |
2802 | } |
2803 | |
2804 | #ifndef UNIV_HOTBACKUP |
2805 | @@ -2062,7 +2079,6 @@ |
2806 | { |
2807 | dict_index_t* new_index; |
2808 | dict_field_t* field; |
2809 | - ulint fixed_size; |
2810 | ulint trx_id_pos; |
2811 | ulint i; |
2812 | ibool* indexed; |
2813 | @@ -2139,7 +2155,7 @@ |
2814 | |
2815 | for (i = 0; i < trx_id_pos; i++) { |
2816 | |
2817 | - fixed_size = dict_col_get_fixed_size( |
2818 | + ulint fixed_size = dict_col_get_fixed_size( |
2819 | dict_index_get_nth_col(new_index, i), |
2820 | dict_table_is_comp(table)); |
2821 | |
2822 | @@ -2156,7 +2172,20 @@ |
2823 | break; |
2824 | } |
2825 | |
2826 | - new_index->trx_id_offset += (unsigned int) fixed_size; |
2827 | + /* Add fixed_size to new_index->trx_id_offset. |
2828 | + Because the latter is a bit-field, an overflow |
2829 | + can theoretically occur. Check for it. */ |
2830 | + fixed_size += new_index->trx_id_offset; |
2831 | + |
2832 | + new_index->trx_id_offset = fixed_size; |
2833 | + |
2834 | + if (new_index->trx_id_offset != fixed_size) { |
2835 | + /* Overflow. Pretend that this is a |
2836 | + variable-length PRIMARY KEY. */ |
2837 | + ut_ad(0); |
2838 | + new_index->trx_id_offset = 0; |
2839 | + break; |
2840 | + } |
2841 | } |
2842 | |
2843 | } |
2844 | |
2845 | === modified file 'Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc' |
2846 | --- Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2013-01-10 04:35:31 +0000 |
2847 | +++ Percona-Server/storage/innodb_plugin/handler/ha_innodb.cc 2013-01-10 04:35:33 +0000 |
2848 | @@ -12123,8 +12123,8 @@ |
2849 | #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG |
2850 | static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, |
2851 | PLUGIN_VAR_RQCMDARG, |
2852 | - "Debug flags for InnoDB change buffering (0=none)", |
2853 | - NULL, NULL, 0, 0, 1, 0); |
2854 | + "Debug flags for InnoDB change buffering (0=none, 2=crash at merge)", |
2855 | + NULL, NULL, 0, 0, 2, 0); |
2856 | #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ |
2857 | |
2858 | static MYSQL_SYSVAR_BOOL(random_read_ahead, srv_random_read_ahead, |
2859 | |
2860 | === modified file 'Percona-Server/storage/innodb_plugin/handler/handler0alter.cc' |
2861 | --- Percona-Server/storage/innodb_plugin/handler/handler0alter.cc 2012-08-20 03:14:02 +0000 |
2862 | +++ Percona-Server/storage/innodb_plugin/handler/handler0alter.cc 2013-01-10 04:35:33 +0000 |
2863 | @@ -108,13 +108,17 @@ |
2864 | /* These column types should never be shipped to MySQL. */ |
2865 | ut_ad(0); |
2866 | |
2867 | - case DATA_CHAR: |
2868 | case DATA_FIXBINARY: |
2869 | case DATA_FLOAT: |
2870 | case DATA_DOUBLE: |
2871 | case DATA_DECIMAL: |
2872 | /* Above are the valid column types for MySQL data. */ |
2873 | ut_ad(flen == len); |
2874 | + /* fall through */ |
2875 | + case DATA_CHAR: |
2876 | + /* We may have flen > len when there is a shorter |
2877 | + prefix on a CHAR column. */ |
2878 | + ut_ad(flen >= len); |
2879 | #else /* UNIV_DEBUG */ |
2880 | default: |
2881 | #endif /* UNIV_DEBUG */ |
2882 | @@ -147,7 +151,7 @@ |
2883 | |
2884 | field->reset(); |
2885 | |
2886 | - ipos = dict_index_get_nth_col_pos(index, i); |
2887 | + ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE); |
2888 | |
2889 | if (UNIV_UNLIKELY(ipos == ULINT_UNDEFINED)) { |
2890 | null_field: |
2891 | |
2892 | === modified file 'Percona-Server/storage/innodb_plugin/ibuf/ibuf0ibuf.c' |
2893 | --- Percona-Server/storage/innodb_plugin/ibuf/ibuf0ibuf.c 2013-01-10 04:35:31 +0000 |
2894 | +++ Percona-Server/storage/innodb_plugin/ibuf/ibuf0ibuf.c 2013-01-10 04:35:33 +0000 |
2895 | @@ -3049,7 +3049,8 @@ |
2896 | /* The records only differ in the delete-mark. |
2897 | Clear the delete-mark, like we did before |
2898 | Bug #56680 was fixed. */ |
2899 | - btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr); |
2900 | + btr_cur_set_deleted_flag_for_ibuf( |
2901 | + rec, page_zip, FALSE, mtr); |
2902 | updated_in_place: |
2903 | mem_heap_free(heap); |
2904 | return; |
2905 | @@ -3134,6 +3135,22 @@ |
2906 | ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no); |
2907 | ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space); |
2908 | |
2909 | +#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG |
2910 | + if (ibuf_debug == 2) { |
2911 | + /* Inject a fault (crash). We do this before trying |
2912 | + optimistic delete, because a pessimistic delete in the |
2913 | + change buffer would require a larger test case. */ |
2914 | + |
2915 | + /* Flag the buffered record as processed, to avoid |
2916 | + an assertion failure after crash recovery. */ |
2917 | + btr_cur_set_deleted_flag_for_ibuf( |
2918 | + btr_pcur_get_rec(pcur), NULL, TRUE, mtr); |
2919 | + mtr_commit(mtr); |
2920 | + log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE); |
2921 | + DBUG_SUICIDE(); |
2922 | + } |
2923 | +#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ |
2924 | + |
2925 | success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr); |
2926 | |
2927 | if (success) { |
2928 | @@ -3152,7 +3169,13 @@ |
2929 | ut_ad(ibuf_rec_get_page_no(btr_pcur_get_rec(pcur)) == page_no); |
2930 | ut_ad(ibuf_rec_get_space(btr_pcur_get_rec(pcur)) == space); |
2931 | |
2932 | - /* We have to resort to a pessimistic delete from ibuf */ |
2933 | + /* We have to resort to a pessimistic delete from ibuf. |
2934 | + Delete-mark the record so that it will not be applied again, |
2935 | + in case the server crashes before the pessimistic delete is |
2936 | + made persistent. */ |
2937 | + btr_cur_set_deleted_flag_for_ibuf( |
2938 | + btr_pcur_get_rec(pcur), NULL, TRUE, mtr); |
2939 | + |
2940 | btr_pcur_store_position(pcur, mtr); |
2941 | |
2942 | btr_pcur_commit_specify_mtr(pcur, mtr); |
2943 | @@ -3461,7 +3484,7 @@ |
2944 | fputs("InnoDB: Discarding record\n ", stderr); |
2945 | rec_print_old(stderr, rec); |
2946 | fputs("\nInnoDB: from the insert buffer!\n\n", stderr); |
2947 | - } else if (block) { |
2948 | + } else if (block && !rec_get_deleted_flag(rec, 0)) { |
2949 | /* Now we have at pcur a record which should be |
2950 | inserted to the index page; NOTE that the call below |
2951 | copies pointers to fields in rec, and we must |
2952 | |
2953 | === modified file 'Percona-Server/storage/innodb_plugin/include/btr0cur.h' |
2954 | --- Percona-Server/storage/innodb_plugin/include/btr0cur.h 2012-10-16 11:18:45 +0000 |
2955 | +++ Percona-Server/storage/innodb_plugin/include/btr0cur.h 2013-01-10 04:35:33 +0000 |
2956 | @@ -358,19 +358,20 @@ |
2957 | ibool val, /*!< in: value to set */ |
2958 | que_thr_t* thr, /*!< in: query thread */ |
2959 | mtr_t* mtr); /*!< in: mtr */ |
2960 | -/***********************************************************//** |
2961 | -Clear a secondary index record's delete mark. This function is only |
2962 | +/*************************************************************** |
2963 | +Sets a secondary index record delete mark. This function is only |
2964 | used by the insert buffer insert merge mechanism. */ |
2965 | UNIV_INTERN |
2966 | void |
2967 | -btr_cur_del_unmark_for_ibuf( |
2968 | -/*========================*/ |
2969 | +btr_cur_set_deleted_flag_for_ibuf( |
2970 | +/*==============================*/ |
2971 | rec_t* rec, /*!< in/out: record to delete unmark */ |
2972 | page_zip_des_t* page_zip, /*!< in/out: compressed page |
2973 | corresponding to rec, or NULL |
2974 | when the tablespace is |
2975 | uncompressed */ |
2976 | - mtr_t* mtr); /*!< in: mtr */ |
2977 | + ibool val, /*!< in: value to set */ |
2978 | + mtr_t* mtr); /*!< in/out: mini-transaction */ |
2979 | /*************************************************************//** |
2980 | Tries to compress a page of the tree if it seems useful. It is assumed |
2981 | that mtr holds an x-latch on the tree and on the cursor page. To avoid |
2982 | |
2983 | === modified file 'Percona-Server/storage/innodb_plugin/include/dict0dict.h' |
2984 | --- Percona-Server/storage/innodb_plugin/include/dict0dict.h 2012-05-09 04:14:12 +0000 |
2985 | +++ Percona-Server/storage/innodb_plugin/include/dict0dict.h 2013-01-10 04:35:33 +0000 |
2986 | @@ -839,6 +839,18 @@ |
2987 | const dict_index_t* index, /*!< in: index */ |
2988 | ulint n); /*!< in: column number */ |
2989 | /********************************************************************//** |
2990 | +Looks for column n in an index. |
2991 | +@return position in internal representation of the index; |
2992 | +ULINT_UNDEFINED if not contained */ |
2993 | +UNIV_INTERN |
2994 | +ulint |
2995 | +dict_index_get_nth_col_or_prefix_pos( |
2996 | +/*=================================*/ |
2997 | + const dict_index_t* index, /*!< in: index */ |
2998 | + ulint n, /*!< in: column number */ |
2999 | + ibool inc_prefix); /*!< in: TRUE=consider |
3000 | + column prefixes too */ |
3001 | +/********************************************************************//** |
3002 | Returns TRUE if the index contains a column or a prefix of that column. |
3003 | @return TRUE if contains the column or its prefix */ |
3004 | UNIV_INTERN |
3005 | |
3006 | === modified file 'Percona-Server/storage/innodb_plugin/include/dict0mem.h' |
3007 | --- Percona-Server/storage/innodb_plugin/include/dict0mem.h 2012-05-09 04:14:12 +0000 |
3008 | +++ Percona-Server/storage/innodb_plugin/include/dict0mem.h 2013-01-10 04:35:33 +0000 |
3009 | @@ -286,10 +286,15 @@ |
3010 | #endif /* !UNIV_HOTBACKUP */ |
3011 | unsigned type:4; /*!< index type (DICT_CLUSTERED, DICT_UNIQUE, |
3012 | DICT_UNIVERSAL, DICT_IBUF) */ |
3013 | - unsigned trx_id_offset:10;/*!< position of the trx id column |
3014 | +#define MAX_KEY_LENGTH_BITS 12 |
3015 | + unsigned trx_id_offset:MAX_KEY_LENGTH_BITS; |
3016 | + /*!< position of the trx id column |
3017 | in a clustered index record, if the fields |
3018 | before it are known to be of a fixed size, |
3019 | 0 otherwise */ |
3020 | +#if (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH |
3021 | +# error (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH |
3022 | +#endif |
3023 | unsigned n_user_defined_cols:10; |
3024 | /*!< number of columns the user defined to |
3025 | be in the index: in the internal |
3026 | |
3027 | === modified file 'Percona-Server/storage/innodb_plugin/include/page0zip.h' |
3028 | --- Percona-Server/storage/innodb_plugin/include/page0zip.h 2011-11-24 02:00:38 +0000 |
3029 | +++ Percona-Server/storage/innodb_plugin/include/page0zip.h 2013-01-10 04:35:33 +0000 |
3030 | @@ -156,9 +156,10 @@ |
3031 | /*==================*/ |
3032 | const page_zip_des_t* page_zip,/*!< in: compressed page */ |
3033 | const page_t* page, /*!< in: uncompressed page */ |
3034 | + const dict_index_t* index, /*!< in: index of the page, if known */ |
3035 | ibool sloppy) /*!< in: FALSE=strict, |
3036 | TRUE=ignore the MIN_REC_FLAG */ |
3037 | - __attribute__((nonnull)); |
3038 | + __attribute__((nonnull(1,2))); |
3039 | /**********************************************************************//** |
3040 | Check that the compressed and decompressed pages match. */ |
3041 | UNIV_INTERN |
3042 | @@ -166,8 +167,9 @@ |
3043 | page_zip_validate( |
3044 | /*==============*/ |
3045 | const page_zip_des_t* page_zip,/*!< in: compressed page */ |
3046 | - const page_t* page) /*!< in: uncompressed page */ |
3047 | - __attribute__((nonnull)); |
3048 | + const page_t* page, /*!< in: uncompressed page */ |
3049 | + const dict_index_t* index) /*!< in: index of the page, if known */ |
3050 | + __attribute__((nonnull(1,2))); |
3051 | #endif /* UNIV_ZIP_DEBUG */ |
3052 | |
3053 | /**********************************************************************//** |
3054 | |
3055 | === modified file 'Percona-Server/storage/innodb_plugin/include/row0undo.h' |
3056 | --- Percona-Server/storage/innodb_plugin/include/row0undo.h 2009-05-26 12:28:49 +0000 |
3057 | +++ Percona-Server/storage/innodb_plugin/include/row0undo.h 2013-01-10 04:35:33 +0000 |
3058 | @@ -87,10 +87,6 @@ |
3059 | enum undo_exec { |
3060 | UNDO_NODE_FETCH_NEXT = 1, /*!< we should fetch the next |
3061 | undo log record */ |
3062 | - UNDO_NODE_PREV_VERS, /*!< the roll ptr to previous |
3063 | - version of a row is stored in |
3064 | - node, and undo should be done |
3065 | - based on it */ |
3066 | UNDO_NODE_INSERT, /*!< undo a fresh insert of a |
3067 | row to a table */ |
3068 | UNDO_NODE_MODIFY /*!< undo a modify operation |
3069 | @@ -108,9 +104,6 @@ |
3070 | undo_no_t undo_no;/*!< undo number of the record */ |
3071 | ulint rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC, |
3072 | ... */ |
3073 | - roll_ptr_t new_roll_ptr; |
3074 | - /*!< roll ptr to restore to clustered index |
3075 | - record */ |
3076 | trx_id_t new_trx_id; /*!< trx id to restore to clustered index |
3077 | record */ |
3078 | btr_pcur_t pcur; /*!< persistent cursor used in searching the |
3079 | |
3080 | === modified file 'Percona-Server/storage/innodb_plugin/log/log0recv.c' |
3081 | --- Percona-Server/storage/innodb_plugin/log/log0recv.c 2012-06-14 09:16:03 +0000 |
3082 | +++ Percona-Server/storage/innodb_plugin/log/log0recv.c 2013-01-10 04:35:33 +0000 |
3083 | @@ -1687,9 +1687,8 @@ |
3084 | if (fil_page_get_type(page) == FIL_PAGE_INDEX) { |
3085 | page_zip_des_t* page_zip = buf_block_get_page_zip(block); |
3086 | |
3087 | - if (page_zip) { |
3088 | - ut_a(page_zip_validate_low(page_zip, page, FALSE)); |
3089 | - } |
3090 | + ut_a(!page_zip |
3091 | + || page_zip_validate_low(page_zip, page, NULL, FALSE)); |
3092 | } |
3093 | #endif /* UNIV_ZIP_DEBUG */ |
3094 | |
3095 | |
3096 | === modified file 'Percona-Server/storage/innodb_plugin/os/os0file.c' |
3097 | --- Percona-Server/storage/innodb_plugin/os/os0file.c 2013-01-04 07:28:01 +0000 |
3098 | +++ Percona-Server/storage/innodb_plugin/os/os0file.c 2013-01-10 04:35:33 +0000 |
3099 | @@ -1296,6 +1296,14 @@ |
3100 | DWORD create_flag; |
3101 | DWORD attributes; |
3102 | ibool retry; |
3103 | + |
3104 | + DBUG_EXECUTE_IF( |
3105 | + "ib_create_table_fail_disk_full", |
3106 | + *success = FALSE; |
3107 | + SetLastError(ERROR_DISK_FULL); |
3108 | + return((os_file_t) -1); |
3109 | + ); |
3110 | + |
3111 | try_again: |
3112 | ut_a(name); |
3113 | |
3114 | @@ -1411,6 +1419,13 @@ |
3115 | ibool retry; |
3116 | const char* mode_str = NULL; |
3117 | |
3118 | + DBUG_EXECUTE_IF( |
3119 | + "ib_create_table_fail_disk_full", |
3120 | + *success = FALSE; |
3121 | + errno = ENOSPC; |
3122 | + return((os_file_t) -1); |
3123 | + ); |
3124 | + |
3125 | try_again: |
3126 | ut_a(name); |
3127 | |
3128 | |
3129 | === modified file 'Percona-Server/storage/innodb_plugin/page/page0cur.c' |
3130 | --- Percona-Server/storage/innodb_plugin/page/page0cur.c 2013-01-10 04:35:31 +0000 |
3131 | +++ Percona-Server/storage/innodb_plugin/page/page0cur.c 2013-01-10 04:35:33 +0000 |
3132 | @@ -310,7 +310,7 @@ |
3133 | #endif /* UNIV_DEBUG */ |
3134 | page = buf_block_get_frame(block); |
3135 | #ifdef UNIV_ZIP_DEBUG |
3136 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
3137 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
3138 | #endif /* UNIV_ZIP_DEBUG */ |
3139 | |
3140 | page_check_dir(page); |
3141 | @@ -1248,7 +1248,7 @@ |
3142 | |
3143 | ut_ad(!page_rec_is_supremum(*current_rec)); |
3144 | #ifdef UNIV_ZIP_DEBUG |
3145 | - ut_a(page_zip_validate(page_zip, page)); |
3146 | + ut_a(page_zip_validate(page_zip, page, index)); |
3147 | #endif /* UNIV_ZIP_DEBUG */ |
3148 | |
3149 | /* 1. Get the size of the physical record in the page */ |
3150 | @@ -1973,7 +1973,7 @@ |
3151 | } |
3152 | |
3153 | #ifdef UNIV_ZIP_DEBUG |
3154 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
3155 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
3156 | #endif /* UNIV_ZIP_DEBUG */ |
3157 | } |
3158 | |
3159 | |
3160 | === modified file 'Percona-Server/storage/innodb_plugin/page/page0page.c' |
3161 | --- Percona-Server/storage/innodb_plugin/page/page0page.c 2013-01-10 04:35:31 +0000 |
3162 | +++ Percona-Server/storage/innodb_plugin/page/page0page.c 2013-01-10 04:35:33 +0000 |
3163 | @@ -625,7 +625,7 @@ |
3164 | Furthermore, btr_compress() may set FIL_PAGE_PREV to |
3165 | FIL_NULL on new_page while leaving it intact on |
3166 | new_page_zip. So, we cannot validate new_page_zip. */ |
3167 | - ut_a(page_zip_validate_low(page_zip, page, TRUE)); |
3168 | + ut_a(page_zip_validate_low(page_zip, page, index, TRUE)); |
3169 | } |
3170 | #endif /* UNIV_ZIP_DEBUG */ |
3171 | ut_ad(buf_block_get_frame(block) == page); |
3172 | @@ -945,7 +945,7 @@ |
3173 | ut_ad(size == ULINT_UNDEFINED || size < UNIV_PAGE_SIZE); |
3174 | ut_ad(!page_zip || page_rec_is_comp(rec)); |
3175 | #ifdef UNIV_ZIP_DEBUG |
3176 | - ut_a(!page_zip || page_zip_validate(page_zip, page)); |
3177 | + ut_a(!page_zip || page_zip_validate(page_zip, page, index)); |
3178 | #endif /* UNIV_ZIP_DEBUG */ |
3179 | |
3180 | if (page_rec_is_infimum(rec)) { |
3181 | @@ -987,7 +987,7 @@ |
3182 | ULINT_UNDEFINED, &heap); |
3183 | rec = rec_get_next_ptr(rec, TRUE); |
3184 | #ifdef UNIV_ZIP_DEBUG |
3185 | - ut_a(page_zip_validate(page_zip, page)); |
3186 | + ut_a(page_zip_validate(page_zip, page, index)); |
3187 | #endif /* UNIV_ZIP_DEBUG */ |
3188 | page_cur_delete_rec(&cur, index, offsets, mtr); |
3189 | } while (page_offset(rec) != PAGE_NEW_SUPREMUM); |
3190 | @@ -1127,7 +1127,8 @@ |
3191 | between btr_attach_half_pages() and insert_page = ... |
3192 | when btr_page_get_split_rec_to_left() holds |
3193 | (direction == FSP_DOWN). */ |
3194 | - ut_a(!page_zip || page_zip_validate_low(page_zip, page, TRUE)); |
3195 | + ut_a(!page_zip |
3196 | + || page_zip_validate_low(page_zip, page, index, TRUE)); |
3197 | } |
3198 | #endif /* UNIV_ZIP_DEBUG */ |
3199 | |
3200 | @@ -1198,9 +1199,10 @@ |
3201 | = buf_block_get_page_zip(block); |
3202 | ut_a(!new_page_zip == !page_zip); |
3203 | ut_a(!new_page_zip |
3204 | - || page_zip_validate(new_page_zip, new_page)); |
3205 | + || page_zip_validate(new_page_zip, new_page, index)); |
3206 | ut_a(!page_zip |
3207 | - || page_zip_validate(page_zip, page_align(split_rec))); |
3208 | + || page_zip_validate(page_zip, page_align(split_rec), |
3209 | + index)); |
3210 | } |
3211 | #endif /* UNIV_ZIP_DEBUG */ |
3212 | |
3213 | |
3214 | === modified file 'Percona-Server/storage/innodb_plugin/page/page0zip.c' |
3215 | --- Percona-Server/storage/innodb_plugin/page/page0zip.c 2011-11-24 02:00:43 +0000 |
3216 | +++ Percona-Server/storage/innodb_plugin/page/page0zip.c 2013-01-10 04:35:33 +0000 |
3217 | @@ -1437,7 +1437,7 @@ |
3218 | page_zip_get_size(page_zip) - PAGE_DATA); |
3219 | mem_heap_free(heap); |
3220 | #ifdef UNIV_ZIP_DEBUG |
3221 | - ut_a(page_zip_validate(page_zip, page)); |
3222 | + ut_a(page_zip_validate(page_zip, page, index)); |
3223 | #endif /* UNIV_ZIP_DEBUG */ |
3224 | |
3225 | if (mtr) { |
3226 | @@ -3123,6 +3123,7 @@ |
3227 | /*==================*/ |
3228 | const page_zip_des_t* page_zip,/*!< in: compressed page */ |
3229 | const page_t* page, /*!< in: uncompressed page */ |
3230 | + const dict_index_t* index, /*!< in: index of the page, if known */ |
3231 | ibool sloppy) /*!< in: FALSE=strict, |
3232 | TRUE=ignore the MIN_REC_FLAG */ |
3233 | { |
3234 | @@ -3210,39 +3211,102 @@ |
3235 | committed. Let us tolerate that difference when we |
3236 | are performing a sloppy validation. */ |
3237 | |
3238 | - if (sloppy) { |
3239 | - byte info_bits_diff; |
3240 | - ulint offset |
3241 | - = rec_get_next_offs(page + PAGE_NEW_INFIMUM, |
3242 | - TRUE); |
3243 | - ut_a(offset >= PAGE_NEW_SUPREMUM); |
3244 | - offset -= 5 /* REC_NEW_INFO_BITS */; |
3245 | - |
3246 | - info_bits_diff = page[offset] ^ temp_page[offset]; |
3247 | - |
3248 | - if (info_bits_diff == REC_INFO_MIN_REC_FLAG) { |
3249 | - temp_page[offset] = page[offset]; |
3250 | - |
3251 | - if (!memcmp(page + PAGE_HEADER, |
3252 | - temp_page + PAGE_HEADER, |
3253 | - UNIV_PAGE_SIZE - PAGE_HEADER |
3254 | - - FIL_PAGE_DATA_END)) { |
3255 | - |
3256 | - /* Only the minimum record flag |
3257 | - differed. Let us ignore it. */ |
3258 | - page_zip_fail(("page_zip_validate: " |
3259 | - "min_rec_flag " |
3260 | - "(ignored, " |
3261 | - "%lu,%lu,0x%02lx)\n", |
3262 | - page_get_space_id(page), |
3263 | - page_get_page_no(page), |
3264 | - (ulong) page[offset])); |
3265 | - goto func_exit; |
3266 | + ulint* offsets; |
3267 | + mem_heap_t* heap; |
3268 | + const rec_t* rec; |
3269 | + const rec_t* trec; |
3270 | + byte info_bits_diff; |
3271 | + ulint offset |
3272 | + = rec_get_next_offs(page + PAGE_NEW_INFIMUM, TRUE); |
3273 | + ut_a(offset >= PAGE_NEW_SUPREMUM); |
3274 | + offset -= 5/*REC_NEW_INFO_BITS*/; |
3275 | + |
3276 | + info_bits_diff = page[offset] ^ temp_page[offset]; |
3277 | + |
3278 | + if (info_bits_diff == REC_INFO_MIN_REC_FLAG) { |
3279 | + temp_page[offset] = page[offset]; |
3280 | + |
3281 | + if (!memcmp(page + PAGE_HEADER, |
3282 | + temp_page + PAGE_HEADER, |
3283 | + UNIV_PAGE_SIZE - PAGE_HEADER |
3284 | + - FIL_PAGE_DATA_END)) { |
3285 | + |
3286 | + /* Only the minimum record flag |
3287 | + differed. Let us ignore it. */ |
3288 | + page_zip_fail(("page_zip_validate: " |
3289 | + "min_rec_flag " |
3290 | + "(%s" |
3291 | + "%lu,%lu,0x%02lx)\n", |
3292 | + sloppy ? "ignored, " : "", |
3293 | + page_get_space_id(page), |
3294 | + page_get_page_no(page), |
3295 | + (ulong) page[offset])); |
3296 | + valid = sloppy; |
3297 | + goto func_exit; |
3298 | + } |
3299 | + } |
3300 | + |
3301 | + /* Compare the pointers in the PAGE_FREE list. */ |
3302 | + rec = page_header_get_ptr(page, PAGE_FREE); |
3303 | + trec = page_header_get_ptr(temp_page, PAGE_FREE); |
3304 | + |
3305 | + while (rec || trec) { |
3306 | + if (page_offset(rec) != page_offset(trec)) { |
3307 | + page_zip_fail(("page_zip_validate: " |
3308 | + "PAGE_FREE list: %u!=%u\n", |
3309 | + (unsigned) page_offset(rec), |
3310 | + (unsigned) page_offset(trec))); |
3311 | + valid = FALSE; |
3312 | + goto func_exit; |
3313 | + } |
3314 | + |
3315 | + rec = page_rec_get_next_low(rec, TRUE); |
3316 | + trec = page_rec_get_next_low(trec, TRUE); |
3317 | + } |
3318 | + |
3319 | + /* Compare the records. */ |
3320 | + heap = NULL; |
3321 | + offsets = NULL; |
3322 | + rec = page_rec_get_next_low( |
3323 | + page + PAGE_NEW_INFIMUM, TRUE); |
3324 | + trec = page_rec_get_next_low( |
3325 | + temp_page + PAGE_NEW_INFIMUM, TRUE); |
3326 | + |
3327 | + do { |
3328 | + if (page_offset(rec) != page_offset(trec)) { |
3329 | + page_zip_fail(("page_zip_validate: " |
3330 | + "record list: 0x%02x!=0x%02x\n", |
3331 | + (unsigned) page_offset(rec), |
3332 | + (unsigned) page_offset(trec))); |
3333 | + valid = FALSE; |
3334 | + break; |
3335 | + } |
3336 | + |
3337 | + if (index) { |
3338 | + /* Compare the data. */ |
3339 | + offsets = rec_get_offsets( |
3340 | + rec, index, offsets, |
3341 | + ULINT_UNDEFINED, &heap); |
3342 | + |
3343 | + if (memcmp(rec - rec_offs_extra_size(offsets), |
3344 | + trec - rec_offs_extra_size(offsets), |
3345 | + rec_offs_size(offsets))) { |
3346 | + page_zip_fail( |
3347 | + ("page_zip_validate: " |
3348 | + "record content: 0x%02x", |
3349 | + (unsigned) page_offset(rec))); |
3350 | + valid = FALSE; |
3351 | + break; |
3352 | } |
3353 | } |
3354 | + |
3355 | + rec = page_rec_get_next_low(rec, TRUE); |
3356 | + trec = page_rec_get_next_low(trec, TRUE); |
3357 | + } while (rec || trec); |
3358 | + |
3359 | + if (heap) { |
3360 | + mem_heap_free(heap); |
3361 | } |
3362 | - page_zip_fail(("page_zip_validate: content\n")); |
3363 | - valid = FALSE; |
3364 | } |
3365 | |
3366 | func_exit: |
3367 | @@ -3264,9 +3328,10 @@ |
3368 | page_zip_validate( |
3369 | /*==============*/ |
3370 | const page_zip_des_t* page_zip,/*!< in: compressed page */ |
3371 | - const page_t* page) /*!< in: uncompressed page */ |
3372 | + const page_t* page, /*!< in: uncompressed page */ |
3373 | + const dict_index_t* index) /*!< in: index of the page, if known */ |
3374 | { |
3375 | - return(page_zip_validate_low(page_zip, page, |
3376 | + return(page_zip_validate_low(page_zip, page, index, |
3377 | recv_recovery_is_on())); |
3378 | } |
3379 | #endif /* UNIV_ZIP_DEBUG */ |
3380 | @@ -3597,7 +3662,7 @@ |
3381 | page_zip->m_nonempty = TRUE; |
3382 | |
3383 | #ifdef UNIV_ZIP_DEBUG |
3384 | - ut_a(page_zip_validate(page_zip, page_align(rec))); |
3385 | + ut_a(page_zip_validate(page_zip, page_align(rec), index)); |
3386 | #endif /* UNIV_ZIP_DEBUG */ |
3387 | } |
3388 | |
3389 | @@ -3644,7 +3709,7 @@ |
3390 | } |
3391 | |
3392 | #ifdef UNIV_ZIP_DEBUG |
3393 | - ut_a(page_zip_validate(page_zip, page)); |
3394 | + ut_a(page_zip_validate(page_zip, page, NULL)); |
3395 | #endif /* UNIV_ZIP_DEBUG */ |
3396 | |
3397 | memcpy(page + offset, |
3398 | @@ -3653,7 +3718,7 @@ |
3399 | ptr + 4, BTR_EXTERN_FIELD_REF_SIZE); |
3400 | |
3401 | #ifdef UNIV_ZIP_DEBUG |
3402 | - ut_a(page_zip_validate(page_zip, page)); |
3403 | + ut_a(page_zip_validate(page_zip, page, NULL)); |
3404 | #endif /* UNIV_ZIP_DEBUG */ |
3405 | } |
3406 | |
3407 | @@ -3720,7 +3785,7 @@ |
3408 | memcpy(externs, field, BTR_EXTERN_FIELD_REF_SIZE); |
3409 | |
3410 | #ifdef UNIV_ZIP_DEBUG |
3411 | - ut_a(page_zip_validate(page_zip, page)); |
3412 | + ut_a(page_zip_validate(page_zip, page, index)); |
3413 | #endif /* UNIV_ZIP_DEBUG */ |
3414 | |
3415 | if (mtr) { |
3416 | @@ -3791,7 +3856,7 @@ |
3417 | } |
3418 | |
3419 | #ifdef UNIV_ZIP_DEBUG |
3420 | - ut_a(page_zip_validate(page_zip, page)); |
3421 | + ut_a(page_zip_validate(page_zip, page, NULL)); |
3422 | #endif /* UNIV_ZIP_DEBUG */ |
3423 | |
3424 | field = page + offset; |
3425 | @@ -3812,7 +3877,7 @@ |
3426 | memcpy(storage, ptr + 4, REC_NODE_PTR_SIZE); |
3427 | |
3428 | #ifdef UNIV_ZIP_DEBUG |
3429 | - ut_a(page_zip_validate(page_zip, page)); |
3430 | + ut_a(page_zip_validate(page_zip, page, NULL)); |
3431 | #endif /* UNIV_ZIP_DEBUG */ |
3432 | } |
3433 | |
3434 | @@ -4039,7 +4104,7 @@ |
3435 | } |
3436 | |
3437 | #ifdef UNIV_ZIP_DEBUG |
3438 | - ut_a(page_zip_validate(page_zip, page)); |
3439 | + ut_a(page_zip_validate(page_zip, page, index)); |
3440 | #endif /* UNIV_ZIP_DEBUG */ |
3441 | } |
3442 | |
3443 | @@ -4063,7 +4128,7 @@ |
3444 | *slot &= ~(PAGE_ZIP_DIR_SLOT_DEL >> 8); |
3445 | } |
3446 | #ifdef UNIV_ZIP_DEBUG |
3447 | - ut_a(page_zip_validate(page_zip, page_align(rec))); |
3448 | + ut_a(page_zip_validate(page_zip, page_align(rec), NULL)); |
3449 | #endif /* UNIV_ZIP_DEBUG */ |
3450 | } |
3451 | |
3452 | @@ -4364,14 +4429,14 @@ |
3453 | goto corrupt; |
3454 | } |
3455 | #ifdef UNIV_ZIP_DEBUG |
3456 | - ut_a(page_zip_validate(page_zip, page)); |
3457 | + ut_a(page_zip_validate(page_zip, page, NULL)); |
3458 | #endif /* UNIV_ZIP_DEBUG */ |
3459 | |
3460 | memcpy(page + offset, ptr, len); |
3461 | memcpy(page_zip->data + offset, ptr, len); |
3462 | |
3463 | #ifdef UNIV_ZIP_DEBUG |
3464 | - ut_a(page_zip_validate(page_zip, page)); |
3465 | + ut_a(page_zip_validate(page_zip, page, NULL)); |
3466 | #endif /* UNIV_ZIP_DEBUG */ |
3467 | } |
3468 | |
3469 | @@ -4446,7 +4511,7 @@ |
3470 | ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); |
3471 | ut_ad(page_is_comp(page)); |
3472 | ut_ad(!dict_index_is_ibuf(index)); |
3473 | - /* Note that page_zip_validate(page_zip, page) may fail here. */ |
3474 | + /* Note that page_zip_validate(page_zip, page, index) may fail here. */ |
3475 | UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE); |
3476 | UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip)); |
3477 | |
3478 | @@ -4533,7 +4598,7 @@ |
3479 | FIL_PAGE_PREV or PAGE_LEVEL, causing a temporary min_rec_flag |
3480 | mismatch. A strict page_zip_validate() will be executed later |
3481 | during the B-tree operations. */ |
3482 | - ut_a(page_zip_validate_low(src_zip, src, TRUE)); |
3483 | + ut_a(page_zip_validate_low(src_zip, src, index, TRUE)); |
3484 | #endif /* UNIV_ZIP_DEBUG */ |
3485 | ut_a(page_zip_get_size(page_zip) == page_zip_get_size(src_zip)); |
3486 | if (UNIV_UNLIKELY(src_zip->n_blobs)) { |
3487 | @@ -4594,7 +4659,7 @@ |
3488 | } |
3489 | |
3490 | #ifdef UNIV_ZIP_DEBUG |
3491 | - ut_a(page_zip_validate(page_zip, page)); |
3492 | + ut_a(page_zip_validate(page_zip, page, index)); |
3493 | #endif /* UNIV_ZIP_DEBUG */ |
3494 | btr_blob_dbg_add(page, index, "page_zip_copy_recs"); |
3495 | |
3496 | |
3497 | === modified file 'Percona-Server/storage/innodb_plugin/row/row0mysql.c' |
3498 | --- Percona-Server/storage/innodb_plugin/row/row0mysql.c 2012-10-17 11:00:21 +0000 |
3499 | +++ Percona-Server/storage/innodb_plugin/row/row0mysql.c 2013-01-10 04:35:33 +0000 |
3500 | @@ -1792,7 +1792,8 @@ |
3501 | one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor", |
3502 | "innodb_table_monitor", then this will also start the printing of monitor |
3503 | output by the master thread. If the table name ends in "innodb_mem_validate", |
3504 | -InnoDB will try to invoke mem_validate(). |
3505 | +InnoDB will try to invoke mem_validate(). On failure the transaction will |
3506 | +be rolled back and the 'table' object will be freed. |
3507 | @return error code or DB_SUCCESS */ |
3508 | UNIV_INTERN |
3509 | int |
3510 | @@ -1931,6 +1932,8 @@ |
3511 | |
3512 | row_drop_table_for_mysql(table->name, trx, FALSE); |
3513 | trx_commit_for_mysql(trx); |
3514 | + } else { |
3515 | + dict_mem_table_free(table); |
3516 | } |
3517 | break; |
3518 | |
3519 | |
3520 | === modified file 'Percona-Server/storage/innodb_plugin/row/row0sel.c' |
3521 | --- Percona-Server/storage/innodb_plugin/row/row0sel.c 2012-04-02 02:09:15 +0000 |
3522 | +++ Percona-Server/storage/innodb_plugin/row/row0sel.c 2013-01-10 04:35:33 +0000 |
3523 | @@ -3926,6 +3926,11 @@ |
3524 | } |
3525 | |
3526 | rec_loop: |
3527 | + if (trx_is_interrupted(trx)) { |
3528 | + err = DB_INTERRUPTED; |
3529 | + goto normal_return; |
3530 | + } |
3531 | + |
3532 | /*-------------------------------------------------------------*/ |
3533 | /* PHASE 4: Look for matching records in a loop */ |
3534 | |
3535 | @@ -4860,12 +4865,16 @@ |
3536 | |
3537 | rec_offs_init(offsets_); |
3538 | |
3539 | - offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); |
3540 | + offsets = rec_get_offsets(rec, index, offsets, col_no + 1, &heap); |
3541 | + |
3542 | + if (rec_offs_nth_sql_null(offsets, col_no)) { |
3543 | + /* There is no non-NULL value in the auto-increment column. */ |
3544 | + value = 0; |
3545 | + goto func_exit; |
3546 | + } |
3547 | |
3548 | data = rec_get_nth_field(rec, offsets, col_no, &len); |
3549 | |
3550 | - ut_a(len != UNIV_SQL_NULL); |
3551 | - |
3552 | switch (mtype) { |
3553 | case DATA_INT: |
3554 | ut_a(len <= sizeof value); |
3555 | @@ -4886,14 +4895,15 @@ |
3556 | ut_error; |
3557 | } |
3558 | |
3559 | - if (UNIV_LIKELY_NULL(heap)) { |
3560 | - mem_heap_free(heap); |
3561 | - } |
3562 | - |
3563 | if (!unsigned_type && (ib_int64_t) value < 0) { |
3564 | value = 0; |
3565 | } |
3566 | |
3567 | +func_exit: |
3568 | + if (UNIV_LIKELY_NULL(heap)) { |
3569 | + mem_heap_free(heap); |
3570 | + } |
3571 | + |
3572 | return(value); |
3573 | } |
3574 | |
3575 | |
3576 | === modified file 'Percona-Server/storage/innodb_plugin/row/row0umod.c' |
3577 | --- Percona-Server/storage/innodb_plugin/row/row0umod.c 2011-02-02 12:12:49 +0000 |
3578 | +++ Percona-Server/storage/innodb_plugin/row/row0umod.c 2013-01-10 04:35:33 +0000 |
3579 | @@ -69,36 +69,6 @@ |
3580 | introduced where a call to log_free_check() is bypassed. */ |
3581 | |
3582 | /***********************************************************//** |
3583 | -Checks if also the previous version of the clustered index record was |
3584 | -modified or inserted by the same transaction, and its undo number is such |
3585 | -that it should be undone in the same rollback. |
3586 | -@return TRUE if also previous modify or insert of this row should be undone */ |
3587 | -static |
3588 | -ibool |
3589 | -row_undo_mod_undo_also_prev_vers( |
3590 | -/*=============================*/ |
3591 | - undo_node_t* node, /*!< in: row undo node */ |
3592 | - undo_no_t* undo_no)/*!< out: the undo number */ |
3593 | -{ |
3594 | - trx_undo_rec_t* undo_rec; |
3595 | - trx_t* trx; |
3596 | - |
3597 | - trx = node->trx; |
3598 | - |
3599 | - if (0 != ut_dulint_cmp(node->new_trx_id, trx->id)) { |
3600 | - |
3601 | - *undo_no = ut_dulint_zero; |
3602 | - return(FALSE); |
3603 | - } |
3604 | - |
3605 | - undo_rec = trx_undo_get_undo_rec_low(node->new_roll_ptr, node->heap); |
3606 | - |
3607 | - *undo_no = trx_undo_rec_get_undo_no(undo_rec); |
3608 | - |
3609 | - return(ut_dulint_cmp(trx->roll_limit, *undo_no) <= 0); |
3610 | -} |
3611 | - |
3612 | -/***********************************************************//** |
3613 | Undoes a modify in a clustered index record. |
3614 | @return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */ |
3615 | static |
3616 | @@ -226,19 +196,11 @@ |
3617 | btr_pcur_t* pcur; |
3618 | mtr_t mtr; |
3619 | ulint err; |
3620 | - ibool success; |
3621 | - ibool more_vers; |
3622 | - undo_no_t new_undo_no; |
3623 | |
3624 | ut_ad(node && thr); |
3625 | |
3626 | log_free_check(); |
3627 | |
3628 | - /* Check if also the previous version of the clustered index record |
3629 | - should be undone in this same rollback operation */ |
3630 | - |
3631 | - more_vers = row_undo_mod_undo_also_prev_vers(node, &new_undo_no); |
3632 | - |
3633 | pcur = &(node->pcur); |
3634 | |
3635 | mtr_start(&mtr); |
3636 | @@ -286,20 +248,6 @@ |
3637 | |
3638 | trx_undo_rec_release(node->trx, node->undo_no); |
3639 | |
3640 | - if (more_vers && err == DB_SUCCESS) { |
3641 | - |
3642 | - /* Reserve the undo log record to the prior version after |
3643 | - committing &mtr: this is necessary to comply with the latching |
3644 | - order, as &mtr may contain the fsp latch which is lower in |
3645 | - the latch hierarchy than trx->undo_mutex. */ |
3646 | - |
3647 | - success = trx_undo_rec_reserve(node->trx, new_undo_no); |
3648 | - |
3649 | - if (success) { |
3650 | - node->state = UNDO_NODE_PREV_VERS; |
3651 | - } |
3652 | - } |
3653 | - |
3654 | return(err); |
3655 | } |
3656 | |
3657 | @@ -799,7 +747,6 @@ |
3658 | trx_undo_update_rec_get_update(ptr, clust_index, type, trx_id, |
3659 | roll_ptr, info_bits, trx, |
3660 | node->heap, &(node->update)); |
3661 | - node->new_roll_ptr = roll_ptr; |
3662 | node->new_trx_id = trx_id; |
3663 | node->cmpl_info = cmpl_info; |
3664 | } |
3665 | |
3666 | === modified file 'Percona-Server/storage/innodb_plugin/row/row0undo.c' |
3667 | --- Percona-Server/storage/innodb_plugin/row/row0undo.c 2010-06-29 13:00:58 +0000 |
3668 | +++ Percona-Server/storage/innodb_plugin/row/row0undo.c 2013-01-10 04:35:33 +0000 |
3669 | @@ -283,25 +283,6 @@ |
3670 | } else { |
3671 | node->state = UNDO_NODE_MODIFY; |
3672 | } |
3673 | - |
3674 | - } else if (node->state == UNDO_NODE_PREV_VERS) { |
3675 | - |
3676 | - /* Undo should be done to the same clustered index record |
3677 | - again in this same rollback, restoring the previous version */ |
3678 | - |
3679 | - roll_ptr = node->new_roll_ptr; |
3680 | - |
3681 | - node->undo_rec = trx_undo_get_undo_rec_low(roll_ptr, |
3682 | - node->heap); |
3683 | - node->roll_ptr = roll_ptr; |
3684 | - node->undo_no = trx_undo_rec_get_undo_no(node->undo_rec); |
3685 | - |
3686 | - if (trx_undo_roll_ptr_is_insert(roll_ptr)) { |
3687 | - |
3688 | - node->state = UNDO_NODE_INSERT; |
3689 | - } else { |
3690 | - node->state = UNDO_NODE_MODIFY; |
3691 | - } |
3692 | } |
3693 | |
3694 | /* Prevent DROP TABLE etc. while we are rolling back this row. |
3695 | |
3696 | === modified file 'Percona-Server/storage/myisam/myisamchk.c' |
3697 | --- Percona-Server/storage/myisam/myisamchk.c 2011-06-30 15:37:13 +0000 |
3698 | +++ Percona-Server/storage/myisam/myisamchk.c 2013-01-10 04:35:33 +0000 |
3699 | @@ -310,7 +310,14 @@ |
3700 | &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG, |
3701 | (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD, |
3702 | INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0}, |
3703 | - { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "", |
3704 | + { "sort_buffer_size", OPT_SORT_BUFFER_SIZE, |
3705 | + "Deprecated. myisam_sort_buffer_size alias is being used", |
3706 | + &check_param.sort_buffer_length, |
3707 | + &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG, |
3708 | + (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), |
3709 | + ULONG_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0}, |
3710 | + { "myisam_sort_buffer_size", OPT_SORT_BUFFER_SIZE, |
3711 | + "Alias of sort_buffer_size parameter", |
3712 | &check_param.sort_buffer_length, |
3713 | &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG, |
3714 | (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), |
3715 | |
3716 | === modified file 'Percona-Server/tests/mysql_client_test.c' |
3717 | --- Percona-Server/tests/mysql_client_test.c 2012-08-20 00:29:22 +0000 |
3718 | +++ Percona-Server/tests/mysql_client_test.c 2013-01-10 04:35:33 +0000 |
3719 | @@ -15278,6 +15278,7 @@ |
3720 | |
3721 | rc= mysql_query(mysql, "set names default"); |
3722 | myquery(rc); |
3723 | + DBUG_VOID_RETURN; |
3724 | } |
3725 | |
3726 |
Setting to WiP until https:/ /code.launchpad .net/~stewart/ percona- server/ 5.5.30/ +merge/ 148984 is merged.