Month: September 2014

基于比较的分页机制 V.S. 页码式分页

基于比较的分页机制中,输入是一个被比较值。 页码式分页机制中,输入则是页码。 用户体验 对于数据不断增长的功能,页码式分页机制在用户体验方面有个缺点:你翻到下一页时可能会看到刚刚已经看到过的记录。 以贴吧为例,你进到第一页时,你看到的是06,05,04这三条记录;翻到第二页时,本应看到的是03、02、01。 然而在你翻页之前,另一个用户插进了记录07记录; 这时再看第二页时,系统认为此时第一页是07、06、05,于是把第二页04、03、02返回给你,而你刚刚已经看了记录04. tps越高,这种现象就越严重。 而基于比较的分页机制就没有这个问题。第一页看到06, 05, 04; 翻到第二页时,客户端 “告诉系统我要比04更小的三条记录”, 不管这时有没有新增记录07,系统收到的指令都是“比04更小的三条记录”,所以总是返回03、02、01. 性能 如果要对分页查看列表的功能进行性能优化,一个常见的策略就是对前几页进行缓存。用缓存有一个问题:缓存的key是哪些? 对于页码式分页机制,缓存的key就是页码;要缓存前N页,只需缓存N个key对应的数据。 而对于比较式分页机制,缓存的key是什么? 它可能是你系统中的任何值,而且随着数据的增减,这个值可能原来是页尾,马上就又不是了。 要缓存多少个key?  只能把所有值都缓存一遍。除了首页由于被比较值固定为0可以缓存之外,其他页都无法缓存。 用户足迹追踪 比较式分页机制对用户足迹追踪不利。你很难根据访问记录(如access log),决定大部分用户会下翻多少页;而页码式分页机制就没这个问题。

mysql: 了解数据库状态时常用的sql语句

show table status like ‘some_table’ 它会给出本表的storage engine, 行数,表占的空间和索引所占的空间。还有一个有意思的信息:每行平均所占的空间。这个信息不仅可用于DB管理,也可以帮助在整个信息系统中估计各种存储空间、网络带宽之类的。 show variables like ‘%slow%’ show variables  like ‘%long%’;   了解慢查询相关的设置 show variables like ‘storage_engine’; 查看当前默认的storage engine show full processlist 当前连到本库的客户端进程 show variables like ‘query_cache_type’ 查看数据库的query cache设置

innodb的record lock, row lock, gap lock, next-key lock

record lock – 对索引上某个记录的锁 row lock -对某条数据记录的锁。然而innodb总是通过施加record lock来施加row lock, 也就是说innodb本身没有row lock的概念,record lock就是row lock gap lock – 索引record之间的锁,用来防止phantom read next-key lock – 本身不是一种锁。它是a combination of a record lock on the index record and a gap lock on the gap before the index record.  用next-key lock可以防止phantom read. 对于这样一条语句, SELECT * FROM child WHERE id > 100 FOR …

innodb的record lock, row lock, gap lock, next-key lock Read More »

poi – 安全地把cell当作string读出来

如果cell并非string类型,调用cell.getStringCellValue()会出错。 下面这样可以保证安全: private String readString(Cell cell) { if (cell == null) { return null; } int cellType = cell.getCellType(); if (cellType == Cell.CELL_TYPE_BLANK) { return null; } if (cellType == Cell.CELL_TYPE_BOOLEAN) { return String.valueOf(cell.getBooleanCellValue()); } if (cellType == Cell.CELL_TYPE_ERROR) { return null; } if (cellType == Cell.CELL_TYPE_FORMULA) { return cell.getCellFormula(); } if (cellType == Cell.CELL_TYPE_NUMERIC) …

poi – 安全地把cell当作string读出来 Read More »

例示Innodb中的read commited和repeatable read

本文读者须已经了解mysql的mvcc机制。 假定某行某字段值为100; 以下所有的查询和修改都针对这个字段。 事务甲                                                                   事务乙 ——————————————————————————- set commit = 0                                                  set commit = 0 select … (值为100) update … = 200; selet … (值为200, 自已事务下的修改是立即可见的)                                                                           update … = 300; select … (仍为200, 右边事务未提交,不关我的事)                                                                                                        commit; select … ( 如果level=read commited, 值为300, 可以读到其它事务的已提交修改 如果level=read repeatable, 值仍为200, 其他事务即使提交了也不关我的事 ) commit; —- select … (值为300,这个不用解释)

innodb中,普通读不加读锁

http://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html "Consistent read(即普通select) is the default mode in which InnoDB processes SELECT statements in READ COMMITTED and REPEATABLE READ isolation levels. " " A consistent read does not set any locks on the tables it accesses" 因此另一个事务可以随便改: " and therefore other sessions are free to modify those tables at the same time a consistent read …

innodb中,普通读不加读锁 Read More »

innodb中,每条语句都运行在事务中

autocommit下,每条语句组成一个事务: "In InnoDB, all user activity occurs inside a transaction. If autocommit mode is enabled, each SQL statement forms a single transaction on its own" "By default, MySQL starts the session for each new connection with autocommit enabled, so MySQL does a commit after each SQL statement if that statement did not return an error." …

innodb中,每条语句都运行在事务中 Read More »

two-phase locking

two-phase locking(2pl)是指在一个事务分成两个阶段: 1. 第1阶段只能加锁 2. 第2阶段只能释放锁 它的反面就是: 对A加锁,然后释放; 再加B锁,再释放。。。 后面这种方式保证不了serializability.   比如, 事务甲               事务乙 ———————- 对A加写锁 set A=100 对A释放写锁                       对A加写锁                       set A=200                       对A释放写锁 对A加读锁 对B加写锁 set B=A*2=… select B 对A释放读锁     对B释放写锁               ———————- 事务甲结束后,B的值变成了400; 而我们本来预期这个值应该是200的 (没有满足repeatable read这个级别) 要解决这个问题,可以干脆等事务甲全部结束再执行事务乙;既然事务之间是通过锁来协调的,可以让事务甲的锁全部释放了,再让事务乙获得锁,以保证一致性。 事务甲               事务乙 ———————- 对A加写锁 set A=100                       对A加写锁                       等待。。。。 对B加写锁 set B=A*2=…                  select B …

two-phase locking Read More »

一个事务跨了多个storage engine会怎么样?

一个事务跨了多个storage engine会怎么样? 比如表A是innodb, 支持事务; 表B是MyISAM,不支持事务.  会怎么样? 会出问题。 如果你要rollback这个事务,会导致A中的数据回滚,B中的数据未回滚,导致不一致性。