再谈事务和锁:mysql innodb

先看看mysql文档最好:

http://dev.mysql.com/doc/refman/5.1/en/innodb-lock-modes.html

http://dev.mysql.com/doc/refman/5.1/en/innodb-transaction-model.html

http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html

http://dev.mysql.com/doc/refman/5.1/en/innodb-record-level-locks.html

http://dev.mysql.com/doc/refman/5.1/en/lock-tables.html

首先InnoDB默认是行级锁,但是,不是说事务里面的select语句是自动加了锁的,需要使用LOCK IN SHARE MODE 设定S锁 或 FOR UPDATE 设定X锁。 并且要看事务隔离级别。例如SERIALIZABLE级别下,本事务下所有不带锁的查询将自动设置为LOCK IN SHARE MODE 。参见http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html

SERIALIZABLE

This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.)

然而update和delete语句是加了X锁的[这个照其文档意思是这样,我没找到明确说明]。insert语句就用不了行级锁了,因为这待插入的数据还没存储。

select 语句即使加了锁,但是如果查找条件没有明确使用索引,则导致锁表。

舉個例子:

假設有個表單 products ,裡面有 id 跟 name 二個欄位,id 是主鍵。

例1: (明確指定主鍵,並且有此筆資料,row lock)

SELECT * FROM products WHERE id='3' FOR UPDATE;

例2: (明確指定主鍵,若查無此筆資料,無 lock)

SELECT * FROM products WHERE id='-1' FOR UPDATE;

例2: (無主鍵,table lock)

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

例3: (主鍵不明確,table lock)

SELECT * FROM products WHERE id<>'3' FOR UPDATE;

例4: (主鍵不明確,table lock)

SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

 

锁和事务的关系这里我再明白了些,参照三级封锁协议两段锁以及隔离级别 ,锁是事务实现并发控制隔离级别的实现方法。为了避免并发操作存在的异常情况出现,在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同 。

虽然各数据库对此标准的实现各有不同,但是它们需要保证这一点。对于使用者则需依据实际情况定义好适当的事务隔离策略再来调用个数据库native sql来实现这些策略来达到应用目的,而不是以为只要使用了事务就万事大吉了。

参考:

http://blog.csdn.net/zdl1016/article/details/6946060

http://hi.baidu.com/thinkinginlamp/blog/item/d677cffcb7098482b901a014.html

http://www.neo.com.tw/archives/900

http://www.tapy.org/index.php/archives/228

http://blog.chinaunix.net/space.php?uid=123581&do=blog&id=2944289

Continue reading 再谈事务和锁:mysql innodb

php foreach引用陷阱

先看这段代码:

<?php
$arr = array('a','b','c');
foreach($arr as &$a){
} 
print_r($arr);
print_r($a);
foreach($arr as $a){
}
print_r($arr);
print_r($a); 
?>

咋一看,就是两个空循环,应该不会对$arr有什么影响,但是实际结果是:

Array ( [0] => a [1] => b [2] => c ) c

Array ( [0] => a [1] => b [2] => b //出问题了 ) b

这就是php文档上写的引用陷阱。

它发生的原因是,php没有局部变量,第一个循环的引用变量$a继续在第二个循环中被赋值,

第一循环

$a = $arr[0]

$a = $arr[1]

$a = $arr[2]

第二循环

$arr[2] = $arr[0]  //$arr[2] = ‘a’

$arr[2] = $arr[1]  //$arr[2] = ‘b’

$arr[2] = $arr[2] //$arr[2] = ‘b’


这是php文档上说明了的陷阱,但是包括我在内很多人仍然要踩进去一回,哈哈。

 

这里补充foreach的一点知识:

<?php
$arr = array();
for($ii = 0 ; $ii < 10 ; $ii ++){
	$arr[] =  array('k'=>$ii . '_v','p'=>'hah');
}
print_r($arr);
$narr = array();
foreach($arr as $i){
	$i['k'] = 'changed';
	unset($i['p']);
	$narr[] = $i  ;
}
print_r($arr);
print_r($narr);
?>

代码里创建一个数组$arr,然后使用foreach遍历,改变每个元素的值。

然后发现原来数组里的值没有变化,而$narr里面的是修改后的元素。

此例说明foreach循环中的元素是拷贝变量,修改它不会影响原来的数组。

所以我们使用引用来达到修改修改元素的目的。

Continue reading php foreach引用陷阱

xshell 反向通道和 tunnlr配置

大家知道putty更多些,但是putty能做的xshell也都能做,而且对于这个商业软件来说,对于个人用户是免费的,真是够厚道。

之前说过xshell通道连主机,见http://blog.ureshika.com/archives/788.html

这次说说反向通道,即让主机连本地机器,做一个ssh的反向代理,这个和www.tunnlr.com 有些像,即外网通过公网主机某个端口访问本地主机的某个端口。

internet—>server—>pc

打开xshell新建session,如下图设置:

Snap1

其中Type/Direction为Remote

Source Host为公网主机,其端口为想要暴露的端口。

Destination Host则为本地机器,端口为本地机器使用的端口。

从上图则配置了test.com:10080 到本机90080的隧道。那么公网访问test.com:10080 实际上经过test.com主机转发到本机90080端口了。

当然test.com不会随便让10080端口暴露的,如果不进行端口配置,公网是无法访问10080端口的。

但是可从test.com ssh控制台中telnet 127.0.0.1:10080 会发现是可连通的。

 

这里也附带说一下使用xshell配置tunnlr,tunnlr的说明是用putty说的,xshell一样可以,以图说明:

Snap2

新建session,connection信息依据tunnlr提供的来,主要是Authentication中的密钥对,点击Browse..可以新建一个,新建以后不要忘了保存私钥,点击export即可导出私钥,要查看公钥字符串,点击对应密钥对属性可看。

然后Tunneling中的配置可参考上面反向通道的配置,也就是

Source Host为空(即为tunnlr.com),其端口为tunnlr分配给你的端口。

Destination Host则为本地机器,端口为本地机器使用的端口。

其他略。

最近 发现xmanager4似乎x11显示有问题,总是连不上,换为xmanager3就可以了,但是安装了xmanager3带了xshell3,结果使用xshell4作为反向代理时,总是报错退出,然后通道就怎么也连不上了,除非重启。改为使用xshell3就没问题,估计是安装两个版本的xshell造成的冲突。

Continue reading xshell 反向通道和 tunnlr配置

php _REQUEST多了个反斜杠

如果你发现提交给php的参数_REQUEST中的值无缘无故多了个反斜杠,请不要奇怪,这个和php的magic_quotes_gpc这个配置有关系。

默认它是on所以,所有传入参数都会用\转义,这当然是安全原因,但是是个很不好的做法,5.3之后就不建议用,6.0以后就直接删除了。

但是代码里还是要处理:

<?php
if (get_magic_quotes_gpc()) {
			$msg = stripslashes($msg);
		}
?>


php文档中还提供了深度反转义的方法:

/>

<?php
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);

return $value;
}

function remove_wp_magic_quotes()
{

if (get_magic_quotes_gpc()) {
$_GET = stripslashes_deep($_GET);
$_POST = stripslashes_deep($_POST);
$_COOKIE = stripslashes_deep($_COOKIE);
$_REQUEST = stripslashes_deep($_REQUEST);

}
}
?>

Continue reading php _REQUEST多了个反斜杠

websocket实践

服务端以jetty8做容器,参考

http://wiki.eclipse.org/Jetty/Feature/WebSockets

http://dev.w3.org/html5/websockets/

如果用maven需要jetty-webapp和jetty-websocket依赖:

<dependency>
			<groupId>org.eclipse.jetty</groupId>
			<artifactId>jetty-webapp</artifactId>
			<version>8.1.2.v20120308</version>
		</dependency>
		<dependency>
        	<groupId>org.eclipse.jetty</groupId>
        	<artifactId>jetty-websocket</artifactId>
        	<version>8.1.2.v20120308</version>
    	</dependency>

注意jetty8实现的是servlet-api-3.0,所以要排除对servlet-api-2.5的依赖。否则会报Java SecurityException : signer information does not match 的错误。

在此jetty版本下webservletsocket代码为:

>package kzg.html5.websocket;

Continue reading websocket实践

heidisql使用ssh远程连接mysql

一般都是使用phpmyadmin来管理远程数据库,但是也可以使用自己喜爱的mysql客户端工具配合ssh通道来连接远程数据库,其道理就似乎是个代理,用ssh工具登陆上mysql所在主机的某个端口,在本地开个端口,那么本机对此端口的请求就会连接到主机上的配置的端口上。

下面以heidisql为例。

最主要的是ssh的配置,putty大家都知道吧,用它来建立隧道。

首先你的远程服务器需要开通ssh连接,此文就不涉及内容,假定已可以通过ssh远程连接,并且检查msql是否允许此主机连接,可以通过cpanel的RemoteMysql来配置。

在putty中需要配置:

打开putty,在session中配置主机ip地址或域名以及端口。

mysqlgui2

然后配置本机到主机的映射隧道:

在tunnels中source port是你打算在本机映射的端口此例中是3307,注意不要使用已被占用的端口。

Destination中添目标mysql主机ip以及mysql端口,此例中是codex345.extremehost,端口是3306

选中local和auto点击Add,那么隧道就配置成功了。

mysqlgui3

在session中保存你的配置,点击open,此时会出现putty控制台登陆远程主机,需要你填入用户名和密码。登陆成功后,就可以在heidisql中项配置本地数据库一样配置到远程数据库的连接了。此例中练的是本地,端口是上面配置的3307,其实就是通过隧道连接到远程主机的3306端口了,是不是很方便呢。

mysqlgui4

实际开发中不喜欢每次都要在putty中输入用户名密码,而putty处于安全的考虑又不提供保存密码的功能,那么你可以使用xshell,它是一款功能更强大的商业软件,而且对个人用户免费哈哈。见http://www.netsarang.com/products/xsh_overview.html

它的配置和putty很类似,对于隧道配置如下图,其实也是一样,只不过界面改了,我在这里烂一下笔头,方便大家区分:

Snap1

 

有时连接出现SQL Error (2013): Lost connection to MySQL server at 'reading initial communication packet',错误,经测试改用ip而不是域名连接远程主机就可以解决这个问题。

Continue reading heidisql使用ssh远程连接mysql

php版本升级问题

升级到5.3注意的问题:

增加了Deprecated 错误级别 http://php.net/manual/en/migration53.deprecated.php

Deprecated features in PHP 5.3.x

PHP 5.3.0 introduces two new error levels: E_DEPRECATED and E_USER_DEPRECATED. The E_DEPRECATED error level is used to indicate that a function or feature has been deprecated. The E_USER_DEPRECATED level is intended for indicating deprecated features in user code, similarly to the E_USER_ERROR and E_USER_WARNING levels.

The following is a list of deprecated INI directives. Use of any of these INI directives will cause an E_DEPRECATED error to be thrown at startup.

Deprecated functions:

Deprecated features:

  • Assigning the return value of new by reference is now deprecated.
  • Call-time pass-by-reference is now deprecated.

Continue reading php版本升级问题

linux cron任务执行php

一般可使用cpanel 中的cron job界面来添加任务,对于执行php来说,可现在本机上执行命令测试了再加上去。

也可使用

crontab -e

来直接编辑,注意cpanel的cron脚本是没有放在这里面的。

还可以使用浏览器来执行呢:

http://www.htmlcenter.com/blog/running-php-scripts-with-cron/

 

默认情况下,crontab中执行的日志写在/var/log下,如:

#ls /var/log/cron*

/var/log/cron /var/log/cron.1 /var/log/cron.2 /var/log/cron.3 /var/log/cron.4

crontab的日志,当crond执行任务失败时会给用户发一封邮件。如果在服务器上发现一个任务没有正常执行,而crond发邮件也失败。通过看mail的日志,看是否是磁盘空间不够造成的

将cornd错误输出和标准输出日志都指向自定义的日志文件:

0 6 * * * $HOME/fro_crontab/createTomorrowTables>>$HOME/for_crontab/mylog.log 2 >&1

 

对于codeigniter来说,可参见他的源码cron.php,它是模仿http请求来做的。

参见:

http://tech.ddvip.com/2008-06/121324087945638.html

Continue reading linux cron任务执行php

Pagination


Total views.

© 2013 - 2024. All rights reserved.

Powered by Hydejack v6.6.1