Tuesday, March 11, 2014

网上购物快捷链接


Monday, October 13, 2008

使用svnserve.exe作为Subversion服务器的简单设置

作者: 陈海青(josonchen,"船长")

(http://www.chq.name/)
(http://www.hhrz.org/)
(http://junit.vicp.net/)
日期:2008.09.29(yyyy.mm.dd)

使用版本管理服务器,不仅仅是一个文件服务器,还能记录并随时恢复每一次改变,对于团队开发自然是必不可少的,对个人使用也能提供很多方便。针对个人或小团队开发的情况,不需要复杂的配置,几步简单的安装和设置,svn就可以就位了,本文记录的就是了利用 svnserve.exe 来作为版本库服务器端,配合使用客户端软件TortoiseSVN的简单设置,主要参照了http://bbs.iusesvn.com/的文章。

1:下载安装(也可到本站hhrz.org 或 chq.name下载中心--Subversion下载:
http://www.chq.name/option,com_remository/Itemid,72/func,select/id_20.htmlhttp://nchc.dl.sourceforge.net/sourceforge/tortoisesvn/TortoiseSVN-1.4.8.12137-win32-svn-1.4.6.msihttp://subversion.tigris.org/files/documents/15/41687/svn-1.4.6-setup.exe

2:配置svn版本库
1)建立版本库:设定版本库的根目标目录:d:\svn_root\版本库,建立项目子目录 movie,使用客户端软件TortoiseSVN在其中建立仓库结构。
2)建立工作拷贝:将初始版本拷贝过来。然后在命令行启动svn:
SVNserve -d -r d:\svn_root\版本库
3) 配置权限:编辑d:\svn_root\版本库\movie\conf 目录中的三个文件
``代码库基础配置文件svnserve.conf`` ,如下::(实际上就是去掉几个注释符#)
[general]
anon-access = none
auth-access = write
password-db = passwd a
uthz-db = authz.conf

``用户帐号文件 passwd`` ,如下::(增加几条记录 用户名=口令)

[users] admin = adminpwd

目录访问权限控制文件authz.conf`` 文件,内容如下::(设置用户组和项目各目录的访问权限)

[groups]
g_admin = admin
[movie:/]
@g_admin = rw * = r

4)import工作拷贝到版本库(访问地址:svn://localhost/movie),使用客户端软件TortoiseSVN,在工作拷贝目录上操作,使用上述设定的用户名和口令:admin/adminpwd

5)测试:重新下载工作拷贝

6)建立自动运行的服务 下载SVNService(参考附录中的SVNService(将svn作为windows服务运行的工具),chq.name的下载中心也有下载),拷贝到:subversion的安装目录的bin子目录中,如D:\Program Files\Subversion\bin 在该目录中运行以下命令,安装服务: SVNservice -install -d -r d:\svn_root\版本库
附录:1:参考文章:1):Subversion之路--实现精细的目录访问权限控制(v1.0 更新于2006.12.05):
http://bbs.iusesvn.com/thread-6-1-1.html
2):[录像视频]windows安装基于svnserve的subversion服务器演示动画(http://bbs.iusesvn.com/thread-236-1-1.html
2:有关资料1) 本站hhrz.org/chq.name下载中心--Subversion :
http://www.chq.name/option,com_remository/Itemid,72/func,select/id_20.html2):SVNService(将svn作为windows服务运行的工具)http://bbs.iusesvn.com/viewthread.php?tid=137&extra=page%3D1%26amp%3Bfilter%3Ddigest

3):Subversion简单常用问题解决方案列表(http://bbs.iusesvn.com/viewthread.php?tid=1981&extra=page%3D1%26amp%3Bfilter%3Ddigest):
经常有新手配置基于svnserve的subversion服务器后,在客户端访问subversion版本库时出现这个错误:svnserve.conf:12: Option expected为什么会出现这个错误呢,就是因为subversion读取配置文件svnserve.conf时,无法识别有前置空格的

4):eclipse使用subclipse导致jvm崩溃(http://doc.iusesvn.com/show-35-1.htmlhttp://subclipse.tigris.org/serv ... ers&msgNo=10234里面说是由于安装svn1.4.4和apache2.2时,一个环境变量所导致的,
原文如下:Subclipse can crash on Windows if you have the environment variableAPR_ICONV_PATH set and it is pointing at a set of libraries that werebuilt against Apache 2.2. If that is the case, change the environmentvariable name to APR_ICONV1_PATH and that will fix the problem. Thelibraries from 2.2 will look for the variable with the "1" in it firstanyway. So this is a proper change to make.
If you want to be thorough, you could download the zip file forSubversion 1.4.3, and point the APR_ICONV_PATH variable at the iconvfolder that came with it.

解决方法:将环境变量 APR_ICONV_PATH改为APR_ICONV1_PATH或者下载Subversion 1.4.3的zip包,将环境变量 APR_ICONV_PATH 指向解压后的 iconv文件夹。

Wednesday, May 23, 2007

在ORACLE数据库上创建VPD(Virtual Private Databases)安全策略的实战记录

在ORACLE数据库上创建VPD(Virtual Private Databases)安全策略的实战记录


作者:陈海青(joson chen)
网站:www.chq.name

日期:2007.05.24


版权声明:转载或引用本网版权所有之内容须注明“转自(或引自)chq.name (Junit fans)”字样,并标明本网站网址 http://www.chq.name


一、关于VPD
VPD,即:Virtual Private Database,提供了对数据库的精密访问控制(graind access
control (FGAC)).
使用VPD,可以在数据记录集定义用户的访问权限.


二、使用VPD的示例:


1)未进行权限控制时,执行的查询语句,可以看到所有商品在2002年的销售额:
SELECT year, prod_category,
sum(sales)
FROM sales_mv
WHERE year = '2002';


2)如果加上了VPD策略,限制访问指定范围内的产品(例如仅能访问'VIDEOS','RADIOS'),
再执行上述的查询语句,会自动加上限制条件--AND
prod_category in ('VIDEOS','RADIOS'),最后实际执行的语句为:


SELECT year, prod_category, sum(sales)
FROM sales_fact
WHERE year =
'2002'
AND prod_category in ('VIDEOS','RADIOS'); --自动加上的限制条件


三、操作的过程


以下为作者总结在ORACLE数据库上创建vpd(Virtual Private Databases),完成安全策略管理,并应用于www.chq.name上的实战记录,于070524更新完毕。


1:确定数据库对象及互相之间的关系
1)相关表和视图

数据库中有两类表,代码表和数据表,数据表均有一个“机构代码”字段(DM_JG),
其“前七位”等于用户代码表的“机构代码”

建立脚本:
CREATE TABLE dm_users
(
user_dm VARCHAR2(11) NOT
NULL,

jg_dm
VARCHAR2(11) NOT NULL
);

CREATE TABLE
DIM_JBXX
(pk VARCHAR2(50) NOT
NULL,
data VARCHAR2(11)
jg_dm
VARCHAR2(11) NOT NULL); --www.chq.name

CREATE VIEW
VIEW_JBXX as select * from DIM_JBXX
;


2)相关用户,并为其授权

相关用户有三个:

VPD:数据表和VPD对象的属主,允许访问全部数据;
1234502
:数据访问用户,其用户名为其单位代码的前7位,访问受限用户
建立脚本:

CONNECT sys/password@www.chq.name
AS SYSDBA;
CREATE USER VPD IDENTIFIED BY VPD

DEFAULT TABLESPACE VPD TEMPORARY TABLESPACE temp;
GRANT connect,
resource TO VPD;

CREATE USER 1234502 IDENTIFIED
BY 1234502
DEFAULT TABLESPACE users TEMPORARY TABLESPACE
temp;
GRANT connect, resource TO 1234502;



GRANT EXECUTE ON DBMS_RLS TO PUBLIC;


CONN VPD/VPD@www.chq.name


GRANT SELECT, INSERT ON V_JBXX TO 1234502, 1234512;


2:定义安全策略(Security Policies)的目标


在数据库里,每个用户分配一个机构代码,在这里直接使用该代码的前7位作为用户名,相关的数据表均有一个“机构代码”字段
安全策略目标:每个用户仅能浏览和操作“机构代码”与自己的机构代码相同的数据记录。
例外情况:vpd用户可以不受限制访问数据


3:创建应用环境(Application Context)

应用环境是一个包含系列环境变量名称和值的值对的集合,是存储用户的环境变量的空间;
系统提供了默认的环境USERENV,含有当前会话相关的默认的变量,如用户名、主机和应用程序名等


1)为创建VPD的context和context package的用户授权,
CONNECT sys/password@www.chq.name AS
SYSDBA;
GRANT create any context, create public synonym TO
VPD;
CONNECT VPD/VPD@www.chq.name;


2)创建应用环境 CTX_VPD_SEC
CREATE CONTEXT CTX_VPD_SEC USING
VPD.PKG_VPD_SEC;


4:创建VPD应用程序包,在包里增加设置环境变量的函数、存储过程

这个包的作用是提供设置环境变量的工具(函数或存储过程),供on login触发器或应用程序等调用。


1) 创建VPD应用程序包PKG_VPD_SEC的包头
CONNECT VPD/VPD@www.chq.name;

CREATE OR REPLACE PACKAGE VPD.PKG_VPD_SEC AS

PROCEDURE Set_Context;
END PKG_VPD_SEC;


2)创建VPD应用程序包的包体
CREATE OR REPLACE PACKAGE BODY
VPD.PKG_VPD_SEC IS
PROCEDURE Set_Context IS

lv_user VARCHAR2(11);
lv_jg_dm
VARCHAR2(11);
BEGIN

DBMS_Session.Set_Context('CTX_VPD_SEC','SETUP','TRUE');

v_ouser := SYS_CONTEXT('USERENV','SESSION_USER');

DBMS_Session.Set_Context('CTX_VPD_SEC','DM_USER',
lv_user);
BEGIN
SELECT
substr(JG_DM,1,7)
INTO
lv_jg_dm
FROM
dm_users
WHERE user_dm =
lv_user;

DBMS_Session.Set_Context('CTX_VPD_SEC','JG_DM', lv_jg_dm);

EXCEPTION
WHEN NO_DATA_FOUND
THEN

DBMS_Session.Set_Context('CTX_VPD_SEC','JG_DM',
substr(lv_user,1,7));
END;

DBMS_Session.Set_Context('CTX_VPD_SEC','SETUP','FALSE');
END
Set_Context;
END PKG_VPD_SEC;
/
SHOW ERRORS


3)授权其他用户可以访问并运行 PKG_VPD_SEC 包:
GRANT EXECUTE ON VPD.PKG_VPD_SEC TO
PUBLIC;
CREATE PUBLIC SYNONYM PKG_VPD_SEC FOR VPD.PKG_VPD_SEC;


4)建立用户登陆触发器,每次登录后首先设置自己的应用环境变量
CONNECT sys/password@www.chq.name AS
SYSDBA;
CREATE OR REPLACE TRIGGER VPD.Set_Security_Context
AFTER LOGON ON
DATABASE
BEGIN
VPD.PKG_VPD_SEC.Set_Context;
END;
/
SHOW
ERRORS


5:创建VPD应用程序-安全策略包,创建策略函数,为简便起见仍使用PKG_VPD_SEC

这是实现策略的函数,该函数从应用环境取得变量值,形成查询语句的一部分


1)建立安全策略( Security Policies)包的包头,简便起见修改PKG_VPD_SEC
--In order for the
context package to have any effect on the users interaction with the database,

--we need to define a Security_Package for use with the security policy.

--This package will tell the database how to treat any interactions with the
specified table:


CONNECT vpd/vpd @ www.chq.name;


CREATE OR REPLACE PACKAGE VPD.PKG_VPD_SEC AS
PROCEDURE
Set_Context;


FUNCTION User_Data_Insert_Security(Owner VARCHAR2, Objname
VARCHAR2)
RETURN VARCHAR2;

FUNCTION
User_Data_Select_Security(Owner VARCHAR2, Objname
VARCHAR2)
RETURN VARCHAR2;
END
Security_Package;
/
2)修改包体,增加安全策略函数:


CREATE OR REPLACE PACKAGE BODY Security_Package IS


PROCEDURE Set_Context IS
......
END
Set_Context;


FUNCTION User_Data_Select_Security(Owner VARCHAR2, Objname
VARCHAR2)RETURN VARCHAR2 IS
Predicate
VARCHAR2(2000);
BEGIN
Predicate :=
'1=2';
IF (SYS_CONTEXT('USERENV','SESSION_USER') = 'VPD')
THEN
Predicate := NULL;

ELSE
Predicate := 'JG_DM =
SYS_CONTEXT(''CTX_VPD_SEC'',''JG_DM'')';
END
IF;
RETURN Predicate;
END
User_Data_Select_Security;


FUNCTION User_Data_Insert_Security(Owner VARCHAR2, Objname VARCHAR2)
RETURN VARCHAR2 IS
Predicate VARCHAR2(2000);

BEGIN
Predicate := '1=2';
IF
(SYS_CONTEXT('USERENV','SESSION_USER') = 'VPD')
THEN
Predicate := NULL;

ELSE
Predicate := 'JG_DM =
SYS_CONTEXT(''CTX_VPD_SEC'',''JG_DM'')';
END
IF;
RETURN Predicate;
END
User_Data_Insert_Security;
END Security_Package;
/
SHOW
ERRORS
3)授权所有用户可以访问并运行安全策略包 PKG_VPD_SEC:


GRANT EXECUTE ON VPD.PKG_VPD_SEC TO PUBLIC;
--CREATE PUBLIC
SYNONYM PKG_VPD_SEC FOR VPD.PKG_VPD_SEC;


6:将策略函数应用到一个表或视图上
使用oracle
提供的DBMS_RLS包来实现安全策略的应用管理。
例如:
CONNECT VPD/VPD@www.chq.name;


BEGIN
DBMS_Rls.Add_Policy('VPD', 'VIEW_JBXX',
'USER_DATA_INSERT_POLICY',


'VPD',
'PKG_VPD_SEC.USER_DATA_INSERT_SECURITY',

'INSERT', TRUE);
DBMS_Rls.Add_Policy('VPD', 'VIEW_JBXX',
'USER_DATA_INSERT_POLICY',


'VPD',
'PKG_VPD_SEC.USER_DATA_INSERT_SECURITY',

'SELECT');

END;
或者:
execute
DBMS_RLS.ADD_POLICY(object_schema=>'VPD',object_name=>'V_FACT_data',policy_name=>'USER_DATA_INSERT_POLICY',

function_schema=>'VPD',policy_function=>'PKG_VPD_SEC.USER_DATA_INSERT_SECURITY',

statement_type=>'select',update_check=>FALSE,enable=>true)

)


注意事项:
1)DBMS_RLS包最初的运行权限须由sys用户授予VPD用户。
2)插入失败的报错信息:
ORA-28115:
policy with check option violation



参考资料:
1 : Oracle9i DBA Handbook ,Kevin Loney and Marlene Theriault ,etc, The McGraw-Hill co.Inc. 中文版:蒋蕊等译 机械工业出版社
2: http://www.oracle-base.com/articles/8i/VirtualPrivateDatabases.php
3:http://www.adp-gmbh.ch/ora/security/VPD/index.html
4:http://www.chq.name
5: http://xsb.itpub.net/post/419/59520
6: http://junit.vicp.net
7:http://zhouwf0726.itpub.net/post/9689/158056



Saturday, May 19, 2007

kettle2.3.1升级到2.5.0后 相关API的变化

kettle2.3.1升级到2.5.0后 相关API的变化
use kettle API under version 2.5.0
作者:陈海青(joson chen)
网站:http://www.chq.name/
日期:2007.05.13

版权声明:转载或引用本网版权所有之内容须注明“转自(或引自)chq.name (Junit fans)”字样,并标明本网站网址http://www.chq.name

1:需引入新的jar包:commons-vfs-1.0.jar
should import the new jar:commons-vfs-1.0.jar
2:使用oracle数据库时,构造TransMeta时,可以使用SchemaName参数,而不必在表名加SchemaName,已由www.chq.name使用oracle9i进行了测试.
when fill in TransMeta ,should use the parameter SchemaName,in 2.3.1,use tablename =SchemaName . tablename ,tested by http://www.chq.name/ on oracle9i.
3:使用新的构造方法StepMeta(fromstepid, fromstepname,(StepMetaInterface) tii) 代替原来的StepMeta(log,fromstepid, fromstepname,(StepMetaInterface) tii)。因为参数logging已经是单实例的,不必再作为参数传送了。
use new constructor method StepMeta(fromstepid, fromstepname,(StepMetaInterface) tii),delete the parameter log,for deprecated The logging is now a singlton, use the constructor without it.
4:将TableInputMeta原来的方法 setDatabase(targetDBInfo) 替换为 setDatabaseMeta(targetDBInfo),这个替换很生硬,使用原来的方法直接显示"未定义的方法".
in class TableInputMeta,use method "setDatabaseMeta(targetDBInfo)" replace the old one ,setDatabase(targetDBInfo),otherwise, compiler will report : The method setDatabase(DatabaseMeta) is undefined for the type TableInputMeta.

Friday, October 06, 2006

oracle数据库在linux上的克隆(clone)和迁移

oracle数据库在linux上的克隆(clone)和迁移

作者:陈海青 (joson) http://www.chq.name/
日期:2006。09。23

版权声明:转载或引用本网版权所有之内容须注明“转自(或引自)chq.name (Junit fans)”字样,并标明本网站网址http://www.chq.name
一、起因:
为搭建一个开发、测试环境,需要克隆一个现有的oracle数据库系统,于是记录了操作过程,供参照。
二、系统环境:
1)被克隆的主机(简称主机http://www.chq.name/):操作系统:redhat 企业版 REHL4.0,数据库:oracle9i
2)克隆目标主机(简称客机http://www.chq.name/):操作系统:redhat 企业版 REHL4.0
三、克隆策略的确定:有几种方法:
一)、硬盘克隆。 限制:
1)主、客机硬件配置要一致;
2)硬盘容量要一致
优点:不必进行操作系统和数据库安装
二)远程拷贝数据库程序和数据文件。
优点:不必安装数据库软件,不必恢复数据。
缺点:需要为运行数据库管理程序进行额外配置。
限制:要选择好合适的拷贝方式(rcp/rsync/cp等),才能高效易用
三)使用exp/imp或者其他数据库备份和恢复手段 优点:经典方法,安全可靠 缺点:
1)速度慢;
2)需要中间性数据存储空间
最后,考虑到效率和空间的因素,最后选择远程拷贝,使用rsync,配置简便、高效、易于管理。

四、操作步骤:
一)下载并在主客机上安装rsync软件,略。
二)编辑主客机的hosts文件,加上对方主机
# vi /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 http://www.chq.name/ localhost.localdomain localhost
192.168.17.35 http://www.chq.name/ localhost.localdomain localhost
192.168.17.22 http://www.chq.name/
三)在主机上进行配置:
1:建立并编辑编辑rsyncd配置文件[
root@www.chq.name_22 ~]# vi /etc/rsyncd.conf
uid=oracle
gid=dbause
chroot=nomax
connections=4
use chroot=no
logfile=/var/log/rsyncd.log
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
auth users=root
secrets file=/etc/rsyncd.pwd
[opt_oracle]
path=/opt/oracle
comment=backup oracle
ignore errors
read only=yes
list=no
auth users=root
。。。。。。
2:建立并编辑编辑rsyncd配置文件
[http://www.chq.name/_22 ~]# vi /etc/rsyncd.pwd
oracle:www.chq.name
3:启动rsync服务器,检查是否运行
[http://www.chq.name_22/ ~]# rsync --daemon[
[http://www.chq.name/_22 ~]# ps -ef grep rsyncroot
四)客户机上的操作
1:安装oracleserver的主版本
(我用的是9.2.0),不必打补丁,主要目的是通过安装来,避免进行其他设置。(由于没时间测试要如何配置,暂时使用这个简便办法)
2:列主机目录下文件
[http://www.chq.name/_35]# rsync rsync://oracle@www.chq.name_22/oradata/ Password:
3:传送文件:
[http://www.chq.name/_35]# rsync -azv rsync:oracle@www.chq.name_22/oradata /oradata
Password:
receiving file list ... donedb/db2_cx_tmp01.dbf。。。db/db2_tmp01.dbf。。。
4:设置oracle数据库
4.1)更改数据库监听器配置[http://www.chq.name/_35]# su - oracle
$ pwd/home/oracle
$ cd /opt/oracle/product/9.2.0/net*/admin[
$ vi listener.ora
4.2)更改数据库tns配置文件
# TNSNAMES.ORA Network Configuration File: /opt/oracle/product/9.2.0/network/admin/tnsnames.ora# Generated by Oracle configuration tools.
http://www.chq.name/ = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = http://www.chq.name)(port/ = 1521)) ) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = http://www.chq.name/) ) )
http://www.chq.name/ = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = http://www.chq.name)(port/ = 1521)) ) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = http://www.chq.name/) ) )
~ "tnsnames.ora" 101L, 1938C written
4.3)复制来创建数据库spfile配置文件[http://www.chq.name/_35]cd /opt/oracle/product/9.2.0/dbs/
$ cp spfilewww.chq.name_22.ora spfilewww.chq.name_35.ora
4.4)复制来创建数据库管理口令文件
[http://www.chq.name/_35]$ mv orapwwww.chq.name_22 orapwwww.chq.name_35
4.5)启动数据库,
[http://www.chq.name/_35]$ sqlplus "/as sysdba"SQL> startupORACLE instance started.
。。。Database mounted.Database opened.
4.6)启动监听器服务
[http://www.chq.name/_35]$ lsnrctl start

五、几点说明:
1:rsync在rehl中默认已经安装。2:要拷贝数据库管理程序目录和数据文件目录,主机与客机路径要完全一致

==================================
参考资料:
用rsync对网站进行镜像备份(文章来源:http://xfocus.org/)

Sunday, September 10, 2006

FreeBSD 硬盘系统和数据的复制迁移实战


FreeBSD 硬盘系统和数据的复制迁移实战


陈海青(joson chen) http://www.chq.name/
2006.09.09

版权声明:转载或引用本网版权所有之内容须注明“转自(或引自)chq.name (Junit fans)”字样,并标明本网站网址http://www.chq.name


最近,为更换硬盘,参照有关资料,进行了一次FreeBSD下的硬盘数据迁移,具体情况如下:
1:起因:原有的硬盘容量小、有坏区、swap设置不合理、/var太小,所以要进行更换

2:计划:1)使用sysinstall--fdisk划分好新硬盘的slice(片段,一块硬盘分成最多四个),本次划分为2个slice,用其中的19GB用于Freebsd); 2) 使用sysinstall--label划分新硬盘的partition(分区,每一个slice上又可以分成最多8个partition):/ (512MB),swap (512MB),/tmp (1GB),/var (2G,数据库等),/usr (10GB),(/home (rest of the hdd));

3:操作步骤:
1)将新硬盘装上并让系统正确识别。原硬盘为IDE0口上的Master,FreeBSD识别为ad0。为了不用设硬盘跳线,这里将新硬盘到IDE1接口的Master,系统识别为ad2;如果你想和旧硬盘接在同一数据线线上,即IDE0接口,则必须将跳线设为slave,系统识别为ad1。 1、关机,将新硬盘装上,重新开机。 2、开机后查看是否系统是否已经识别到新硬盘了:
http://www.chq.name/# dmesg grep ad2

2)记下旧硬盘文件系统所对应的mount点:查看/etc/fstab,并且运行命令df,记录结果。新硬盘分区次序基本按照旧的一样,避免混淆。

3)使用sysinstall的FDISK命令把新硬盘分片,设置MBR;然后用LABEL命令分区。可以先自动分区,再对照原来的次序修改,假设原来的文件系统/dev/ad0s1g 对应/usr,那你新硬盘/dev/ad2s1g就用来做/usr,划分好后,按M分别清空所有文件系统的mount点,因为我们还没有建立临时的mount的目录,不清空会和系统原来的mount冲突的。

4)创建临时的目录用来作临时mount点,用于以下步骤挂载文件系统。
http://www.chq.name/ mkdir /backup http://www.chq.name/ mkdir /backup/root http://www.chq.name/ mkdir /backup/usr http://www.chq.name/ mkdir /backup/var
http://www.chq.name/ mkdir /backup/tmp

5)停止原系统的主要服务,如APACHE,MYSQL等,或者重启后进入单用户状态,准备复制。进入单用户模式的方法:1.重启,在启动菜单开始倒计时的时候按下空格(space)键,输入boot -s ,然后在#后输入 fsck -p mount -u / mount -a swapon -a adjkerntz -i

6)运行以下脚本,执行硬盘数据和系统的复制。要注意根据前面记录的/etc/fstab和df结果查看文件系统的对应关系,修改mount等脚本。
#1 - create new filesystems (newfs the drive)
#2 - mount the partitions
#3 - dump the data from my old drive, and restore it to my new one
#4 - unmount the new drives partitions
#5 - enable softupdates on the new drive (optional)

newfs /dev/ad1s1a
newfs /dev/ad1s1e
newfs /dev/ad1s1f
newfs /dev/ad1s1g
mount /dev/ad1s1a /backup/root
mount /dev/ad1s1e /backup/var
mount /dev/ad1s1f /backup/tmp
mount /dev/ad1s1g /backup/usr

( dump -0f - / ) ( cd /backup/root ; restore -rf - )
( dump -0f - /var ) ( cd /backup/var ; restore -rf - )
( dump -0f - /usr ) ( cd /backup/usr ; restore -rf - )
( dump -0f - /tmp ) ( cd /backup/tmp ; restore -rf - )

# umount /backup/root
# umount /backup/var
# umount /backup/usr
# umount /backup/tmp
# tunefs -n enable /dev/ad2s1a
# tunefs -n enable /dev/ad2s1e
# tunefs -n enable /dev/ad2s1f
# tunefs -n enable /dev/ad2s1g
#end

其中:
(1):( dump -0f - / ) ( cd /backup/root ; restore -rf - ),这是把老的根目录下所有内容复制输出到管道 , restore 从管道里读数据 , 写入当前目录所在目录.
(2):进行dump/restore的操作可能会花点时间,需耐心等待,我迁移了3GB数据,运行脚本用了大约40分钟。

7)调整新硬盘中的/etc/fstab,将Device等修正,我原来使用的是第二块slice,现在使用第一个slice,于是修改了Device列:
http://www.chq.name/)#mount /dev/ad1s1a /backup/root
http://www.chq.name/)# vi /backup/root/etc/fstab

8)关机,摘掉原来的硬盘,把新硬盘挂到旧硬盘原来的位置,这步不要省略了,如果你不换位置,系统还是认为新硬盘是ad2,由于你的/etc/fstab里面是对应ad0的,所以启动会找不到/usr和/var等文件系统。

9)注意事项:重新启动,如果没有什么异常,那恭喜你,数据迁移已经成功,否则,请再看看有什么操作错误或者忘记做哪一步了。建议,让新的系统运行几天,正常后再处置旧硬盘。切记,数据迁移的是一件比较危险的事情,操作过程中不能有差错,否则可能导致你原来的数据丢失,所以必须非常谨慎。

10)我的部分操作输出结果(http://www.chq.name/):
# cd /
# mkdir backup
# cd backup
# mkdir root
。。。
www# newfs /dev/ad2s1a
/dev/ad2s1a: 1024.0MB (2097152 sectors) block size 16384, fragment size 2048
using 6 cylinder groups of 183.77MB, 11761 blks, 23552 inodes.
super-block backups (for fsck -b #) at:
160, 376512, 752864, 1129216, 1505568, 1881920
。。。
# sh restore.sh
DUMP: WARNING: should use -L when dumping live read-write filesystems!
DUMP: Date of this level 0 dump: Thu Sep 7 22:22:40 2006
DUMP: Date of last level 0 dump: the epoch
DUMP: Dumping /dev/ad0s2a (/) to standard output
DUMP: mapping (Pass I) [regular files]
DUMP: mapping (Pass II) [directories]
DUMP: estimated 37230 tape blocks.
DUMP: dumping (Pass III) [directories]
DUMP: dumping (Pass IV) [regular files]
warning: ./.snap: File exists
DUMP: DUMP: 37868 tape blocks
DUMP: finished in 7 seconds, throughput 5409 KBytes/sec
DUMP: DUMP IS DONE
DUMP: WARNING: should use -L when dumping live read-write filesystems!
DUMP: Date of this level 0 dump: Thu Sep 7 22:22:49 2006
DUMP: Date of last level 0 dump: the epoch
……
DUMP: finished in 1 seconds, throughput 7128 KBytes/sec
DUMP: DUMP IS DONE
tunefs: soft updates set

参考资料:FreeBSD硬盘分区和数据迁移相关资料