#### 15.20.6.4 Controlling Transactional Behavior of the InnoDB memcached Plugin

 Unlike traditional **memcached**, the `daemon_memcached` plugin allows you to control durability of data values produced through calls to `add`, `set`, `incr`, and so on. By default, data written through the **memcached** interface is stored to disk, and calls to `get` return the most recent value from disk. Although the default behavior does not offer the best possible raw performance, it is still fast compared to the SQL interface for `InnoDB` tables.

 As you gain experience using the `daemon_memcached` plugin, you can consider relaxing durability settings for non-critical classes of data, at the risk of losing some updated values in the event of an outage, or returning data that is slightly out-of-date.

##### Frequency of Commits

 One tradeoff between durability and raw performance is how frequently new and changed data is [committed](glossary.html#glos_commit). If data is critical, is should be committed immediately so that it is safe in case of an unexpected exit or outage. If data is less critical, such as counters that are reset after an unexpected exit or logging data that you can afford to lose, you might prefer higher raw throughput that is available with less frequent commits.

 When a **memcached** operation inserts, updates, or deletes data in the underlying `InnoDB` table, the change might be committed to the `InnoDB` table instantly (if [`daemon_memcached_w_batch_size=1`](innodb-parameters.html#sysvar_daemon_memcached_w_batch_size)) or some time later (if the [`daemon_memcached_w_batch_size`](innodb-parameters.html#sysvar_daemon_memcached_w_batch_size) value is greater than 1). In either case, the change cannot be rolled back. If you increase the value of [`daemon_memcached_w_batch_size`](innodb-parameters.html#sysvar_daemon_memcached_w_batch_size) to avoid high I/O overhead during busy times, commits could become infrequent when the workload decreases. As a safety measure, a background thread automatically commits changes made through the **memcached** API at regular intervals. The interval is controlled by the [`innodb_api_bk_commit_interval`](innodb-parameters.html#sysvar_innodb_api_bk_commit_interval) configuration option, which has a default setting of `5` seconds.

 When a **memcached** operation inserts or updates data in the underlying `InnoDB` table, the changed data is immediately visible to other **memcached** requests because the new value remains in the memory cache, even if it is not yet committed on the MySQL side.

##### Transaction Isolation

 When a **memcached** operation such as `get` or `incr` causes a query or DML operation on the underlying `InnoDB` table, you can control whether the operation sees the very latest data written to the table, only data that has been committed, or other variations of transaction [isolation level](glossary.html#glos_isolation_level). Use the [`innodb_api_trx_level`](innodb-parameters.html#sysvar_innodb_api_trx_level) configuration option to control this feature. The numeric values specified for this option correspond to isolation levels such as [`REPEATABLE READ`](innodb-transaction-isolation-levels.html#isolevel_repeatable-read). See the description of the [`innodb_api_trx_level`](innodb-parameters.html#sysvar_innodb_api_trx_level) option for information about other settings.

 A strict isolation level ensures that data you retrieve is not rolled back or changed suddenly causing subsequent queries to return different values. However, strict isolation levels require greater [locking](glossary.html#glos_locking) overhead, which can cause waits. For a NoSQL-style application that does not use long-running transactions, you can typically use the default isolation level or switch to a less strict isolation level.

##### Disabling Row Locks for memcached DML Operations

 The [`innodb_api_disable_rowlock`](innodb-parameters.html#sysvar_innodb_api_disable_rowlock) option can be used to disable row locks when **memcached** requests through the `daemon_memcached` plugin cause DML operations. By default, `innodb_api_disable_rowlock` is set to `OFF` which means that **memcached** requests row locks for `get` and `set` operations. When `innodb_api_disable_rowlock` is set to `ON`, **memcached** requests a table lock instead of row locks.

 The `innodb_api_disable_rowlock` option is not dynamic. It must be specified at startup on the [**mysqld**](mysqld.html) command line or entered in a MySQL configuration file.

##### Allowing or Disallowing DDL

 By default, you can perform [DDL](glossary.html#glos_ddl) operations such as [`ALTER TABLE`](alter-table.html) on tables used by the `daemon_memcached` plugin. To avoid potential slowdowns when these tables are used for high-throughput applications, disable DDL operations on these tables by enabling [`innodb_api_enable_mdl`](innodb-parameters.html#sysvar_innodb_api_enable_mdl) at startup. This option is less appropriate when accessing the same tables through both **memcached** and SQL, because it blocks [`CREATE INDEX`](create-index.html) statements on the tables, which could be important for running reporting queries.

##### Storing Data on Disk, in Memory, or Both

 The `innodb_memcache.cache_policies` table specifies whether to store data written through the **memcached** interface to disk (`innodb_only`, the default); in memory only, as with traditional **memcached** (`cache_only`); or both (`caching`).

 With the `caching` setting, if **memcached** cannot find a key in memory, it searches for the value in an `InnoDB` table. Values returned from `get` calls under the `caching` setting could be out-of-date if the values were updated on disk in the `InnoDB` table but are not yet expired from the memory cache.

 The caching policy can be set independently for `get`, `set` (including `incr` and `decr`), `delete`, and `flush` operations.

 For example, you might allow `get` and `set` operations to query or update a table and the **memcached** memory cache at the same time (using the `caching` setting), while making `delete`, `flush`, or both operate only on the in-memory copy (using the `cache_only` setting). That way, deleting or flushing an item only expires the item from the cache, and the latest value is returned from the `InnoDB` table the next time the item is requested.

```
mysql> SELECT * FROM innodb_memcache.cache_policies;
+--------------+-------------+-------------+---------------+--------------+
| policy_name  | get_policy  | set_policy  | delete_policy | flush_policy |
+--------------+-------------+-------------+---------------+--------------+
| cache_policy | innodb_only | innodb_only | innodb_only   | innodb_only  |
+--------------+-------------+-------------+---------------+--------------+

mysql> UPDATE innodb_memcache.cache_policies SET set_policy = 'caching'
       WHERE policy_name = 'cache_policy';
```

`innodb_memcache.cache_policies` values are only read at startup. After changing values in this table, uninstall and reinstall the `daemon_memcached` plugin to ensure that changes take effect.

```
mysql> UNINSTALL PLUGIN daemon_memcached;

mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
```

