0%

进程管理

1.进程的管理:

当我们运行一个程序,那么我们将该程序叫进程
进程 线程 协程

2.为什么要学进程管理?

为了管理架构的服务

3.程序和进程的区别

1)程序:开发写出来的代码,程序是永久存在的。
2)进程:它会随着程序的终止而销毁。

4.进程的生命周期

1.当父进程接收到任务调度时,会通过fork派生子进程来处理,那么子进程会继承父进程的衣钵。
2.子进程在处理任务代码时,父进程会进入等待的状态...
3.如果子进程在处理任务过程中,父进程退出了,子进程没有退出,那么这些子进程就没有父进程来管理了,就变成了僵尸进程。
4.每个进程都会有自己的PID号,(process id)子进程则PPID

5.进程管理命令(静态管理):ps

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
a:显示所有与终端相关的进程
u:显示用户
x:显示所有与终端无关的进程

#用户
USER
#进程号
PID
#占CPU的百分比
%CPU
#占内存的百分比
%MEM
#虚拟内存
VSZ
#物理内存
RSS
#该进程在哪个终端运行
TTY
tty1: 物理机的终端
pts/0: 远程连接的终端
?: 内核运行的终端


#状态
STAT
S:进入睡眠状态的进程
s:父进程
R:正在运行的进程
D:不可中断的进程
N:优先级低
<:优先级高
l:多线程的
+:在前台运行的进程
T:暂停,停止的进程
Z:僵尸进程



L:页被锁进内存
|:多进程的

#进程启动时间
START
#进程使用CPU的时间
TIME
#程序运行的命令
COMMAND

进程相关的命令:

1.按照某一列排序:

1
[root@oldboyedu ~]# ps aux --sort vsz

2.指定想查看的列

1
[root@oldboyedu ~]# ps axo user,pid,vsz,command

3.查看子进程

1
2
3
4
5
6
[root@oldboyedu ~]# ps auxf |grep [n]ginx
root 119884 0.0 0.1 125108 2256 ? Ss 10:06 0:00 nginx: master process /usr/sbin/nginx
nginx 119885 0.0 0.1 125496 3140 ? S 10:06 0:00 \_ nginx: worker process
nginx 119886 0.0 0.1 125496 3140 ? S 10:06 0:00 \_ nginx: worker process
nginx 119887 0.0 0.1 125496 3140 ? S 10:06 0:00 \_ nginx: worker process
nginx 119888 0.0 0.1 125496 3140 ? S 10:06 0:00 \_ nginx: worker process

4.额外命令:pstree

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
查看进程树:
[root@oldboyedu ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
├─VGAuthService
├─abrt-watch-log
├─abrtd
├─agetty
├─auditd───{auditd}
├─crond
├─dbus-daemon───{dbus-daemon}
├─irqbalance
├─master─┬─pickup
│ └─qmgr
├─nginx───4*[nginx]
├─polkitd───6*[{polkitd}]
├─rsyslogd───2*[{rsyslogd}]
├─sshd─┬─sshd───bash───pstree
│ └─sshd───bash───bash───bash
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───4*[{tuned}]
├─vmtoolsd───{vmtoolsd}
└─vsftpd

#默认不加选项是查看进程的pid
[root@oldboyedu ~]# pgrep -l -a nginx
[root@oldboyedu ~]# pgrep sshd
119346
120226
120254
[root@oldboyedu ~]# pgrep -l sshd
119346 sshd
120226 sshd
120254 sshd
[root@oldboyedu ~]# pgrep -l -a sshd
119346 /usr/sbin/sshd -D
120226 sshd: root@pts/0
120254 sshd: root@pts/1

-a:查看进程的运行命令
-l:查看进程名字
-u:指定用户

[root@oldboyedu ~]# pidof sshd
120254 120226 119346

5.top命令

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
28
29
第一行内容:
当前系统时间 服务器运行时间 有3个用户在登录
top - 10:54:23 up 1 day, 17:56, 3 users,

#平均负载(系统)
load average: 0.00, 0.01, 0.05

第二行内容:

总共122个任务 1个正在运行(R) 121个进入睡眠状态的(S) 没有停止(T) 0个僵尸进程(Z)
Tasks: 122 total, 1 running, 121 sleeping, 0 stopped, 0 zombie

第三行内容:
用户态 内核态 优先级 空闲 等待(wait) 硬中断 软中断 虚拟机占用物理机CPU的百分比
%Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

第四行:内存
KiB Mem : 2028116 total, 150780 free, 144108 used, 1733228 buff/cache

第五行:swap虚拟内存
KiB Swap: 2097148 total, 2097148 free, 0 used. 1645080 avail Mem

第六行:

进程号 用户 优先级 虚拟内存 物理内存 共享内存 状态 占CPU的百分比 占内存的百分比
PID USER PR NI VIRT RES SHR S %CPU %MEM

运行时间 进程的运行命令
TIME+ COMMAND

中断:硬中断
中断是系统用来影响硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序来影响设备的请求

软中断:
事实上,为了解决中断处理程序执行过长的和丢失中断的问题,Linux将中断处理过程分成了两个阶段:
第一阶段:用来快速处理(硬中断)中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关工作
第二阶段:用来延迟处理第一阶段未完成的工作,通常以内核线程的方式运行。

top命令使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
命令行
-d:指定刷新时间
-p:指定pid
-u:指定用户
-b:保存到文件中
-n:指定次数
---------------------------------------------------------------------------------------------
top内使用
z:高亮显示
b:运行的进程,高亮显示
s:修改刷新时间
M:按照内存排序
P:按照CPU排序
R:倒叙
f:自定义显示字段
q:退出

kil信号管理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	1:重新加载
2:类似于ctrl + c
3:正常终止进程
9:强制杀死(少用)
15:默认信号,进程终止


不常用
18:重新唤起停止的进程
19:直接暂停
20:把进程放到后台并暂停

pkill
-t:指定终端
-9:强制,把终端运行的命令和终端一并杀掉


killall
接进程的名字

Shell流程控制

流程控制if语句

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
单分支结构

if 如果你有钱 ;then
就嫁给你
fi


[root@shell shell]# cat if-1.sh
#!/bin/bash
if ls /opt ;then
echo "Ok"
fi


双分支结构

if 如果你有钱 ;then
就嫁给你
else
再见
fi


[root@shell shell]# cat if-1.sh
#!/bin/bash
if ls /opt ;then
echo "Ok"
else
echo "err"
fi


多分支


if 如果你有钱 ;then
就嫁给你
elif 如果你有房 ;then
也会嫁给你
elif 活好,运维技术好 ;then
倒贴也嫁给你
else
再见
fi

if语句中的文件比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
选项	说明								示例
-e 如果文件或目录存在则为真 [ -e file ]
-s 如果文件存在且至少有一个字符则为真 [ -s file ]
-d 如果文件存在且为目录则为真 [ -d file ]
-f 如果文件存在且为普通文件则为真 [ -f file ]
-r 如果文件存在且可读则为真 [ -r file ]
-w 如果文件存在且可写则为真 [ -w file ]
-x 如果文件存在且可执行则为真 [ -x file ]




[root@shell shell]# [ -d /etc ] && echo "该目录存在" || echo "该目录不存在"
该目录存在
[root@shell shell]# [ -d /etcc ] && echo "该目录存在" || echo "该目录不存在"
该目录不存在
[root@shell shell]# [ -f /etcc ] && echo "该目录存在" || echo "该目录不存在"
该目录不存在
[root@shell shell]# [ -f /etc ] && echo "该目录存在" || echo "该目录不存在"
该目录不存在
[root@shell shell]# [ -f /etc/hosts ] && echo "该目录存在" || echo "该目录不存在"
该目录存在
[root@shell shell]# [ ! -f /etc/hosts ] && echo "该目录存在" || echo "该目录不存在"
该目录不存在

数值比较[整数1 操作符 整数2 ]

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
28
29
30
31
32
33
34
35
36
选项	说明						示例
-eq 等于则条件为真 [ 1 -eq 10 ]
-ne 不等于则条件为真 [ 1 -ne 10 ]
-gt 大于则条件为真 [ 1 -gt 10 ]
-lt 小于则条件为真 [ 1 -lt 10 ]
-ge 大于等于则条件为真 [ 1 -ge 10 ]
-le 小于等于则条件为真 [ 1 -le 10 ]



[root@shell shell]# [ 10 -eq 20 ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ 20 -eq 20 ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ 20 -ne 20 ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ 10 -ne 20 ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ 10 -ge 20 ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ 30 -ge 20 ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ 20 -ge 20 ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ 20 -le 20 ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ 30 -le 20 ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ 30 -gt 20 ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ 20 -gt 20 ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ 20 -lt 20 ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ 10 -lt 20 ] && echo "为真" || echo "为假"
为真

if字符比较

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
28
29
选项		说明					示例
== 等于则条件为真 [ "$a" == "$b" ]
!= 不相等则条件为真 [ "$a" != "$b" ]
-z 字符串的长度为零则为真 [ -z "$a" ]
-n 字符串的长度不为零则为真 [ -n "$a" ]



[root@shell shell]# [ $USER == "root" ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ $USER == "roo" ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ $USER != "roo" ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ $USER != "root" ] && echo "为真" || echo "为假"
为假
[root@shell shell]# name=''
[root@shell shell]# [ -z $name ] && echo "为真" || echo "为假"
为真
[root@shell shell]# name=1
[root@shell shell]# [ -z $name ] && echo "为真" || echo "为假"
为假
[root@shell shell]# [ -n $name ] && echo "为真" || echo "为假"
为真
[root@shell shell]# name=''
[root@shell shell]# [ -n $name ] && echo "为真" || echo "为假"
为真
[root@shell shell]# [ -z $name ] && echo "为真" || echo "为假"
为真

多整数进行比较

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
28
29
30
31
32
33
34
35
36
37
38
39
40
-a  并且    

-o 或者

[root@shell shell]# [ 1 -gt 10 -a 2 -lt 1 ] && echo "正确" || echo "错误"
错误
[root@shell shell]# [ 11 -gt 10 -a 2 -lt 1 ] && echo "正确" || echo "错误"
错误
[root@shell shell]# [ 11 -gt 10 -a 2 -gt 1 ] && echo "正确" || echo "错误"
正确
[root@shell shell]# [ 10 -gt 10 -a 2 -gt 1 ] && echo "正确" || echo "错误"
错误


[root@shell shell]# [ 10 -gt 10 -o 2 -gt 1 ] && echo "正确" || echo "错误"
正确
[root@shell shell]# [ 10 -gt 10 -o 2 -gt 10 ] && echo "正确" || echo "错误"
错误
[root@shell shell]# [ 11 -gt 10 -o 2 -gt 1 ] && echo "正确" || echo "错误"
正确


&& 并且
|| 或者
必须要用双[]号
[root@shell shell]# [[ 11 -gt 10 && 2 -gt 1 ]] && echo "正确" || echo "错误"
正确
[root@shell shell]# [[ 11 -lt 10 && 2 -gt 1 ]] && echo "正确" || echo "错误"
错误
[root@shell shell]# [[ 9 -lt 10 && 2 -gt 10 ]] && echo "正确" || echo "错误"
错误



[root@shell shell]# [[ 9 -lt 10 || 2 -gt 10 ]] && echo "正确" || echo "错误"
正确
[root@shell shell]# [[ 11 -lt 10 || 2 -gt 10 ]] && echo "正确" || echo "错误"
错误
[root@shell shell]# [[ 9 -lt 10 || 2 -gt 10 ]] && echo "正确" || echo "错误"
正确

if正则比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@shell shell]# [ $USER =~ root ]  &&  echo "OK"  ||  echo  "ERR"
-bash: [: =~: binary operator expected
ERR
[root@shell shell]# [[ $USER =~ root ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# [[ $USER =~ ^r ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# name=roo
[root@shell shell]# [[ $name =~ ^r ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# name=123
[root@shell shell]# [[ $name =~ ^r ]] && echo "OK" || echo "ERR"
ERR
[root@shell shell]# [[ $name =~ ^[0-9]+$ ]] && echo "OK" || echo "ERR"
OK
[root@shell shell]# name=123a
[root@shell shell]# [[ $name =~ ^[0-9]+$ ]] && echo "OK" || echo "ERR"
ERR
[root@shell shell]# name=ok
[root@shell shell]# [[ $name =~ ^[0-9]+$ ]] && echo "OK" || echo "ERR"
ERR
[root@shell shell]# [[ $name =~ ^[a-Z]+$ ]] && echo "OK" || echo "ERR"
OK

case语句

case用来实现对程序流程的选择、循环等进行控制。语法如下:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
case 变量 in
变量1)
命令序列 1;;
变量2)
命令序列 2;;
变量3)
命令序列 3;;
*)
无匹配后命令序列
esac


安装PHP的不同版本


菜单

1、安装PHP 5.5 版本
2、安装PHP 5.6 版本
3、安装PHP 7.0 版本
4、退出


[root@shell shell]# cat case-1.sh
#!/bin/bash
#定义菜单
cat << EOF
######################
1、安装PHP 5.5 版本
2、安装PHP 5.6 版本
3、安装PHP 7.0 版本
4、退出
######################
EOF
#根据上方菜单进行选择要安装PHP版本
read -p "请选择你要安装的PHP版本,请输入对应的数字:" install

case $install in
1)
echo "你选择安装PHP版本为5.5."
echo "正在安装,请稍后......."
sleep 2
echo "PHP 5.5 已经安装完成!"
;;
2)
echo "你选择安装PHP版本为5.6."
echo "正在安装,请稍后......."
sleep 2
echo "PHP 5.6 已经安装完成!"
;;
3)
echo "你选择安装PHP版本为7.0."
echo "正在安装,请稍后......."
sleep 2
echo "PHP 7.0 已经安装完成!"
;;
4)
exit
;;
*)
echo "请输入数字[1-4],不能乱输!"
esac

Shell数组应用

什么是数组

数组其实也算是变量,传统的变量只能存储一个值,但数组可以存储多个值。

数组的分类

1
2
3
4
5
Shell数组分为普通数组和关联数组。

普通数组:只能使用整数作为数组索引。

关联数组:可以使用字符串作为数组索引。

数组基本使用

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
01. 普通数组仅能使用整数来作为索引


#普通数组赋值方式

#1.方式一:针对每个索引进行赋值

[root@qiudao ~]# array1[0]=pear
[root@qiudao ~]# array1[1]=apple
[root@qiudao ~]# array1[2]=orange
[root@qiudao ~]# array1[3]=peach

#2.方式二:一次赋多个值,数组名=(多个变量值)

[root@qiudao ~]# array2=(tom jack alice)
[root@qiudao ~]# array3=(tom jack alice "bash shell")
[root@qiudao ~]# array4=(1 2 3 "linux shell" [20]=puppet)

#3.方式三:将该文件中的每一个列作为一个元数赋值给数组array5,默认以空格为分割符

[root@qiudao ~]# array5=(`cat /etc/passwd`)

-------------------------------------------------------------------------------------------

02. 如何查看普通数组的赋值与访问数组的内容


#1.定义普通数组,其实也可以不用定义

[root@qiudao ~]# declare -a array

#2.统计数组元数的个数

[root@qiudao ~]# echo ${#array1[@]}
4

#3.访问数组中的第一个元素

[root@qiudao ~]# echo ${array1[0]}
pear

#4.从数组索引1开始

[root@qiudao ~]# echo ${array1[@]:1}
apple orange peach

#5.从数组索引1开始,访问两个元素

[root@qiudao ~]# echo ${array1[@]:1:2}
apple orange

#6.访问数组中所有数据,相当于echo ${array1[*]}

[root@qiudao ~]# echo ${array1[@]}
pear apple orange peach

-------------------------------------------------------------------------------------------

03. 关联数组能使用字符串的方式作为索引


#关联数组赋值

#1.定义关联数组, 申明是关联数据

[root@qiudao ~]# declare -A tt_array_1
[root@qiudao ~]# declare -A tt_array_2

#2.方式一:给关联数组进行赋值,数组名[索引]=变量值

[root@qiudao ~]# tt_array1[index1]=pear
[root@qiudao ~]# tt_array1[index2]=apple
[root@qiudao ~]# tt_array1[index3]=orange
[root@qiudao ~]# tt_array1[index4]=peach

#3.方式二:给关联数组一次赋多个值

[root@qiudao ~]# tt_array2=([index1]=tom [index2]=jack [index3]=alice [index4]='bash shell')

#4.查看关联数组

[root@qiudao ~]# declare -A

-------------------------------------------------------------------------------------------

04. 如何访问关联数组中的数据。


#1.访问数组中的第二个元数

[root@qiudao ~]# echo ${tt_array2[index2]}
jack

#2.访问数组中所有元数
等同于 echo ${array1[*]}

[root@qiudao ~]# echo ${tt_array2[@]}
bash shell tom jack alice

#3.访问数组中所有元数的索引

[root@qiudao ~]# echo ${!tt_array2[@]}
index4 index1 index2 index3

数组遍历与循环

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
方式一:通过数组元数的个数进行遍历(不推荐) 。

方式二:通过数组元数的索引进行遍历(推荐) 注意: 将统计的对象作为数组的索引,仅针对关联数据。

01.普通数组赋值与遍历示例


[root@qiudao ~]# cat array-1.sh
#!/usr/bin/bash
#1.使用while读入一个文件
while read line
do
#2.定义普通数组, 将读入的每行数据,单个单个进行赋值
hosts[i++]=$line
#正常定义普通数组是hosts[1]=test,只不过我们将[]变成自增
#$line是读取的文件内容
done </etc/hosts
#3.使用for循环遍历数组, 遍历数组的索引
for i in ${!hosts[@]}
do
echo "hosts数组对应的索引是:$i, 对应的值是: ${hosts[i]}"
done

-------------------------------------------------------------------------------------------

02.使用关联数组统计文件中的每个Shell数量


[root@qiudao ~]# cat count_passwd.sh
#!/bin/bash
declare -A array_passwd
#1.对数组进行赋值
while read line
do
type=$(echo $line|awk -F ':' '{print $NF}')
let array_passwd[$type]++
done </etc/passwd

#2.对数组进行遍历
for i in ${!array_passwd[@]}
do
echo "Shell: $i count: ${array_passwd[$i]}"
done

#步骤拆分讲解

[root@qiudao ~]# declare -A array_passwd
[root@qiudao ~]# array_passwd=([/bin/bash]=1 [/sbin/nologin]=1)
[root@qiudao ~]# let array_passwd[/bin/bash]++
[root@qiudao ~]# let array_passwd[/sbin/nologin]++
[root@qiudao ~]# echo ${!array_passwd[@]}
/sbin/nologin /bin/bash
[root@qiudao ~]# echo ${array_passwd[@]}
2 2

-------------------------------------------------------------------------------------------

03. 统计Nginx日志IP访问次数


[root@qiudao ~]# cat array_nginx_count.sh
#!/usr/bin/bash
# nginx log top 10 IP conut
declare -A array_nginx
#1.给关联数组的索引进行赋值
while read line
do
type=$(echo $line|awk '{print $1}')
let array_nginx[$type]++
done </var/log/nginx/access.log
#2.遍历数组
for i in ${!array_nginx[@]}
do
echo "IP是:$i 出现多少次: ${array_nginx[$i]}"
done

-------------------------------------------------------------------------------------------

04. 统计tcp的状态信息


[root@qiudao ~]# cat array_ss_state.sh
#!/usr/bin/bash
declare -A array_state
type=$(ss -ant |sed '1d' |awk '{print $1}')
#1.对数组进行的索引赋值
for i in $type
do
let array_state[$i]++
done
#2.遍历数组
for j in ${!array_state[@]}
do
echo "当前的状态是:$j,当前状态出现了多少次:${array_state[$j]}"
done

Shell变量概述

什么是变量

变量是Shell传递数据的一种方法,简单理解:用一个固定的字符串去表示不固定的内容,便于后续引用。

变量命令规范

1
2
3
4
5
6
7
8
9
10
11
变量定义时名称有要求:字母、数字、下划线几个组成,尽量字母开头,变量名最好具备一定的含义。

ip=10.0.0.100

ip1=10.0.0.100

Hostname_Ip=10.0.0.100

hostname_IP=10.0.0.100

等号是赋值,需要注意:等号两边不能有空格,其次定义的变量不要与系统命令出现冲突。

Shell变量定义的方式

1
2
3
4
5
6
7
01)用户自定义变量:人为定义的变量名称。

02)系统环境变量:保存的是和系统操作环境相关的数据。

03)位置参数变量:向脚本中进行参数传递,变量名不能自定义,变量作用是固定的。

04)预定义的变量:是bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。

shell变量运算

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
整数运算

expr 值两边必须要有空格隔开

[root@shell shell]# expr 1 + 1
2
[root@shell shell]# num1=10
[root@shell shell]# num2=20
[root@shell shell]# expr $num1 + $num2
30
[root@shell shell]# expr $num1 - $num2
-10
[root@shell shell]# expr $num1 * $num2
expr: syntax error
[root@shell shell]# expr $num1 \* $num2
200
[root@shell shell]# expr $num1 / $num2
0
[root@shell shell]# expr $num2 / $num2
1
[root@shell shell]# expr $num2 % $num2
0
[root@shell shell]# expr $num1 % $num2
10


$(())

[root@shell shell]# echo $(( $num1 + $num2 ))
30
[root@shell shell]# echo $(( $num1 - $num2 ))
-10
[root@shell shell]# echo $(( $num1 * $num2 ))
200


$[]

[root@shell shell]# echo $[$num1 * $num2 ]
200
[root@shell shell]# echo $[$num1 / $num2 ]
0
[root@shell shell]# echo $[$num1 + $num2 ]
30



let ****

[root@shell shell]# a=1
[root@shell shell]# let a++
[root@shell shell]# echo $a
2
[root@shell shell]# let a++
[root@shell shell]# echo $a
3
[root@shell shell]# let a--
[root@shell shell]# echo $a
2

小数运算

bc awk python

bc
[root@shell shell]# yum install -y bc


[root@shell shell]# echo $num1 + $num2 |bc
30
[root@shell shell]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
10+20
30
^C
(interrupt) Exiting bc.
[root@shell shell]# echo $num1 - $num2 |bc
-10
[root@shell shell]# echo $num1 ^ $num2 |bc
100000000000000000000
[root@shell shell]# echo $num1 / $num2 |bc
0
[root@shell shell]# echo "scale=2;$num1 / $num2" | bc
.50
[root@shell shell]# echo "scale=1;$num1 / $num2" | bc
.5
[root@shell shell]# echo "scale=1; 20 / 6" | bc
3.3
[root@shell shell]#



awk

[root@shell shell]# awk 'BEGIN{print 20 * 10 }'
200
[root@shell shell]# awk 'BEGIN{print 20 ^ 10 }'
10240000000000
[root@shell shell]# awk 'BEGIN{print 20 / 6 }'
3.33333
[root@shell shell]# awk 'BEGIN{printf "%.2f\n", 20 / 6 }'
3.33


python

[root@shell shell]# echo "print $num1+$num2" | python
30
[root@shell shell]# echo "print $num1/$num2" | python
0
[root@shell shell]# echo "print ${num1}.0/$num2" | python
0.5


[root@shell shell]# python
Python 2.7.5 (default, Oct 30 2018, 23:45:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 10+20
30
>>> 30.0/9
3.3333333333333335
>>>


示例: 执行ps aux 进行计算VSZ这列的所有数的和

[root@shell shell]# ps aux | awk 'NR>1{print $5}' |tr "\n" "+" |sed -r 's#(.*)\+#\1\n#g' |bc
4431300


[root@shell shell]# ps aux | awk 'NR>1{print $5}' |tr "\n" "+" |sed -r 's#(.*)\+#\1\n#g' |bc
4301596
[root@shell shell]# ps aux | awk 'NR>1{print $5}' |awk '{i+=$1}END{print i}'
4306700

[root@shell shell]# seq 100| awk '{print $1}' |tr "\n" "+" |sed -r 's#(.*)\+#\1\n#g' |bc
5050
[root@shell shell]# seq 100| awk '{print $1}' |awk '{i+=$1}END{print i}'
5050

shell变量案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
使用Shell脚本打印,系统版本、内核版本平台、虚拟平台、静态主机名、eth0网卡IP地址、lo网卡IP地址、当前主机的外网IP地址curl -s  icanhazip.com


[root@shell shell]# cat varable.sh
#!/bin/bash
System=$(hostnamectl |awk '/System/{print $3,$4,$5}')
Kernel=$(hostnamectl |awk '/Kernel/{print $NF}')
Vm=$(hostnamectl |awk '/Virtua/{print $NF}')
Sh=$(hostnamectl |awk '/Static/{print $NF}')
Eth0=$(ifconfig eth0 |awk 'NR==2{print $2}')
Lo=$(ifconfig lo |awk 'NR==2{print $2}')
W_network=$(curl -s ifconfig.me)
echo "当前系统的版本为:$System"
echo "当前系统内核版本为:$Kernel"
echo "当前系统虚拟化平台为:$Vm"
echo "当前系统静态主机名为:$Sh"
echo "当前系统eth0ip地址为:$Eth0"
echo "当前系统loip地址为:$Lo"
echo "当前系统外网ip地址为:$W_network"

Shell正则应用

什么是正则表达式

正则表达式regular expression, RE是一种字符模式,用于在查找过程中匹配指定的字符。

为什么要使用正则表达式

​ 在工作中,我们时刻面对着大量的日志,程序,以及命令的输出。迫切的需要过滤我们需要的一部分内容,甚至是一个字符串。比如: 现在有一个上千行的文件,我们仅需要其中包含”root”的行,怎么办? 此时就需要使用到正则表达式的规则来筛选想要的内容。

正则表达式注意事项

1
2
3
4
5
6
7
1.正则表达式应用非常广泛,存在于各种语言中,例如:php,python,java等。

2.正则表达式和通配符特殊字符是有本质区别的

3.要想学好grep、sed、awk首先就要掌握正则表达式。

4.注意正则神坑,中文符号。

正则表达式规则

正则表达式 描述
\ 转义符,将特殊字符进行转义,忽略其特殊意义
^ 匹配行首,^是匹配字符串的开始
$ 匹配行尾,$是匹配字符串的结尾
^$ 表示空行
.(点) 匹配换行符之外的任意单个字符
[ ] 匹配包含在[字符]之中的任意一个字符
[^] 匹配[^]之外的任意一个字符
[a-z] 匹配[]中指定范围内的任意一个字符
? 匹配其前面的字符1次或者0次
+ 匹配其前面的字符1次或者多次
***** 匹配其前面的字符0次或者多次
.* 表示所有
( ) 匹配表达式,创建一个用于匹配的字符串
{n} 匹配之前的项n次,n是可以为0的正整数
{n,} 之前的项至少需要匹配n次
{n,m} 指定之前的项至少匹配n次,最多匹配m次,n<=m
| 或者
特定字符 含义
[[:upper:]] 所有大写字母
[[:lower:]] 所有小写字母
[[:alpha:]] 所有字母
[[:digit:]] 所有数字
[[:alnum:]] 所有的字母和数字
[[:space:]] 空白字符,空白。
[[:punct:]] 所有标点符号

正则表达式之GREP文本过滤

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#环境准备
[root@qls ~]# cat test.txt
I am qiuzengjia teacher!
I teach linux.
test

I like badminton ball ,billiard ball and chinese chess!
my blog is http://www.oldboyedu.blog.com
our site is http://www.increase93.com
my qq num is 1176495252.
not 117666649555252.

#过滤以m开头的行

[root@qls ~]# grep "^m" test.txt

#过滤以m为结尾的行

[root@qls ~]# grep "m$" test.txt

#排除空行, 并打印行号

[root@qls ~]# grep -vn "^$" test.txt

#匹配任意一个字符,不包括空行

[root@qls ~]# grep "." test.txt

#匹配所有内容

[root@qls ~]# grep ".*" test.txt

#过滤出以.为结尾的行

[root@qls ~]# grep "\.$" test.txt

#过滤出以m和n为开头的行

[root@qls ~]# grep "^[mn]" test.txt

#过滤出文件中不是以m或n或o开始的行

[root@qls ~]# egrep "^[^mno]" test.txt
[root@qls ~]# egrep -v "^[mno]" test.txt

#过滤出空行,并显示行号

[root@qls ~]# grep -n "^$" test.txt

#把文件中每个字母总共出现多少次统计出

[root@qls ~]# grep -o "[a-Z]" test.txt |sort |uniq -c|sort -rh

#把文件中每个单词总共出现多少次统计出

[root@qls ~]# egrep -o "[a-Z]+" test.txt |sort |uniq -c|sort -rh

#找出/etc/passwd文件中的两位数或三位数的行;

[root@qls ~]# grep -Ew "[0-9]{2,3}" /etc/passwd

#找出/proc/meminfo文件中,所有大写或小写s开头的行;至少有三种实现方式;

[root@qls ~]# grep "^[sS]" /proc/meminfo
[root@qls ~]# grep -i "^s" /proc/meminfo
[root@qls ~]# grep -E "^(s|S)" /proc/meminfo

#显示当前系统上root、CentOS或user1用户的相关信息;

[root@qls ~]# grep -E "^(root|CentOS|user1)" /etc/passwd

#找出/etc/init.d/functions文件中某单词后跟一个小括号的行;

[root@qls ~]# grep -E -o "^[_[:alnum:]]+\(\)" /etc/init.d/functions

#环境准备
[root@qls ~]# cat id.txt
邹 371481199403259478
莫 52020319810613433X
韩 46010619911113727A
荣 53012419750413543
荣 530124197504135438
阮 360702197902169951
任 6212231987082X5176
姜 370602198507189574
赵 BBB602198507189574

#找出正确的身份证号码

[root@qls ~]# egrep "[0-9]{17}[0-9X]" id.txt

正则表达式之SED文本处理

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    Sed是一个流编辑器, 非交互式的编辑器,它一次处理一行内容. 处理时,把当前处理的行存储在临时缓冲区中,称
"模式空间"(pattern space)
接着用Sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接
着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed是用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

01. Sed命令格式


sed [options] 'command' file(s)

Sed正则使用

与Grep一样,Sed在文件中查找模式时也可以使用正则表达式(RE)和各种元字符。正则表达式是括在斜杠间的模式,用于查找和替换,以下是sed支持的元字符。使用基本元字符集 ^, $, ., *, [], [^], < >, (), {} 使用扩展元字符集 ?, +, { }, |, ( ) 使用扩展元字符的方式 + sed -r

02. Sed命令示例


Sed对指定行进行操作,包括打印、删除、修改、追加等。

Sed选项参数

-e #允许多项编辑

-n #取消默认的输出

-i #直接修改对应文件

-r #支持扩展元字符

Sed命令参数

a #在当前行后添加一行或多行

c #在当前行进行替换修改

d #在当前行进行删除操作
i #在当前行之前插入文本
p #打印匹配的行或指定行

n #读入下一输入行,从下一条命令进行处理

! #对所选行以外的所有行应用命令

h #把模式空间里的内容重定向到暂存缓冲区

H #把模式空间里的内容追加到暂存缓冲区

g #取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有内容

G #取出暂存缓冲区的内容,将其复制到模式空间,追加在原有内容后面

正则表达式之AWK文本处理

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
01. Awk基本介绍

什么是Awk?


awk是一种编程语言,用于在`linux/unix`下对文本和数据进行处理。
awk数据可以来自标准输入、一个或多个文件,或其它命令的输出。
awk通常是配合脚本进行使用, 是一个强大的文本处理工具。

awk 的处理文本和数据的方式如下:

1.进行逐行扫描文件, 从第一行到最后一行
2.寻找匹配的特定模式的行,在行上进行操作
3.如果没有指定处理动作,则把匹配的行显示到标准输出
4.如果没有指定模式,则所有被操作的行都被处理

Awk工作原理


awk -F: '{print $1,$3}' /etc/passwd

1.awk将文件中的每一行作为输入, 并将每一行赋给内部变量 $0 , 以换行符结束

2.awk开始进行字段分解,每个字段存储在已编号的变量中,从$1开始[默认空格分割]
3.awk默认字段分隔符是由内部FS变量来确定, 可以使用-F修订

4.awk行处理时使用了print数打印分割后的字段

5.awk在打印后的字段加上空格,因为$1,$3之间有一个逗号。逗号被映射至OFS内部变量中,称为输出字段分隔符,OFS 默认为空格.
6.awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕.

Awk命令格式


#示例1, 匹配 awk 'pattern' filename

[root@qls ~]# awk '/root/' /etc/passwd

#示例2, 处理动作 awk '{action}' filename

[root@qls ~]# awk -F: '{print $1}' /etc/passwd

#示例3, 匹配+处理动作 awk 'pattern {action}' filename

[root@qls ~]# awk -F ':' '/root/ {print $1,$3}' /etc/passwd
[root@qls ~]# awk 'BEGIN{FS=":"} /root/{print $1,$3}' /etc/passwd

#示例4, 判断大于多少则输出什么内容 command |awk 'pattern {action}'

[root@qls ~]# df |awk '/\/$/ {if ($3>50000) print $4}'

06. Awk循环语句


while循环

[root@qls ~]# awk 'BEGIN{ i=1; while(i<=10){print i; i++} }'
[root@qls ~]# awk -F: '{i=1; while(i<=NF){print i; i++}}' /etc/passwd
[root@qls ~]# awk -F: '{i=1; while(i<=10) {print $0; i++}}' /etc/passwd
[root@qls ~]# cat b.txt
111 222
333 444 555
666 777 888 999
[root@qls ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt

for循环

#C 风格 for

[root@qls ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i} }'

#将每行打印 10 次

[root@qls ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd


Awk数组概述

将需要统计的某个字段作为数组的索引,然后对索引进行遍历

1 统计/etc/passwd 中各种类型 shell 的数量


[root@qls ~]# awk -F: '{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }' /etc/passwd

2 网站访问状态统计<当前时实状态ss>


[root@qls ~]# ss -an|awk '/:80/{tcp[$2]++} END {for(i in tcp){print i,tcp[i]}}'

3 统计当前的tcp的11种状态数量<当前时实状态 netstat,ss>


[root@qls ~]# ss -ant|sed '1d'|awk '{status[$1]++} END {for(i in status){print i,status[i]}}'


Awk数组案例

Nginx日志分析,日志格式如下:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

52.55.21.59 - - [22/Nova/2018:14:55:36 +0800] "GET /feed/ HTTP/1.1" 404 162 "https:#www.google.com/" "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52" "-"
1 统计2018年11月22日,当天的PV量


[root@qls ~]# grep "22/Nov/2018" access.log |wc -l
[root@qls ~]# awk "/22\/Nov\/2018/" access.log |wc -l
[root@qls ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips) {sum+=ips[i]} {print sum}}' access.log

#统计11-12点的pv量

[root@qls ~]# awk '$4>="[22/Nov/2018:11:00:00" && $4<="[22/Nov/2018:12:00:00 {print $0}"' access.log |wc -l

2 统计2018年11月22日,一天内访问最多的10个IP


[root@qls ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips){ print ips[i],i}}' access.log |sort -rn|head

#统计11-12点访问次数最多的10个IP

[root@qls ~]# awk '$4>="[22/Nov/2018:15:00:00" && $4<="[22/Nov/2018:19:00:00"' access.log |awk '{ips[$1]++} END {for(i in ips){print ips[i],i}}'|sort -rn|head
3 统计2018年11月22日,访问大于100次的IP


[root@qls ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips){if(ips[i]>100){print i,ips[i]}}}' access.log

4 统计2018年11月22日,访问最多的10个页面($request top 10)


[root@qls ~]# awk '/22\/Nov\/2018/ {request[$7]++} END {for(i in request){print request[i],i}}' access.log |sort -rn|head

5 统计2018年11月22日,每个URL访问内容总大小($bodybytessent)


[root@qls ~]# awk '/22\/Nov\/2018/{size[$7]+=$10} END {for(i in size){print size[i],i}}' access.log |sort -rn|head

6 统计2018年11月22日,每个IP访问状态码数量($status)


[root@qls ~]# awk '{ip_code[$1 " " $9]++} END {for(i in ip_code){print ip_code[i],i}}' access.log|sort -rn|head

7 统计2018年11月22日,访问状态码为404及出现的次数($status)


[root@qls ~]# grep "404" access.log |wc -l
[root@qls ~]# awk '{if($9=="404") code[$9]++} END {for(i in code){print i,code[i]}}' access.log
8 统计2018年11月22日,8:30-9:00访问状态码是404


[root@qls ~]# awk '$4>="[22/Nov/2018:15:00:00" && $4<="[22/Nov/2018:19:00:00" && $9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' access.log
[root@qls ~]# awk '$9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' access.log

9 统计2018年11月22日,各种状态码数量


[root@qls ~]# awk '{code[$9]++} END {for(i in code){print i,code[i]}}' access.log

10 统计日志中所有URL访问的次数及访问响应的内容总大小


[root@qls ~]# awk '{request[$7]++;size[$7]+=$10} END {for(i in request){print request[i],i,size[i]}}' access.log |sort -rn|head

Shell循环语句

for循环基本使用示例

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#取值列表有多种取值方式,可以直接读取in后面的值,默认以空格做分割符
语法
for i in 变量的值
do
循环体
done

#出现值中间有空白字符
[root@shell day04]# cat for-1.sh
#!/bin/bash
for i in file1 "file2 dir" file3
do
echo $i
done



#特殊符号

[root@shell day04]# cat for-1.sh
#!/bin/bash
for i in file1 \"file2 dir file3
do
echo $i
done


#从变量中取值


[root@shell day04]# cat for-1.sh
#!/bin/bash
list="file1 file2 dir file3"
for i in $list
do
echo $i
done


#从文件中取值


[root@shell day04]# cat for-2.sh
#!/bin/bash
for i in $(cat /etc/hosts)
do
echo $i
done


#给for定义指定分隔符

[root@shell day04]# cat for-2.sh
#!/bin/bash
IFS=:
for i in $(cat /etc/passwd | head -1)
do
echo $i
done

#以换行符为分隔符
[root@shell day04]# cat for-2.sh
#!/bin/bash
IFS=$'\n'
for i in $(cat /etc/hosts)
do
echo $i
done

for循环基本使用示例

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
28
29
30
31
32
33
34
35
36
37
38
39
#以冒号做分隔符                         IFS=:


#以冒号,分号和双引号作为字段分隔符 IFS=:;"


#以换行符作为字段分隔符 IFS=$'\n'


#以回车为换行符
[root@qiudao /scripts]# cat for-6.sh
#!/bin/bash
IFS=$'\n'
for var in `cat /etc/hosts`
do
echo $var
done
[root@qiudao /scripts]# sh for-6.sh
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6


#以:为分隔符
[root@qiudao /scripts]# cat for-7.sh
#!/bin/bash
IFS=:
list=`head -1 /etc/passwd`
for var in $list
do
echo $var
done
[root@qiudao /scripts]# sh for-7.sh
root
x
0
0
root
/root
/bin/bash

使用for循环实现数据库的分库分表备份。

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
28
29
30
31
32
33
34
35
36
37
38
39
40
1.怎么备份数据库    
mysqldump -uroot -p123.com -B world > world_database.sql
2.怎么备份数据库的表
mysqldump -uroot -p123.com world city > world_city_tables.sql
3.备份到哪儿
/mysql_dump/oldboy/city_2019_07_16.sql



[root@shell day05]# cat for-3.sh
#!/bin/bash
Db_user=root
Db_pass=123456
Db_name=$(mysql -u$Db_user -p$Db_pass -e "show databases;" |sed 1d |grep -v ".*_schema")
Date=$(date +%F)

for database in $Db_name
do
if [ ! -d /backup/$database ];then
mkdir -p /backup/$database
fi
mysqldump -u$Db_user -p${Db_pass} --single-transaction -B $database >/backup/$database/${database}_${Date}.sql
if [ $? -eq 0 ];then
echo "数据库 $database 备份成功!"
Db_table=$(mysql -u$Db_user -p${Db_pass} -e "use $database;show tables;" |sed 1d)
for tables in $Db_table
do
mysqldump -u$Db_user -p${Db_pass} --single-transaction $database $tables >/backup/$database/${database}_${tables}_${Date}.sql
if [ $? -eq 0 ];then
echo "数据库$database 中的表 $tables 备份成功!"
else
echo "数据库$database 中的表 $tables 备份失败!"
continue
fi
done
else
echo "数据库 $database 备份失败!"
continue
fi
done

循环语句while基本概述

1
2
3
4
5
6
7
8
while循环语句,只要条件成立就反复执行对应的命令操作,直到命令不成立或为假
#当条件测试成立(条件测试为真),执行循环体

while 条件测试
do
循环体

done

while循环基本使用示例

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#降序输出10到1的数字
[root@qiudao /scripts]# cat while-1.sh
#!/bin/bash
var=10
while [ $var -gt 0 ]
do
echo $var
var=$[$var-1]
done


#简单加法表
[root@qiudao /scripts]# cat while-2.sh
#!/usr/bin/bash


a=1
b=10
while [ $a -le 10 ]
do
sum=$(( $a + $b ))
echo $a + $b = $sum
let a++
let b--
done


#两数相乘
#自增
[root@qiudao /scripts]# cat while-3.sh
#!/bin/bash
num=9
while [ $num -ge 1 ]
do
sum=$(( $num * $num ))
echo "$num * $num = $sum"
num=$[$num-1]
done


#自减
[root@qiudao /scripts]# cat while-4.sh
#!/bin/bash
num=1
while [ $num -le 9 ]
do
sum=$(( $num * $num ))
echo "$num * $num = $sum"
num=$[$num+1]
done

猜数字游戏脚本

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
28
29
30
31
32
33
34
35
36
37
38
39
40
1) 随机输出一个1-100的数字 echo $((RANDOM % 100 + 1 )) 
2) 要求用户输入的必须是数字(数字处加判断)

3) 如果比随机数小则提示比随机数小了
大则提示比随机数大了

4) 正确则退出
错误则继续死循环

5) 最后统计总共猜了多少次(成功多少次,失败多少次)


#!/usr/bin/bash
sj=$(echo $((RANDOM % 100 + 1 )))
i=0
while true
do
read -p "请输入一个你需要猜的数字: " cc
if [[ ! $cc =~ ^[0-9]+$ ]];then
echo "请输入整数"
continue
fi


#将用户的输入的数字与随机数进行比较

if [ $cc -gt $sj ];then
echo "你猜的太大"
elif [ $cc -lt $sj ];then
echo "你猜的太小,继续加油"
else
echo "猜对了....."
break
fi
#进行数值自增

let i++
done
echo "你总共失败了多少次 $i"
echo "你总共猜了多少次 $(( $i + 1 ))"

跳出循环语句指令

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
01. exit,退出整个程序

[root@qiudao /scripts]# cat for-exit.sh
#!/bin/bash
for i in {1..3}
do
echo "123"
exit
echo "456"
done
echo "done ......"


#执行结果
[root@qiudao /scripts]# sh for-exit.sh
123
-----------------------------------------------------------------------------------------

02. break,结束当前循环,或跳出本层循环

[root@qiudao /scripts]# cat for-break.sh
#!/bin/bash
for i in {1..3}
do
echo "123"
break
echo "456"
done
echo "done ......"


#执行结果
[root@qiudao /scripts]# sh for-break.sh
123
done ......
-----------------------------------------------------------------------------------------

03. continue,忽略本次循环剩余的代码,直接进行下一次循环。


[root@qiudao /scripts]# cat for-continue.sh
#!/bin/bash
for i in {1..3}
do
echo "123"
continue
echo "456"
done
echo "done ......"


#执行结果
[root@qiudao /scripts]# sh for-continue.sh
123
123
123
done ......

Shell函数应用

什么是函数

​ 函数其实就是一堆命令的合集,用来完成特定功能的代码块,你可以对它进行自定义命令,并且可以在脚本中任意位置使用这个函数,要使用定义的函数,只需要填写函数名称就可以了。

函数的作用

1.使用函数可以让代码模块化,便于代码的复用,同时增加脚本的可读性。
2.函数和变量类似,必须先定义才可使用,如果定义不调用则不会被执行。

函数基本的使用

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
01. 如何定义Shell函数,可以通过如下两种方式进行定义。


#方式一

函数名() {
command1
command2
...
commandN
}

#方式二

function 函数名 {
command1
command2
...
commandN
}
------------------------------------------------------------------------------------------

02. 如何调用Shell函数,直接使用函数名调用即可。在函数内部也可以使用$1$2..$n的方式传递参数。


#1.命令行定义函数
[root@qiudao /scripts]# fun1() { echo "hello world"; }

#2.命令行调用函数
[root@qiudao /scripts]# fun1
hello world

#给函数传递参数
[root@qiudao /scripts]# fun2() { echo "hello $1"; }
[root@qiudao /scripts]# fun2 linux
hello linux

#4.给函数传递多个参数{$*,接收所有的参数传递}
[root@qiudao /scripts]# fun3() { echo "hello $*"; }
[root@qiudao /scripts]# fun3 zhangsan lisi wangwu
hello zhangsan lisi wangwu

函数参数传递

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
01. 函数传参示例,使用变量方式传递固定值


[root@qiudao /scripts]# cat fun-1.sh
#!/bin/bash
fun_1() {
echo "$num"
}
num=10 #传递参数
fun_1 #调用函数

#执行脚本
[root@qiudao /scripts]# sh fun-1.sh
10

------------------------------------------------------------------------------------------

02. 函数传参示例,使用变量方式传递可变的值


[root@qiudao /scripts]# cat fun-2.sh
#!/bin/bash
fun_1() {
echo "$num"
}
num=$1 #将脚本的第一个位置参数传递给变量num
fun_1 #调用函数

#执行脚本
[root@qiudao /scripts]# sh fun-2.sh 20
20

------------------------------------------------------------------------------------------

03. 函数传参示例,传递多个位置参数


[root@qiudao /scripts]# cat fun-3.sh
#!/bin/bash
fun_1() {
echo "$1" #接收执行函数是传递的第一个参数
}
fun_1 $1 #接收脚本第一个位置参数,传入函数中算第一个参数
fun_1 $2 #接收脚本第二个位置参数,传入函数中算第一个参数
fun_1 $3 #接收脚本第三个位置参数,传入函数中算第一个参数

#执行脚本
[root@qiudao /scripts]# sh fun-3.sh 10 20 30
10
20
30

[root@qiudao /scripts]# cat fun-3.sh
#!/bin/bash
fun_1() {
echo "$1"
}
fun_1 $1 $2 $3
fun_1 $2
fun_1 $3

[root@qiudao shell]# sh fun.sh 1 2 3
1
2
3

------------------------------------------------------------------------------------------

04. 函数传参示例,传递多个函数参数


[root@qiudao /scripts]# cat fun-4.sh
#!/bin/bash
fun_1() {
echo "$1" "$2" "$3" #函数接收传递三个参数
}
#rc=$(fun_1 10 20 30) #传递固定的值
rc=$(fun_1 $1 $2 $3) #传递可变的值
echo "传递参数的值为,$rc"

#执行脚本
[root@qiudao /scripts]# sh fun-4.sh 10 20 30
传递参数的值为,10 20 30

------------------------------------------------------------------------------------------

05. 函数传参示例,将脚本的位置参数与函数的位置参数发生联动。


[root@qiudao /scripts]# cat fun-5.sh
#!/bin/bash
fun_1() {
echo "$num1" "$num2" "$num3"
}
num1=$1 #将脚本位置参数一的值传递给变量num1
num2=$2 #将脚本位置参数二的值传递变量给num2
num3=$3 #将脚本位置参数二的值传递变量给num3

rc=$(fun_1) #将函数执行的结果保存至rc变量中,便于后续echo输出

echo "传递参数的值为,$rc"

#执行脚本
[root@qiudao /scripts]# sh fun-5.sh 10 20 30
传递参数的值为,10 20 30

函数状态返回

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#Shell的函数返回值,也算是退出的状态。在Shell中只有echo、return两种方式。

1.使用return返回值:只能返回0-255的整数,函数使用return返回值,通常只是用来供其他地方调用获取状态,因此通常仅返回0或1;0表示成功,1表示失败。

2.使用echo返回值:使用echo可以返回任何字符串结果,通常用于返回数据,比如一个字符串值或者列表值。

01. Shell函数echoreturn返回值示例

[root@qiudao /scripts]# cat fun_echo_return.sh
#!/bin/bash
fun_echo_return() {
echo 100 #返回函数执行后的数据
return 1 #返回函数执行后的状态码(放置最后)
}

result=`fun_echo_return`

echo "函数的状态码是:$? "
echo "函数的返回值是:$result "

#执行脚本
[root@qiudao /scripts]# sh fun_echo_return.sh
函数的状态码是:1
函数的返回值是:100

------------------------------------------------------------------------------------------

02. Shell函数return返回值使用场景示例

#return示例一:
[root@qiudao /scripts]# cat fun_return.sh
#!/bin/bash
file=/etc/passwd #定义文件
t_file() {
if [ -f $file ];then
return 0
else
return 1
fi
}
#调用函数,并根据函数返回状态码进行输出
t_file && echo "该文件存在 $file" || echo "该文件不存在 $file"

#执行脚本
[root@qiudao /scripts]# sh fun_return.sh
该文件存在 /etc/passwd

#return示例二:(了解即可)
[root@qiudao /scripts]# cat fun_nginx_run.sh
#!/bin/bash
this_pid=$$
is_nginx_running() {
ps -ef|grep nginx |grep -v grep |grep -v $this_pid &>/dev/null
if [ $? -eq 0 ];then
return 0
else
return 1
fi
}
#调用函数,并根据函数返回状态码进行输出
is_nginx_running && echo "Nginx is running" || echo "Nginx is stoped"

函数场景示例

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#系统初始化版本

[root@qiudao /scripts]# cat system.sh
#!/bin/bash
#1.显示系统版本
check_system_version() {
awk '{print $(NF-1)}' /etc/redhat-release
}

#2.更新yum源
check_yum() {
tt=$(awk '{print $(NF-1)}' /etc/redhat-release)
if [ ${tt%%.*} -eq "6" ];then
mkdir -p /etc/yum.repos.d/backup
\mv /etc/yum.repos.d/.*repo /etc/yum.repos.d/backup/
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
elif [ ${tt%%.*} -eq "7" ];then
mkdir -p /etc/yum.repos.d/backup
\mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
fi
yum clean all && yum makecache
}

#3.安装基础软件包
package_install() {
yum install -y net-tools vim tree htop iftop \
iotop lrzsz wget unzip telnet nmap nc ntpdate \
bash-completion bash-completion-extra sysstat rsync nfs-utils -y
}

#4.关闭selinux
disable_selinux() {
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
setenforc 0 &> /dev/null
}

#5.关闭firewalld
disable_firewalld() {
systemctl stop firewalld.service
systemctl disable firewalld.service
}

#6.配置sshd服务
ssh_config() {
sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config
sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config
}
#7.加大文件描述符
limit_conf() {
echo '* - nofile 65535 ' >>/etc/security/limits.conf
}
#8.时间同步
date_time() {
echo '*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null' >/var/spool/cron/root
}
menu() {
cat <<EOF
##########################################
## 1、操作系统发行版本 ##
## 2、部署yum源 ##
## 3、安装系统软件包 ##
## 4、关闭Selinux ##
## 5、关闭Firewalld ##
## 6、配置SSHD服务 ##
## 7、加大文件描述符 ##
## 8、同步系统时间 ##
## 9、打印菜单 ##
## q、退出程序 ##
##########################################
EOF
}
#打印菜单
menu
while true
do
read -p "您想干什么?就请输入上面对应的字符:" n
case $n in
1)
check_system_version
;;
2)
check_yum &>/dev/null
echo $? &>/dev/null && echo "yum源更新完成" || echo "yum源更新失败"
;;
3)
echo "安装软件包需要一部分时间,请耐心等待,正在安装中......."
package_install &>/dev/null
echo $? &>/dev/null && echo "基础软件包安装完成" || echo "基础软件包安装报错"
;;
4)
disable_selinux &>/dev/null
echo $? &>/dev/null && echo "Selinux 关闭成功" || echo "Selinux 关闭失败"
;;
5)
disable_firewalld &>/dev/null
echo $? &>/dev/null && echo "Firewalld 关闭成功" || echo "Firewalld 关闭失败"
;;
6)
ssh_config &>/dev/null
echo $? &>/dev/null && echo "sshd服务配置完成" || echo "sshd服务配置报错"
;;
7)
limit_conf &>/dev/null
echo $? &>/dev/null && echo "文件描述符数量修改成功" || echo "文件描述符数量修改失败"
;;
8)
date_time &>/dev/null
echo $? &>/dev/null && echo "定时任务添加成功" || echo "定时任务添加失败"
;;
9)
clear
menu
;;
q)
echo "您即将退出程序!"
exit 1
esac
done

数据库备份管理:逻辑和物理备份

  • [一.备份的原因]
  • [二.备份的类型]
  • [三.备份的方式]
  • [四.备份策略]
  • [五.备份工具]

备份的原因

1)备份就是为了恢复。
2)尽量减少数据的丢失(公司的损失)

备份的类型

冷备份:
这些备份在用户不能访问数据时进行,因此无法读取或修改数据。这些脱机备份会阻止执行任何使用数据的活动。这些类型的备份不会干扰正常运行的系统的性能。但是,对于某些应用程序,会无法接受必须在一段较长的时间里锁定或完全阻止用户访问数据。

温备份:
这些备份在读取数据时进行,但在多数情况下,在进行备份时不能修改数据本身。这种中途备份类型的优点是不必完全锁定最终用户。但是,其不足之处在于无法在进行备份时修改数据集,这可能使这种类型的备份不适用于某些应用程序。在备份过程中无法修改数据可能产生性能问题。

热备份:
这些动态备份在读取或修改数据的过程中进行,很少中断或者不中断传输或处理数据的功能。使用热备份时,系统仍可供读取和修改数据的操作访问。

备份方式

1.逻辑备份

  • binlog
  • mysqldump
  • into outfile
  • replication
  • mysqlbinlog

2.物理备份

  • cp data
  • Xtrabackup(percona公司)

备份策略

1.全量备份

2.增量备份

3.差异备份

逻辑备份工具-mysqldump

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
mysqldump
-u:指定用户
-p:指定密码
-h:指定主机域
-P:指定端口
-S:指定socket文件

#-A(--all-databases):全库备份
[root@db01 mysql]# mysqldump -uroot -p1 -A > /tmp/full.sql

#-B:指定库备份(可以备份多个库)
[root@db01 mysql]# mysqldump -uroot -p1 -B world > /tmp/world.sql
[root@db01 mysql]# mysqldump -uroot -p1 -B world test > /tmp/world_test.sql

#什么都不加:备份表(只能备份表,不能备份多个库)
[root@db01 mysql]# mysqldump -uroot -p1 world > /tmp/world_1.sql
#单表备份
[root@db01 mysql]# mysqldump -uroot -p1 world city > /tmp/world_2.sql

#-F (--flush-logs):备份的同时刷新binlog 有多少个库,刷新多少个binlog
[root@db01 mysql]# mysqldump -uroot -p1 -A -F > /tmp/full_F.sql

#--master-data=2 (打点备份,温备)
2:打点备份并且注释change master to
1:打点备份不注释change master to
0:相当于不开启,等于没写

#--single-transaction(快照备份)
[root@db01 ~]# mysqldump -uroot -p1 -A --master-data=2 --single-transaction > /tmp/f.sql

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000030', MASTER_LOG_POS=20550;
mysqlbinlog --start-position=20550 --stop-position=25058

#-R:备份存储过程和函数
[root@db01 ~]# mysqldump -uroot -p1 -A -R --master-data=2 --single-transaction > /tmp/f.sql

#--triggers:备份触发器
[root@db01 ~]# mysqldump -uroot -p1 -A -R --triggers --master-data=2 --single-transaction > /tmp/f.sql

#gzip 压缩备份
#终极备份语句
[root@db01 ~]# mysqldump -uroot -p1 -A -R --triggers --master-data=2 --single-transaction|gzip > /tmp/full_$(date +%F).sql.gz

####了解即可
#-d:仅备份表结构
#-t:仅备份数据
#-x:锁表备份

#恢复压缩数据
[root@db01 tmp]# zcat /tmp/full_2019-11-13.sql.gz | mysql -uroot -p1

注意:

1)mysqldump在备份和恢复时都需要MySQL实例启动为前提
2)一般数据量级100G以内,大约15-30分钟可以恢复(PB、EB就需要考虑别的方式:物理备份)
3)mysqldump是以覆盖的形式恢复数据的

企业故障恢复案例

背景:
正在运行的网站系统,MySQL数据库,数据量25G,日业务增量10-15M。

备份策略:
每天23:00,计划任务调用mysqldump执行全备脚本

故障时间点:
上午10点开发人员误删除一个核心业务表,如何恢复?

思路:

1.停库,停止业务(避免二次伤害数据)

1
[root@db01 tmp]# /etc/init.d/mysqld stop

2.准备新环境

  • 多实例(物理服务器)
  • 再买一台云主机

3.将昨天晚上23点做的全备导入新环境

1
zcat full_2019-11-12.sql |mysql -uroot -p1

4.根据binlog截取昨晚23点到今天上午10点的数据

1
2
3
4
[root@db01 tmp]# zcat /tmp/full_2019-11-13.sql|head -25
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000030', MASTER_LOG_POS=1010290;

mysqlbinlog --start-position=1010290 --stop-position=xxx /application/mysql/data/mysql-bin.000030 > /tmp/inc_23_10.sql

5.将截取出来的数据发送到新环境

1
scp /tmp/inc_23_10.sql 172.16.1.52:/tmp

6.导入新增数据

1
2
set sql_log_bin=0
mysql -uroot -p1 < /tmp/inc_23_10.sql

7.恢复生产业务

  • 应用割接(修改连接数据库的代码)

  • 导出核心业务表,恢复到旧生产环境

    1
    2
    3
    mysqldump -uroot -p1 db1 tb1 > /tmp/tb1.sql
    scp /tmp/tb1.sql 172.16.1.51:/tmp
    mysql -uroot -p1 db1 < /tmp/tb1.sql

以上两种方式都可以,选择速度最快的一种方式

改代码:

1).开发提交gitlab,从gitlab拉取,上线

2).开发写好了配置文件

8.开启业务

1
/etc/init.d/mysqld start

故障模拟恢复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql -uroot -p1

mysql> create database backup;

mysql> use backup

mysql> create table full select * from world.city;

mysql> create table full_1 select * from world.city;


mysql> show tables;
+------------------+
| Tables_in_backup |
+------------------+
| full |
| full_1 |
+------------------+

到时候了:23:00全备

1
[root@db01 mysql]# mysqldump -uroot -p1 -A -R --triggers --master-data=2 --single-transaction|gzip > /tmp/full_$(date +%F).sql.gz

模拟数据变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@db01 mysql]# mysql -uroot -p1

mysql> use backup

mysql> create table inc select * from mysql.user;

mysql> create table inc_1 select * from mysql.user;

mysql> show tables;
+------------------+
| Tables_in_backup |
+------------------+
| full |
| full_1 |
| inc |
| inc_1 |
+------------------+

mysql> insert into full_1 select * from world.city;
mysql> commit;

模拟删除核心业务表

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
mysql> drop table backup.full_1;

mysql> show tables;
+------------------+
| Tables_in_backup |
+------------------+
| full |
| inc |
| inc_1 |
+------------------+

mysql> drop database backup;

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| OD |
| QLS |
| ZLS |
| ageofoldboy |
| binlog |
| blog |
| db1 |
| db2 |
| linux5 |
| mysql |
| mysqldump |
| od |
| performance_schema |
| qwe |
| test |
| test1 |
| test2 |
| test3 |
| wordpress |
| world |
| xxx |
| zls1 |
| zls2 |
+--------------------+

恢复数据

mysqlbinlog –base64-output=decode-rows -vvv /application/mysql/data/mysql-bin.000032 |grep -i -B 5 ‘drop database shell’|sed -rn ‘s#.at (.)#\1#gp’

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#1.停业务
#停止连接数据库的服务(php,tomcat,python)*****
[root@db01 mysql]# /etc/init.d/mysqld stop
Shutting down MySQL. SUCCESS!

#2.准备新的环境(初始化一个新的数据库实例,二进制安装MySQL)
[root@db02 scripts]# ./mysql_install_db --user=mysql --basedir=/application/mysql --datadir=/application/mysql/data
[root@db02 scripts]# /etc/init.d/mysqld start
. SUCCESS!

[root@db02 mysql]# mysql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+

#3.将全备的数据导入新环境
[root@db01 mysql]# scp /tmp/full_2019-11-14.sql.gz 172.16.1.52:/tmp/
[root@db02 mysql]# zcat /tmp/full_2019-11-14.sql.gz |mysql
mysql> show tables from backup;
+------------------+
| Tables_in_backup |
+------------------+
| full |
| full_1 |
+------------------+

mysql> select count(*) from backup.full_1;
+----------+
| count(*) |
+----------+
| 4079 |
+----------+

#4.截取binlog
[root@db02 mysql]# zcat /tmp/full_2019-11-14.sql.gz |head -25
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000031', MASTER_LOG_POS=268002;

[root@db01 data]# mysqlbinlog --base64-output=decode-rows -vvv /application/mysql/data/mysql-bin.000031|less
#搜索DROP
410758

[root@db01 data]# mysqlbinlog --start-position=268002 --stop-position=410758 /application/mysql/data/mysql-bin.000031 > /tmp/inc23_10.sql

#5.发送并导入sql文件
[root@db01 data]# scp /tmp/inc23_10.sql 172.16.1.52:/tmp/
[root@db02 mysql]# mysql < /tmp/inc23_10.sql

mysql> use backup

mysql> show tables;
+------------------+
| Tables_in_backup |
+------------------+
| full |
| full_1 |
| inc |
| inc_1 |
+------------------+

mysql> select count(*) from full_1;
+----------+
| count(*) |
+----------+
| 8158 |
+----------+

#6.恢复生产业务
- 1.修改代码
- 2.导出核心业务表,恢复到生产库

[root@db02 mysql]# mysqldump -B backup > /tmp/backup.sql
[root@db02 mysql]# scp /tmp/backup.sql 172.16.1.51:/tmp/

[root@db01 data]# /etc/init.d/mysqld start
[root@db01 data]# mysql -uroot -p1 < /tmp/backup.sql
#7.启动服务
tomcat php ...

结合:mysqldump全备+binlog增备 恢复数据。

物理备份-Xtrabackup

1
[root@db01 ~]# yum localinstall percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm -y

1)对于非innodb表(比如myisam)是直接锁表cp数据文件,属于一种温备。
2)对于innodb的表(支持事务),不锁表,cp数据页最终以数据文件方式保存下来,并且把redo和undo一并备走,属于热备方式。
3)备份时读取配置文件/etc/my.cnf

全量备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@db01 ~]# mkdir /backup
[root@db01 ~]# innobackupex --user=root --password=1 /backup
completed OK!
#记录binlog名字和位置点
-rw-r----- 1 root root 21 Nov 15 00:29 xtrabackup_binlog_info
#
-rw-r----- 1 root root 119 Nov 15 00:29 xtrabackup_checkpoints
#备份类型(全备)
backup_type = full-backuped
#从哪个日志版本号开始
from_lsn = 0
#备份到哪个日志版本号
to_lsn = 1025046494
#最新的日志版本号
last_lsn = 1025046494
compact = 0
recover_binlog_info = 0

-rw-r----- 1 root root 466 Nov 15 00:29 xtrabackup_info
-rw-r----- 1 root root 2560 Nov 15 00:29 xtrabackup_logfile

恢复数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#1.先停库
/etc/init.d/mysqld stop

#2.清空data目录或者备份data目录
[root@db01 mysql]# mv /application/mysql/data/ /tmp/

#3.先做redo和undo 模拟CSR
[root@db01 mysql]# innobackupex --user=root --password=1 --apply-log /backup/2019-11-15_00-35-57

#4.恢复data 在my.cnf里面必须有datadir
[root@db01 mysql]# innobackupex --copy-back /backup/2019-11-15_00-35-57

#5.授权
[root@db01 mysql]# chown -R mysql.mysql /application/mysql/data

增量备份

备份方式

1)基于上一次备份进行增量
2)增量备份无法单独恢复,必须基于全备进行恢复
3)所有增量必须要按顺序合并到全备当中

1
2
3
4
5
6
7
8
9
10
[root@db01 ~]# innobackupex --user=root --password=1 --no-timestamp /backup/full

#1.第一次增量备份
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp --incremental --incremental-basedir=/backup/full /backup/inc1

#2.第二次增量备份
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp --incremental --incremental-basedir=/backup/inc1 /backup/inc2

#3.第三次增量备份
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp --incremental --incremental-basedir=/backup/inc2 /backup/inc3

恢复数据

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
28
29
30
31
32
1.增量备份无法单独恢复,必须基于全备进行恢复
2.所有增量必须要按顺序合并到全备当中
3.分步骤进行--apply-log

full + inc1 + inc2 + inc3
1)给全备,只做redo,不做undo
[root@db01 backup]# innobackupex --apply-log --redo-only /backup/full/
backup_type = log-applied
from_lsn = 0
to_lsn = 1025119769

2)将inc1合并到full中 只做redo 不做undo
[root@db01 backup]# innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full/
from_lsn = 0
to_lsn = 1025140919

3)将inc2合并到full中 只做redo 不做undo
[root@db01 backup]# innobackupex --apply-log --redo-only --incremental-dir=/backup/inc2 /backup/full/

4)将inc3合并到full中 redo 和 undo 都做
[root@db01 backup]# innobackupex --apply-log --incremental-dir=/backup/inc3 /backup/full/
backup_type = full-prepared
from_lsn = 0
to_lsn = 1025168949

5)将整个full目录模拟一次CSR
[root@db01 backup]# innobackupex --apply-log /backup/full/

6)copy back
[root@db01 backup]# rm -fr /application/mysql/data/*
[root@db01 backup]# innobackupex --copy-back /backup/full/
[root@db01 backup]# chown -R mysql.mysql /application/mysql/data/

差异备份

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
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp /backup/full_1
backup_type = full-backuped
from_lsn = 0
to_lsn = 1025176220

#1.第一次差异备份
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp --incremental --incremental-basedir=/backup/full_1 /backup/chayi1
[root@db01 backup]# cat chayi1/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 1025176220
to_lsn = 1025202474

#2.第二次差异备份
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp --incremental --incremental-basedir=/backup/full_1 /backup/chayi2
backup_type = incremental
from_lsn = 1025176220
to_lsn = 1025208985

#3.第三次差异备份
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp --incremental --incremental-basedir=/backup/full_1 /backup/chayi3

#4.第四次差异备份
[root@db01 backup]# innobackupex --user=root --password=1 --no-timestamp --incremental --incremental-basedir=/backup/full_1 /backup/chayi4
backup_type = incremental
from_lsn = 1025176220
to_lsn = 1025234244

恢复数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#1.停数据库
[root@db01 backup]# /etc/init.d/mysqld stop

#2.删除data目录或者备份
[root@db01 backup]# rm -fr /application/mysql/data/*

#3.模拟CSR合并数据
full_1 + chayi1 + chayi2 + chayi3 + chayi4
1)full_1只做redo 不做undo
[root@db01 backup]# innobackupex --apply-log --redo-only /backup/full_1/
2)将chayi4合并到full_1 redo undo 都做
[root@db01 backup]# innobackupex --apply-log --incremental-dir=/backup/chayi4 /backup/full_1/
3)将full_1 redo undo 都做
[root@db01 backup]# innobackupex --apply-log /backup/full_1/

#4.copy back
[root@db01 backup]# innobackupex --copy-back /backup/full_1/
[root@db01 backup]# chown -R mysql.mysql /application/mysql/data/
1
2
3
4
5
6
#!/bin/bash

while true;do
mysql -uroot -p1 -e 'insert into mysqldump.mysqldump values(1);commit;'
sleep 2
done

优点:

1.备份的时候,方便

2.恢复的时候,也方便

缺点:

重复数据多,占用磁盘空间大

Nginx-LNMP架构搭建

Nginx和fastcgi之间的故事

1566179108056

1)发起一个!1566179108056](C:\Users\86152\Desktop\typora-user-images\1566179108056.png)动态请求,连接到服务器找到nginx

2)nginx来判断请求,找到相应location

1
2
3
location ~ \.php$ {
fastcgi_pass 127.0.0.1;
}

3)通过fastcgiphp-fpm管理进程建立连接

4)php-fpm调用wrapper对动态请求进行解析

php-fpm.conf:配置php进程相关的

php.ini:配置php工作请求相关的

5)如果需要用到数据库,php代码连接 数据库

nginx->fastcgi->php-fpm->wrapper->php.ini->php解析器->mysql

部署LNMP

部署nginx

1)更换nginx的官方源

1
2
3
4
5
6
[root@web01 ~]# vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

2)安装nginx

1
[root@web01 ~]# yum install -y nginx

3)创建nginx启动用户

1
2
[root@web01 ~]# groupadd www -g 666
[root@web01 ~]# useradd www -u 666 -g 666 -s /sbin/nologin -M

4)修改nginx的启动用户

1
2
3
#修改nginx的配置文件
[root@web01 ~]# vim /etc/nginx/nginx.conf
user www;

5)启动nginx并加入开机自启

1
2
[root@web01 ~]# systemctl start nginx
[root@web01 ~]# systemctl enable nginx

6)打开浏览器查看nginx是否启动成功

http://10.0.0.7

1566181245191

部署PHP

1)更改PHP源

1
2
3
4
5
[root@web02 ~]# vim /etc/yum.repos.d/php.repo 
[php-webtatic]
name = PHP Repository
baseurl = http://us-east.repo.webtatic.com/yum/el7/x86_64/
gpgcheck = 0

2)安装PHP

1
[root@web02 ~]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb

3)修改PHP的启动用户

1
2
3
[root@web01 conf.d]# vim /etc/php-fpm.d/www.conf
user = www
group = www

4)启动php加入开机自启

1
2
[root@web01 conf.d]# systemctl start php-fpm
[root@web01 conf.d]# systemctl enable php-fpm

5)配置nginx通过fastcgi连接php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@web01 conf.d]# vim php.conf
server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html;
}
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

6)打开浏览器访问

1566182781238

部署数据库

1)安装mariadb

1
[root@web01 ~]# yum install -y mariadb-server

2)启动并加入开机自启

1
2
[root@web01 ~]# systemctl start mariadb
[root@web01 ~]# systemctl enable mariadb

3)设置数据库密码

1
[root@web01 ~]# mysqladmin -uroot password 'Zls123.com'

4)连接数据库

1
[root@web01 ~]# mysql -uroot -pZls123.com

5)测试php连接数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$servername = "localhost";
$username = "root";
$password = "Zls123.com";

// 创建连接
$conn = mysqli_connect($servername, $username, $password);

// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "小哥哥,php可以连接MySQL...";
?>

<img style='width:100%;height:100%;' src=https://www.driverzeng.com/zenglaoshi/php_mysql.png>

1566186558517

6)连接数据库,创建库

1
2
3
4
5
6
7
8
9
10
11
12
13
#查看有哪些数据库
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
#创建数据库
MariaDB [(none)]> create database wordpress;
Query OK, 1 row affected (0.00 sec)

1566188109395

1566188157026

mysql-day01

数据库管理员:

1.用户管理

  • 用户名
  • 密码

2.权限管理

1
grant all on *.* to root@'%' identified by '123';

3.数据管理

  • 备份\恢复

4.集群管理

  • 主从复制
    • 异步复制
    • 半同步复制
    • 延时复制
    • 过滤复制
  • 读写分离
    • mycat
    • atlas
    • mysql-proxy
  • 高可用
    • MMM
    • MHA
    • 双主+keepalived
    • MGR
  • 监控
    • shell
    • zabbix
    • percona

MySQL安装选择

mysql官网

1572398449570

1572398466007

1572398490014

1572398508063

MySQL版本选择的潜规则:

MySQL5.6版本:GA 6-12个月 ,小版本是偶数版本

1572398840189

MySQL5.7版本:GA 6-12个月 ,小版本是偶数版本,选择MySQL5.7.17以上版本 (MGR)

源码:mysql-5.6.44.tar.gz

1572399210091

二进制:mysql-5.6.44-linux-glibc2.12-x86_64.tar.gz

1572399269196

什么是数据?

数据(data)是事实或观察的结果,是对客观事物的逻辑归纳,是用于表示客观事物的未经加工的的原始素材。
数据可以是连续的值,比如声音、图像,称为模拟数据。也可以是离散的,如符号、文字,称为数字数据。
在计算机系统中,数据以二进制信息单元0,1的形式表示。

为什么不把数据放到 word这些工具里面?

1.安全性

2.集群

什么是数据库管理系统

DBMS(database management system)

1.管理数据

2.存储数据

数据库的种类

1.关系型数据库(RDBMS)

典型产品:MySQL,Oracle,MSSQL(SQLserver)t-sql

img

表与表之间是由关联的(连表查询)

2.非关系型数据库(NoSQL)

img

不使用SQL语句

json(key:value)

MongoDB、Redis、elasticsearch

关系型数据库非关系型数据库功能对比

img

关系型和非关系型特点对比:

关系型数据库(RDBMS)的特点:

  • 1.二维表
  • 2.典型产品Oracle传统企业,MySQL互联网企业
  • 3.数据存取是通过SQL(Structured Query Language结构化查询语言)
  • 4.最大特点数据安全性方面强(ACID)

非关系型数据库(NoSQL:Not only SQL)的特点:

  • 1.不是否定关系型数据库,而是做关系型数据库的补充。

时代特点对比

    1. web1.0时代
    • 1.1 企业提供内容,用户浏览,所以关系型数据库够用,并发并不高,所以不需要nosql。
    1. web2.0时代
    • 2.1 核心是企业提供平台,用户参与提供内容,这个时代关系型数据库无法满足需求了。
    1. 2003NoSQL出现
    • 3.1 memcache的诞生,关注的点是性能,但是针对安全性能关注比较低,随着安全性能需求不断提升,所以有了redis。
    1. redis的特点
    • 4.1 依然高性能高并发
    • 4.2 数据持久化功能
    • 4.3 支持多数据类型,主从复制和集群
    • 4.4 管理不再使用SQL了

NoSQL的分类、特点、典型产品

  • 1.键值(KV)存储:memcached、redis
  • 2.列存储(column-oriented):HBASE(新浪、360)Cassandra(200台服务器集群)
  • 3.文档数据库(document-oriented):MongoDB(最接近关系型数据库的NoSQL)
  • 4.图形存储(Graph):Neo4j
大版本 经典版本号
7 7.3.4
8i(internet) 8.1.7
9i 9.2.0.8
10g(grid) 10.2.0.4
11g 11.2.0.3、11.2.0.4
12c(cloud) None
18c None

源码安装MySQL

  • 解压
  • 生成
  • 编译
  • 安装

0.安装依赖包

1
[root@db01 mysql-5.6.44]# yum install -y cmake ncurses-devel autoconf

1.下载安装包

1
wget https://downloads.mysql.com/archives/get/file/mysql-5.6.44.tar.gz

2.解压

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@db01 ~]# tar xf mysql-5.6.44.tar.gz
[root@db01 ~]# cd mysql-5.6.44
[root@db01 mysql-5.6.44]# ll
total 252
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 BUILD
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 client
drwxr-xr-x 4 7161 31415 4096 Mar 15 2019 cmake
-rw-r--r-- 1 7161 31415 23415 Mar 15 2019 CMakeLists.txt
drwxr-xr-x 3 7161 31415 21 Mar 15 2019 cmd-line-utils
-rw-r--r-- 1 7161 31415 19838 Mar 15 2019 config.h.cmake
-rw-r--r-- 1 7161 31415 40929 Mar 15 2019 configure.cmake
-rw-r--r-- 1 7161 31415 17987 Mar 15 2019 COPYING
drwxr-xr-x 2 7161 31415 312 Mar 15 2019 dbug
drwxr-xr-x 2 7161 31415 80 Mar 15 2019 Docs
-rw-r--r-- 1 7161 31415 65958 Mar 15 2019 Doxyfile-perfschema
drwxr-xr-x 4 7161 31415 229 Mar 15 2019 extra
drwxr-xr-x 4 7161 31415 4096 Mar 15 2019 include
-rw-r--r-- 1 7161 31415 333 Mar 15 2019 INSTALL
drwxr-xr-x 3 7161 31415 224 Mar 15 2019 libmysql
drwxr-xr-x 3 7161 31415 204 Mar 15 2019 libmysqld
drwxr-xr-x 2 7161 31415 221 Mar 15 2019 libservices
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 man
drwxr-xr-x 10 7161 31415 305 Mar 15 2019 mysql-test
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 mysys
drwxr-xr-x 2 7161 31415 300 Mar 15 2019 mysys_ssl
drwxr-xr-x 9 7161 31415 113 Mar 15 2019 packaging
drwxr-xr-x 11 7161 31415 187 Mar 15 2019 plugin
-rw-r--r-- 1 7161 31415 2496 Mar 15 2019 README
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 regex
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 scripts
drwxr-xr-x 2 7161 31415 6 Mar 15 2019 source_downloads
drwxr-xr-x 4 7161 31415 12288 Mar 15 2019 sql
drwxr-xr-x 5 7161 31415 4096 Mar 15 2019 sql-bench
drwxr-xr-x 2 7161 31415 155 Mar 15 2019 sql-common
drwxr-xr-x 13 7161 31415 169 Mar 15 2019 storage
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 strings
drwxr-xr-x 5 7161 31415 4096 Mar 15 2019 support-files
drwxr-xr-x 2 7161 31415 4096 Mar 15 2019 tests
drwxr-xr-x 5 7161 31415 70 Mar 15 2019 unittest
-rw-r--r-- 1 7161 31415 88 Mar 15 2019 VERSION
drwxr-xr-x 3 7161 31415 298 Mar 15 2019 vio
drwxr-xr-x 2 7161 31415 32 Mar 15 2019 win
drwxr-xr-x 11 7161 31415 4096 Mar 15 2019 zlib

3.创建需要安装的路径

1
[root@db01 mysql-5.6.44]# mkdir /application

4.生成 ./configure –prefix=/usr/local/nginx-1.16.0 cmake 、gmake

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.44 \
-DMYSQL_DATADIR=/application/mysql-5.6.44/data \
-DMYSQL_UNIX_ADDR=/application/mysql-5.6.44/tmp/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \
-DWITH_ZLIB=bundled \
-DWITH_SSL=bundled \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_EMBEDDED_SERVER=1 \
-DENABLE_DOWNLOADS=1 \
-DWITH_DEBUG=0

5.编译

1
[root@db01 mysql-5.6.44]# make

6.安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@db01 mysql-5.6.44]# make install
[root@db01 mysql-5.6.44]# ll /application/mysql-5.6.44/
total 44
drwxr-xr-x 2 root root 4096 Oct 30 16:18 bin
-rw-r--r-- 1 root root 17987 Mar 15 2019 COPYING
drwxr-xr-x 3 root root 18 Oct 30 16:17 data
drwxr-xr-x 2 root root 55 Oct 30 16:17 docs
drwxr-xr-x 3 root root 4096 Oct 30 16:17 include
drwxr-xr-x 3 root root 291 Oct 30 16:17 lib
drwxr-xr-x 4 root root 30 Oct 30 16:17 man
drwxr-xr-x 10 root root 4096 Oct 30 16:18 mysql-test
-rw-r--r-- 1 root root 2496 Mar 15 2019 README
drwxr-xr-x 2 root root 30 Oct 30 16:18 scripts
drwxr-xr-x 28 root root 4096 Oct 30 16:18 share
drwxr-xr-x 4 root root 4096 Oct 30 16:18 sql-bench
drwxr-xr-x 2 root root 136 Oct 30 16:18 support-files

[root@db01 mysql-5.6.44]# ll /application/mysql-5.6.44/data/
total 0
drwxr-xr-x 2 root root 20 Oct 30 16:17 test

—————————————————华丽的分割线—————————————————

7.创建用户

1
[root@db01 mysql-5.6.44]# useradd mysql -s /sbin/nologin -M

8.拷贝启动脚本

1
2
[root@db01 support-files]# cd /application/mysql-5.6.44/support-files/
[root@db01 support-files]# cp mysql.server /etc/init.d/mysqld

9.拷贝配置文件

1
2
[root@db01 support-files]# cp my-default.cnf /etc/my.cnf
cp: overwrite ‘/etc/my.cnf’? y(覆盖)

10.创建socket文件存放目录

1
mkdir /application/mysql-5.6.44/tmp

11.软链接

1
[root@db01 scripts]# ln -s /application/mysql-5.6.44 /application/mysql

12.给MySQL目录授权

1
[root@db01 scripts]# chown -R mysql.mysql /application/*

13.初始化数据库

1
2
[root@db01 scripts]# cd /application/mysql-5.6.44/scripts
[root@db01 scripts]# ./mysql_install_db --user=mysql --basedir=/application/mysql --datadir=/application/mysql/data

1572425444772

14.启动MySQL

1
2
[root@db01 scripts]# /etc/init.d/mysqld start
Starting MySQL. SUCCESS!

15.添加环境变量

1
2
3
4
5
6
7
8
9
10
11
[root@db01 scripts]# vim /etc/profile.d/mysql.sh
export PATH="/application/mysql/bin:$PATH"
#加载环境变量
[root@db01 scripts]# source /etc/profile
#查看所有的环境变量
[root@db01 scripts]# echo $PATH
/application/mysql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

#检查端口
[root@db01 scripts]# netstat -lntup
tcp6 0 0 :::3306 :::* LISTEN 34209/mysqld

二进制安装MySQL

解压开就能使用,绿色安装

1.下载

1
wget https://downloads.mysql.com/archives/get/file/mysql-5.6.44-linux-glibc2.12-x86_64.tar.gz

2.解压

1
[root@db02 ~]# tar xf mysql-5.6.44-linux-glibc2.12-x86_64.tar.gz

3.创建MySQL用户

1
[root@db02 ~]# useradd mysql -s /sbin/nologin -M

4.创建MySQL安装目录

1
[root@db02 ~]# mkdir /application

5.移动MySQL到安装目录下

1
[root@db02 ~]# mv mysql-5.6.44-linux-glibc2.12-x86_64 /application/mysql-5.6.44

6.做软链接

1
[root@db02 ~]# ln -s /application/mysql-5.6.44 /application/mysql

7.拷贝启动脚本

1
[root@db02 support-files]# cp mysql.server /etc/init.d/mysqld

8.拷贝配置文件

1
2
[root@db02 support-files]# cp my-default.cnf /etc/my.cnf
cp: overwrite ‘/etc/my.cnf’? y(覆盖)

9.初始化

1
[root@db02 scripts]# ./mysql_install_db --basedir=/application/mysql --datadir=/application/mysql/data --user=mysql

10.授权MySQL目录

1
[root@db02 scripts]# chown -R mysql.mysql /application/mysql*

11.修改mysql启动脚本和程序

1
[root@db02 scripts]# sed -i 's#/usr/local#/application#g' /etc/init.d/mysqld /application/mysql/bin/mysqld_safe

12.启动

1
[root@db02 scripts]# /etc/init.d/mysqld start

13.添加环境变量

1
2
[root@db02 scripts]# vim /etc/profile.d/mysql.sh
export PATH="/application/mysql/bin:$PATH"