CentOS 下 Redmine 的 init 脚本

近几天选型项目管理系统,最终定下来使用 Redmine。维护时感觉启动、重启敲那么长的命令很麻烦,而且还不能在操作系统启动时自动启动,就自己写了个 init 脚本,在此分享给大家。
以下是脚本代码:

#!/bin/sh
#
# redmine       Redmine Daemon
#
# chkconfig: - 99 36
# description: Remine Daemon
. /etc/rc.d/init.d/functions

HOMEPATH=/home/redmine/redmine
PIDFILE=$HOMEPATH/tmp/pids/server.pid
PARAMS="-e production -p 80 -d"
SERVER=mongrel

cd $HOMEPATH

start(){
        echo 'Starting redmine...'
        ruby script/rails server $SERVER $PARAMS
        RETVAL=$?
        return $RETVAL
}

stop(){
        echo -n 'Stopping redmine...'
        killproc -p $PIDFILE -INT
        RETVAL=$?
        return $RETVAL
}

status(){
        echo -n 'Redmine is '
        if [ -f $PIDFILE ]
        then
                PID=`/bin/cat $PIDFILE`
                STATUS=`/bin/ps -p $PID`
                RETVAL=$?
                if [ $RETVAL -eq 0 ]
                then
                        echo 'running.'
                        return $RETVAL
                fi
        fi
        echo 'not running.'
}

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                start
                echo
                ;;
        status)
                status
                ;;
        *)
                echo "Usage $0 {start|stop|status|restart}"
                exit 1
esac

将以上脚本保存为 /etc/init.d/redmine 后,就可以使用 chkconfig 来配置随系统启动了:

chkconfig --add redmine
chkconfig redmine on

Cgroups 学习笔记[6] – blkio 子系统

参数说明

可设置的参数:

  • blkio.weight
    说明:指定 cgroup 默认可用 IO 的比例(加权),值的范围为 100 至 1000。该值可由具体设备的 blkio.weight_device 参数覆盖。
    示例:设置 cgroup lv0 的默认加权为 500: cgset -r blkio.weight=100 lv0
  • blkio.weight_device
    说明:指定 cgroup 中指定设备的可用 IO 比例(加权),范围是 100 至 1000。该值的的格式为 major:minor weight ,其中 majorminor 参考文档 Linux 分配的设备
    示例:设置 cgroup lv0 对 /dev/sda 的加权为 500: cgset -r blkio.weight_device="8:0 500" lv0
  • blkio.throttle.read_bps_device / blkio.throttle.write_bps_device
    说明:指定 cgroup 中某设备每秒钟读/写数据的字节上限。其格式为 major:minor bytes_per_second
    示例:设置 cgroup lv0 在 /dev/sdc 上每秒最多读 10KiB 数据: cgset -r blkio.throttle.read_bps_device="8:32 10240" lv0
  • blkio.throttle.read_iops_device / blkio.throttle.write_iops_device
    说明:指定 cgroup 中某设备每秒钟可以执行的读/写请求数上限。其格式为 major:minor operations_per_second
    示例:设置 cgroup lv0 在 /dev/sdc 上每秒最多执行 1000 次读请求: cgset -r blkio.throttle.read_iops_device="8:32 1000" lv0

报告参数:

继续阅读

推荐杨万富写的“思考MySQL内核”系列文章

MySQL 用到一定程度后,免不了要去读一下 MySQL 的源码。这里推荐一下杨万富的“思考MySQL内核”系列文章,写的挺浅显易懂的,对准备读 MySQL 源码的同学应该会有一点帮助:

  1. 思考mysql内核之初级系列1— mysql的启动过程
  2. 思考mysql内核之初级系列2—我可以为你服务什么?
  3. 思考mysql内核之初级系列3—办理业务的流程
  4. 思考mysql内核之初级系列4–innodb缓冲区管理
  5. 思考mysql内核之初级系列5—information_schema不是innodb数据字典
  6. 思考mysql内核之初级系列6—innodb文件管理
  7. 思考mysql内核之初级系列7—innodb的hash表实现
  8. 思考mysql内核之初级系列8—innodb的list算法
  9. 思考mysql内核之初级系列9—innodb动态数组的实现
  10. 思考mysql内核之初级系列10—mysql内核调试方法
  11. 思考mysql内核之初级系列11—innodb的页编号
  12. 思考mysql内核之初级系列12—innodb的簇描述结构
  13. 思考mysql内核之初级系列13—innodb的簇页管理
  14. 思考mysql内核之初级系列14—innodb的旧式记录结构

关于 Linux 文件系统的 Superblock, Inode, Dentry 和 File

首先,Superblock, Inode, Dentry 和 File 都属于元数据(Metadata),根据维基百科中的解释,所谓元数据,就是描述数据的数据(data about data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件纪录等功能。Linux/Unix 文件系统的元数据以多级结构保存。

Superblock 是文件系统最基本的元数据,它定义了文件系统的类似、大小、状态,和其他元数据结构的信息(元数据的元数据)。Superblock 对于文件系统来说是非常关键的,因此对于每个文件系统它都冗余存储了多份。Superblock对于文件系统来说是一个非常“高等级”的元数据结构。例如,如果 /var 分区的 Superblock 损坏了,那么 /var 分区将无法挂载。在这时候,一般会执行 fsck 来自动选择一份 Superblock 备份来替换损坏的 Superblock,并尝试修复文件系统。主 Superblock 存储在分区的 block 0 或者 block 1 中,而 Superblock 的备份则分散存储在文件系统的多组 block 中。当需要手工恢复时,我们可以使用 dumpe2fs /dev/sda1 | grep -i superblock 来查看 sda1 分区的 superblock 备份有哪一份是可用的。我们假设 dumpe2fs 输出了这样一行:Backup superblock at 163840, Group descriptors at 163841-163841 ,通过这条信息,我们就可以尝试使用这个 superblock 备份:/sbin/fsck.ext3 -b 163840 -B 1024 /dev/sda1。请注意,这里我们假设 block 的大小为 1024 字节。

Inode 中包含了一个文件的元数据。为清晰起见,Linux/Unix 系统中的所有对象均为文件:实际的文件、目录、设备等等。请注意,在 Inode 所包含的元数据中,并没有文件名。一个 Inode 包含的基本信息有:所有权(用户,组),访问模式(读、写、执行权限)和文件类型。

Dentry 是将 Inode 和 文件联系在一起的”粘合剂”,它将 Inode number 和文件名联系起来。Dentry 也在目录缓存中扮演了一定的角色,它缓存最常使用的文件以便于更快速的访问。Dentry 还保存了目录及其子对象的关系,用于文件系统的遍历。

File 即文件,其实只是一些逻辑上相关的数据,相对而言没什么好说的。

参考:
http://zh.wikipedia.org/wiki/%E5%85%83%E6%95%B0%E6%8D%AE
http://unix.stackexchange.com/questions/4402/what-is-a-superblock-inode-dentry-and-a-file

MegaCli 有关 RAID Rebuild 的几条指令

1. 查看物理磁盘状态:

# MegaCli -PdInfo -PhysDrv \[E:S\] -aALL
Rebuild 中的物理磁盘状态中会显示:"Firmware state: Rebuild"

2. 查询 Rebuild 进度:

# MegaCli -pdrbld -showprog -physdrv\[E:S\] -aALL
返回内容类似于下面这样:
Rebuild Progress on Device at Enclosure 32, Slot 5 Completed 77% in 101 Minutes.

3. 以文本进度条样式显示 Rebuild 进度:

# MegaCli -pdrbld -progdsply -physdrv\[E:S\] -aALL 继续阅读

Cgroups 学习笔记[5] – 管理 Cgroups 中的进程

1. 将已有进程加入 Cgroups

我们可以使用 cgclassify 将进程加入 Cgroups,其用法为:
~]# cgclassify -g subsystems:path_to_cgroup pidlist
其中 subsystems 可以为一个子系统或者多个以逗号 ‘,’ 隔开的子系统,pidlist 为进程 ID,多个进程 ID 之间以空格隔开。
例如:
~]# cgclassify -g cpu,memory:group1 1701 1138

类似于设置 Cgroups 参数,我们也可以直接使用 echo 来将进程加入 Cgroups。使用方法为
~]# echo pid > /cgroup_path/tasks
对于前面的例子,使用 echo 的方法为:
~]# echo 1701 > /cgroup/lab1/group1/tasks
~]# echo 1138 > /cgroup/lab1/group1/tasks

继续阅读

Cgroups 学习笔记[4] – 设置控制参数

我们可以使用 cgset 来设置 Cgroups 的参数,其格式为:
~]# cgset -r parameter=value path_to_cgroup
例如,当存在 /cgroup/cpuset/group1 时,可以使用如下命令指定该组有权访问的 CPU:
~]# cgset -r cpuset.cpus=0-1 group1

如果要设置根层次结构(如 /cgroup/cpuset/)的参数,可以设置 path_to_cgroup 为 “/” 或 “.”。例如:
~]# cgset -r cpuacct.usage=0 /

~]# cgset -r cpuacct.usage=0 .
注:只有少数的一些参数可以指定给根层次结构(比如前面例子中的 cpuacct.usage),其他比如 cpuset.cpu 等大多数参数对根层次结构都不会起作用。

我们还可以使用 –copy-from 参数来以某一个 Group 为模板快速的复制一个新的 Group 出来,其命令格式为:
~]# cgset --copy-from path_to_source_cgroup path_to_target_cgroup
例如:
~]# cgset --copy-from group1/ group2/

不使用 cgset 的话,我们也可以使用 echo 来设置 Cgroups 参数,对于第一个例子,设置 group1 的 cpuset.cpus=0-1,也可以用下面这条指令:
~]# echo 0-1 > /cgroup/cpuset/group1/cpuset.cpus

Cgroups 学习笔记[3] – 如何编辑层次结构和组

要创建和修改 Cgroups 的层次结构和组,最简单的办法就是修改 /etc/cgconfig.conf,然后重启 cgconfig 服务。

以下这段配置创建了一个名为 cpu_and_mem 的层次结构,并关联了 cpuset, cpu, cpuacct, memory 四个子系统:

mount {
    cpuset  = /cgroup/cpu_and_mem;
    cpu     = /cgroup/cpu_and_mem;
    cpuacct = /cgroup/cpu_and_mem;
    memory  = /cgroup/cpu_and_mem;
}

下面我们学习一下如何手动创建这个层次结构:

首先我们创建一个目录作为层次结构的挂载点,方法为:
~]# mkdir /cgroup/name
例如:
~]# mkdir /cgroup/cpu_and_mem
继续阅读

Cgroups 学习笔记[2] – cgconfig 简介

RHEL 6 提供了 libcgroup 来管理 Cgroups,该软件包中包含了一系列 Cgroup 工具及其使用手册。我们可以使用它来绑定 Cgroups 层次结构,设置 Cgroups 参数。上文开头我们提到的 cgconfig 服务便是包含在 libcgroup 软件包里的。

cgconfig 默认是不随系统启动的,我们可以使用 chkconfig 来配置它随系统启动,以便每次系统重启后都能自动恢复之前的 Cgroups 配置。

cgconfig 在启动时默认会读取 /etc/cgconfig.conf 中的配置来创建 Cgroups 层次结构,绑定所需的文件系统并关联子系统,创建 Cgroups 组并设置每个组的子系统参数。当我们停止 cgconfig 服务时,它会卸载全部的 Cgroups 配置。

/etc/cgconfig.conf 包含两大部分:mount 和 group。
继续阅读

Cgroups 学习笔记[1] – Cgroups 介绍

Control Groups (Cgroups) 是 Red Hat Enterprise Linux 6 (以后简称 RHEL6) 提供的一项内核功能。我们可以使用 Cgroups 为任务(进程)分配资源,例如 CPU 时间、系统内存、网络带宽等。我们可以对 Cgroups 进行监控,禁止 Cgroups 控制下的进程访问某些资源,还可以在一个运行中的系统中对 Cgroups 动态地进行配置。cgconfig ( control group config ) 是一项系统服务,它可以根据配置文件创建 Cgroups,我们可以通过它在每次重启操作系统之后保持一致的 Cgroups 配置。

Cgroups 的组织结构为层次体系,类似于进程,子 Cgroups 继承上一级的属性。Cgroups 可以有多个单独的层次结构,每个层次结构关联一个或多个子系统。一个子系统表示一个单一的资源,如 CPU 时间或内存。RHEL6 提供了以下 9 个子系统:

* blkio – 该子系统限制块设备的输入输出访问,例如物理驱动器(磁盘、SSD、USB等)。
* cpu – 该子系统调度 cgroup 任务对 CPU 的访问。
* cpuacct – 该子系统生成 cgroup 中的任务使用 CPU 资源的报告。
* cpuset – 该子系统将各个 CPU 和内存节点指定给 cgroup 中的任务。
* devices – 该子系统可以允许或者禁止 cgroup 中的任务访问某个设备。
* freezer – 该子系统暂停或者继续 cgroup 中的任务。
* memory – 该子系统设置 cgroup 中任务对内存的使用限制,并且生成各任务对内存的使用报告。
* net_col – 该子系统使用类标识符 ( classid ) 来标记网络包,以使用 Linux 流量控制 ( tc ) 能够分辨 cgroup 中的特定任务所发出的数据包。
* net_prio – 该子系统可以动态地设置每个网络接口 ( network interface ) 的优先级。
* ns – 命名空间子系统。

继续阅读