~tsarev/percona-server/5.1-install_tests_fix-790199

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# name       : innodb_expand_undo_slots.patch
# introduced : 11 or before
# maintainer : Yasufumi
#
#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
--- a/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 16:06:22.000000000 +0900
+++ b/storage/innodb_plugin/handler/ha_innodb.cc	2010-04-29 16:06:59.000000000 +0900
@@ -165,6 +165,7 @@
 #endif /* UNIV_LOG_ARCHIVE */
 static my_bool	innobase_use_doublewrite		= TRUE;
 static my_bool	innobase_use_checksums			= TRUE;
+static my_bool	innobase_extra_undoslots		= FALSE;
 static my_bool	innobase_locks_unsafe_for_binlog	= FALSE;
 static my_bool	innobase_rollback_on_timeout		= FALSE;
 static my_bool	innobase_create_status_file		= FALSE;
@@ -2122,6 +2123,8 @@
 		goto error;
 	}
 
+	srv_extra_undoslots = (ibool) innobase_extra_undoslots;
+
 	/* -------------- Log files ---------------------------*/
 
 	/* The default dir for log files is the datadir of MySQL */
@@ -10785,6 +10788,13 @@
   "The common part for InnoDB table spaces.",
   NULL, NULL, NULL);
 
+static MYSQL_SYSVAR_BOOL(extra_undoslots, innobase_extra_undoslots,
+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+  "Enable to use about 4000 undo slots instead of default 1024. "
+  "#### Attention: Once you enable this parameter, "
+  "don't use the datafile for normal mysqld or ibbackup! ####",
+  NULL, NULL, FALSE);
+
 static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
   PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
   "Enable InnoDB doublewrite buffer (enabled by default). "
@@ -11177,6 +11187,7 @@
   MYSQL_SYSVAR(data_file_path),
   MYSQL_SYSVAR(data_home_dir),
   MYSQL_SYSVAR(doublewrite),
+  MYSQL_SYSVAR(extra_undoslots),
   MYSQL_SYSVAR(fast_shutdown),
   MYSQL_SYSVAR(file_io_threads),
   MYSQL_SYSVAR(read_io_threads),
diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
--- a/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-29 16:06:22.000000000 +0900
+++ b/storage/innodb_plugin/handler/innodb_patch_info.h	2010-04-29 16:06:59.000000000 +0900
@@ -28,5 +28,6 @@
 {"innodb_io","Improvements to InnoDB IO","","http://www.percona.com/docs/wiki/percona-xtradb"},
 {"innodb_opt_lru_count","Fix of buffer_pool mutex","Decreases contention on buffer_pool mutex on LRU operations","http://www.percona.com/docs/wiki/percona-xtradb"},
 {"innodb_buffer_pool_pages","Information of buffer pool content","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_expand_undo_slots","expandable maximum number of undo slots","from 1024 (default) to about 4000","http://www.percona.com/docs/wiki/percona-xtradb"},
 {NULL, NULL, NULL, NULL}
 };
diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
--- a/storage/innodb_plugin/include/srv0srv.h	2010-04-29 15:55:25.000000000 +0900
+++ b/storage/innodb_plugin/include/srv0srv.h	2010-04-29 16:06:59.000000000 +0900
@@ -112,6 +112,8 @@
 extern ulint*	srv_data_file_sizes;
 extern ulint*	srv_data_file_is_raw_partition;
 
+extern ibool	srv_extra_undoslots;
+
 extern ibool	srv_auto_extend_last_data_file;
 extern ulint	srv_last_file_size_max;
 extern char**	srv_log_group_home_dirs;
diff -ruN a/storage/innodb_plugin/include/trx0rseg.h b/storage/innodb_plugin/include/trx0rseg.h
--- a/storage/innodb_plugin/include/trx0rseg.h	2010-04-06 23:07:13.000000000 +0900
+++ b/storage/innodb_plugin/include/trx0rseg.h	2010-04-29 16:06:59.000000000 +0900
@@ -123,8 +123,11 @@
 	trx_rseg_t*	rseg);		/* in, own: instance to free */
 
 
+/* Real max value may be 4076 in usual. But reserve 4 slot for safety or etc... */
+#define TRX_RSEG_N_EXTRA_SLOTS	(((UNIV_PAGE_SIZE - (FIL_PAGE_DATA + FIL_PAGE_DATA_END + TRX_RSEG_UNDO_SLOTS)) / TRX_RSEG_SLOT_SIZE) - 4)
+
 /* Number of undo log slots in a rollback segment file copy */
-#define TRX_RSEG_N_SLOTS	(UNIV_PAGE_SIZE / 16)
+#define TRX_RSEG_N_SLOTS	(srv_extra_undoslots ? TRX_RSEG_N_EXTRA_SLOTS : (UNIV_PAGE_SIZE / 16))
 
 /* Maximum number of transactions supported by a single rollback segment */
 #define TRX_RSEG_MAX_N_TRXS	(TRX_RSEG_N_SLOTS / 2)
diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
--- a/storage/innodb_plugin/srv/srv0srv.c	2010-04-29 15:55:25.000000000 +0900
+++ b/storage/innodb_plugin/srv/srv0srv.c	2010-04-29 16:06:59.000000000 +0900
@@ -142,6 +142,8 @@
 /* size in database pages */
 UNIV_INTERN ulint*	srv_data_file_sizes = NULL;
 
+UNIV_INTERN ibool	srv_extra_undoslots = FALSE;
+
 /* if TRUE, then we auto-extend the last data file */
 UNIV_INTERN ibool	srv_auto_extend_last_data_file	= FALSE;
 /* if != 0, this tells the max size auto-extending may increase the
diff -ruN a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c
--- a/storage/innodb_plugin/trx/trx0undo.c	2010-04-06 23:07:14.000000000 +0900
+++ b/storage/innodb_plugin/trx/trx0undo.c	2010-04-29 16:06:59.000000000 +0900
@@ -1395,9 +1395,47 @@
 	rseg_header = trx_rsegf_get_new(rseg->space, rseg->zip_size,
 					rseg->page_no, &mtr);
 
+	if (!srv_extra_undoslots) {
+		/* uses direct call for avoid "Assertion failure" */
+		//page_no = trx_rsegf_get_nth_undo(rseg_header, TRX_RSEG_N_EXTRA_SLOTS - 1, &mtr);
+		page_no = mtr_read_ulint(rseg_header + TRX_RSEG_UNDO_SLOTS
+					 + (TRX_RSEG_N_EXTRA_SLOTS - 1) * TRX_RSEG_SLOT_SIZE,
+					 MLOG_4BYTES, &mtr);
+		if (page_no != 0) {
+			/* check extended slots are not used */
+			for (i = TRX_RSEG_N_SLOTS; i < TRX_RSEG_N_EXTRA_SLOTS; i++) {
+				/* uses direct call for avoid "Assertion failure" */
+				page_no = mtr_read_ulint(rseg_header + TRX_RSEG_UNDO_SLOTS
+							 + i * TRX_RSEG_SLOT_SIZE,
+							 MLOG_4BYTES, &mtr);
+				if (page_no != 0 && page_no != FIL_NULL) {
+					srv_extra_undoslots = TRUE;
+					fprintf(stderr,
+"InnoDB: Error: innodb_extra_undoslots option is disabled, but it was enabled before.\n"
+"InnoDB: The datafile is not normal for mysqld and disabled innodb_extra_undoslots.\n"
+"InnoDB: Enable innodb_extra_undoslots if it was enabled before, and\n"
+"InnoDB: ### don't use this datafile with other mysqld or ibbackup! ###\n"
+"InnoDB: Cannot continue operation for the safety. Calling exit(1).\n");
+					exit(1);
+				}
+			}
+			fprintf(stderr,
+"InnoDB: Warning: innodb_extra_undoslots option is disabled, but it was  enabled before.\n"
+"InnoDB: But extended undo slots seem not used, so continue operation.\n");
+		}
+	}
+
 	for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
 		page_no = trx_rsegf_get_nth_undo(rseg_header, i, &mtr);
 
+		/* If it was not initialized when the datafile created,
+		page_no will be 0 for the extended slots after that */
+
+		if (page_no == 0) {
+			page_no = FIL_NULL;
+			trx_rsegf_set_nth_undo(rseg_header, i, page_no, &mtr);
+		}
+
 		/* In forced recovery: try to avoid operations which look
 		at database pages; undo logs are rapidly changing data, and
 		the probability that they are in an inconsistent state is