Memcached

登陆 MySQL 查看插件目录,安装对应的配置数据表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mysql -hlocalhost -uroot -p
mysql > SELECT @@plugin_dir; // 查看插件目录

// 导入 memcache 相关的表

mysql > SOURCE /usr/local/mysql/share/innodb_memcached_config.sql
Query OK, 1 row affected (0.00 sec)

Database changed
Query OK, 0 rows affected (0.02 sec)


// 多了一个 innodb_memcache 库
mysql> show databases;
+------------------------+

| Database |
+------------------------+

| information_schema |
| innodb_memcache |

| test |
+------------------------+

……

激活和卸载插件

1
2
mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";  //  激活插件
mysql> UNINSTALL PLUGIN daemon_memcached; // 卸载插件

通过 MySQL 查看配置信息

1
2
3
4
5
6
7
8
myssql> SHOW VARIABLES LIKE '%memcached%';

daemon_memcached_enable_binlog OFF
daemon_memcached_engine_lib_name innodb_engine.so
daemon_memcached_engine_lib_path
daemon_memcached_option
daemon_memcached_r_batch_size 1
daemon_memcached_w_batch_size 1

查看 Memcached

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
shell > telnet localhost 11211
stats

Trying ::1...
Connected to localhost.
Escape character is '^]'.
stats
STAT pid 94
STAT uptime 317
STAT time 1450766105
STAT version 5.6.27
STAT libevent 5.6.27
STAT pointer_size 64
STAT rusage_user 16.726572
STAT rusage_system 18.890886
……

innodb_memcache 库的详细信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> use innodb_memcache;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> show tables;
+---------------------------+

| Tables_in_innodb_memcache |
+---------------------------+

| cache_policies |
| config_options |

| containers |
+---------------------------+

3 rows in set (0.00 sec)

cache_policies 缓存策略

  • innodb_only 只使用InnoDB作为数据存储
  • cache-only 只使用传统的Memcached引擎作为后端存储
  • caching 二者皆使用,如果在Memcached里找不到,就查询InnoDB
1
2
3
4
5
6
7
mysql> select * from cache_policies \G
*************************** 1. row ***************************
policy_name: cache_policy
get_policy: innodb_only
set_policy: innodb_only
delete_policy: innodb_only
flush_policy: innodb_only

config_options 配置参数

1
2
3
4
5
6
7
mysql> select * from config_options \G
*************************** 1. row ***************************
name: separator // Memcached只识别单值,使用此分隔符(|)来连接多个字段的值,需要注意当值内含有`|`的时候,会带来错误,所以需要修改 separator
value: |

*************************** 2. row ***************************
name: table_map_delimiter // 通过此分隔符(.)来确认表和键,如:@@table.key。
value: .

如果通过 Memcached 协议来访问数据表,还需要在 containers 表里做一些配置 demo_test 是开始 SOURCE 导入 innodb_memcached_config.sql 文件的时候生成的。

1
2
3
4
5
6
7
8
9
10
11
mysql> SELECT * FROM containers\G
*************************** 1. row ***************************
name: aaa
db_schema: test
db_table: demo_test
key_columns: c1
value_columns: c2
flags: c3
cas_column: c4
expire_time_column: c5
unique_idx_name_on_key: PRIMARY

查看 demo_test 表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> DESC test.demo_test;
+-------+---------------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+

| c1 | varchar(32) | NO | PRI | | |
| c2 | varchar(1024) | YES | | NULL | |
| c3 | int(11) | YES | | NULL | |
| c4 | bigint(20) unsigned | YES | | NULL | |
| c5 | int(11) | YES | | NULL | |
+-------+---------------------+------+-----+---------+-------+

5 rows in set (0.01 sec)

mysql> select * from test.demo_test;
+----+--------------+------+------+------+

| c1 | c2 | c3 | c4 | c5 |
+----+--------------+------+------+------+

| AA | HELLO, HELLO | 8 | 0 | 0 |
+----+--------------+------+------+------+

1 row in set (0.00 sec)

通过 Memcached 协议获得数据

1
2
3
4
5
6
7
8
shell> telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
get @@aaa.AA // aaa 就是 containers 表的 name 字段的值,相当于 `db_schema.db_table`
VALUE @@aaa.AA 8 12 // VALUE <key> <flags> <bytes>
HELLO, HELLO
END

通过 php 来访问这个数据

1
2
3
4
<?php
$mc = new Memcache();
$mc->connect('127.0.0.1', 11211);
var_dump($mc->get('@@aaa.AA')); // 这里需要注意如果 `containers` 有多行数据的时候,需要使用表前缀 `@@name.` 如果不使用表名,那么会默认会按照表名的字母顺序,取第一个。如果 `containers` 只有一行数据 name 为 `aaa`,那么默认 `get('AA')` 也是会取 `@aaa.AA`

DDL online

修改表结构是我们开发过程中经常遇到的事情,早期 MySQL 版本在修改表结构的时候,主要采用以下方式:

  • 创建临时表 tmp ,该表与原表 table 相似
  • table数据复制到 tmp
  • 删除原有表 table
  • rename tmp to table
    如果数据量非常大的情况下,整个表被加共享锁,基本就不能提供服务了。

在 MySQL5.6 中,这个操作有了改善,在 ALERT TABLE 语法上,增加了 | ALGORITHM [=] {DEFAULT|INPLACE|COPY} 选项,如果没有指定 ALGORITHM ,MySQL 会根据支持的算法,自动选择,而 INPLACE 会优先被选择,这样就可以在修改表的时候依然可以提供服务。有些 Online DDL 是不支持的,有些是有依赖条件的,MySQL 官方明确的列出了一个表格 Online DDL 操作总结

MySQL 复制的新特性

  • 多线程复制 由于数据库的主从架构,以前的MySQL版本主库多线程写入,为了保证顺序从库是单线程读取,现在的多线程复制是为每个数据库开启了一个单独的线程(sql thread),所以如果要使用多线程复制特性,需要把库拆分成多个,如果还是一个数据库,那么这个多线程复制特性无效。

  • GTID 全局事务ID(global transaction identifier),GTID 是事务提交时创建分配的唯一标识符,所有事务均与 GTID 一一映射。以前如果主从复制断了,需要人工去找到断点,重新开始,而 GTID 的引入可以自动寻找同步点,自动完成复制,不需要人工干预。

  • 基于 Row 复制只保存改变的列,降低硬盘、网络、内存等消耗。

  • 支持把 Master 和 Slave 的相关信息记录在表中,原来是记录在文件里,记录在表里,增强可用性。
  • 支持延时复制。

GTID 的格式类似 server_uuid:id

1
2
3
4
5
6
7
mysql> select @@server_uuid;
+--------------------------------------+

| @@server_uuid |
+--------------------------------------+

| fbf78286-701a-11e5-a88b-5b1557785233 |
+--------------------------------------+

1 row in set (0.00 sec)

该数据被写在 DATADIR (/usr/local/mysql/data/auto.cnf) 文件中,第一次启动的时候由 generate_server_uuid 函数生成。
id 是事务编号, server_uuid:id 共同组成了事务的唯一 ID,用来标示一个事务。
GTID 复制有着严格的限制,GTID 实例和非 GTID 实例是不能进行复制的。
GTID 官方文档 , MySQL 内核月报参考