Merge lp:~akopytov/percona-server/bug1131189-5.6 into lp:percona-server/5.6

Proposed by Alexey Kopytov
Status: Merged
Approved by: Laurynas Biveinis
Approved revision: no longer in the source branch.
Merged at revision: 356
Proposed branch: lp:~akopytov/percona-server/bug1131189-5.6
Merge into: lp:percona-server/5.6
Prerequisite: lp:~laurynas-biveinis/percona-server/ci-fixes-5.6.11
Diff against target: 1545 lines (+617/-233)
21 files modified
Percona-Server/sql/handler.cc (+7/-17)
Percona-Server/sql/sql_base.cc (+9/-3)
Percona-Server/sql/sql_class.cc (+1/-3)
Percona-Server/sql/sql_connect.cc (+9/-6)
Percona-Server/sql/sql_parse.cc (+6/-2)
Percona-Server/sql/sql_prepare.cc (+26/-10)
Percona-Server/storage/innobase/include/read0read.h (+7/-4)
Percona-Server/storage/innobase/include/read0read.ic (+11/-28)
Percona-Server/storage/innobase/include/trx0sys.h (+58/-10)
Percona-Server/storage/innobase/include/trx0sys.ic (+66/-13)
Percona-Server/storage/innobase/include/trx0trx.h (+24/-0)
Percona-Server/storage/innobase/lock/lock0lock.cc (+13/-3)
Percona-Server/storage/innobase/read/read0read.cc (+82/-114)
Percona-Server/storage/innobase/row/row0sel.cc (+2/-2)
Percona-Server/storage/innobase/row/row0vers.cc (+5/-8)
Percona-Server/storage/innobase/trx/trx0sys.cc (+10/-0)
Percona-Server/storage/innobase/trx/trx0trx.cc (+177/-10)
policy/apparmor/usr.sbin.mysqld (+61/-0)
policy/apparmor/usr.sbin.mysqld.local (+2/-0)
policy/selinux/percona-server.fc (+6/-0)
policy/selinux/percona-server.te (+35/-0)
To merge this branch: bzr merge lp:~akopytov/percona-server/bug1131189-5.6
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+165584@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

    - The patch would be OK, but I did find one issue which IMHO
      requires recommitting (although the test cycle could be
      skipped) or follow-up addressing (I don't have a strong opinion
      on recomitting vs follow-up): trx_rw_is_active_low is a
      bool-returning function that returns NULL in one of the code
      paths.

    - If we are recommitting, then in_trx_serial_list should be bool,
      not ibool as well, and true/false used instead of 0/1 for
      setting it, spurious newline at diff line 278. The row0sel.cc
      change is spurious as well?

    Random remark:

    - trx_descr_cmp() should be defined in trx0trx.ic, not .c? So
      then compiler can resolve the function pointer to inlining. It
      is also possible to use std::binary_search() in the brave new
      C++ world.

    Last and least absolutely random remarks:

    - I don't fully understand the header comment for
      trx_rw_get_active_trx_by_id() stating that the returned pointer
      must not be dereferenced unless lock_sys->mutex is held. But
      the function itself dereferences the pointer in
      trx_state_eq()? I see that all callers hold the
      lock_sys->mutex, thus it does not seem to be a real issue
      though.

    - Upstream started making heavy use of __attribute__ function
      annotations to cause extra warnings on misuse, especially
      nonnull, warn_unused_result. Maybe not bad idea for us well
      where it applies.

review: Needs Fixing
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Will merge as-is and handle the minor issues in a follow-up.

review: Approve
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Hi Laurynas,

On Fri, 24 May 2013 14:22:31 -0000, Laurynas Biveinis wrote:
> Review: Needs Fixing
>
> - The patch would be OK, but I did find one issue which IMHO
> requires recommitting (although the test cycle could be
> skipped) or follow-up addressing (I don't have a strong opinion
> on recomitting vs follow-up): trx_rw_is_active_low is a
> bool-returning function that returns NULL in one of the code
> paths.

Right, good catch! Thanks for fixing it as a followup.

>
> - If we are recommitting, then in_trx_serial_list should be bool,
> not ibool as well, and true/false used instead of 0/1 for
> setting it, spurious newline at diff line 278. The row0sel.cc
> change is spurious as well?
>

I deliberately made it ibool to be consistent with in_ro_trx_list /
in_rw_trx_list (which is also new 5.6 code BTW). But OK.

> Random remark:
>
> - trx_descr_cmp() should be defined in trx0trx.ic, not .c? So
> then compiler can resolve the function pointer to inlining. It
> is also possible to use std::binary_search() in the brave new
> C++ world.
>

bsearch() is a library function, so no inlining is possible. Is it
different with std::binary_search()?

> Last and least absolutely random remarks:
>
> - I don't fully understand the header comment for
> trx_rw_get_active_trx_by_id() stating that the returned pointer
> must not be dereferenced unless lock_sys->mutex is held. But
> the function itself dereferences the pointer in
> trx_state_eq()? I see that all callers hold the
> lock_sys->mutex, thus it does not seem to be a real issue
> though.
>

There's actually an upstream problem with that code, but it only applies
to debug builds. Will report it separately.

> - Upstream started making heavy use of __attribute__ function
> annotations to cause extra warnings on misuse, especially
> nonnull, warn_unused_result. Maybe not bad idea for us well
> where it applies.
>

Yes, that's good stuff.

/Alexey

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Ah, indeed trx_descr_cmp() is just a wrapper around bsearch(), thus removing the indirection would not help there.

std::binary_search() 3rd optional arg is a C++ callable object for performing element comparisons. If a function pointer is passed there, then it's the same as with bsearch(), but if a template function object is passed instead, then it's all inlineable.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Percona-Server/sql/handler.cc'
--- Percona-Server/sql/handler.cc 2013-05-12 06:24:46 +0000
+++ Percona-Server/sql/handler.cc 2013-05-24 12:02:59 +0000
@@ -2516,8 +2516,13 @@
2516 dup_ref=ref+ALIGN_SIZE(ref_length);2516 dup_ref=ref+ALIGN_SIZE(ref_length);
2517 cached_table_flags= table_flags();2517 cached_table_flags= table_flags();
2518 }2518 }
2519 rows_read= rows_changed= 0;2519
2520 memset(index_rows_read, 0, sizeof(index_rows_read));2520 if (unlikely(opt_userstat))
2521 {
2522 rows_read= rows_changed= 0;
2523 memset(index_rows_read, 0, sizeof(index_rows_read));
2524 }
2525
2521 DBUG_RETURN(error);2526 DBUG_RETURN(error);
2522}2527}
25232528
@@ -4667,12 +4672,6 @@
4667// Updates the global table stats with the TABLE this handler represents.4672// Updates the global table stats with the TABLE this handler represents.
4668void handler::update_global_table_stats()4673void handler::update_global_table_stats()
4669{4674{
4670 if (!opt_userstat)
4671 {
4672 rows_read= rows_changed= 0;
4673 return;
4674 }
4675
4676 if (!rows_read && !rows_changed)4675 if (!rows_read && !rows_changed)
4677 return; // Nothing to update.4676 return; // Nothing to update.
4678 // table_cache_key is db_name + '\0' + table_name + '\0'.4677 // table_cache_key is db_name + '\0' + table_name + '\0'.
@@ -4730,15 +4729,6 @@
4730 !table->s->table_name.str)4729 !table->s->table_name.str)
4731 return;4730 return;
47324731
4733 if (!opt_userstat)
4734 {
4735 for (uint x= 0; x < table->s->keys; ++x)
4736 {
4737 index_rows_read[x]= 0;
4738 }
4739 return;
4740 }
4741
4742 for (uint x = 0; x < table->s->keys; ++x)4732 for (uint x = 0; x < table->s->keys; ++x)
4743 {4733 {
4744 if (index_rows_read[x])4734 if (index_rows_read[x])
47454735
=== modified file 'Percona-Server/sql/sql_base.cc'
--- Percona-Server/sql/sql_base.cc 2013-05-13 04:25:56 +0000
+++ Percona-Server/sql/sql_base.cc 2013-05-24 12:02:59 +0000
@@ -1490,11 +1490,13 @@
1490 table->mdl_ticket= NULL;1490 table->mdl_ticket= NULL;
14911491
1492 mysql_mutex_lock(&thd->LOCK_thd_data);1492 mysql_mutex_lock(&thd->LOCK_thd_data);
1493 if(table->file)1493
1494 if(unlikely(opt_userstat && table->file))
1494 {1495 {
1495 table->file->update_global_table_stats();1496 table->file->update_global_table_stats();
1496 table->file->update_global_index_stats();1497 table->file->update_global_index_stats();
1497 }1498 }
1499
1498 *table_ptr=table->next;1500 *table_ptr=table->next;
1499 mysql_mutex_unlock(&thd->LOCK_thd_data);1501 mysql_mutex_unlock(&thd->LOCK_thd_data);
15001502
@@ -2152,8 +2154,12 @@
2152 DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",2154 DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
2153 table->s->db.str, table->s->table_name.str));2155 table->s->db.str, table->s->table_name.str));
21542156
2155 table->file->update_global_table_stats();2157 if (unlikely(opt_userstat))
2156 table->file->update_global_index_stats();2158 {
2159 table->file->update_global_table_stats();
2160 table->file->update_global_index_stats();
2161 }
2162
2157 free_io_cache(table);2163 free_io_cache(table);
2158 closefrm(table, 0);2164 closefrm(table, 0);
2159 if (delete_table)2165 if (delete_table)
21602166
=== modified file 'Percona-Server/sql/sql_class.cc'
--- Percona-Server/sql/sql_class.cc 2013-05-22 10:51:07 +0000
+++ Percona-Server/sql/sql_class.cc 2013-05-24 12:02:59 +0000
@@ -1520,8 +1520,6 @@
1520// Updates 'diff' stats of a THD.1520// Updates 'diff' stats of a THD.
1521void THD::update_stats(bool ran_command)1521void THD::update_stats(bool ran_command)
1522{1522{
1523 if (opt_userstat)
1524 {
1525 diff_total_busy_time+= busy_time;1523 diff_total_busy_time+= busy_time;
1526 diff_total_cpu_time+= cpu_time;1524 diff_total_cpu_time+= cpu_time;
1527 diff_total_bytes_received+= bytes_received;1525 diff_total_bytes_received+= bytes_received;
@@ -1566,7 +1564,7 @@
1566 /* reset counters to zero to avoid double-counting since values1564 /* reset counters to zero to avoid double-counting since values
1567 are already store in diff_total_*.1565 are already store in diff_total_*.
1568 */1566 */
1569 }1567
1570 busy_time= 0;1568 busy_time= 0;
1571 cpu_time= 0;1569 cpu_time= 0;
1572 bytes_received= 0;1570 bytes_received= 0;
15731571
=== modified file 'Percona-Server/sql/sql_connect.cc'
--- Percona-Server/sql/sql_connect.cc 2013-05-22 10:51:07 +0000
+++ Percona-Server/sql/sql_connect.cc 2013-05-24 12:02:59 +0000
@@ -566,9 +566,6 @@
566 const char* client_string= get_client_host(thd);566 const char* client_string= get_client_host(thd);
567 int return_value= 0;567 int return_value= 0;
568568
569 if (!opt_userstat)
570 return return_value;
571
572 if (acl_is_utility_user(thd->security_ctx->user, thd->security_ctx->host,569 if (acl_is_utility_user(thd->security_ctx->user, thd->security_ctx->host,
573 thd->security_ctx->ip))570 thd->security_ctx->ip))
574 return return_value;571 return return_value;
@@ -1383,8 +1380,9 @@
1383 my_net_set_write_timeout(net, thd->variables.net_write_timeout);1380 my_net_set_write_timeout(net, thd->variables.net_write_timeout);
13841381
1385 thd->reset_stats();1382 thd->reset_stats();
1383
1386 // Updates global user connection stats.1384 // Updates global user connection stats.
1387 if (increment_connection_count(thd, true))1385 if (opt_userstat && increment_connection_count(thd, true))
1388 DBUG_RETURN(1);1386 DBUG_RETURN(1);
13891387
1390 DBUG_RETURN(0);1388 DBUG_RETURN(0);
@@ -1621,8 +1619,13 @@
16211619
1622end_thread:1620end_thread:
1623 close_connection(thd);1621 close_connection(thd);
1624 thd->update_stats(false);1622
1625 update_global_user_stats(thd, create_user, time(NULL));1623 if (unlikely(opt_userstat))
1624 {
1625 thd->update_stats(false);
1626 update_global_user_stats(thd, create_user, time(NULL));
1627 }
1628
1626 if (MYSQL_CALLBACK_ELSE(thd->scheduler, end_thread, (thd, 1), 0))1629 if (MYSQL_CALLBACK_ELSE(thd->scheduler, end_thread, (thd, 1), 0))
1627 return; // Probably no-threads1630 return; // Probably no-threads
16281631
16291632
=== modified file 'Percona-Server/sql/sql_parse.cc'
--- Percona-Server/sql/sql_parse.cc 2013-05-22 10:51:07 +0000
+++ Percona-Server/sql/sql_parse.cc 2013-05-24 12:02:59 +0000
@@ -6545,11 +6545,15 @@
6545 else6545 else
6546 thd->cpu_time = 0;6546 thd->cpu_time = 0;
6547 }6547 }
6548
6548 // Updates THD stats and the global user stats.6549 // Updates THD stats and the global user stats.
6549 thd->update_stats(true);6550 if (unlikely(opt_userstat))
6551 {
6552 thd->update_stats(true);
6550#ifndef EMBEDDED_LIBRARY6553#ifndef EMBEDDED_LIBRARY
6551 update_global_user_stats(thd, true, time(NULL));6554 update_global_user_stats(thd, true, time(NULL));
6552#endif6555#endif
6556 }
65536557
6554 DBUG_VOID_RETURN;6558 DBUG_VOID_RETURN;
6555}6559}
65566560
=== modified file 'Percona-Server/sql/sql_prepare.cc'
--- Percona-Server/sql/sql_prepare.cc 2013-05-12 06:24:46 +0000
+++ Percona-Server/sql/sql_prepare.cc 2013-05-24 12:02:59 +0000
@@ -2267,7 +2267,7 @@
2267 double start_cpu_nsecs= 0;2267 double start_cpu_nsecs= 0;
2268 double end_cpu_nsecs= 0;2268 double end_cpu_nsecs= 0;
22692269
2270 if (opt_userstat)2270 if (unlikely(opt_userstat))
2271 {2271 {
2272#ifdef HAVE_CLOCK_GETTIME2272#ifdef HAVE_CLOCK_GETTIME
2273 /* get start cputime */2273 /* get start cputime */
@@ -2309,7 +2309,7 @@
23092309
2310 /* check_prepared_statemnt sends the metadata packet in case of success */2310 /* check_prepared_statemnt sends the metadata packet in case of success */
2311end:2311end:
2312 if (opt_userstat)2312 if (unlikely(opt_userstat))
2313 {2313 {
2314 // Gets the end time.2314 // Gets the end time.
2315 if (!(end_time_error= gettimeofday(&end_time, NULL)))2315 if (!(end_time_error= gettimeofday(&end_time, NULL)))
@@ -2351,11 +2351,15 @@
2351 else2351 else
2352 thd->cpu_time = 0;2352 thd->cpu_time = 0;
2353 }2353 }
2354
2354 // Updates THD stats and the global user stats.2355 // Updates THD stats and the global user stats.
2355 thd->update_stats(true);2356 if (unlikely(opt_userstat))
2357 {
2358 thd->update_stats(true);
2356#ifndef EMBEDDED_LIBRARY2359#ifndef EMBEDDED_LIBRARY
2357 update_global_user_stats(thd, true, time(NULL));2360 update_global_user_stats(thd, true, time(NULL));
2358#endif2361#endif
2362 }
23592363
2360 DBUG_VOID_RETURN;2364 DBUG_VOID_RETURN;
2361}2365}
@@ -2813,11 +2817,15 @@
2813 else2817 else
2814 thd->cpu_time = 0;2818 thd->cpu_time = 0;
2815 }2819 }
2820
2816 // Updates THD stats and the global user stats.2821 // Updates THD stats and the global user stats.
2817 thd->update_stats(true);2822 if (unlikely(opt_userstat))
2823 {
2824 thd->update_stats(true);
2818#ifndef EMBEDDED_LIBRARY2825#ifndef EMBEDDED_LIBRARY
2819 update_global_user_stats(thd, true, time(NULL));2826 update_global_user_stats(thd, true, time(NULL));
2820#endif2827#endif
2828 }
28212829
2822 DBUG_VOID_RETURN;2830 DBUG_VOID_RETURN;
2823}2831}
@@ -2990,11 +2998,15 @@
2990 } else2998 } else
2991 thd->cpu_time= 0;2999 thd->cpu_time= 0;
2992 }3000 }
3001
2993 // Updates THD stats and the global user stats.3002 // Updates THD stats and the global user stats.
2994 thd->update_stats(true);3003 if (unlikely(opt_userstat))
3004 {
3005 thd->update_stats(true);
2995#ifndef EMBEDDED_LIBRARY3006#ifndef EMBEDDED_LIBRARY
2996 update_global_user_stats(thd, true, time(NULL));3007 update_global_user_stats(thd, true, time(NULL));
2997#endif3008#endif
3009 }
29983010
2999 DBUG_VOID_RETURN;3011 DBUG_VOID_RETURN;
3000}3012}
@@ -3118,11 +3130,15 @@
3118 else3130 else
3119 thd->cpu_time= 0;3131 thd->cpu_time= 0;
3120 }3132 }
3133
3121 // Updates THD stats and the global user stats.3134 // Updates THD stats and the global user stats.
3122 thd->update_stats(true);3135 if (unlikely(opt_userstat))
3136 {
3137 thd->update_stats(true);
3123#ifndef EMBEDDED_LIBRARY3138#ifndef EMBEDDED_LIBRARY
3124 update_global_user_stats(thd, true, time(NULL));3139 update_global_user_stats(thd, true, time(NULL));
3125#endif3140#endif
3141 }
31263142
3127 DBUG_VOID_RETURN;3143 DBUG_VOID_RETURN;
3128}3144}
31293145
=== modified file 'Percona-Server/storage/innobase/include/read0read.h'
--- Percona-Server/storage/innobase/include/read0read.h 2013-05-23 06:51:50 +0000
+++ Percona-Server/storage/innobase/include/read0read.h 2013-05-24 12:02:59 +0000
@@ -32,6 +32,7 @@
32#include "ut0byte.h"32#include "ut0byte.h"
33#include "ut0lst.h"33#include "ut0lst.h"
34#include "trx0trx.h"34#include "trx0trx.h"
35#include "trx0sys.h"
35#include "read0types.h"36#include "read0types.h"
3637
37/*********************************************************************//**38/*********************************************************************//**
@@ -46,6 +47,7 @@
46 transaction, or 0 used in purge */47 transaction, or 0 used in purge */
47 read_view_t*& view); /*!< in,out: pre-allocated view array or48 read_view_t*& view); /*!< in,out: pre-allocated view array or
48 NULL if a new one needs to be created */49 NULL if a new one needs to be created */
50
49/*********************************************************************//**51/*********************************************************************//**
50Makes a copy of the oldest existing read view, or opens a new. The view52Makes a copy of the oldest existing read view, or opens a new. The view
51must be closed with ..._close.53must be closed with ..._close.
@@ -154,17 +156,18 @@
154 are strictly smaller (<) than this value.156 are strictly smaller (<) than this value.
155 In other words,157 In other words,
156 this is the "low water mark". */158 this is the "low water mark". */
157 ulint n_trx_ids;159 ulint n_descr;
158 /*!< Number of cells in the trx_ids array */160 /*!< Number of cells in the trx_ids array */
159 ulint max_trx_ids;161 ulint max_descr;
160 /*!< Maximum number of cells in the trx_ids162 /*!< Maximum number of cells in the trx_ids
161 array */163 array */
162 trx_id_t* trx_ids;/*!< Additional trx ids which the read should164 trx_id_t* descriptors;
165 /*!< Additional trx ids which the read should
163 not see: typically, these are the read-write166 not see: typically, these are the read-write
164 active transactions at the time when the read167 active transactions at the time when the read
165 is serialized, except the reading transaction168 is serialized, except the reading transaction
166 itself; the trx ids in this array are in a169 itself; the trx ids in this array are in a
167 descending order. These trx_ids should be170 ascending order. These trx_ids should be
168 between the "low" and "high" water marks,171 between the "low" and "high" water marks,
169 that is, up_limit_id and low_limit_id. */172 that is, up_limit_id and low_limit_id. */
170 trx_id_t creator_trx_id;173 trx_id_t creator_trx_id;
171174
=== modified file 'Percona-Server/storage/innobase/include/read0read.ic'
--- Percona-Server/storage/innobase/include/read0read.ic 2012-08-22 01:40:20 +0000
+++ Percona-Server/storage/innobase/include/read0read.ic 2013-05-24 12:02:59 +0000
@@ -35,11 +35,13 @@
35 const read_view_t* view) /*!< in: view to validate */35 const read_view_t* view) /*!< in: view to validate */
36{36{
37 ut_ad(mutex_own(&trx_sys->mutex));37 ut_ad(mutex_own(&trx_sys->mutex));
3838 ut_ad(view->max_descr >= view->n_descr);
39 /* Check that the view->trx_ids array is in descending order. */39 ut_ad(view->descriptors == NULL || view->max_descr > 0);
40 for (ulint i = 1; i < view->n_trx_ids; ++i) {40
4141 /* Check that the view->descriptors array is in ascending order. */
42 ut_a(view->trx_ids[i] < view->trx_ids[i - 1]);42 for (ulint i = 1; i < view->n_descr; ++i) {
43
44 ut_a(view->descriptors[i] > view->descriptors[i - 1]);
43 }45 }
4446
45 return(true);47 return(true);
@@ -92,31 +94,12 @@
92 } else if (trx_id >= view->low_limit_id) {94 } else if (trx_id >= view->low_limit_id) {
9395
94 return(false);96 return(false);
95 } else {
96 ulint lower = 0;
97 ulint upper = view->n_trx_ids - 1;
98
99 ut_a(view->n_trx_ids > 0);
100
101 do {
102 ulint mid = (lower + upper) >> 1;
103 trx_id_t mid_id = view->trx_ids[mid];
104
105 if (mid_id == trx_id) {
106 return(FALSE);
107 } else if (mid_id < trx_id) {
108 if (mid > 0) {
109 upper = mid - 1;
110 } else {
111 break;
112 }
113 } else {
114 lower = mid + 1;
115 }
116 } while (lower <= upper);
117 }97 }
11898
119 return(true);99 /* Do a binary search over this view's descriptors array */
100
101 return(trx_find_descriptor(view->descriptors, view->n_descr,
102 trx_id) == NULL);
120}103}
121104
122/*********************************************************************//**105/*********************************************************************//**
123106
=== modified file 'Percona-Server/storage/innobase/include/trx0sys.h'
--- Percona-Server/storage/innobase/include/trx0sys.h 2013-05-10 09:39:17 +0000
+++ Percona-Server/storage/innobase/include/trx0sys.h 2013-05-24 12:02:59 +0000
@@ -184,6 +184,17 @@
184trx_sys_get_max_trx_id(void);184trx_sys_get_max_trx_id(void);
185/*========================*/185/*========================*/
186186
187/*************************************************************//**
188Find a slot for a given trx ID in a descriptors array.
189@return: slot pointer */
190UNIV_INLINE
191trx_id_t*
192trx_find_descriptor(
193/*================*/
194 const trx_id_t* descriptors, /*!< in: descriptors array */
195 ulint n_descr, /*!< in: array size */
196 trx_id_t trx_id); /*!< in: trx pointer */
197
187#ifdef UNIV_DEBUG198#ifdef UNIV_DEBUG
188/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */199/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
189extern uint trx_rseg_n_slots_debug;200extern uint trx_rseg_n_slots_debug;
@@ -231,14 +242,26 @@
231trx_rw_min_trx_id(void);242trx_rw_min_trx_id(void);
232/*===================*/243/*===================*/
233/****************************************************************//**244/****************************************************************//**
245Returns pointer to a transaction instance if a rw transaction with the given id
246is active. Caller must hold trx_sys->mutex. If the caller is not holding
247lock_sys->mutex, the transaction may already have been committed.
248@return transaction instance if active, or NULL;
249the pointer must not be dereferenced unless lock_sys->mutex was
250acquired before calling this function and is still being held */
251UNIV_INLINE
252trx_t*
253trx_rw_get_active_trx_by_id(
254/*========================*/
255 trx_id_t trx_id, /*!< in: trx id of the transaction */
256 ibool* corrupt); /*!< in: NULL or pointer to a flag
257 that will be set if corrupt */
258/****************************************************************//**
234Checks if a rw transaction with the given id is active. Caller must hold259Checks if a rw transaction with the given id is active. Caller must hold
235trx_sys->mutex in shared mode. If the caller is not holding260trx_sys->mutex. If the caller is not holding lock_sys->mutex, the
236lock_sys->mutex, the transaction may already have been committed.261transaction may already have been committed.
237@return transaction instance if active, or NULL;262@return true if rw transaction it with a given id is active. */
238the pointer must not be dereferenced unless lock_sys->mutex was
239acquired before calling this function and is still being held */
240UNIV_INLINE263UNIV_INLINE
241trx_t*264bool
242trx_rw_is_active_low(265trx_rw_is_active_low(
243/*=================*/266/*=================*/
244 trx_id_t trx_id, /*!< in: trx id of the transaction */267 trx_id_t trx_id, /*!< in: trx id of the transaction */
@@ -248,11 +271,9 @@
248Checks if a rw transaction with the given id is active. If the caller is271Checks if a rw transaction with the given id is active. If the caller is
249not holding lock_sys->mutex, the transaction may already have been272not holding lock_sys->mutex, the transaction may already have been
250committed.273committed.
251@return transaction instance if active, or NULL;274@return true if rw transaction it with a given id is active. */
252the pointer must not be dereferenced unless lock_sys->mutex was
253acquired before calling this function and is still being held */
254UNIV_INLINE275UNIV_INLINE
255trx_t*276bool
256trx_rw_is_active(277trx_rw_is_active(
257/*=============*/278/*=============*/
258 trx_id_t trx_id, /*!< in: trx id of the transaction */279 trx_id_t trx_id, /*!< in: trx id of the transaction */
@@ -598,6 +619,8 @@
598 | TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)619 | TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)
599/* @} */620/* @} */
600621
622#define TRX_DESCR_ARRAY_INITIAL_SIZE 1000
623
601#ifndef UNIV_HOTBACKUP624#ifndef UNIV_HOTBACKUP
602/** The transaction system central memory data structure. */625/** The transaction system central memory data structure. */
603struct trx_sys_t{626struct trx_sys_t{
@@ -618,6 +641,18 @@
618 trx_id_t max_trx_id; /*!< The smallest number not yet641 trx_id_t max_trx_id; /*!< The smallest number not yet
619 assigned as a transaction id or642 assigned as a transaction id or
620 transaction number */643 transaction number */
644 char pad1[64]; /*!< Ensure max_trx_id does not share
645 cache line with other fields. */
646 trx_id_t* descriptors; /*!< Array of trx descriptors */
647 ulint descr_n_max; /*!< The current size of the descriptors
648 array. */
649 char pad2[64]; /*!< Ensure static descriptor fields
650 do not share cache lines with
651 descr_n_used */
652 ulint descr_n_used; /*!< Number of used elements in the
653 descriptors array. */
654 char pad3[64]; /*!< Ensure descriptors do not share
655 cache line with other fields */
621#ifdef UNIV_DEBUG656#ifdef UNIV_DEBUG
622 trx_id_t rw_max_trx_id; /*!< Max trx id of read-write transactions657 trx_id_t rw_max_trx_id; /*!< Max trx id of read-write transactions
623 which exist or existed */658 which exist or existed */
@@ -626,6 +661,8 @@
626 memory read-write transactions, sorted661 memory read-write transactions, sorted
627 on trx id, biggest first. Recovered662 on trx id, biggest first. Recovered
628 transactions are always on this list. */663 transactions are always on this list. */
664 char pad4[64]; /*!< Ensure list base nodes do not
665 share cache line with other fields */
629 trx_list_t ro_trx_list; /*!< List of active and committed in666 trx_list_t ro_trx_list; /*!< List of active and committed in
630 memory read-only transactions, sorted667 memory read-only transactions, sorted
631 on trx id, biggest first. NOTE:668 on trx id, biggest first. NOTE:
@@ -633,6 +670,8 @@
633 is not necessary. We should exploit670 is not necessary. We should exploit
634 this and increase concurrency during671 this and increase concurrency during
635 add/remove. */672 add/remove. */
673 char pad5[64]; /*!< Ensure list base nodes do not
674 share cache line with other fields */
636 trx_list_t mysql_trx_list; /*!< List of transactions created675 trx_list_t mysql_trx_list; /*!< List of transactions created
637 for MySQL. All transactions on676 for MySQL. All transactions on
638 ro_trx_list are on mysql_trx_list. The677 ro_trx_list are on mysql_trx_list. The
@@ -645,6 +684,15 @@
645 mysql_trx_list may additionally contain684 mysql_trx_list may additionally contain
646 transactions that have not yet been685 transactions that have not yet been
647 started in InnoDB. */686 started in InnoDB. */
687 char pad6[64]; /*!< Ensure list base nodes do not
688 share cache line with other fields */
689 trx_list_t trx_serial_list;
690 /*!< trx->no ordered List of
691 transactions in either TRX_PREPARED or
692 TRX_ACTIVE which have already been
693 assigned a serialization number */
694 char pad7[64]; /*!< Ensure list base nodes do not
695 share cache line with other fields */
648 trx_rseg_t* const rseg_array[TRX_SYS_N_RSEGS];696 trx_rseg_t* const rseg_array[TRX_SYS_N_RSEGS];
649 /*!< Pointer array to rollback697 /*!< Pointer array to rollback
650 segments; NULL if slot not in use;698 segments; NULL if slot not in use;
651699
=== modified file 'Percona-Server/storage/innobase/include/trx0sys.ic'
--- Percona-Server/storage/innobase/include/trx0sys.ic 2013-05-10 09:39:17 +0000
+++ Percona-Server/storage/innobase/include/trx0sys.ic 2013-05-24 12:02:59 +0000
@@ -368,16 +368,16 @@
368}368}
369369
370/****************************************************************//**370/****************************************************************//**
371Checks if a rw transaction with the given id is active. Caller must hold371Returns pointer to a transaction instance if a rw transaction with the given id
372trx_sys->mutex. If the caller is not holding lock_sys->mutex, the372is active. Caller must hold trx_sys->mutex. If the caller is not holding
373transaction may already have been committed.373lock_sys->mutex, the transaction may already have been committed.
374@return transaction instance if active, or NULL;374@return transaction instance if active, or NULL;
375the pointer must not be dereferenced unless lock_sys->mutex was375the pointer must not be dereferenced unless lock_sys->mutex was
376acquired before calling this function and is still being held */376acquired before calling this function and is still being held */
377UNIV_INLINE377UNIV_INLINE
378trx_t*378trx_t*
379trx_rw_is_active_low(379trx_rw_get_active_trx_by_id(
380/*=================*/380/*========================*/
381 trx_id_t trx_id, /*!< in: trx id of the transaction */381 trx_id_t trx_id, /*!< in: trx id of the transaction */
382 ibool* corrupt) /*!< in: NULL or pointer to a flag382 ibool* corrupt) /*!< in: NULL or pointer to a flag
383 that will be set if corrupt */383 that will be set if corrupt */
@@ -412,29 +412,58 @@
412}412}
413413
414/****************************************************************//**414/****************************************************************//**
415Checks if a rw transaction with the given id is active. Caller must hold
416trx_sys->mutex. If the caller is not holding lock_sys->mutex, the
417transaction may already have been committed.
418@return true if rw transaction it with a given id is active. */
419UNIV_INLINE
420bool
421trx_rw_is_active_low(
422/*=================*/
423 trx_id_t trx_id, /*!< in: trx id of the transaction */
424 ibool* corrupt) /*!< in: NULL or pointer to a flag
425 that will be set if corrupt */
426{
427 ut_ad(mutex_own(&trx_sys->mutex));
428
429 if (UNIV_UNLIKELY(trx_id >= trx_sys->max_trx_id)) {
430
431 /* There must be corruption: we let the caller handle the
432 diagnostic prints in this case. */
433
434 if (corrupt != NULL) {
435 *corrupt = TRUE;
436 }
437
438 return(NULL);
439 }
440
441 return(trx_find_descriptor(trx_sys->descriptors, trx_sys->descr_n_used,
442 trx_id) != NULL);
443}
444
445/****************************************************************//**
415Checks if a rw transaction with the given id is active. If the caller is446Checks if a rw transaction with the given id is active. If the caller is
416not holding lock_sys->mutex, the transaction may already have been447not holding lock_sys->mutex, the transaction may already have been
417committed.448committed.
418@return transaction instance if active, or NULL;449@return true if rw transaction it with a given id is active. */
419the pointer must not be dereferenced unless lock_sys->mutex was
420acquired before calling this function and is still being held */
421UNIV_INLINE450UNIV_INLINE
422trx_t*451bool
423trx_rw_is_active(452trx_rw_is_active(
424/*=============*/453/*=============*/
425 trx_id_t trx_id, /*!< in: trx id of the transaction */454 trx_id_t trx_id, /*!< in: trx id of the transaction */
426 ibool* corrupt) /*!< in: NULL or pointer to a flag455 ibool* corrupt) /*!< in: NULL or pointer to a flag
427 that will be set if corrupt */456 that will be set if corrupt */
428{457{
429 trx_t* trx;458 bool res;
430459
431 mutex_enter(&trx_sys->mutex);460 mutex_enter(&trx_sys->mutex);
432461
433 trx = trx_rw_is_active_low(trx_id, corrupt);462 res = trx_rw_is_active_low(trx_id, corrupt);
434463
435 mutex_exit(&trx_sys->mutex);464 mutex_exit(&trx_sys->mutex);
436465
437 return(trx);466 return(res);
438}467}
439468
440/*****************************************************************//**469/*****************************************************************//**
@@ -509,4 +538,28 @@
509538
510 return(n_trx);539 return(n_trx);
511}540}
541
542
543/*************************************************************//**
544Find a slot for a given trx ID in a descriptors array.
545@return: slot pointer */
546UNIV_INLINE
547trx_id_t*
548trx_find_descriptor(
549/*================*/
550 const trx_id_t* descriptors, /*!< in: descriptors array */
551 ulint n_descr, /*!< in: array size */
552 trx_id_t trx_id) /*!< in: trx id */
553{
554 ut_ad(descriptors != trx_sys->descriptors ||
555 mutex_own(&trx_sys->mutex));
556
557 if (UNIV_UNLIKELY(n_descr == 0)) {
558
559 return(NULL);
560 }
561
562 return((trx_id_t *) bsearch(&trx_id, descriptors, n_descr,
563 sizeof(trx_id_t), trx_descr_cmp));
564}
512#endif /* !UNIV_HOTBACKUP */565#endif /* !UNIV_HOTBACKUP */
513566
=== modified file 'Percona-Server/storage/innobase/include/trx0trx.h'
--- Percona-Server/storage/innobase/include/trx0trx.h 2013-05-23 06:51:50 +0000
+++ Percona-Server/storage/innobase/include/trx0trx.h 2013-05-24 12:02:59 +0000
@@ -459,6 +459,24 @@
459/*============*/459/*============*/
460 trx_t* trx); /*!< A read-only transaction that460 trx_t* trx); /*!< A read-only transaction that
461 needs to be assigned a RBS. */461 needs to be assigned a RBS. */
462
463/*************************************************************//**
464Callback function for trx_find_descriptor() to compare trx IDs. */
465UNIV_INTERN
466int
467trx_descr_cmp(
468/*==========*/
469 const void *a, /*!< in: pointer to first comparison argument */
470 const void *b); /*!< in: pointer to second comparison argument */
471
472/*************************************************************//**
473Release a slot for a given trx in the global descriptors array. */
474UNIV_INTERN
475void
476trx_release_descriptor(
477/*===================*/
478 trx_t* trx); /*!< in: trx pointer */
479
462/*******************************************************************//**480/*******************************************************************//**
463Transactions that aren't started by the MySQL server don't set481Transactions that aren't started by the MySQL server don't set
464the trx_t::mysql_thd field. For such transactions we set the lock482the trx_t::mysql_thd field. For such transactions we set the lock
@@ -892,6 +910,12 @@
892 /*!< TRUE if in910 /*!< TRUE if in
893 trx_sys->mysql_trx_list */911 trx_sys->mysql_trx_list */
894#endif /* UNIV_DEBUG */912#endif /* UNIV_DEBUG */
913 UT_LIST_NODE_T(trx_t)
914 trx_serial_list;/*!< list node for
915 trx_sys->trx_serial_list */
916 ibool in_trx_serial_list;
917 /* Set when transaction is in the
918 trx_serial_list */
895 /*------------------------------*/919 /*------------------------------*/
896 dberr_t error_state; /*!< 0 if no error, otherwise error920 dberr_t error_state; /*!< 0 if no error, otherwise error
897 number; NOTE That ONLY the thread921 number; NOTE That ONLY the thread
898922
=== modified file 'Percona-Server/storage/innobase/lock/lock0lock.cc'
--- Percona-Server/storage/innobase/lock/lock0lock.cc 2013-05-12 09:13:00 +0000
+++ Percona-Server/storage/innobase/lock/lock0lock.cc 2013-05-24 12:02:59 +0000
@@ -5556,7 +5556,7 @@
5556 if the check and assertion are covered by the lock mutex. */5556 if the check and assertion are covered by the lock mutex. */
55575557
5558 trx_id = lock_clust_rec_some_has_impl(rec, index, offsets);5558 trx_id = lock_clust_rec_some_has_impl(rec, index, offsets);
5559 impl_trx = trx_rw_is_active_low(trx_id, NULL);5559 impl_trx = trx_rw_get_active_trx_by_id(trx_id, NULL);
55605560
5561 ut_ad(lock_mutex_own());5561 ut_ad(lock_mutex_own());
5562 /* impl_trx cannot be committed until lock_mutex_exit()5562 /* impl_trx cannot be committed until lock_mutex_exit()
@@ -6055,7 +6055,9 @@
6055 /* If the transaction is still active and has no6055 /* If the transaction is still active and has no
6056 explicit x-lock set on the record, set one for it */6056 explicit x-lock set on the record, set one for it */
60576057
6058 impl_trx = trx_rw_is_active(trx_id, NULL);6058 mutex_enter(&trx_sys->mutex);
6059 impl_trx = trx_rw_get_active_trx_by_id(trx_id, NULL);
6060 mutex_exit(&trx_sys->mutex);
60596061
6060 /* impl_trx cannot be committed until lock_mutex_exit()6062 /* impl_trx cannot be committed until lock_mutex_exit()
6061 because lock_trx_release_locks() acquires lock_sys->mutex */6063 because lock_trx_release_locks() acquires lock_sys->mutex */
@@ -6843,8 +6845,12 @@
6843 }6845 }
68446846
6845 /* The transition of trx->state to TRX_STATE_COMMITTED_IN_MEMORY6847 /* The transition of trx->state to TRX_STATE_COMMITTED_IN_MEMORY
6846 is protected by both the lock_sys->mutex and the trx->mutex. */6848 is protected by both the lock_sys->mutex and the trx->mutex.
6849 We also lock trx_sys->mutex, because state transition to
6850 TRX_STATE_COMMITTED_IN_MEMORY must be atomic with removing trx
6851 from the descriptors array. */
6847 lock_mutex_enter();6852 lock_mutex_enter();
6853 mutex_enter(&trx_sys->mutex);
6848 trx_mutex_enter(trx);6854 trx_mutex_enter(trx);
68496855
6850 /* The following assignment makes the transaction committed in memory6856 /* The following assignment makes the transaction committed in memory
@@ -6863,6 +6869,8 @@
68636869
6864 /*--------------------------------------*/6870 /*--------------------------------------*/
6865 trx->state = TRX_STATE_COMMITTED_IN_MEMORY;6871 trx->state = TRX_STATE_COMMITTED_IN_MEMORY;
6872 /* The following also removes trx from trx_serial_list */
6873 trx_release_descriptor(trx);
6866 /*--------------------------------------*/6874 /*--------------------------------------*/
68676875
6868 /* If the background thread trx_rollback_or_clean_recovered()6876 /* If the background thread trx_rollback_or_clean_recovered()
@@ -6880,6 +6888,8 @@
68806888
6881 trx_mutex_exit(trx);6889 trx_mutex_exit(trx);
68826890
6891 mutex_exit(&trx_sys->mutex);
6892
6883 lock_release(trx);6893 lock_release(trx);
68846894
6885 lock_mutex_exit();6895 lock_mutex_exit();
68866896
=== modified file 'Percona-Server/storage/innobase/read/read0read.cc'
--- Percona-Server/storage/innobase/read/read0read.cc 2013-05-23 06:51:50 +0000
+++ Percona-Server/storage/innobase/read/read0read.cc 2013-05-24 12:02:59 +0000
@@ -189,23 +189,23 @@
189 if (view == NULL) {189 if (view == NULL) {
190 view = static_cast<read_view_t*>(190 view = static_cast<read_view_t*>(
191 ut_malloc(sizeof(read_view_t)));191 ut_malloc(sizeof(read_view_t)));
192 view->max_trx_ids = 0;192 view->max_descr = 0;
193 view->trx_ids = NULL;193 view->descriptors = NULL;
194 }194 }
195195
196 if (UNIV_UNLIKELY(view->max_trx_ids < n)) {196 if (UNIV_UNLIKELY(view->max_descr < n)) {
197197
198 /* avoid frequent reallocations by extending the array to the198 /* avoid frequent re-allocations by extending the array to the
199 desired size + 10% */199 desired size + 10% */
200200
201 view->max_trx_ids = n + n / 10;201 view->max_descr = n + n / 10;
202 view->trx_ids = static_cast<trx_id_t*>(202 view->descriptors = static_cast<trx_id_t*>(
203 ut_realloc(view->trx_ids,203 ut_realloc(view->descriptors,
204 view->max_trx_ids *204 view->max_descr *
205 sizeof *view->trx_ids));205 sizeof *view->descriptors));
206 }206 }
207207
208 view->n_trx_ids = n;208 view->n_descr = n;
209209
210 return(view);210 return(view);
211}211}
@@ -225,24 +225,24 @@
225 NULL */225 NULL */
226{226{
227 read_view_t* clone;227 read_view_t* clone;
228 trx_id_t* old_trx_ids;228 trx_id_t* old_descriptors;
229 ulint old_max_trx_ids;229 ulint old_max_descr;
230230
231 ut_ad(mutex_own(&trx_sys->mutex));231 ut_ad(mutex_own(&trx_sys->mutex));
232232
233 clone = read_view_create_low(view->n_trx_ids, prebuilt_clone);233 clone = read_view_create_low(view->n_descr, prebuilt_clone);
234234
235 old_trx_ids = clone->trx_ids;235 old_descriptors = clone->descriptors;
236 old_max_trx_ids = clone->max_trx_ids;236 old_max_descr = clone->max_descr;
237237
238 memcpy(clone, view, sizeof(*view));238 memcpy(clone, view, sizeof(*view));
239239
240 clone->trx_ids = old_trx_ids;240 clone->descriptors = old_descriptors;
241 clone->max_trx_ids = old_max_trx_ids;241 clone->max_descr = old_max_descr;
242242
243 if (view->n_trx_ids) {243 if (view->n_descr) {
244 memcpy(clone->trx_ids, view->trx_ids,244 memcpy(clone->descriptors, view->descriptors,
245 view->n_trx_ids * sizeof(trx_id_t));245 view->n_descr * sizeof(trx_id_t));
246 }246 }
247247
248 return(clone);248 return(clone);
@@ -280,53 +280,6 @@
280 ut_ad(read_view_list_validate());280 ut_ad(read_view_list_validate());
281}281}
282282
283/** Functor to create thew view trx_ids array. */
284struct CreateView {
285
286 CreateView(read_view_t* view)
287 : m_view(view)
288 {
289 m_n_trx = m_view->n_trx_ids;
290 m_view->n_trx_ids = 0;
291 }
292
293 void operator()(const trx_t* trx)
294 {
295 ut_ad(mutex_own(&trx_sys->mutex));
296 ut_ad(trx->in_rw_trx_list);
297
298 /* trx->state cannot change from or to NOT_STARTED
299 while we are holding the trx_sys->mutex. It may change
300 from ACTIVE to PREPARED or COMMITTED. */
301
302 if (trx->id != m_view->creator_trx_id
303 && !trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) {
304
305 ut_ad(m_n_trx > m_view->n_trx_ids);
306
307 m_view->trx_ids[m_view->n_trx_ids++] = trx->id;
308
309 /* NOTE that a transaction whose trx number is <
310 trx_sys->max_trx_id can still be active, if it is
311 in the middle of its commit! Note that when a
312 transaction starts, we initialize trx->no to
313 IB_ULONGLONG_MAX. */
314
315 /* trx->no is protected by trx_sys->mutex, which
316 we are holding. It is assigned by trx_commit()
317 before lock_trx_release_locks() assigns
318 trx->state = TRX_STATE_COMMITTED_IN_MEMORY. */
319
320 if (m_view->low_limit_no > trx->no) {
321 m_view->low_limit_no = trx->no;
322 }
323 }
324 }
325
326 read_view_t* m_view;
327 ulint m_n_trx;
328};
329
330/*********************************************************************//**283/*********************************************************************//**
331Opens a read view where exactly the transactions serialized before this284Opens a read view where exactly the transactions serialized before this
332point in time are seen in the view.285point in time are seen in the view.
@@ -340,11 +293,12 @@
340 read_view_t*& view) /*!< in,out: pre-allocated view array or293 read_view_t*& view) /*!< in,out: pre-allocated view array or
341 NULL if a new one needs to be created */294 NULL if a new one needs to be created */
342{295{
343 ulint n_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);296 trx_id_t* descr;
297 ulint i;
344298
345 ut_ad(mutex_own(&trx_sys->mutex));299 ut_ad(mutex_own(&trx_sys->mutex));
346300
347 view = read_view_create_low(n_trx, view);301 view = read_view_create_low(trx_sys->descr_n_used, view);
348302
349 view->undo_no = 0;303 view->undo_no = 0;
350 view->type = VIEW_NORMAL;304 view->type = VIEW_NORMAL;
@@ -355,13 +309,52 @@
355 view->low_limit_no = trx_sys->max_trx_id;309 view->low_limit_no = trx_sys->max_trx_id;
356 view->low_limit_id = view->low_limit_no;310 view->low_limit_id = view->low_limit_no;
357311
358 /* No active transaction should be visible, except cr_trx */312 descr = trx_find_descriptor(trx_sys->descriptors,
359313 trx_sys->descr_n_used,
360 ut_list_map(trx_sys->rw_trx_list, &trx_t::trx_list, CreateView(view));314 cr_trx_id);
361315 if (UNIV_LIKELY(descr != NULL)) {
362 if (view->n_trx_ids > 0) {316 ut_ad(trx_sys->descr_n_used > 0);
317 ut_ad(view->n_descr > 0);
318
319 view->n_descr--;
320
321 i = descr - trx_sys->descriptors;
322 } else {
323 i = trx_sys->descr_n_used;
324 }
325
326 if (UNIV_LIKELY(i > 0)) {
327 /* Copy the [0; i-1] range */
328 memcpy(view->descriptors, trx_sys->descriptors,
329 i * sizeof(trx_id_t));
330 }
331
332 if (UNIV_UNLIKELY(i + 1 < trx_sys->descr_n_used)) {
333 /* Copy the [i+1; descr_n_used-1] range */
334 memcpy(view->descriptors + i,
335 trx_sys->descriptors + i + 1,
336 (trx_sys->descr_n_used - i - 1) *
337 sizeof(trx_id_t));
338 }
339
340 /* NOTE that a transaction whose trx number is < trx_sys->max_trx_id can
341 still be active, if it is in the middle of its commit! Note that when a
342 transaction starts, we initialize trx->no to IB_ULONGLONG_MAX. */
343
344 if (UT_LIST_GET_LEN(trx_sys->trx_serial_list) > 0) {
345
346 trx_id_t trx_no;
347
348 trx_no = UT_LIST_GET_FIRST(trx_sys->trx_serial_list)->no;
349
350 if (trx_no < view->low_limit_no) {
351 view->low_limit_no = trx_no;
352 }
353 }
354
355 if (UNIV_LIKELY(view->n_descr > 0)) {
363 /* The last active transaction has the smallest id: */356 /* The last active transaction has the smallest id: */
364 view->up_limit_id = view->trx_ids[view->n_trx_ids - 1];357 view->up_limit_id = view->descriptors[0];
365 } else {358 } else {
366 view->up_limit_id = view->low_limit_id;359 view->up_limit_id = view->low_limit_id;
367 }360 }
@@ -442,29 +435,29 @@
442 ut_a(oldest_view->creator_trx_id > 0);435 ut_a(oldest_view->creator_trx_id > 0);
443 creator_trx_id = oldest_view->creator_trx_id;436 creator_trx_id = oldest_view->creator_trx_id;
444437
445 view = read_view_create_low(oldest_view->n_trx_ids + 1, prebuilt_view);438 view = read_view_create_low(oldest_view->n_descr + 1, prebuilt_view);
446439
447 /* Add the creator transaction id in the trx_ids array in the440 /* Add the creator transaction id in the trx_ids array in the
448 correct slot. */441 correct slot. */
449442
450 for (i = 0; i < oldest_view->n_trx_ids; ++i) {443 for (i = 0; i < oldest_view->n_descr; ++i) {
451 trx_id_t id;444 trx_id_t id;
452445
453 id = oldest_view->trx_ids[i - insert_done];446 id = oldest_view->descriptors[i - insert_done];
454447
455 if (insert_done == 0 && creator_trx_id > id) {448 if (insert_done == 0 && creator_trx_id < id) {
456 id = creator_trx_id;449 id = creator_trx_id;
457 insert_done = 1;450 insert_done = 1;
458 }451 }
459452
460 view->trx_ids[i] = id;453 view->descriptors[i] = id;
461 }454 }
462455
463 if (insert_done == 0) {456 if (insert_done == 0) {
464 view->trx_ids[i] = creator_trx_id;457 view->descriptors[i] = creator_trx_id;
465 } else {458 } else {
466 ut_a(i > 0);459 ut_a(i > 0);
467 view->trx_ids[i] = oldest_view->trx_ids[i - 1];460 view->descriptors[i] = oldest_view->descriptors[i - 1];
468 }461 }
469462
470 view->creator_trx_id = 0;463 view->creator_trx_id = 0;
@@ -472,10 +465,10 @@
472 view->low_limit_no = oldest_view->low_limit_no;465 view->low_limit_no = oldest_view->low_limit_no;
473 view->low_limit_id = oldest_view->low_limit_id;466 view->low_limit_id = oldest_view->low_limit_id;
474467
475 if (view->n_trx_ids > 0) {468 if (view->n_descr > 0) {
476 /* The last active transaction has the smallest id: */469 /* The last active transaction has the smallest id: */
477470
478 view->up_limit_id = view->trx_ids[view->n_trx_ids - 1];471 view->up_limit_id = view->descriptors[0];
479 } else {472 } else {
480 view->up_limit_id = oldest_view->up_limit_id;473 view->up_limit_id = oldest_view->up_limit_id;
481 }474 }
@@ -531,11 +524,11 @@
531524
532 fprintf(file, "Read view individually stored trx ids:\n");525 fprintf(file, "Read view individually stored trx ids:\n");
533526
534 n_ids = view->n_trx_ids;527 n_ids = view->n_descr;
535528
536 for (i = 0; i < n_ids; i++) {529 for (i = 0; i < n_ids; i++) {
537 fprintf(file, "Read view trx id " TRX_ID_FMT "\n",530 fprintf(file, "Read view trx id " TRX_ID_FMT "\n",
538 view->trx_ids[i]);531 view->descriptors[i]);
539 }532 }
540}533}
541534
@@ -582,8 +575,8 @@
582 return;575 return;
583 }576 }
584577
585 if (view->trx_ids != NULL) {578 if (view->descriptors != NULL) {
586 ut_free(view->trx_ids);579 ut_free(view->descriptors);
587 }580 }
588581
589 ut_free(view);582 ut_free(view);
@@ -604,7 +597,6 @@
604{597{
605 read_view_t* view;598 read_view_t* view;
606 mem_heap_t* heap;599 mem_heap_t* heap;
607 ulint n_trx;
608 cursor_view_t* curview;600 cursor_view_t* curview;
609601
610 /* Use larger heap than in trx_create when creating a read_view602 /* Use larger heap than in trx_create when creating a read_view
@@ -625,36 +617,12 @@
625617
626 mutex_enter(&trx_sys->mutex);618 mutex_enter(&trx_sys->mutex);
627619
628 n_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list);
629
630 curview->read_view = NULL;620 curview->read_view = NULL;
631 read_view_create_low(n_trx, curview->read_view);621 read_view_open_now_low(UINT64_UNDEFINED, curview->read_view);
632622
633 view = curview->read_view;623 view = curview->read_view;
634 view->undo_no = cr_trx->undo_no;624 view->undo_no = cr_trx->undo_no;
635 view->type = VIEW_HIGH_GRANULARITY;625 view->type = VIEW_HIGH_GRANULARITY;
636 view->creator_trx_id = UINT64_UNDEFINED;
637
638 /* No future transactions should be visible in the view */
639
640 view->low_limit_no = trx_sys->max_trx_id;
641 view->low_limit_id = view->low_limit_no;
642
643 /* No active transaction should be visible */
644
645 ut_list_map(trx_sys->rw_trx_list, &trx_t::trx_list, CreateView(view));
646
647 view->creator_trx_id = cr_trx->id;
648
649 if (view->n_trx_ids > 0) {
650 /* The last active transaction has the smallest id: */
651
652 view->up_limit_id = view->trx_ids[view->n_trx_ids - 1];
653 } else {
654 view->up_limit_id = view->low_limit_id;
655 }
656
657 read_view_add(view);
658626
659 mutex_exit(&trx_sys->mutex);627 mutex_exit(&trx_sys->mutex);
660628
661629
=== modified file 'Percona-Server/storage/innobase/row/row0sel.cc'
--- Percona-Server/storage/innobase/row/row0sel.cc 2013-05-23 06:51:50 +0000
+++ Percona-Server/storage/innobase/row/row0sel.cc 2013-05-24 12:02:59 +0000
@@ -5205,8 +5205,8 @@
5205 if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ5205 if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ
5206 && !trx->read_view) {5206 && !trx->read_view) {
52075207
5208 trx->read_view = read_view_open_now(5208 trx->read_view = read_view_open_now(trx->id,
5209 trx->id, trx->prebuilt_view);5209 trx->prebuilt_view);
52105210
5211 trx->global_read_view = trx->read_view;5211 trx->global_read_view = trx->read_view;
5212 }5212 }
52135213
=== modified file 'Percona-Server/storage/innobase/row/row0vers.cc'
--- Percona-Server/storage/innobase/row/row0vers.cc 2013-05-10 09:39:17 +0000
+++ Percona-Server/storage/innobase/row/row0vers.cc 2013-05-24 12:02:59 +0000
@@ -646,7 +646,7 @@
646 version = rec;646 version = rec;
647647
648 for (;;) {648 for (;;) {
649 const trx_t* version_trx;649 trx_id_t* version_trx_descr;
650 mem_heap_t* heap2;650 mem_heap_t* heap2;
651 rec_t* prev_version;651 rec_t* prev_version;
652 trx_id_t version_trx_id;652 trx_id_t version_trx_id;
@@ -657,19 +657,16 @@
657 }657 }
658658
659 mutex_enter(&trx_sys->mutex);659 mutex_enter(&trx_sys->mutex);
660 version_trx = trx_get_rw_trx_by_id(version_trx_id);660 version_trx_descr = trx_find_descriptor(trx_sys->descriptors,
661 trx_sys->descr_n_used,
662 version_trx_id);
661 /* Because version_trx is a read-write transaction,663 /* Because version_trx is a read-write transaction,
662 its state cannot change from or to NOT_STARTED while664 its state cannot change from or to NOT_STARTED while
663 we are holding the trx_sys->mutex. It may change from665 we are holding the trx_sys->mutex. It may change from
664 ACTIVE to PREPARED or COMMITTED. */666 ACTIVE to PREPARED or COMMITTED. */
665 if (version_trx
666 && trx_state_eq(version_trx,
667 TRX_STATE_COMMITTED_IN_MEMORY)) {
668 version_trx = NULL;
669 }
670 mutex_exit(&trx_sys->mutex);667 mutex_exit(&trx_sys->mutex);
671668
672 if (!version_trx) {669 if (!version_trx_descr) {
673committed_version_trx:670committed_version_trx:
674 /* We found a version that belongs to a671 /* We found a version that belongs to a
675 committed transaction: return it. */672 committed transaction: return it. */
676673
=== modified file 'Percona-Server/storage/innobase/trx/trx0sys.cc'
--- Percona-Server/storage/innobase/trx/trx0sys.cc 2013-05-12 06:24:46 +0000
+++ Percona-Server/storage/innobase/trx/trx0sys.cc 2013-05-24 12:02:59 +0000
@@ -506,6 +506,13 @@
506506
507 mtr_start(&mtr);507 mtr_start(&mtr);
508508
509 /* Allocate the trx descriptors array */
510 trx_sys->descriptors = static_cast<trx_id_t*>(
511 ut_malloc(sizeof(trx_id_t) *
512 TRX_DESCR_ARRAY_INITIAL_SIZE));
513 trx_sys->descr_n_max = TRX_DESCR_ARRAY_INITIAL_SIZE;
514 trx_sys->descr_n_used = 0;
515
509 sys_header = trx_sysf_get(&mtr);516 sys_header = trx_sysf_get(&mtr);
510517
511 if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {518 if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
@@ -1232,6 +1239,9 @@
12321239
1233 mutex_free(&trx_sys->mutex);1240 mutex_free(&trx_sys->mutex);
12341241
1242 ut_ad(trx_sys->descr_n_used == 0);
1243 ut_free(trx_sys->descriptors);
1244
1235 mem_free(trx_sys);1245 mem_free(trx_sys);
12361246
1237 trx_sys = NULL;1247 trx_sys = NULL;
12381248
=== modified file 'Percona-Server/storage/innobase/trx/trx0trx.cc'
--- Percona-Server/storage/innobase/trx/trx0trx.cc 2013-05-23 06:51:50 +0000
+++ Percona-Server/storage/innobase/trx/trx0trx.cc 2013-05-24 12:02:59 +0000
@@ -83,6 +83,127 @@
83 sizeof(trx->detailed_error));83 sizeof(trx->detailed_error));
84}84}
8585
86/*************************************************************//**
87Callback function for trx_find_descriptor() to compare trx IDs. */
88UNIV_INTERN
89int
90trx_descr_cmp(
91/*==========*/
92 const void *a, /*!< in: pointer to first comparison argument */
93 const void *b) /*!< in: pointer to second comparison argument */
94{
95 const trx_id_t* da = (const trx_id_t*) a;
96 const trx_id_t* db = (const trx_id_t*) b;
97
98 if (*da < *db) {
99 return -1;
100 } else if (*da > *db) {
101 return 1;
102 }
103
104 return 0;
105}
106
107/*************************************************************//**
108Reserve a slot for a given trx in the global descriptors array. */
109UNIV_INLINE
110void
111trx_reserve_descriptor(
112/*===================*/
113 const trx_t* trx) /*!< in: trx pointer */
114{
115 ulint n_used;
116 ulint n_max;
117 trx_id_t* descr;
118
119 ut_ad(mutex_own(&trx_sys->mutex) || srv_is_being_started);
120 ut_ad(srv_is_being_started ||
121 !trx_find_descriptor(trx_sys->descriptors,
122 trx_sys->descr_n_used,
123 trx->id));
124
125 n_used = trx_sys->descr_n_used + 1;
126 n_max = trx_sys->descr_n_max;
127
128 if (UNIV_UNLIKELY(n_used > n_max)) {
129
130 n_max = n_max * 2;
131
132 trx_sys->descriptors = static_cast<trx_id_t*>(
133 ut_realloc(trx_sys->descriptors,
134 n_max * sizeof(trx_id_t)));
135
136 trx_sys->descr_n_max = n_max;
137 }
138
139 descr = trx_sys->descriptors + n_used - 1;
140
141 if (UNIV_UNLIKELY(n_used > 1 && trx->id < descr[-1])) {
142
143 /* Find the slot where it should be inserted. We could use a
144 binary search, but in reality linear search should be faster,
145 because the slot we are looking for is near the array end. */
146
147 trx_id_t* tdescr;
148
149 for (tdescr = descr - 1;
150 tdescr >= trx_sys->descriptors && *tdescr > trx->id;
151 tdescr--) {
152 }
153
154 tdescr++;
155
156 ut_memmove(tdescr + 1, tdescr, (descr - tdescr) *
157 sizeof(trx_id_t));
158
159 descr = tdescr;
160 }
161
162 *descr = trx->id;
163
164 trx_sys->descr_n_used = n_used;
165}
166
167/*************************************************************//**
168Release a slot for a given trx in the global descriptors array. */
169UNIV_INTERN
170void
171trx_release_descriptor(
172/*===================*/
173 trx_t* trx) /*!< in: trx pointer */
174{
175 ulint size;
176 trx_id_t* descr;
177
178 ut_ad(mutex_own(&trx_sys->mutex));
179
180 if (UNIV_LIKELY(trx->in_trx_serial_list)) {
181
182 UT_LIST_REMOVE(trx_serial_list, trx_sys->trx_serial_list,
183 trx);
184 trx->in_trx_serial_list = 0;
185 }
186
187 descr = trx_find_descriptor(trx_sys->descriptors,
188 trx_sys->descr_n_used,
189 trx->id);
190
191 if (UNIV_UNLIKELY(descr == NULL)) {
192
193 return;
194 }
195
196 size = (trx_sys->descriptors + trx_sys->descr_n_used - 1 - descr) *
197 sizeof(trx_id_t);
198
199 if (UNIV_LIKELY(size > 0)) {
200
201 ut_memmove(descr, descr + 1, size);
202 }
203
204 trx_sys->descr_n_used--;
205}
206
86/****************************************************************//**207/****************************************************************//**
87Creates and initializes a transaction object. It must be explicitly208Creates and initializes a transaction object. It must be explicitly
88started with trx_start_if_not_started() before using it. The default209started with trx_start_if_not_started() before using it. The default
@@ -108,6 +229,7 @@
108 trx->isolation_level = TRX_ISO_REPEATABLE_READ;229 trx->isolation_level = TRX_ISO_REPEATABLE_READ;
109230
110 trx->no = IB_ULONGLONG_MAX;231 trx->no = IB_ULONGLONG_MAX;
232 trx->in_trx_serial_list = 0;
111233
112 trx->support_xa = TRUE;234 trx->support_xa = TRUE;
113235
@@ -207,11 +329,12 @@
207}329}
208330
209/********************************************************************//**331/********************************************************************//**
210Frees a transaction object. */332Frees a transaction object without releasing the corresponding descriptor.
333Should be used by callers that already own trx_sys->mutex. */
211static334static
212void335void
213trx_free(336trx_free_low(
214/*=====*/337/*=========*/
215 trx_t* trx) /*!< in, own: trx object */338 trx_t* trx) /*!< in, own: trx object */
216{339{
217 ut_a(trx->magic_n == TRX_MAGIC_N);340 ut_a(trx->magic_n == TRX_MAGIC_N);
@@ -255,6 +378,21 @@
255}378}
256379
257/********************************************************************//**380/********************************************************************//**
381Frees a transaction object. */
382static
383void
384trx_free(
385/*=========*/
386 trx_t* trx) /*!< in, own: trx object */
387{
388 mutex_enter(&trx_sys->mutex);
389 trx_release_descriptor(trx);
390 mutex_exit(&trx_sys->mutex);
391
392 trx_free_low(trx);
393}
394
395/********************************************************************//**
258Frees a transaction object of a background operation of the master thread. */396Frees a transaction object of a background operation of the master thread. */
259UNIV_INTERN397UNIV_INTERN
260void398void
@@ -328,7 +466,11 @@
328 UT_LIST_REMOVE(trx_list, trx_sys->rw_trx_list, trx);466 UT_LIST_REMOVE(trx_list, trx_sys->rw_trx_list, trx);
329 ut_d(trx->in_rw_trx_list = FALSE);467 ut_d(trx->in_rw_trx_list = FALSE);
330468
331 trx_free(trx);469 trx_release_descriptor(trx);
470
471 trx_free_low(trx);
472
473 ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->rw_trx_list));
332}474}
333475
334/********************************************************************//**476/********************************************************************//**
@@ -595,6 +737,7 @@
595737
596 UT_LIST_INIT(trx_sys->ro_trx_list);738 UT_LIST_INIT(trx_sys->ro_trx_list);
597 UT_LIST_INIT(trx_sys->rw_trx_list);739 UT_LIST_INIT(trx_sys->rw_trx_list);
740 UT_LIST_INIT(trx_sys->trx_serial_list);
598741
599 /* Look from the rollback segments if there exist undo logs for742 /* Look from the rollback segments if there exist undo logs for
600 transactions */743 transactions */
@@ -617,6 +760,11 @@
617760
618 trx = trx_resurrect_insert(undo, rseg);761 trx = trx_resurrect_insert(undo, rseg);
619762
763 if (trx->state == TRX_STATE_ACTIVE ||
764 trx->state == TRX_STATE_PREPARED) {
765
766 trx_reserve_descriptor(trx);
767 }
620 trx_list_rw_insert_ordered(trx);768 trx_list_rw_insert_ordered(trx);
621 }769 }
622770
@@ -642,6 +790,11 @@
642 trx_resurrect_update(trx, undo, rseg);790 trx_resurrect_update(trx, undo, rseg);
643791
644 if (trx_created) {792 if (trx_created) {
793 if (trx->state == TRX_STATE_ACTIVE ||
794 trx->state == TRX_STATE_PREPARED) {
795
796 trx_reserve_descriptor(trx);
797 }
645 trx_list_rw_insert_ordered(trx);798 trx_list_rw_insert_ordered(trx);
646 }799 }
647 }800 }
@@ -791,6 +944,8 @@
791 UT_LIST_ADD_FIRST(trx_list, trx_sys->rw_trx_list, trx);944 UT_LIST_ADD_FIRST(trx_list, trx_sys->rw_trx_list, trx);
792 ut_d(trx->in_rw_trx_list = TRUE);945 ut_d(trx->in_rw_trx_list = TRUE);
793 ut_d(trx_sys->rw_max_trx_id = trx->id);946 ut_d(trx_sys->rw_max_trx_id = trx->id);
947
948 trx_reserve_descriptor(trx);
794 }949 }
795950
796 ut_ad(trx_sys_validate_trx_list());951 ut_ad(trx_sys_validate_trx_list());
@@ -820,6 +975,14 @@
820975
821 trx->no = trx_sys_get_new_trx_id();976 trx->no = trx_sys_get_new_trx_id();
822977
978 if (UNIV_LIKELY(trx->in_trx_serial_list == 0)) {
979
980 UT_LIST_ADD_LAST(trx_serial_list, trx_sys->trx_serial_list,
981 trx);
982
983 trx->in_trx_serial_list = 1;
984 }
985
823 /* If the rollack segment is not empty then the986 /* If the rollack segment is not empty then the
824 new trx_t::no can't be less than any trx_t::no987 new trx_t::no can't be less than any trx_t::no
825 already in the rollback segment. User threads only988 already in the rollback segment. User threads only
@@ -1104,6 +1267,8 @@
1104 } else {1267 } else {
1105 UT_LIST_REMOVE(trx_list, trx_sys->rw_trx_list, trx);1268 UT_LIST_REMOVE(trx_list, trx_sys->rw_trx_list, trx);
1106 ut_d(trx->in_rw_trx_list = FALSE);1269 ut_d(trx->in_rw_trx_list = FALSE);
1270 ut_ad(trx_sys->descr_n_used <=
1271 UT_LIST_GET_LEN(trx_sys->rw_trx_list));
1107 MONITOR_INC(MONITOR_TRX_RW_COMMIT);1272 MONITOR_INC(MONITOR_TRX_RW_COMMIT);
1108 }1273 }
11091274
@@ -1220,6 +1385,8 @@
12201385
1221 trx->dict_operation = TRX_DICT_OP_NONE;1386 trx->dict_operation = TRX_DICT_OP_NONE;
12221387
1388 ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->rw_trx_list));
1389
1223 trx->error_state = DB_SUCCESS;1390 trx->error_state = DB_SUCCESS;
12241391
1225 /* trx->in_mysql_trx_list would hold between1392 /* trx->in_mysql_trx_list would hold between
@@ -1343,10 +1510,14 @@
1343 ut_a(!trx->read_only);1510 ut_a(!trx->read_only);
13441511
1345 UT_LIST_REMOVE(trx_list, trx_sys->rw_trx_list, trx);1512 UT_LIST_REMOVE(trx_list, trx_sys->rw_trx_list, trx);
1513 ut_ad(trx_sys->descr_n_used <= UT_LIST_GET_LEN(trx_sys->rw_trx_list));
13461514
1347 assert_trx_in_rw_list(trx);1515 assert_trx_in_rw_list(trx);
1348 ut_d(trx->in_rw_trx_list = FALSE);1516 ut_d(trx->in_rw_trx_list = FALSE);
13491517
1518 trx->state = TRX_STATE_NOT_STARTED;
1519 trx_release_descriptor(trx);
1520
1350 mutex_exit(&trx_sys->mutex);1521 mutex_exit(&trx_sys->mutex);
13511522
1352 /* Change the transaction state without mutex protection, now1523 /* Change the transaction state without mutex protection, now
@@ -1356,7 +1527,6 @@
1356 ut_ad(!trx->in_ro_trx_list);1527 ut_ad(!trx->in_ro_trx_list);
1357 ut_ad(!trx->in_rw_trx_list);1528 ut_ad(!trx->in_rw_trx_list);
1358 ut_ad(!trx->in_mysql_trx_list);1529 ut_ad(!trx->in_mysql_trx_list);
1359 trx->state = TRX_STATE_NOT_STARTED;
1360}1530}
13611531
1362/********************************************************************//**1532/********************************************************************//**
@@ -1376,11 +1546,8 @@
1376 return(trx->read_view);1546 return(trx->read_view);
1377 }1547 }
13781548
1379 if (!trx->read_view) {1549 trx->read_view = read_view_open_now(trx->id, trx->prebuilt_view);
1380 trx->read_view = read_view_open_now(trx->id,1550 trx->global_read_view = trx->read_view;
1381 trx->prebuilt_view);
1382 trx->global_read_view = trx->read_view;
1383 }
13841551
1385 return(trx->read_view);1552 return(trx->read_view);
1386}1553}
13871554
=== added directory 'policy'
=== added directory 'policy/apparmor'
=== added file 'policy/apparmor/usr.sbin.mysqld'
--- policy/apparmor/usr.sbin.mysqld 1970-01-01 00:00:00 +0000
+++ policy/apparmor/usr.sbin.mysqld 2013-05-24 12:02:59 +0000
@@ -0,0 +1,61 @@
1# Last Modified: Thu Mar 7 21:58:51 2013
2# Based on usr.sbin.mysqld packaged in mysql-server in Ubuntu.
3# For Percona Server and Percona XtraDB Cluster
4
5#include <tunables/global>
6
7/usr/sbin/mysqld flags=(complain) {
8 #include <abstractions/base>
9 #include <abstractions/mysql>
10 #include <abstractions/nameservice>
11 #include <abstractions/user-tmp>
12 #include <abstractions/winbind>
13 #include <local/usr.sbin.mysqld>
14
15
16 capability chown,
17 capability dac_override,
18 capability setgid,
19 capability setuid,
20 capability sys_rawio,
21 capability sys_resource,
22
23 network tcp,
24
25
26 /dev/dm-0 r,
27 /etc/group r,
28 /etc/gai.conf r,
29 /etc/hosts.allow r,
30 /etc/hosts.deny r,
31 /etc/ld.so.cache r,
32 /etc/mtab r,
33 /etc/my.cnf r,
34 /etc/mysql/*.cnf r,
35 /etc/mysql/*.pem r,
36 /etc/mysql/conf.d/ r,
37 /etc/mysql/conf.d/* r,
38 /etc/nsswitch.conf r,
39 /etc/passwd r,
40 /etc/services r,
41 /run/mysqld/mysqld.pid w,
42 /run/mysqld/mysqld.sock w,
43 /sys/devices/system/cpu/ r,
44 owner /tmp/** lk,
45 /tmp/** rw,
46 /usr/lib/mysql/plugin/ r,
47 /usr/lib/mysql/plugin/*.so* mr,
48 /usr/sbin/mysqld mr,
49 /usr/share/mysql/** r,
50 /var/lib/mysql/ r,
51 /var/lib/mysql/** rwk,
52 /var/log/mysql.err rw,
53 /var/log/mysql.log rw,
54 /var/log/mysql/ r,
55 /var/log/mysql/* rw,
56 /var/run/mysqld/mysqld.pid w,
57 /var/run/mysqld/mysqld.sock w,
58
59 # Site-specific additions and overrides. See local/README for details.
60 #include <local/usr.sbin.mysqld>
61}
062
=== added file 'policy/apparmor/usr.sbin.mysqld.local'
--- policy/apparmor/usr.sbin.mysqld.local 1970-01-01 00:00:00 +0000
+++ policy/apparmor/usr.sbin.mysqld.local 2013-05-24 12:02:59 +0000
@@ -0,0 +1,2 @@
1# Site-specific additions and overrides for usr.sbin.mysqld..
2# For more details, please see /etc/apparmor.d/local/README.
03
=== added directory 'policy/selinux'
=== added file 'policy/selinux/percona-server.fc'
--- policy/selinux/percona-server.fc 1970-01-01 00:00:00 +0000
+++ policy/selinux/percona-server.fc 2013-05-24 12:02:59 +0000
@@ -0,0 +1,6 @@
1/etc/init\.d/rc\.d/mysql -- gen_context(system_u:object_r:mysqld_initrc_exec_t,s0)
2/var/lib/mysql/.*\.log -- gen_context(system_u:object_r:mysqld_log_t,s0)
3/var/lib/mysql/.*\.err -- gen_context(system_u:object_r:mysqld_log_t,s0)
4/var/lib/mysql/.*\.pid -- gen_context(system_u:object_r:mysqld_var_run_t,s0)
5/var/lib/mysql/.*\.cnf -- gen_context(system_u:object_r:mysqld_etc_t,s0)
6/usr/bin/xtrabackup.* -- gen_context(system_u:object_r:mysqld_exec_t,s0)
07
=== added file 'policy/selinux/percona-server.te'
--- policy/selinux/percona-server.te 1970-01-01 00:00:00 +0000
+++ policy/selinux/percona-server.te 2013-05-24 12:02:59 +0000
@@ -0,0 +1,35 @@
1# This adds few more rules in addition to mysql.pp in selinux-policy-targeted
2module percona-server 1.0;
3
4require {
5 type user_tmp_t;
6 type mysqld_safe_t;
7 type tmp_t;
8 type fixed_disk_device_t;
9 type mysqld_t;
10 type tmpfs_t;
11 class sock_file { getattr unlink create };
12 class capability { sys_nice sys_resource };
13 class blk_file { read write open };
14 class file { write getattr read create unlink open };
15 class dir { search read write remove_name open add_name };
16}
17
18#============= mysqld_safe_t ==============
19allow mysqld_safe_t self:capability { sys_nice sys_resource };
20
21allow mysqld_safe_t tmp_t:dir { write remove_name };
22allow mysqld_safe_t tmp_t:sock_file { getattr unlink };
23allow mysqld_safe_t user_tmp_t:sock_file { getattr unlink };
24
25#============= mysqld_t ==============
26allow mysqld_t fixed_disk_device_t:blk_file { read write open };
27allow mysqld_t tmp_t:sock_file { create unlink };
28
29allow mysqld_t tmpfs_t:dir { write search read remove_name open add_name };
30allow mysqld_t tmpfs_t:file { write getattr read create unlink open };
31
32allow mysqld_t user_tmp_t:dir { write add_name };
33allow mysqld_t user_tmp_t:file create;
34
35allow mysqld_t tmp_t:file { append create read write open getattr unlink setattr };

Subscribers

People subscribed via source and target branches