April 11, 2012
| 作者:白菜
|
分类:编程算法
一、概述
如果你的Oracle数据库性能低下,行链接和行迁移可能是其中的原因之一。我们能够通过合理的设计或调整数据库来阻止这个现象。行链接和行迁移是能够被避免的两个潜在性问题。我们可以通过合理的调整来提高数据库性能。本文主要描述的是:
● 什么是行迁移与行链接● 如何判断行迁移与行链接● 如何避免行迁移与行链接
当使用索引读取单行时,行迁移影响OLTP系统。最糟糕的情形是,对所有读取操作而言,增加了额外的I/O。行链接则影响索引读和全表扫描。注:在翻译行(row)时使用记录来描述(便于理解),如第一行,使用第一条记录。
二、Oralce 块
操作系统块的大小是操作系统读写的最小操作单元,也是操作系统文件的属性之一。当创建一个数据库时,选择一个基于操作系统块的整数倍大小作为Oracle数据库块的大小。Oracle数据库读写操作则是以Oracle块为最小单位,而非操作系统块。一旦设置了Oracle数据块的大小,则在整个数据库生命期间不能被更改(除 Oracle 9i之外)。因此为Oracle数据库定制合理的Oralce块大小,象预期数据库总大小以及并发用户数这些因素应当予以考虑。
数据库块由下列逻辑结构(在整个数据库结构下)

头部:头部包含一些常用信息,象块地址,段的类型(表段、索引段等)。也包含一些表、实际数据行的地址信息等。
阅读剩余部分...
July 12, 2011
| 作者:白菜
|
分类:编程算法
一句话:不论什么数据库,最好每个表显式指定主键。
mysql表如果没有指定主键的话,系统会默认加上一个隐式的主键,有时候因为是手写SQL,懒,所以能省就省了。理论上,为了查询效率考虑,也应该给表建主键的。
今天用pgadmin建表的时候,有一个表无论怎么都不能插入数据,很奇怪,刚开始怀疑难道是这个软件的BUG,可不应该啊。网上查了查,人家的都正常。翻了不少资料,最后终于找到了一条“使用pgadmin,如果数据表没有主键的话,在网格查看页面是不允许编辑和插入新数据的”。恍然大悟,决定痛改前非,再不偷懒,哪怕即使是测试用的表,也不要懒。
March 4, 2011
| 作者:白菜
|
分类:编程算法
说说mysql_connect和mysql_pconnect的区别,这俩函数用法上差不多,网上有说应该用pconnect的,pconnect是个好东西;也有视pconnect如洪水猛兽的,坚决不让用pconnect的,也有态度暧昧不清的。那这个东西到底如何呢?
永久链接并不是说,服务器打开了一个连接,然后所有的人都共享这个链接。永久连接一样是每个客户端来就打开一个连接,有200人访问就有200个连接。其实mysql_pconnect()本身并没有做太多的处理, 它唯一做的只是在php运行结束后不主动close掉mysql的连接.
在php经cgi方式运行时pconnect和connect是基本没有区别的, 因为cgi方式是每一个php访问起一个进程, 访问结束后进程也就结束了, 资源也全释放了. 当php以apache模块方式运行时, 由于apache有使用进程池, 一个httpd进程结束后会被放回进程池, 这也就使得用pconnect打开的的那个mysql连接资源不被释放, 于是有下一个连接请求时就可以被复用.这就使得在apache并发访问量不大的时候, 由于使用了pconnect, php节省了反复连接db的时间, 使得访问速度加快. 这应该是比较好理解的. 但是在apache并发访问量大的时候, 如果使用pconnect, 会由于之前的一些httpd进程占用的mysql连接没有close, 则可能会因为mysql已经达到最大连接着, 使得之后的一些请求永远得不到满足.若mysql最大连接数设为500, 而apache的最大同时访问数设为2000,假设所有访问都会要求访问db, 而且操作时间会比较长,当前500个请求的httpd都没有结束的时候,之后的httd进程都是无法连接到mysql的(因已经达到mysql最大连接数). 只有当前500个httpd进程结束或被复用才可以连接得到了mysql.
当db操作复杂, 耗时较长时, 因httpd会fork很多并发进程处理, 而先产生的httpd进程不释放db连接, 使得后产生的httpd进程无法连上db. 因为这样没有复用其它httpd进程的mysql连接. 于是会就产生很多连接超时。 在并发访问量不高时,使用pconnect可以简单提高访问速度, 但在并发量增大后, 是否再使用pconnect就要看程序员的选择了.
就我个人认为, php现在对mysql的连接并没有真正用到连接池, pconnect也只是相当于借了apache的进程池来用, 所以在并发访问量大的时候pconnect并不能很好的提高访问db效率.
在实际的应用中,用mysql_pconnect的话,每次刷新和请求新的页面都比较快,而用mysql_connect的话,每次刷新都要重新请求,当数据库连接比较慢的时候,就能看出差异了。当你的数据库连接比较慢,DB操作不是很复杂,并且你的程序足够自信,不会产生死锁的时候,或者你拥有对服务器的控制权,满足以上四个条件中的任意两个,那就可以用pconnect。
pconnect不用在脚本里关闭,可以在mysql中设置lifetime,也可以写shell定期扫描,kill掉休眠过长的连接。 一句话总结:要用好pconnect,不仅仅是php脚本的事 还关系到数据库和服务器的设置。
March 2, 2011
| 作者:白菜
|
分类:php,编程算法
关键字:mysql,PROCEDURE,event,crontab.摘自《PHP开发指南》第十八章。
我在第一章提到过CLI的执行是不限时的,所以你可以用它来做计划任务。也就是在未来的某个时间自动执行某个任务。网页的话,可以这么来
<?Php
set_time_limit(0);
if(date("m")%5==0){
//do something}
加入ignore_user_abort(true)是为了保证用户在关闭了网页后,程序不会立即中断,而是在后台执行。计划任务的触发可以由用户或蜘蛛来触发,也可以对某些任务采取伪任务的方式(即若任务没有被外界触发,那么在后台查看任务时,先标记任务为已执行,然后再触发慢慢地去执行。因为很多任务的实时性并不高)。如果是unix系操作系统的话,则用crontab这款工具来执行。如果是涉及到单纯的数据库操作的话,则可以由mysql5.1的event来定时触发。这样比用php来的更直接。既然是数据库操作,我为啥不直接用mysql呢?何必再php调mysql多此一举?下面我举个例子,顺带介绍下mysql里的存储过程和定时器。
比如,我有个需求,需要定期删除已被处理过的log,而这些log存储在数据库里,表结构如下:
阅读剩余部分...
February 23, 2011
| 作者:白菜
|
分类:编程算法
关键字:mysql无法启动服务,mysql卡死,InnoDB' registration as a STORAGE ENGINE failed.Unknown/unsupported table type: innodb.
前几天,启动mysql时,突然报1067系统错误,死活无法启动。
当时不管三七二十八,重装,清空注册表,重启,任然没办法启动。
总是在安装后的配置那里最后一步启动服务的界面卡死,半天没反应。
折腾了两三个小时,才猛然想起,该去看看日志,
110223 15:58:08 [Note] Plugin 'FEDERATED' is disabled.
110223 15:58:08 InnoDB: Initializing buffer pool, size = 17.0M
110223 15:58:08 InnoDB: Completed initialization of buffer pool
InnoDB: No valid checkpoint found.
InnoDB: If this error appears when you are creating an InnoDB database,
InnoDB: the problem may be that during an earlier attempt you managed
InnoDB: to create the InnoDB data files, but log file creation failed.
InnoDB: If that is the case, please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/error-creating-innodb.html
110223 15:58:08 [ERROR] Plugin 'InnoDB' init function returned error.
110223 15:58:08 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
110223 15:58:08 [ERROR] Unknown/unsupported table type: innodb
110223 15:58:08 [ERROR] Aborting
大意是innodb初始化失败,不认识innodb类型。
google了一下,把my.ini文件打开,更改default-storage-engine=innodb为default-storage-engine=myism
启动成功。但是建表时找不到innodb引擎了。
但想着,也不能老这样啊,这样innodb也用不了了,有google了一下,主要是innodb日志大小不对造成的
innodb_buffer_pool_size=512M
innodb_log_file_size=128M
把以上几个参数调大点,然后把ibdata1,ib_logfile0,ib_logfile1这三个文件删除后,再重启服务就好了。
如果还是不行,在my.ini文件里还需要加入tmpdir="usr/tmp"这样的路径,因为innodb还需要一个临时的文件缓存区。
还遇到的问题是在安装MYSQL配置了密码后(卡在了最后一步上,因为mysql默认生成的配置文件是错误的,无法启动service,第四步权限设置也无法设置,等下去是没用的,你应该关闭配置工具,按我上面说的修改配置文件),无法登陆,可以先启动服务(此时配置已经被我们修改正确了),然后在命令行下用root用户登陆刷新权限就可以了。flush privileges.记住,登录时root不要输入密码(尽管你安装时设置了密码,但是无效),否则是操作不了的,因为此时权限还不存在。等一切正常了之后再改密码.
记录下来,仅供遇到此类问题的同学参考。主要是MYSQL 5.5在win下安装问题很多,需要手工处理。
February 8, 2011
| 作者:白菜
|
分类:编程算法
在上一次的测试中我们比较了MongoDB与Tokyo Tyrant的Table Database两种存储方式的性能。不过由于条件限制,我只能在自己的MBP上测试,而这至少会带来两个问题。首先,真实环境下客户端和服务器是通过内网连接的,它的性能比本地回环要慢不少,一些和网络传输性能有关的问题可能会体现不出。其次,由于无法进行并发测试(并发测试的客户端资源占用较高,放在同一台机器上准确性较差),这又和生产环境有很大区别了。因此,我前两天向同事借了台性能测试用的机器,希望可以得到更可靠的结果。
测试环境与数据
这次我使用了新的环境进行性能测试:
- OS:CentOS release 5.3 (Final)
- RAM:4GB
- CPU:Intel(R) Xeon(R) CPU E5405 @ 2.00GHz (64 bit, 4 cores * 2)
- 其他:SCSI硬盘,ext3文件系统
阅读剩余部分...
February 8, 2011
| 作者:白菜
|
分类:编程算法
以前的项目大都把数据存放在关系型数据库中,关系型数据库的优势在于使用普及,资料丰富,且有大量辅助类库来简化开发。当然它们的问题比较明显的,一是在数据量上升的情况下伸缩性比较差,且进行结构调整的代价比较高。因此现在有个所谓NoSQL的“运动”也逐渐普遍起来了,它便是借助一些非关系型存储方式来开发项目(个人认为其实将它解释为Not Only SQL更为合适)。因此在新项目里,我也想尝试一下使用之前一直只是“听说”的存储方式。
在和同事的交流过程中,我了解到他们的项目正在尝试使用(后称TT)进行存储,并且据说效果不错,因此我一开始也打算尝试使用TT进行主要存储,为此也花了一定时间为其编写.NET平台下的驱动程序。不过在驱动程序的开发过程中,我逐渐意识到TT的功能有着严重的限制,似乎并不适合作为接下来项目的主要存储方式。因此,我又将眼光转向了之前关注过的上。MongoDB也是NoSQL的代表之一,是一个面向文档的,架构灵活(Schema-less)的存储方式,在仔细阅读相关资料之后,我发现它的功能与TT相比可谓天上地下,非常适合许搭建各类项目(关于这点以后有机会再谈)。
不过,既然选择NoSQL的原因是性能,那么他们的性能表现究竟如何呢?TT的性能表现在业界非常出名,而MongoDB的使用便相对较少了(当然,官网,最近著名的开源网站SourceForge也打算使用MongoDB重新设计他们的网站)。为此,我决定亲手比较一下两者的性能表现。
阅读剩余部分...
January 21, 2011
| 作者:白菜
|
分类:php
项目中碰到 PHP 和数据库之间,计算存在时间计算误差。大致的情况为根据段时间字符串,例如
2012-12-14 00:00:00 UTC
使用 MySQL 的 UNIX_TIMESTAMP 函数以及 PHP 的 strtotime 计算得出的时间戳,大概有半分钟(差不多有28秒)的误差。
同时,比较‘诡异’的是直接使用当前时间(MySQL 中 UNIX_TIMESTAMP 不带参数,同时 PHP 直接使用 time 函数),却不存在误差(测试脚本)。
排除了 PHP 和 MySQL 之间因为时区设置造成的时间误差 -- 根据经验,如果是时区设置造成的时间误差,应该有几个小时不会那么少。
搜索解决问题期间扫了下这篇帖子,觉得应该是‘闰秒’这玩意造成的问题。搜索 PHP 闰秒相关的配置似乎没有相关的,不过在这里似乎找到了些答案。
You also can experience this behavior if your system timezone
is with leap seconds. To avoid the problem in this case please
run query UPDATE mysql.time_zone SET Use_leap_seconds='N'
and restart the server. Please inform us if this helps.
按照上述的步骤执行,解决了问题。
回过头来,我在工作机(Windows)上测试,发现并不起作用。研究了下,原来闰秒也需要操作系统的支持:
1、对于大多数新的 Linux 内核,在设计时它们都是支持闰
秒的,这一点在 REHL4/5 的 2.6.x 内核中得到肯定。
2、如果 Linux 系统没有配种某种时间同步机制(比如NTP),
那么和闰秒无关,唯一导致的结果只是系统时间会比 UTC
时间快一秒。
3、Window Time Service 不支持闰秒,包括服务器和客户端。
回过头来考虑项目中碰到的这种情况,直接使用时间戳存储时间点会更精确些。最后,提供下相关的测试脚本,看看你的环境是否也会有类似的问题。