1、Docker容器的数据卷备份与恢复

数据卷的备份与恢复

-备份-

注:
  -v指定数据卷时,如果数据卷不存在则自动创建。

1.使用nginx基础镜像新启动一个名为nginx的容器,-v指定数据卷名为web并挂载到nginx容器的/mnt/web目录

[root@localhost ~]# docker run -itd --name nginx -v web:/mnt/web nginx
3e99025339a4600ae7f607fbaafaff9f36bdf8d8533aaa441a42103be4260de5[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
3e99025339a4        nginx               "nginx -g 'daemon of…"   3 minutes ago       Up 3 minutes        80/tcp              nginx[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               web      //可以看到web数据卷自动创建

2.在名为nginx的容器中新增数据

可以进入nginx容器中新增,也可以直接使用docker命令新增数据。
[root@localhost ~]# docker exec -it nginx mkdir /mnt/web/test[root@localhost ~]# docker exec -it nginx touch /mnt/web/data.txt[root@localhost ~]# docker exec -it nginx ls /mnt/web
data.txt  test        //可以看到新增的文件夹与文本文件

3.数据卷备份

命令详解:

使用nginx基础镜像新建一个临时的容器(不放入后台运行),数据共享容器nginx的数据卷web,并且-v 指定将本机的/root/test目录挂载到临时容器的/backup目录,执行备份命令将临时容器的/mnt/web目录打包压缩到/backup目录下名为web.tar的备份文件(因为数据卷web挂载到了nginx容器的/mnt/web目录,而临时容器又共享了nginx容器的数据卷web,所以直接打包容器的/mnt/web目录即可) (因为本机的/root/test目录挂载到了临时容器的/backup目录,所以可以直接在本机的/root/test目录中查找备份文件web.tar即可)

[root@localhost ~]# docker run -it --volumes-from nginx -v /root/test:/backup nginx tar cvf /backup/web.tar /mnt/web
tar: Removing leading `/' from member names
/mnt/web/
/mnt/web/test/
/mnt/web/data.txt[root@localhost ~]# ll -h /root/test/
总用量 357M
-rw-r--r-- 1 root root  10K 5月  13 02:29 web.tar      //备份数据

-恢复-

1.用nginx基础镜像新启动一个带有空数据卷webdata的容器nginxback

[root@localhost ~]# docker run -itd --name nginxback -v webdata:/mnt/web nginx
33149ce377ae168d09f69227c8216db731e24593db7f57f0cca594d011a7c9c9[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               web
local               webdata    //自动创建的新数据卷(用于恢复数据)[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
33149ce377ae        nginx               "nginx -g 'daemon of…"   3 seconds ago       Up 1 second         80/tcp              nginxback
3e99025339a4        nginx               "nginx -g 'daemon of…"   7 minutes ago       Up 7 minutes        80/tcp              nginx

2.数据卷恢复

命令详解:

使用nginx基础镜像新建一个临时的容器(不放入后台运行),数据共享容器nginxback的数据卷webdata(作用是将web.tar文件数据恢复至数据卷webdata),并且-v 指定将本机的/root/test目录挂载到临时容器的/backup目录,所以直接执行恢复命令将临时容器的/backup目录下名为web.tar的备份文件恢复至nginxback容器的数据卷webdata中 。

[root@localhost ~]# docker run -it --volumes-from nginxback -v /root/test:/backup nginx tar xvf /backup/web.tar
mnt/web/
mnt/web/test/
mnt/web/data.txt[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               web
local               webdata[root@localhost ~]# docker exec -it nginx ls /mnt/web
data.txt  test      //原始数据容器nginx中的数据(数据卷web)[root@localhost ~]# docker exec -it nginxback ls /mnt/web
data.txt  test     //备份数据卷恢复后的nginxback容器中的数据(数据卷webdata)

3.为了验证web数据卷备份恢复到webdata数据卷的数据,再启动一个新容器挂载webdata数据卷查看数据

[root@localhost ~]# docker run -itd --name webtest -v webdata:/mnt/web nginx
60e73b319aff246ac2d1debca13b1d7581a056d8a13a9c508ae614f4a58273a5//启动新容器webtest,并且-v将webdata数据卷挂载到容器/mnt/web目录[root@localhost ~]# docker exec -it webtest ls /mnt/web
data.txt  test        //查看容器webtest中的数据

Mysql容器数据卷的备份与恢复问题?

问题:

使用上面nginx数据卷备份恢复的方法对mysql容器数据卷进行备份与恢复,在备份与恢复的过程都能够看到新建的test库,但是恢复之后数据库中就是没有test库,不知道是什么问题?有懂的大佬解答一下,万分感谢!!!

实验过程:

1.使用mysql基础镜像新启动一个mysql4容器,-v指定数据卷名为mysql并挂载到mysql4容器的/var/lib/mysql目录,-e设置mysql4容器数据库密码为123。

[root@localhost ~]# docker run -itd --name mysql4 -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 mysql//启动mysql4容器,-v指定数据卷mysql挂载到/var/lib/mysql目录,-e设置密码[root@localhost ~]# docker volume ls    //查看创建的数据卷
DRIVER              VOLUME NAME
local               mysql[root@localhost ~]# docker ps     //查看运行的mysql4容器
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
7632976b82d4        mysql               "docker-entrypoint.s…"   6 hours ago         Up 6 hours          3306/tcp, 33060/tcp   mysql4

2.进入mysql4容器并创建新库test

[root@localhost ~]# docker exec -it mysql4 /bin/bash
root@7632976b82d4:/# mysql -uroot -p123
...
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.68 sec)mysql> create database test;       //创建test库
Query OK, 1 row affected (0.24 sec)mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.01 sec)

3.数据卷mysql备份

命令详解:

使用mysql基础镜像新建一个临时的容器(不放入后台运行),数据共享容器mysql4的数据卷mysql,并且-v 指定将本机的/root/test目录挂载到临时容器的/backup目录,执行备份命令将临时容器的/var/lib/mysql目录打包压缩到/backup目录下名为test.tar的备份文件(因为数据卷mysql挂载到了mysql4容器的/var/lib/mysql目录,而临时容器又共享了mysql4容器的数据卷mysql,所以直接打包容器的/var/lib/mysql目录即可) (因为本机的/root/test目录挂载到了临时容器的/backup目录,所以可以直接在本机的/root/test目录中查找备份文件test.tar即可)

[root@localhost ~]# docker stop mysql4
mysql4[root@localhost ~]# docker run -it --volumes-from mysql4 -v /root/test:/backup mysql tar cvf /backup/test.tar /var/lib/mysql
tar: Removing leading `/' from member names
/var/lib/mysql/
/var/lib/mysql/ibdata1
/var/lib/mysql/ib_logfile1
/var/lib/mysql/#ib_16384_0.dblwr
/var/lib/mysql/#ib_16384_1.dblwr
...
/var/lib/mysql/1d90619790ec.err
/var/lib/mysql/binlog.000001
/var/lib/mysql/binlog.000002
/var/lib/mysql/test/
/var/lib/mysql/binlog.000003
/var/lib/mysql/binlog.000004
/var/lib/mysql/binlog.000005
/var/lib/mysql/binlog.000006
/var/lib/mysql/binlog.000007
/var/lib/mysql/binlog.000008
/var/lib/mysql/binlog.index
/var/lib/mysql/ib_buffer_pool[root@localhost ~]# ll -h /root/test/       //查看备份文件
总用量 172M
-rw-r--r-- 1 root root 172M 5月  12 22:38 test.tar

4.数据卷恢复

[root@localhost ~]# docker run -itd --name mysql_back -v mysqltest:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 mysql
246f59e233116c3b0e8a8d041f3ca7b4b5096ca170ebb0e2fac586236c92d4b7//启动新容器mysql_back,将空数据卷mysqlback挂载至容器的/var/lib/mysql目录[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
246f59e23311        mysql               "docker-entrypoint.s…"   4 seconds ago       Up 3 seconds        3306/tcp, 33060/tcp   mysql_back[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               mysql
local               mysqlback[root@localhost ~]# docker run -it --volumes-from mysql_back -v /root/test:/backup mysql tar xvf /backup/test.tar -C /var/lib/mysql
var/lib/mysql/
var/lib/mysql/ibdata1
var/lib/mysql/ib_logfile1
var/lib/mysql/#ib_16384_0.dblwr
var/lib/mysql/#ib_16384_1.dblwr
var/lib/mysql/undo_001
var/lib/mysql/undo_002
var/lib/mysql/ib_logfile0
var/lib/mysql/#innodb_temp/
var/lib/mysql/#innodb_temp/temp_1.ibt
var/lib/mysql/#innodb_temp/temp_2.ibt
var/lib/mysql/#innodb_temp/temp_3.ibt
var/lib/mysql/#innodb_temp/temp_4.ibt
var/lib/mysql/#innodb_temp/temp_5.ibt
var/lib/mysql/#innodb_temp/temp_6.ibt
var/lib/mysql/#innodb_temp/temp_7.ibt
var/lib/mysql/#innodb_temp/temp_8.ibt
var/lib/mysql/#innodb_temp/temp_9.ibt
...
var/lib/mysql/test/        ------》可以看到恢复的时候有test库
var/lib/mysql/binlog.000003
var/lib/mysql/binlog.000004
var/lib/mysql/binlog.000005
var/lib/mysql/binlog.000006
var/lib/mysql/ib_buffer_pool
var/lib/mysql/ibtmp1
var/lib/mysql/binlog.000007
var/lib/mysql/binlog.index[root@localhost test]# docker exec -it mysql_back /bin/bash
root@2ffefb7516b9:/# mysql -uroot -p123//查看新容器mysql_back进行数据卷恢复后数据库中的数据
...
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |     ----》数据库中无test库????
+--------------------+
4 rows in set (0.07 sec)root@8fff18326739:/# ls /var/lib/mysql/
'#ib_16384_0.dblwr'   auto.cnf        ca.pem            ib_logfile1   performance_schema   sys
'#ib_16384_1.dblwr'   binlog.000001   client-cert.pem   ibdata1       private_key.pem      test
'#innodb_temp'        binlog.000002   client-key.pem    ibtmp1        public_key.pem       undo_001509ca1ee2a1b.err     binlog.index    ib_buffer_pool    mysql         server-cert.pem      undo_0028fff18326739.err     ca-key.pem      ib_logfile0       mysql.ibd     server-key.pem       var

2、Docker镜像与容器备份迁移(export、import与commit、save、load)

容器与镜像迁移

注:

用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。

export与import命令:

注意:

1.会丢弃历史记录和元数据。   2.启动export与import命令导出导入的镜像必须加/bin/bash或者其他/bin/sh,否则会报错。
   docker: Error response from daemon: No command specified.

export:导出容器会丢失历史记录和元数据,类似与快照。

命令格式:

docker export [容器ID|Name] > xxx.tar
 或
 docker export -o xxx.tar [容器ID|Name]

应用场景:
  主要用来制作基础镜像,比如从一个ubuntu镜像启动一个容器,然后安装一些软件和进行一些设置后,使用docker export保存为一个基础镜像。然后,把这个镜像分发给其他人使用,比如作为基础的开发环境。

import:导入容器快照到本地镜像库。

命令格式:
 docker import xxx.tar newname:tag

如:
   docker import redis.tar myredis:v1

1.创建容器web并新增数据

[root@localhost ~]# docker run -itd --name web nginx
9a17f7c9f00a3711018581a1523ecd7a06c40d1408ae5678e034be1a1e4e0cd8[root@localhost ~]# docker exec -it web touch /mnt/test.txt
[root@localhost ~]# docker exec -it web ls /mnt/
test.txt

2.导出容器快照

[root@localhost ~]# docker export web > web.tar[root@localhost ~]# ll -h web.tar
-rw-r--r-- 1 root root 123M 5月  13 04:34 web.tar

3.导入容器快照到本机镜像库

[root@localhost ~]# docker import web.tar web:v1
sha256:134f9251e15e56060d564c23cec4be0048434fb90b19188ea64bf77af77b85ff[root@localhost ~]# docker images
REPOSITORY                      TAG                      IMAGE ID            CREATED             SIZE
web                             v1                       134f9251e15e        10 minutes ago      125MB

4.启动使用import导入镜像库的web:v1镜像,并查看数据

注意:
  启动export与import命令导出导入的镜像必须加/bin/bash或者其他/bin/sh,否则会报错。

    docker: Error response from daemon: No command specified.[root@localhost ~]# docker run -itd --name web2 web:v1 /bin/bash
ef07135bcda92c8660392ce29e24c7c8de82f3369fb024ae772c34cd74b9258d[root@localhost ~]# docker exec -it web2 ls /mnt/
test.txt

总结:
  通过export命令也可以将容器里的数据保存,并可以迁移到别的docker主机。

commit命令:

将已存在容器中的镜像和修改内容提交为一个新的镜像,通过这个方式同样能保存读写层内容。

命令格式:

docker commit [容器名称|ID] 生成新的镜像名字

选项说明:

-a:提交的镜像作者

-c:使用dockerfile指令来创建镜像

-m:提交时的说明文字

-p:在commit的时候,将正在运行的容器暂停

应用场景:
 主要作用是将配置好的一些容器生成新的镜像,可以得到复用(再次使用不需要再配置)。

1.启动一个nginx容器,并且在容器的/mnt目录下创建一个文件

[root@localhost ~]# docker run -itd --name nginxweb -p 80:80 nginx
fda3ca1b33ba4c9dc6a1ca27c7242bbbdc2a08f4e6e7642d3ec5de62e1e8f78c[root@localhost ~]# docker exec -it nginxweb touch /mnt/test.txt[root@localhost ~]# docker exec -it nginxweb ls /mnt/
test.txt

2.将nginxweb容器commit成一个新的镜像

[root@localhost ~]# docker commit nginxweb nginx_test:v1
sha256:a06b16b343036bcbf424c499022ca635bf90740aa7d76acbe0c271a731aba2ef[root@localhost ~]# docker images
REPOSITORY                      TAG                      IMAGE ID            CREATED             SIZE
nginx_test                      v1                       a06b16b34303        4 seconds ago       127MB

3.使用nginxweb生成的新镜像nginx_test启动一个nginx_v1容器,并查看新容器中的数据

[root@localhost ~]# docker stop nginxweb     //为了方便先停止nginxweb容器,因为80端口已被占用
nginxweb[root@localhost ~]# docker run -itd --name nginx_v1 -p 80:80 nginx_test:v1
df074341d7a39b072966672ef9bb8769142b67395488e30e81711d0c75f2a821[root@localhost ~]# docker exec -it nginx_v1 ls /mnt/
test.txt       ---》可以看到新容器nginx_v1中有之前nginxweb的数据

注意:
  commit 命令虽然能实现保存读写层数据,但不适于做数据持久化。

save与load命令:

注意:
  1.不会丢弃历史记录和元数据,并可以回滚版本。  2.启动不用加/bin/bash。

save:将指定镜像保存成tar文件。

命令格式:

docker save 镜像名 > xxx.tar
 或
 docker save -o xxx.tar 镜像名

应用场景:
  如果你的应用是使用docker-compose.yml编排的多个镜像组合,但你要部署的客户服务器并不能连外网。这时,你可以使用docker save将用到的镜像打个包,然后拷贝到客户服务器上使用docker load载入(一般用于镜像迁移到别处)。

load:导入使用docker save命令导出的镜像。在这里插入代码片

命令格式:
 docker load -i xxx.tar

 docker load < xxx.tar

容器备份迁移案例:

运行一段时间后的容器,其中包含了新的数据,如果想把这些内容数据一并迁移到新的主机上,可以按照以下步骤进行:

1.提交容器生成新的镜像

[root@localhost ~]# docker ps    //查看正在运行的容器web
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
9a17f7c9f00a        nginx               "nginx -g 'daemon of…"   19 hours ago        Up 19 hours         80/tcp              web[root@localhost ~]# docker commit -p web webdata:v1    //-p暂停web容器并提交为新镜像webdata:v1
sha256:b25ea02c5f1f4efe4c35d6503a277d968d5dfdf0cfd69092b3e99202dd687723[root@localhost ~]# docker images      //查看提交的新镜像webdata
REPOSITORY                      TAG                      IMAGE ID            CREATED             SIZE
webdata                         v1                       b25ea02c5f1f        3 seconds ago       127MB

2.将镜像保存成一个tar压缩包

[root@localhost ~]# docker save webdata:v1 > webdata.tar[root@localhost ~]# ll -h webdata.tar
-rw-r--r-- 1 root root 125M 5月  13 23:47 webdata.tar

3.将tar压缩包复制到另一台主机

[root@localhost ~]# scp webdata.tar root@192.168.2.128:/root/test

4.在另一台主机上加载镜像的tar压缩包

[root@localhost ~]# cd test/[root@localhost test]# ll
总用量 127572
-rw-r--r-- 1 root root 130631168 5月  13 23:49 webdata.tar[root@localhost test]# docker load -i webdata.tar
d9d778e6751c: Loading layer [==================================================>]  10.24kB/10.24kB
Loaded image: webdata:v1[root@localhost test]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
webdata                       v1                  b25ea02c5f1f        12 minutes ago      127MB

5.使用这个加载的镜像运行容器

[root@localhost test]# docker run -itd --name web webdata:v1
51d9ed10961b9620ea6456f5bd75dbd43168b73c7bd184dcccdd25fcf956d9e5[root@localhost test]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
51d9ed10961b        webdata:v1          "nginx -g 'daemon of…"   35 seconds ago      Up 33 seconds       80/tcp              web[root@localhost test]# docker exec -it web ls /mnt/
test.txt

注意:
 如果有docker镜像仓库的权限,也可以直接将第1步生成的镜像push到docker仓库,然后在另一台主机上pull镜像并运行为容器即可。

docker save和docker export的区别

docker save保存的是镜像(image),docker export保存的是容器(container);

docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;

docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。

docker export的包会比save的包要小,原因是save的是一个分层的文件系统,export导出的只是一个linux系统的文件目录。

参考链接 :
Docker容器的数据卷备份与恢复https://mp.weixin.qq.com/s/43p3S2qXikW7YWkz1oho9w

Docker镜像与容器备份迁移(export、import与commit、save、load) :https://mp.weixin.qq.com/s/5OvAhrjf1RUCvRLKugjgZw

Docker容器的数据卷备份与恢复相关推荐

  1. Linux中的Docker容器的数据卷

    一.数据卷的概念 1.数据卷是宿主机中的一个目录或者文件 2.当容器目录和数据卷目录绑定后,对方的修改会立即同步 3.一个数据卷可以被多个容器同时挂载 4.一个容器也可以挂载多个数据卷 二.数据卷的作 ...

  2. Docker容器的数据卷(volumes)

    目录 1.容器数据卷技术解决什么问题 docker可将应用和环境打包成一个镜像.容器是镜像的实例化. 我们的数据如果都在容器中,一旦容器删除,数据就会丢失. 数据卷技术可将容器产生的数据同步到本地,容 ...

  3. Docker 安装 命令 数据卷 应用部署 网络优化 Dockerfile 服务编排Compose 私有仓库

    Docker 1. 初识docker 1.1 Docker是什么 了解Docker的前生LXC LXC与docker的关系 Docker 的特点 1.2 为什么使用Docker Docker的优势 缺 ...

  4. Docker——使用docker工具管理软件/组件的运行,镜像、容器、数据卷的基本概念,常用指令,使用docker搭建Java微服务运行环境

    Docker--使用docker工具管理软件/组件的运行,镜像.容器.数据卷的基本概念,常用指令,使用docker搭建Java微服务运行环境 一.docker的安装和卸载 1.卸载 2.安装 3. 导 ...

  5. docker webdav_跨主机容器共享数据卷(webdav 双向同步)

    在校内搭建的 Git 仓库,有时候需要在校外访问操作.因为使用的是 Gogs 搭建,所以只需要同步 data 文件夹即可,网上关于双向同步的方案有很多,但是都很麻烦,而且经常会"打架&quo ...

  6. docker中的数据卷

    目录 1. 为什么使用数据卷 2. 数据卷基本操作 2.1 创建数据卷 2.2 查看数据卷 2.3 查看数据卷详细信息 2.4 数据卷删除 3. 数据卷的使用 3.1 先创建数据卷再挂载 3.2 直接 ...

  7. docker学习5--docker数据卷(volume)

    https://blog.csdn.net/dream_broken/article/details/52314993 1.什么是数据卷volume 为了了解什么是Docker Volume,首先我们 ...

  8. docker 容器共享数据_如何在Docker容器之间共享数据

    docker 容器共享数据 介绍 (Introduction) Docker is a popular containerization tool used to provide software a ...

  9. 知识点9--Docker容器的数据卷

    我前面介绍容器命令的时候,最后说过一个cp命令,可以把容器和宿主机之间的文件互相拷贝,保证数据的持久化,但是这种持久化偏向于比较独立完整的文件,大家有没有想过如果遇到成体系的数据保存,比如我整个数据库 ...

最新文章

  1. 对数组中的数字从小到大排序
  2. JDK1.6安装与环境变量设置详细图解
  3. numpy的random
  4. android log丢失(一)使用logd丢失log原理
  5. leetcode200. 岛屿数量
  6. 【MySQL】【高可用】从masterha_master_switch工具简单分析MHA的切换逻辑
  7. 执行存储过程SQL Server阻止了对组件xp_cmdshell过程的解决方案
  8. Docker镜像优化:从1.16GB到22.4MB,真强!
  9. Zend Studio 10 phpFormatter 错误的解决
  10. 1月5日 char **argv是什么用法啊?
  11. php微积分难吗,微积分中10大经典问题
  12. 你的深度思考能力,是如何一步步被毁掉的?奶嘴战略
  13. 正弦交流电有效值系数sqrt(2)的推导
  14. poj2287田忌赛马
  15. 读书记之《UnixLinux大学教程》
  16. 张一鸣:年轻人一定要懂得延迟满足
  17. LeetCode 热题 HOT 100 -------31. 下一个排列(数组,数学问题)128. 最长连续序列(数组) 11. 盛最多水的容器(数组) 621. 任务调度器 (数组)
  18. Java毕业设计-会议室预约小程序系统
  19. 罗技K480拆解_减重
  20. SublimeLinter进行PHP代码检查

热门文章

  1. pytorch如何将训练提速?
  2. 计算机应用基础案例教程习题答案,计算机应用基础案例教程习题答案
  3. 开机自动启动_工控机断电恢复后自动开机的设置方法
  4. WIZnet开源平台ioPlatform所趋,全硬件TCP/IP尽显内芯智慧!
  5. Windows 8 Directx 开发学习笔记(六)添加水模型
  6. str_replace中的匹配空白符,必须用双引号
  7. Apache 的 httpd.conf 详解(很实用)
  8. XML XPATH simpleXML
  9. unix编程之文件锁,exit
  10. 如何使用 vimdiff 来 git diff /svn diff