2014/01/31

DB トランザクション分離レベル

・MultiVersion Concurrency Control
データベース管理システムの可用性を向上させる制御技術のひとつ。複数のユーザから同時に処理要求が行われた場合でも同時並行性を失わずに処理し、かつ情報の一貫性を保証する仕組みが提供される。

MVCCは、書き込み処理(トランザクション)が行われている最中に他のユーザによる読み取りアクセスがあった場合、書き込みの直前の状態(スナップショット)を処理結果として返す。つまり、書き込み中も読み取りができ、読み取り中でも書き込みができる。

MVCCにおいて可用性を達成するには、最低限、全ての処理が「どの順番で」行われたかを確実に記録する必要がある。そのため、タイムスタンプやトランザクションIDなどを用いて全ての更新処理が管理される。

★トランザクション分離レベル

あるデータに対する読み書きの処理を行う場合、わずかでも処理時間が発生する。処理が「複数同時に並行して」実行されようとした場合、感覚的にはどちらかの処理が先に行われ、残ったほうの処理が後に行われるであろう。この場合、後に行われた処理は先に行われた処理が完了するまでの間「待ち」の状態になってしまう。

データベース管理システムはこれらの「待ち」の状態を可能な限り防ぐため、複数の処理を並列で行っている間でもその他の処理を受け付けられる制御方法が確立された。このとき、1つのトランザクション処理が他の処理からどれだけ独立して行われるかが焦点になる、すなわち、「待ち時間を減らすためどれだけデータの一貫性を犠牲にして良いか」を定めたものが、トランザクション分離レベルである。


    SERIALIZABLE ( 直列化可能 )

    複数の並行に動作するトランザクションそれぞれの結果が、いかなる場合でも、それらのトランザクションを時間的重なりなく逐次実行した場合と同じ結果となる.このような性質を直列化可能性(Serializability)と呼ぶ.SERIALIZABLEは最も強い分離レベルであり、最も安全にデータを操作できるが、相対的に性能は低い。ただし同じ結果とされる逐次実行の順はトランザクション処理のレベルでは保証されない。
   
    REPEATABLE READ ( 読み取り対象のデータを常に読み取る )

    ひとつのトランザクションが実行中の間、読み取り対象のデータが途中で他のトランザクションによって変更される心配はない。同じトランザクション中では同じデータは何度読み取りしても毎回同じ値を読むことができる。
    ただし ファントム・リード(Phantom Read) と呼ばれる現象が発生する可能性がある。ファントム・リードでは、並行して動作する他のトランザクションが追加したり削除したデータが途中で見えてしまうため、処理の結果が変わってしまう。
   
    READ COMMITTED ( 確定した最新データを常に読み取る )
    他のトランザクションによる更新については、常にコミット済みのデータのみを読み取る。 MVCC はREAD COMMITTEDを実現する実装の一つである。
    ファントム・リード に加え、非再現リード(Non-Repeatable Read)と呼ばれる、同じトランザクション中でも同じデータを読み込むたびに値が変わってしまう現象が発生する可能性がある。
   
    READ UNCOMMITTED ( 確定していないデータまで読み取る )
   
    他の処理によって行われている、書きかけのデータまで読み取る。
    PHANTOM 、 NON-REPEATABLE READ 、さらに ダーティ・リード(Dirty Read) と呼ばれる現象(不完全なデータや、計算途中のデータを読み取ってしまう動作)が発生する。トランザクションの並行動作によってデータを破壊する可能性は
    高いが、その分性能は高い。

ssh tunnel - bind: Cannot assign requested address

★ssh -v を付けて、デバッグ情報:
OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *

....

debug1: Authentication succeeded (password).
debug1: Local connections to LOCALHOST:1080 forwarded to remote address socks:0
debug1: Local forwarding listening on 127.0.0.1 port 1080.
debug1: channel 0: new [port listener]
debug1: Local forwarding listening on ::1 port 1080.
bind: Cannot assign requested address
debug1: channel 1: new [client-session]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.utf8

★Answer
The close the loop here. The answer, in this case, was to force the ssh client to use ipv4. E.g.
ssh -4 -D 8081 user@8.8.8.8

2014/01/24

mysql日志设置优化

前言

在安装完MySQL之后,肯定是需要对MySQL的各种参数选项进行一些优化调整的。虽然MySQL系统的伸缩性很强,既可以在有很充足的硬件资源 环境下高效的运行,也可以在极少资源环境下很好的运行,但不管怎样,尽可能充足的硬件资源对MySQL的性能提升总是有帮助的。在这一节我们主要分析一下 MySQL的日志(主要是Binlog)对系统性能的影响,并根据日志的相关特性得出相应的优化思路。

日志产生的性能影响

由于日志的记录带来的直接性能损耗就是数据库系统中最为昂贵的IO资源。
在之前介绍MySQL物理架构的章节中,我们已经了解到了MySQL的日志包括错误日志(ErrorLog),更新日志(UpdateLog),二 进制日志(Binlog),查询日志(QueryLog),慢查询日志(SlowQueryLog)等。当然,更新日志是老版本的MySQL才有的,目前 已经被二进制日志替代。
在默认情况下,系统仅仅打开错误日志,关闭了其他所有日志,以达到尽可能减少IO损耗提高系统性能的目的。但是在一般稍微重要一点的实际应用场景 中,都至少需要打开二进制日志,因为这是MySQL很多存储引擎进行增量备份的基础,也是MySQL实现复制的基本条件。有时候为了进一步的性能优化,定 位执行较慢的SQL语句,很多系统也会打开慢查询日志来记录执行时间超过特定数值(由我们自行设置)的SQL语句。
一般情况下,在生产系统中很少有系统会打开查询日志。因为查询日志打开之后会将MySQL中执行的每一条Query都记录到日志中,会该系统带来比 较大的IO负担,而带来的实际效益却并不是非常大。一般只有在开发测试环境中,为了定位某些功能具体使用了哪些SQL语句的时候,才会在短时间段内打开该 日志来做相应的分析。所以,在MySQL系统中,会对性能产生影响的MySQL日志(不包括各存储引擎自己的日志)主要就是Binlog了。

Binlog 相关参数及优化策略

我们首先看看Binlog的相关参数,通过执行如下命令可以获得关于Binlog的相关参数。当然,其中也显示出了“innodb_locks_unsafe_for_binlog”这个Innodb存储引擎特有的与Binlog相关的参数:
mysql> show variables like '%binlog%'; 
+--------------------------------+------------+ | Variable_name | Value | +--------------------------------+------------+ 
| binlog_cache_size | 1048576 | 
| innodb_locks_unsafe_for_binlog | OFF |
| max_binlog_cache_size| 4294967295 |
| max_binlog_size| 1073741824 |
| sync_binlog| 0|
+--------------------------------+------------+

“binlog_cache_size":在事务过程中容纳二进制日志SQL语句的缓存大小。二进制日志缓存是服务器支持事务存储引擎并且服务器启 用了二进制日志(—log-bin选项)的前提下为每个客户端分配的内存,注意,是每个Client都可以分配设置大小的binlogcache空间。如 果读者朋友的系统中经常会出现多语句事务的华,可以尝试增加该值的大小,以获得更有的性能。当然,我们可以通过MySQL的以下两个状态变量来判断当前的 binlog_cache_size的状况:Binlog_cache_use和Binlog_cache_disk_use。
“max_binlog_cache_size”:和"binlog_cache_size"相对应,但是所代表的是binlog能够使用的最大 cache内存大小。当我们执行多语句事务的时候,max_binlog_cache_size如果不够大的话,系统可能会报出“Multi- statementtransactionrequiredmorethan'max_binlog_cache_size'bytesofstorage” 的错误。
“max_binlog_size”:Binlog日志最大值,一般来说设置为512M或者1G,但不能超过1G。该大小并不能非常严格控制 Binlog大小,尤其是当到达Binlog比较靠近尾部而又遇到一个较大事务的时候,系统为了保证事务的完整性,不可能做切换日志的动作,只能将该事务 的所有SQL都记录进入当前日志,直到该事务结束。这一点和Oracle的Redo日志有点不一样,因为Oracle的Redo日志所记录的是数据文件的 物理位置的变化,而且里面同时记录了Redo和Undo相关的信息,所以同一个事务是否在一个日志中对Oracle来说并不关键。而MySQL在 Binlog中所记录的是数据库逻辑变化信息,MySQL称之为Event,实际上就是带来数据库变化的DML之类的Query语句。
sync_binlog”:这个参数是对于MySQL系统来说是至关重要的,他不仅影响到Binlog对MySQL所带来的性能损耗,而且还影响到MySQL中数据的完整性。对于“sync_binlog”参数的各种设置的说明如下:
sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。
sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。
在MySQL中系统默认的设置是sync_binlog=0, 也就是不做任何强制性的磁盘刷新指令,这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有 binlog信息都会被丢失。而当设置为“1”的时候,是最安全但是性能损耗最大的设置。因为当设置为1的时候,即使系统Crash,也最多丢失 binlog_cache中未完成的一个事务,对实际数据没有任何实质性影响。从以往经验和相关测试来看,对于高并发事务的系统来说,“sync_binlog”设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。

大家都知道,MySQL的复制(Replication),实际上就是通过将Master端的Binlog通过利用IO线程通过网络复制到 Slave端,然后再通过SQL线程解析Binlog中的日志再应用到数据库中来实现的。所以,Binlog量的大小对IO线程以及Msater和 Slave端之间的网络都会产生直接的影响。
MySQL中Binlog的产生量是没办法改变的,只要我们的Query改变了数据库中的数据,那么就必须将该Query所对应的Event记录到 Binlog中。那我们是不是就没有办法优化复制了呢?当然不是,在MySQL复制环境中,实际上是是有8个参数可以让我们控制需要复制或者需要忽略而不 进行复制的DB或者Table的,分别为:
Binlog_Do_DB:设定哪些数据库(Schema)需要记录Binlog;
Binlog_Ignore_DB:设定哪些数据库(Schema)不要记录Binlog;
Replicate_Do_DB:设定需要复制的数据库(Schema),多个DB用逗号(“,”)分隔;
Replicate_Ignore_DB:设定可以忽略的数据库(Schema);
Replicate_Do_Table:设定需要复制的Table;
Replicate_Ignore_Table:设定可以忽略的Table;
Replicate_Wild_Do_Table:功能同Replicate_Do_Table,但可以带通配符来进行设置;
Replicate_Wild_Ignore_Table:功能同Replicate_Ignore_Table,可带通配符设置;

通过上面这八个参数,我们就可以非常方便按照实际需求,控制从Master端到Slave端的Binlog量尽可能的少,从而减小Master端到 Slave端的网络流量,减少IO线程的IO量,还能减少SQL线程的解析与应用SQL的数量,最终达到改善Slave上的数据延时问题。
实际上,上面这八个参数中的前面两个是设置在Master端的,而后面六个参数则是设置在Slave端的。虽然前面两个参数和后面六个参数在功能上 并没有非常直接的关系,但是对于优化MySQL的Replication来说都可以启到相似的功能。当然也有一定的区别,其主要区别如下:
如果在Master端设置前面两个参数,不仅仅会让Master端的Binlog记录所带来的IO量减少,还会让Master端的IO线程就可以减 少Binlog的读取量,传递给Slave端的IO线程的Binlog量自然就会较少。这样做的好处是可以减少网络IO,减少Slave端IO线程的IO 量,减少Slave端的SQL线程的工作量,从而最大幅度的优化复制性能。当然,在Master端设置也存在一定的弊端,因为MySQL的判断是否需要复 制某个Event不是根据产生该Event的Query所更改的数据

所在的DB,而是根据执行Query时刻所在的默认Schema,也就是我们登录时候指定的DB或者运行“USEDATABASE”中所指定的 DB。只有当前默认DB和配置中所设定的DB完全吻合的时候IO线程才会将该Event读取给Slave的IO线程。所以如果在系统中出现在默认DB和设 定需要复制的DB不一样的情况下改变了需要复制的DB中某个Table的数据的时候,该Event是不会被复制到Slave中去的,这样就会造成 Slave端的数据和Master的数据不一致的情况出现。同样,如果在默认Schema下更改了不需要复制的Schema中的数据,则会被复制到 Slave端,当Slave端并没有该Schema的时候,则会造成复制出错而停止。
而如果是在Slave端设置后面的六个参数,在性能优化方面可能比在Master端要稍微逊色一点,因为不管是需要还是不需要复制的Event都被 会被IO线程读取到Slave端,这样不仅仅增加了网络IO量,也给Slave端的IO线程增加了RelayLog的写入量。但是仍然可以减少Slave 的SQL线程在Slave端的日志应用量。虽然性能方面稍有逊色,但是在Slave端设置复制过滤机制,可以保证不会出现因为默认Schema的问题而造 成Slave和Master数据不一致或者复制出错的问题。

Slow Query Log 相关参数及使用建议

再来看看SlowQueryLog的相关参数配置。有些时候,我们为了定位系统中效率比较地下的Query语句,则需要打开慢查询日志,也就是SlowQueryLog。我们可以如下查看系统慢查询日志的相关设置:
mysql> show variables like 'log_slow%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| log_slow_queries | ON |
+------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like 'long_query%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| long_query_time | 1 |
+-----------------+-------+
1 row in set (0.01 sec)

“log_slow_queries”参数显示了系统是否已经打开SlowQueryLog功能,而“long_query_time”参数则告诉 我们当前系统设置的SlowQuery记录执行时间超过多长的Query。在MySQLAB发行的MySQL版本中SlowQueryLog可以设置的最 短慢查询时间为1秒,这在有些时候可能没办法完全满足我们的要求,如果希望能够进一步缩短慢查询的时间限制,可以使用Percona提供的 microslow-patch(件成为mslPatch)来突破该限制。mslpatch不仅仅能将慢查询时间减小到毫秒级别,同时还能通过一些特定的 规则来过滤记录的SQL,如仅记录涉及到某个表的SlowQuery等等附加功能。考虑到篇幅问题,这里就不介绍mslpatch给我们带来的更为详细的 功能和使用,大家请参考官方介绍(http://www.mysqlperformanceblog.com/2008/04/20/updated- msl-microslow-patch-installation-walk-through/)
打开SlowQueryLog功能对系统性能的整体影响没有Binlog那么大,毕竟SlowQueryLog的数据量比较小,带来的IO损耗也就 较小,但是,系统需要计算每一条Query的执行时间,所以消耗总是会有一些的,主要是CPU方面的消耗。如果大家的系统在CPU资源足够丰富的时候,可 以不必在乎这一点点损耗,毕竟他可能会给我们带来更大性能优化的收获。但如果我们的CPU资源也比较紧张的时候,也完全可以在大部分时候关闭该功能,而只 需要间断性的打开SlowQueryLog功能来定位可能存在的慢查询。
MySQL的其他日志由于使用很少(QueryLog)或者性能影响很少,我们就不在此过多分析了,至于各个存储引擎相关的日志,我们留在后面“常用存储引擎优化”部分再做相应的分析。

转自 《MySQL性能调优与架构设计》

MySQL的innodb_flush_log_at_trx_commit配置值的设定

我发现同事在项目做压力测试的时候,误解了innodb_flush_log_at_trx_commit的含义,认为配置为0是不写日志,所以性能高。

配置项说明

0
如 果innodb_flush_log_at_trx_commit的值为0,log buffer每秒就会被刷写日志文件到磁盘,提交事务的时候不做任何操作。(执行是由mysql的master thread线程来执行的。主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件(REDO LOG)中。不论事务是否已经提交。)默认的日志文件是ib_logfile0,ib_logfile1

1

当设为默认值1的时候,每次提交事务的时候,都会将log buffer刷写到日志。

2

如果设为2,每次提交事务都会写日志,但并不会执行刷的操作。每秒定时会刷到日志文件。要注意的是,并不能保证100%每秒一定都会刷到磁盘,这要取决于进程的调度。每次事务提交的时候将数据写入事务日志,而这里的写入仅是调用了文件系统的写入操作,而文件系统是有 缓存的,所以这个写入并不能保证数据已经写入到物理磁盘
默认值1是为了保证完整的ACID。 当然,你可以将这个配置项设为1以外的值来换取更高的性能,但是在系统崩溃的时候,你将会丢失1秒的数据。设为0的话,mysqld进程崩溃的时候,就会 丢失最后1秒的事务。设为2,只有在操作系统崩溃或者断电的时候才会丢失最后1秒的数据。InnoDB在做恢复的时候会忽略这个值。

刷写的概念

刷 写其实是两个操作,刷(flush)和写(write),区分这两个概念(两个系统调用)是很重要的。在大多数的操作系统中,把Innodb的log buffer(内存)写入日志(调用系统调用write),只是简单的把数据移到操作系统缓存中,操作系统缓存同样指的是内存。并没有实际的持久化数据。
所以,通常设为0和2的时候,在崩溃或断电的时候会丢失最后一秒的数据,因为这个时候数据只是存在于操作系统缓存。之所以说“通常”,可能会有丢失不只1秒的数据的情况,比如说执行flush操作的时候阻塞了。

总结

设为1当然是最安全的,但性能页是最差的(相对其他两个参数而言,但不是不能接受)。如果对数据一致性和完整性要求不高,完全可以设为2,如果只最求性能,例如高并发写的日志服务器,设为0来获得更高性能

mysql: logs-slave-updates

--logs-slave-updates
通常情况,从服务器从主服务器接收到的更新不记入它的二进制日志。该选项告诉从服务器将其SQL线程执行的更新记入到从服务器自己的二进制日志。为 了使该选项生效,还必须用--logs-bin选项启动从服务器以启用二进制日志。如果想要应用链式复制服务器,应使用--logs-slave- updates。例如,可能你想要这样设置:
A -> B -> C

也就是说,A为从服务器B的主服务器,B为从服务器C的主服务器。为了能工作,B必须既为主服务器又为从服务器。你必须用--logs-bin启动A和B以启用二进制日志,并且用--logs-slave-updates选项启动B。

以上是摘自mysql对于logs-slave-updates启动选项的描述。
当然logs-slave-upates也可以写入my.cnf :
//////////////////
log_slave_updates=1
//////////////////
当然在这种机制下可能有的同学会存在这么个问题:
如果a->b b->a 这样的双master架构下,a,b都打开log_slave_updates选项会不会出现无限循环的状态。
mysql已经考滤到了这个问题,每条bin-log都会记录执行语句的源server_id.当slave读到语句的server_id等于本身的ID的时候,不会忽略执行,所以我们不用担心a,b会不会无限循环下去。

基于以上这种情况,mysql的replication集群将更加灵活,你如果需要可以做成各种各样的链式复制。比如 a->b b->a b中设置log_slave_updates后还可以b->c. 这样a,c中的数据也是一致的。


在双A的情况下,如果log-slave-updates = 1 ,replicate-save-server-id = 1 ,那势必会造成循环复制sql。
“当然在这种机制下可能有的同学会存在这么个问题:
如果a->b b->a 这样的双master架构下,a,b都打开log_slave_updates选项会不会出现无限循环的状态。
mysql已经考滤到了这个问题,每条bin-log都会记录执行语句的源server_id.当slave读到语句的server_id等于本身的ID的时候,不会忽略执行,所以我们不用担心a,b会不会无限循环下去。”
以上问题只是因为replicate-same-server-id 默认值为0

2014/01/23

Mysql索引覆盖covered index

什么是索引覆盖

就是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。
那么显然select * from ...是一种拙劣的查询,除非你建立了包含所有列的索引(这样建索引脑子进水)。

对 于索引覆盖查询(index-covered query),使用EXPLAIN时,可以在Extra一列中看到“Using index”。

使用索引覆盖

如果你想要通过索引覆盖select多列,那么需要给需要的列建立一个多列索引,当然如果带查询条件,where条件要求满足最左前缀原则。
Innodb的辅助索引叶子节点包含的是主键列,所以主键一定是被索引覆盖的。

(1)例如,在sakila的inventory表中,有一个组合索引(store_id,film_id),对于只需要访问这两列的查 询,MySQL就可以使用索引,如下:
mysql> EXPLAIN SELECT store_id, film_id FROM sakila.inventory\G
*************************** 1. row ***************************
        id: 1
select_type: SIMPLE
        table: inventory
        type: index
possible_keys: NULL
        key: idx_store_id_film_id
        key_len: 3
        ref: NULL
      rows: 5007
      Extra: Using index
1 row in set (0.17 sec)

(2)再比如说在文章系统里分页显示的时候,一般的查询是这样的(转):
SELECT id, title, content FROM article ORDER BY created DESC LIMIT 10000, 10;
通常这样的查询会把索引建在created字段(其中id是主键),不过当LIMIT偏移很大时,查询效率仍然很低,改变一下查询:
SELECT id, title, content FROM article
INNER JOIN (
    SELECT id FROM article ORDER BY created DESC LIMIT 10000, 10
) AS page USING(id)
此时,建立复合索引"created, id"【只要建立created索引就可以吧,Innodb是会在辅助索引里面存储主键值的】,就可以在子查询里利用上Covering Index,快速定位id,查询效率嗷嗷的

mysql innodb 詳細

知识点一:在5.1中,innodb存储引擎的默认的行格式为compact(redundant为兼容以前的版本),对于 blob,text,varchar(8099)这样的大字段,innodb只会存放前768字节在数据页中,而剩余的数据则会存储在溢出段中(发生溢出 情况的时候适用);

知识点二:innodb的块大小默认为16kb,由于innodb存储引擎表为索引组织表,树底层的叶子节点为一双向链表,因此每个页中至少应该有两行记录,这就决定了innodb在存储一行数据的时候不能够超过8k(8098字节);

知识点三:使用了blob数据类型,是不是一定就会存放在溢出段中?通常我们认为blob,clob这类的大对象的存储会把数据存放在数据页之外, 其实不然,关键点还是要看一个page中到底能否存放两行数据,blob可以完全存放在数据页中(单行长度没有超过8098字节),而varchar类型 的也有可能存放在溢出页中(单行长度超过8098字节,前768字节存放在数据页中);

知识点四:5.1中的innodb_plugin引入了新的文件格式:barracuda(将compact和redundant合称为 antelope),该文件格式拥有新的两种行格式:compressed和dynamic,两种格式对blob字段采用完全溢出的方式,数据页中只存放 20字节,其余的都存放在溢出段中:


我们使用show table status来查看表的相关信息:
可以看到,平均一行大约1.5K,也就说大约1/10行会使用“溢出存储”,一旦采用了这种方式存储,返回数据的时候本来是顺序读取的数据,就变成了随机读取了,所以导致性能急剧下降。

另 外,在测试过程中还发现,无论这条语句执行多少次,甚至将整个表select *几次,语句的执行速度都没有明显变化。这个表的数据和索引加起来才150M左右,而整个Innodb buffer pool有5G,缓存整张表绰绰有余,如果缓存了溢出页,性能应该大幅提高才对。
但实测结果却并没有提高,因此从这个测试可以推论Innodb并没有将溢出页(overflow page)缓存到内存里面
这样的设计也是符合逻辑的,因为overflow page本来就是存放大数据的,如果也放在缓存里面,就会出现一次大数据列(blob、text、varchar)查询,可能就将所有的缓存都更新了,这样会导致其它普通的查询性能急剧下降。

mysql table engine 確認

user information_schema;
show tables;
中に名前は「tables」のがある。

describe tables;
select Table_name,engine,table_schema from tables where engine='MyISAM';
  iNnoDB
  NULL---->なになにViewだよね。。
  ーーーーーーーーーーーーー

2014/01/22

レース・コンディション race condition

複数のプロセスが共有リソースに対して何かを行う場合,プロセスの実行順序に依存して結果が異なる状況をレース・コンディションと呼ぶ。デッド・ロックや レース・コンディションの可能性を検出するためのツールも提供されている。レース・コンディションを悪用する攻撃プログラムも存在する。例え ば,util-linux packageのsetpwnam.cが/etc/passwdファイルに変更を加えるときに使用するテンポラリ・ファイルを不適当にロックする。これを 突いてシステム上の特権を上げるためのレース・コンディションを誘発する問題が発見された。


-->いわゆるマジックだね。。。(千変万化の実行結果)

2014/01/20

tomcat app class ロード順

決まり事である。
ーーーーー>
クラスやリソースのロードの際のリポジトリのチェックは、 Webアプリケーションから見ると以下の順序になります。
  • JVM のブートストラップクラス
  • System クラスローダの各クラス (上述)
  • Webアプリケーションの /WEB-INF/classes
  • Webアプリケーションの /WEB-INF/lib/*.jar
  • $CATALINA_HOME/common/classes
  • $CATALINA_HOME/common/endorsed/*.jar
  • $CATALINA_HOME/common/lib/*.jar
  • $CATALINA_HOME/shared/classes
  • $CATALINA_HOME/shared/lib/*.jar

mysql slow qurey

  • Q:mysql slow qurey :
    sending Data->Page_faults_minor:8 のせいで検索は時間かかるみたい。。。
    Page_faults_minorを発生させないためには?(to edit mysql caching parameter?
     
    A: tmpTableSize,openFile,openTable,tableCache辺の設定かな。。確認する
     
     

2014/01/17

mysql SlowLog  見方 slow sql 分析


# Time: 040624  1:25:24 
# User@Host: [ODBC] @ localhost [127.0.0.1]
# Query_time: 5  Lock_time: 0  Rows_sent: 30670  Rows_examined: 38828
select * from city 、country 、language where country.code=city.country
 and city.country=language.country;
1行目 記録日時
 2行目 ユーザーIDとリクエストした端末
 3行目 Query_time(実行時間) Lock_time(ロック時間) Rows_sent(送信行数) Rows_examined(処理対象となった行数)
 4行目 SQL文

・queries that do not use indexes for lookups are not logged
 if you want log_queries_not_using_indexes,
・change log file :  Set slow_query_log_file 


mysql explain
mysql> explain select * from city \G;
*************************** 1. row ***************************
        table: city               対象テーブル名
         type: ALL                テーブル内のすべてのレコードを処理対処とする
possible_keys: NULL               使用可能なインデックスを表す
          key: NULL               実際に使用したインデックスを表す
      key_len: NULL               実際に使用したインデックス長を表す
          ref: NULL               行の特定方法を表す
         rows: 4079               結果として返したレコード数を表す
        Extra:                    クエリーに関する追加情報を表す
1 row in set (0.00 sec)
EXPLAINコマンドはどのようにクエリを書き換えればいいかについては何も教えてくれない
そのSQLはどこで時間を掛かった?
ぜんぜんわからない。
 EXPLAIN SELECT でどんな風に検索されているか確認だけかな。。。。。
★TYPE
Const     一意にレコードを選択できる(UNIQUE や PRIMARY KEYを使用)
eq_ref     複数のテーブルごとに一意にレコードを選択できる
ref     インデックスを使用してレコードを選択できる(UNIQUE や PRIMARY KEYではないインデックス)
range     インデックスを使用して範囲に該当するレコードを選択できる
ALL     テーブル内の全てのレコードを検査する



mysql> show table status like 'city' \G;
*************************** 1. row ***************************
           Name: city                    テーブル名
           Type: MyISAM                  テーブル・タイプ
     Row_format: Fixed                   レコードの長さを表す
           Rows: 4079                    格納されている行数
 Avg_row_length: 67                      平均レコード長
    Data_length: 273293                  使用容量
Max_data_length: 287762808831            最大レコード数(最大格納容量)
   Index_length: 83968                   インデックス・ファイル容量
      Data_free: 0                       開放可能な容量
 Auto_increment: 4080                    次に使用する連番
    Create_time: 2004-06-23 22:56:37     テーブル作成日時
    Update_time: 2004-06-23 22:56:38     テーブル更新日時
     Check_time: 2004-06-23 22:56:38     テーブル検査日時
 Create_options:                         テーブル作成時のオプション
        Comment:                         コメント
1 row in set (0.00 sec)
ーーーーーーーーーーーーー


・そのSQLはどこで時間を掛かった?
set profiling=1;
 sqlを実行する
 SHOW PROFILE;
 
 mysql> SHOW PROFILE;
+---------------------------+----------+
| Status                    | Duration |
+---------------------------+----------+
| starting                  | 0.000089 |
| Opening tables            | 0.000237 |
| System lock               | 0.000005 |
| Table lock                | 0.000009 |
| init                      | 0.000009 |
| optimizing                | 0.000005 |
| statistics                | 0.000009 |
| preparing                 | 0.000009 |
| executing                 | 0.001803 |
| converting HEAP to MyISAM | 0.003110 |
| executing                 | 0.982382 |
| Sending data              | 0.031821 |
| end                       | 0.000017 |
| query end                 | 0.000006 |
| freeing items             | 0.000080 |
| removing tmp table        | 0.020215 |
| closing tables            | 0.000021 |
| logging slow query        | 0.000007 |
| cleaning up               | 0.000009 |
+---------------------------+----------+
19 rows in set (0.00 sec)

 SHOW PROFILEは、デフォルトではStatusとDurationを表示する。StatusはSHOW PROCESSLISTで表示されるステータスと同じだ。Durationは経過時間である。つまり、どの段階の処理にどのぐらい時間がかかったのかが一目で分かるのである
 
オプション: 
    ALL・・・すべての情報を表示。
    BLOCK IO・・・ディスクへのBlock I/Oの回数。
    CONTEXT SWITCHES・・・コンテキストスイッチの回数。
    CPU・・・CPUの使用時間。(システム、ユーザの内訳など。)
    IPC・・・メッセージ送受信。
    MEMORY・・・未実装。(これは待望の機能である!!)
    PAGE FAULTS・・・ページフォルト回数。
    SWAPS・・・スワップアウトの回数。


ysql> SHOW PROFILES;
+----------+------------+-------------------------------+
| Query_ID | Duration   | Query                         |
+----------+------------+-------------------------------+
|        1 | 1.03984300 | SHOW LOCAL STATUS             |
|        2 | 0.69961500 | SHOW GLOBAL STATUS            |
|        3 | 0.00078000 | SHOW DATABASES                |
|        4 | 0.00022000 | SELECT DATABASE()             |
|        5 | 0.00059500 | show databases                |
|        6 | 0.54332000 | show tables                   |
|        7 | 0.00092800 | SHOW TABLES                   |
|        8 | 0.00031400 | SELECT * FROM ptest LIMIT 100 |
+----------+------------+-------------------------------+
8 rows in set (0.00 sec)

特定のクエリの情報を見たい場合には次のコマンドを実行する。
profiling_history_sizeのデフォルト値は15、最大値は100

1
mysql> SHOW PROFILE SOURCE FOR QUERY 1;

select count(userinfovi0_.user_id) as col_0_0_ from userinfo_view userinfovi0_ limit 2;
ーーーー>
*************************** 11. row ***************************
             Status: Sending data
           Duration: 0.670087       Sending dataは一番時間掛かった。
           CPU_user: 2.424631
         CPU_system: 0.378942
  Context_voluntary: 9806
Context_involuntary: 182
       Block_ops_in: 0
      Block_ops_out: 4168
      Messages_sent: 0
  Messages_received: 0
  Page_faults_major: 0
  Page_faults_minor: 8
              Swaps: 0
    Source_function: exec
        Source_file: sql_executor.cc
        Source_line: 187
ーーーーーーー>       
Sending dataは、読み込みと絞りこみに掛かってる時間       
This is quite a misleading status. It should be called "reading and filtering data".
This means that MySQL has some data stored on the disk (or in memory) which is yet to be read and sent over. It may be the table itself, an index, a temporary table, a sorted output etc
この辺でMySQLのファイルが上手くキャッシュメモリに乗っていないのではないか? という疑惑が
MySQLのtable_cacheは、テーブルそのもののキャッシュではなく、テーブルに必要なファイルのハンドラをキャッシュする領域
テーブルそのもののキャッシュと勘違い

Page_faults_major: 0ーー>メモリー上はない、コスト高い
Page_faults_minor: 8ーー>メモリー上はある。登録されいていない。

数据跨页,IO 大,explain显示下查询计划,还有表结构     
ページフォールト (page fault) とは、プログラムが物理メモリがマップされていない仮想アドレス空間上のページにアクセスしたときにハードウェアが発生する割り込み(または例外)である
ーーー>DISKに取りに行くのこと


2014/01/16

Mysql的锁机制解读 lock ロック 

从基本概念开始:
共享锁
共享锁的代号是S,是Share的缩写,共享锁的锁粒度是行或者元组(多个行)。一个事务获取了共享锁之后,可以对锁定范围内的数据执行读操作。

排它锁
排它锁的代号是X,是eXclusive的缩写,排它锁的粒度与共享锁相同,也是行或者元组。一个事务获取了排它锁之后,可以对锁定范围内的数据执行写操作。

假设有两个事务t1和t2
如果事务t1获取了一个元组的共享锁,事务t2还可以立即获取这个元组的共享锁,但不能立即获取这个元组的排它锁(必须等到t1释放共享锁之后)。
如果事务t1获取了一个元组的排它锁,事务t2不能立即获取这个元组的排共享锁,也不能立即获取这个元组的排它锁(必须等到t1释放排它锁之后)。

意向锁
意 向锁是一种表锁,锁定的粒度是整张表,分为意向共享锁(IS)和意向排它锁(IX)两类。意向共享锁表示一个事务有意对数据上共享锁或者排它锁。“有意” 这两个字表达的意思比较微妙,说的明白点就是指事务想干这个事但还没真去干。举例说明下意向共享锁,比如一个事务t执行了这样一个语句:select * from table lock in share model ,如果这个语句执行成功,就对表table上了一个意向共享锁。lock in share model就是说事务t1在接下来要执行的语句中要获取S锁。如果t1的select * from table lock in share model执行成功,那么接下来t1应该可以畅通无阻的去执行只需要共享锁的语句了。意向排它锁的含义同理可知,上例中要获取意向排它锁,可以使用select * from table for update

lock in share model 和 for update这两个东西在数据率理论中还有个学名叫悲观锁,与悲观锁相对的当然还有乐观锁。大家可以看到各种锁都是成双成对出现的。关于悲观锁和乐观锁的问题暂且不表,下文再来详述。

锁的互斥与兼容关系
锁和锁之间的关系,要么是相容的,要么是互斥的。
锁a和锁b相容是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2还可以获取锁b;
锁a和锁b互斥是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2在t1释放锁a之前无法获取锁b。

上面提到的共享锁、排它锁、意向共享锁、意向排它锁相互之前都是有兼容/互斥关系的,可以用一个兼容性矩阵表示(y表示兼容,n表示不兼容):
    X    S    IX    IS
X  n     n    n     n
S  n     y    n     y
IX n     n    y     y
IS n     y    y     y 

兼容性矩阵为什么是这个样子的?
X和S的相互关系在上文中解释过了,IX和IS的相互关系全部是兼容,这也很好理解,因为它们都只是“有意”,还处于YY阶段,没有真干,所以是可以兼容的;
剩下的就是X和IX,X和IS, S和IX, S和IS的关系了,我们可以由X和S的关系推导出这四组关系。
简 单的说:X和IX的=X和X的关系。为什么呢?因为事务在获取IX锁后,接下来就有权利获取X锁。如果X和IX兼容的话,就会出现两个事务都获取了X锁的 情况,这与我们已知的X与X互斥是矛盾的,所以X与IX只能是互斥关系。其余的三组关系同理,可用同样的方式推导出来。

一致性非阻塞读

select... lock in share mode和select ... for update的区别

索引记录锁
间隙锁
后码锁

各种语句对应的锁类型
在有索引的情况下是以后码锁为基础的行级锁,在固定索引键查找的情况下是索引记录锁,在没有可用索引的情况下上升到表锁
有索引的情况:
select ... from 一致性非阻塞读,不上锁。在serializable隔离级别下例外,在这个隔离级别下上共享后码锁
select ... from ... lock in share mode  共享后码锁
select ... from ... for update 排它后码锁
update .... where  排它后码锁
delete from .... where 排它后码锁
insert ... 排它索引记录锁,如果发生键值唯一性冲突则转成共享锁
insert ... on duplicate key update ,一直都是排它锁
replace ... 一直都是排它锁


死锁情境分析(Innodb)
・更新対象の行が異なればロック待ちの必要はない
・クエリーの書き方より、テーブル全体をロックしてしまう場合がある
 ・テーブルロックさせないためには、インデックスのあるカラムで条件指定する




MVCC的理论与实现

mysql 調整 視点

★大体の流れ。
    ・問題の場所にハードウェアを投入する
    ==>だから、リソースがたりないよ。。。。増やしてください。
    ===>はい、CPUを2倍に、MEMを4倍に、SSDにした。
    ・MySQL プロセスの設定を調整する
    ==>だから、MySQLの設定の問題だよ。。。適切に設定されていないでしょうか?
    ===>既に調整しました、今のこんなレポートがあり、見てください。
    =====>あ。。ちょっとプログラムを調査します。
    ・クエリーを最適化する

プロセスを調整するということは、メモリーを適切な場所に割り当て、そしてどんな種類の負荷を想定するかを mysqld に伝えるということです。ディスクを高速にするよりも、必要なディスク・アクセス数を減らした方が効果的です。同様に、MySQL プロセスが適切に動作している状態を確実にするということは、MySQL プロセスが、クエリーの処理にたくさんの時間を費やすことができ、一時ディスク・テーブルを扱うようなバックグラウンド・タスクの処理や、ファイルを開いたり閉じたりといった処理には、あまり時間を使わずに済むということです。


★★スロー・クエリーのログを取る
SQL サーバーでは、データ・テーブルはディスク上にあります。サーバーは索引によって、テーブル全体を検索することなく、テーブル内の特定のデータ行を見つけることができます。テーブル全体の検索が必要な場合、その検索はテーブル・スキャンと呼ばれます。ほとんどの場合、必要なものはテーブルの中のデータの、ごく小さなサブセットのみであるため、完全なテーブル・スキャンは大量のディスク I/O を浪費し、従って時間を浪費します。この問題は、データの連結が必要な場合にはさらに悪化します。連結されるデータ同士の間で、さらに多くの行を比較しなければならないからです。

slow_query_log     スロークエリログの有効/無効を設定 0(または OFF)で無効、1(または ON)が有効
log-output     出力対象を設定 ファイル(FILE)、テーブル(TABLE)または両方を指定可能
slow_query_log_file     ログ出力先ファイル名(絶対パス/想定パス指定可)
long_query_tim     指定した時間(sec)以上かかったクエリを記録(デフォルト10秒)
----->The time to acquire the initial locks is not counted as execution time.
log_queries_not_using_indexes     インデックスを使用しないクエリを記録=====>これは良さそう。。。
min_examined_row_limit     指定数以上のレコードを読み込んだ場合にクエリを記録


★★クエリーをキャッシュする
多くの LAMP アプリケーションはデータベースに大きく依存していますが、同じクエリーを何度も繰り返し行います。クエリーが実行されるたびに、データベースは同じ作業を行わなければなりません (つまりクエリーを解析し、その実行方法を決定し、ディスクから情報をロードし、その情報をクライアントに返します)。MySQL にはクエリー・キャッシュと呼ばれる機能があり、クエリーの結果が再度必要な時のために、その結果をメモリーに保存します。多くの場合、これによってパフォーマンスを劇的に向上させることができます。ただし注意する点として、クエリー・キャッシュはデフォルトで無効になっています。

mysql> SHOW STATUS LIKE 'qcache%';
+-------------------------+------------+
| Variable_name           | Value      |
+-------------------------+------------+
| Qcache_free_blocks      | 5216       |
| Qcache_free_memory      | 14640664   |
| Qcache_hits             | 2581646882 |
| Qcache_inserts          | 360210964  |
| Qcache_lowmem_prunes    | 281680433  |
| Qcache_not_cached       | 79740667   |
| Qcache_queries_in_cache | 16927      |
| Qcache_total_blocks     | 47042      |
+-------------------------+------------+

★★制限を設定する
リスト 3. MySQL のリソース設定

set-variable=max_connections=500
set-variable=wait_timeout=10
max_connect_errors = 100

1 行目では最大接続数が指定されています。Apache の MaxClients の場合と同様、最大接続数の考え方は、処理することが可能な接続数の範囲でのみ接続を許可することです。これまでサーバーで観察された最大接続数の情報を得るためには、SHOW STATUS LIKE 'max_used_connections' を実行します。
Connections--->起動してから、成否かかわず接続試行の回数
max_used_connections-->同時に接続の最大数

show variables like '%timeout%'
-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 3600     |
| wait_timeout                | 28800    |->単位は秒、8時間である
+-----------------------------+----------+


A large or growing Table_locks_waited value is the sign of a serious concurrency bottleneck.
Any long running select will block an insert or update from happening. That will in turn prevent any further selects from occurring until after the queued insert or update is complete. Your computer — with all its wonderful parallelism — will suddenly begin working in serial, at least with respect to MySQL. It doesn't matter how many CPUs you throw at it, only one will be used. A performance nightmare.

2 行目は、10 秒以上アイドル状態であったすべての接続を終了するように mysqld に指示されます。通常、LAMP アプリケーションでのデータベースへの接続は、Web サーバーがリクエストを処理するために必要な期間にのみ存在します。場合によると、負荷のある状態で接続が継続し、接続テーブルのスペースを占有してしまうことがあります。対話型のユーザーが多い場合、あるいはデータベースに対して永続的な接続を使用する場合には、この値を低く設定することは賢明ではありません。

最後の行は安全策です。もしホストとサーバーとの接続に問題があり、ホストがリクエストの処理をアボートする回数が多すぎる場合には、FLUSH HOSTS が実行されるまでホストはロックされます。デフォルトでは、10 回も失敗すればブロックされる条件としては十分です。この値を 100 に変更すると、サーバーにはどのような問題からも回復できるだけの十分な時間が与えられます。この値を大きくしても、あまり効果はありません。もしサーバーが 100 回試行しても 1 度も接続できないのであれば、まったく接続できない可能性が高いからです。


★★バッファーとキャッシュ
MySQL には、100 項目をはるかに超える調整可能な設定があります。しかし幸いなことに、そのごく一部をマスターすれば、必要なことのほとんどに対応することができます。こうした設定の適切な値を見つけるためには、SHOW STATUS コマンドを使ってステータス変数を調べ、その結果を基に、mysqld が期待どおり動作しているかどうかを判断します。

mysql> SHOW STATUS LIKE 'open%tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 5000  |
| Opened_tables | 195   |
+---------------+-------+
2 rows in set (0.00 sec)

-----症状例ーーーーー
Open_tables 512--->table_open_cacheに合う。
Opend_tablesーー>開けたテーブル!
 The number of tables that have been opened. If Opened_tables is big, your table_open_cache value is probably too small.

MySQL is MySQL はマルチスレッド化されているため、多数のクライアントが同時に同じものに対してクエリを使用することがあります。2 つのクライアントスレッドで 1 つのファイルに異なるステータスが発生する問題を最小にするため、同時に実行しているスレッドがそれぞれで無関係にテーブルを開きます。これはメモリの消費を増やしますが、一般にパフォーマンスは向上します。

table_open_cache is related to max_connections. For example, for 200 concurrent running connections, specify a table cache size of at least 200 * N, where N is the maximum number of tables per join in any of the queries which you execute. You must also reserve some extra file descriptors for temporary tables and files


リスト 5. は、十分な数のスレッドがキャッシュされているかどうかを調べる方法を示しています。
リスト 5. スレッド使用状況の統計を示す

・mysql> SHOW STATUS LIKE 'threads%';
+-------------------+--------+
| Variable_name     | Value  |
+-------------------+--------+
| Threads_cached    | 27     |
| Threads_connected | 15     |
| Threads_created   | 838610 |
| Threads_running   | 3      |
+-------------------+--------+
4 rows in set (0.00 sec)

ここで重要な値は Threads_created です。この値は、mysqld が新しいスレッドを作成する必要が生じるたびにインクリメントされます。もし SHOW STATUS コマンドを継続して実行している間にこの数字が急激に増加するようであれば、スレッド・キャッシュを増加することを検討する必要があります。そのためには、my.cnf の中で、例えば thread_cache = 40 のようにします。


リスト 6. キーの効率を調べる

mysql> show status like '%key_read%';
+-------------------+-----------+
| Variable_name     | Value     |
+-------------------+-----------+
| Key_read_requests | 163554268 |
| Key_reads         | 98247     |
+-------------------+-----------+

show status like '%key%';
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| Com_assign_to_keycache | 0      |
| Com_preload_keys       | 0      |
| Com_show_keys          | 0      |
| Handler_read_key       | 0      |
| Key_blocks_not_flushed | 0      |
| Key_blocks_unused      | 319666 |ーー>数であり、一個は1K
| Key_blocks_used        | 0      |
| Key_read_requests      | 0      |
| Key_reads              | 0      |
| Key_write_requests     | 0      |
| Key_writes             | 0      |
+------------------------+--------+

Key_reads はディスクへのアクセスが行われた要求の数を表し、Key_read_requests は要求の合計数を表します。Key_reads を Key_read_requests で割ると、ミス・レートが得られます。この場合では 1,000 回の要求に対して 0.6 回のミスです。もし 1,000 回の要求に対して 1 回を超えるミスが起きている場合には、キー・バッファーを増加することを検討する必要があります。例えば key_buffer = 384M とするとバッファーは 384MB に設定されます。

The Key_reads/Key_read_requests ratio should normally be less than 0.01. The Key_writes/Key_write_requests ratio is usually near 1 if you are using mostly updates and deletes, but might be much smaller if you tend to do updates that affect many rows at the same time or if you are using the DELAY_KEY_WRITE table option.

information_shema,mysql下のtableはMyISAMを使っている。


一時テーブルは高度なクエリーに使われます (例えば GROUP BY 句の場合のように、さらに処理を行う前に一時的にデータを保存しなければならない場合など)。理想的には、そうしたテーブルをメモリー内に作成しますが、一時テーブルは大きくなりすぎすぎるとディスクに書き込まれます。リスト 7 は一時テーブルの作成に関連する統計を示しています。
リスト 7. 一時テーブルの使用状況を調べる

mysql> SHOW STATUS LIKE 'created_tmp%';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 30660 |
| Created_tmp_files       | 2     |
| Created_tmp_tables      | 32912 |
+-------------------------+-------+
3 rows in set (0.00 sec)

一時テーブルが使われるごとに Created_tmp_tables が増加します。またディスク・ベースのテーブルが使われると Created_tmp_disk_tables がインクリメントされます。この比率はどのようなクエリーが行われるかに依存するため、この比率に関する確かなルールはありません。時間をかけて Created_tmp_disk_tables を観察すると、作成されたディスク・テーブルの割合を知ることができ、そこから設定の効果を判断することができます。tmp_table_size と max_heap_table_size はどちらも一時テーブルの最大サイズを制御します。そのため、この両方を my.cnf の中で設定する必要があります。

・lock
ここが行列になっているみたい。
show status like '%_row_lock_%';
+-------------------------------+----------+
| Variable_name                 | Value    |
+-------------------------------+----------+
| Innodb_row_lock_current_waits | 1        |
| Innodb_row_lock_time          | 28066933 |単位はmilisecond-->7.796時間、昨日再起動したばかりので、1/3の時間ロック待ち
| Innodb_row_lock_time_avg      | 1568     |待ち時間平均で1.5秒
| Innodb_row_lock_time_max      | 51960    |51秒のロック、すごい
| Innodb_row_lock_waits         | 17894    |ロック待ちのクエリ総数
+-------------------------------+----------+

・極端で理想の形が、slaveから読んで直接Masterを更新してどうかな?危険
・いろいろしてコミットしないの間もずっとロック持ちだ。。。。トランザクション
その意味で操作を細かくして、早いうちにコミットする

2014/01/14

mysql host cache

★The host_cache table provides access to the contents of the host cache, which contains client host name and IP address information and is used to avoid DNS lookups. (See Section 8.11.5.2, “DNS Lookup Optimization and the Host Cache”.) The host_cache table exposes the contents of the host cache so that it can be examined using SELECT statements. The Performance Schema must be enabled or this table is empty.
==>
The host_cache table was added in MySQL 5.6.5.


MySQLでのホストのキャッシュをクリアするコマンド
mysqladmin -u root flush-hosts

これは、IP からホスト名に逆引きしようとしたときに MySQL でエラーが発生したことを意味する。この場合、mysqladmin flush-hosts を実行して内部 DNS キャッシュをリセットすることができる

Difference between commit and flush in Hibernate

★★★Q:
Transaction t = session.beginTransaction();
session.update(item);
t.commit();
-------------------------------------------
session.update(item);
session.flush();

----------------------------------------------
i found out that they basically does the same thing

so what is Difference between commit and flush in Hibernate?

★★★A:
・Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory
・The flush process synchronizes database state with session state by detecting state changes and executing SQL statemen

★★★テスト
//set the JDBC batch size (it is fine somewhere between 20-50) 
hibernate.jdbc.batch_size 30 
 
//disable second-lavel cache 
hibernate.cache.use_second_level_cache false 
 
//and now do your job like this 
Session S=SF.openSession(); //SF = SessionFactory object 
Transaction T=S.beginTransaction(); 
    
for (int i=0;i<200000;i++) 

   record r=new record(...); 
   S.save(record); 
   if(i % 30==0) 
   {     
      //30, same as the JDBC batch size 
      //flush a batch and release memory 
      session.flush(); // Line 1 
      session.clear(); 
   } 
}  
//clean   
T.commit(); // Line 2 
S.close(); 
==ー>
My test tells me the session.flush() does not make the data visible to other clients. It is available only after the commit.
And I also notice when I set the batch size from 10, 100, 1000, 10000, the performance is pretty much the same. 1%-2% difference with
each other.

bash 正規表現

.     改行文字以外の任意の1文字
*     直前の1文字の0回以上の繰り返しに一致。直前の文字は正規表現でも構わない
^     行の先頭
$     行の末尾
[ ]     かっこ内の任意の1文字に一致。ハイフン(-)で範囲指定もできる
[^ ]     かっこ内の任意の1文字に不一致。ハイフン(-)で範囲指定もできる
\+     直前の文字の1個以上の繰り返しに一致
\?     直前の文字の0または1文字に一致
\{n\}     直前の文字のn個の繰り返しに一致
\{n,\}     直前の文字のn個以上の繰り返しに一致
\{,m\}     直前の文字のm個以下の繰り返しに一致
\{n,m\}     直前の文字のn個以上、m個以下の繰り返しに一致
pattern1\|pattern2     pattern1またはpattern2のいずれかに一致
\(pattern\)     patternをグループ化する。マッチした内容は参照できる
\     正規表現に使われる記号を普通の文字として扱う