Wednesday, January 31, 2007

Understanding Transaction Isolation

自从开始作为一个developer, 就可以是接触和了解事务隔离级别(transaction isolation level) , 但是坦白说我还没有真正的理解过这个概念, 总是停留再一种似懂非懂的境界. 期间也去网上找过很多资料, 但是都是搜索中文网页, 老实说, 国内的网站技术文章太少了 ,而且都是一篇文章所有网站抄来抄去, 很悲哀到了现在还是似懂非懂, 难道要糊涂的生, 然后糊涂的死么?
昨天, 当我现在在这里写这些文字的时候,我一直在回想, 昨天是什么促使我突然又开始关注事务隔离级别这个话题. 想不起来了, 昨天晚上公司年夜饭, 喝了不少红酒, 还喝了一杯白酒, 回家之后倒头就睡,过去的记忆仿佛都在昨天被抛弃了. 就是说想不起来了, 想不起来也无所谓, 这件事情还是要做的, 所以今天又google了一把, 关键字是transaction isolation level, 嘿嘿,找到了一些资源, 先看看. 写这些文字的时候, 我还根本没看那些找到的文章, 有点颠倒是非. 先写道这里, 看了之后, 然后再说我是否已经真正理解了事务隔离级别这个概念. 理解了我便要在这里写下我的理解.
下面这篇文章不错, 我决定直接copy过来.
--------------------------

Understanding Transaction Isolation

http://www.expresscomputeronline.com/20040426/techspace01.shtml

Article summary

This is a topic related to SQL Server. However, the concept is applicable to any RDBMS. While auditing many applications, I have found that incomplete or no understanding of ‘Isolation Level’ leads to a lot of real life problems. These include performance degradation, blocking, locking as well as major deadlocks.

This article provides an easy-to-understand view of what ‘Isolation Levels’ really mean and when to use which level.

‘Isolation Level’ is a setting that decides how data which is a part of an ongoing transaction is made visible to other transactions.

Transactions are well understood. So what is the problem?

As all of us know, it is a unit of work. The work may contain many steps but either all steps happen or all steps don’t happen. This is fairly well known. Nothing new here. But consider how transactions occur in real life.

  • I am updating one row in a Begin Tran and Commit section. I have issued Begin Tran as well as the Update statement. Commit is not yet issued – because I want to perform some more actions in the same transactions on some other tables. If some other user wants to read this row that I have updated but not yet committed, what should happen?
  • Consider another scenario. I start a transaction. I calculate a total of a field based upon all rows in a table. Now, I need to add a new record in another table which contains this total. Now, can the original table be changed by some other user after I calculate the total? In which case, there could be a mismatch. Do you want to take such chances?
  • Another scenario. I am working on some transaction table between a range of keys within a transaction—say 10 and 20. There were only 5 records when I read the range – 10, 12, 14, 16, 20. Now I am working on other things in the transaction. Before I could commit the transaction, someone added another row with a key value of 11. Now, my base assumption about what records I read between 10 and 20 and further work upon them itself is wrong. Problem!!! Is it not?
  • I start reading a long table. It is not a transaction at all. But other users want to refer to that table for updating some fields in specific rows. The query takes 20 minutes to read all the rows. What happens to other users who are trying to update the rows? Do they wait for 20 minutes? Or they are allowed to update the rows even when the rows are being read in a large query? What if the query was used to generate a summary report containing grand totals? The total would be wrong because after the summation started, some rows have changed. Some of these rows could have changed after the summation occurred. What’s to be done now?

As you can see all these situations are confusing and prone to inaccuracies. To avoid such problems we have a feature called “Isolation Levels”.

Isolation Levels are applicable to transactions. These decide the visibility of information which is a part of an ongoing transaction.

In very simple terms Isolation Levels decide “What happens when some data being referred to (for reading or writing) within an incomplete transaction is also being referred to (for reading or writing) from another connection (or user – actually it is called another ‘transaction lock space’)?”

To make things sound technical, all these problems have been given nice and complex sounding names.

Data visibility problems that can occur during a transaction

Let us understand some jargon.

  • Transaction Lock Space:

Each transaction performs certain operations (select / insert / update / delete) on one or more rows of one or more tables. Transaction starts with Begin Tran command and ends with Commit. If unsuccessful, it ends with Rollback command. Now, after Begin Tran is issues and before Commit is issued, multiple tables may participate in the transaction related commands. Specific parts of these tables need to be locked during this phase to ensure that other users do not interfere with this transaction. This is called Transaction Lock Space.

  • Uncommitted (dirty) data:

Consider this code snippet (Blue text is code; green indicates comments):

1. Begin Transaction

—we want to change the customer status from active = “yes” to active = “no”

2. Update customer Set active = “No”

where CustomerID = 2324

—some more commandss

3. Select * from customer where CustomerID = 2324

4. Commit Transaction

Now, if the transaction commits, the value will be “No”. If it does not commit (for whatever reason), the value will remain “Yes”.

Consider that the value has already been changed to “No”. But there are more commands to be executed before the entire transaction commits. These commands are time consuming and take, say, 3 minutes. During these three minutes, if some user outside the transaction lock space reads the value of Active field in the Customer table for ID 2324, what should they see? “Yes” or “No”? The answer is simple. The value is changed but not committed. Therefore, external queries should still show “Yes”.

Now what would happen if a Select active from Customer where CustomerID – 2324 returns “No” to another user? What happens if the transaction rolls back? This is called Uncommitted Data. Ideally this should not be visible outside the transaction.

However, consider the same command executed within the transaction (line 4). It should – and it will return “No”.

Now let us consider various problems that can occur. The problems can be of three types:

1. Dirty Read

2. Non-repeatable read

3. Phantom rows

- Dirty reads

This is when connections outside the transaction space can read the uncommitted data. You don’t want this to happen in most cases. The only reason when you may want to allow this is when you are creating a report which assumes a certain amount of inaccuracy. You think this situation is rare? Not really. Suppose the report compares the current month sale with last month sale and returns a percentage difference. Consider that the report takes 5 minutes to generate. During these 5 minutes, more transactions may be getting added to the sales data. Typically 5 transactions would get added to the sales table. The average transaction value is Rs. 1000. The total sale for the month is typically 30-40 lacs. In such cases, you really don’t need to worry about absolute accuracy. You can intentionally allow dirty reads because the impact is really not significant from a business perspective.

- Non-repeatable read

Consider the above code. We change the value of Active to “No” in line 2. Now in line 4 you expect the value to be “No” because we are querying the row ‘within’ the transaction.

Now what would happen if some other transaction was allowed to change the same value to, say, “Maybe”? In line 4, we would expect value of “No” but actually get value of “Maybe”. This problem is called non-repeatable read. The idea is that within a transaction, the same data read any number of times should yield consistent results. If it is not same then the reads are ‘non-repeatable’.

- Phantom Rows

This was explained in the introduction (range 10 to 20 example). The concept is simple. If you have already read a range of data based upon a key value, another transaction inserts a new row which happens to have a value between this range. The original range which was referred to would now become invalid. This is because a “Phantom row” was added. This is also a major problem.

Important learning

Although the above three issues are listed as problems, they may not always be considered as problems! Paradoxical? Not really. As explained for Dirty Read, whether it is a problem or not depends entirely upon the business context. Technology exists to allow these problems to occurs as well as prevent them. The choice is yours. I know this complicates matters. But if these matters were not complicated, what are IT professionals paid for!

Now let us see how to prevent these problems? The answer is “using Isolation Levels”.

Types of Isolation Levels

To solve the problem of … The Isolation Level should be…
Dirty Read Read Committed (Default of SQL Server)

Dirty Read and Non-Repeatable Read Repeatable Read Non-Repeatable Read

Dirty Read and Non-Repeatable

Read and Phantom Rows

Serializable
To retain all three problems Read Uncommitted

Before we discuss each isolation level, let us understand how to set or change it in T-SQL.

Syntax

SET TRANSACTION ISOLATION LEVEL
{ READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE
}

Remember:

- This setting applies to all transactions which are happening within a single connection.

- Multiple connections can have different Isolation Levels.

- Within a single connection, you can change the Isolation Level for specific transactions.

- You must know the kind of transaction you are performing and its business requirements before you can decide the right isolation level.

- Isolation level does not just affect the current transactions in a given connection. It also affects how other transactions issued within other connections will behave.

- Therefore, you should have a good idea of what kind of concurrent transactions occur in your application when the system is live and many users are active.

This is the single biggest problem which leads to low performance, locking and blocking, as well as deadlocks

- Most developers think of individual transactions as though they are occurring in a single user system.

- It is difficult to envisage all permutations of possible transactions which can occur together. But it is very much possible to plan for it in a structured and informed manner. This requires additional effort, monitoring live systems and tweaking of specific transactions and so on.

- Unfortunately, this additional effort is rarely a part of system deployment! Such problems surface only after the system load increases in such a way that small, unnoticed issues become amplified due to large volume of data and / or large number of concurrent users.

- Only one of the options can be set at a time.

- It remains in effect till you explicitly change the option by issuing another command. This is an important aspect to consider.

Best Practice : When you change the Isolation Level for a transaction, remember to set it back to the original level after the transaction is completed.

Isolation levels

  • Read Uncommitted

This is as good (or bad) as not having any isolation. All data which is uncommitted is readable from any connection. This should not be used unless you have a very good reason to do so.

  • Read Committed

This prevents dirty reads. This does not prevent phantoms or non-repeatable reads. This is the default. Although it is the default, it does not mean that this isolation level is ideal for all transactions. One of the regular tendencies amongst techies is to simply use default values without giving it a second thought! I cannot imagine the number of phantom and non-repeatable reads that must be occurring in the world because someone simply used the ‘default’ value. It is a scary thought to say the least.

This level is obviously more restrictive than the ‘Read Uncommitted’ level.

  • Repeatable read

This prevents dirty reads as well as non-repeatable reads. It does not prevent phantom rows. This is more restrictive than Read Committed level. When I say restrictive what does it mean? It means that the chances of other transactions having to wait for this one to finish are INCREASED. Another way of saying this is – Repeatable Read reduces concurrency compared to Read Committed level.

  • Serializable

This is the most restrictive of the options. This should never be used as the default level. If you use this one as the default, it will most probably create a single user system!

This prevents all three problems.

How do Isolation Levels work?

You will notice that we have not yet addressed this issue at all in this article. The answer to this question is another Pandora’s box. The answer is simple. It uses the appropriate types of locks to achieve the desired effects. We will see what locks are and how they are implemented using Isolation Levels in the next article.

In the meantime, please go through your code and see if you are simply using the default level or are there some transactions which merit a different isolation level. If you feel like changing a level, never do it in production system. It can create havoc. Try it out in a test environment first, satisfy yourself that it has no side effects and then implement it in production system.

Don’t stop there. Monitor the production system. Some problems are never detected in test systems. They may occur in production. Handle them as required.

If you have a packaged product which handles large amount of data and many concurrent users, you must analyse the appropriate usage of Isolation Levels.

Friday, December 01, 2006

[Window]配置sqlcmd远程连接sqlserver2005.

痛苦!!
我不是数据库管理员,对sqlserver不怎么熟悉,尤其是这些涉及到管理员的活儿. 因为sqlcmd是一个命令行的工具,可以用来做一些自动化的工作,比如自动创建数据库表模式, 自动装载数据. 本身ant又个sql的task是可以用来做这些事情的, 但是由于项目中的数据库脚本都是直接从sqlserver中导出的,完全是sqlserver的一套语法, 'sql' task不支持这些语法, 原来我是手工把数据库脚本中一些sqlserver特定的语句给删掉,比如 'GO', 'if exist...'等,但那得建立在数据库脚本比较少的基础上,而且得没有存储过程, 在现在的项目中,这些前提全被打破了, 实在没有办法,只好借助'sqlcmd'.

但是sqlcmd怎么都无法连接到到远程数据库服务器, google了一把, 也到msdn上看了不少资料, 知道关于远程连接的配置主要集中在' sqlserver外围应用配置器'上.
------------------------------------------------
1. 打开'Sqlserver 2005 Surface Area Configuration'->'按实例查看'->'Database Engine', 确保远程连接已经被设置.
2. 打开'Sqlserver Configuraion manager', 保证tcp/ip已经被激活了(服务器端与客户端).
NOTE: 上面两步都是在数据库服务器上进行的操作
3. 在客户端上, 打开'Sqlserver Configuraion manager', 保证tcp/ip已经被激活.
------------------------------------------------
在命令行窗口执行命令:
>sqlcmd -S 192.168.0.94 -U hp_ante -P hp_ante -d AnteProxy
可以连接到数据库服务器.
>sqlcmd -S hp-server-94 -U hp_ante -P hp_ante -d AnteProxy
连接也能成功.
>sqlcmd -s tcp:192.168.0.84,1433
如果'database engine'的远程连接配置的为'同时使用name piple和tcp/ip':
------------
HResult 0x2, Level 16, State 1
命名管道提供程序: 无法打开与 SQL Server 的连接 [2].
Sqlcmd: Error: Microsoft SQL Native Client : 建立到服务器的连
到 SQL Server 2005 时,默认设置 SQL Server 不允许远程连接这个
。.
Sqlcmd: Error: Microsoft SQL Native Client : 登录超时已过期.
------------
如果'database engine'的远程连接配置的为'仅使用tcp/ip':
------------
HResult 0x274D, Level 16, State 1
TCP 提供程序: No connection could be made because the target machine actively re
fused it.

Sqlcmd: Error: Microsoft SQL Native Client : 建立到服务器的连接时发生错误。连接
到 SQL Server 2005 时,默认设置 SQL Server 不允许远程连接这个事实可能会导致失败
。.
Sqlcmd: Error: Microsoft SQL Native Client : 登录超时已过期.
------------

我知道为什么最后那个命令不能成功, 后来又试了几种办法:
- 启动'Sqlserver 2005 Surface Area Configuration'中的'sqlserver browser'服务: 无法连接
唉,不管怎么样,至少有方法可以连接成功了. 如果你的sqlcmd连接不能成功, 除了上面说的配置以外,还要检查以下部分:
1. SQL Express is running (hey, gotta check)
2. SQL Browser is running
3. TCP/IP is enabled as a server protocol
4. You've created an Exception in your firewall for SQL Express
5. You've created an Exception in your firewall for SQL Browser

参考资料:
- http://blogs.msdn.com/sqlexpress/archive/2005/05/05/415084.aspx
- http://msdn2.microsoft.com/zh-cn/library/ms162773.aspx

Monday, November 20, 2006

[UBUNTU]如何在英文界面中使用中文输入法? ...以及其他的中文问题

首先说明一下我为什么要把UBUNTU的界面设置为英文。 原因很简单,其一,英文字体比较美观,我试过用中文界面,效果怎么都不能让我满意。其二,学学英文也是好的。
但是在英文界面下面使用中文输入法还不是那么简单的,嘿嘿,要胆大心细。现在的中文输入法主要是fcitx和scim。以前一直是使用scim,这东西真烦,和很多应用程序冲突,导致键盘不能输入,比如不能在firefox的地址栏输入,快捷键也失效。更受不了的是在ubuntu中居然不能重命名我自己创建的文件夹,还有realplay,acrobatreader等等都被影响不能使用(有些可以解决,有效没办法解决,至少我是不知道的,比如文件夹重命名这种事情)。那时候也试过小企鹅,但是试了几次,在英文界面下面都调不出来,所以一直是用的scim。今天小企鹅安装成功了,所以写下这些文字表示纪念。

我的ubuntu是6.10, 使用‘dist-upgrade’过来的,中间有惨痛的经历,反正最后我的数据全部被删除掉了(因为dist-upgrade之后无法起动xserver,所以只好重装,稀里哗啦的把数据分区给干掉了)。有点扯远,反正我写这些东西主要是为了记录ubuntu下中文设置的一些问题。

英文界面下使用中文输入法
------------------------------------------
1. 安装fcitx和im-switch
> sudo apt-get install im-switch libapt-pkg-perl fcitx
im-switch是一个输入法切换工具,你可以同时安装scim和fcitx,然后使用im-switch来决定使用哪个输入法。
> im-switch -s fcitx
2. 配置英文界面中文环境
修改/etc/environent
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
LANGUAGE="en_US:en"
GST_ID3_TAG_ENCODING=GBK
LANG=en_US.UTF-8
其实,不需要设置的那么详细,向LC_ALL可以进行全局性配置,唉,这里我也搞不清楚每个环境变量的具体作用。
#要界面是英文,那么
LANG和LANGUAGE3必须为‘en_US.UTF-8’(必须使用UTF-8,否则不能使用中文输入法).
#要使用中文输入法
LC_CTYPE必须为"zh_CN.UTF-8"。
3.编辑X的输入法配置文件
编辑/etc/X11/Xsession.d/95xinput(没有则创建一个,xsession.d中的文件在xserver启动的时候会被自动执行,就像init.d)
export LC_CTYPE=zh_CN.UTF8
export XMODIFIERS=@im=fcitx;
export XIM=fcitx;
export XIM_PROGRAM=fcitx;
export GTK_IM_MODULE="XIM";
export QT_IM_MODULE="XIM"
fcitx
4.logout之后,登录进来就可以在英文界面下面使用中文输入法了。

使用中文字体
---------------------
1.可以参考www.ubuntu.org.cn上wiki里6.10的快速设置指南,安装文泉绎的字体.
2.然后编辑/etc/X11/xorg.conf,在其中找到‘Provide required aliases for standard names’,
在随后的alias定义中都要添加“ WenQuanYi Bitmap Song”。
3.'System->Preference->Font"中配置字体。

配置openoffice的中文字体
---------------------
我一经安装了文泉绎的字体,但是在openoffice中看不到这个字体,没办法,到openoffice的官方网站上
下了一个简体中文版的。安装之后,发现界面是成了间体中文的,但是仍然无法找到中文字体,相当的郁闷。后来
在www。ubuntu。org上面看到一个贴子也是说vopenoffice的中文字体,我也决定试一下。
1.ubuntu的字体文件在/etc/share/fonts中,我只接在/etc/share/fonts/truetype中创建了一个文件夹
‘ttf-window’,然后把c:/windows/fonts/的中文字体文件vcopy过来(也不太确定哪些是中文字体,实在不
行就把所有字体文件都搞过去)
2.打开openoffice,嘿嘿,应该能看到中文字体了(如果还是没有,尝试在/etc/share/fonts/truetype/openoffice
下为/etc/share/fonts/truetype/ttf-window中的中文字体创建符号链结).
# openoffice有个spadmin的工具,可以装载字体,没有试过,好像说不行
# openoffice自己也有一个字体文件夹$OPENOFFICE_HOME/share/fonts/truetype,可以将字体文件放进去(ttf的字体)

Friday, November 10, 2006

[UBUNTU]在ubuntu下安装trac。

首先得说trac官方网站上的安装帮助文档真是比较烂,写得稀里糊涂,如果完全按照它的文档来做肯定会抓狂,主要就是它的安装步骤次序有问题,应该先执行的居然被放到了后面。无论怎么说,最后我还是安装成功了,不过主要还得归功于ubuntu的方便,敲了几个命令,ubuntu就帮我安装好了。
1. 安装软件包
sudo apt-get install trac libapache2-svn
** 可以看的出来,一个是trac的包,一个是apache连接subversion的mod。
** 自动安装之后,至少可以找到两个应用程序/usr/bin/trac-admin /usr/bin/tracd(以standalone的方式运行trac),其他的文件可以在/usr/share/trac下找到。

2. 初始化trac环境(这里定义为/var/trac/TestEnv)
sudo mkdir /var/trac
sudo chown www-data:www-data /var/trac
** 这里使用www-data是因为apache启动之后,会设置自己的进程owner为www-data。
sudo trac-admin /var/trac/TestEnv initenv
- input the project name
- adopt the default database connection, as SqlLite is a embeded database,it has been installed.
- specify the absolute path of svn repository.
- adopt the template directory.
** 执行命令之后,可以进入/var/trac/TestEnv看到已经创建了很多文件。

3. 设置apache2
在/etc/apache2/sites-available下创建一个trac文件来定义apache的VirtualHost:

ServerAdmin webmaster@localhost
ServerName trac.hengpeng.com
DocumentRoot /usr/share/trac/cgi-bin/

Options Indexes FollowSymLinks MultiViews ExecCGI
AllowOverride All
Order allow,deny
allow from all

Alias /trac "/usr/share/trac/htdocs"


SetEnv TRAC_ENV "/var/trac/TestEnv"


DirectoryIndex trac.cgi
ErrorLog /var/log/apache2/error.trac.log
CustomLog /var/log/apache2/access.trac.log combined

同时,还需要修改/etc/apache2/apache2.conf,注释掉addHandler行使trac的CGI程序能够被执行:
# To use CGI scripts outside /cgi-bin/:
#
AddHandler cgi-script .cgi
现在,disable默认的virtualhost,同时激活trac的虚拟主机:
sudo a2ensite trac
sudo /etc/init.d/apache2 reload

4. 创建subversion的环境(好像必须新建一个仓库,使用已有的仓库在执行trac-admin命令的时候就会报错,未确认)
我将新仓库放在/var/trac/TestTrac下面:
sudo svnadmin create /var/trac/TestTrac
sudo svn import /tmp/myproject file:///var/trac/TestTrac -m "initial import"

5. 启动服务
sudo chown -R www-data /var/trac/
sudo chown -R www-data /usr/share/trac

sudo apache2 -k restart

打开浏览器,访问http://trac.hengpeng.com(当然如果你没有域名,那么需要在本地设置域名解析,一般是在hosts文件加就可以了)。

Tuesday, October 17, 2006

在UBUNTU下面配置SAMBA

基本上我的日常工作都是在ubuntu下面了,绝大多数软件都可以找到linux下面的替代品,除了那个讨厌的VSS,一直我都没有找到可以在linux下面使用的替代品。因为这样,每周我提交 周报的时候总是要先到window下面,提交了周报之后再切换回ubuntu。 我痛恨vss,但是没办法。

后来总算找到了一个复杂的workaround,就是在自己的机器上面开了postfix的ftp服务,然后再在vss服务器上面装了个UltraVNC来作远程控制。这样我就先远程控制vss服务器,然后从vss服务器上访问我本机的ftp服务下载周报文件,最后在vss服务器上提交周报。
很丑陋的解决方案,后来想到了samba,为什么不用samba直接文件共享,虽然仍然要远程控制,但是至少不用在各个文件夹里面把文件copy来copy去了。

UBUNTU 内置了samba,应该是一早就安装好的,所以直接就能用了。
一开始,我是打算共享一个ubuntu的文件夹,然后从远程window机器上面访问。配置好像是很简单的,就是从System->Administration->Share Folders里面进行配置。但是需要添加samba访问的用户,就是从window上访问临近的机器时弹出的那个用户名/密码框,如果输入ubuntu的登录名/密码那是没有用的,至少在你做特定的设置以前。
为smaba添加用户使用下面的命令:
> sudo smbpasswd -a samba
这样会为samba添加一个叫‘samba‘的用户,同时还可以指定该用户的密码。
完成这些配置之后,我就从window上面访问UBUNTU机器,比如“\\192.168.0.40”,恩,可以看的共享文件夹了,但是双击无法打开,提示‘不能访问网络名“,郁闷。基本上我的日常工作都是在ubuntu下面了,绝大多数软件都可以找到linux下面的替代品,除了那个讨厌的VSS,一直我都没有找到可以在linux 下面使用的替代品。因为这样,每周我提交 周报的时候总是要先到window下面,提交了周报之后再切换回ubuntu。 我痛恨vss,但是没办法。

后来总算找到了一个复杂的workaround,就是在自己的机器上面开了postfix的ftp服务,然后再在vss服务器上面装了个UltraVNC 来作远程控制。这样我就先远程控制vss服务器,然后从vss服务器上访问我本机的ftp服务下载周报文件,最后在vss服务器上提交周报。
很出哦

没办法,我只好反过来在ubunt中mount一个window的共享文件夹。这里假设有一台叫hp-server的机器,我设置了f://liming.l共享。这里先检查一下从ubuntu上是否能够访问hp-server的共享,可以用下面的命令:
> smbclient -L \\hp-server -U administrator (或者是//hp-server)
根据提示输入访问密码之后,下面列出了所有hp-server上的共享目录:
Password:
Domain=[HP-SERVER3] OS=[Windows 5.0] Server=[Windows 2000 LAN Manager]

Sharename Type Comment
--------- ---- -------
E$ Disk ─¼╚¤╣▓¤Ý
VSS Disk
IPC$ IPC ÈÂ│╠ IPC
D$ Disk ─¼╚¤╣▓¤Ý
liming.li Disk
Installation Disk
F$ Disk ─¼╚¤╣▓¤Ý
ADMIN$ Disk ÈÂ│╠╣▄└Ý
C$ Disk ─¼╚¤╣▓¤Ý
Domain=[HP-SERVER3] OS=[Windows 5.0] Server=[Windows 2000 LAN Manager]

Server Comment
--------- -------

Workgroup Master
--------- -------
这个说明ubuntu能访问远程window的共享目录。在进行mount之前,保证系统已经安装了smbfs,可以用> sudo apt-get install smbfs来安装,最后可以用以下命令类执行mount:
> sudo mount -t smbfs -o username=administrator,password=hpsystem //hp-server/liming.li window/
这表示//hp-server/liming.li已经被mount到本地的当前目录下的window目录,嘿嘿,总算搞定了一点!!剩下的以后再说吧。