ディスクとメモリーへの書き込み速度確認
ddコマンドで128Mのブロックサイズを2回書き込んだ速度確認

ディスク: real 0m7.087s
メモリー: real 0m0.788s
約9倍の書き込み速度の違いが見られる。

ファイルシステムへの書き込み速度

[root@HOME001 local]# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_home001-lv_root
                       47G  2.5G   42G   6% /
tmpfs                 947M     0  947M   0% /dev/shm
/dev/sda1             485M   36M  424M   8% /boot
/dev/mapper/vg_home001-lv_home
                      4.6G  322M  4.0G   8% /home
[root@HOME001 local]# time dd if=/dev/zero of=/usr/local/tmp/tmpfs bs=128M count=2
2+0 records in
2+0 records out
268435456 bytes (268 MB) copied, 7.06478 s, 38.0 MB/s

real    0m7.087s
user    0m0.001s
sys     0m0.949s
[root@HOME001 local]# rm -f /usr/local/tmp/*

[root@HOME001 local]# free
             total       used       free     shared    buffers     cached
Mem:       1938948     200436    1738512          0      10720      94452
-/+ buffers/cache:      95264    1843684
Swap:      4161528          0    4161528
[root@HOME001 local]#

tmpfs(メモリー)への書き込み速度

[root@HOME001 local]# mount -t tmpfs -o size=512m tmpfs /usr/local/tmp
[root@HOME001 local]# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_home001-lv_root
                       47G  2.5G   42G   6% /
tmpfs                 947M     0  947M   0% /dev/shm
/dev/sda1             485M   36M  424M   8% /boot
/dev/mapper/vg_home001-lv_home
                      4.6G  322M  4.0G   8% /home
tmpfs                 512M     0  512M   0% /usr/local/tmp
[root@HOME001 local]# time dd if=/dev/zero of=/usr/local/tmp/tmpfs bs=128M count=2
2+0 records in
2+0 records out
268435456 bytes (268 MB) copied, 0.770854 s, 348 MB/s

real    0m0.788s
user    0m0.000s
sys     0m0.784s
[root@HOME001 local]#

[root@HOME001 local]# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_home001-lv_root
                       47G  2.5G   42G   6% /
tmpfs                 947M     0  947M   0% /dev/shm
/dev/sda1             485M   36M  424M   8% /boot
/dev/mapper/vg_home001-lv_home
                      4.6G  322M  4.0G   8% /home
tmpfs                 512M  257M  256M  51% /usr/local/tmp
[root@HOME001 local]# free
             total       used       free     shared    buffers     cached
Mem:       1938948     462820    1476128          0      10720     356596
-/+ buffers/cache:      95504    1843444
Swap:      4161528          0    4161528
[root@HOME001 local]#

tempfs

fstabに追記して常時起動

[root@HOME001 local]# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_home001-lv_root     47G  2.5G   42G   6% /
tmpfs                             947M     0  947M   0% /dev/shm
/dev/sda1                         485M   36M  424M   8% /boot
/dev/mapper/vg_home001-lv_home    4.6G  322M  4.0G   8% /home
[root@HOME001 local]# vi /etc/fstab

[root@HOME001 local]# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Sun Nov 25 06:08:34 2012
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/vg_home001-lv_root /                       ext4    defaults        1 1
UUID=d0a823c7-d51e-42de-b422-2f3ab5d82d96 /boot                   ext4    defaults        1 2
/dev/mapper/vg_home001-lv_home /home                   ext4    defaults        1 2
/dev/mapper/vg_home001-lv_swap swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
# add for memory disk
tmpfs                   /usr/local/tmp          tmpfs   defaults,size=512m 0 0
[root@HOME001 local]#


[root@HOME001 local]# mount -a
[root@HOME001 local]# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_home001-lv_root     47G  2.5G   42G   6% /
tmpfs                             947M     0  947M   0% /dev/shm
/dev/sda1                         485M   36M  424M   8% /boot
/dev/mapper/vg_home001-lv_home    4.6G  322M  4.0G   8% /home
tmpfs                             128M     0  512M   0% /usr/local/tmp
[root@HOME001 local]#


[root@HOME001 local]# time dd if=/dev/zero of=/usr/local/tmp/tmpfs bs=128M count=2
2+0 records in
2+0 records out
268435456 bytes (268 MB) copied, 0.776067 s, 346 MB/s

real    0m0.793s
user    0m0.001s
sys     0m0.789s
[root@HOME001 local]#

再起動後もマウントされている事を確認済み

fstab

関連スレ
MYSQL with tempfs


memcached は、データとオブジェクトをメモリ内にキャッシュすることで、
データベースなどからデータを頻繁に取りにいくことを減らしてパフォーマンスを改善させたり、
セッションをmemcached上に載せる事で、高速なセッション管理を行ったりする事が出来る。

The latest stable memcached release is
v1.4.13
memcached.org

Free & open source, high-performance, distributed memory object caching system,
generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

libeventのインストール

[root@ Sun May 27]# yum install libevent libevent-devel
Loaded plugins: fastestmirror, priorities, security, update-motd
Loading mirror speeds from cached hostfile
* amzn-main: packages.ap-northeast-1.amazonaws.com
* amzn-updates: packages.ap-northeast-1.amazonaws.com
amzn-main | 2.1 kB 00:00
amzn-updates | 2.3 kB 00:00
Setting up Install Process
Resolving Dependencies
–> Running transaction check
—> Package libevent.x86_64 0:1.4.13-1.6.amzn1 will be installed
—> Package libevent-devel.x86_64 0:1.4.13-1.6.amzn1 will be installed
–> Finished Dependency Resolution

省略…
Dependencies ResolvedDownloading Packages:
(1/2): libevent-1.4.13-1.6.amzn1.x86_64.rpm | 114 kB 00:00
(2/2): libevent-devel-1.4.13-1.6.amzn1.x86_64.rpm | 386 kB 00:00

MEMCACHEDインストール

[root@ Sun May 27]# wget http://memcached.googlecode.com/files/memcached-1.4.13.tar.gz
–2012-05-27 17:56:05– http://memcached.googlecode.com/files/memcached-1.4.13.tar.gz
Resolving memcached.googlecode.com… 72.14.203.82
Connecting to memcached.googlecode.com|72.14.203.82|:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 320751 (313K) [application/x-gzip]
Saving to: “memcached-1.4.13.tar.gz”

100%[==========================================================================>] 320,751 1.37M/s in 0.2s

2012-05-27 17:56:06 (1.37 MB/s) – “memcached-1.4.13.tar.gz” saved [320751/320751]

[root@ Sun May 27]#

[root@ Sun May 27]# tar zxf memcached-1.4.13.tar.gz
[root@ Sun May 27]# ls -l
total 320
drwxr-xr-x 6 1000 1000 4096 Feb 3 06:24 memcached-1.4.13
-rw-r–r– 1 root root 320751 Feb 3 06:27 memcached-1.4.13.tar.gz
[root@ Sun May 27]# cd memcached-1.4.13
[root@ Sun May 27]# ./configure
checking build system type… x86_64-unknown-linux-gnu
checking host system type… x86_64-unknown-linux-gnu
checking target system type… x86_64-unknown-linux-gnu
checking for a BSD-compatible install… /usr/bin/install -c
checking whether build environment is sane… yes
checking for a thread-safe mkdir -p… /bin/mkdir -p
checking for gawk… gawk
checking whether make sets $(MAKE)… yes
checking for gcc… gcc
checking whether the C compiler works… yes
checking for C compiler default output file name… a.out
checking for suffix of executables…
checking whether we are cross compiling… no
checking for suffix of object files… o
checking whether we are using the GNU C compiler… yes
checking whether gcc accepts -g… yes

[省略]……………………………………..

[root@ Sun May 27]# make
make all-recursive
make[1]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13′
Making all in doc
make[2]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make all-am
make[3]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[3]: Nothing to be done for `all-am’.
make[3]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[2]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[2]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13′
gcc -std=gnu99 -DHAVE_CONFIG_H -I. -DNDEBUG -g -O2 -pthread -Wall -Werror -pedantic
-Wmissing-prototypes -Wmissing-declarations -Wredundant -decls -fno-strict-aliasing -MT memcached-memcached.o
-MD -MP -MF .deps/memcached-memcached.Tpo -c -o memcached-memcached.o `test -f ‘memcached.c’ || echo ‘./’`memcached.c

[root@ Sun May 27]# make install
make install-recursive
make[1]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13′
Making install in doc
make[2]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make install-am
make[3]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[4]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[4]: Nothing to be done for `install-exec-am’.
test -z “/usr/local/share/man/man1” || /bin/mkdir -p “/usr/local/share/man/man1”
/usr/bin/install -c -m 644 memcached.1 ‘/usr/local/share/man/man1′
make[4]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[3]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[2]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13/doc’
make[2]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13′
make[3]: Entering directory `/home/ec2-user/memcached/memcached-1.4.13′
test -z “/usr/local/bin” || /bin/mkdir -p “/usr/local/bin”
/usr/bin/install -c memcached ‘/usr/local/bin’
test -z “/usr/local/include/memcached” || /bin/mkdir -p “/usr/local/include/memcached”
/usr/bin/install -c -m 644 protocol_binary.h ‘/usr/local/include/memcached’
make[3]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13′
make[2]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13′
make[1]: Leaving directory `/home/ec2-user/memcached/memcached-1.4.13′
[root@ Sun May 27]#

[root@ Sun May 27]# whereis memcached
memcached: /usr/local/bin/memcached
[root@ Sun May 27]#

基本起動確認

[ec2-user@ Sun May 27]$ /usr/local/bin/memcached -p 11211 -m 10m -vv
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 120 perslab 8738
slab class 3: chunk size 152 perslab 6898
slab class 4: chunk size 192 perslab 5461
slab class 5: chunk size 240 perslab 4369
slab class 6: chunk size 304 perslab 3449
slab class 7: chunk size 384 perslab 2730
slab class 8: chunk size 480 perslab 2184
slab class 9: chunk size 600 perslab 1747
slab class 10: chunk size 752 perslab 1394
slab class 11: chunk size 944 perslab 1110
slab class 12: chunk size 1184 perslab 885
slab class 13: chunk size 1480 perslab 708
slab class 14: chunk size 1856 perslab 564
slab class 15: chunk size 2320 perslab 451
slab class 16: chunk size 2904 perslab 361
slab class 17: chunk size 3632 perslab 288
slab class 18: chunk size 4544 perslab 230
slab class 19: chunk size 5680 perslab 184
slab class 20: chunk size 7104 perslab 147
slab class 21: chunk size 8880 perslab 118
slab class 22: chunk size 11104 perslab 94
slab class 23: chunk size 13880 perslab 75
slab class 24: chunk size 17352 perslab 60
slab class 25: chunk size 21696 perslab 48
slab class 26: chunk size 27120 perslab 38
slab class 27: chunk size 33904 perslab 30
slab class 28: chunk size 42384 perslab 24
slab class 29: chunk size 52984 perslab 19
slab class 30: chunk size 66232 perslab 15
slab class 31: chunk size 82792 perslab 12
slab class 32: chunk size 103496 perslab 10
slab class 33: chunk size 129376 perslab 8
slab class 34: chunk size 161720 perslab 6
slab class 35: chunk size 202152 perslab 5
slab class 36: chunk size 252696 perslab 4
slab class 37: chunk size 315872 perslab 3
slab class 38: chunk size 394840 perslab 2
slab class 39: chunk size 493552 perslab 2
slab class 40: chunk size 616944 perslab 1
slab class 41: chunk size 771184 perslab 1
slab class 42: chunk size 1048576 perslab 1
<26 server listening (auto-negotiate) <27 server listening (auto-negotiate) <28 send buffer was 229376, now 268435456 <29 send buffer was 229376, now 268435456 <28 server listening (udp) <29 server listening (udp)

バックグラウンド起動し動作検証

デーモンとしてバックグラウンド起動
[ec2-user@ Sun May 27]$ /usr/local/bin/memcached -p 11211 -m 10m -d
[ec2-user@ Sun May 27]$ ps -ef | grep mem
ec2-user 18639 1 0 18:04 ? 00:00:00 /usr/local/bin/memcached -p 11211 -m 10m -d
ec2-user 18646 17197 0 18:04 pts/0 00:00:00 grep mem
[ec2-user@ Sun May 27]$

[ec2-user@ Sun May 27]$ /usr/local/bin/memcached -h
memcached 1.4.13
-p TCP port number to listen on (default: 11211)
-U UDP port number to listen on (default: 11211, 0 is off)
-s UNIX socket path to listen on (disables network support)
-a access mask for UNIX socket, in octal (default: 0700)
-l interface to listen on (default: INADDR_ANY, all addresses)
may be specified as host:port. If you don’t specify
a port number, the value you specified with -p or -U is
used. You may specify multiple addresses separated by comma
or by using -l multiple times
-d run as a daemon
-r maximize core file limit
-u assume identity of (only when run as root)
-m max memory to use for items in megabytes (default: 64 MB)
-M return error on memory exhausted (rather than removing items)
-c max simultaneous connections (default: 1024)
-k lock down all paged memory. Note that there is a
limit on how much memory you may lock. Trying to
allocate more than that would fail, so be sure you
set the limit correctly for the user you started
the daemon with (not for -u user;
under sh this is done with ‘ulimit -S -l NUM_KB’).
-v verbose (print errors/warnings while in event loop)
-vv very verbose (also print client commands/reponses)
-vvv extremely verbose (also print internal state transitions)
-h print this help and exit
-i print memcached and libevent license
-P save PID in , only used with -d option
-f chunk size growth factor (default: 1.25)
-n minimum space allocated for key+value+flags (default: 48)
-L Try to use large memory pages (if available). Increasing
the memory page size could reduce the number of TLB misses
and improve the performance. In order to get large pages
from the OS, memcached will allocate the total item-cache
in one large chunk.
-D Use as the delimiter between key prefixes and IDs.
This is used for per-prefix stats reporting. The default is
“:” (colon). If this option is specified, stats collection
is turned on automatically; if not, then it may be turned on
by sending the “stats detail on” command to the server.
-t number of threads to use (default: 4)
-R Maximum number of requests per event, limits the number of
requests process for a given connection to prevent
starvation (default: 20)
-C Disable use of CAS
-b Set the backlog queue limit (default: 1024)
-B Binding protocol – one of ascii, binary, or auto (default)
-I Override the size of each slab page. Adjusts max item size
(default: 1mb, min: 1k, max: 128m)
-o Comma separated list of extended or experimental options
– (EXPERIMENTAL) maxconns_fast: immediately close new
connections if over maxconns limit
– hashpower: An integer multiplier for how large the hash
table should be. Can be grown at runtime if not big enough.
Set this based on “STAT hash_power_level” before a
restart.
[ec2-user@ Sun May 27]$

telnet経由でデータの入力などの基本動作検証

[ec2-user@ Sun May 27]$ telnet localhost 11211
Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
stats
STAT pid 18639
STAT uptime 1139
STAT time 1338110621
STAT version 1.4.13
STAT libevent 1.4.13-stable
STAT pointer_size 64
STAT rusage_user 0.015997
STAT rusage_system 0.015997
STAT curr_connections 10
STAT total_connections 11

set key01 0 0 5
00001
set key02 0 0 5
00002
set key03 0 0 5
00003

memcached

memcached


メモリーテーブルは高速で便利ですが、サイズの制限をしておかないとメモリーを使いすぎて
しまうので、「set global max_heap_table_size = xxxxxx」でメモリーの上限を設定しておく。
反対に作成しようとしているテーブルが大きい場合は大きめに設定しておく。

mysql> select @@global.max_heap_table_size;
+------------------------------+
| @@global.max_heap_table_size |
+------------------------------+
| 16777216 |
+------------------------------+
1 row in set (0.00 sec)

mysql> set GLOBAL max_heap_table_size = 1024 * 1024;
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> select @@global.max_heap_table_size;
+------------------------------+
| @@global.max_heap_table_size |
+------------------------------+
| 1048576 |
+------------------------------+
1 row in set (0.00 sec)

mysql>

max_heap

set globalでの変更は、DBの再起動で設定が消えてしまうので、オプションファイル(my.cnf)に書いておく。

メモ:
その他の動的変数はここ 4.2.4.2. 動的システム変数


メモリーテーブルは、処理が早いので使い方によってはかなり
作業効率をあげてくれるかと思います。

mysql> CREATE TABLE MEM_TABLE (i INT) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)
mysql>

mysql> show table status like 'MEM%'\G
*************************** 1. row ***************************
           Name: MEM_TABLE
         Engine: MEMORY
        Version: 10
     Row_format: Fixed
           Rows: 0
 Avg_row_length: 5
    Data_length: 0
Max_data_length: 10485760
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.01 sec)

mysql> DROP TABLE MEM_TABLE;
Query OK, 0 rows affected (0.00 sec)

memory_tbl

===============================================================
そのニ
===============================================================


mysql> CREATE TABLE MEM ENGINE = MEMORY
    -> select id,comment from T1;
Query OK, 12 rows affected (0.00 sec)
Records: 12  Duplicates: 0  Warnings: 0

mysql> show table status like 'MEM'\G
*************************** 1. row ***************************
           Name: MEM
         Engine: MEMORY
        Version: 10
     Row_format: Fixed
           Rows: 12
 Avg_row_length: 156
    Data_length: 260160
Max_data_length: 16357692
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

mysql>

オリジナルテーブル

mysql> select id,comment from T1;
+----+---------------+
| id | comment       |
+----+---------------+
|  1 | test update   |
|  2 | 22222222222   |
|  3 | test 20090117 |
|  4 | test 20090117 |
|  5 | test 20090117 |
|  6 | test 20090117 |
|  7 | test 20090117 |
|  8 | test 20090117 |
|  9 | test 20090117 |
| 10 | TEST DE SU    |
| 11 | TEST DE SU    |
| 12 | TEST DE SU    |
+----+---------------+
12 rows in set (0.00 sec)

メモリー(HEAP)テーブル

mysql> select * from MEM;
+----+---------------+
| id | comment       |
+----+---------------+
|  1 | test update   |
|  2 | 22222222222   |
|  3 | test 20090117 |
|  4 | test 20090117 |
|  5 | test 20090117 |
|  6 | test 20090117 |
|  7 | test 20090117 |
|  8 | test 20090117 |
|  9 | test 20090117 |
| 10 | TEST DE SU    |
| 11 | TEST DE SU    |
| 12 | TEST DE SU    |
+----+---------------+
12 rows in set (0.00 sec)

mysql>

[root@colinux TEST]# /etc/init.d/mysql.server restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@colinux TEST]#

mysql> show tables;
+----------------+
| Tables_in_TEST |
+----------------+
| MEM            |
| MEM2           |
| MEM3           |
| T1             |
| T2             |
+----------------+
5 rows in set (0.00 sec)

mysql> select * from MEM;
Empty set (0.00 sec)

mysql>

※ 再起動するとメモリーテーブルにデータはありません。
.frmファイルはあるので、テーブルはDROPしない限り再起動しても存在します。

frm_mem

ハッシュインデックスを使用し、処理が非常に高速で、
テンポラリーテーブルを作成するのに大変便利です。
ただし、サーバがクラッシュすると、この MEMORY
テーブルに格納されたすべてのデータが失われます。
テーブル自体は、定義がディスク上に .frm ファイルで
格納されているので引き続き存在しますが、サーバが
再起動したときにはデータは全て失われています。

MEMORY テーブルは、テーブルあたり最大32インデックスまで、
インデックスあたり16列、インデックスの最大幅は500バイトです。
The MEMORY ストレージエンジンは HASHBTREE 両方のインデックスを
使って実行します。ここに記すように USING 節 を追加することに
よりどちらのインデックスであるかを明確にすることが出来ます。

=========================================================
HASH
=========================================================


mysql> CREATE TABLE MEM2
    ->     (id INT, INDEX USING HASH (id))
    ->     ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)

=========================================================
BTREE
=========================================================


mysql> CREATE TABLE MEM3
    ->     (id INT, INDEX USING BTREE (id))
    ->     ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)

mysql>desc MEM;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id      | int(11)     | NO   |     | 0       |       |
| comment | varchar(50) | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> desc MEM2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  | MUL | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> desc MEM3;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  | MUL | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql>

■MEMORY テーブルに、一意でないキーを使用出来ます (ハッシュテーブルにはあまり見られない機能です)。
■MEMORY テーブル上に重複キーをもつハッシュインデックスがある場合(作成されるインデックスは同じ
値を持つことが多い)、 キーの値に影響を与えるテーブルアップデートと、
全ての消去は非常に処理が遅くなります。処理速度がどの程度落ちるかは、
重複の度合いに比例します (或いは、インデックス濃度に反比例します。) 。
BTREE インデックス を使用すれば、この問題は生じません。
■インデックスを張ったカラムが NULL 値を含みます。
■MEMORY テーブルが固定長のレコードフォーマットを使用しています。
■MEMORY テーブルは BLOB や TEXT カラムをサポートしません。
■MEMORY は AUTO_INCREMENT カラムのサポートもしています。
■INSERT DELAYED のスレッドを MEMORY テーブルで使用出来ます。
■MEMORY テーブルは全てのクライアント間で共有されます(他の TEMPORARY と同様。)。
■MEMORY テーブルのデータはメモリ内に格納されますが、MEMORY
テーブルは、クエリ実行中サーバが作成するテンポラリーテーブルとその情報を共有します。
■テンポラリーテーブルのサイズが大きくなりすぎると、サーバは自動的に
テーブル形式を変換してディスクに格納します。最大サイズはシステム変数
tmp_table_size から求められます。
■MEMORY テーブルは決してディスク上のテーブルに変換されないようにします。
誤った操作を行わないために、 max_heap_table_size システム変数をセットして
MEMORY テーブルの最大サイズを設定することが出来ます。
個々のテーブルに関しては、CREATE TABLE ステートメントの中で
MAX_ROWS のオプションを指定することも出来ます。
■サーバには、同時に動作する全ての MEMORY テーブルを維持するための十分なメモリが必要です。
■MEMORY テーブルの不要になったメモリを開放するには、DELETE または TRUNCATE TABLE
を実行するか、DROP TABLEを指定してテーブルをまとめて削除します。
■MySQLサーバ起動時に MEMORY テーブルにデータを投入したい場合は、
–init-file オプションを指定します。例えば、ファイルに
INSERT INTO … SELECT または LOAD DATA INFILE iなどの
ステートメントを使用し、固定データソースからテーブルを取り込むことが出来ます。
■レプリケーションを使用している場合、 シャットダウン、再起動後のマスタサーバの
MEMORY テーブルは空になっています。ところが、スレーブはこれを認識しないため、
そこにある情報は古いものとなってしまいます。マスタ起動後、マスタ上のMEMORY
テーブルを初めて使う際、DELETE ステートメントがマスタのバイナリログに自動的に
書き込まれます。このようにして、スレーブをマスタに再び一致させます。 ここで注意することは、
この方法によっても、マスタ再起動からその後のテーブル使用時までのインターバル中、
スレーブは依然として古いデータを保存し続けているということです。ただし、マスタ起動時
MEMORY テーブルにデータを投入する際 –init-file オプションを使用することにより、
このインターバルタイムはゼロになります。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━MEMORYテーブル上、一行に必要なメモリは以下の表現で算出━━━
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) × 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) × 2)
+ ALIGN(length_of_row+1, sizeof(char*))
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ALIGN() は行の長さを char ポインタサイズのちょうど倍数にするための数式です。
sizeof(char*) は32ビットマシンでは4、64ビットマシンでは8です。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

MEMORY (HEAP) ストレージエンジン

REPLICATION環境での留意点 add on 2015/05/13


root@localhost [test]> show create table T_MEM01\G
*************************** 1. row ***************************
       Table: T_MEM01
Create Table: CREATE TABLE `T_MEM01` (
  `id` int(11) DEFAULT NULL,
  `text` varchar(100) DEFAULT NULL,
  KEY `idx_T_MEM01_id` (`id`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

root@localhost [test]> 

root@localhost [test]> insert into T_MEM01 select * from  T_ONLINE_DDL;
Query OK, 9 rows affected (0.01 sec)
Records: 9  Duplicates: 0  Warnings: 0

root@localhost [test]> select * from T_MEM01;
+------+-----------------+
| id   | text            |
+------+-----------------+
|    1 | Group by Test A |
|    2 | Group by Test A |
|    3 | Group by Test A |
|    4 | Group by Test B |
|    5 | Group by Test B |
|    6 | Group by Test B |
|    7 | Group by Test C |
|    8 | Group by Test C |
|    9 | Group by Test C |
+------+-----------------+
9 rows in set (0.00 sec)

root@localhost [test]> 

root@localhost [test]> explain select * from T_MEM01 where id = 8;
+----+-------------+---------+------+----------------+----------------+---------+-------+------+-------+
| id | select_type | table   | type | possible_keys  | key            | key_len | ref   | rows | Extra |
+----+-------------+---------+------+----------------+----------------+---------+-------+------+-------+
|  1 | SIMPLE      | T_MEM01 | ref  | idx_T_MEM01_id | idx_T_MEM01_id | 5       | const |    2 | NULL  |
+----+-------------+---------+------+----------------+----------------+---------+-------+------+-------+
1 row in set (0.00 sec)

root@localhost [test]> 

再起動してみる

[admin@GA01 ~]$ sudo -s
[sudo] password for admin: 
[root@GA01 admin]# /etc/init.d/mysql.server restart
Shutting down MySQL... SUCCESS! 
Starting MySQL. SUCCESS! 
[root@GA01 admin]# exit


[admin@GA01 ~]$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.24-enterprise-commercial-advanced-log MySQL Enterprise Server - Advanced Edition (Commercial)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

root@localhost [(none)]> use test
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
root@localhost [test]> select * from T_MEM01;
Empty set (0.00 sec)

root@localhost [test]> show create table T_MEM01\G
*************************** 1. row ***************************
       Table: T_MEM01
Create Table: CREATE TABLE `T_MEM01` (
  `id` int(11) DEFAULT NULL,
  `text` varchar(100) DEFAULT NULL,
  KEY `idx_T_MEM01_id` (`id`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

root@localhost [test]> 

※ Masterは再起動してデータは無いが、Slaveには残っているので注意!!
※ レプリケーション環境で利用する場合はレプリケーション対象外にする方法もある。
その他、17.4.1.21 Replication and MEMORY Tablesに色々と留意点が載っているので要確認。

補足: 
MEMORYテーブル以外には、TEMPORARY TABLEを利用する方法もあります。
MYSQL: Create Temporary Table with Index and SELECT
http://stackoverflow.com/questions/14397785/mysql-create-temporary-table-with-index-and-select