说实话,第一次接触这类
测试,刚开始有些摸不到头脑,确切的说是摸不到重点,无论是测试还是TC,都让我很头疼,后来慢慢的,我就领悟到了这类测试的方法以及技巧,后来觉得真的很简单,并不像当初想的那么不容易。
首先明确哪些是需要测试的API
研发的代码中可能实现了很多API,首先必须明确哪些需要测,哪些不必要测;哪些整个迭代不测,下一个迭代再测;有一些接口是可能就直接调用另外一个接口,这些接口有没有必要测等。这些没有确定清楚直接导致漏测或者做无用功。
明确每个API实现的功能和设计TC
在确定了哪些接口需要测试之后,就必须明确每个接口实现的功能以及接口的参数、返回值的意义等。理解这些接口参数的含义,这些参数僵尸设计TC的维度,简单的说,这些参数可以看成一个一个输入框,李四网页手工测试一样,将准备数据输入即可。用黑盒的方法来为API设计TC和网页手工测试很类似,无非就是把参数看成输入框而已。但是
API测试在设计TC的时候还可以'偏白'一点,就是直接去看接口的实现的代码,特别是一些异常情况的处理,一般程序在异常处理上总是相对于正常情况要脆弱一些,然后对前面用黑盒的方法设计好的TC进行一些补充。
值得注意的是,1)TC设计的时候尽量详细,粒度尽量的小,测试代码都是类似的,可能仅仅是传入的参数不一样,而测试校验的
工作是计算机做的,所以一般情况下针对某个接口,10个TC和20个TC跑的花费是差不多的,但是测试粒度方面和代码覆盖率方面可能就增加了不少。2)TC也是要进行维护的,在测试执行阶段,如果发现需要补充TC,最好不要在现有的测试代码上改,要新加代码,同时在TC文档中也同步更新。如果是TC的缺陷,才去修改对应的代码,并在TC文档中做更新。3)在设计TC文档的时候,测试步骤的粒度最好能够细到每一步需要调用哪个函数或接口,有点类似伪代码的风格,这样在写代码的时候就不用怎么思考,仅仅去实现它。
我们做这类测试,是直接拿应用程序在本地开启service,首先你在启动service之前,要配置好
web.config文件,这个很重要,包括你测试所需要的
数据库名字以及相应API测试所需要的特殊配置。我们这里主要配置和外部有交互的一些service地址,以及一些数字电视产品的ID等信息。
API测试除了要测试功能以外还要测试接口。一个API或者函数可以作为一个单元,对这个单元进行
单元测试,可以用黑盒也可以用白盒方法。黑盒方法就是不去看这个单元的实现代码,只根据中广核单元的功能说明来设计
测试用例并进行测试。测试的时候可能需要写一些简单的代码来做数据准备,然胡去调用需要测试的接口,一般也需要写一些代码来接受或者验证被测单元的输出是否正确;
白盒测试方法就是同构分心被测单元的实现代码,根据不同的测试策略来设计测试用例并作相应的测试。平台产品的需求很多事来自网站,简而言之,平台产品提供API给网站研发使用。我们需要测的就是那些暴漏出来的API,确保这些API在功能上没有缺陷。
我在做API测试的时候,主要采用的是
黑盒测试方法,用Fiddler工具去调接口,这个方便又明了,很容易看出被测单元的输出是否正确。不过事先你需要明确的了解需求,以及整个系统的架构,需要了解都和哪些service有交互,都做哪些交互等。
当启动chrome作selenium测试时,如果没有设置driver,则会出错.
driver下载地址https://code.google.com/p/chromedriver/downloads/list
三种方式
1.命令行中带参数-Dwebdriver.chrome.driver
java -Dwebdriver.chrome.driver=chromedriver_win_22_0_1203_0b.exe org.junit.runner.JUnitCore seleniumtest_name
2.命令行中可以没有-Dwebdriver.chrome.driver,但是需要在环境变量path中添加
chromedriver.exe(注意此处文件名只能是chromedriver.exe)的路径.
例如chromedriver.exe的放在d:/中, 则把"d:/"添加到path变量中
此时命令简化为:
java org.junit.runner.JUnitCore seleniumtest_name
3.可以在.java源文件中显示设置chromedriver
System.setProperty("webdriver.chrome.driver","d:/chromedriver_win_22_0_1203_0b.exe")
RabbitMQ远程调用
测试,使用外部机器192.168.174.132上的RabbitMQ,使用之前需要对远程调用进行配置,操作过程见博文“解决RabbitMQ远程不能访问的问题”。
SendTest:
package com.mq.rabbitmq.rabbitmqtest; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Channel; import com.rabbitmq.client.QueueingConsumer; public class ReceiveTest { private final static String QUEUE_NAME = "ftpAgent"; private final static String userName = "admin"; private final static String password = "admin"; private final static String virtualHost = "/"; private final static int portNumber = 5672; private final static String hostName = "master"; private final static String host = "192.168.174.132"; public static void main(String[] argv) throws java.io.IOException, java.lang.InterruptedException { ConnectionFactory factory = new ConnectionFactory(); // factory.setHost("192.168.174.160"); factory.setUsername(userName); factory.setPassword(password); // factory.setVirtualHost(virtualHost); factory.setHost(host); factory.setPort(portNumber); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // channel.queueDeclare(QUEUE_NAME, false, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume(QUEUE_NAME, true, consumer); Date nowTime = new Date(); while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println("RecieveTime: " + nowTime); System.out.println(" [x] Received '" + message + "'"); } } } |
ReceiveTest:
package com.mq.rabbitmq.rabbitmqtest; import java.util.Date; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Channel; import com.rabbitmq.client.QueueingConsumer; public class ReceiveTest { private final static String QUEUE_NAME = "ftpAgent"; private final static String userName = "admin"; private final static String password = "admin"; private final static String virtualHost = "/"; private final static int portNumber = 5672; private final static String hostName = "master"; private final static String host = "192.168.174.132"; public static void main(String[] argv) throws java.io.IOException, java.lang.InterruptedException { ConnectionFactory factory = new ConnectionFactory(); // factory.setHost("192.168.174.160"); factory.setUsername(userName); factory.setPassword(password); // factory.setVirtualHost(virtualHost); factory.setHost(host); factory.setPort(portNumber); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // channel.queueDeclare(QUEUE_NAME, false, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume(QUEUE_NAME, true, consumer); Date nowTime = new Date(); while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println("RecieveTime: " + nowTime); System.out.println(" [x] Received '" + message + "'"); } } } |
运行结果:
SendTest:
磁盘IO是云主机的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类。
1、测试顺序读性能
fio --filename=/home/test -iodepth=64-ioengine=libaio--direct=1--rw=read--bs=1m--size=2g--numjobs=4--runtime=10 --group_reporting --name=test-read
2、测试顺序写性能
fio -filename=/home/test -iodepth=64-ioengine=libaio-direct=1-rw=write-bs=1m-size=2g-numjobs=4-runtime=20 -group_reporting -name=test-write
3、测试随机读性能
fio -filename=/home/test -iodepth=64-ioengine=libaio-direct=1-rw=randread-bs=4k-size=2G-numjobs=64-runtime=20 -group_reporting -name=test-rand-read
4、测试随机写性能
fio -filename=/home/test -iodepth=64-ioengine=libaio-direct=1-rw=randwrite-bs=4k-size=2G-numjobs=64-runtime=20 -group_reporting -name=test-rand-write
参数说明:
filename=/home/test 测试文件名称,通常选择需要测试的盘的data目录。
direct=1 测试过程绕过机器自带的buffer。使测试结果更真实。
rw=randwrite 测试随机写的I/O
rw=randrw 测试随机写和读的I/O
bs=4k 单次io的块文件大小为4k
size=2g 本次的测试文件大小为2g,以每次4k的io进行测试。
numjobs=64 本次的测试线程为64.
runtime=20 测试时间为20秒,如果不写则一直将2g文件分4k每次写完为止。
报告如何查看:
fio的结果报告内容丰富,我们主要关心的是两项:
磁盘的吞吐量bw,这个是顺序读写考察的重点
磁盘的每秒读写次数iops,这个是随机读写考察的重点
比如,下面是4个测试的结果部分截取:
test-read: (groupid=0, jobs=4): err= 0: pid=4752
read : io=839680KB, bw=76823KB/s, iops=75 , runt= 10930msec
顺序读,带宽76823KB/s,iops 75
test-write: (groupid=0, jobs=4): err= 0: pid=4758
write: io=899072KB, bw=42854KB/s, iops=41 , runt= 20980msec
顺序写,带宽42854KB/s, iops=41
test-rand-read: (groupid=0, jobs=64): err= 0: pid=4619
read : io=72556KB, bw=3457.4KB/s, iops=864 , runt= 20986msec
随机读,带宽3457.4KB/s, iops=864
test-rand-write: (groupid=0, jobs=64): err= 0: pid=4685
write: io=129264KB, bw=6432.4KB/s, iops=1608 , runt= 20097msec
随机写,带宽6432.4KB/s, iops=1608。
使用
shell分析了一些数据有一些时间了,而且分析的数据情况也是基于历史数据,今天写了个脚本对历史的数据进行一个简单的分析,看看准确率到底有多高。
这里有一个借助一个脚本12c.sh 对一些数据的排列百分比进行分析,比如今天有两个球队,主队让球一个,胜平负的概率为35%,40%,25%
表data里存放着一些样本数据,记录了球队的比赛情况。
sqlplus -s n1/n1 <<EOF set linesize 150 set pages 0 set feedback off spool check_$1.sh select 'ksh 12c.sh'||w||' '||t||' '||l||' '||rw||' '||rt||' '||rl||' ' from data where r=-1 and startdate='$1'; spool off; EOF ksh check_$1.sh |tee check_$1.log grep suggest check_$1.log |awk '{print $7" "$8" "$9" "$10" "$11" "$12" "$1" "$2" "$3" "$4" "$5" "$6}'>>filter_check.log cat filter_check.log function get_result { echo $1 sqlplus -s n1/n1 <<EOF set pages 0 select case when zhu>ke+1 then rpad('big win:',20)||to_number(w+rw)||' '||'$2'||','||'$3'||','||'$4'||','||'$5'||','||'$6'||','||'$7' when zhu=ke+1 then rpad('little win:',20)||to_number(w+rt)||' '||'$2'||','||'$3'||','||'$4'||','||'$5'||','||'$6'||','||'$7' when zhu=ke then rpad('tie:',20)||to_number(t+rl)||' '||'$2'||','||'$3'||','||'$4'||','||'$5'||','||'$6'||','||'$7' when zhu=ke-1 then rpad('little lose:',20)||to_number(l+rl)||' '||'$2'||','||'$3'||','||'$4'||','||'$5'||','||'$6'||','||'$7' when zhu<ke-1 then rpad('big lose:',20)||to_number(l+rl)||' '||'$2'||','||'$3'||','||'$4'||','||'$5'||','||'$6'||','||'$7' end end from data where startdate='$1' and w=$2 and t=$3 and l=$4 and rw=$5 and rt=$6 and rl=$7 order by (zhu-ke); EOF } while read line do echo ---start echo $line input_params=`echo $line|awk '{print $1" "$2" "$3" "$4" "$5" "$6}'` get_result $1 $input_params echo ....end echo . done <filter_check.log rm check_$1.log rm filter_check.log rm check_$1.sh |
分析结果如下,比如对前几天的比赛情况进行分析,在我不知道比赛结果的前提下。
5场比赛猜中了3场,仅供娱乐。
---start
1.24 5.35 7.6 1.8 3.75 3.28 suggest w :82% of total 11
2014-08-26
little win: 4.99 1.24,5.35,7.6,1.8,3.75,3.28
....end
.
---start
1.18 5.85 9.4 1.65 3.9 3.75 suggest w :71% of total 17
2014-08-26
tie: 9.6 1.18,5.85,9.4,1.65,3.9,3.75
....end
.
---start
1.43 4.15 5.42 2.42 3.4 2.38 suggest w :65% of total 97
2014-08-26
little lose: 7.8 1.43,4.15,5.42,2.42,3.4,2.38
....end
.
---start
2.1 2.95 3.25 4.7 3.6 1.57 suggest rl :68% of total 50
2014-08-26
tie: 4.52 2.1,2.95,3.25,4.7,3.6,1.57
....end
.
---start
1.1 6.75 15 1.45 4.2 4.95 suggest w :80% of total 5
2014-08-26
big win: 2.55 1.1,6.75,15,1.45,4.2,4.95
....end
CLASSPATH是什么?它的作用是什么?
它是javac编译器的一个环境变量。它的作用与import、package关键字有关。当你写下improt
java.util.*时,编译器面对import关键字时,就知道你要引入java.util这个package中的类;但是编译器如何知道你把这个 package放在哪里了呢?所以你首先得告诉编译器这个package的所在位置;如何告诉它呢?就是设置CLASSPATH啦 :) 如果java.util这个package在c:/jdk/ 目录下,你得把c:/jdk/这个路径设置到CLASSPATH中去!当编译器面对import java.util.*这个语句时,它先会查找CLASSPATH所指定的目录,并检视子目录java/util是否存在,然后找出名称吻合的已编译文件 (.class文件)。如果没有找到就会报错!CLASSPATH有点像c/c++编译器中的INCLUDE路径的设置哦,是不是?当c/c++编译器遇 到include 这样的语句,它是如何运作的?哦,其实道理都差不多!搜索INCLUDE路径,检视文件!当你自己开发一个package时,然后想要用这个 package中的类;自然,你也得把这个package所在的目录设置到CLASSPATH中去!CLASSPATH的设定,对JAVA的初学者而言是 一件棘手的事。所以Sun让JAVA2的JDK更聪明一些。你会发现,在你安装之后,即使完全没有设定CLASSPATH,你仍然能够编译基本的JAVA 程序,并且加以执行。 .....................................................................................................................................................
1. PATH环境变量。作用是指定命令搜索路径, 在命令行下面执行命令如javac编译java程序时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序。我们需要把jdk安装目录下的 bin目录增加到现有的PATH变量中,bin目录中包含经常要用到的可执行文件如javac/java/javadoc等待,设置好PATH变量后,就 可以在任何目录下执行javac/java等工具了。我们这里设定的PATH值为:
%SystemRoot%/system32;%SystemRoot%;%SystemRoot%/System32/Wbem;%SYSTEMROOT%/System32/WindowsPowerShell/v1.0/;C:/Program Files/Common Files/Thunder Network/KanKan/Codecs;C:/Program Files/Microsoft
SQL Server/90/Tools/binn/;C:/Program Files/Common Files/TTKN/Bin;C:/Program Files/Common Files/Teleca Shared;C:/Program Files/Java/jdk1.6.0_21/bin
上述只有红色部分;C:/Program Files/Java/jdk1.6.0_21/bin是java的PATH变量,注意变量之间需要用";”隔开。
2. CLASSPATH环境变量。作用是指定类搜索路径, 要使用已经编写好的类,前提当然是能够找到它们了,JVM就是通过CLASSPATH来寻找类的。我们需要把jdk安装目录下的lib子目录中的 dt.jar和tools.jar设置到CLASSPATH中,当然,当前目录“.”也必须加入到该变量中。这里CLASSPATH为:
.;C:/Program Files/Java/jdk1.6.0_21/lib/dt.jar;C:/Program Files/Java/jdk1.6.0_21/lib/tools.jar
3. JAVA_HOME环境变量。它指向jdk的安装目录,Eclipse/NetBeans/Tomcat等软件就是通过搜索JAVA_HOME变量来找到并使用安装好的jdk。这里JAVA_HOME为:
C:/Program Files/Java/jdk1.6.0_21
.....................................................................................................................................................
java环境变量配置步骤:
在
windows桌面上右击“我的电脑” —> “属性” —> “高级” —> “环境变量”,在“系统变量”里我们可以看到系统的各个环境变量的值。双击某个变量名可以修改变量值,变量值之间用“;”隔开。我们还可以“新建”原先没 有的变量。与jdk有关的有3个环境变量;“JAVA_HOME”,“PATH”,“CLASSPATH”。我的系统中“PATH”变量已经存在,可以直 接添加新值(其它变量值不要动,防止其它程序运行异常),其它两个变量需要新建。
CLASSPATH= .;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar
JAVA_HOME = C:/Program Files/Java/jdk1.5.0
PATH = %JAVA_HOME%/bin;%JAVA_HOME%/jre/bin
从上面我们可以看出,PATH和CLASSPATH都使用到了JAVA_HOME,也可以使用绝对路径,两者皆可。
Tomcat环境变量配置:
系统变量中新建
BASEDIR,路径为:Tomcat根目录,如D:\Tomcat
其它与java jdk相关的引用路径可以查看文件bin\setclasspath.bat
注意,java环境变量配置JAVA_HOME主要为了其它容器调用,JAVA_HOME的java jdk路径后边不带“;” 即不可分号结束。
.....................................................................................................................................................
Tomcat\bin中setclasspath.bat文件 rem --------------------------------------------------------------------------- rem Set CLASSPATH and Java options rem rem $Id: setclasspath.bat,v 1.6.2.1 2004/08/21 15:49:50 yoavs Exp $ rem --------------------------------------------------------------------------- rem Make sure prerequisite environment variables are set if not "%JAVA_HOME%" == "" goto gotJavaHome echo The JAVA_HOME environment variable is not defined echo This environment variable is needed to run this program goto exit :gotJavaHome if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome if not exist "%JAVA_HOME%\bin\javaw.exe" goto noJavaHome if not exist "%JAVA_HOME%\bin\jdb.exe" goto noJavaHome if not exist "%JAVA_HOME%\bin\javac.exe" goto noJavaHome goto okJavaHome :noJavaHome echo The JAVA_HOME environment variable is not defined correctly echo This environment variable is needed to run this program echo NB: JAVA_HOME should point to a JDK not a JRE goto exit :okJavaHome if not "%BASEDIR%" == "" goto gotBasedir echo The BASEDIR environment variable is not defined echo This environment variable is needed to run this program goto exit :gotBasedir if exist "%BASEDIR%\bin\setclasspath.bat" goto okBasedir echo The BASEDIR environment variable is not defined correctly echo This environment variable is needed to run this program goto exit :okBasedir rem Set the default -Djava.endorsed.dirs argument set JAVA_ENDORSED_DIRS=%BASEDIR%\common\endorsed rem Set standard CLASSPATH rem Note that there are no quotes as we do not want to introduce random rem quotes into the CLASSPATH set CLASSPATH=%JAVA_HOME%\lib\tools.jar rem Set standard command for invoking Java. rem Note that NT requires a window name argument when using start. rem Also note the quoting as JAVA_HOME may contain spaces. set _RUNJAVA="%JAVA_HOME%\bin\java" set _RUNJAVAW="%JAVA_HOME%\bin\javaw" set _RUNJDB="%JAVA_HOME%\bin\jdb" set _RUNJAVAC="%JAVA_HOME%\bin\javac" goto end :exit exit /b 1 :end |
前言:mysql参数的修改在mysql的课程里面应该属于相对基础的知识,但是作为一个mysql的初学者还是很有必要弄懂这个知识点,以后的
学习过程中将会经常用到的。技术很多时候都是相通的,如果有学过oracle的朋友应该会知道,oracle的参数里面有几个标签:动态参数、静态参数、session级别修改、全局修改、立即生效和延迟生效。作为数据库mysql也同样有这些特性,但是整体学起来后会发现mysql某些方面还是没有oracle做的到位,在该文档的最后咱们再做个总结。
一、参数文件
1、查看参数文件
通过命令行"mysql --help | grep my.cnf"查看my.cnf文件的位置,linux操作系统中参数文件默认为/etc/my.cnf,按照mysql官方文档的说明,mysql的启动参数文件的顺序如下:
1、查找根据顺序查找全局 /etc/my.cnf /etc/mysql/my.cnf /SYSCONFDIR/my.cnf为全局选项
2、$MYSQL_HOME/my.cnf为服务指定变量
二、参数文件的修改
1、动态参数和静态参数的概念
Mysql 的参数类型:分为动态(dynamic)和静态参数(static);
动态参数意味着可以再mysql实例运行中进行更改;
静态参数说明在整个实例声明周期内都不得进行更改,就好像是只读的。
在动态参数中,有些参数修改可以是基于回话的也可以是基于整个实例的生命周期。
2、全局变量与会话变量
全局变量在MYSQL启动的时候由服务器自动将它们初始化为默认值。会话变量在每次建立一个新的连接的时候,由MYSQL来初始化。MYSQL会将当前所有全局变量的值复制一份。来做为会话变量。(也就是说,如果在建立会话以后,没有手动更改过会话变量与全局变量的值,那所有这些变量的值都是一样的。全局变量与会话变量的区别就在于,对全局变量的修改会影响到整个服务器,但是对会话变量的修改,只会影响到当前的会话(也就是当前的
数据库连接)
3、参数的查看方式
Mysql的参数可以通过"show variables"来查看,由于从mysql5.1版本开始,可以通过information_schema架构下的GLOBAL_VARIABLES视图来进行查找,所以也可以这样查看"select * from information_schema.global_variables";
查看参数的脚本:
语句一、
mysql> SHOW VARIABLES LIKE 'max_join_size';
mysql> SHOW GLOBAL VARIABLES LIKE 'max_join_size';
语句二、
mysql> select * from information_schema.global_variables; +---------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ | VARIABLE_NAME | VARIABLE_VALUE | +---------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+ | MAX_PREPARED_STMT_COUNT | 16382 | | INNODB_BUFFER_POOL_SIZE | 134217728 | | HAVE_CRYPT | YES | | PERFORMANCE_SCHEMA_EVENTS_WAITS_HISTORY_LONG_SIZE | 10000 | | INNODB_VERSION | 5.5.36 | | QUERY_PREALLOC_SIZE | 8192 | | DELAYED_QUEUE_SIZE | 1000 | | PERFORMANCE_SCHEMA_MAX_COND_INSTANCES | 1000 | | SSL_CIPHER | | | COLLATION_SERVER | utf8_general_ci | | SECURE_FILE_PRIV | | | TIMED_MUTEXES | OFF | | DELAYED_INSERT_TIMEOUT | 300 | | PERFORMANCE_SCHEMA_MAX_MUTEX_INSTANCES | 1000000 | | LC_TIME_NAMES | en_US |
4、参数的修改,参数的修改有以下几种方法,作为学习、便于理解其中的原理所在,这里把几种方法都整理出来了,欢迎各位的查看
方法一、修改参数文件。所有的参数都保存在/etc/my.cnf文件中,所以直接修改该参数文件便可修改相应的系统参数。
弊端:修改该参数需要重启后才能生效,当系统上线后一般都不能随便重启,所以该方法很少用;
操作方法:
1、修改参数文件/etc/my.cnf,添加general_log_file = /data/mysql/mysql_2.logvi /etc/my.cnf
# The MySQL server [mysqld] port = 3306 socket = /tmp/mysql.sock skip-external-locking key_buffer_size = 384M max_allowed_packet = 1M table_open_cache = 512 sort_buffer_size = 2M read_buffer_size = 2M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 64M thread_cache_size = 8 query_cache_size = 32M # Try number of CPU's*2 for thread_concurrency thread_concurrency = 8 general_log_file = /data/mysql/mysql_2.log |
2、重启mysql服务
service mysqld stop
3、检查参数是否生效
mysql> show variables like 'general%';
+------------------+-------------------------+
| Variable_name | Value |
+------------------+-------------------------+
| general_log | OFF |
| general_log_file | /data/mysql/mysql_2.log |
+------------------+-------------------------+
2 rows in set (0.00 sec)
当前显示已生效
方法二、如果是动态参数的话,便可以直接通过语句修改。
(http://dev.mysql.com/doc/refman/5.6/en/dynamic-system-variables.html mysql的所有参数详情介绍
sql语法:
SET variable_assignment [, variable_assignment] ... //可以同时修改多个参数
variable_assignment:
user_var_name = expr
| [GLOBAL | SESSION] system_var_name = expr
| @@[global. | session.]system_var_name = expr
例子:
SET sort_buffer_size=10000; /修改SESSION参数
SET @@local.sort_buffer_size=10000; /修改全局参数
SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000; /同时修改多个SESSION参数
SET @@sort_buffer_size=1000000; /第二种修改全局参数的方法
SET @@global.sort_buffer_size=1000000, @@local.sort_buffer_size=1000000;
说明如下:
1)修改SESSION的参数的影响:如果您使用SESSION(默认情况)设置一个系统变量,则该值仍然有效,直到当前会话结束为止,或者直到您把变量设置为一个不同的值为止。
2)如果您使用GLOBAL(要求SUPER权限)来设置一个系统变量,则该值被记住,并被用于新的连接,直到服务器重新启动为止。
如果您想要进行永久式变量设置,需要写入到参数文件。(通过SET命令并不会修改参数文件的内容,还需要另行修改,这点做的没有ORACLE好)
3)为了防止不正确的使用,如果您使用SET GLOBAL时同时使用了一个只能与SET SESSION同时使用的变量,或者如果您在设置一个全局变量时未指定GLOBAL(或@@),则MySQL会产生一个错误。( SET GLOBAL命令修改SESSION参数的时候会报错)
4)如果您想要把一个SESSION变量设置为GLOBAL值或把一个GLOBAL值设置为内部MySQL默认值,需使用DEFAULT关键词。例如,在把max_join_size会话值设置为全局值时,以下两个语句是一样的:SET max_join_size=DEFAULT;(恢复成默认值的设置)
总结:1、mysql的参数设置相对oracle来说较为简单。
2、针对参数设置的方法本身没有太多经验,作为一个DBA不管是修改oracle参数、或mysql参数,建议每个数据库都有一个文档用于记录参数修改的历史,这样哪台出现了问题,便于跟踪;
根据IEEE 828和CMM/CMMI,
配置管理计划常常被认为是一份文档,确实的,对于一个大项目而言,往往需要制定项目自身的配置管理计划。
但不是所有的组织都是软件外包组织,不是每个项目针对的是不同的客户。
在非软件外包的高效
软件开发组织中,推荐的配置管理计划应有三个层面。
首先是组织层面,一般,提供统一的配置管理服务,不会允许每个团队自己搭建配置管理服务器。所以对于组织级的配置管理服务要有所约定,约定的主要内容有:
如何建立项目文档目录?
如何建立产品级目录?
如何建立代码目录?
配置项如何命名?
配置库的备份和恢复如何进行?谁来进行?
什么情况下拉分支?什么情况下合并到主干? 关于分支主干要提供多种模式,或者放开限制,让产品线或者项目组选择。
如何进行变更? 一般应当在组织级进行定义和发布。如果放到项目层面,变更流程的制定太费功夫;当然有些大项目是有足够的预算和特殊情况需要专门定义项目级的变更。
对产品线和项目如何开展配置审计?
有什么推荐的配置管理实践?
组织级配置管理规程或者指南的更新频率在每年一次左右。
其次是产品线层面。对于特定产品线,已经存在大量的源代码和文档,那么结合实际,这个产品线在配置管理存储时有哪些约定?
比如对代码配置项和非配置项有所说明,不要假设每个团队新人都是代码配置管理达人,小心自以为是的新手加入一些自以为是的垃圾。虽然可以删除,但发现再删除,其本身就是成本。
比如哪些依赖项值得存储?
比如哪些区域是机密,权限另外管理
比如那些代码是核心代码,如果改动需要资深人员复核。
本产品线的主干和分支策略是什么? 守护主干?还是先锋主干?无分支?还是单分支?还是多分支?
比如约定团队统一一致的
工作环境:都把
Java装在C:/java,把eclipse装在D:/eclipse
最后是项目层面。在有了上述组织级和产品线级的配置管理约定后,项目层面的配置管理计划中最关键的是需要明确人员、基线和项目特殊配置项。其中基线的安排必须与项目本身生命周期的选择相匹配,最重要而言,必须匹配于里程碑。
在这样的三层结构下,为项目高效计,不需要单独写项目的配置管理计划,只需把项目级的配置管理约定写入项目计划即可,一般的篇幅不超过1页。
项目所处的阶段越早,项目不确定性就越大,项目调整或变更的可能性就越大,同时带来的代价比较低。但随着项目的进行,不确定性逐渐减小,而变更的代价、付出的人力、资源逐渐增加,就会增加决策的困难度。
一旦项目变更发生了,项目经理该怎么处理呢?
1.记录变更请求(CR): 任何变更,不论以后是否会被接受,都应该首先记录下来,有些变更请求也许在本阶段不被接受,也许可以成为以后参考的功能或范围。所以对于任何变更请求,首先要做的是记录下来是一个什么样的变更请求,是由哪一类项目干系人提出来的,以及相应的联系方式。
2.澄清变更细节,分析相应变更请求的必要性。
3.对变更请求产生的原因进行分析,像是由于在项目初期对需求没有明确产生的项目变更,或是没有明确项目范围产生的变更,还是由于外部事件产生的变更。
4.根据变更请求,分析变更对现有项目进度的影响程度,及变更之间的依赖关系。
5.根据变更请求对现有项目进度的影响程度,确认相应的成本估计。
6.对项目变更排列优先级。
7.同项目赞助人协商项目变更影响,解决变更请求需要符合的条件以及相应的费用,并达到项目赞助人的可接受程度。最终确定是否实施变更。
8.项目配置控制委员会批准相应的项目范围变更,进度计划,人员和费用计划。
9.将变更加入详细计划,更新相应文档,通知相应项目干系人(变更的内容、进度、人员、费用)。
10.执行并提交项目变更。
11.在项目变更被接受后,终止变更请求。
12.记录实际项目变更所带来的影响,汲取教训。
背景:已经使用Jira和
Confluence管理了一个产品团队的任务和资源,现在又想加入另外一个产品团队的任务和资源,首要问题是如何解决两个团队之间的权限隔离。研究了半天,阅读了Jira和confluence的相关文档,终于搞定,现在分享给大家。
Jira
打开系统管理中的权限模型我们可以看到现在有系统默认的权限模型和我自定义的两个权限模型(建议自建权限模型时采用复制默认模型的方法然后进行更改)
我们打开系统的默认权限模型可以看到系统默认的三种用户组(管理员,开发者,普通用户)
我们可以打开tester的权限模型然后对相应权限应用的用户组进行更改
这些组和组成员的管理在用户、组及角色中进行设置
3.我们再把项目的权限模型改为需要的权限模型即可
Confluence
Confluence不同产品团队间的资源权限可以利用“空间”的方式来做隔离,如下所示
创建一个空间,标红的地方本来是默认选中的,我们不选它们,以便之后的隔离权限。
创建空间后管理员可以进入相应空间的空间管理界面进行权限设置,比如这里除管理员外我只给ibaby组用户分配关于此产品空间的权限。
这些组和组成员在站点管理的管理用户中设置即可。
这样当某个用户登录后只会看到自己所属组拥有权限的空间。
一点小感想:我个人感觉Jira和Confluence不仅功能完善、流程清晰、易用性也好;更重要的是它的主旨是鼓励团队间的协作,千万不要把它作为一个监控员工工作的工具。现在很多公司还在继续采用限制监管员工的管理方式,采用这种自上而下的监管,不如接受自下而上的协作去推动工作。