=== modified file 'Percona-Server/mysql-test/suite/innodb/r/percona_changed_page_bmp.result'
--- Percona-Server/mysql-test/suite/innodb/r/percona_changed_page_bmp.result	2013-02-04 13:53:47 +0000
+++ Percona-Server/mysql-test/suite/innodb/r/percona_changed_page_bmp.result	2013-05-29 15:11:30 +0000
@@ -47,13 +47,20 @@
 ib_modified_log_1
 ib_modified_log_2
 ib_modified_log_3
+DROP TABLE t1, t2;
 8th restart
 RESET CHANGED_PAGE_BITMAPS;
 call mtr.add_suppression("InnoDB: Error: page [0-9]* log sequence number [0-9]*");
 9th restart
+<<<<<<< TREE
 CREATE TABLE t3 (a MEDIUMBLOB) ENGINE=InnoDB;
 call mtr.add_suppression("InnoDB: Error: the age of the oldest untracked record exceeds the log group capacity!");
 call mtr.add_suppression("InnoDB: Error: stopping the log tracking thread at LSN");
 INSERT INTO t3 VALUES (REPEAT('a', 12582912));
 10th restart
 DROP TABLE t1, t2, t3;
+=======
+ib_modified_log_1
+10th restart
+11th restart
+>>>>>>> MERGE-SOURCE

=== modified file 'Percona-Server/mysql-test/suite/innodb/r/percona_changed_pages.result'
--- Percona-Server/mysql-test/suite/innodb/r/percona_changed_pages.result	2013-01-29 15:14:23 +0000
+++ Percona-Server/mysql-test/suite/innodb/r/percona_changed_pages.result	2013-05-29 15:11:30 +0000
@@ -1,5 +1,5 @@
 RESET CHANGED_PAGE_BITMAPS;
-DROP TABLE IF EXISTS T1;
+DROP TABLE IF EXISTS T1, ICP_COPY;
 CREATE TABLE T1 (F1 CHAR(255)) ENGINE=INNODB;
 1st interval end LSN greater than interval start LSN:
 should_be_1
@@ -54,35 +54,35 @@
 ICP tests (all should be 1):
 SELECT COUNT(*) = @cond_test_pages_count
 FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-WHERE END_LSN = @cond_test_max_end_lsn;
-COUNT(*) = @cond_test_pages_count
-1
-SELECT COUNT(*) = @cond_test_pages_count
-FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-WHERE
-END_LSN > (@cond_test_max_end_lsn - 1) AND
-END_LSN < (@cond_test_max_end_lsn + 1);
-COUNT(*) = @cond_test_pages_count
-1
-SELECT COUNT(*) = @cond_test_pages_count
-FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-WHERE
-END_LSN >= @cond_test_max_end_lsn AND
-END_LSN <= @cond_test_max_end_lsn;
-COUNT(*) = @cond_test_pages_count
-1
-SELECT COUNT(*) = @cond_test_pages_count
-FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-WHERE
-(@cond_test_max_end_lsn - 1) < END_LSN AND
-@cond_test_max_end_lsn >= END_LSN;
-COUNT(*) = @cond_test_pages_count
-1
-SELECT COUNT(*) = @cond_test_pages_count
-FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-WHERE
-START_LSN <= @cond_test_max_end_lsn AND
-END_LSN >= @cond_test_max_end_lsn;
+WHERE END_LSN = @max_end_lsn;
+COUNT(*) = @cond_test_pages_count
+1
+SELECT COUNT(*) = @cond_test_pages_count
+FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+WHERE
+END_LSN > (@max_end_lsn - 1) AND
+END_LSN < (@max_end_lsn + 1);
+COUNT(*) = @cond_test_pages_count
+1
+SELECT COUNT(*) = @cond_test_pages_count
+FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+WHERE
+END_LSN >= @max_end_lsn AND
+END_LSN <= @max_end_lsn;
+COUNT(*) = @cond_test_pages_count
+1
+SELECT COUNT(*) = @cond_test_pages_count
+FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+WHERE
+(@max_end_lsn - 1) < END_LSN AND
+@max_end_lsn >= END_LSN;
+COUNT(*) = @cond_test_pages_count
+1
+SELECT COUNT(*) = @cond_test_pages_count
+FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+WHERE
+START_LSN <= @max_end_lsn AND
+END_LSN >= @max_end_lsn;
 COUNT(*) = @cond_test_pages_count
 1
 SELECT COUNT(*) = @cond_test_pages_count
@@ -101,7 +101,7 @@
 FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
 WHERE
 START_LSN >= @cond_test_max_start_lsn AND
-END_LSN <= @cond_test_max_end_lsn;
+END_LSN <= @max_end_lsn;
 COUNT(*) = @cond_test_pages_count
 1
 SELECT COUNT(*) = @cond_test_pages_count
@@ -115,7 +115,7 @@
 FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
 WHERE
 @cond_test_max_start_lsn <= START_LSN AND
-@cond_test_max_end_lsn >= END_LSN;
+@max_end_lsn >= END_LSN;
 COUNT(*) = @cond_test_pages_count
 1
 SELECT COUNT(*)
@@ -153,4 +153,29 @@
 COUNT(*)
 5
 SET GLOBAL INNODB_MAX_CHANGED_PAGES = 1000000;
-DROP TABLE T1;
+CREATE TABLE ICP_COPY (
+space_id INT(11) NOT NULL,
+page_id INT(11) NOT NULL,
+start_lsn BIGINT(21) NOT NULL,
+end_lsn BIGINT(21) NOT NULL,
+INDEX page_id(space_id, page_id)) ENGINE=InnoDB;
+INSERT INTO ICP_COPY SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+WHERE END_LSN <= @max_end_lsn;
+SELECT @@global.innodb_track_changed_pages;
+@@global.innodb_track_changed_pages
+0
+SET @max_end_lsn= (SELECT MAX(end_lsn) FROM ICP_COPY);
+TRUNCATE TABLE ICP_COPY;
+INSERT INTO ICP_COPY SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+WHERE END_LSN <= @max_end_lsn;
+Check that INNODB_CHANGED_PAGES copies checksum the same (should be 1):
+should_be_1
+1
+SELECT @@global.innodb_track_changed_pages;
+@@global.innodb_track_changed_pages
+1
+ib_modified_log_4
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+WHERE START_LSN > 10000;
+ERROR HY000: Can't read record in system table
+DROP TABLE T1, ICP_COPY;

=== modified file 'Percona-Server/mysql-test/suite/innodb/r/percona_changed_pages_empty.result'
--- Percona-Server/mysql-test/suite/innodb/r/percona_changed_pages_empty.result	2012-09-17 13:08:32 +0000
+++ Percona-Server/mysql-test/suite/innodb/r/percona_changed_pages_empty.result	2013-05-29 15:11:30 +0000
@@ -1,2 +1,3 @@
+RESET CHANGED_PAGE_BITMAPS;
 SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES;
 space_id	page_id	start_lsn	end_lsn

=== modified file 'Percona-Server/mysql-test/suite/innodb/t/percona_changed_page_bmp.test'
--- Percona-Server/mysql-test/suite/innodb/t/percona_changed_page_bmp.test	2013-02-04 13:53:47 +0000
+++ Percona-Server/mysql-test/suite/innodb/t/percona_changed_page_bmp.test	2013-05-29 15:11:30 +0000
@@ -205,6 +205,8 @@
 --replace_regex /_[[:digit:]]+\.xdb$//
 list_files $MYSQLD_DATADIR ib_modified_log*;
 
+DROP TABLE t1, t2;
+
 #
 # Test for log tracking compatibility with innodb_force_recovery (bug 1083596).
 #
@@ -221,7 +223,19 @@
 RESET CHANGED_PAGE_BITMAPS;
 
 call mtr.add_suppression("InnoDB: Error: page [0-9]* log sequence number [0-9]*");
+
+#
+# Test that bitmap files are created correctly in innodb_data_home_dir without a trailing
+# path separator (bug 1181887)
+#
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+--remove_files_wildcard $MYSQLD_DATADIR ib_logfile*
+--mkdir $MYSQLTEST_VARDIR/tmpdatadir
+--enable_reconnect
 --echo 9th restart
+<<<<<<< TREE
 --source include/restart_mysqld.inc
 
 #
@@ -238,3 +252,22 @@
 --source include/restart_mysqld.inc
 
 DROP TABLE t1, t2, t3;
+=======
+--exec echo "restart:--innodb-data-home-dir=$MYSQLTEST_VARDIR/tmpdatadir" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--source include/wait_until_connected_again.inc
+
+file_exists $MYSQLTEST_VARDIR/tmpdatadir/ib_modified_log_1_0.xdb;
+--replace_regex /_[[:digit:]]+\.xdb$//
+list_files $MYSQLTEST_VARDIR/tmpdatadir ib_modified_log*;
+
+--echo 10th restart
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+--remove_files_wildcard $MYSQLD_DATADIR ib_logfile*
+--remove_files_wildcard $MYSQLD_DATADIR ibdata*
+--enable_reconnect
+--echo 11th restart
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--source include/wait_until_connected_again.inc
+>>>>>>> MERGE-SOURCE

=== modified file 'Percona-Server/mysql-test/suite/innodb/t/percona_changed_page_bmp_flush.test'
--- Percona-Server/mysql-test/suite/innodb/t/percona_changed_page_bmp_flush.test	2013-02-06 09:06:08 +0000
+++ Percona-Server/mysql-test/suite/innodb/t/percona_changed_page_bmp_flush.test	2013-05-29 15:11:30 +0000
@@ -61,7 +61,7 @@
 INSERT INTO t1 VALUES (3, REPEAT("c", 20000));
 
 #
-# Test innodb_flush_method=O_DIRECT
+# Test innodb_flush_method=ALL_O_DIRECT
 # Check that the previous test produced bitmap data while the server is down.
 #
 --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
@@ -71,7 +71,7 @@
 --replace_regex /_[[:digit:]]+\.xdb$//
 list_files $MYSQLD_DATADIR ib_modified_log*;
 --enable_reconnect
---exec echo "restart:--innodb-track-changed-pages=1 --innodb-flush-method=O_DIRECT" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--exec echo "restart:--innodb-track-changed-pages=1 --innodb-flush-method=ALL_O_DIRECT" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
 --source include/wait_until_connected_again.inc
 
 INSERT INTO t1 VALUES (4, REPEAT("d", 20000));

=== modified file 'Percona-Server/mysql-test/suite/innodb/t/percona_changed_pages.test'
--- Percona-Server/mysql-test/suite/innodb/t/percona_changed_pages.test	2013-01-29 15:14:23 +0000
+++ Percona-Server/mysql-test/suite/innodb/t/percona_changed_pages.test	2013-05-29 15:11:30 +0000
@@ -9,7 +9,7 @@
 RESET CHANGED_PAGE_BITMAPS;
 
 --disable_warnings
-DROP TABLE IF EXISTS T1;
+DROP TABLE IF EXISTS T1, ICP_COPY;
 --enable_warnings
 
 let $old_max_changed_pages= `SELECT @@GLOBAL.INNODB_MAX_CHANGED_PAGES`;
@@ -105,9 +105,9 @@
 # Gather data for condition pushdown testing not using conditions #
 ###################################################################
 --disable_result_log
-SET @cond_test_max_end_lsn=
-	(SELECT MAX(end_lsn)
-		FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES);
+SET @max_end_lsn=
+        (SELECT MAX(end_lsn)
+                FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES);
 
 SET @cond_test_max_start_lsn=
         (SELECT MAX(start_lsn)
@@ -153,31 +153,31 @@
 # Baseline as ICP currently does not support equality
 SELECT COUNT(*) = @cond_test_pages_count
   FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-  WHERE END_LSN = @cond_test_max_end_lsn;
+  WHERE END_LSN = @max_end_lsn;
   
 SELECT COUNT(*) = @cond_test_pages_count
   FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
   WHERE
-  END_LSN > (@cond_test_max_end_lsn - 1) AND
-  END_LSN < (@cond_test_max_end_lsn + 1);
-
-SELECT COUNT(*) = @cond_test_pages_count
-  FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-  WHERE
-  END_LSN >= @cond_test_max_end_lsn AND
-  END_LSN <= @cond_test_max_end_lsn;
-
-SELECT COUNT(*) = @cond_test_pages_count
-  FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-  WHERE
-  (@cond_test_max_end_lsn - 1) < END_LSN AND
-  @cond_test_max_end_lsn >= END_LSN;
-
-SELECT COUNT(*) = @cond_test_pages_count
-  FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
-  WHERE
-  START_LSN <= @cond_test_max_end_lsn AND
-  END_LSN >= @cond_test_max_end_lsn;
+  END_LSN > (@max_end_lsn - 1) AND
+  END_LSN < (@max_end_lsn + 1);
+
+SELECT COUNT(*) = @cond_test_pages_count
+  FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+  WHERE
+  END_LSN >= @max_end_lsn AND
+  END_LSN <= @max_end_lsn;
+
+SELECT COUNT(*) = @cond_test_pages_count
+  FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+  WHERE
+  (@max_end_lsn - 1) < END_LSN AND
+  @max_end_lsn >= END_LSN;
+
+SELECT COUNT(*) = @cond_test_pages_count
+  FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+  WHERE
+  START_LSN <= @max_end_lsn AND
+  END_LSN >= @max_end_lsn;
 
 SELECT COUNT(*) = @cond_test_pages_count
   FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
@@ -193,7 +193,7 @@
   FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
   WHERE
   START_LSN >= @cond_test_max_start_lsn AND
-  END_LSN <= @cond_test_max_end_lsn;
+  END_LSN <= @max_end_lsn;
 
 SELECT COUNT(*) = @cond_test_pages_count
   FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
@@ -205,7 +205,7 @@
   FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
   WHERE
   @cond_test_max_start_lsn <= START_LSN AND
-  @cond_test_max_end_lsn >= END_LSN;
+  @max_end_lsn >= END_LSN;
 
 # Empty range
 SELECT COUNT(*)
@@ -262,4 +262,75 @@
 
 eval SET GLOBAL INNODB_MAX_CHANGED_PAGES = $old_max_changed_pages;
 
-DROP TABLE T1;
+#
+# Test that I_S.INNODB_CHANGED_PAGES can be queried with the log tracking disabled
+# (bug 1185304)
+#
+
+# We have to skip ICP_COPY bitmap writes.  Thus all the I_S queries from
+# this point are limited to the max_end_lsn.
+
+# Save the copy of current table contents
+CREATE TABLE ICP_COPY (
+       space_id INT(11) NOT NULL,
+       page_id INT(11) NOT NULL,
+       start_lsn BIGINT(21) NOT NULL,
+       end_lsn BIGINT(21) NOT NULL,
+       INDEX page_id(space_id, page_id)) ENGINE=InnoDB;
+
+INSERT INTO ICP_COPY SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+       WHERE END_LSN <= @max_end_lsn;
+
+# Restart with log tracking disabled       
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--shutdown_server 10
+--source include/wait_until_disconnected.inc
+--enable_reconnect
+--exec echo "restart:--innodb-track-changed-pages=FALSE" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--source include/wait_until_connected_again.inc
+
+SELECT @@global.innodb_track_changed_pages;
+
+let $icp_1_checksum= `CHECKSUM TABLE ICP_COPY`;
+
+SET @max_end_lsn= (SELECT MAX(end_lsn) FROM ICP_COPY);
+
+# Read the table again
+TRUNCATE TABLE ICP_COPY;
+
+INSERT INTO ICP_COPY SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+       WHERE END_LSN <= @max_end_lsn;
+
+# Compare the checksums of both reads
+let $icp_2_checksum= `CHECKSUM TABLE ICP_COPY`;
+--disable_query_log
+--echo Check that INNODB_CHANGED_PAGES copies checksum the same (should be 1):
+eval SELECT "$icp_1_checksum" LIKE "$icp_2_checksum" AS should_be_1;
+--enable_query_log
+
+--source include/restart_mysqld.inc
+
+SELECT @@global.innodb_track_changed_pages;
+
+#
+# Test for
+# - bug 1179974 (INFORMATION_SCHEMA.INNODB_CHANGED_PAGES query fails server
+#   with an I/O error if a bitmap file in the middle of requested range is missing)
+# - bug 1185040 (INFORMATION_SCHEMA.INNODB_CHANGED_PAGES_QUERY should return a
+#   warning if the result set is partial)
+#
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_regex /_[[:digit:]]+\.xdb$//
+list_files $MYSQLD_DATADIR ib_modified_log_4_*;
+
+remove_files_wildcard $MYSQLD_DATADIR ib_modified_log_4_*.xdb;
+
+--replace_regex /_[[:digit:]]+\.xdb$//
+list_files $MYSQLD_DATADIR ib_modified_log_4_*;
+
+--error ER_CANT_FIND_SYSTEM_REC
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES
+  WHERE START_LSN > 10000;
+
+DROP TABLE T1, ICP_COPY;

=== modified file 'Percona-Server/mysql-test/suite/innodb/t/percona_changed_pages_empty.test'
--- Percona-Server/mysql-test/suite/innodb/t/percona_changed_pages_empty.test	2012-09-17 13:08:32 +0000
+++ Percona-Server/mysql-test/suite/innodb/t/percona_changed_pages_empty.test	2013-05-29 15:11:30 +0000
@@ -1,8 +1,10 @@
 ###############################################################################
-# Test for empty I_S.INNODB_CHANGED_PAGES table. The table should be empty if#
-# innodb_track_changed_pages is false.                                        #
+# Test for empty I_S.INNODB_CHANGED_PAGES table. The table should be empty if #
+# no bitmap files exist                                                       #
 ###############################################################################
 
 --source include/have_innodb.inc
 
+RESET CHANGED_PAGE_BITMAPS;
+
 SELECT * FROM INFORMATION_SCHEMA.INNODB_CHANGED_PAGES; 

=== modified file 'Percona-Server/mysql-test/suite/sys_vars/r/all_vars.result'
--- Percona-Server/mysql-test/suite/sys_vars/r/all_vars.result	2013-01-29 15:14:23 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/r/all_vars.result	2013-05-29 15:11:30 +0000
@@ -14,7 +14,5 @@
 INNODB_FAKE_CHANGES
 INNODB_KILL_IDLE_TRANSACTION
 INNODB_KILL_IDLE_TRANSACTION
-INNODB_MAX_CHANGED_PAGES
-INNODB_MAX_CHANGED_PAGES
 drop table t1;
 drop table t2;

=== added file 'Percona-Server/mysql-test/suite/sys_vars/r/innodb_max_changed_pages_basic.result'
--- Percona-Server/mysql-test/suite/sys_vars/r/innodb_max_changed_pages_basic.result	1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/r/innodb_max_changed_pages_basic.result	2013-05-29 15:11:30 +0000
@@ -0,0 +1,78 @@
+SET @start_value = @@global.innodb_max_changed_pages;
+SELECT @start_value;
+@start_value
+1000000
+SET @@global.innodb_max_changed_pages = 5000;
+SET @@global.innodb_max_changed_pages = DEFAULT;
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+1000000
+SET @@global.innodb_max_changed_pages = 0;
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+0
+SET @@global.innodb_max_changed_pages = 1;
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+1
+SET @@global.innodb_max_changed_pages = 18446744073709551614;
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+18446744073709551614
+SET @@global.innodb_max_changed_pages = 18446744073709551615;
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+18446744073709551615
+SET @@global.innodb_max_changed_pages = 18446744073709551616;
+ERROR 42000: Incorrect argument type to variable 'innodb_max_changed_pages'
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+18446744073709551615
+SET @@global.innodb_max_changed_pages = 18446744073709551617;
+ERROR 42000: Incorrect argument type to variable 'innodb_max_changed_pages'
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+18446744073709551615
+SET @@global.innodb_max_changed_pages = 105.54;
+ERROR 42000: Incorrect argument type to variable 'innodb_max_changed_pages'
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+18446744073709551615
+SET @@global.innodb_max_changed_pages = -200;
+Warnings:
+Warning	1292	Truncated incorrect innodb_max_changed_pages value: '-200'
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+0
+SET @@global.innodb_max_changed_pages = ON;
+ERROR 42000: Incorrect argument type to variable 'innodb_max_changed_pages'
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+0
+SET @@global.innodb_max_changed_pages = 'foo';
+ERROR 42000: Incorrect argument type to variable 'innodb_max_changed_pages'
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+0
+SET @@session.innodb_max_changed_pages = 4096;
+ERROR HY000: Variable 'innodb_max_changed_pages' is a GLOBAL variable and should be set with SET GLOBAL
+SELECT @@session.innodb_max_changed_pages;
+ERROR HY000: Variable 'innodb_max_changed_pages' is a GLOBAL variable
+SELECT @@global.innodb_max_changed_pages = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_max_changed_pages';
+@@global.innodb_max_changed_pages = VARIABLE_VALUE
+1
+SELECT @@global.innodb_max_changed_pages = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='innodb_max_changed_pages';
+@@global.innodb_max_changed_pages = VARIABLE_VALUE
+1
+SET @@global.innodb_max_changed_pages=6789;
+SELECT @@global.innodb_max_changed_pages=@@innodb_max_changed_pages;
+@@global.innodb_max_changed_pages=@@innodb_max_changed_pages
+1
+SET @@global.innodb_max_changed_pages=@start_value;
+SELECT @@global.innodb_max_changed_pages;
+@@global.innodb_max_changed_pages
+1000000

=== added file 'Percona-Server/mysql-test/suite/sys_vars/t/innodb_max_changed_pages_basic.test'
--- Percona-Server/mysql-test/suite/sys_vars/t/innodb_max_changed_pages_basic.test	1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/t/innodb_max_changed_pages_basic.test	2013-05-29 15:11:30 +0000
@@ -0,0 +1,60 @@
+# Tests for innodb_max_changed_pages variable
+--source include/have_innodb.inc
+
+SET @start_value = @@global.innodb_max_changed_pages;
+SELECT @start_value;
+
+SET @@global.innodb_max_changed_pages = 5000;
+SET @@global.innodb_max_changed_pages = DEFAULT;
+SELECT @@global.innodb_max_changed_pages;
+
+# Valid boundary values
+SET @@global.innodb_max_changed_pages = 0;
+SELECT @@global.innodb_max_changed_pages;
+SET @@global.innodb_max_changed_pages = 1;
+SELECT @@global.innodb_max_changed_pages;
+SET @@global.innodb_max_changed_pages = 18446744073709551614;
+SELECT @@global.innodb_max_changed_pages;
+SET @@global.innodb_max_changed_pages = 18446744073709551615;
+SELECT @@global.innodb_max_changed_pages;
+
+# Invalid values
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@global.innodb_max_changed_pages = 18446744073709551616;
+SELECT @@global.innodb_max_changed_pages;
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@global.innodb_max_changed_pages = 18446744073709551617;
+SELECT @@global.innodb_max_changed_pages;
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@global.innodb_max_changed_pages = 105.54;
+SELECT @@global.innodb_max_changed_pages;
+SET @@global.innodb_max_changed_pages = -200;
+SELECT @@global.innodb_max_changed_pages;
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@global.innodb_max_changed_pages = ON;
+SELECT @@global.innodb_max_changed_pages;
+--error ER_WRONG_TYPE_FOR_VAR
+SET @@global.innodb_max_changed_pages = 'foo';
+SELECT @@global.innodb_max_changed_pages;
+
+# Accessing as session variable forbidden
+--error ER_GLOBAL_VARIABLE
+SET @@session.innodb_max_changed_pages = 4096;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.innodb_max_changed_pages;
+
+# Verify INFORMATION_SCHEMA access
+SELECT @@global.innodb_max_changed_pages = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_max_changed_pages';
+
+SELECT @@global.innodb_max_changed_pages = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='innodb_max_changed_pages';
+
+# Check default scope
+SET @@global.innodb_max_changed_pages=6789;
+SELECT @@global.innodb_max_changed_pages=@@innodb_max_changed_pages;
+
+SET @@global.innodb_max_changed_pages=@start_value;
+SELECT @@global.innodb_max_changed_pages;

=== modified file 'Percona-Server/storage/innobase/handler/i_s.cc'
--- Percona-Server/storage/innobase/handler/i_s.cc	2013-05-15 05:05:18 +0000
+++ Percona-Server/storage/innobase/handler/i_s.cc	2013-05-29 15:11:30 +0000
@@ -52,7 +52,7 @@
 #include "dict0mem.h"
 #include "dict0types.h"
 #include "ha_prototypes.h" /* for innobase_convert_name() */
-#include "srv0srv.h" /* for srv_track_changed_pages */
+#include "srv0srv.h" /* for srv_max_changed_pages */
 #include "srv0start.h" /* for srv_was_started */
 #include "trx0i_s.h"
 #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
@@ -7473,6 +7473,7 @@
 	ib_uint64_t		output_rows_num = 0UL;
 	ib_uint64_t		max_lsn = IB_ULONGLONG_MAX;
 	ib_uint64_t		min_lsn = 0ULL;
+	int			ret = 0;
 
 	DBUG_ENTER("i_s_innodb_changed_pages_fill");
 
@@ -7484,10 +7485,6 @@
 
 	RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
 
-	if (!srv_track_changed_pages) {
-		DBUG_RETURN(0);
-	}
-
 	if (cond) {
 		limit_lsn_range_from_condition(table, cond, &min_lsn,
 					       &max_lsn);
@@ -7563,8 +7560,13 @@
 		++output_rows_num;
 	}
 
+	if (i.failed) {
+		my_error(ER_CANT_FIND_SYSTEM_REC, MYF(0));
+		ret = 1;
+	}
+
 	log_online_bitmap_iterator_release(&i);
-	DBUG_RETURN(0);
+	DBUG_RETURN(ret);
 }
 
 static

=== modified file 'Percona-Server/storage/innobase/include/log0log.h'
--- Percona-Server/storage/innobase/include/log0log.h	2013-04-02 18:49:46 +0000
+++ Percona-Server/storage/innobase/include/log0log.h	2013-05-29 15:11:30 +0000
@@ -400,7 +400,9 @@
 	byte*		buf,		/*!< in: buffer where to read */
 	log_group_t*	group,		/*!< in: log group */
 	ib_uint64_t	start_lsn,	/*!< in: read area start */
-	ib_uint64_t	end_lsn);	/*!< in: read area end */
+	ib_uint64_t	end_lsn,	/*!< in: read area end */
+	ibool		release_mutex);	/*!< in: whether the log_sys->mutex
+				        should be released before the read */
 /******************************************************//**
 Writes a buffer to a log file group. */
 UNIV_INTERN

=== modified file 'Percona-Server/storage/innobase/include/log0online.h'
--- Percona-Server/storage/innobase/include/log0online.h	2013-01-30 13:42:52 +0000
+++ Percona-Server/storage/innobase/include/log0online.h	2013-05-29 15:11:30 +0000
@@ -159,6 +159,8 @@
 /** Struct for an iterator through all bits of changed pages bitmap blocks */
 struct log_bitmap_iterator_struct
 {
+	ibool				failed;		/*!< Has the iteration
+							stopped prematurely */
 	log_online_bitmap_file_range_t	in_files;	/*!< The bitmap files
 							for this iterator */
 	size_t				in_i;		/*!< Currently read

=== modified file 'Percona-Server/storage/innobase/include/os0file.h'
--- Percona-Server/storage/innobase/include/os0file.h	2013-02-06 09:26:12 +0000
+++ Percona-Server/storage/innobase/include/os0file.h	2013-05-29 15:11:30 +0000
@@ -76,15 +76,19 @@
 #endif
 
 #ifdef __WIN__
+#define SRV_PATH_SEPARATOR	'\\'
 /** File handle */
 # define os_file_t	HANDLE
+# define os_file_invalid	INVALID_HANDLE_VALUE
 /** Convert a C file descriptor to a native file handle
 @param fd	file descriptor
 @return		native file handle */
 # define OS_FILE_FROM_FD(fd) (HANDLE) _get_osfhandle(fd)
 #else
+#define SRV_PATH_SEPARATOR	'/'
 /** File handle */
 typedef int	os_file_t;
+# define os_file_invalid	(-1)
 /** Convert a C file descriptor to a native file handle
 @param fd	file descriptor
 @return		native file handle */
@@ -819,7 +823,6 @@
 	ulint		src_line);/*!< in: line where the func invoked */
 #endif	/* UNIV_PFS_IO */
 
-#ifdef UNIV_HOTBACKUP
 /***********************************************************************//**
 Closes a file handle.
 @return	TRUE if success */
@@ -828,7 +831,6 @@
 os_file_close_no_error_handling(
 /*============================*/
 	os_file_t	file);	/*!< in, own: handle to a file */
-#endif /* UNIV_HOTBACKUP */
 /***********************************************************************//**
 Gets a file size.
 @return	TRUE if success */

=== modified file 'Percona-Server/storage/innobase/log/log0log.c'
--- Percona-Server/storage/innobase/log/log0log.c	2013-04-03 06:56:50 +0000
+++ Percona-Server/storage/innobase/log/log0log.c	2013-05-29 15:11:30 +0000
@@ -2307,7 +2307,8 @@
 }
 
 /******************************************************//**
-Reads a specified log segment to a buffer. */
+Reads a specified log segment to a buffer.  Optionally releases the log mutex
+before the I/O.  */
 UNIV_INTERN
 void
 log_group_read_log_seg(
@@ -2316,7 +2317,9 @@
 	byte*		buf,		/*!< in: buffer where to read */
 	log_group_t*	group,		/*!< in: log group */
 	ib_uint64_t	start_lsn,	/*!< in: read area start */
-	ib_uint64_t	end_lsn)	/*!< in: read area end */
+	ib_uint64_t	end_lsn,	/*!< in: read area end */
+	ibool		release_mutex)	/*!< in: whether the log_sys->mutex
+					should be released before the read */
 {
 	ulint	len;
 	ulint	source_offset;
@@ -2346,6 +2349,10 @@
 
 	log_sys->n_log_ios++;
 
+	if (release_mutex) {
+		mutex_exit(&(log_sys->mutex));
+	}
+
 	fil_io(OS_FILE_READ | OS_FILE_LOG, sync, group->space_id, 0,
 	       source_offset / UNIV_PAGE_SIZE, source_offset % UNIV_PAGE_SIZE,
 	       len, buf, NULL);
@@ -2355,6 +2362,9 @@
 
 	if (start_lsn != end_lsn) {
 
+		if (release_mutex) {
+			mutex_enter(&(log_sys->mutex));
+		}
 		goto loop;
 	}
 }
@@ -2846,7 +2856,7 @@
 
 	log_group_read_log_seg(LOG_ARCHIVE, log_sys->archive_buf,
 			       UT_LIST_GET_FIRST(log_sys->log_groups),
-			       start_lsn, limit_lsn);
+			       start_lsn, limit_lsn, FALSE);
 
 	mutex_exit(&(log_sys->mutex));
 

=== modified file 'Percona-Server/storage/innobase/log/log0online.c'
--- Percona-Server/storage/innobase/log/log0online.c	2013-04-04 03:54:12 +0000
+++ Percona-Server/storage/innobase/log/log0online.c	2013-05-29 15:11:30 +0000
@@ -43,8 +43,8 @@
 
 /** Log parsing and bitmap output data structure */
 struct log_bitmap_struct {
-	byte		read_buf[FOLLOW_SCAN_SIZE];
-					/*!< log read buffer */
+	byte*		read_buf_ptr;	/*!< Unaligned log read buffer */
+	byte*		read_buf;	/*!< log read buffer */
 	byte		parse_buf[RECV_PARSING_BUF_SIZE];
 					/*!< log parse buffer */
 	byte*		parse_buf_end;  /*!< parse buffer position where the
@@ -53,6 +53,8 @@
 					parsed, it points to the start,
 					otherwise points immediatelly past the
 					end of the incomplete log record. */
+	char		bmp_file_home[FN_REFLEN];
+					/*!< directory for bitmap files */
 	log_online_bitmap_file_t out;	/*!< The current bitmap file */
 	ulint		out_seq_num;	/*!< the bitmap file sequence number */
 	ib_uint64_t	start_lsn;	/*!< the LSN of the next unparsed
@@ -490,9 +492,8 @@
 	ib_uint64_t	start_lsn)	/*!< in: the start LSN name part */
 {
 	ut_snprintf(log_bmp_sys->out.name, FN_REFLEN, bmp_file_name_template,
-		    srv_data_home, bmp_file_name_stem,
+		    log_bmp_sys->bmp_file_home, bmp_file_name_stem,
 		    log_bmp_sys->out_seq_num, start_lsn);
-
 }
 
 /*********************************************************************//**
@@ -509,7 +510,8 @@
 
 	/* Currently, it's OK to overwrite 0-sized files only */
 	success = os_file_get_status(path, &file_info);
-	return success && file_info.size == 0LL;
+	return success && file_info.type == OS_FILE_TYPE_FILE
+		&& file_info.size == 0LL;
 }
 
 /*********************************************************************//**
@@ -525,7 +527,7 @@
 
 	/* Check for an old file that should be deleted first */
 	if (log_online_should_overwrite(log_bmp_sys->out.name)) {
-		success = os_file_delete(log_bmp_sys->out.name);
+		success = os_file_delete_if_exists(log_bmp_sys->out.name);
 	}
 
 	if (UNIV_LIKELY(success)) {
@@ -544,7 +546,6 @@
 		fprintf(stderr,
 			"InnoDB: Error: Cannot create \'%s\'\n",
 			log_bmp_sys->out.name);
-		log_bmp_sys->out.file = -1;
 		return FALSE;
 	}
 
@@ -563,9 +564,9 @@
 	ib_uint64_t	next_file_start_lsn)	/*!<in: the start LSN name
 						part */
 {
-	if (log_bmp_sys->out.file != -1) {
+	if (log_bmp_sys->out.file != os_file_invalid) {
 		os_file_close(log_bmp_sys->out.file);
-		log_bmp_sys->out.file = -1;
+		log_bmp_sys->out.file = os_file_invalid;
 	}
 	log_bmp_sys->out_seq_num++;
 	log_online_make_bitmap_name(next_file_start_lsn);
@@ -613,6 +614,7 @@
 	os_file_dir_t	bitmap_dir;
 	os_file_stat_t	bitmap_dir_file_info;
 	ib_uint64_t	last_file_start_lsn	= MIN_TRACKED_LSN;
+	size_t		srv_data_home_len;
 
 	/* Bitmap data start and end in a bitmap block must be 8-byte
 	aligned. */
@@ -620,20 +622,39 @@
 	compile_time_assert(MODIFIED_PAGE_BLOCK_BITMAP_LEN % 8 == 0);
 
 	log_bmp_sys = ut_malloc(sizeof(*log_bmp_sys));
+	log_bmp_sys->read_buf_ptr = ut_malloc(FOLLOW_SCAN_SIZE
+					      + OS_FILE_LOG_BLOCK_SIZE);
+	log_bmp_sys->read_buf = ut_align(log_bmp_sys->read_buf_ptr,
+					 OS_FILE_LOG_BLOCK_SIZE);
 
 	mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys->mutex,
 		     SYNC_LOG_ONLINE);
 
+	/* Initialize bitmap file directory from srv_data_home and add a path
+	separator if needed.  */
+	srv_data_home_len = strlen(srv_data_home);
+	ut_a (srv_data_home_len < FN_REFLEN);
+	strcpy(log_bmp_sys->bmp_file_home, srv_data_home);
+	if (srv_data_home_len
+	    && log_bmp_sys->bmp_file_home[srv_data_home_len - 1]
+	    != SRV_PATH_SEPARATOR) {
+
+		ut_a (srv_data_home_len < FN_REFLEN - 1);
+		log_bmp_sys->bmp_file_home[srv_data_home_len]
+			= SRV_PATH_SEPARATOR;
+		log_bmp_sys->bmp_file_home[srv_data_home_len + 1] = '\0';
+	}
+
 	/* Enumerate existing bitmap files to either open the last one to get
 	the last tracked LSN either to find that there are none and start
 	tracking from scratch.  */
 	log_bmp_sys->out.name[0] = '\0';
 	log_bmp_sys->out_seq_num = 0;
 
-	bitmap_dir = os_file_opendir(srv_data_home, TRUE);
+	bitmap_dir = os_file_opendir(log_bmp_sys->bmp_file_home, TRUE);
 	ut_a(bitmap_dir);
-	while (!os_file_readdir_next_file(srv_data_home, bitmap_dir,
-					  &bitmap_dir_file_info)) {
+	while (!os_file_readdir_next_file(log_bmp_sys->bmp_file_home,
+					  bitmap_dir, &bitmap_dir_file_info)) {
 
 		ulong		file_seq_num;
 		ib_uint64_t	file_start_lsn;
@@ -648,8 +669,8 @@
 		    && bitmap_dir_file_info.size > 0) {
 			log_bmp_sys->out_seq_num = file_seq_num;
 			last_file_start_lsn = file_start_lsn;
-			/* No dir component (srv_data_home) here, because
-			that's the cwd */
+			/* No dir component (log_bmp_sys->bmp_file_home) here,
+			because	that's the cwd */
 			strncpy(log_bmp_sys->out.name,
 				bitmap_dir_file_info.name, FN_REFLEN - 1);
 			log_bmp_sys->out.name[FN_REFLEN - 1] = '\0';
@@ -659,7 +680,7 @@
 	if (os_file_closedir(bitmap_dir)) {
 		os_file_get_last_error(TRUE);
 		fprintf(stderr, "InnoDB: Error: cannot close \'%s\'\n",
-			srv_data_home);
+			log_bmp_sys->bmp_file_home);
 		exit(1);
 	}
 
@@ -762,9 +783,9 @@
 {
 	ib_rbt_node_t *free_list_node = log_bmp_sys->page_free_list;
 
-	if (log_bmp_sys->out.file != -1) {
+	if (log_bmp_sys->out.file != os_file_invalid) {
 		os_file_close(log_bmp_sys->out.file);
-		log_bmp_sys->out.file = -1;
+		log_bmp_sys->out.file = os_file_invalid;
 	}
 
 	rbt_free(log_bmp_sys->modified_pages);
@@ -777,6 +798,7 @@
 
 	mutex_free(&log_bmp_sys->mutex);
 
+	ut_free(log_bmp_sys->read_buf_ptr);
 	ut_free(log_bmp_sys);
 }
 
@@ -978,8 +1000,8 @@
 
 	mutex_enter(&log_sys->mutex);
 	log_group_read_log_seg(LOG_RECOVER, log_bmp_sys->read_buf,
-			       group, block_start_lsn, block_end_lsn);
-	mutex_exit(&log_sys->mutex);
+			       group, block_start_lsn, block_end_lsn, TRUE);
+	/* log_group_read_log_seg will release the log_sys->mutex for us */
 
 	while (log_block < log_block_end
 	       && log_bmp_sys->next_parse_lsn < log_bmp_sys->end_lsn) {
@@ -1256,15 +1278,18 @@
 	os_file_dir_t	bitmap_dir;
 	os_file_stat_t	bitmap_dir_file_info;
 	ulong		first_file_seq_num	= ULONG_MAX;
+	ulong		last_file_seq_num	= 0;
 	ib_uint64_t	first_file_start_lsn	= IB_ULONGLONG_MAX;
 
+	ut_ad(range_end >= range_start);
+
 	bitmap_files->count = 0;
 	bitmap_files->files = NULL;
 
 	/* 1st pass: size the info array */
 
 	bitmap_dir = os_file_opendir(srv_data_home, FALSE);
-	if (!bitmap_dir) {
+	if (UNIV_UNLIKELY(!bitmap_dir)) {
 		fprintf(stderr,
 			"InnoDB: Error: "
 			"failed to open bitmap directory \'%s\'\n",
@@ -1286,12 +1311,17 @@
 			continue;
 		}
 
+		if (file_seq_num > last_file_seq_num) {
+
+			last_file_seq_num = file_seq_num;
+		}
+
 		if (file_start_lsn >= range_start
 		    || file_start_lsn == first_file_start_lsn
 		    || first_file_start_lsn > range_start) {
 
 			/* A file that falls into the range */
-			bitmap_files->count++;
+
 			if (file_start_lsn < first_file_start_lsn) {
 
 				first_file_start_lsn = file_start_lsn;
@@ -1309,23 +1339,27 @@
 		}
 	}
 
-	ut_a(first_file_seq_num != ULONG_MAX || bitmap_files->count == 0);
+	if (UNIV_UNLIKELY(os_file_closedir(bitmap_dir))) {
 
-	if (os_file_closedir(bitmap_dir)) {
 		os_file_get_last_error(TRUE);
 		fprintf(stderr, "InnoDB: Error: cannot close \'%s\'\n",
 			srv_data_home);
 		return FALSE;
 	}
 
-	if (!bitmap_files->count) {
+	if (first_file_seq_num == ULONG_MAX && last_file_seq_num == 0) {
+
+		bitmap_files->count = 0;
 		return TRUE;
 	}
 
+	bitmap_files->count = last_file_seq_num - first_file_seq_num + 1;
+
 	/* 2nd pass: get the file names in the file_seq_num order */
 
 	bitmap_dir = os_file_opendir(srv_data_home, FALSE);
-	if (!bitmap_dir) {
+	if (UNIV_UNLIKELY(!bitmap_dir)) {
+
 		fprintf(stderr, "InnoDB: Error: "
 			"failed to open bitmap directory \'%s\'\n",
 			srv_data_home);
@@ -1349,11 +1383,25 @@
 					       &file_start_lsn)
 		    || file_start_lsn >= range_end
 		    || file_start_lsn < first_file_start_lsn) {
+
 			continue;
 		}
 
 		array_pos = file_seq_num - first_file_seq_num;
+		if (UNIV_UNLIKELY(array_pos >= bitmap_files->count)) {
+
+			fprintf(stderr,
+				"InnoDB: Error: inconsistent bitmap file "
+				"directory for a "
+				"INFORMATION_SCHEMA.INNODB_CHANGED_PAGES query"
+				"\n");
+			free(bitmap_files->files);
+			return FALSE;
+		}
+
+
 		if (file_seq_num > bitmap_files->files[array_pos].seq_num) {
+
 			bitmap_files->files[array_pos].seq_num = file_seq_num;
 			strncpy(bitmap_files->files[array_pos].name,
 				bitmap_dir_file_info.name, FN_REFLEN);
@@ -1364,7 +1412,8 @@
 		}
 	}
 
-	if (os_file_closedir(bitmap_dir)) {
+	if (UNIV_UNLIKELY(os_file_closedir(bitmap_dir))) {
+
 		os_file_get_last_error(TRUE);
 		fprintf(stderr, "InnoDB: Error: cannot close \'%s\'\n",
 			srv_data_home);
@@ -1411,6 +1460,8 @@
 	ulint	size_low;
 	ulint	size_high;
 
+	ut_ad(name[0] != '\0');
+
 	ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name);
 	bitmap_file->file
 		= os_file_create_simple_no_error_handling(innodb_file_bmp_key,
@@ -1418,7 +1469,8 @@
 							  OS_FILE_OPEN,
 							  OS_FILE_READ_ONLY,
 							  &success);
-	if (!success) {
+	if (UNIV_UNLIKELY(!success)) {
+
 		/* Here and below assume that bitmap file names do not
 		contain apostrophes, thus no need for ut_print_filename(). */
 		fprintf(stderr,
@@ -1461,7 +1513,8 @@
 	    || (bitmap_file->offset
 		> bitmap_file->size - MODIFIED_PAGE_BLOCK_SIZE)) {
 
-		if (bitmap_file->offset != bitmap_file->size) {
+		if (UNIV_UNLIKELY(bitmap_file->offset != bitmap_file->size)) {
+
 			/* If we are not at EOF and we have less than one page
 			to read, it's junk.  This error is not fatal in
 			itself. */
@@ -1472,7 +1525,8 @@
 				bitmap_file->name);
 		}
 
-		if (!last_page_in_run) {
+		if (UNIV_UNLIKELY(!last_page_in_run)) {
+
 			/* We are at EOF but the last read page did not finish
 			a run */
 			/* It's a "Warning" here because it's not a fatal error
@@ -1512,18 +1566,29 @@
 	if (!log_online_setup_bitmap_file_range(&i->in_files, min_lsn,
 		max_lsn)) {
 
+		i->failed = TRUE;
 		return FALSE;
 	}
 
-	ut_a(i->in_files.count > 0);
+	i->in_i = 0;
+
+	if (i->in_files.count == 0) {
+
+		/* Empty range */
+		i->in.file = os_file_invalid;
+		i->page = NULL;
+		i->failed = FALSE;
+		return TRUE;
+	}
 
 	/* Open the 1st bitmap file */
-	i->in_i = 0;
-	if (!log_online_open_bitmap_file_read_only(i->in_files.files[i->in_i].
-						   name,
-						   &i->in)) {
+	if (UNIV_UNLIKELY(!log_online_open_bitmap_file_read_only(
+				i->in_files.files[i->in_i].name,
+				&i->in))) {
+
 		i->in_i = i->in_files.count;
 		free(i->in_files.files);
+		i->failed = TRUE;
 		return FALSE;
 	}
 
@@ -1534,6 +1599,7 @@
 	i->first_page_id = 0;
 	i->last_page_in_run = TRUE;
 	i->changed = FALSE;
+	i->failed = FALSE;
 
 	return TRUE;
 }
@@ -1548,11 +1614,20 @@
 {
 	ut_a(i);
 
-	if (i->in_i < i->in_files.count) {
+	if (i->in.file != os_file_invalid) {
+
 		os_file_close(i->in.file);
-	}
-	ut_free(i->in_files.files);
-	ut_free(i->page);
+		i->in.file = os_file_invalid;
+	}
+	if (i->in_files.files) {
+
+		ut_free(i->in_files.files);
+	}
+	if (i->page) {
+
+		ut_free(i->page);
+	}
+	i->failed = TRUE;
 }
 
 /*********************************************************************//**
@@ -1567,10 +1642,16 @@
 	log_bitmap_iterator_t *i) /*!<in/out: iterator */
 {
 	ibool	checksum_ok = FALSE;
+	ibool	success;
 
 	ut_a(i);
 
-	if (i->bit_offset < MODIFIED_PAGE_BLOCK_BITMAP_LEN)
+	if (UNIV_UNLIKELY(i->in_files.count == 0)) {
+
+		return FALSE;
+	}
+
+	if (UNIV_LIKELY(i->bit_offset < MODIFIED_PAGE_BLOCK_BITMAP_LEN))
 	{
 		++i->bit_offset;
 		i->changed =
@@ -1587,29 +1668,56 @@
 
 			/* Advance file */
 			i->in_i++;
-			os_file_close(i->in.file);
-			log_online_diagnose_bitmap_eof(&i->in,
-						       i->last_page_in_run);
-			if (i->in_i == i->in_files.count
-			    || i->in_files.files[i->in_i].seq_num == 0) {
-
-				return FALSE;
-			}
-
-			if (!log_online_open_bitmap_file_read_only(
+			success = os_file_close_no_error_handling(i->in.file);
+			i->in.file = os_file_invalid;
+			if (UNIV_UNLIKELY(!success)) {
+
+				os_file_get_last_error(TRUE);
+				i->failed = TRUE;
+				return FALSE;
+			}
+
+			success = log_online_diagnose_bitmap_eof(
+					&i->in, i->last_page_in_run);
+			if (UNIV_UNLIKELY(!success)) {
+
+				i->failed = TRUE;
+				return FALSE;
+
+			}
+
+			if (i->in_i == i->in_files.count) {
+
+				return FALSE;
+			}
+
+			if (UNIV_UNLIKELY(i->in_files.files[i->in_i].seq_num
+					  == 0)) {
+
+				i->failed = TRUE;
+				return FALSE;
+			}
+
+			success = log_online_open_bitmap_file_read_only(
 					i->in_files.files[i->in_i].name,
-					&i->in)) {
+					&i->in);
+			if (UNIV_UNLIKELY(!success)) {
+
+				i->failed = TRUE;
 				return FALSE;
 			}
 		}
 
-		if (!log_online_read_bitmap_page(&i->in, i->page,
-						 &checksum_ok)) {
+		success = log_online_read_bitmap_page(&i->in, i->page,
+						      &checksum_ok);
+		if (UNIV_UNLIKELY(!success)) {
+
 			os_file_get_last_error(TRUE);
 			fprintf(stderr,
 				"InnoDB: Warning: failed reading "
 				"changed page bitmap file \'%s\'\n",
 				i->in_files.files[i->in_i].name);
+			i->failed = TRUE;
 			return FALSE;
 		}
 	}
@@ -1666,7 +1774,7 @@
 		/* If we have to delete the current output file, close it
 		first. */
 		os_file_close(log_bmp_sys->out.file);
-		log_bmp_sys->out.file = -1;
+		log_bmp_sys->out.file = os_file_invalid;
 	}
 
 	for (i = 0; i < bitmap_files.count; i++) {

=== modified file 'Percona-Server/storage/innobase/log/log0recv.c'
--- Percona-Server/storage/innobase/log/log0recv.c	2013-05-23 08:39:28 +0000
+++ Percona-Server/storage/innobase/log/log0recv.c	2013-05-29 15:11:30 +0000
@@ -546,7 +546,8 @@
 		}
 
 		log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
-				       up_to_date_group, start_lsn, end_lsn);
+				       up_to_date_group, start_lsn, end_lsn,
+				       FALSE);
 
 		len = (ulint) (end_lsn - start_lsn);
 
@@ -590,7 +591,7 @@
 	ut_a(start_lsn != end_lsn);
 
 	log_group_read_log_seg(LOG_RECOVER, recv_sys->last_block,
-			       up_to_date_group, start_lsn, end_lsn);
+			       up_to_date_group, start_lsn, end_lsn, FALSE);
 
 	group = UT_LIST_GET_FIRST(log_sys->log_groups);
 
@@ -2887,7 +2888,7 @@
 		end_lsn = start_lsn + RECV_SCAN_SIZE;
 
 		log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
-				       group, start_lsn, end_lsn);
+				       group, start_lsn, end_lsn, FALSE);
 
 		finished = recv_scan_log_recs(
 			(buf_pool_get_n_pages()

=== modified file 'Percona-Server/storage/innobase/os/os0file.c'
--- Percona-Server/storage/innobase/os/os0file.c	2013-05-23 08:39:28 +0000
+++ Percona-Server/storage/innobase/os/os0file.c	2013-05-29 15:11:30 +0000
@@ -1890,7 +1890,6 @@
 #endif
 }
 
-#ifdef UNIV_HOTBACKUP
 /***********************************************************************//**
 Closes a file handle.
 @return	TRUE if success */
@@ -1925,7 +1924,6 @@
 	return(TRUE);
 #endif
 }
-#endif /* UNIV_HOTBACKUP */
 
 /***********************************************************************//**
 Gets a file size.

=== modified file 'Percona-Server/storage/innobase/srv/srv0start.c'
--- Percona-Server/storage/innobase/srv/srv0start.c	2013-02-04 11:28:50 +0000
+++ Percona-Server/storage/innobase/srv/srv0start.c	2013-05-29 15:11:30 +0000
@@ -496,12 +496,6 @@
 }
 #endif /* !UNIV_HOTBACKUP */
 
-#ifdef __WIN__
-#define SRV_PATH_SEPARATOR	'\\'
-#else
-#define SRV_PATH_SEPARATOR	'/'
-#endif
-
 /*********************************************************************//**
 Normalizes a directory path for Windows: converts slashes to backslashes. */
 UNIV_INTERN

