工作中 CentOS 的一些笔记 02

工作中 CentOS 的一些笔记 02

工作中 CentOS 的一些笔记 02,其实大部分都是 Linux 通用。

[toc]

Tengine

安装 Tengine

安装编译环境:

1
sudo yum -y install gcc gcc-c++ autoconf automake

安装 PCRE:

1
sudo yum install pcre pcre-static

通过包管理器安装 OpenSSL(yum 源默认 openssl 版本较老,要使用更新版本特性可以手动拉取源码编译安装):

1
sudo yum install openssl openssl-static

拉取 jemalloc 源码:

1
2
3
wget 192.168.188.1:8000/jemalloc-5.2.1.tar.bz2 # 拉取代码
sudo yum -y install bzip2 # 安装 bzip2 支持库
tar -xvjf jemalloc-5.2.1.tar.bz2 # 解压

设置用户组和目录:

1
2
sudo groupadd -r app # 添加 app 组
sudo useradd -g app -r app # 添加 app 用户,其组为 app

下载 tengine 源码并解压:

1
2
wget https://tengine.taobao.org/download/tengine-2.3.2.tar.gz # 下载
tar xzf tengine-2.3.2.tar.gz # 解压

进行 makefile 文件的编译配置,指定用户为 app,组为 app,设置 jemalloc 源码路径,Tengine 可以静态编译和链接该库:

1
2
3
./configure --user=app \
--group=app \
--with-jemalloc=/home/bolitao/jemalloc-5.2.1

编译配置概述如下:

image-20200709101823704

进行编译和安装:

1
2
make
sudo make install

查看安装是否成功:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
➜  tengine-2.3.2 sudo /usr/local/nginx/sbin/nginx -V # 查看版本
Tengine version: Tengine/2.3.2
nginx version: nginx/1.17.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --user=app --group=app --with-jemalloc=/home/bolitao/jemalloc-5.2.1
➜  tengine-2.3.2 sudo /usr/local/nginx/sbin/nginx -t # 测试配置是否正常
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

配置 Tengine

配置 systemd 服务:

1
sudo vim /usr/lib/systemd/system/nginx.service

nginx.service 内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Unit]
Description=Tengine/nginx
Documentation=https://nginx.org/en/docs/
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target

修改 tengine 配置文件,取消注释 user 行,修改 userapp

1
2
3
4
sudo vim /usr/local/nginx/conf/nginx.conf

# nginx.conf 中 user 字段修改如下:
user  app;

修改 systemd 相关权限,配置开机自启动等功能:

1
2
3
4
sudo chmod 745 /usr/lib/systemd/system/nginx.service # 修改权限
sudo systemctl daemon-reload # 重载 systemd
sudo systemctl start nginx.service # 启动 Tengine 服务
sudo systemctl enable nginx.service # 允许开机自启动

使用 sudo systemctl status nginx.service 查看运行状态:

image-20200709105018474

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
➜  tengine-2.3.2 sudo systemctl status nginx.service
● nginx.service - Tengine/nginx
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since 四 2020-07-09 10:44:12 CST; 5min ago
     Docs: https://nginx.org/en/docs/
 Main PID: 30407 (nginx)
   CGroup: /system.slice/nginx.service
           ├─30407 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
           └─30409 nginx: worker process

7月 09 10:44:12 localhost.localdomain systemd[1]: Starting Tengine/nginx...
7月 09 10:44:12 localhost.localdomain nginx[30404]: nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
7月 09 10:44:12 localhost.localdomain nginx[30404]: nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
7月 09 10:44:12 localhost.localdomain systemd[1]: New main PID 28173 does not exist or is a zombie.
7月 09 10:44:12 localhost.localdomain systemd[1]: Started Tengine/nginx.

检查运行状态

使用 curl 访问 127.0.0.1 查看 Tengine 返回的 HTTP 头:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
➜  tengine-2.3.2 curl -I 127.0.0.1
HTTP/1.1 200 OK
Server: Tengine/2.3.2
Date: Thu, 09 Jul 2020 02:51:18 GMT
Content-Type: text/html
Content-Length: 555
Last-Modified: Thu, 09 Jul 2020 02:22:10 GMT
Connection: keep-alive
ETag: "5f067f52-22b"
Accept-Ranges: bytes

从以上可看到 Tengine web 服务器运行正常。

防火墙放行 80443 端口:

1
2
3
4
➜  tengine-2.3.2 sudo firewall-cmd --zone=public --add-port=443/tcp
success
➜  tengine-2.3.2 sudo firewall-cmd --zone=public --add-port=80/tcp
success

通过宿主机访问虚拟机 IP(192.168.188.128),Tengine 运行正常:

image-20200709110628353

MySQL

安装 MySQL

通过二进制压缩包进行安装的笔记在 其他 - 通过二进制压缩包进行安装 部分。

下载 MySQL 官方 rpm 包,安装 rpm 包并更新 yum 源后,可以通过 yum 包管理器安装 MySQL server:

1
2
3
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm # 下载 rpm 包
sudo rpm -Uvh mysql80-community-release-el7-3.noarch.rpm
sudo yum update # 进行更新,会提示安装 mysql-community-libs 和 mysql-community-common,并导入 MySQL 官方 GPG key

查看 MySQL repo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
➜  ~ yum repolist all | grep mysql
mysql-cluster-7.5-community/x86_64  MySQL Cluster 7.5 Community     禁用
mysql-cluster-7.5-community-source  MySQL Cluster 7.5 Community - S 禁用
mysql-cluster-7.6-community/x86_64  MySQL Cluster 7.6 Community     禁用
mysql-cluster-7.6-community-source  MySQL Cluster 7.6 Community - S 禁用
mysql-cluster-8.0-community/x86_64  MySQL Cluster 8.0 Community     禁用
mysql-cluster-8.0-community-source  MySQL Cluster 8.0 Community - S 禁用
mysql-connectors-community/x86_64   MySQL Connectors Community      启用:    153
mysql-connectors-community-source   MySQL Connectors Community - So 禁用
mysql-tools-community/x86_64        MySQL Tools Community           启用:    110
mysql-tools-community-source        MySQL Tools Community - Source  禁用
mysql-tools-preview/x86_64          MySQL Tools Preview             禁用
mysql-tools-preview-source          MySQL Tools Preview - Source    禁用
mysql55-community/x86_64            MySQL 5.5 Community Server      禁用
mysql55-community-source            MySQL 5.5 Community Server - So 禁用
mysql56-community/x86_64            MySQL 5.6 Community Server      禁用
mysql56-community-source            MySQL 5.6 Community Server - So 禁用
mysql57-community/x86_64            MySQL 5.7 Community Server      禁用
mysql57-community-source            MySQL 5.7 Community Server - So 禁用
mysql80-community/x86_64            MySQL 8.0 Community Server      启用:    177
mysql80-community-source            MySQL 8.0 Community Server - So 禁用

可发现默认启用的是 8.0 版本,可以通过 yum-config-manager 更改版本:

1
2
3
sudo yum -y install yum-utils # 安装 yum 相关管理包
sudo yum-config-manager --disable mysql80-community # 禁用 MySQL 8.x 版本
sudo yum-config-manager --enable mysql57-community # 启用 MySQL 5.7

安装 MySQL:

1
2
3
sudo yum remove mysql-community-common mysql-community-libs # 卸载原来 MySQL 8 的相关依赖
sudo yum install mysql-community-common mysql-community-libs # 重新安装 MySQL 5 的相关依赖
sudo yum install mysql-community-server # 安装 MySQL

启动并查看 MySQL 状态:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
➜  ~ sudo systemctl start mysqld.service # 启动 MySQL
➜  ~ sudo systemctl status mysqld.service # 查看 MySQL 运行状态
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since 四 2020-07-09 11:39:12 CST; 1s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 32346 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 32297 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 32349 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─32349 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

7月 09 11:39:09 localhost.localdomain systemd[1]: Starting MySQL Server...
7月 09 11:39:12 localhost.localdomain systemd[1]: Started MySQL Server.

配置 MySQL

查看 MySQL 安装时生成的暂用 root 密码:

1
2
➜  ~ sudo grep 'temporary password' /var/log/mysqld.log
2020-07-09T03:39:10.757404Z 1 [Note] A temporary password is generated for root@localhost: qX-SXV1guhsW

从上知 MySQL 安装过程中自动生成的密码为 qX-SXV1guhsW。使用 sudo mysql_secure_installation 命令重新配置 root 密码和远程访问:

 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
➜  ~ sudo mysql_secure_installation

Securing the MySQL server deployment.

Enter password for user root:

The existing password for the user account root has expired. Please set a new password.

New password:

Re-enter new password:

Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : n

 ... skipping.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : n

 ... skipping.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done!

检查运行状态

配置完成后可用 mysql cli 访问安装的 MySQL:

 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
➜  ~ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 5.7.30 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.30, for Linux (x86_64) using  EditLine wrapper

Connection id:          24
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          less
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.30 MySQL Community Server (GPL)
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 9 min 4 sec

Threads: 1  Questions: 17  Slow queries: 0  Opens: 113  Flush tables: 1  Open tables: 106  Queries per second avg: 0.031
--------------

防火墙开放 MySQL 端口:

1
sudo firewall-cmd --zone=public --add-port=3306/tcp

宿主机使用 MySQL CLI 访问虚拟机 MySQL:

1
mysql -u root -p -P 3306 -h 192.168.188.130

image-20200709135449122

Redis

Redis 安装的几个方法

  1. 通过 EPEL 源安装
  2. 拉取源码编译安装
  3. 使用 Docker 安装,Redis 提供了官方 Docker 镜像

编译安装 Redis

CentOS 7 中 GCC 版本为 4.x,无法编译 Redis 6,为避免污染系统环境,使用 scl 安装其他编译软件集:

1
2
3
sudo yum install centos-release-scl
sudo yum update
sudo yum install tcl devtoolset-9 # 安装版本为 9 的 scl 软件集,其中包含 gcc 9

进入 scl 软件集环境,并使用源码编译 Redis:

1
2
3
4
5
6
wget 192.168.188.1:8000/redis-6.0.5.tar.gz
tar -xzf redis-6.0.5.tar.gz
cd redis-6.0.5
scl enable devtoolset-9 bash
make
make test # 该步骤耗时较长,依赖 tcl 包

image-20200709144609307

安装:

1
sudo make install # 将会安装至 /usr/local/bin 目录

将 Redis 注册为系统服务

复制 redis 模板配置文件:

1
sudo cp redis.conf /etc/redis

修改 Redis 配置文件:

1
2
3
4
5
6
sudo vim /etc/redis/redis.conf

# 修改以下字段:
daemonize yes
...
supervised systemd

编辑 redis systemd 配置:

1
sudo vim /etc/systemd/system/redis.service

配置内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Unit]
Description=Redis data structure server
Documentation=https://redis.io/documentation
After=network.target syslog.target

[Service]
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/local/bin/redis-cli shutdown
Type=forking
TimeoutStartSec=10 # 服务允许的最大启动时长
TimeoutStopSec=20 # 服务自身停止的超时时长
Restart=always

[Install]
WantedBy=multi-user.target

确认运行状态

使用 systemd 确认运行状态:

1
sudo systemctl status redis.service

image-20200709153458669

使用 redis-cli 确认运行状态:

1
2
➜  redis-6.0.5 redis-cli ping
PONG

ZooKeeper

安装

创建用户和组:

1
2
sudo groupadd zookeeper
sudo useradd -g zookeeper -d /opt/zookeeper -s /sbin/nologin zookeeper

下载、解压、移动二进制压缩包:

1
2
3
4
5
6
7
8
9
wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz
tar xzvf apache-zookeeper-3.6.1-bin.tar.gz
sudo mv apache-zookeeper-3.6.1-bin /opt
cd opt
sudo mv apache-zookeeper-3.6.1-bin zookeeper
cd zookeeper
sudo mkdir data # 数据目录
sudo mkdir logs # 日志文件目录
sudo vim /opt/zookeeper/conf/zoo.cfg # 编辑配置文件

zoo.cfg 内容如下:

1
2
3
4
5
6
tickTime=2000 # 时间单元
initLimit=10 
syncLimit=5
dataDir=/opt/zookeeper/data
dataLogDir=/opt/zookeeper/logs
clientPort=2181

启动

1
zookeeper sudo /opt/zookeeper/bin/zkServer.sh start

image-20200709165619490

查看状态:

1
sudo /opt/zookeeper/bin/zkServer.sh status

image-20200709165659940

可以看到 zk 正以单机模式运行,端口号为 2181。

将 ZooKeeper 注册为系统服务

新增 sk systemd 配置文件:

1
sudo vim /etc/systemd/system/zookeeper.service

配置文件内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[Unit]
Description=Zookeeper Service
After=syslog.target

[Service]
Type=simple
WorkingDirectory=/opt/zookeeper/
PIDFile=/opt/zookeeper/data/zookeeper_server.pid
SyslogIdentifier=zookeeper
ExecStart=/opt/zookeeper/bin/zkServer.sh start
ExecStop=/opt/zookeeper/bin/zkServer.sh stop
Restart=always
TimeoutSec=20
SuccessExitStatus=130 143
Restart=on-failure

[Install]
WantedBy=multi-user.target

使用 systemctl 命令进行管理:

1
2
sudo systemctl daemon-reload
sudo systemctl status zookeeper.service # 开启服务

查看运行状态:

1
sudo systemctl status zookeeper.service

image-20200709170310667

其他

几种 MySQL 的安装及其对应的卸载方式

通过 MySQL 官方提供的 yum 源进行安装

1
2
3
4
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm # 下载 rpm 包
sudo rpm -Uvh mysql80-community-release-el7-3.noarch.rpm
sudo yum update
sudo yum install mysql-community-server

通过该方法安装的 MySQL 卸载方式:

1
2
sudo yum remove mysql # 卸载 MySQL-community-server
sudo rm -rf /var/lib/mysql # 删除 MySQL 数据目录

通过源码编译安装

该方法耗时较长。

相关文档:MySQL :: MySQL 5.7 Reference Manual :: 2.9 Installing MySQL from Source

通过二进制压缩包进行安装

// TODO

[TOC]

2020-07-10 学习日志(阶段2)

几种 MySQL 的安装及其对应的卸载方式(接昨日内容)

通过二进制压缩包进行安装

安装依赖、拉取二进制压缩包:

1
2
3
4
5
6
sudo yum install libaio # 安装 MySQL 基础 AIO 依赖
wget -P /mysql https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz # 下载二进制压缩包
sudo mkdir /usr/local/mysql
tar -xzvf mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz # 解压缩
cd mysql-5.7.29-linux-glibc2.12-x86_64
sudo mv * /usr/local/mysql # 移动二进制文件至 /usr/local/mysql

更新环境变量:

1
2
# 在 .bashrc 或 .zshrc 文件内添加如下行,更新环境变量:
export PATH=$PATH:/usr/local/mysql/bin

添加用户和组:

1
2
3
4
# 添加用户和组
sudo groupadd mysql
sudo useradd -r -g mysql -s /bin/false mysql
#sudo useradd -g mysql -s /sbin/nologin mysql

创建 MySQL 相关必要目录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 创建 MySQL 相关目录
sudo mkdir -p /usr/local/mysql/datadir \
sudo mkdir -p /usr/local/mysql/log \
sudo mkdir -p /usr/local/mysql/etc \
sudo mkdir -p /usr/local/mysql/run \
sudo mkdir -p /usr/local/mysql/binlogs

# 修改相关目录 owner 为 mysql
sudo chown -R mysql.mysql /usr/local/mysql/datadir \
sudo chown -R mysql.mysql /usr/local/mysql/etc \
sudo chown -R mysql.mysql /usr/local/mysql/log \
sudo chown -R mysql.mysql /usr/local/mysql/run \
sudo chown -R mysql.mysql /usr/local/mysql/binlogs

创建 MySQL 配置文件:

1
sudo vim /usr/local/mysql/my.cnf

MySQL 配置内容如下:

 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
[client]
port = 3306
socket = /usr/local/mysql/run/mysql.sock

[mysqld]
port = 3306
socket = /usr/local/mysql/run/mysql.sock
pid_file = /usr/local/mysql/run/mysql.pid
datadir = /usr/local/mysql/datadir
default_storage_engine = InnoDB
max_allowed_packet = 128M
max_connections = 2048
open_files_limit = 65535

skip-name-resolve
lower_case_table_names=1

character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'


innodb_buffer_pool_size = 128M
innodb_log_file_size = 128M
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 0


key_buffer_size = 16M

log-error = /usr/local/mysql/log/mysql_error.log
log-bin = /usr/local/mysql/log/mysql_bin.log
slow_query_log = 1
slow_query_log_file = /usr/local/mysql/log/mysql_slow_query.log
long_query_time = 5


tmp_table_size = 16M
max_heap_table_size = 16M
query_cache_type = 0
query_cache_size = 0

server-id=1

初始化 MySQL,指定工作目录和数据存放目录:

1
sudo ./bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/datadir

查看安装过程日志:

1
2
3
➜  mysql cat log/mysql_error.log
...
2020-07-10T00:46:47.484981Z 1 [Note] A temporary password is generated for root@localhost: o9./mrQpygcO

可以看到为 root@localhost 生成的暂用密码为 o9./mrQpygcO

将 MySQL 注册为 服务(使用 systemd):

1
sudo vim /etc/systemd/system/mysqld.service

mysqld.service 配置文件内容如下:

 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
[Unit]
Description=MySQL Server
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql

Type=forking
PIDFile=/usr/local/mysql/run/mysql.pid

# Disable service start and stop timeout logic of systemd for mysqld service.
TimeoutSec=0

# Execute pre and post scripts as root
PermissionsStartOnly=true

# Start main service
ExecStart=/usr/local/mysql/bin/mysqld --daemonize --pid-file=/usr/local/mysql/run/mysql.pid $MYSQLD_OPTS

# Sets open_files_limit
LimitNOFILE = 65535

Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false

随后便能使用 systemd 管理 MySQL 服务:

1
2
3
sudo systemctl daemon-reload
sudo systemctl start mysqld.service
sudo systemctl status mysqld.service

使用 sudo systemctl status mysqld.service 命令查看 MySQL 运行状态:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
sudo systemctl status mysqld.service

# 以下是输出内容
● mysqld.service - MySQL Server
   Loaded: loaded (/etc/systemd/system/mysqld.service; disabled; vendor preset: disabled)
   Active: active (running) since 五 2020-07-10 08:58:46 CST; 2s ago
     Docs: http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 2193 ExecStart=/usr/local/mysql/bin/mysqld --daemonize --pid-file=/usr/local/mysql/run/mysql.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
 Main PID: 2195 (mysqld)
    Tasks: 27
   Memory: 180.9M
   CGroup: /system.slice/mysqld.service
           └─2195 /usr/local/mysql/bin/mysqld --daemonize --pid-file=/usr/local/mysql/run/mysql.pid

7月 10 08:58:45 localhost.localdomain systemd[1]: Starting MySQL Server...
7月 10 08:58:46 localhost.localdomain systemd[1]: Started MySQL Server.

使用 mysql_secure_installation 命令修改 root 密码、设置安全策略:

 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
mysql_secure_installation
# 以下是部分命令输出
Securing the MySQL server deployment.

Enter password for user root:

The existing password for the user account root has expired. Please set a new password.

New password:

Re-enter new password:

VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No: n
Using existing password for root.
Change the password for root ? ((Press y|Y for Yes, any other key for No) : y

New password:

Re-enter new password:
...

修改密码后,可使用 mysql -u root -p 命令本地连接数据库:

 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
mysql -u root -p
# mysql cli 客户端
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.29-log MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.29, for linux-glibc2.12 (x86_64) using  EditLine wrapper

Connection id:          6
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          less
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.29-log MySQL Community Server (GPL)
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /usr/local/mysql/run/mysql.sock
Uptime:                 4 min 22 sec

Threads: 1  Questions: 14  Slow queries: 0  Opens: 116  Flush tables: 1  Open tables: 109  Queries per second avg: 0.053
--------------

mysql>

防火墙放行 3306 端口的 TCP 连接:

1
sudo firewall-cmd --zone=public --add-port=3306/tcp

允许 root 用户远程访问:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select host,user from user;
+-----------+---------------+
| host      | user          |
+-----------+---------------+
| localhost | mysql.session |
| localhost | mysql.sys     |
| localhost | root          |
+-----------+---------------+
3 rows in set (0.00 sec)

mysql> update user set host='%' where user='root';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

由于 data 目录放在 /usr/local/mysql/datadir,在删除 MySQL 所在的 /usr/local/mysql 目录时,还会删除数据文件,因此注意在卸载前做好数据导出和备份

通过二进制压缩包方式安装 MySQL 的卸载方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 停止 MySQL 服务
sudo systemctl stop mysqld.service
# 删除 MySQL 安装文件夹,注意备份
sudo rm -rf /usr/local/mysql
# 删除 MySQL systemd 配置文件
sudo systemctl disable mysqld.service
sudo rm /etc/systemd/system/mysqld.service
sudo systemctl daemon-reload
sudo systemctl reset-failed

# 删除 .bashrc 中 MySQL 相关的环境变量,即以下行:
export PATH=$PATH:/usr/local/mysql/bin

最大文件操作数

单个进程打开文件的限制:ulimit -a 命令中 open files 的值:

image-20200710102223297

系统所有进程打开文件的限制:cat /proc/sys/fs/file-max

image-20200710103413464

暂时调整单个进程文件操作数

使用 ulimit -n xxx 进行调整。

硬限制:严格的设定,必定不能超过这个设定的数值。

软限制:警告的设定,可以超过这个设定值,但是若超过则有警告信息。

在普通用户下,无法调整超过 hard limit 的值,只能够调整 soft limit 的值,soft limit 无法超过 hard limit:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
➜  tmp ulimit -n # 默认看到的是 soft limit
1024
➜  tmp ulimit -nS
1024
➜  tmp ulimit -nH # -H 参数可以查看 hard limit 数量
4096
➜  tmp ulimit -nH 2000 # 普通用户无法调整 hard limit
4096
➜  tmp ulimit -n 2000 # 普通用户可以调整 soft limit
➜  tmp ulimit -nS 2000
2000
➜  tmp ulimit -nS 9000 # soft limit 无法超过 hard limit
ulimit: value exceeds hard limit
2000

永久调整单个进程文件操作数

修改 /etc/security/limits.conf 文件,一般 soft limit 值可以稍低于 hard limit:

1
2
* soft nofile 50000 
* hard nofile 65535

* 表示对所有用户生效。

如果只想对某些用户生效,比如只对运行 nginx 的用户 nginx 生效,可以修改如下:

1
2
nginx soft nofile 50000
nginx hard nofile 65535

调整所有进程文件打开总数限制

该值必须永远大于单个进程文件操作数。

修改 /etc/sysctl.conf 文件,添加或修改 fs.file-max 字段值:

1
fs.file-max = 655350

检查修改是否生效

重启后查看单个进程文件限制和总文件限制:

1
2
3
4
5
6
7
8
➜  ~ ulimit -n # 默认显示 soft limit
50000
➜  ~ ulimit -nH # hard limit
65535
➜  ~ ulimit -nS # soft limit
50000
➜  ~ cat /proc/sys/fs/file-max # 总文件限制
655350

Tengine 补充

Tengine 配置负载均衡

在宿主机添加一个 tomcat,虚拟机访问地址为 192.168.188.1:8080,开启虚拟机上的 tomcat,虚拟机 tomcat 访问地址为 127.0.0.1:8080

1
sudo systemctl start tomcat

修改 tomcat 默认主页,为顶部添加 虚拟机上的 tomcat主机的 tomcat 标识:

image-20200710161256212

进行 Tengine 相关配置:

1
sudo vim /usr/local/nginx/conf/nginx.conf

配置内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    upstream tomcats { # 使用权重进行轮询
        server 127.0.0.1:8080 weight=1;
        server 192.168.188.1:8080 weight=1;
    }
    server {
        listen 10010;
        server_name localhost;


        location / {
            proxy_pass http://tomcats;
        }
        access_log /home/bolitao/logs/tomcat_access.log; # 访问记录日志
    }

测试 nginx 配置无误:

1
2
3
➜ sudo ./sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

重启 nginx:

1
sudo systemctl restart nginx.service

放行相关端口:

1
2
sudo firewall-cmd --zone=public --permanent --add-port=10010/tcp # 放行 10010 端口
sudo systemctl restart firewalld.service # 重启防火墙

之后在宿主机可以使用 192.168.188.130:10010 访问由 Tengine 进行负载均衡的网页:

image-20200710161522901

image-20200710161536094

Tengine 后端节点检查

Tengine 2.3.2 默认不再自带 http_upstream_check_module 模块。

需要重新编译 Tengine,配置添加 --add-module=./modules/ngx_http_upstream_check_module 参数来添加健康检查模块:

1
2
3
4
5
6
7
./configure --user=app \
--group=app \
--with-jemalloc=/home/bolitao/jemalloc-5.2.1 \
--add-module=./modules/ngx_http_upstream_check_module

make # 重新编译
sudo make install # 重新安装

配置站点健康检查:

1
sudo vim /usr/local/nginx/conf/nginx.conf # 编辑 nginx 配置

tomcats upstream 中添加以下检查语句:

1
2
3
check interval=3000 rise=2 fall=5 timeout=1000 type=http; # 健康检查包发送间隔时间为 3秒;成功次数超过 2 次,认为服务器是 up 状态;失败次数超过 5 次,被认为是 down 状态;超时s时间为 1 秒;检查包类型为 http
check_http_send "HEAD / HTTP/1.0\r\n\r\n"; # 使用 HEAD 方法发送请求内容
check_http_expect_alive http_2xx http_3xx; # 指定 HTTP 回复的成功状态为 2xx 和 3xx

tomcats 对应的 server 中添加以下 location:

1
2
3
4
location /status {
    check_status; # 开启健康检查
    access_log   off; # 关闭日志记录
}

检查 nginx 配置是否正常,如果正常就重启 nginx 服务:

1
2
3
4
➜ sudo ./sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
➜ sudo systemctl restart nginx

访问网页的 /status 地址,结果如下:

image-20200710165016340

手动停止一个服务器,健康检查结果发生改变:

image-20200710165155694

Nginx 与 Tengine 的区别

Tengine 是基于 Nginx 的 fork,由淘宝网发起,针对大访问量情景做了优化,添加了许多高级功能和特性。Tengine 拥有 Nginx 1.17.3 的所有特性,兼容 Nginx 配置文件。

Tengine 增强了运维、监控相关功能,比如异步打印日志及回滚、本地DNS缓存、内存监控等;提供更多的负载均衡能力,可以适应更多场景,比如一致性hash模块、会话保持模块;还可以对后端的服务器进行主动健康检查,根据服务器状态自动上线下线,以及动态解析 upstream 中出现的域名。

Redis 补充

远程访问

将 Redis /etc/redis/redis.conf 配置文件中 bind 值修改为 0.0.0.0

1
bind 0.0.0.0

确认 protected-mode 处于打开状态:

1
protected-mode yes

防火墙放行 redis 端口:

1
sudo firewall-cmd --zone=public --permanent --add-port=6379/tcp

重启 redis 服务:

1
sudo systemctl restart redis.service

通过宿主机访问虚拟机 redis:

1
2
redis-cli -h 192.168.188.130 -p 6379 ping
PONG

设置密码

修改 配置文件,设置 requirepass 的值:

1
requirepass redis

重启 redis:

1
sudo systemctl restart redis.service

进行测试:

1
2
redis-cli -a redis -h 192.168.188.130 -p 6379 ping
PONG

持久化

Redis 官方文档对持久化介绍如下:

  • RDB 持久化方式每隔特定的间隔时间对数据进行一次快照备份
  • AOF 持久化方式记录服务器收到的每次写操作,当下次 redis 服务重启时,redis 会照着记录文件进行数据恢复。命令的日志格式与 Redis 协议本身相同,以追加的方式进行保存。当日志过大时,Redis 可以在后台进行重写
  • 持久化是一项可选功能
  • 在同一 Redis 实例中,可以同时启用 RDB 和 AOF 持久化方式。在同时使用这两种持久化方式的场景下,当 redis 重启时,会优先使用 AOF 文件恢复数据,因为 AOF 文件能尽可能保证数据完整性。

配置 Redis 持久化

redis 默认有以下持久化配置:

1
2
3
save 900 1 # 900 秒内如果有一条数据变动那么进行持久化
save 300 10 # 300 秒内有 10 条数据变动进行持久化
save 60 10000 # 60 秒内有 10000 条数据变动进行持久化

为方便观察,再添加一条规则:

1
save 30 1 # 30 秒内有一条数据变动就进行持久化

再启用 AOF 方式持久化:

1
2
appendonly yes
appendfilename "appendonly.aof"

设置 redis 持久化文件保存位置:

1
2
3
4
mkdir /home/bolitao/redisFile

# 以下是 redis 配置
dir /home/bolitao/redisFile

重启 redis 服务:

1
sudo systemctl restart redis.service

添加几条数据:

1
2
3
4
5
6
7
8
9
➜ redis-cli -a redis
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> set foo "bar"
OK
127.0.0.1:6379> set number 50
OK
127.0.0.1:6379> set foo "bar2"
OK
127.0.0.1:6379>

查看 AOF 文件:

image-20200710151226324

查看 RDB 文件:

image-20200710150500495

重启 redis:

1
sudo systemctl restart redis

在两种持久化方式都开启的情况下,优先从 AOF 进行数据恢复。重启后可以看到 redis 的数据已从持久化文件中恢复,没有丢失:

1
2
3
4
5
6
7
8
➜ redis-cli -a redis
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> keys *
1) "number"
2) "foo"
127.0.0.1:6379> get foo
"bar2"
127.0.0.1:6379>

总结

  • 如果对数据安全性和完整性要求高,那么应该同时使用这两种持久化方法
  • 如果在出现问题时可以忍受数分钟的数据丢失,那么可以只使用 RDB
  • Redis 官方不推荐单独使用 AOF,RDB 能够在 AOF 出现 bug 时提供次要恢复选择。并且 RDB 在备份、更快地重启方面有较好表现

Redis 相关操作和信息解读

基本命令

连接(包括远程和本地),-a 参数表示 auth,即认证密码,-h 表示地址,-p 表示端口:

1
redis-cli -a redis -h 192.168.188.130 -p 6379 # 连接本地 redis 则输入 127.0.0.1 或者不输即可

查看 redis 相关信息,在 cli 中输入 info 命令:

1
2
3
4
5
6
7
8
➜ redis-cli -a redis
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> info
# Server
redis_version:6.0.5
redis_git_sha1:00000000
redis_git_dirty:0
...
  • set key value:设置 key 值为 value
  • del key:删除 key
  • dump key:序列化 key
  • exists key:检查 key 是否存在
  • EXPIRE key:设置过期时间
  • KEYS pattern:查找符合给定模式的 key
  • move key dbx:将 key 移至 dbx 库
  • persist key:取消 key 的过期时间
  • ttl key:查询 key 的剩余生存时间
  • randomkey:随机获得一个 key
  • rename key newkey:将 key 的名字修改为 newkey
  • RENAMENX key newkey:只有 newkey 不存在时,把 key 名字改为 newkey
  • type key:key 的类型

Redis info 信息解读

在 redis-cli 中输入 info,可查询 Redis 相关信息。以下是几个比较重要的参数解读:

  • redis_version:redis 版本

  • redis_mode:redis 服务运行模式,有 standalone(单机)、sentinel(哨兵)、cluster(集群) 三种模式

  • os:系统版本

  • arch_bits:系统位数

  • gcc_version:编译时所使用的 gcc 编译器版本

  • tcp_port:运行端口

  • config_file:所使用的配置文件目录

  • used_memory:使用内存,单位为 bytes

  • used_memory_human:易于阅读的使用内存量

  • rdb_last_save_time:最近一次 rdb 方式持久化的时间戳

  • rdb_last_bgsave_status:最近一次 rdb 持久化是否成功

  • aof_enabled:AOF 方式持久化是否成功

  • total_connections_received:新创建连接个数

  • total_commands_processed:共处理命令条数

  • used_cpu_sys:内核态所占用 CPU

  • used_cpu_user:用户态所占用 CPU

  • used_cpu_sys_children:后台进程和子进程占用的内核态 CPU

  • used_cpu_user_children:后台进程和子进程占用的用户态 CPU

  • cluster_enabled:是否开启集群

MySQL 二进制安装第二版

安装

安装依赖、拉取二进制压缩包:

1
2
yum install libaio # 安装 MySQL 基础 AIO 依赖
wget -P /opt/mysql/bin https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz # 下载二进制压缩包,地址可能变动

解压缩、创建链接:

1
2
3
tar -xzvf /opt/mysql/bin/mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz -C /opt/mysql/bin
rm /opt/mysql/bin/mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz # 删除程序压缩包
ln -s /opt/mysql/bin/mysql-5.7.31-linux-glibc2.12-x86_64 /usr/local/mysql # 慎用 ln -snf

修改环境变量:

1
vim /etc/profile

添加内容如下:

1
export PATH=$PATH:/usr/local/mysql/bin

刷新环境变量:

1
source /etc/profile

查看 MySQL 版本:

1
2
3
mysql -V
# 输出:
mysql  Ver 14.14 Distrib 5.7.31, for linux-glibc2.12 (x86_64) using  EditLine wrapper

初始化

添加用户和组:

1
2
3
# 添加用户和组
groupadd mysql
useradd -r -g mysql -s /bin/false mysql

创建相关文件夹、赋权:

1
2
3
4
mkdir /opt/mysql/mysqlFiles
mkdir /opt/mysql/mysqlFiles/data
mkdir /opt/mysql/mysqlFiles/log
chown -R mysql:mysql /opt/mysql

编辑 MySQL 配置文件:

1
vim /etc/my.cnf

输入内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[client]
port=3306
socket=/tmp/mysql.sock

[mysqld]
basedir=/usr/local/mysql
datadir=/opt/mysql/mysqlFiles/data
port=3306
socket=/tmp/mysql.sock
key_buffer_size=16M
max_allowed_packet=8M

初始化,记得记录初始化命令输出的日志

1
/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize --user=mysql

启动脚本

拷贝 MySQL 的脚本:

1
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

使服务生效、允许开机启动,此步骤后可使用 servicesystemctl 命令管理 MySQL 服务:

1
chkconfig --add mysqld && chkconfig mysqld on

启动 MySQL 服务:

1
systemctl start mysqld

检查 MySQL 状态:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
systemctl status mysqld
# 以下是命令输出:
● mysqld.service - LSB: start and stop MySQL
   Loaded: loaded (/etc/rc.d/init.d/mysqld; bad; vendor preset: disabled)
   Active: active (running) since 四 2020-09-10 10:53:33 CST; 1s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 13053 ExecStop=/etc/rc.d/init.d/mysqld stop (code=exited, status=0/SUCCESS)
  Process: 13079 ExecStart=/etc/rc.d/init.d/mysqld start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/mysqld.service
           ├─13090 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/opt/mysql/mysqlFiles/data --pid-file=/opt/mysql/mysqlFiles/data/loc...
           └─13258 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/opt/mysql/mysqlFiles/data --plugin-dir=/usr/local/mys...

9月 10 10:53:32 localhost.localdomain systemd[1]: Starting LSB: start and stop MySQL...
9月 10 10:53:33 localhost.localdomain mysqld[13079]: Starting MySQL. SUCCESS!
9月 10 10:53:33 localhost.localdomain systemd[1]: Started LSB: start and stop MySQL.

使用 ps 命令查看 MySQL 进程:

1
2
3
4
ps -ef | grep mysql | grep -v grep
# 命令输出
root      13090      1  0 10:53 ?        00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/opt/mysql/mysqlFiles/data --pid-file=/opt/mysql/mysqlFiles/data/localhost.localdomain.pid
mysql     13258  13090  0 10:53 ?        00:00:02 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/opt/mysql/mysqlFiles/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=localhost.localdomain.err --pid-file=/opt/mysql/mysqlFiles/data/localhost.localdomain.pid --socket=/tmp/mysql.sock --port=3306

设置密码

初始化命令会输出一个暂用密码,比如本人密码是 9FohA-kl._p)

1
2020-09-10T02:30:26.452271Z 1 [Note] A temporary password is generated for root@localhost: 9FohA-kl._p)

使用 mysql_secure_installation 修改密码、进行安全相关设置:

 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
Securing the MySQL server deployment.

# 下面的步骤输入初始化时日志给出的暂用密码:
Enter password for user root:

The existing password for the user account root has expired. Please set a new password.
# 提示密码过期,设置一个新的 root 密码:
New password:
...
# 是否使用 VALIDATE PASSWORD 插件,用来验证密码强度的,我一般不用
VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No:
...
# 是否删除匿名用户:
Remove anonymous users? (Press y|Y for Yes, any other key for No) :
...
# 是否禁用 root 用户的远程登陆:
Disallow root login remotely? (Press y|Y for Yes, any other key for No) :
...
# 是否删除测试库以及相关权限:
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
...
# 是否立刻刷新权限表,一般选是
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y

设置完毕后即可使用新密码进行登录:

1
mysql -uroot -p

TODO

  • 修改 server 的 encoding

参考:

阶段 2 补充

MySQL 补充:常用操作和命令

mysql

连接命令

-u 指定用户名,-h 指定 ip,-P 指定端口号,-p 表示使用密码提示,-D 表示使用的数据库:

1
mysql -u root -p -h 192.168.188.130 -P 3306 -D mysql

查看 MySQL 信息

\s 命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> \s
--------------
mysql  Ver 14.14 Distrib 5.7.29, for linux-glibc2.12 (x86_64) using  EditLine wrapper

Connection id:          7
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          less
Using outfile:          ''
Using delimiter:        ;
Server version:         5.7.29-log MySQL Community Server (GPL)
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    utf8mb4
Db     characterset:    utf8mb4
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:            /usr/local/mysql/run/mysql.sock
Uptime:                 6 min 55 sec

Threads: 1  Questions: 18  Slow queries: 0  Opens: 108  Flush tables: 1  Open tables: 101  Queries per second avg: 0.043
--------------

创建用户

1
2
CREATE USER 'bolitao'@'localhost' IDENTIFIED BY 'bolitao'; -- 创建只能在本地访问,用户名和密码为 bolitao 的用户
GRANT ALL PRIVILEGES ON *.* TO 'bolitao'@'localhost' WITH GRANT OPTION; -- 将所有权限赋予用户 bolitao(即和 root 账户相同的权限)

explain 命令

sql 语句运行详情(常用于 SQL 语句调优):

1
2
3
4
5
6
7
8
mysql> explain select user, host from user where user = 'root';
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra
   |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | user  | NULL       | index | NULL          | PRIMARY | 276     | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
  • id:当 sql 语句中有子查询和关联查询时会显示多列,id 用于标志多列数据
  • select_type:表示简单查询还是复杂查询
    • SIMPLE:简单查询
    • PRIMARY:查询中包含子部分,最外层的 select 被标记为 PRIMARY
    • UNION:UNION 中的 第二个及其之后的 select 查询
    • UNION RESULT:UNION 查询的结果
    • SUBQUERY:子查询中的第一个 select
    • UNCACHEABLE SUBQUERY:未被缓存的子查询
  • table:表名,当有子查询及 UNION 时,会有中间匿名表生成
  • partitions:分区表命中的分区情况
  • type:查询类型,
    • ALL:全表扫描,最差情况
    • index:扫描索引树
    • range:有限制的索引扫描
    • fef:是一种索引访问(索引查找),它返回所有匹配某个单个值的行
    • eq_ref:索引查找,mysql最多只返回一条记录,在使用主键或者唯一索引查找时看得到
    • const、system:当MySQL对查询某部分进行优化,并转换为一个常量时出现
    • NULL:执行阶段不用访问表和索引
  • possible_keys:显示查询可以使用的索引
  • key:使用哪个索引来优化对表的访问
  • key_len:索引中使用的字节数
  • ref:显示table在key中选取的索引中查找值所用的列或者常量
  • rows:为了找到所需的行而要读取的行数
  • filtered:返回结果的行占需要读到的行(rows列的值)的百分比
  • Extra
    • Using index:将使用覆盖索引,以避免访问表
    • Using where:服务器将在存储引擎检索行后再进行过滤
    • Using temporary:查询过程使用了中间表
    • Using filesort:使用一个外部索引排序,而不是按索引的顺序读取表

mysqldump

  • 导出数据库所有数据到 /tmp/all.sql

    1
    2
    
    ➜ mysqldump -u root -p123 --all-databases >/tmp/all.sql
    mysqldump: [Warning] Using a password on the command line interface can be insecure.
    
  • 导出指定数据库:

    1
    2
    
    # 以下命令导出 csuft_sd 和 sys 库
    mysqldump -u root -p123 --databases csuft_sd sys > /tmp/spec_database_dump.sql
    
  • 导出数据库特定的表:

    1
    2
    
    # 导出 csuft_sd 库中的 role 和 user 表
    mysqldump -u root -p123 --databases csuft_sd --tables role user > /tmp/tables.sql
    
  • 导出某表中特定条件的数据:

    1
    2
    
    # 导出 user 表中 real_name 为 bolitao 的数据
    mysqldump -u root -p123 --databases csuft_sd --tables user --where='real_name="bolitao"' > /tmp/data.sql
    
  • 仅导出表结构:

    1
    2
    
    # 导出 role 和 user 的建表语句
    mysqldump -u root -pZxc7601329! --databases csuft_sd --tables role user --no-data > /tmp/no_data_tables.sql
    

ZooKeeper 补充

集群

在三台虚拟机的 ZooKeeper 数据目录建立 myid 文件,文件内容分别写入 1、2、3:

1
sudo vim /opt/zookeeper/data/myid

三台服务器的 Zookeeper 配置文件分别添加以下配置:

1
2
3
4
5
6
sudo vim /opt/zookeeper/conf/zoo.cfg

# 以下是追加的配置文件内容:
server.1=192.168.188.130:2888:3888
server.2=192.168.188.131:2888:3888
server.3=192.168.188.132:2888:3888

在三台服务器分别开放防火墙端口:

1
2
3
4
sudo firewall-cmd --zone=public --permanent --add-port=2181/tcp
sudo firewall-cmd --zone=public --permanent --add-port=2888/tcp
sudo firewall-cmd --zone=public --permanent --add-port=3888/tcp
sudo firewall-cmd --reload

在三台服务器分别开启 Zookeeper 服务:

1
sudo systemctl start zookeeper

之后查看其运行状态:

1
sudo /opt/zookeeper/bin/zkServer.sh status

可以看到 3 号机为主,1、2 号机为从:

3 号机状态:

image-20200713115553410

2 号机状态:

image-20200713115609068

1 号机状态:

image-20200713115744553

基本操作和了解

  • 连接:

    1
    
    sudo zkCli.sh -server 192.168.188.132:2181
    
  • 查看帮助:

    1
    2
    3
    4
    5
    6
    7
    8
    
    [zk: localhost:2181(CONNECTED) 0] help # 随便输入不存在的命令
    ZooKeeper -server host:port -client-configuration properties-file cmd args
            addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE
            addauth scheme auth
            close
            config [-c] [-w] [-s]
            connect host:port
    ...
    
  • 创建节点:

    1
    2
    3
    4
    5
    6
    7
    8
    
    [zk: localhost:2181(CONNECTED) 6] create /mynode hello # 普通节点
    Created /mynode
      
    [zk: localhost:2181(CONNECTED) 8] create -s /mynode2 hello # 有序节点,可以创建多个,会自动按顺序命名
    Created /mynode20000000001
      
    [zk: localhost:2181(CONNECTED) 18] create -e /temp hello # 临时节点
    Created /temp 
    
  • 列出节点:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    [zk: localhost:2181(CONNECTED) 8] ls /mynode # 列出节点
    [subnode]
      
    [zk: localhost:2181(CONNECTED) 7] ls -s /mynode # 列出节点及其状态
    [subnode]
    cZxid = 0x200000006
    ctime = Mon Jul 13 13:10:58 CST 2020
    mZxid = 0x200000006
    mtime = Mon Jul 13 13:10:58 CST 2020
    pZxid = 0x200000007
    cversion = 1
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 5
    numChildren = 1
    
  • 获取节点:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    [zk: localhost:2181(CONNECTED) 15] get /mynode
    hello
      
    [zk: localhost:2181(CONNECTED) 17] get -w /mynode # 获取 /mynode 并监听
    hello
    [zk: localhost:2181(CONNECTED) 18] set /mynode 1 # 修改 /mynode,发现 watch 发出消息
      
    WATCHER::
      
    WatchedEvent state:SyncConnected type:NodeDataChanged path:/mynode
    
  • 状态检查:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    [zk: localhost:2181(CONNECTED) 19] stat /mynode
    cZxid = 0x200000006 # 创建 node 时的 zxid
    ctime = Mon Jul 13 13:10:58 CST 2020 # 创建时间
    mZxid = 0x20000001b # 修改 node 时的 zxid
    mtime = Mon Jul 13 13:37:53 CST 2020 # 修改时间
    pZxid = 0x200000007 # 最后一次修改子节点时的 zxid
    cversion = 1 # 子节点的版本
    dataVersion = 1 # 内容版本,修改一次该节点数字都会 +1(即使 set 了相同值也会 +1)
    aclVersion = 0 # ALC 版本
    ephemeralOwner = 0x0 # 如果是临时节点,会列出其所在 zk 服务器的 session id;如不是临时节点那么这个值为 0
    dataLength = 1 # 数据长度
    numChildren = 1 # 子节点个数
    
  • 修改节点:

    1
    
    [zk: localhost:2181(CONNECTED) 24] set /mynode 123 # 将 /mynode 的值 修改为 123
    
  • 删除节点:

    1
    2
    3
    
    deleteall /mynode # 删除节点及其子节点
      
    delete /mynode # 删除节点,如存在子节点会报错:Node not empty: /xxx
    
  • 强制同步:

    1
    2
    
    [zk: localhost:2181(CONNECTED) 32] sync /mynode20000000001
    Sync is OK
    

通过 Java 命令看进程和堆栈

jps

使用 JDK 附带的 jps 命令查看运行中的 Java 程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
➜ jps -l # -l 表示显示完整的 package 名或者 jar 名
7904 sun.tools.jps.Jps
7482 org.apache.catalina.startup.Bootstrap

➜ jps -m # -m 表示查看传递给 main 的参数
7921 Jps -m
7482 Bootstrap start

➜  bin jps -v # -v 表示传输给 jvm 的详细参数
7939 Jps -Dapplication.home=/usr/lib/jvm/jdk1.8.0_251 -Xms8m
7482 Bootstrap -Djava.util.logging.config.file=/home/bolitao/apps/apache-tomcat-9.0.37/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/home/bolitao/apps/apache-tomcat-9.0.37 -Dcatalina.home=/home/bolitao/apps/apache-tomcat-9.0.37 -Djava.io.tmpdir=/home/bolitao/apps/apache-tomcat-9.0.37/temp

通常可以将这几个命令一起使用,表示查看使用该 JDK 运行的 Java 程序,并列出包名、传入 main 的参数和 jvm 详细参数:

1
2
3
➜ jps -mlv
7956 sun.tools.jps.Jps -mlv -Dapplication.home=/usr/lib/jvm/jdk1.8.0_251 -Xms8m
7482 org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/home/bolitao/apps/apache-tomcat-9.0.37/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/home/bolitao/apps/apache-tomcat-9.0.37 -Dcatalina.home=/home/bolitao/apps/apache-tomcat-9.0.37 -Djava.io.tmpdir=/home/bolitao/apps/apache-tomcat-9.0.37/temp

查看垃圾收集情况

jstat -gcutil -h 5 7482 1000:查看 pid 为 7482 的 Java 程序垃圾收集信息,-h 5 表示每五次输出一次头部标题,1000 表示每秒输出一次相关信息。

1
2
3
4
5
6
7
# 比如查看 pid 为 4542 的 Java 程序的垃圾收集情况:
➜  ~ sudo jstat -gcutil -h 5 4542 1000
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00 100.00  67.60  65.42  94.47  92.92    207  374.753    43 1032.588 1407.341
  0.00 100.00  67.60  65.42  94.47  92.92    207  374.753    43 1032.588 1407.341
  0.00 100.00  67.60  65.42  94.47  92.92    207  374.753    43 1032.588 1407.341
  0.00 100.00  67.60  65.42  94.47  92.92    207  374.753    43 1032.588 1407.341

参数解读:

  • S0:Survivor space 0 区使用比率
  • S1:Survivor space 1 区使用比率
  • E:伊甸区使用比率
  • O:老年代使用比率
  • M:元数据区使用比率
  • CCS:类指针压缩空间使用率
  • YGC:新生代 GC 次数
  • YGCT:新生代 GC 总时长
  • FGC:full GC 次数
  • FGCT:full GC 时长
  • GCT:总垃圾回收时长

查看堆栈信息

使用 jstack 命令查看 Java 进程的线程快照,使用 -l 参数还会额外输出关于锁的附加信息(对于死锁的调试比较有用)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
➜ sudo jstack -l 4542
2020-07-13 14:53:03
Full thread dump OpenJDK 64-Bit Server VM (25.252-b09 mixed mode):

"Attach Listener" #51474 daemon prio=9 os_prio=0 tid=0x00007fa328024000 nid=0x3ab5 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"logback-8" #6303 daemon prio=5 os_prio=0 tid=0x00007fa334019800 nid=0x2910 waiting on condition [0x00007fa3160df000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000e25b1f90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
...
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
        - None
...

其他 Linux 操作学习

查看网络情况

  • 查看网卡信息 ifconfig

    1
    2
    3
    4
    5
    6
    7
    8
    
    ➜  ~ ifconfig
    ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.188.130  netmask 255.255.255.0  broadcast 192.168.188.255
            ether 00:0c:29:32:3a:38  txqueuelen 1000  (Ethernet)
            RX packets 44757  bytes 14517781 (13.8 MiB) # 收到的数据包
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 26733  bytes 4783585 (4.5 MiB) # 发送的数据包
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
  • 查看网络流量:iftop

    1
    
    sudo yum install -y epel-release && sudo yum install -y iftop # 安装此软件包
    

    运行效果:

    image-20200713152055579

  • 查看某端口使用情况:

    1
    
    netstat -ntulp |grep xx # xx 为端口号
    

查看 IO 使用情况

  • 使用 iotop 工具:

    image-20200713152454089

  • 使用 df 命令查看空间情况:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    ➜  ~ sudo df
    文件系统                   1K-块      已用      可用  已用% 挂载点
    devtmpfs                  486004       0   486004    0% /dev
    tmpfs                     497840       0   497840    0% /dev/shm
    tmpfs                     497840    7856   489984    2% /run
    tmpfs                     497840       0   497840    0% /sys/fs/cgroup
    /dev/mapper/centos-root 52403200 6761420 45641780   13% /
    /dev/sda1                1038336  163360   874976   16% /boot
    /dev/mapper/centos-home 49250820 3250356 46000464    7% /home
    tmpfs                      99572       0    99572    0% /run/user/1000
      
    ➜ sudo df / # 查看根目录情况
    文件系统                   1K-块      已用      可用  已用% 挂载点
    /dev/mapper/centos-root 52403200 6761420 45641780   13% /
    

查找指定文件

  • find 命令:

    1
    2
    3
    
    ➜ find /opt/mysql -name 'my*' # 查找 /opt/mysql 目录下,名为 my 开头的文件
    /opt/mysql
    /opt/mysql/etc/my.cnf
    
  • whereis:用于搜索二进制程序:

    1
    2
    
    ➜ whereis mysql
    mysql: /usr/local/mysql /usr/share/mysql /usr/local/mysql/bin/mysql
    
  • whitch:用于搜索 PATH 中找到的第一个结果:

    1
    2
    
    ➜ which java
    /usr/lib/jvm/jdk1.8.0_251/bin/java
    

查看某个文件大小和权限

使用 ls -al xx 命令,比如:

1
2
➜ ls -al configure
-rwxrwxr-x 1 bolitao bolitao 2502 9月   5 2019 configure

以上结果可以知道该文件大小为 2502 字节,权限为 rwxrwxrx,即文件拥有者和同组有读、写、执行权限,其他用户有读和执行权限。

加载评论