Raid:
Level仅用于标识磁盘组合方式的不同
raid0, raid1, raid5, raid10, raid50, jbod
raid0:至少需要两块磁盘,不允许任何盘出错,没有容错能力,读写性能都提升,硬盘利用率100%
raid1: 至少需要两块磁盘,允许一块盘出错,镜像,硬件容错能力,读性能提升,写性能下降,硬盘利用率50%
raid5: 至少需要三块磁盘,允许一块盘出错,校验盘分布在各盘上,读写性能都提升,硬盘利用率(n-1)/n%
raid10: 至少需要四块磁盘,允许不同组内各坏一块盘,读写性能都提升,硬盘利用率50%(先做raid1,再做raid0)
jbod:在逻辑上把几个物理磁盘一个接一个串联到一起,从而提供一个大的逻辑磁盘。jbod上的数据简单的从第一个磁盘开始存储, 当第一个磁盘的存储空间用完后, 再依次从后面的磁盘开始存储数据。
mdadm: 模式化的工具
-A:装配模式
-C:创建模式
-F:监控模式
管理模式
-f模拟硬盘损坏
-r移除硬盘
-a添加硬盘
-C:创建模式
-a yes自动为创建的raid设备创建设备文件;
-l 级别 指定Raid级别
-n # 用于创建RAID设备的设备个数;
-x #用于创建RAID热备磁盘的个数;
-c #指定分块大小,默认为512,单位为KB
-D: 显示阵列的详细信息
--detail:
-S /path/to/raid_device停止指定的RAID设备
-A /path/to/raid_device DEVICES使用指定的设备装配并启动指定的RAID设备
watch -n # ‘COMMAND‘每隔#执行一次指定的命令;单位为秒钟
wathc -n 1 ‘cat /proc/mdstat‘每秒钟查看一次RAID的同步状态
练习:创建一个大小为4G的RAID5;
给其添加一个空闲盘,模拟损坏等;
停止raid;
mdadm -C /dev/md5 -a yes -l 5 -n 3 -x 1 /dev/sdb{1,2,3,4}
mdadm -D /dev/md5
cat /proc/mdstat
mke2fs -t ext4 /dev/md5
mount /dev/md5 /mnt/
ls /mnt
mdadm -f /dev/md5 /dev/sdb1
mdadm -r /dev/md5 /dev/sdb1
mdadm -a /dev/md5 /dev/sdb1
umount /mnt
mdadm -S /dev/md5
mdadm -A /dev/md5 /dev/sdb{1,2,3,4}
bash知识点:while循环和until循环
for varName in 列表; do
循环体
done
条件测试:
执行命令: 命令成功,条件测试成功;否则为失败;
根据$?, 状态返回值; 0表示命令执行成功,非0表示命令执行失败;
表达式:
[ expression ]
[[ expression ]]
test expression
while 条件测试; do
循环体
done
while循环:条件测试成功,则循环;失败,则退出;
如何让while循环退出:在循环体中改变测试条件中用于控制循环次数的变量的值;
练习:求100以内所有正整数的和;
declare -i sum=0
declare -i i=1
while [ $i -le 100 ]; do
let sum+=$i
let i++
done
echo $sum
练习:通过键盘提示用户输入字符,将用户输入的小写字母转换为大写,转换一次之后,再次提醒,再输再转换;但输入quit表示退出;
#!/bin/bash
read -p "Enter a word: " word
while [[ "$word" != "quit" ]]; do
echo $word | tr ‘a-z‘ ‘A-Z‘
read -p "Enter a word again: " word
done
练习:显示如下菜单给用户
cpu) print cpu information;
mem) print memory information;
disk) print disk infomation;
quit) quit
Enter your option:
根据用户的选择输出相应信息;
每次执行后,不退出,而由用户再次指定新的选项;
#!/bin/bash
#
cat << EOF
cpu) print cpu information;
mem) print memory information;
disk) print disk infomation;
quit) quit
EOF
read -p "Enter your option: " option
option=`echo $option | tr ‘A-Z‘ ‘a-z‘`
while [[ "$option" != "quit" ]]; do
if [[ "$option" == "cpu" ]]; then
cat /proc/cpuinfo
elif [[ "$option" == "mem" ]]; then
free -m
elif [[ "$option" == "disk" ]]; then
df -h
else
echo "Wrong option..."
fi
read -p "Enter your option again: " option
option=`echo $option | tr ‘A-Z‘ ‘a-z‘`
done
练习:提示用户输入一个用户名,如果存在:显示用户UID和SHELL信息;否则,则显示无此用户;
显示完成之后,提示用户再次输入;如果是quit则退出;
#!/bin/bash
#
read -p "Enter a user name: " userName
while [[ "$userName" != "quit" ]]; do
if [ -z "$userName" ]; then
echo "User name null."
elif id $userName &> /dev/null; then
grep "^$userName\>" /etc/passwd | cut -d: -f3,7
else
echo "No such user."
fi
read -p "Enter a user name again(quit to exit): " userName
done
练习:提示用户输入一个用户名,判断用户是否登录了当前系统;
如果没有登录,则停止5秒钟之后,再次判断;直到用户登录系统,显示“用户来了”,而后退出;
#!/bin/bash
#
read -p "Enter a user name: " userName
while ! id $userName &> /dev/null; do
read -p "Enter a user name again: " userName
done
while ! who | grep "^$userName" &> /dev/null; do
echo "$userName is not here."
sleep 5
done
echo "$userName is on."
#!/bin/bash
#
read -p "Enter a user name: " userName
until [ -n "$userName" ] && id $userName &> /dev/null; do
read -p "Enter a user name again: " userName
done
until who | grep "^$userName" &> /dev/null; do
echo "$userName is not here."
sleep 5
done
echo "$userName is on."
bash编程之until循环:
until 测试条件; do
循环体
done
条件不满足,则循环;否则,退出;
练习:用until循环,求100以内所有正整数之和;
#!/bin/bash
declare -i sum=0
declare -i i=1
until [ $i -gt 100 ]; do
let sum+=$i
let i++
done
echo $sum
bash编程之组合测试条件深入探讨:
逻辑与:多个条件同时满足
[ CONDITION1 ] && [ CONDITION2 ]
[ CONDITION1 -a CONDITION2 ]
[[ CONDITION1 && CONDITION2 ]]
注意:前两个使用单或双中括号都可,但,&&不允许用于单中括号中,所以第三种只能用于双中括号中;
逻辑或:多个条件中有一个满足即为真;
[ CONDITION1 ] || [ CONDITION2 ]
[ CONDITION1 -o CONDITION2 ]
[[ CONDITION1 || CONDITION2 ]]
注意:||不允许用于单中括号中;
德 摩根 定律
!(条件1 或 条件2) = !条件1 并且 !条件2
!(条件1 并且 条件2) = !条件1 或 !条件2
使用while循环一次读取文件的一行,直到文件尾部:
while read line; do
循环体
done < /path/to/somefile
练习:取出当前系统上,默认shell为bash的用户
#!/bin/bash
#
while read line; do
[[ `echo $line | cut -d: -f7` == "/bin/bash" ]] && echo $line | cut -d: -f1
done < /etc/passwd
练习:显示所有其ID号为偶数的用户;
#!/bin/bash
#
while read line; do
userID=`echo $line | cut -d: -f3`
if [ $[$userID%2] -eq 0 ]; then
echo -n "$userID: "
echo $line | cut -d: -f1
fi
done < /etc/passwd
练习:显示/etc/rc.d/rc.sysinit文件中,其总字符个数大于30的行;
#!/bin/bash
#
while read line; do
charCounts=`echo $line | wc -c`
if [ $charCounts -gt 30 ]; then
echo -n "$charCounts: "
echo $line
fi
done < /etc/rc.d/rc.sysinit
练习:显示所有其UID和GID均为偶数的用户;
#!/bin/bash
#
while read line; do
userID=`echo $line | cut -d: -f3`
groupID=`echo $line | cut -d: -f4`
if [ $[$userID%2] -eq 0 ] && [ $[$groupID%2] -eq 0 ]; then
echo -n "$userID, $groupID: "
echo $line | cut -d: -f1
fi
done < /etc/passwd
练习:显示/etc/rc.d/rc.sysinit文件中,其总字符个数大于30且非以“#”开头的行;
#!/bin/bash
#
while read line; do
charCounts=`echo $line | wc -c`
if [ $charCounts -gt 30 ] && [[ "$line" =~ ^[^#] ]] ; then
echo -n "$charCounts: "
echo $line
fi
done < /etc/rc.d/rc.sysinit
练习:写一个脚本,完成如下任务
1、提示用户输入一个磁盘设备文件路径;
如果用户给定的路径文件不存在或不是一个块设备文件,则提示用户重新输入,直到输入正确为止,或者输入quit以9为退出码结束脚本;
2、提示用户“下面的操作会清空磁盘中的数据,并提问是否继续”
如果用户给出字符y或单词yes,则继续,否则,则提供以8为退出码结束脚本;
3、将用户指定的磁盘上的分区清空,而后创建两个主分,大小分别为100M和512M;
4、格式化此两个分区;
5、将第一个分区挂载至/mnt/boot目录;第二个分区挂载至/mnt/sysroot目录;
#!/bin/bash
echo -n -e "\033[31mEnter a disk path: \033[0m"
read diskPath
while [ $diskPath != "quit" ];do
if ! [ -b $diskPath ];then
echo -n -e "\033[31mEnter a disk path again: \033[0m"
read diskPath
else
echo -n -e "\033[31mFlow action clear disk data y | n:\033[0m"
read option
if [[ $option == "n" ]];then
exit 8
elif [[ $option == "y" ]];then
dd if=/dev/zero of=$diskPath bs=512 count=1 &> /dev/null
echo "n
p
1
+100M
n
p
2
+512M
w" | fdisk $diskPath &> /dev/null
if mount | grep /mnt/boot &> /dev/null;then
umount /mnt/boot
fi
if mount | grep /mnt/sysroot &> /dev/null;then
umount /mnt/sysroot
fi
mke2fs -t ext4 ${diskPath}1 &> /dev/null
mke2fs -t ext4 ${diskPath}2 &> /dev/null
if ! [ -e /mnt/boot ];then
mkdir /mnt/boot
fi
if ! [ -e /mnt/sysroot ];then
mkdir /mnt/sysroot
fi
mount ${diskPath}1 /mnt/boot
mount ${diskPath}2 /mnt/sysroot
echo -e "\033[32mFinished !\033[0m"
exit 0
else
echo "Unkown option!"
fi
fi
done
exit 9
LVM: Logical Volume Manager
设备文件:/dev/卷组名/逻辑卷名
/dev/mapper/卷组名-逻辑卷名
物理卷管理命令:pv
pvcreate创建
pvremove移除
pvscan, pvs, pvdisplay查看
pvmove 块迁移
卷组的管理命令:vg
vgcreate创建
vgremove移除
vgscan, vgs, vgdisplay查看
vgextend, vgreduce扩展、缩减
vgcreate,
-s: PE大小, 默认4M
#vgcreate -s 4M vg_name
逻辑卷的管理命令:lv
lvcreate创建
lvremove移除
lvscan, lvdisplay, lvs查看
lvextend, lvreduce 扩展、缩减
lvcreate
-L :空间大小
-n : lv名称
# lvcreate -L Size -n Name vg_name
扩展卷组:
1、准备要添加的物理卷;
2、扩展卷组:
添加物理卷至卷组中;
# vgextend vg_name /path/to/pv_device
缩减卷组:
1、确定要移除的物理卷的总空间大小,要小于VG当前的可用空间大小;
2、将要移除的物理卷上的所有PE移动至其它PV
# pvmove /path/to/pv_device
3、缩减vg
# vgreduce vg_name /path/to/pv_device
逻辑卷扩展的步骤:
1、先确定扩展的大小;并确保所属的卷组有足够的剩余空间;
2、扩展物理边界:
# lvextend -L [+]Size /path/to/lv_device
3、扩展逻辑边界:
# resize2fs /path/to/lv_device
缩减逻辑卷的步骤:
1、卸载卷,并执行强制检测
# e2fsck -f /path/to/lv_device
2、缩减逻辑边界:
# resize2fs /path/to/lv_device SIZE
3、缩减物理边界:
# lvreduce -L [-]Size /path/to/lv_device
快照卷:逻辑卷的一种,通常为只读(通常用于数据备份)
# lvcreate -s -L Size -n Name -p r /path/to/original_lv_device
练习:
1、创建一个由两个物理卷组成大小为20G的卷组myvg,要求PE大小16M;而后新建 大小为7G逻辑卷mylv1,要求其文件系统为ext4,块大小为2048,且开机能自动挂载至/users;
2、新建用户openstack,其家目录为/users/openstack,而后切换至openstack用户,复制一些文件至其家目录中;
3、缩减mylv1至5G大小;而后切换至openstack用户,确保其数据没有丢失;
4、对mylv1创建快照卷snap-mylv1,并通过其备份数据至/tmp/user.tar.bz2;
pvcreate /dev/sdb{1,2}
vgcreate -s 16M myvg /dev/sdb{1,2}
lvcreate -L 7G -n mylv1 myvg
mke2fs -t ext4 -b 2048 /dev/myvg/mylv1
mkdir /users
blkid /dev/myvg/mylv1
echo UUID=c457275b-5aa6-42d7-b770-5d40f44a17f4 /users ext4 defaults 0 0 >> /etc/fstab
mount -a
useradd -d /users/openstack openstack
su - openstack
cp /etc/fstab ./
umount /users
e2fsck -f /dev/myvg/mylv1
resize2fs /dev/myvg/mylv1 5G
lvreduce -L 5G /dev/myvg/mylv1
mount -a
su - openstack
cat fstab
lvcreate -s -p r -L 1M -n snap-mylv1 /dev/myvg/mylv1
mount /dev/myvg/snap-mylv1 /mnt
tar jcf /tmp/user.tar.bz2 /mnt
umount /mnt
lvremove /dev/myvg/snap-mylv1