利用 bash 命令做 SQL 数据修补

如果是把一个 DB 或者一个 table 从一个服务器送到另一个, 那么使用 mysqldump 命令就可以了. 但有的时候, 需要的数据可能只是若干条记录, 就不能用 mysqldump 了. 奇怪的是我 google 了一番居然也没找到很方便的方法. 求人不如求自己吧, 下面是用 bash 命令的解决方法:

mysql <database> -uroot -e “select * from <table> where <condition>…” |tail -n +2 |sed -e ‘s/^/(“/g’ -e ‘s/$/”)/g’ -e ‘s/\t/”,”/g’ |while read values; do echo “insert into <table> values $values”; done

然后把输出的 SQL 在目标服务器上运行即可. 记得把< >里面的变量替换为实际需要的内容. 🙂

Linux 命令行上的文字处理

总是有些用户, 明明是自己手抖点错了, 却偏偏要怪服务器出问题. 如果让我选择相信一个人还是一台机器, 那… 还是选机器比较放心. 当然也不能冤枉好人, 于是如何从若干 GB 的服务器日志里找到线索就成为解决问题的关键了.

首先是 grep. grep 就好像是个过滤器, 将无关的内容滤掉, 却从不漏下真相. 假设服务器日志是 server.log, 其中包含时间, 地点, 人物:

1, 找出所有含 beijing 的记录

grep beijing server.log

2, 包含 2013-12-01 当天, 在 beijing 关于 user 的记录

grep  -E -e ‘2013-12-01.*beijing.*user’ server.log

3, 也可以将 grep 串联起来, 逐步缩小包围圈, 这样如果个别记录不符合时间, 地点, 人物的顺序, 也不会被漏掉. 当然我觉得日志还是规矩一点的好.

grep ‘2013-12-01’ server.log |grep beijing |grep user

另外作为开发人员, 使用 grep 来分析代码也很不错的. 找到目标之后, 很可能需要生成一个报表, 最简单的就是 cut 命令了. 假设日志格式是”date time location user action”, 如果我们只需要”date time user action”, 那么

grep beijing server.log| cut -d ‘ ‘ -f1,2,4,5

其中 -d ‘ ‘ 指定使用空格 ‘ ‘ 来做分隔符, -f1,2,4,5 就分别代表需要输出的字段, 因为 location 是第三个, 因此 3 没有出现. 比 cut 强大的多的就是 awk 了, 生成一个有小计/总计什么的表格完全是小菜. 不过这个不是我的兴趣, 所以就点到为止.

🙂

在 Linux 中充分利用多核 CPU 来转码

上回写的<听美剧, 练英语听力>之后, 发现忘了放个批量处理的脚本. 下面补上, 顺便练习一下多核心协同处理. 嗯, 手机都4核了不是?

用到的命令类似:

avconv -i your.mkv -vn -acodec libmp3lame -ac 2 -f mp3 your.mp3

简单的 bash 单循环写法:

ls *.mkv |while read i; do avconv -i $i -vn -acodec libmp3lame -ac 2 -f mp3 $i.mp3; done

这就只用到了一个 CPU 核心. 如果将 avconv 放到后台执行就可以做到多进程, 但又不方便控制进程数, 当进程数远远大于 CPU 核心数时就可以体验一下一台服务器快被烤熟时的感觉了. 后来发现 xargs 支持指定数目的进程, 简直是无法要求更多了:

ls *.mkv | xargs -n 1 -P 4 -I filename avconv -i filename -vn -acodec libmp3lame -ac 2 -f mp3 filename.mp3

又简单又高效了是不是? 其中 -P 4 就是开启4个进程来执行. 🙂

给 Ubuntu Linux 添加一个大硬盘

曾经预测 3.5″ 的硬盘即将被 2.5″ 硬盘取代. 无奈存储业不争气, 2.5″ 硬盘的容量依旧远远落后于 3.5″. 下面是在 Ubuntu Linux 中使用命令行添加一个 3TB 硬盘的过程.

首先使用 parted (fdisk已退休), 假设新硬盘是第二块, 因此是 sdb:

(parted) select /dev/sdb 
Using /dev/sdb

(parted) print
Model: ATA WDC WD30EZRX-00M (scsi)
Disk /dev/sdb: 3001GB
Sector size (logical/physical): 512B/4096B
Partition Table: msdos

可以看出, 出厂的硬盘使用的是旧式的 MBR 分区表, 不支持大于 2TB 的分区. 那么接班的是谁呢, 是 GPT

(parted) mklabel gpt
Warning: The existing disk label on /dev/sdb will be destroyed and all data on
this disk will be lost. Do you want to continue?
Yes/No? yes

GPT 分区表做好了, 下面是生成一个使用全部空间的主分区. 其中的 1 表示从第1个MB开始. 不是应该从0开始么? 但是输入 0 -1 的话会收到一个  Warning: The resulting partition is not properly aligned for best performance.  警告.

(parted) mkpart primary 1 -1

(parted) print
Model: ATA WDC WD30EZRX-00M (scsi)
Disk /dev/sdb: 3001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt

Number  Start   End     Size    File system  Name     Flags
1      1049kB  3001GB  3001GB  ntfs         primary

到此, parted 的任务已完成, 输入 ‘quit’ 退出. 缺省文件系统居然是 NTFS… 用 EXT4 取代吧.

~ mkfs.ext4 /dev/sdb1
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
183148544 inodes, 732566272 blocks
36628313 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
22357 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
102400000, 214990848, 512000000, 550731776, 644972544

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

然后将旧硬盘里的内容复制过去, 我喜欢用 rsync, 保证原汁原味的复制

~ rsync -av /path/to/source/* /path/to/destination

下面是将新分区挂载到文件系统, 使用 UUID

ls /dev/disk/by-uuid -lh total 0 lrwxrwxrwx 1 root root 10 May 18 13:23 09985c43-f6c2-43c2-a1da-6643c56d5590 -> ../../sdb1 …

最后一件事是把上面的 UUID 写在 /etc/fstab 里面

UUID=09985c43-f6c2-43c2-a1da-6643c56d5590         /home        ext4    defaults    0    2

要生效的话还要 mount -a 一下.

🙂