0%

GDB, the GNU Project debugger,它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。 本文将对一些常用的gdb指令进行简单介绍。

Read more »

分段机制

在32位系统中, 每个进程都认为拥有了2^32 的内存空间。其实这是一种假象,实际上操作系统内核一般占据2GB,剩余的2GB由用户空间的进程共享。其实,操作系统有种 保护方式,就是,使程序能拥有独立的内存空间,又认为占据了4GB空间。

Read more »

问题描述#

在linux系统下,用Tab键自动补全时,报如下错误:

1
$ sh dojo-bash: cannot create temp file for here-document: No space left on device

问题定位#

  1. df -h查看磁盘空间
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/dm-0 7.8G 7.8G 20K 100% /
    udev 10M 0 10M 0% /dev
    tmpfs 3.2G 353M 2.8G 11% /run
    tmpfs 7.9G 56K 7.9G 1% /dev/shm
    tmpfs 5.0M 0 5.0M 0% /run/lock
    tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
    /dev/vdc1 200G 47G 154G 24% /home
    /dev/vda1 236M 34M 190M 15% /boot

这里的/dev/dm-0 空间已满

1
/dev/dm-0       7.8G  7.8G   20K 100% /

  1. df -i查看磁盘Inodes消耗 和 剩余量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Filesystem        Inodes  IUsed     IFree IUse% Mounted on
    /dev/dm-0 129312 127969 1343 99% /
    udev 2056585 356 2056229 1% /dev
    tmpfs 2058885 501 2058384 1% /run
    tmpfs 2058885 15 2058870 1% /dev/shm
    tmpfs 2058885 4 2058881 1% /run/lock
    tmpfs 2058885 13 2058872 1% /sys/fs/cgroup
    /dev/vdc1 209713152 371880 209341272 1% /home
    /dev/vda1 62248 328 61920 1% /boot

这里的/dev/dm-0 Inodes已用99%

1
/dev/dm-0         129312 127969      1343   99% /

  1. 分析 /dev/dm-0

迅速查找 '/' 路径下 各文件占用大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
sudo du -h --max-depth=1 /

32M ./boot
4.0M ./etc
0 ./media
3.6G ./var
3.7G ./usr
205M ./lib
0 ./lib64
8.9M ./bin
7.8M ./sbin
du: cannot access ‘./proc/12844/task/12844/fd/4’: No such file or directory
du: cannot access ‘./proc/12844/task/12844/fdinfo/4’: No such file or directory
du: cannot access ‘./proc/12844/fd/4’: No such file or directory
du: cannot access ‘./proc/12844/fdinfo/4’: No such file or directory
0 ./proc
27M ./tmp
0 ./dev
47G ./home
341M ./root
0 ./sys
337M ./run
0 ./mnt
0 ./srv
0 ./opt
55G .

  1. 定位/var 和 /usr 查看/var路径

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    du -lh --max-depth=1 /var
    349M /var/lib
    65M /var/cache
    3.2G /var/log
    0 /var/tmp
    64K /var/spool
    6.7M /var/backups
    0 /var/local
    0 /var/opt
    144K /var/mail
    192K /var/initsh
    3.6G /var
    这里/var/log有3.2G,可以删除一波

  2. 重新查看df -h 和 df -i

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    $df -h
    Filesystem Size Used Avail Use% Mounted on
    /dev/dm-0 7.8G 7.4G 368M 96% /
    udev 10M 0 10M 0% /dev
    tmpfs 3.2G 345M 2.9G 11% /run
    tmpfs 7.9G 56K 7.9G 1% /dev/shm
    tmpfs 5.0M 0 5.0M 0% /run/lock
    tmpfs 7.9G 0 7.9G 0% /sys/fs/cgroup
    /dev/vdc1 200G 47G 154G 24% /home
    /dev/vda1 236M 34M 190M 15% /boot

    $df -i
    Filesystem Inodes IUsed IFree IUse% Mounted on
    /dev/dm-0 1619760 127756 1492004 8% /
    udev 2056585 356 2056229 1% /dev
    tmpfs 2058885 501 2058384 1% /run
    tmpfs 2058885 15 2058870 1% /dev/shm
    tmpfs 2058885 4 2058881 1% /run/lock
    tmpfs 2058885 13 2058872 1% /sys/fs/cgroup
    /dev/vdc1 209713152 371880 209341272 1% /home
    /dev/vda1 62248 328 61920 1% /boot
    磁盘占用还是很大,但是inodes数量降下来了。

最后,kill掉启动的python进程后,随着时间推移,/dev/dm-0 几分钟内降到了53%。

个人猜测是由于这些 python进程一直在写/var/log,虽然在系统上清空了/var/log下的文件,但是 这些进程还在占用这些log文件,linux未能及时回收

reference#

  1. What is this dm-0 device?
  2. what is /dev/dm-0 that is 100% used?

skip(), limit() 和 sort()操作#

MongoDB使用find()方法查询后,可能需要对于返回结果进行排序。在有些查询中,我们并不需要返回全部结果,而是按指定的页长和页码返回指定数量的结果。本节来学习一下 查询操作中常用的 skip(), limit() 和 sort()操作。

limit()#

  • find()方法查询文档后,其默认返回前20条数据
  • 要限制MongoDB查询结果数,使用limit()方法, 读取指定数量的数据,如返回 NUMBER条数据:
1
db.COLLECTION_NAME.find().limit(NUMBER)

skip()#

  • 跳过指定数量的数据, 指定查询偏移量
  • 通过搭配limit() , 可以实现分页查询
1
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

sort()#

  • 实现查询结果排序
  • 使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列
1
db.COLLECTION_NAME.find().sort({KEY:1})

MongoDB 数据分页#

使用 skip(), limit() 和 sort()组合#

1
db.myCollection.find().sort({"_id":1}).skip(10).limit(10)
  • sort将数据根据_id排序

  • skip指跳过前10条记录,也可以说是从第10条开始

  • limit限制查询10条数据

  • 结果为按_id升序排序后的第10-19条的数据

然而, 根据MongoDB 数据分页和排序 limit,skip,sort用户测试结果而言: skip的大小严重影响性能,应该严格避免特别大的skip操作

避免比较大的skip操作#

分页查询时,可以记录上一条查询的score值,用如下方法获取数据(按score降序取数据):

1
db.scores.find({lid: lid, score: {$lt: last_score}}).sort({score: -1}).limit(20)

分批加载数据#

下面仅为实现思路, 不是正确的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def _load_callback(infos):
if infos:
next_id = None
for info in infos:
uid = info.get('_id')
...
next_id = uid

if len(infos) < 1000:
pass # do finish operation
else:
# continue load
self._load_db(next_id) # 记录上一条查询的id值
else:
pass # do finish operation

def _load_db(self, begin_id=''):
"""分批加载数据,batch_size=1000"""

infos = db.COLLECTION_NAME.find({'_id': {'$gt': begin_id,}}).sort({'_id': 1}).limit(1000)
self._load_callback(infos)

self._load_db()

what is rsnyc#

rsync 其实就是"远程同步"(remote sync)的意思, rsync 区别于FTP or scp的最大特点是会 检查发送方和接收方已有的文件,仅传输有变动的部分

它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件, 可替代cp和mv命令。

基本用法#

1.-r 参数,表示递归(包括子目录)

1
$ rsync -r source destination

若有多个文件或目录需要同步

1
$ rsync -r source1 source2 destination

2.-a 参数, 可以替代-r, 还可以同步元信息(比如修改时间、权限等) 由于 rsync 默认使用文件大小和修改时间决定文件是否需要更新,所以-a比-r更有用

3.-n 参数, 模拟执行的结果

1
$ rsync -anv source/ destination
-n参数模拟命令执行的结果,并不真的执行命令。-v参数则是将结果输出到终端,这样就可以看到哪些内容会被同步

4.--delete 参数, 删除只存在于目标目录、不存在于源目录的文件

1
$ rsync -av --delete source/ destination
--delete参数会使得destination成为source的一个镜像

5.--exclude 参数, 同步时排除某些文件或目录

排除了所有 TXT 文件

1
2
3
$ rsync -av --exclude='*.txt' source/ destination
# 或者
$ rsync -av --exclude '*.txt' source/ destination

要排除某个目录里面的所有文件,但不希望排除目录本身

1
$ rsync -av --exclude 'dir1/*' source/ destination

多个排除模式,可以用多个--exclude参数。

1
2
3
$ rsync -av --exclude 'file1.txt' --exclude 'dir1/*' source/ destination
或者
$ rsync -av --exclude={'file1.txt','dir1/*'} source/ destination

6.--include 参数,指定必须同步的文件模式

1
$ rsync -av --include="*.txt" --exclude='*' source/ destination

7.SSH 协议远程同步 将本地内容,同步到远程服务器

1
$ rsync -av source/ username@remote_host:destination

将远程内容同步到本地

1
$ rsync -av username@remote_host:source/ destination

如果 ssh 命令有附加的参数,则必须使用-e参数指定所要执行的 SSH 命令

1
$ rsync -av -e 'ssh -p 2234' source/ user@remote_host:/destination

8.增量备份

rsync 的最大特点就是它可以完成增量备份,也就是默认只复制有变动的文件。

除了源目录与目标目录直接比较,rsync 还支持使用基准目录,即将源目录与基准目录之间变动的部分,同步到目标目录。 第一次同步是全量备份,所有文件在基准目录里面同步一份。以后每一次同步都是增量备份,只同步源目录与基准目录之间有变动的部分,将这部分保存在一个新的目标目录。这个新的目标目录之中,也是包含所有文件,但实际上,只有那些变动过的文件是存在于该目录,其他没有变动的文件都是指向基准目录文件的硬链接。

--link-dest参数用来指定同步时的基准目录

1
$ rsync -a --delete --link-dest /compare/path /source/path /target/path

--link-dest参数指定基准目录/compare/path,然后源目录/source/path跟基准目录进行比较,找出变动的文件,将它们拷贝到目标目录/target/path。那些没变动的文件则会生成硬链接。这个命令的第一次备份时是全量备份,后面就都是增量备份了。

reference#

  1. rsync 用法教程

what is sed#

  • SED是功能强大的文本流编辑器。可以进行插入,删除,搜索和替换,最常用于查找、替换。SED可以在没有打开文件的情况下就编辑文件,这效率比用vim等软件打开并替换高多了。
  • Unix中的SED命令支持正则表达式,从而可以执行复杂的模式匹配。

参数说明#

  • a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
  • c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
  • d :删除,d 后面通常不接任何东西
  • i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
  • p :打印,通常 会与参数 sed -n 一起运行
  • s :替换,可以搭配正规表示法,例如 1,20s/old/new/g 就是啦!

替换#

1. 替换每行第一个字符串pattern#

1
$sed 's/unix/linux/' geekfile.txt

2. 替换每行第n个 pattern (使用/1,/2)#

1
$sed 's/unix/linux/2' geekfile.txt

3. 替换每行所有 pattern (使用/1,/2)#

1
$sed 's/unix/linux/g' geekfile.txt

4.给行内单词第一个字母加括号#

1
2
3
$ echo "Welcome To The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g'

(W)elcome (T)o (T)he (G)eek (S)tuff

删除#

1.删除第5行#

1
$ sed '5d' filename.txt

2.删除 3到5行#

1
$ sed '3,5d' filename.txt

3.删除 行内的 abc#

1
$ sed '/abc/d' filename.txt

打印#

1. 打印4到6行#

1
[root@rhel7 ~]# sed -n '4,6'p a.txt

2. 打印从n到最后#

1
# sed -n '3,$'p a.txt

3. 打印含有特定pattern的行#

1
# sed -n /every/p a.txt

reference#

  1. SED command in Linux
  2. Linux sed 命令