Merge lp:~akopytov/percona-server/bug1125259 into lp:percona-server/5.5

Proposed by Alexey Kopytov
Status: Merged
Approved by: Stewart Smith
Approved revision: no longer in the source branch.
Merged at revision: 449
Proposed branch: lp:~akopytov/percona-server/bug1125259
Merge into: lp:percona-server/5.5
Diff against target: 158 lines (+72/-59)
1 file modified
Percona-Server/storage/innobase/srv/srv0srv.c (+72/-59)
To merge this branch: bzr merge lp:~akopytov/percona-server/bug1125259
Reviewer Review Type Date Requested Status
Stewart Smith (community) Approve
Registry Administrators Pending
Review via email: mp+148695@code.launchpad.net

Description of the change

Bug #1125259: srv_pass_corrupt_table can share the cache line with row
                  counters

    The place where srv_pass_corrupt_table (and a few other variables) was
    declared in srv0srv.c might become an infinite source of false sharing due
    to their proximity to row counters.

    Fixed by grouping and aligning all counters properly to ensure they are
    on separate cache lines and never share lines with other variables.

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :
Revision history for this message
Stewart Smith (stewart) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Percona-Server/storage/innobase/srv/srv0srv.c'
2--- Percona-Server/storage/innobase/srv/srv0srv.c 2013-02-13 20:31:43 +0000
3+++ Percona-Server/storage/innobase/srv/srv0srv.c 2013-02-17 09:43:26 +0000
4@@ -312,58 +312,11 @@
5 /* the number of rollback segments to use */
6 UNIV_INTERN ulong srv_rollback_segments = TRX_SYS_N_RSEGS;
7
8-/* variable counts amount of data read in total (in bytes) */
9-UNIV_INTERN ulint srv_data_read = 0;
10-
11 /* Internal setting for "innodb_stats_method". Decides how InnoDB treats
12 NULL value when collecting statistics. By default, it is set to
13 SRV_STATS_NULLS_EQUAL(0), ie. all NULL value are treated equal */
14 ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
15
16-/* here we count the amount of data written in total (in bytes) */
17-UNIV_INTERN ulint srv_data_written = 0;
18-
19-/* the number of the log write requests done */
20-UNIV_INTERN ulint srv_log_write_requests = 0;
21-
22-/* the number of physical writes to the log performed */
23-UNIV_INTERN ulint srv_log_writes = 0;
24-
25-/* amount of data written to the log files in bytes */
26-UNIV_INTERN ulint srv_os_log_written = 0;
27-
28-/* amount of writes being done to the log files */
29-UNIV_INTERN ulint srv_os_log_pending_writes = 0;
30-
31-/* we increase this counter, when there we don't have enough space in the
32-log buffer and have to flush it */
33-UNIV_INTERN ulint srv_log_waits = 0;
34-
35-/* this variable counts the amount of times, when the doublewrite buffer
36-was flushed */
37-UNIV_INTERN ulint srv_dblwr_writes = 0;
38-
39-/* here we store the number of pages that have been flushed to the
40-doublewrite buffer */
41-UNIV_INTERN ulint srv_dblwr_pages_written = 0;
42-
43-/* in this variable we store the number of write requests issued */
44-UNIV_INTERN ulint srv_buf_pool_write_requests = 0;
45-
46-/* here we store the number of times when we had to wait for a free page
47-in the buffer pool. It happens when the buffer pool is full and we need
48-to make a flush, in order to be able to read or create a page. */
49-UNIV_INTERN ulint srv_buf_pool_wait_free = 0;
50-
51-/* variable to count the number of pages that were written from buffer
52-pool to the disk */
53-UNIV_INTERN ulint srv_buf_pool_flushed = 0;
54-UNIV_INTERN ulint buf_lru_flush_page_count = 0;
55-
56-/** Number of buffer pool reads that led to the
57-reading of a disk page */
58-UNIV_INTERN ulint srv_buf_pool_reads = 0;
59-
60 /** Time in seconds between automatic buffer pool dumps */
61 UNIV_INTERN uint srv_auto_lru_dump = 0;
62
63@@ -489,23 +442,83 @@
64 UNIV_INTERN ibool srv_print_latch_waits = FALSE;
65 #endif /* UNIV_DEBUG */
66
67-UNIV_INTERN ulint srv_n_rows_inserted = 0;
68-UNIV_INTERN ulint srv_n_rows_updated = 0;
69-UNIV_INTERN ulint srv_n_rows_deleted = 0;
70-UNIV_INTERN ulint srv_n_rows_read = 0;
71-
72 static ulint srv_n_rows_inserted_old = 0;
73 static ulint srv_n_rows_updated_old = 0;
74 static ulint srv_n_rows_deleted_old = 0;
75 static ulint srv_n_rows_read_old = 0;
76
77-UNIV_INTERN ulint srv_n_lock_deadlock_count = 0;
78-UNIV_INTERN ulint srv_n_lock_wait_count = 0;
79-UNIV_INTERN ulint srv_n_lock_wait_current_count = 0;
80-UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0;
81-UNIV_INTERN ulint srv_n_lock_max_wait_time = 0;
82-
83-UNIV_INTERN ulint srv_truncated_status_writes = 0;
84+/* Ensure counters are on separate cache lines */
85+
86+#define CACHE_LINE_SIZE 64
87+#define CACHE_ALIGNED __attribute__ ((aligned (CACHE_LINE_SIZE)))
88+
89+UNIV_INTERN byte
90+counters_pad_start[CACHE_LINE_SIZE] __attribute__((unused)) = {0};
91+
92+UNIV_INTERN ulint srv_n_rows_inserted CACHE_ALIGNED = 0;
93+UNIV_INTERN ulint srv_n_rows_updated CACHE_ALIGNED = 0;
94+UNIV_INTERN ulint srv_n_rows_deleted CACHE_ALIGNED = 0;
95+UNIV_INTERN ulint srv_n_rows_read CACHE_ALIGNED = 0;
96+
97+UNIV_INTERN ulint srv_n_lock_deadlock_count CACHE_ALIGNED = 0;
98+UNIV_INTERN ulint srv_n_lock_wait_count CACHE_ALIGNED = 0;
99+UNIV_INTERN ulint srv_n_lock_wait_current_count CACHE_ALIGNED = 0;
100+UNIV_INTERN ib_int64_t srv_n_lock_wait_time CACHE_ALIGNED = 0;
101+UNIV_INTERN ulint srv_n_lock_max_wait_time CACHE_ALIGNED = 0;
102+
103+UNIV_INTERN ulint srv_truncated_status_writes CACHE_ALIGNED = 0;
104+
105+/* variable counts amount of data read in total (in bytes) */
106+UNIV_INTERN ulint srv_data_read CACHE_ALIGNED = 0;
107+
108+/* here we count the amount of data written in total (in bytes) */
109+UNIV_INTERN ulint srv_data_written CACHE_ALIGNED = 0;
110+
111+/* the number of the log write requests done */
112+UNIV_INTERN ulint srv_log_write_requests CACHE_ALIGNED = 0;
113+
114+/* the number of physical writes to the log performed */
115+UNIV_INTERN ulint srv_log_writes CACHE_ALIGNED = 0;
116+
117+/* amount of data written to the log files in bytes */
118+UNIV_INTERN ulint srv_os_log_written CACHE_ALIGNED = 0;
119+
120+/* amount of writes being done to the log files */
121+UNIV_INTERN ulint srv_os_log_pending_writes CACHE_ALIGNED = 0;
122+
123+/* we increase this counter, when there we don't have enough space in the
124+log buffer and have to flush it */
125+UNIV_INTERN ulint srv_log_waits CACHE_ALIGNED = 0;
126+
127+/* this variable counts the amount of times, when the doublewrite buffer
128+was flushed */
129+UNIV_INTERN ulint srv_dblwr_writes CACHE_ALIGNED = 0;
130+
131+/* here we store the number of pages that have been flushed to the
132+doublewrite buffer */
133+UNIV_INTERN ulint srv_dblwr_pages_written CACHE_ALIGNED = 0;
134+
135+/* in this variable we store the number of write requests issued */
136+UNIV_INTERN ulint srv_buf_pool_write_requests CACHE_ALIGNED = 0;
137+
138+/* here we store the number of times when we had to wait for a free page
139+in the buffer pool. It happens when the buffer pool is full and we need
140+to make a flush, in order to be able to read or create a page. */
141+UNIV_INTERN ulint srv_buf_pool_wait_free CACHE_ALIGNED = 0;
142+
143+/** Number of buffer pool reads that led to the
144+reading of a disk page */
145+UNIV_INTERN ulint srv_buf_pool_reads CACHE_ALIGNED = 0;
146+
147+/* variable to count the number of pages that were written from buffer
148+pool to the disk */
149+UNIV_INTERN ulint srv_buf_pool_flushed CACHE_ALIGNED = 0;
150+
151+/* variable to count the number of LRU flushed pages */
152+UNIV_INTERN ulint buf_lru_flush_page_count CACHE_ALIGNED = 0;
153+
154+UNIV_INTERN byte
155+counters_pad_end[CACHE_LINE_SIZE] __attribute__((unused)) = {0};
156
157 /*
158 Set the following to 0 if you want InnoDB to write messages on

Subscribers

People subscribed via source and target branches