如何在Ubuntu上安装MySQL / MariaDB

本教程面向Ubuntu服务器,适用于Ubuntu的任何LTS版本,包括Ubuntu 14.04,Ubuntu 16.04,Ubuntu 18.04,甚至非LTS版本(如Ubuntu 17.10和其他基于Ubuntu的发行版)。我们在Ubuntu 16.04服务器上测试了这个。

在我们开始安装MySQL / MariaDB之前

一些要求和其他说明:

当涉及LAMP堆栈中的基本用法时,MySQL和MariaDB几乎完全相同。大多数命令是相同的,即使安装也是如此。选择一个并将其安装到您的LAMP堆栈中,我们将包含两者的说明。

你需要一个Ubuntu服务器来运行MySQL/MariaDB。

您需要root用户或具有sudo访问权限的用户访问服务器。以下命令全部由root用户执行,所以我们不必为每个命令添加’sudo’。如果您使用非root用户,则可能必须执行此操作。
如果您使用的是Windows,则需要启用SSH,如果您使用Ubuntu或MobaXterm等SSH客户端。

MySQL / MariaDB可能已经安装在您的服务器上。您可以通过输入“mysql”或“mariadb”来检查它们是否已安装,并且您应该根据输出结果来了解它们。

现在就是这样。 我们来看看我们的教程。

如何在Ubuntu上安装MySQL

我们将从MySQL开始。 如果您想安装MariaDB,请跳至MariaDB说明。

更新Ubuntu
首先,像往常一样,在你做任何事之前,通过运行以下命令来更新你的Ubuntu服务器:

apt-get update && apt-get upgrade

安装MySQL
然后,通过运行以下命令安装MySQL:

apt-get install mysql-server

该命令将安装MySQL服务器和客户端。 你会得到一个提示,为你的root用户输入一个密码。

而已。 MySQL已安装。 现在,您需要保护并配置它。

安全的MySQL
你应该运行mysql_secure_installation脚本来帮助你保护你的MySQL。

使用以下命令启动脚本:

mysql_secure_installation

并回应提示。 您可以使用每个提示的默认响应。

优化MySQL(仅限高级用户)
要优化你的MySQL,你可以使用MySQLTuner脚本。 它不会为你做所有的工作。 该脚本仅向您提供如何改进和优化MySQL的建议。

使用以下命令下载并运行脚本:

curl -L http://mysqltuner.pl/ | perl

并检查建议。 做一些研究和使用谷歌每个建议。 如果你不知道自己在做什么,请联系其他人,让他们为你做,或者跳过这个。

你也可以使用mysqlcheck来修复你的数据库。 您可以使用单个命令修复所有数据库:

mysqlcheck -A –auto-repair -u root -p

还有其他的优化可以在你的服务器和数据库上完成,如果你想进一步优化MySQL,你也可以自己做一些研究。

如何在Ubuntu上安装MariaDB

现在来看我们的MariaDB安装说明。

更新Ubuntu
首先,更新你的Ubuntu服务器:

apt-get update && apt-get upgrade

添加MariaDB存储库
在您可以安装MariaDB之前,您需要添加MariaDB存储库。

根据您的Ubuntu发行版,您可能需要运行不同的命令,因此请前往官方的MariaDB存储库页面,选择您的发行版并选择离您的服务器位置最近的镜像。 然后,复制你在页面上得到的命令。 我们使用Ubuntu 16.04.1并选择了美国镜像,因此我们将运行以下命令来添加存储库:

apt-get install software-properties-common
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
add-apt-repository 'deb [arch=amd64,i386,ppc64el] https://mirrors.evowise.com/mariadb/repo/10.1/ubuntu xenial main'

接下来,您需要再次更新您的软件包列表:

apt-get update

并转到安装MariaDB。

安装MariaDB
添加MariaDB存储库后,可以通过运行以下命令来安装它:

apt-get install mariadb-server

就是这样。 你已经在服务器上安装了MariaDB。

保护MariaDB
这与MySQL的过程相同。 使用以下命令运行安全脚本:

mysql_secure_installation

并按照提示进行操作。 您可以输入每个提示的默认值。 当然,使用强密码。

优化MariaDB(仅限高级用户)
同样,与MySQL相同,您可以使用MySQLTuner检查您的MariaDB并获取有关如何改进它的建议。 它不会为你做所有的工作。 该脚本仅向您提供如何改进和优化MariaDB的建议。

运行脚本:

curl -L http://mysqltuner.pl/ | perl

并检查建议。 做一些研究和使用谷歌每个建议。 如果你不知道自己在做什么,请联系其他人,让他们为你做,或者跳过这个。

Mysqlcheck也适用于MariaDB,因此要一次优化所有MariaDB数据库,请运行以下命令:

mysqlcheck -A --auto-repair -u root -p

您可以在服务器和数据库上进行其他优化,因此如果您想进一步优化MariaDB,请自行研究.

详解Centos7扩展磁盘空间(LVM管理)

本文介绍了Centos7扩展磁盘空间(LVM管理),分享给大家,具体如下:

查看磁盘情况

# fdisk -l /dev/sda
Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00063fa6
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 1026047 512000 83 linux
/dev/sda2 1026048 20971519 9972736 8e Linux LVM
/dev/sda3 20971520 41943039 10485760 8e Linux LVM

现在,磁盘大小为 21.5 GB。磁盘占用情况为:

# df -h

Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 19G 8.1G 11G 44% /
devtmpfs 482M 0 482M 0% /dev
tmpfs 497M 88K 497M 1% /dev/shm
tmpfs 497M 7.0M 490M 2% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/sda1 497M 157M 341M 32% /boot
Share 103G 36G 67G 35% /media/sf_Share
tmpfs 100M 4.0K 100M 1% /run/user/42
tmpfs 100M 12K 100M 1% /run/user/0

试试看用 dd 命令创建一个大小为 1GB 的块文件:

# dd if=/dev/zero of=1.0G.img bs=1M count=1000
dd: writing `1.0G.img': No space left on device
1+0 records in
0+0 records out
8192 bytes (8.2 kB) copied, 0.00300509 s, 2.7 MB/s

提示磁盘空间不足,说明,虽然已给虚拟机分配了足够的空间,但是系统并不识别该空间。

下面调整虚拟机操作系统的文件系统,使之识别新增的空间

1、创建新的分区

# fdisk /dev/sda
n {new partition}
p {primary partition}
3 {partition number}
[这时会提示修改大小,选择默认直接回车即可]
t {change partition id}
3 {partition number}
8e {Linux LVM partition}
w

如果中间有设置大小之类的提示,就直接回车。

完成后,如果提示:
PS:经实际测试,无此提示,但还是要重启系统,看看是否已识别该磁盘空间。

WARNING: Re-reading the partition table failed with error 16: 设备或资源忙. The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8)

就重启一下系统。

2、查看新增加的sda3是否标记为LVM,如果没有需要reboot
PS:经实际测试,sda3已经是LVM了,但系统还是不识别该磁盘空间。

3、调整LVM大小

查看Volume Group名称

# vgdisplay
--- Volume group ---
VG Name centos
System ID 
Format lvm2

4、为新分配的空间创建一个新的物理卷

#pvcreate /dev/sda3

5、使用新的物理卷来扩展 LVM 的 VolGroup

# vgextend centos /dev/sda3
No physical volume label read from /dev/sda3
Writing physical volume data to disk "/dev/sda3"
Physical volume "/dev/sda3" successfully created
Volume group "vg_aimin" successfully extended

6、扩展 LVM 的逻辑卷 centos-root

先查看逻辑卷:

# lvdisplay
--- Logical volume ---
LV Path /dev/centos/root
LV Name root
VG Name centos
# lvextend /dev/centos/root /dev/sda3

7、调整逻辑卷的大小

# xfs_growfs /dev/centos/root

PS:不知道是调整还是同步,经实际测试需要用xfs_growfs命令,而非resize2fs命令

8、查看结果

# lvscan
ACTIVE '/dev/centos/root' [18.46 GiB] inherit
ACTIVE '/dev/centos/swap' [1.00 GiB] inherit

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

如何在 MariaDB 中配置主从复制?

未分类

复制是用于为我们的数据库创建多个副本,这些副本可以在其它数据库上用于运行查询,像一些非常繁重的查询可能会影响主数据库服务器的性能,或者我们可以使用它来做数据冗余,或者兼具以上两个目的。我们可以将这个过程自动化,即主服务器到从服务器的复制过程自动进行。执行备份而不影响在主服务器上的写操作。

在我们前面的教程中,我们已经学习了如何安装与配置MariaDB,也学习了 管理 MariaDB 的一些基础命令。现在我们来学习,如何在 MariaDB 服务器上配置一个主从复制。
复制是用于为我们的数据库创建多个副本,这些副本可以在其它数据库上用于运行查询,像一些非常繁重的查询可能会影响主数据库服务器的性能,或者我们可以使用它来做数据冗余,或者兼具以上两个目的。我们可以将这个过程自动化,即主服务器到从服务器的复制过程自动进行。执行备份而不影响在主服务器上的写操作。

因此,我们现在去配置我们的主-从复制,它需要两台安装了 MariaDB 的机器。它们的 IP 地址如下:

  • 主服务器 – 192.168.1.120 主机名 – master.ltechlab.com
  • 从服务器 – 192.168.1.130 主机名 – slave.ltechlab.com

MariaDB 安装到这些机器上之后,我们继续进行本教程。如果你需要安装和配置 MariaDB 的教程,请查看以前的教程。

第 1 步 – 主服务器配置

我们现在进入到 MariaDB 中的一个命名为 important 的数据库,它将被复制到我们的从服务器。为开始这个过程,我们编辑名为 /etc/my.cnf 的文件,它是 MariaDB 的配置文件。

$ vi /etc/my.cnf

在这个文件中找到 [mysqld] 节,然后输入如下内容:

[mysqld]
log-bin
server_id=1
replicate-do-db=important
bind-address=192.168.1.120

保存并退出这个文件。完成之后,需要重启 MariaDB 服务。

$ systemctl restart mariadb

接下来,我们登入我们的主服务器上的 Mariadb 实例。

$ mysql -u root -p

在它上面创建一个命名为 slaveuser 的为主从复制使用的新用户,然后运行如下的命令为它分配所需要的权限:

STOP SLAVE;
GRANT REPLICATION SLAVE ON *.* TO  'slaveuser'@'%' IDENTIFIED BY 'iamslave';
FLUSH PRIVILEGES;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

注意: 我们配置主从复制需要 MASTER_LOG_FILE 和 MASTER_LOG_POS 的值,它可以通过 show master status 来获得,因此,你一定要确保你记下了它们的值。

这些命令运行完成之后,输入 exit 退出这个会话。

第 2 步 – 创建一个数据库备份,并将它移动到从服务器上

现在,我们需要去为我们的数据库 important 创建一个备份,可以使用 mysqldump 命令去备份。

$ mysqldump -u root -p important > important_backup.sql

备份完成后,我们需要重新登录到 MariaDB 数据库,并解锁我们的表。

$ mysql -u root -p
$ UNLOCK TABLES;

然后退出这个会话。现在,我们移动我们刚才的备份到从服务器上,它的 IP 地址是:192.168.1.130。
在主服务器上的配置已经完成了,现在,我们开始配置从服务器。

第 3 步:配置从服务器

我们再次去编辑(从服务器上的) /etc/my.cnf 文件,找到配置文件中的 [mysqld]节,然后输入如下内容:

[mysqld]
server-id = 2
replicate-do-db=important
[ …]

现在,我们恢复我们主数据库的备份到从服务器的 MariaDB 上,运行如下命令:

$ mysql -u root -p < /data/ important_backup.sql

当这个恢复过程结束之后,我们将通过登入到从服务器上的 MariaDB,为数据库 important 上的用户 ‘slaveuser’ 授权。

$ mysql -u root -p
GRANT ALL PRIVILEGES ON important.* TO 'slaveuser'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;

接下来,为了这个变化生效,重启 MariaDB。

$ systemctl restart mariadb

第 4 步:启动复制

记住,我们需要 MASTER_LOG_FILE 和 MASTER_LOG_POS 变量的值,它可以通过在主服务器上运行 SHOW MASTER STATUS 获得。现在登入到从服务器上的 MariaDB,然后通过运行下列命令,告诉我们的从服务器它应该去哪里找主服务器。

STOP SLAVE;
CHANGE MASTER TO MASTER_HOST= '192.168.1.110′, MASTER_USER='slaveuser', MASTER_PASSWORD='iamslave', MASTER_LOG_FILE='mariadb-bin.000001′, MASTER_LOG_POS=460;
SLAVE START;
SHOW SLAVE STATUSG;

注意: 请根据你的机器的具体情况来改变主服务器的配置。

第 5 步:测试复制

我们将在我们的主服务器上创建一个新表来测试主从复制是否正常工作。因此,登入到主服务器上的 MariaDB。

$ mysql -u root -p

选择数据库为 important:

use important;

在这个数据库上创建一个名为 test 的表:

create table test (c int);

然后在这个表中插入一些数据:

insert into test (c) value (1);

检索刚才插入的值是否存在:

select * from test;

你将会看到刚才你插入的值已经在这个新建的表中了。
现在,我们登入到从服务器的数据库中,查看主从复制是否正常工作。

$ mysql -u root -p
$ use important;
$ select * from test;

你可以看到与前面在主服务器上的命令输出是一样的。因此,说明我们的主从服务工作正常,没有发生任何问题。

我们的教程结束了,请在下面的评论框中留下你的查询/问题。

Nginx访问频率控制

HTTP服务器的吞吐率(单位时间吞吐量)通常有一个上限,尤其是普通配置的机器,在带宽够的情况下,用压测工具经常能把服务器压出翔,为了线上环境稳定性,防止恶意攻击影响到其他用户,可选择对客户端访问频率进行合理限制。

限制原理

限制原理并不难,可一句话概括为:“根据客户端特征,限制其访问频率”,客户端特征主要指IP、UserAgent等。使用IP比UserAgent更可靠,因为IP无法造假,UserAgent可随意伪造。

虽然IP无法造假,但恶意人员可以利用代理,因此仅依靠限制IP访问频率并不能应对大量代理的情况,另外在限制IP访问频率时也要考虑多用户共享网络出口的情况,比如校园网、企业局域网网络之类。

实践

由于存在盲区,不知道Nginx中有访问控制模块,想着自己在应用代码中使用Redis实现基于IP的访问频率控制,在准备写代码之前发现Nginx有limit_req模块可限制基于IP的访问频率,因此选择Nginx,这肯定比自己实现更省事,性能也更优秀。

limit_req_zone

Syntax:  limit_req_zone key zone=name:size rate=rate;
Default: —
Context: http
  • key,表示作为限制的请求特征,可以包含文本与变量,IP场景使用$binary_remote_addr
  • name,zone的名称,limit_req会用到
  • size,zone的大小,1M大小在64位系统可存储8000个state(ip、count…),每次添加新state时,可能删除至多两个前60秒未使用的- state,若添加新state时zone大小不够,则删除较旧的state,释放空间后依旧不够返回503
  • rate,访问速率,支持秒或者分钟为单位,但nginx内部使用毫秒追踪请求数,如果限制是10r/1s,实际上是1r/100ms

limit_req

Syntax:  limit_req zone=name [burst=number] [nodelay];
Default: —
Context: http, server, location
  • name,limit_req_zone中配置的名称
  • burst,可理解为缓冲卡槽,如果设置则所有请求都经由缓冲卡槽转发给upstream,通常可并发接收的请求数为number + 1,但当number为0时会拒绝所有请求
  • nodelay,缓冲卡槽中请求转发给upstream的时机,不设置时,会按照zone的速率逐个转发,当设置为nodelay时,请求到达缓冲卡槽后会立即转发给upstream,但卡槽中的占位依旧按照频率释放

配置

理解limit_req_zone与limit_req之后,感叹这真是个好设计,也知道它背后的形象的名称:漏桶算法。

了解配置方式后开始实际操作,在Nginx配置中的http内添加:

limit_req_zone $binary_remote_addr zone=one:2m rate=10r/s;

在需要限制的server内添加:

limit_req zone=one burst=10 nodelay;

按照官方文档,2M大小在64位系统中大约可存储16000个状态数据,针对自己的个人网站足够,10r/s即1r/100ms,配合burst=10应该也OK,重启Nginx,然后使用压测工具检验一下。

rate、burst、nodelay的不同特点:

排除其他因素,rate的大小针对同一客户端的平均吞吐率起到决定性作用,而burst与nodelay可根据业务需求选择,burst越大可接收的并发请求越多,但rate跟不上可能导致大量客户端请求超时,nodelay在rate较小时可以提升业务在瞬时的吞吐率表现

白名单

之所以会限制IP访问频率,主要是为了阻止外部调用者的恶意行为,但经过上述配置后,对系统内部调用者同样会有所限制,因此我们希望将内部调用者列入白名单内,使其不受访问频率限制。

这主要借助Nginx中的geo与map功能,通过geo将IP映射成值,然后再通过map将值映射成变量或常量,恰好limit_req_zone中如果key为”表示不对其进行频率限制,所以只需要将白名单用户的key设置为”。

修改配置文件中http的内容:

geo $limit {
    default 1;
    127.0.0.1 0;     # 本机地址
    172.31.0.0/16 0; # 内网地址
}

map $limit $limit_key {
    0 "";
    1 $binary_remote_addr;
}

limit_req_zone $limit_key zone=one:2m rate=10r/s;

总结

至此,根据IP限制访问频率配置完成,Nginx中与limit_req类似的还有limit_conn,可用来在连接层面进行限制,同时针对limit_req还有两个配置项limit_req_status与limit_req_log_level,前者用来设置达到限制时返回何种状态码,后者制定达到限制时的日志采用何种级别,会导致达到限制的信息出现在不同的日志文件中。

从打算自己实现,到使用Nginx实现,感觉自己的对服务器的理解还需要提升,应该从合理性角度就可以推断出Nginx包含该类功能,而不是在搜索的过程中发现Nginx包含该功能。

如何使用 fail2ban 防御 SSH 服务器的暴力破解攻击

对于SSH服务的常见的攻击就是暴力破解攻击——远程攻击者通过不同的密码来无限次地进行登录尝试。当然SSH可以设置使用非密码验证验证方式来对抗这种攻击,例如公钥验证或者双重验证。将不同的验证方法的优劣处先放在一边,如果我们必须使用密码验证方式怎么办?你是如何保护你的 SSH 服务器免遭暴力破解攻击的呢?

未分类

fail2ban 是 Linux 上的一个著名的入侵保护的开源框架,它会监控多个系统的日志文件(例如:/var/log/auth.log 或者 /var/log/secure)并根据检测到的任何可疑的行为自动触发不同的防御动作。事实上,fail2ban 在防御对SSH服务器的暴力密码破解上非常有用。

在这篇指导教程中,我会演示如何安装并配置 fail2ban 来保护 SSH 服务器以避免来自远程IP地址的暴力攻击。

在linux上安装Fail2ban

为了在CentOS 或 RHEL上安装fail2ban,首先设置EPEL仓库,然后运行以下命令。

$ sudo yum install fail2ban

在Fedora上安装fail2ban,简单地运行以下命令:

$ sudo yum install fail2ban

在ubuntu,Debian 或 Linux Mint上安装fail2ban:

$ sudo apt-get install fail2ban

为SSH服务器配置Fail2ban

现在你已经准备好了通过配置 fail2ban 来加强你的SSH服务器。你需要编辑其配置文件 /etc/fail2ban/jail.conf。 在配置文件的“[DEFAULT]”区,你可以在此定义所有受监控的服务的默认参数,另外在特定服务的配置部分,你可以为每个服务(例如SSH,Apache等)设置特定的配置来覆盖默认的参数配置。

在针对服务的监狱区(在[DEFAULT]区后面的地方),你需要定义一个[ssh-iptables]区,这里用来定义SSH相关的监狱配置。真正的禁止IP地址的操作是通过iptables完成的。

下面是一个包含“ssh-iptables”监狱配置的/etc/fail2ban/jail.conf的文件样例。当然根据你的需要,你也可以指定其他的应用监狱。

$ sudo vi /etc/fail2ban/jail.local
[DEFAULT]
# 以空格分隔的列表,可以是 IP 地址、CIDR 前缀或者 DNS 主机名
# 用于指定哪些地址可以忽略 fail2ban 防御
ignoreip = 127.0.0.1 172.31.0.0/24 10.10.0.0/24 192.168.0.0/24

# 客户端主机被禁止的时长(秒)
bantime = 86400

# 客户端主机被禁止前允许失败的次数 
maxretry = 5

# 查找失败次数的时长(秒)
findtime = 600

mta = sendmail

[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, [email protected], [email protected]]
# Debian 系的发行版 
logpath = /var/log/auth.log
# Red Hat 系的发行版
logpath = /var/log/secure
# ssh 服务的最大尝试次数 
maxretry = 3

根据上述配置,fail2ban会自动禁止在最近10分钟内有超过3次访问尝试失败的任意IP地址。一旦被禁,这个IP地址将会在24小时内一直被禁止访问 SSH 服务。这个事件也会通过sendemail发送邮件通知。

一旦配置文件准备就绪,按照以下方式重启fail2ban服务。

在 Debian, Ubuntu 或 CentOS/RHEL 6:

$ sudo service fail2ban restart

在 Fedora 或 CentOS/RHEL 7:

$ sudo systemctl restart fail2ban

为了验证fail2ban成功运行,使用参数’ping’来运行fail2ban-client 命令。 如果fail2ban服务正常运行,你可以看到“pong(嘭)”作为响应。

$ sudo fail2ban-client ping
Server replied: pong

测试 fail2ban 保护SSH免遭暴力破解攻击

为了测试fail2ban是否能正常工作,尝试通过使用错误的密码来用SSH连接到服务器模拟一个暴力破解攻击。与此同时,监控 /var/log/fail2ban.log,该文件记录在fail2ban中发生的任何敏感事件。

$ sudo tail -f /var/log/fail2ban.log

未分类

根据上述的日志文件,Fail2ban通过检测IP地址的多次失败登录尝试,禁止了一个IP地址192.168.1.8。

检查fail2ban状态并解禁被锁住的IP地址

由于fail2ban的“ssh-iptables”监狱使用iptables来阻塞问题IP地址,你可以通过以下方式来检测当前iptables来验证禁止规则。

$ sudo iptables --list -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-SSH  tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-SSH (1 references)
target     prot opt source               destination
DROP       all  --  192.168.1.8          0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

如果你想要从fail2ban中解锁某个IP地址,你可以使用iptables命令:

$ sudo iptables -D fail2ban-SSH -s 192.168.1.8 -j DROP

当然你可以使用上述的iptables命令手动地检验和管理fail2ban的IP阻塞列表,但实际上有一个适当的方法就是使用fail2ban-client命令行工具。这个命令不仅允许你对”ssh-iptables”监狱进行管理,同时也是一个标准的命令行接口,可以管理其他类型的fail2ban监狱。

为了检验fail2ban状态(会显示出当前活动的监狱列表):

$ sudo fail2ban-client status

为了检验一个特定监狱的状态(例如ssh-iptables):

$ sudo fail2ban-client status ssh-iptables

上面的命令会显示出被禁止IP地址列表。

未分类

为了解锁特定的IP地址:

$ sudo fail2ban-client set ssh-iptables unbanip 192.168.1.8

未分类

注意,如果你停止了Fail2ban 服务,那么所有的IP地址都会被解锁。当你重启 Fail2ban,它会从/etc/log/secure(或 /var/log/auth.log)中找到异常的IP地址列表,如果这些异常地址的发生时间仍然在禁止时间内,那么Fail2ban会重新将这些IP地址禁止。

设置 Fail2ban 自动启动

一旦你成功地测试了fail2ban之后,最后一个步骤就是在你的服务器上让其在开机时自动启动。在基于Debian的发行版中,fail2ban已经默认让自动启动生效。在基于Red-Hat的发行版中,按照下面的方式让自动启动生效。

在 CentOS/RHEL 6中:

$ sudo chkconfig fail2ban on

在 Fedora 或 CentOS/RHEL 7:

$ sudo systemctl enable fail2ban

总结

在该教程中,我演示了如何安装并配置fail2ban来保护一个SSH服务器。当然fail2ban可以缓解暴力密码攻击,但是请注意,这并不能保护SSH服务器避免来自复杂的分布式暴力破解组织,这些攻击者通过使用成千上万个机器控制的IP地址来绕过fail2ban的防御机制。

Mysql/Mariadb备份(xtrabackup)还原实战

一、概述

之前的文章说到mysql的安装与mysql的基本使用;本文是后续补充,主要说明针对mysql或mariadb的备份与还原;众所周知,数据是重中之重,因此平时对企业数据需要做备份,当数据系统崩溃,数据丢失异常时,才能依据备份文件进行恢复!

本次的环境:
CentOS7.4_x64 , mysql5.7.21, xtrabackup

mysql的安装配置可参考之前系列文章;只补充相关配置项的开启;以及xtrabackup安装使用;
用到的演示数据导入mysql数据库

[root@db ~]# mysql -uroot -predhat < testdb.sql
或
mysql> source   testdb.sql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| example            |
| mysql              |
| performance_schema |
| study              |
| sys                |
以上study即为测试数据库包含以下测试表

mysql> show tables;
+-----------------+
| Tables_in_study |
+-----------------+
| class           |
| course          |
| part            |
| score           |
| student         |
| tb31            |
| tb32            |
| teacher         |
| test1           |
| test2           |
| user_info       |
+-----------------+

测试数据库及数据表准备完成,在进行数据的备份与恢复前,我们先简单了解下数据库备份与恢复的相关概念原理;

关于数据库的备份与还原

为什么备份?
主要是为了灾难恢复如:硬件故障(冗余)、软件故障(bug)、自然灾害、黑客攻击、误操作、以及测试需要导出数据等;
还原或叫恢复时即基于以往的备份文件;

备份类型

全量备份、增量备份、差异备份:
完全备份: 备份数据的副本(某时间点);
增量备份:仅备份自上一次完全备份或 增量备份以来变量的那部数据;
差异备份:仅备份自上一次完全备份以来变量的那部数据;

物理备份、逻辑备份:
物理备份:复制数据文件进行的备份;
逻辑备份:从数据库导出数据另存在一个或多个文件中;

根据数据服务是否在线:
热备:读写操作均可进行的状态下所做的备份;
温备:可读但不可写状态下进行的备份;
冷备:读写操作均不可进行的状态下所做的备份
以上的各备份类型备份执行时只能备份数据在备份时的状态,如想要恢复数据库崩溃那一刻的状态,需要打开binary log功能,需要基于备份的数据+binary log来恢复到数据崩溃前一刻的状态;
备份的工具有mysqldump(温备,不适合大型数据的在线备份),xtrabackup(支持对InnoDB热备,开源专业的备份数据,支持mysql/mariadb)本文将通过mysqldump与xtrabackup来说明数据的备份与恢复(异地);

无论那种工具备份,在恢复时均要binary log才能恢复到崩溃前的状态;因此需要配置数据库开启binary log功能;以下能mysql5.7.21

#cat /usr/local/mysql/etc/my.cnf
server-id       = 1
log_bin         = /data1/mysqldb/mysql-bin.log

二、mysqldump备份与恢复

mysqldump使用说明

单进程逻辑备份、完全备份、部分备份;

Usage: 
mysqldump [OPTIONS] database [tables]
         OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
         OR     mysqldump [OPTIONS] --all-databases [OPTIONS]

mysqldump mydb:表级别备份(还原时库需要存在)
mysqldump --databases mydb:库级别备份(库不在会自行创建库)

MyISAM存储引擎:支持温备,备份时要锁定表;
         -x, --lock-all-tables:锁定所有库的所有表,读锁;
         -l, --lock-tables:锁定指定库所有表;

InnoDB存储引擎:支持温备和热备;
         -x, --lock-all-tables:锁定所有库的所有表,读锁;
         -l, --lock-tables:锁定指定库所有表;
        --single-transaction:创建一个事务,基于此快照执行备份;
                -R, --routines:存储过程和存储函数;
                --triggers      触发器
                -E, --events      事件

                 --master-data[=#]
                        1:记录为CHANGE MASTER TO语句,此语句不被注释;
                        2:记录为CHANGE MASTER TO语句,此语句被注释;

                --flush-logs:锁定表完成后,即进行日志刷新操作(重新生成binlog日志);

基于mysqldump备份study数据库

热备,备份存储过程和存储函数,事件,并记得下事件位置;(便于从binlog中的位置开始恢复到故障前)
#mysqldump -uroot -predhat --single-transaction  -R -E --triggers --master-data=2 --databases study >/home/san/studydb.sql

说明:

less studydb.sql

会看到以下内容

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=154;

这就是–master-data=2 选项作用,注释了,binary log 点在154

模拟备份后数据修改操作

修改前的:
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   20 | 男     |        1 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)
增加一条:
mysql> insert into user_info values(13,'hi',18,'男',4);
Query OK, 1 row affected (0.03 sec)
删除一条:
mysql> delete  from user_info where nid=1;
Query OK, 1 row affected (0.01 sec)
最终在上次备份后user_info数据如下:
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)
可以看出少了一条,加了一条;

模拟数据库损坏并恢复study数据库

关闭mysql并到数据目录删除study数据库;

假设发现study数据已经丢失了;

数据库运行正常;查看binlog位置
mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       815 |
| mysql-bin.000002 |       177 |
| mysql-bin.000003 |       177 |
| mysql-bin.000004 |   1890875 |
| mysql-bin.000005 |       725 |
+------------------+-----------+
记住这里最后一个binlog文件及位置是mysql-bin.000005   725
结合上面备份文件中的-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=154; 可以分析出备份时位置是154而数据库丢失前是725
因此我们恢复study数据库里需要恢复上次的全备+加mysql-bin.000005中的154-725内容;

模拟study丢失过程(传说溃的删库路)
[root@db mysqldb]# service stop mysqld
[root@db mysqldb]# pwd
/data1/mysqldb
[root@db mysqldb]# rm -rf  study/
启动数据库
[root@db mysqldb]# service stop mysqld
登录数据库并查看发现study数据库已经丢失了

还原数据库

mysql -uroot -predhat < studydb.sql
mysql> show databases;
可发现已经恢复;但是之前完整备份的到崩溃前的修改不见了;如下:
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   20 | 男     |        1 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)

结合binlog恢复:

从binlog上导出sql文件
[root@db mysqldb]# mysqlbinlog mysql-bin.000005 >/root/binlog.sql
登录mysql恢复
恢复过程中临时关闭binlog记录
mysql> set @@session.sql_log_bin=OFF;
mysql> source binlog.sql;
Query OK, 0 rows affected (0.00 sec

mysql> set @@session.sql_log_bin=ON;
mysql> use study; 
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
+-----+-------+------+--------+----------+
11 rows in set (0.00 sec)

可以看出study数据库已经恢复到崩溃损坏前的状态;另外完全 可以新准备一台数据库服务器;把sql转移到新机器上恢复;前提数据配置参数需要一样;

三、xtrabackup备份与恢复

xtrabackup简介

xtrabackup是Percona一款开源工具,支持innodb,Xtradb(mariadb)引擎数据库的热备;
对MyISAM:温备,不支持增量备份;InnoDB:热备,增量;
物理备份,速率快、可靠;备份完成后自动校验备份结果集是否可用;还原速度快
功能介绍与Innobackup(mysql企业版收费)对比参考官网
所数据库引擎请使用innodb引擎

xtrabackup安装与使用说明

安装
[官方下载地址](https://www.percona.com/downloads/XtraBackup/LATEST/)
本次使用percona-xtrabackup-24-2.4.8-1
[root@db ~]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.8/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.8-1.el7.x86_64.rpm
[root@db ~]# yum install ./percona-xtrabackup-24-2.4.8-1.el7.x86_64.rpm -y

**获取帮助与使用:**
可以通过man  xtrabackup 获取详细使用说明与实例
Usage: 
 innobackupex [--defaults-file=#] --backup | innobackupex [--defaults-file=#] --prepare] [OPTIONS]
 备份用到的主要选项:
    --defaults-file=     #mysql或mariadb配置文件
        --user=                  #备份时使用的用户(对备份的数据库有备份权限)
        --password=         #备份用户密码
        -H | --host=            #localhost或远程主机

**恢复时到的主要选项:**
        --apply-log         #分析获取binary log文件生成backup_binlog_info文件
        ---copy-back      #基于backup_binlog_info等文件恢复
注:innobackupex是xtrabackup的软件链接;

xtrabackup全备与恢复:

注意:备份时数据库是在线状态;恢复时需要离线并且mysql数据目录为空;
备份:

创建备份目录 
mkdir -pv /data/backup
创建备份授权账号root(可以是其他用户最小权限)
mysql> GRANT ALL ON *.* TO 'root'@'127.0.0.1' identified by "redhat";
Query OK, 0 rows affected, 1 warning (0.00 sec)

[root@db mysqldb]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --user=root --password=redhat  --host=127.0.0.1 /data/backup
看到类似如下信息表示备份成功:
xtrabackup: Transaction log of lsn (7701576) to (7701585) was copied.
180401 11:52:35 completed OK!
同时在/data/backup目录中产生以时间为目录的备份目录
[root@db backup]# ll /data/backup/
drwxr-x--- 14 root root 4096 4月   1 11:52 2018-04-01_11-52-29

备份后对数据库study 中的表进行修改

删除student表
mysql> drop table student;
Query OK, 0 rows affected (0.04 sec)
往user_info表中插入两行
mysql> insert into user_info values(1,"san",18,"男",4),(14,"Hello",28,"女",2);
Query OK, 1 row affected (0.00 sec)

模拟数据库崩溃

注意binlog文件备份好;如果binglog和数据目录在一起
[root@db backup]# service mysqld stop
[root@db backup]# rm -rf /data1/mysqldb/*

恢复数据:

切换到备份数据目录
[root@db backup]# cd /data/backup/2018-04-01_11-52-29
事务回滚不提交
[root@db 2018-04-01_11-52-29]# innobackupex  --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log ./
类似以下提示表示完成:
InnoDB: Shutdown completed; log sequence number 7702056
180401 12:13:40 completed OK!

数据还原

由于centos7默认有/etc/my.cnf文件
因此需要重命名my.cnf或移除以免影响恢复;
[root@db 2018-04-01_11-52-29]# innobackupex  --defaults-file=/usr/local/mysql/etc/my.cnf --copy-back ./
类似以下提示表示恢复完成:
180401 12:16:15 [01]        ...done
180401 12:16:15 completed OK!

恢复binlog中信息

查看全备中的binlog信息(文件和位置)

[root@db backup]# cat /data/backup/2018-04-01_11-52-29/xtrabackup_binlog_info
mysql-bin.000008        14775
由引可知在上次全备时的binglog文件是mysql-bin.000008位置为14775
获取binlog信息
[root@db backup]# mysqlbinlog -j 14775 mysql-bin.000008 >/data/backup/binlog.sql
还原binlog中的内容(全备后的修改数据内容)
切换到mysql数据目录(/data1/mysqldb)并修改权限
[root@db mysqldb]# cd /data1/mysqldb
[root@db mysqldb]# chown mysql.mysql *  -R
启动mysql
[root@db mysqldb]# service mysqld start

登录数据库并导入binlog.sql

mysql> source /data/backup/binlog.sql
Query OK, 0 rows affected (0.00 sec)

mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   18 | 男     |        4 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  10 | e     |   22 | 男     |        3 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
|  14 | Hello |   28 | 女     |        2 |
+-----+-------+------+--------+----------+
13 rows in set (0.00 sec)

xtrabackup 增量备份与恢复

备份流程:
首次增量备份是基于完整备份后做的增量备份 ,后面的增量备份将基于前一次增量备份;
恢复流程:
合并完整备份事务 –>再合并第一次增量的事务–>….最后一次增量备份 +binlog日志

完整备份:

[root@db ~# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --user=root --password=redhat  --host=127.0.0.1 /data/backup
提示类似如下信息完成 :
xtrabackup: Transaction log of lsn (7802468) to (7802477) was copied.
180401 13:13:13 completed OK!
[root@db ~# ll /data/backup
2018-04-01_13-13-10    ######完整备份目录

模拟数据库的修改操作

删除第10行并新增一行
mysql> delete from user_info where nid=10;
Query OK, 1 row affected (0.01 sec)

mysql> insert into user_info value(15,'hehe',22,'男',1);
Query OK, 1 row affected (0.01 sec)

第一次增量备份

[root@db ~# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --incremental --user=root --password=redhat  --host=127.0.0.1 /data/backup/ --incremental-basedir=/data/backup/2018-04-01_13-13-10/
提示类似如下信息完成 :
xtrabackup: Transaction log of lsn (7803424) to (7803433) was copied.
180401 13:17:26 completed OK!

再次模拟数据库的修改操作

mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   18 | 男     |        4 |
|   2 | dong  |   29 | 男     |        2 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
|  14 | Hello |   28 | 女     |        2 |
|  15 | hehe  |   22 | 男     |        1 |
+-----+-------+------+--------+----------+
13 rows in set (0.01 sec)
插入一行再删除一行
mysql> insert into user_info value(16,'haha',21,'女',3);
Query OK, 1 row affected (0.01 sec)

mysql> delete from user_info where nid=2;
Query OK, 1 row affected (0.01 sec)
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name  | age  | gender | part_nid |
+-----+-------+------+--------+----------+
|   1 | san   |   18 | 男     |        4 |
|   4 | Ling  |   28 | 男     |        4 |
|   5 | ling  |   28 | 男     |        3 |
|   6 | dong  |   30 | 男     |        1 |
|   7 | b     |   11 | 女     |        1 |
|   8 | c     |   12 | 女     |        1 |
|   9 | d     |   18 | 女     |        4 |
|  11 | f     |   23 | 男     |        2 |
|  12 | dongy |   22 | 男     |        1 |
|  13 | hi    |   18 | 男     |        4 |
|  14 | Hello |   28 | 女     |        2 |
|  15 | hehe  |   22 | 男     |        1 |
|  16 | haha  |   21 | 女     |        3 |
+-----+-------+------+--------+----------+
13 rows in set (0.00 sec)

第二次增量备份:

[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --incremental --user=root --password=redhat  --host=127.0.0.1 /data/backup/ --incremental-basedir=/data/backup/2018-04-01_13-17-21/
注意:这里的 --incremental-basedir=/data/backup/2018-04-01_13-17-21/ 是上一次增量备份 产生的备份 目录 
如果基于第一次完整备份 则成为差异备份 

找出最近一次增量备份的binlog文件及信息

cd /data/backup/2018-04-01_13-21-56
[root@db 2018-04-01_13-21-56]# cat xtrabackup_binlog_info 
mysql-bin.000001    17452
备份 mysql-bin.000001 到/data/backup中
[root@db backup]# cd /data/backup
[root@db backup]# cp /data1/mysqldb/mysql-bin.000001 .
[root@db backup]# mysqlbinlog mysql-bin.000001 >binlog.sql

模拟数据库崩溃数据丢失

[root@db backup]# service mysqld stop
[root@db backup]# rm -rf /data1/mysqldb/*

数据恢复

[root@n1 backup]# ls
2018-04-01_13-13-10     2018-04-01_13-17-21    2018-04-01_13-21-56     binlog.sql    mysql-bin.000001

依次是完全整备份 ,第一次和第二次增量备份 目录 ,以及备份出来的binlog文件与binlog.sql
恢复过程:
首先对第1个(完整备份)合并只提交事务不回滚 再把第2个目录合并提交事务不回滚到第一个,再把第3个合并到第1个中;最后做一次回滚,再做统一事务提交;最后再加binlog恢复

完整备份 的事务合并
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log --redo-only 2018-04-01_13-13-10/
合并第一次增量事务
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log --redo-only 2018-04-01_13-13-10/ --incremental-dir=2018-04-01_13-17-21/
合并第二次增量事务
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf --apply-log --redo-only 2018-04-01_13-13-10/ --incremental-dir=2018-04-01_13-21-56/
合并所有的事务
[root@db backup]# innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf  --apply-log 2018-04-01_13-13-10/
提交还原事务
[root@db backup] innobackupex --defaults-file=/usr/local/mysql/etc/my.cnf  --copy-back 2018-04-01_13-13-10/

修改还原数据权限与启动数据库:

[root@db backup]chown mysq.mysql /data1/mysqldb -R
[root@db backup] systemctl start mysqld

binlog事务恢复

mysql> source /data/backup/binlog.sql
mysql> select * from user_info;
+-----+-------+------+--------+----------+
| nid | name | age | gender | part_nid |
+-----+-------+------+--------+----------+
| 1 | san | 18 | 男 | 4 |
| 4 | Ling | 28 | 男 | 4 |
| 5 | ling | 28 | 男 | 3 |
| 6 | dong | 30 | 男 | 1 |
| 7 | b | 11 | 女 | 1 |
| 8 | c | 12 | 女 | 1 |
| 9 | d | 18 | 女 | 4 |
| 11 | f | 23 | 男 | 2 |
| 12 | dongy | 22 | 男 | 1 |
| 13 | hi | 18 | 男 | 4 |
| 14 | Hello | 28 | 女 | 2 |
| 15 | hehe | 22 | 男 | 1 |
| 16 | haha | 21 | 女 | 3 |
+-----+-------+------+--------+----------+
13 rows in set (0.00 sec)

到此增量备份 与恢复 已经 完成!

总结

日常数据库的备份是十分有必要的,而且不管用什么方法恢复,开启binary log十分重要,否则恢复不完整;binary log最好不要和数据目录一起,另外建议数据目录和binary log所在目录不要放在同一块物理磁盘;同时需要计划备份并实现异地备份;这样出现删库跑或崩溃数据丢失时就不怕了!本文很多步骤,可能存在遗漏之处,如有错误之处,欢迎指点。

记录分享两个 MariaDB 导入大量记录 MySQL 备份错误的解决

昨天晚上明月给三个网站做迁移,在导出导入MySQL数据库到新服务器上 MariaDB 的时候折腾了好长的时间,碰到的错误也是一个接着一个的,虽然一个一个都解决了,但是明月感觉还是很有必要记录分享一下的。

未分类

首先给大家先说明一下具体的导入导出场景,三个网站分别在不同的阿里云虚拟主机上,以为业务发展需要三个网站都需要HTTPS支持和更加稳定的服务器,新服务器选的是阿里云ECS的,配置还是很不错哦的,所以直接上的是Linux+Nginx+PHP+MariaDB这样的LNMP生产环境。

导入MySQL数据报错:1064

问题就出在虚拟主机上导出的MySQL备份.sql文件上,在新服务器上导入总是提示“ERROR 1064 (42000): You have an error in your SQL syntax1”这样的错误,检查了好久才发现是虚拟主机上导出的.sql文件都是 UTF+BOM 格式的文件,这就造成直接在phpMyAdmin里导入就会出现无法识别.sql里的编码的问题,MySQL提示的也就是“语法问题”了。

解决办法

解决其实很简单,就是将这个导出的.sql文件使用纯文本编辑软件打开以 UTF 无签名的格式再保存覆盖一下即可正常的导入了。

这个问题目前明月就在阿里云虚拟主机上碰到过,这个可能跟阿里云虚拟主机默认数据库管理用的是 DMS 的缘故,使用phpMyAdmin估计就没有这个问题了。

导入MySQL数据报错:1153终止导入

这个错误一般都是造成数据导入不完整,因为是错误造成“终止导入”了。报错“1153 - Got a packet bigger than 'max_allowed_packet' bytes”。一般都是因为当MySQL客户端或mysqld服务器收到大于max_allowed_packet字节的信息包时,将发出“信息包过大”错误,并关闭连接。对于某些客户端,如果通信信息包过大,在执行查询期间,可能会遇到“丢失与MySQL服务器的连接”错误。

客户端和服务器均有自己的max_allowed_packet变量,因此,如你打算处理大的信息包,必须增加客户端和服务器上的该变量。一般情况下,服务器默认max-allowed-packet为1MB。

解决办法

其中net_buffer_length参数也会影响到这个错误的出现,所以要跟max_allowed_packet一起来修改,可以通过编辑MySQL的配置文件my.cnf(具体位置默认是/etc/my.cnf),修改里面对应的参数值就可以了,然后保存退出重启MySQL。

但是明月这样竟然没有效果,没有办法只能是使用下面的MySQL命令行来设置这两参数了,如下:

mysql -u root -p
set global net_buffer_length=1000000; 
set global max_allowed_packet=1000000000;
quit

这样再导入就可以顺利完成了,完美的导入数据!造成这个错误一般都是因为导入的数据量过大,超出了max_allowed_packet和net_buffer_length的默认值触发的,所以在导入大量记录的MySQL数据的时候一定要提前调整好这两个参数的赋值以备不测,一般只要数据记录超过2万条以后一定要注意提前修改默认赋值。

最后再吐槽一下LNMP1.5里集成的acme.sh脚本,问题实在是太多了,使用DNS API模式申请证书都是提示“无效主机域名”,前前后后测试了N遍都是这个问题,我自己的服务器上使用的是 GitHub 上的acme.sh就完全没有问题,三个站点的Let’s Encrypt证书全部一次就申请成功,无解中……。

LINXU | 在虚拟机里调整LVM逻辑卷的空间大小

lvresize命令

lvresize命令用于调整LVM逻辑卷的空间大小,可以增大空间和缩小空间。使用lvresize命令调整逻辑卷空间大小和缩小空间时需要谨慎,因为它有可能导致数据丢失。

语法

lvresize(选项)(参数)

选项

-L:指定逻辑卷的大小,单位为“kKmMgGtT”字节; 
-l:指定逻辑卷的大小(LE数)。

查看盘符位置

df -h

参数

逻辑卷:指定要删除的逻辑卷。

实例

使用lvresize命令调整最大的逻辑卷大小。在命令行中输入下面的命令:

[root@localhost ~]# lvresize -L +200M /dev/vg1000/lvol0 #将逻辑卷空间增加200M /dev/vg1000/lvol0为盘符位置

输出信息如下:

Extending logical volume lvol0 to 280.00 MB 
Logical volume lvol0 successfully resized

MongoDB 任意时间点恢复

简介

Mongodump是MongoDB附带的基础逻辑备份工具。它将备份完整的数据库/集合的BSON副本,并且可以选择备份保持数据库一致性的日志(oplog),备份的oplog记录的是备份执行期间数据库的变更日志。Mongorestore是用于恢复由Mongodump创建的逻辑备份的工具。我将在本文的步骤中使用这俩工具来恢复备份数据。本文假设一个基于mongodump的一致性备份(通过使用 –oplog),并将备份恢复到MongoDB实例。

本实例中,mongodump将会备份恢复基础的集合数据,并单独搜集基于时间点备份恢复所需的oplog变更,恢复时将其应用到数据。

需要指出的是:Percona开发了一个名为 mongodb_consistent_backup 的备份工具,它是’mongodump’的包装,增加了集群范围的备份一致性。 由mongodb_consistent_backup创建的备份(在Dump/Mongodump模式下)可以使用与常规“mongodump”备份相同的步骤进行恢复。
附:mongodb_consistent_backup: https://github.com/Percona-Lab/mongodb_consistent_backup

实验步骤

Stage 1:获得一个Mongodump备份

mongodump参数:

--host/--port (and –user/–password)
即使您使用的是默认主机/端口(localhost:27017),也是必需的。如果启用了授权,则还要添加 –user / –password 参数。

--oplog
任何replset成员都需要!此参数使“mongodump”在备份过程中捕获oplog更改日志,以保持一致的时间点。

--gzip
可选的。适用于mongodump > = 3.2,启用备份文件的内联压缩。

附:–oplog创建一个名为oplog.bson文件作为mongodump结果的一部分,包含了mongodump操作期间的oplog条目,实现了某个时间点的一致性快照。可用mongorestore –oplogReplay进行恢复。它的实际作用是在导出的同时生成一个oplog.bson文件,存放在你开始进行dump到dump结束之间所有的oplog。用图形来说明下oplog.bson的覆盖范围:

未分类

注意:mongodump时,–oplog只能在master节点(主从结构)或者副本集的成员中执行。也就是说,mongodump –oplog不能在主从结构的slave上执行(当然,估计也没人用主从了)。

备份命令:

$ mongodump --host localhost --port 27017 --oplog --gzip
2016-08-15T12:32:28.930+0200    writing wikipedia.pages to
2016-08-15T12:32:31.932+0200    [#########...............]  wikipedia.pages  674/1700   (39.6%)
2016-08-15T12:32:34.931+0200    [####################....]  wikipedia.pages  1436/1700  (84.5%)
2016-08-15T12:32:37.509+0200    [########################]  wikipedia.pages  2119/1700  (124.6%)
2016-08-15T12:32:37.510+0200    done dumping wikipedia.pages (2119 documents)
2016-08-15T12:32:37.521+0200    writing captured oplog to
2016-08-15T12:32:37.931+0200    [##......................]  .oplog  44/492   (8.9%)
2016-08-15T12:32:39.648+0200    [########################]  .oplog  504/492  (102.4%)
2016-08-15T12:32:39.648+0200    dumped 504 oplog entries

stage 2 恢复备份的数据

步骤:

  1. 找到分片的PRIMARY成员(肯定要在主节点做恢复)

  2. 三重检查是否将正确的备份恢复至正确的分片/主机

  3. 将基于mongodump的备份还原到PRIMARY节点(具体可参考官方文档)

  4. 检查是否有错误

  5. 检查所有SECONDARY成员是否与PRIMARY同步。

stage 3 获取时间点恢复的Oplogs

在这个阶段,我们将收集从备份时间点(向前滚动数据)到我们想要恢复的时间点(oplog位置)所需的更改。

在下面的这个例子中,假设有人在oplog时间戳“Timestamp(1470923942,3)”中意外删除了整个集合,我们想修复它。如果我们递减“时间戳(1470923942,3)”的增量(第2个数字),我们将获取到在意外命令之前进行的最后更改,在本例中为“时间戳(1470923942,2)”。 通过使用时间戳,我们可以捕获并重放oplog,从备份时间点到问题/错误操作之前。

我们需要开始和结束时间戳来获取oplog中的数据。在所有情况下,这都需要手动收集。

用到的脚本:
【dump_oplog_range.sh】

#!/bin/bash
#
# This tool will dump out a BSON file of MongoDB oplog changes based on a range of Timestamp() objects.
# The captured oplog changes can be applied to a host using 'mongorestore --oplogReplay --dir /path/to/dump'.
set -e
TS_START=$1
TS_END=$2
MONGODUMP_EXTRA=$3
function usage_exit() {
  echo "Usage $0: [Start-BSON-Timestamp] [End-BSON-Timestamp] [Extra-Mongodump-Flags (in quotes for multiple)]"
  exit 1
}
function check_bson_timestamp() {
  local TS=$1
  echo "$TS" | grep -qP "^Timestamp(d+,sd+)$"
  if [ $? -gt 0 ]; then
    echo "ERROR: Both timestamp fields must be in BSON Timestamp format, eg: 'Timestamp(########, #)'!"
    usage_exit
  fi
}
if [ -z "$TS_START" ] || [ -z "$TS_END" ]; then
  usage_exit
else
  check_bson_timestamp "$TS_START"
  check_bson_timestamp "$TS_END"
fi
MONGODUMP_QUERY='{ "ts" : { "$gte" : '$TS_START' }, "ts" : { "$lte" : '$TS_END' } }'
MONGODUMP_FLAGS='--db=local --collection=oplog.rs'
[ ! -z "$MONGODUMP_EXTRA" ] && MONGODUMP_FLAGS="$MONGODUMP_FLAGS $MONGODUMP_EXTRA"
if [ -d dump ]; then
  echo "'dump' subdirectory already exists! Exiting!"
  exit 1
fi
echo "# Dumping oplogs from '$TS_START' to '$TS_END'..."
mkdir dump
mongodump $MONGODUMP_FLAGS --query "$MONGODUMP_QUERY" --out - >dump/oplog.bson
if [ -f dump/oplog.bson ]; then
  echo "# Done!"
else
  echo "ERROR: Cannot find oplog.bson file! Exiting!"
  exit 1
fi

脚本用法:

$ ./dump_oplog_range.sh
Usage ./dump_oplog_range.sh: [Start-BSON-Timestamp] [End-BSON-Timestamp] [Extra-Mongodump-Flags (in quotes for multiple)]

操作步骤:

1、找到包含PITR(point-in-time-recovery)还原所需的oplog的PRIMARY成员。

2、确定需要恢复的“end”Timestamp()。 这个oplog时间应该在问题出现之前。

3、确定备份开始之前的“start”Timestamp()。
这个时间戳不需要精确,所以Timestamp()对象等于“在备份开始前几分钟”都没有问题,但时间越精确,您需要重放的更改就更少(可以节省恢复时间)。

4、使用MongoToolsAndSnippets脚本: “get_oplog_range.sh”(就是上面贴的“帮助脚本”)将需要恢复的oplog时间范围dump到您选择的时间点。 在这个例子中,我在两个时间点之间收集oplog(同时在引号中传入–username / –password作为第三个参数):

1) 起始时间戳:本示例中的“阶段2:恢复集合数据”中的mongodump备份之前的BSON时间戳。在本例中,“时间戳(1470923918,0)”是在mongodump执行之前几秒钟的时间(不需要精确)。
2) 结束时间戳:在此示例中,恢复到哪个时间点的BSON时间戳。“时间戳(1470923942,2)”是发生问题之前的最后一次oplog更改。

$ wget -q https://raw.githubusercontent.com/percona/MongoToolsAndSnippets/master/rdba/dump_oplog_range.sh
$ bash ./dump_oplog_range.sh 'Timestamp(1470923918, 0)' 'Timestamp(1470923942, 2)' '--username=secret --password=secret --host=mongo01.example.com --port=27024'
# Dumping oplogs from 'Timestamp(1470923918, 0)' to 'Timestamp(1470923942, 2)'...
2016-08-12T13:11:17.676+0200    writing local.oplog.rs to stdout
2016-08-12T13:11:18.120+0200    dumped 22 documents
# Done!

注意:所有额外的mongodump 参数(第三个参数)必须用引号括起来!

5、通过查找 ‘oplog.bson’ 文件并检查文件中是否有一些数据(下面的例子中为168mb)来检查它的工作情况:

$ ls -alh dump/oplog.bson
-rw-rw-r--. 1 tim tim 168M Aug 12 13:11 dump/oplog.bson

stage 4 应用Oplogs进行时间点恢复(PITR)

在此阶段,我们将在阶段3中收集的基于时间范围的oplog应用于恢复的数据集,以便将数据从备份时间带到发生问题之前的特定时间点。

mongorestore 参数:

--host/--port(--user / --password)
即使您使用的是默认主机/端口(localhost:27017),也是必需的。如果启用授权,则还要添加 –user / –password 参数。

--oplogReplay
必须。这一步用于重放oplog。

--dir
必须。 mongodump数据的路径。

步骤:

1、将仅包含“oplog.bson”文件(在阶段3中捕获)的“dump”目录复制到需要应用oplog更改的主机(还原主机)。

2、在“dump”目录中运行“mongorestore”以将oplog重放到实例中。注意确保“dump”目录只包含“oplog.bson”文件。

$ mongorestore --host localhost --port 27017 --oplogReplay --dir ./dump
2016-08-12T13:12:28.105+0200    building a list of dbs and collections to restore from dump dir
2016-08-12T13:12:28.106+0200    replaying oplog
2016-08-12T13:12:31.109+0200    oplog   80.0 MB
2016-08-12T13:12:34.109+0200    oplog   143.8 MB
2016-08-12T13:12:35.501+0200    oplog   167.8 MB
2016-08-12T13:12:35.501+0200    done

3、使用任何可能的方式验证恢复的数据,(例如:.count()查询,一些随机的.find()查询等)。

解决Linux中PHP-FPM进程过量占用内存

1. 事情经过

其实这个问题困扰了我很长时间。事情经过是这样的:我在写这篇文章前几天,对网站服务器进行了停机维护,其中包括更换操作系统、重新配置网站环境、更换博客程序、使用新模板等许多操作(包括误删数据库并没有)。然后问题就出现了!内存多次跑满(如图)!由于我在服务器商处设置了内存超量报警,导致收到了几十条报警信息。由于我这几天有些事情(因为懒并不是),没有认真打理网站,所以只是确定服务器未被入侵后就重启了之。这一拖就到了今天。但是问题早晚要解决!现在我们来解决这个问题吧。

未分类

2. 排查过程

实际上排查还是很简单的,直接使用 linux 自带的命令free -m 然后查看空闲内存确定是内存跑满,然后是使用top命令查看进程情况,并确定 cpu 状态正常。

(这里本应有一张我修复故障前的 top 命令结果图,但是我忘记截图了……)

查询结果可以看见我服务器中PHP-FPM进程占用了一半多的内存,找到原因,果断处理!

补充几条命令,会对你排错有帮助:

查看每个PHP-FPM进程的内存占用:ps -ylC php-fpm –sort:rss

查看消耗内存最多的前 40 个进程:ps auxw|head -1;ps auxw|sort -rn -k4|head -40

查看PHP-FPM的平均内存占用:ps –no-headers -o “rss,cmd” -C php-fpm | awk ‘{ sum+=$1 } END { printf (“%d%sn”, sum/NR/1024,”M”) }’

3. 处理方法

我们可以通过修改 php 的配置文件来限制PHP-FPM的创建和销毁。

我们找到 /www/server/php/etc/php-fpm.conf (在我服务器中是这个路径) 文件,用 vi 打开,找到 pm.max_children 也就是控制 php-fpm 子进程数量的字段,我修改前这个字段是 50,我将其修改为 25。再找到pm.max_spare_servers 这个字段表示空闲进程数的最大值,这个数应为pm.max_children 的 60%~80%,所以我设置为 17。

注意:如果pm.max_children设置过小可能会导致 502 错误频发,应按照自己服务器业务要求和服务器能力自行设置!

这样我们就修改好了配置文件 :wq 退出 vi,并使用 systemctl restart php-fpm 重启PHP-FPM。

未分类

(我基本可以确定,90%用户的php-fpm.conf文件与上图不同,大家自己找对应字段就好

4. 处理结果

我们可以看到重启服务后内存瞬间降低至 26%然后稳定到 50%,所以这个问题算是解决了!

未分类