NFS锁相关的问题

8 篇文章 0 订阅

NFS锁相关的问题

前言

问题的来源是对nfs的共享目录的锁控制问题,关于共享的文件系统,通常有两种需求

需求一

需要有一个共同的锁,然后客户端的软件会判断锁在哪台机器上面,然后根据这个来进行服务的管理

需求二

使用共同的文件,客户端相互之间不能有锁,否则服务无法同时启动,那么需要高可用的时候,可能存在问题

本篇就是根据实际情况,我们来看怎么处理nfs服务,怎么样能够开启锁,怎么用关闭锁,这个根据实际情况进行配置

实践

准备三台机器,一台服务器进行nfs的数据的共享,另外两台机器同时去访问这个共享目录,使用的是nfs v3

lab201 nfs服务端

lab202 nfs客户端

lab203 nfs客户端

在lab201配置nfs服务

[root@lab201 ~]# chmod 777 /nfsshare/
[root@lab201 ~]# cat /etc/exports
/nfsshare *(fsid=123,no_root_squash,async,no_subtree_check,rw)

在lab202和lab203同时使用默认参数挂载nfs服务

[root@lab202 ~]# mount -t nfs -o v3 192.168.0.201:/nfsshare /mnt
[root@lab203 ~]# mount -t nfs -o v3 192.168.0.201:/nfsshare /mnt

查看挂载参数

192.168.0.201:/nfsshare on /mnt type nfs (rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.201,mountvers=3,mountport=892,mountproto=udp,local_lock=none,addr=192.168.0.201)

查看服务端的

[root@lab201 ~]# systemctl status rpc-statd
● rpc-statd.service - NFS status monitor for NFSv2/3 locking.
   Loaded: loaded (/usr/lib/systemd/system/rpc-statd.service; static; vendor preset: disabled)
   Active: active (running) since Fri 2021-10-08 14:52:07 CST; 2min 25s ago
  Process: 8400 ExecStart=/usr/sbin/rpc.statd $STATDARGS (code=exited, status=0/SUCCESS)
 Main PID: 8405 (rpc.statd)
    Tasks: 1
   CGroup: /system.slice/rpc-statd.service
           └─8405 /usr/sbin/rpc.statd -p 662 -o 2020

Oct 08 14:52:07 lab201 systemd[1]: Starting NFS status monitor for NFSv2/3 locking....
Oct 08 14:52:07 lab201 rpc.statd[8405]: Version 1.3.0 starting
Oct 08 14:52:07 lab201 rpc.statd[8405]: Flags: TI-RPC
Oct 08 14:52:07 lab201 systemd[1]: Started NFS status monitor for NFSv2/3 locking..

这里介绍下,nfs的多个客户端同时挂载的时候是通过rpc-statd这个服务来处理多台机器的锁的情况的,默认就是通过这个服务来加锁的,也就是远程锁

如果有锁的时候是什么情况,我们看下

在lab202上面运行服务,并且对文件加锁

[root@lab202 mnt]# flock lockfile -c top

这个时候top的命令是有输出的,并且文件是加上锁了,我们在另外一台机器lab203上面执行

[root@lab203 mnt]# flock lockfile -c top

可以看到,这个命令并没有输出,处于一直卡着的状态,这个是在等待lockfile释放以后,这个命令就可以输出了,我们去中断下lab202上面刚刚的命令
下面的lab203的命令马上有输出了,这个时候就是正常的开启了远程锁的情况

既然我们知道上面的rpc-statd是管理锁的,我们把那个服务停止掉,看下什么情况

注意操作步骤如下:

  • 卸载客户端

  • 重启nfs服务

  • 关闭rpc-statd

  • 挂载客户端

必须上面的操作步骤

然后即使一台机器执行,也会报下面的,无法上锁

[root@lab202 mnt]# flock lockfile -c top
flock: lockfile: No locks available

这种情况实际上是有问题的,也就是默认的挂载把锁交给了远端nfs server,但是远端无法上锁,所以就出现提示无法上锁

我们验证服务
把mysql的数据放到上面这种配置的没有锁的目录里面

[root@lab202 mariadb]# df -h /var/lib/mysql/
Filesystem               Size  Used Avail Use% Mounted on
192.168.0.201:/nfsshare   80G   68G   13G  84% /var/lib/mysql
[root@lab202 mariadb]# ls /var/lib/mysql/
aria_log.00000001  ibdata1      ib_logfile1  mysql               test
aria_log_control   ib_logfile0  lockfile     performance_schema

启动服务,可以看到卡住

[root@lab202 mysql]# systemctl start mariadb

我们查看日志

[root@lab202 mariadb]# tail -n 50 /var/log/mariadb/mariadb.log
211008 15:07:07 InnoDB: Using Linux native AIO
211008 15:07:07 InnoDB: Initializing buffer pool, size = 128.0M
211008 15:07:07 InnoDB: Completed initialization of buffer pool
InnoDB: Unable to lock ./ibdata1, error: 37
211008 15:07:13  InnoDB: Retrying to lock the first data file
InnoDB: Unable to lock ./ibdata1, error: 37
InnoDB: Unable to lock ./ibdata1, error: 37
InnoDB: Unable to lock ./ibdata1, error: 37

可以看到这个地方,即使一台机器的mysql,这个服务也是无法启动的,所以我们可以得到一个结论,mysql服务启动是需要对文件上锁的

然后我们现在远端没有提供锁,这个服务就无法启动,但是如果启动锁,那么如果要两台服务器启动,不可能同时拿到远程锁

那么这个地方的处理,应该就只有一种情况了,我们需要让每个客户端自己去处理自己的锁的情况,远端的锁,启动和不启动不影响客户端这边,并且远端的锁有的时候通过内核lockd进行的提供,并没有关闭的地方,nfs是通过客户端这边进行控制,提供了挂载参数处理这种情况

我们看下说明比较清楚

[root@lab202 ~]# man 5 nfs
      lock / nolock  Selects  whether  to  use  the  NLM  sideband  protocol to lock files on the
                      server.  If neither option is specified (or if lock is specified), NLM lock‐
                      ing  is  used  for this mount point.  When using the nolock option, applica‐
                      tions can lock files, but such locks provide exclusion  only  against  other
                      applications  running  on  the  same  client.   Remote  applications are not
                      affected by these locks.

                  NLM locking must be disabled with the nolock option when using NFS to  mount
                  /var  because  /var  contains files used by the NLM implementation on Linux.
                  Using the nolock option is  also  required  when  mounting  exports  on  NFS
                  servers that do not support the NLM protocol.

可以看下内容,默认会开启nlm的锁,如果没添加挂载参数的话,如果使用了nolock,那么跨机器之间的锁是没影响的,本机器的锁由本机器来提供
/var/目录进行挂载nfs的时候,需要使用nolock,因为里面包含了一些nlm锁没有实现的功能
也就是通过nolock来挂载/var/lib/mysql服务,由本地机器提供锁相关的

再次挂载

[root@lab202 ~]# mount -t nfs -o v3,nolock 192.168.0.201:/nfsshare /var/lib/mysql/
[root@lab202 ~]# mount|grep mysql
192.168.0.201:/nfsshare on /var/lib/mysql type nfs (rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.201,mountvers=3,mountport=892,mountproto=udp,local_lock=all,addr=192.168.0.201)

再次启动mysql,可以正常启动

[root@lab202 ~]# systemctl start mariadb

我们在另外一台机器上面把mysql挂载起来,可以看到直接可以启动

目前两台机器上面都是以nolock进行的挂载,我们继续之前的flock测试

在lab202上面开两个终端
运行

flock lockfile -c top

在lab203上面开一个终端运行

flock lockfile -c top

可以看到lab202与lab203能够同时运行成功,lab202另外一个终端运行会卡住等待,这里说明本地锁是成功的,跨机器是没有锁的,也就是我们需要运行两台机器mysql的模式

我们查看上面的挂载参数的时候可以看到
默认的挂载参数里面的,local_lock=none,而加上了nolock之后,local_lock=all,自动修正为这个选项了,也就是本地锁

我们看下这块的参数解释

[root@lab202 ~]# man 5 nfs
       local_lock=mechanism
                      Specifies whether to use local locking for any or both of the flock and  the
                      POSIX  locking  mechanisms.   mechanism  can be one of all, flock, posix, or
                      none.  This option is supported in kernels 2.6.37 and later.

                  The Linux NFS client provides a way to make locks  local.  This  means,  the
                  applications  can  lock files, but such locks provide exclusion only against
                  other applications running on the same client. Remote applications  are  not
                  affected by these locks.

                  If this option is not specified, or if none is specified, the client assumes
                  that the locks are not local.

                  If all is specified, the client assumes that both flock and POSIX locks  are
                  local.

                  If  flock  is  specified, the client assumes that only flock locks are local
                  and uses NLM sideband protocol to lock files when POSIX locks are used.

                  If posix is specified, the client assumes that POSIX  locks  are  local  and
                  uses NLM sideband protocol to lock files when flock locks are used.

                  To  support  legacy  flock behavior similar to that of NFS clients < 2.6.12,
                  use 'local_lock=flock'. This option is required when  exporting  NFS  mounts
                  via Samba as Samba maps Windows share mode locks as flock. Since NFS clients
                  > 2.6.12 implement flock by emulating POSIX locks, this will result in  con‐
                  flicting locks.

                  NOTE:  When  used together, the 'local_lock' mount option will be overridden
                  by 'nolock'/'lock' mount option.

可以看到,如果指定了本地,锁就用本地锁,不指定,就默认不用本地锁,如果指定了nolock选项,会覆盖这个选项

我们试下不指定nolock,直接指定local_lock的效果

[root@lab202 ~]# mount -t nfs -o v3,local_lock=all 192.168.0.201:/nfsshare /var/lib/mysql/
[root@lab202 ~]# mount |grep mysql
192.168.0.201:/nfsshare on /var/lib/mysql type nfs (rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.201,mountvers=3,mountport=892,mountproto=udp,local_lock=all,addr=192.168.0.201)

通过flock命令进行测试,可以看到与nolock的效果一致

总结

我们使用nfs的时候,如果需要用到锁

首先判断,是需要本地锁还是远程锁

如果远程锁,需要看下rpc-statd服务是否正常启动,提供远程锁服务
如果是本地锁,那么需要检查local_lock=all这个是否开启,或者nolock与local_lock=all是否同时开启
通过上面的flock命令可以快速判断锁的情况

备注

nfs v3的锁是通过nlm协议处理的,nfs v4的锁是nfs 自己处理的,本篇所说的都是nfs v3的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值