So, the only place where it's referred in the code (5.6.27 from GitHub) is in srv0srv.cc:
/******************************************************************//**
Function to pass InnoDB status variables to MySQL */
UNIV_INTERN
void
srv_export_innodb_status(void)
/*==========================*/
{
... export_vars.innodb_current_row_locks
= lock_sys->rec_num;
...
First, let's check when srv_export_innodb_status() is called:
[openxs@centos percona-server]$ grep -rn srv_export_innodb_status *
storage/innobase/include/srv0srv.h:812:srv_export_innodb_status(void);
storage/innobase/srv/srv0mon.cc:1435:srv_export_innodb_status() for related global counters used by
storage/innobase/srv/srv0srv.cc:1577:srv_export_innodb_status(void)
storage/innobase/handler/ha_innodb.cc:13330: srv_export_innodb_status();
[openxs@centos percona-server]$
So, this is where it's called:
/************************************************************************//**
Here we export InnoDB status variables to MySQL. */
static
void
innodb_export_status()
/*==================*/
{
if (innodb_inited) { srv_export_innodb_status();
}
}
Let's check when innodb_export_status() is called:
/****************************************************************//**
Callback function for accessing the InnoDB variables from MySQL:
SHOW VARIABLES. */
static
int
show_innodb_vars(
/*=============*/
THD* thd,
SHOW_VAR* var,
char* buff)
{ innodb_export_status();
var->type = SHOW_ARRAY;
var->value = (char*) &innodb_status_variables;
return(0);
}
So, we can assume it's called every time when SHOW VARIABLES is called. Now, let's check where lock_sys->rec_num comes from:
Creates a new record lock and inserts it to the lock queue. Does NOT check
for deadlocks or lock compatibility!
@return created lock */
static
lock_t*
lock_rec_create(
... HASH_INSERT(lock_t, hash, lock_sys->rec_hash, lock_rec_fold(space, page_no), lock);
lock_sys->rec_num++;
...
This is the only place in the code when it is incremented. This is where it's decremented:
/*************************************************************//**
Removes a record lock request, waiting or granted, from the queue and
grants locks to other transactions in the queue if they now are entitled
to a lock. NOTE: all record locks contained in in_lock are removed. */
static
void
lock_rec_dequeue_from_page(
/*=======================*/
lock_t* in_lock) /*!< in: record lock object: all record locks which are contained in this lock object are removed; transactions waiting behind will get their lock requests granted, if they are now qualified to it */
... HASH_DELETE(lock_t, hash, lock_sys->rec_hash, lock_rec_fold(space, page_no), in_lock); lock_sys->rec_num--;
...
and then later:
/*************************************************************//**
Removes a record lock request, waiting or granted, from the queue. */
static
void
lock_rec_discard(
/*=============*/
lock_t* in_lock) /*!< in: record lock object: all record locks which are contained in this lock object are removed */
... HASH_DELETE(lock_t, hash, lock_sys->rec_hash, lock_rec_fold(space, page_no), in_lock); lock_sys->rec_num--;
...
From what I see I'd say it's a number of lock structures for record locks, with every record lock being able to track several individual row locks of the same "kind". Hence the value 3 in my original example.
I've spent some time checking the code to find out what this variable really shows:
[openxs@centos ~]$ cd git/percona-server/ current_ row_locks * ps-variables. rst:788: * - :variable: `Innodb_ current_ row_locks` diagnostics/ innodb_ show_status. rst:432: .. variable:: Innodb_ current_ row_locks innobase/ include/ srv0srv. h:1047: ulint innodb_ current_ row_locks; innobase/ srv/srv0srv. cc:1763: export_ vars.innodb_ current_ row_locks innobase/ handler/ ha_innodb. cc:809: (char*) &export_ vars.innodb_ current_ row_locks, SHOW_LONG},
[openxs@centos percona-server]$ grep -rni Innodb_
doc/source/
doc/source/
storage/
storage/
storage/
So, the only place where it's referred in the code (5.6.27 from GitHub) is in srv0srv.cc:
/****** ******* ******* ******* ******* ******* ******* ******* ******* ****//* * innodb_ status( void) ======= ======= ======= */
export_ vars.innodb_ current_ row_locks
Function to pass InnoDB status variables to MySQL */
UNIV_INTERN
void
srv_export_
/*=====
{
...
= lock_sys->rec_num;
...
First, let's check when srv_export_ innodb_ status( ) is called:
[openxs@centos percona-server]$ grep -rn srv_export_ innodb_ status * innobase/ include/ srv0srv. h:812:srv_ export_ innodb_ status( void); innobase/ srv/srv0mon. cc:1435: srv_export_ innodb_ status( ) for related global counters used by innobase/ srv/srv0srv. cc:1577: srv_export_ innodb_ status( void) innobase/ handler/ ha_innodb. cc:13330: srv_export_ innodb_ status( );
storage/
storage/
storage/
storage/
[openxs@centos percona-server]$
So, this is where it's called:
/****** ******* ******* ******* ******* ******* ******* ******* ******* ******* ***//** export_ status( ) ======= ======* /
srv_export_ innodb_ status( );
Here we export InnoDB status variables to MySQL. */
static
void
innodb_
/*=====
{
if (innodb_inited) {
}
}
Let's check when innodb_ export_ status( ) is called:
[openxs@centos percona-server]$ vi +13330 storage/ innobase/ handler/ ha_innodb. cc export_ status * innobase/ handler/ ha_innodb. cc:13326: innodb_ export_ status( ) innobase/ handler/ ha_innodb. cc:16429: innodb_ export_ status( );
[openxs@centos percona-server]$ grep -rn innodb_
storage/
storage/
[openxs@centos percona-server]$
So, here it is:
/****** ******* ******* ******* ******* ******* ******* ******* ******* **//**
innodb_ export_ status( ); status_ variables;
Callback function for accessing the InnoDB variables from MySQL:
SHOW VARIABLES. */
static
int
show_innodb_vars(
/*=============*/
THD* thd,
SHOW_VAR* var,
char* buff)
{
var->type = SHOW_ARRAY;
var->value = (char*) &innodb_
return(0);
}
So, we can assume it's called every time when SHOW VARIABLES is called. Now, let's check where lock_sys->rec_num comes from:
[openxs@centos percona-server]$ grep -rn 'lock_sys->rec_num' * innobase/ lock/lock0lock. cc:619: lock_sys->rec_num = 0; innobase/ lock/lock0lock. cc:1869: lock_sys- >rec_num+ +; innobase/ lock/lock0lock. cc:2511: lock_sys- >rec_num- -; innobase/ lock/lock0lock. cc:2562: lock_sys- >rec_num- -; innobase/ srv/srv0srv. cc:1764: = lock_sys->rec_num;
...
storage/
storage/
storage/
storage/
storage/
Creates a new record lock and inserts it to the lock queue. Does NOT check
HASH_INSERT( lock_t, hash, lock_sys->rec_hash,
lock_ rec_fold( space, page_no), lock);
for deadlocks or lock compatibility!
@return created lock */
static
lock_t*
lock_rec_create(
...
...
This is the only place in the code when it is incremented. This is where it's decremented:
/****** ******* ******* ******* ******* ******* ******* ******* ******/ /** dequeue_ from_page( ======= ======= ====*/
record locks which are contained in
this lock object are removed;
transactio ns waiting behind will
get their lock requests granted,
if they are now qualified to it */
HASH_DELETE( lock_t, hash, lock_sys->rec_hash,
lock_ rec_fold( space, page_no), in_lock);
lock_sys- >rec_num- -;
Removes a record lock request, waiting or granted, from the queue and
grants locks to other transactions in the queue if they now are entitled
to a lock. NOTE: all record locks contained in in_lock are removed. */
static
void
lock_rec_
/*=====
lock_t* in_lock) /*!< in: record lock object: all
...
...
and then later:
/****** ******* ******* ******* ******* ******* ******* ******* ******/ /**
record locks which are contained
in this lock object are removed */
HASH_DELETE( lock_t, hash, lock_sys->rec_hash,
lock_ rec_fold( space, page_no), in_lock);
lock_sys- >rec_num- -;
Removes a record lock request, waiting or granted, from the queue. */
static
void
lock_rec_discard(
/*=============*/
lock_t* in_lock) /*!< in: record lock object: all
...
...
From what I see I'd say it's a number of lock structures for record locks, with every record lock being able to track several individual row locks of the same "kind". Hence the value 3 in my original example.