当前位置: 首页 > news >正文

搭建GPFS双机集群

1.环境说明:

系统主机名IP地址内存添加共享磁盘大小
Centos7.9gpfs1192.168.10.1012G20G
Centos7.9gpfs2192.168.10.1022G20G

2.环境配置:

  • 配置网路IP地址:

    • 修改网卡会话:

      nmcli connection modify ipv4.method manual ipv4.addresses '192.168.10.101/24' \ipv4.gateway 192.168.10.2 ipv4.dns 8.8.8.8 autoconnect yes
      nmcli conection up ens33

    • (可选)在网卡上添加会话:

      nmcli connection add type ethernet con-name ens38 ifname ens38 \ipv4.method manual ipv4.addresses '192.168.10.152/24' \ipv4.gateway 192.168.10.2 ipv4.dns 8.8.8.8 autoconnect yes
      nmcli connection up ens38

  • 关闭防火墙和selinux:

    [root@localhost ~]# systemctl stop firewalld;systemctl disable firewalld
    Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
    Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
    [root@localhost ~]# sed -i 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
    [root@localhost ~]# reboot
    ​
    连接断开
    连接主机...
    连接主机成功
    Last failed login: Wed Jul 12 19:43:52 EDT 2023 on tty1
    There was 1 failed login attempt since the last successful login.
    Last login: Wed Jul 12 11:53:49 2023 from 192.168.178.1
    [root@localhost ~]# getenforce
    Disabled

3.配置yum源:

  • 配置本地yum源:

    mkdir /mnt/cdrom;mount /dev/cdrom /mnt/cdrom
    cat << eof >> /etc/fstab
    /dev/cdrom /mnt/cdrom iso9660 defaults  0  0
    eof
    cat << eof > /etc/yum.repos.d/centos-local.repo
    [centos7.9]
    name=centos7.9
    baseurl=file:///mnt/cdrom
    enabled=1
    gpgcheck=0
    eof
    yum clean all && yum repolist

  • 配置扩展源:

    yum install epel-release -y
    yum clean all && yum repolist

  • (可选)配置远程阿里源:

    yum install -y wget && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    yum clean all && yum repolist

4.安装必要工具:

yum install -y bash-completion vim net-tools tree psmisc lrzsz dos2unix

5.配置域名映射:

cat << eof >> /etc/hosts
192.168.10.101 node1
192.168.10.102 node2
192.168.10.111 client-side
eof

6.ssh免密登录:

# 自己生成的公钥也要给自己添加上
ssh-keygen -t rsa -b 1024
ssh-copy-id -i ~/.ssh/id_rsa.pub root@[IP地址]

7.配置chrony时间服务器:

  • 两个节点都并且连接到阿里云时间服务器,安装:

    [root@node1 ~]# yum -y install chrony
  • 启动进程:

    [root@node1 ~]# systemctl enable chronyd;systemctl start chronyd
  • node1节点,修改配置文件/etc/chrony.conf

    [root@node1 ~]# sed -i '/^server [0-9]/d' /etc/chrony.conf
    [root@node1 ~]# sed -i '2a\server 192.168.10.101 iburst\' /etc/chrony.conf
    [root@node1 ~]# sed -i 's/#allow 192.168.0.0\/16/allow 192.168.10.0\/24/' /etc/chrony.conf
    [root@node1 ~]# sed -i 's/#local stratum 10/local stratum 10/' /etc/chrony.conf
  • node2节点,修改配置文件/etc/chrony.conf

    [root@node2 ~]# sed -i '/^server [0-9]/d' /etc/chrony.conf
    [root@node2 ~]# sed -i '2a\server 192.168.10.101 iburst\' /etc/chrony.conf
  • 重启服务:

    [root@node1 ~]# systemctl restart chronyd
  • 查看时间同步状态:

    [root@node1 ~]# timedatectl statusLocal time: 三 2023-07-26 23:02:14 EDTUniversal time: 四 2023-07-27 03:02:14 UTCRTC time: 四 2023-07-27 03:02:14Time zone: America/New_York (EDT, -0400)NTP enabled: yes
    NTP synchronized: yesRTC in local TZ: noDST active: yesLast DST change: DST began at日 2023-03-12 01:59:59 EST日 2023-03-12 03:00:00 EDTNext DST change: DST ends (the clock jumps one hour backwards) at日 2023-11-05 01:59:59 EDT日 2023-11-05 01:00:00 EST
  • 开启网络时间同步:

    [root@node1 ~]# timedatectl set-ntp true
  • 查看具体的同步信息:

    [root@node1 ~]# chronyc sources -v
    210 Number of sources = 1
    ​.-- Source mode  '^' = server, '=' = peer, '#' = local clock./ .- Source state '*' = current synced, '+' = combined , '-' = not combined,
    | /   '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
    ||                                                 .- xxxx [ yyyy ] +/- zzzz
    ||      Reachability register (octal) -.           |  xxxx = adjusted offset,
    ||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
    ||                                \     |          |  zzzz = estimated error.
    ||                                 |    |           \
    MS Name/IP address         Stratum Poll Reach LastRx Last sample               
    ===============================================================================
    ^* 203.107.6.88                  2   6    17     2  +2105us[+1914us] +/-   20ms

8.配置共享硬盘:

  • 前提:两台虚拟机没有拍摄快照

  • 在mds001主机中:

    • 添加五块5G的硬盘

      SCSI > 创建新虚拟磁盘 > 指定磁盘容量 ,立即分配所有磁盘空间,将虚拟磁盘存储为单个文件

    • 修改磁盘属性:

  • 在mds002主机中:

    • 添加5块5G的硬盘

      SCSI > 使用已有的虚拟磁盘 > 指定磁盘容量 ,立即分配所有磁盘空间,将虚拟磁盘存储为单个文件 > 选择mds001主机新添加的磁盘文件

    • 修改磁盘属性:

  • 在mds001和mds002的虚拟机目录下,找个后缀名为vmx的文件,在文件末尾添加一下内容:

    scsi1.sharedBus = "virtual"
    disk.locking = "false"
    diskLib.dataCacheMaxSize = "0"
    diskLib.dataCacheMaxReadAheadSize = "0"
    diskLib.dataCacheMinReadAheadSize = "0"
    diskLib.dataCachePageSize = "4096"
    diskLib.maxUnsyncedWrites = "0"
    disk.EnableUUID = "TRUE"
  • 重启两台虚拟机发现,添加成功

    [root@mds001 ~]# lsblk
    NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda               8:0    0   20G  0 disk 
    ├─sda1            8:1    0    1G  0 part /boot
    └─sda2            8:2    0   19G  0 part ├─centos-root 253:0    0   17G  0 lvm  /└─centos-swap 253:1    0    2G  0 lvm  [SWAP]
    sdb               8:16   0    5G  0 disk 
    sdc               8:32   0    5G  0 disk 
    sdd               8:48   0    5G  0 disk 
    sde               8:64   0    5G  0 disk 
    sdf               8:80   0    5G  0 disk 
    sr0              11:0    1  9.5G  0 rom  /mnt/cdrom

9.安装GPFS软件包:

  • GPFS所需包:

    软件包说明
    gpfs.base-***.x86_64.rpmGPFS的基本软件包(GPFS服务器和客户端组件)
    gpfs.docs-***.noarch.rpmGPFS的文档和帮助文件软件包
    gpfs.gpl-***.noarch.rpmGPFS的GNU通用公共许可证(GPL)软件包,包含一些GPFS的开源组件
    gpfs.gskit-***.x86_64.rpmIBM Global Security Kit(GSKit)的组件,用于加密和安全通信
    gpfs.msg.en_US-***.noarch.rpmGPFS的英语消息文件,用于本地化和国际化
    gpfs.ext-***.x86_64.rpmGPFS 的扩展工具包,用于安装和管理 GPFS 文件系统的特定组件
  • 创建目录:

    mkdir ~/gpfs-***
  • 上传gpfs的rpm包

  • 安装依赖:

    yum -y install make perl rsh ld-linux.so libm.so.6 libc.so.6 ksh libstdc++.so.5 rsh-server rpcbind xinetd libaio cpp gcc-c++ gcc nfs-utils kernel-headers kernel-devel compat-libstdc++ glibc-devel libXp.so.6 imake rpm-build rpm-build m4
  • 安装:

    cd ~/gpfs-*** && rpm -ivh \gpfs.base-***.x86_64.rpm \gpfs.docs-***.noarch.rpm \gpfs.gpl-***.noarch.rpm \gpfs.gskit-***.x86_64.rpm \gpfs.msg.en_US-***.noarch.rpm \gpfs.ext-***.x86_64.rpm
  • 编译1:

    cd /usr/lpp/mmfs/src && make Autoconfig LINUX_DISTRIBUTION=REDHAT_AS_LINUX && make World && make InstallImages
  • 编译问题:

    • 问题一:

        Cannot find a valid kernel header file. One of these files should exist./lib/modules/3.10.0-1160.el7.x86_64/build/include/linux/version.h/usr/src/linux-3.10.0-1160.el7.x86_64/include/linux/version.h/usr/src/kernels/3.10.0-1160.el7.x86_64/include/generated/uapi/linux/version.h/lib/modules/3.10.0-1160.el7.x86_64/build/include/generated/uapi/linux/version.h
      ​
      Contact IBM Service if you still encounter this problem after you install all the required packages.
      make: *** [Autoconfig] 错误 1
      # 原因:路径/usr/src/kernels/3.10.0-1160.el7.x86_64不存在
      [root@gpfs 3.10.0-1160.el7.x86_64]# ll /lib/modules/3.10.0-1160.el7.x86_64
      total 3300
      lrwxrwxrwx.  1 root root     39 Aug 31 08:35 build -> /usr/src/kernels/3.10.0-1160.el7.x86_64
      .....
      [root@node1 src]# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/kernel-devel-3.10.0-1160.el7.x86_64.rpm
      [root@node1 src]# rpm -Uvh kernel-devel-3.10.0-1160.el7.x86_64.rpm --force
    • 问题二:

      In file included from /usr/include/sys/ioctl.h:26:0,from /usr/lpp/mmfs/src/gpl-linux/lxtrace.c:61:
      /usr/include/bits/ioctls.h:23:24: 致命错误:asm/ioctls.h:没有那个文件或目录#include <asm/ioctls.h>^
      [root@node1 src]# find /usr/src/kernels/3.10.0-1160.el7.x86_64 -name "ioctls.h"
      /usr/src/kernels/3.10.0-1160.el7.x86_64/arch/x86/include/uapi/asm/ioctls.h
      /usr/src/kernels/3.10.0-1160.el7.x86_64/include/uapi/asm-generic/ioctls.h
      [root@node1 src]# rm -rf /usr/include/asm/ioctls.h
      [root@node1 src]# ln -s /usr/src/kernels/3.10.0-1160.el7.x86_64/arch/x86/include/uapi/asm/ioctls.h /usr/include/asm/ioctls.h
    • 问题三:

      kdump-kern.o:在函数‘GetOffset’中:
      kdump-kern.c:(.text+0x15):对‘__x86_return_thunk’未定义的引用
      kdump-kern.o:在函数‘KernInit’中:
      kdump-kern.c:(.text+0x1a5):对‘__x86_return_thunk’未定义的引用
      kdump-kern.o:在函数‘GenericGet’中:
      kdump-kern.c:(.text+0x348):对‘__x86_return_thunk’未定义的引用
      kdump-kern.c:(.text+0x35e):对‘__x86_return_thunk’未定义的引用
      kdump-kern.o:在函数‘tiInit’中:
      kdump-kern.c:(.text+0x3bc):对‘__x86_return_thunk’未定义的引用
      kdump-kern.o:kdump-kern.c:(.text+0x445): 跟着更多未定义的参考到 __x86_return_thunk
      collect2: 错误:ld 返回 1
      make[1]: *** [modules] 错误 1
      make[1]: 离开目录“/usr/lpp/mmfs/src/gpl-linux”
      make: *** [Modules] 错误 1
      vim /usr/lpp/mmfs/src/gpl-linux/kdump.c
      # 在122行添加内容
      unsigned long __x86_return_thunk;
    • 问题三:

      kdump-kern.o: In function `GetOffset':
      kdump-kern.c:(.text+0x9): undefined reference to `page_offset_base'
      kdump-kern.o: In function `KernInit':
      kdump-kern.c:(.text+0x58): undefined reference to `page_offset_base'
      collect2: error: ld returned 1 exit status
      make[1]: *** [modules] Error 1
      make[1]: Leaving directory `/usr/lpp/mmfs/src/gpl-linux'
      make: *** [Modules] Error 1
      vim /usr/lpp/mmfs/src/gpl-linux/kdump.c
      # 在122行添加内容
      unsigned page_offset_base;
  • 如果没有任何错误,即为成功

  • 继续执行编译命令2:(构建 GPFS 可移植层)

    cd /usr/lpp/mmfs/src && make rpm
  • 完全成功如下:

    检查未打包文件:/usr/lib/rpm/check-files /tmp/rpm
    写道:/root/rpmbuild/RPMS/x86_64/gpfs.gplbin-***.el7.x86_64-4.2.3-22.x86_64.rpm
    执行(%clean): /bin/sh -e /var/tmp/rpm-tmp.WyvdX3
    + umask 022
    + cd /root/rpmbuild/BUILD
    + /usr/bin/rm -rf /tmp/rpm
    + exit 0
  • 最后的安装:

    [root@gpfs1 src]# rpm -ivh /root/rpmbuild/RPMS/x86_64/gpfs.gplbin-***.el7.x86_64-4.2.3-22.x86_64.rpm
    准备中...                          ################################# [100%]
    正在升级/安装...1:gpfs.gplbin-***.el7.################################# [100%]
  • 查看GPFS安装情况:

    [root@gpfs1 ~]# rpm -qa|grep gpfs
    gpfs.msg.en_US-***.noarch
    gpfs.base-***.x86_64
    gpfs.ext-***.x86_64
    gpfs.gskit-***.x86_64
    gpfs.gplbin-***.el7.x86_64-***.x86_64
    gpfs.gpl-***.noarch
    gpfs.docs-***-22.noarch
  • gpfs的执行文件位于/usr/lpp/mmfs/bin目录中,请尽量将此路径添加到系统PATH环境变量中

    echo 'export PATH=$PATH:/usr/lpp/mmfs/bin' >> /etc/profile
    source /etc/profile

10.创建集群:

  • 修改配置文件:

    # 第一项为所使用机器的主机名,第二项为配置项,包括quorum节点的指定和manager节点的指定
    cat << eof > /tmp/gpfsfile
    node1:quorum-manager
    node2:quorum-manager
    eof
  • 创建集群:

    参数说明
    -N指定节点文件名
    -p指定主NSD服务器
    -s指定备NSD服务器
    -r和-R-r是rsa密钥,-R是复制命令
    -A指定当节点出现时自动启动 GPFS 守护进程。默认情况下不自动启动守护进程
    -C设定集群名称
    -Ubgbc 定义域名
    -c配置文件
    [root@node1 ~]# mmcrcluster -N /tmp/gpfsfile -p node1 -s node2 -r /usr/bin/ssh -R /usr/bin/scp -A -C gpfs
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    mmcrcluster: Performing preliminary node verification ...
    node1:  which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    mmcrcluster: Processing quorum and other critical nodes ...
    mmcrcluster: Finalizing the cluster data structures ...
    mmcrcluster: Command successfully completed
    mmcrcluster: Warning: Not all nodes have proper GPFS license designations.Use the mmchlicense command to designate licenses as needed.
    mmcrcluster: Propagating the cluster configuration data to allaffected nodes.  This is an asynchronous process.
  • 创建集群报错:

    • 报错1:卡住不动:

      [root@node1 ~]# mmcrcluster -N /tmp/gpfsfile -p node1 -s node2 -r /usr/bin/ssh -R /usr/bin/scp -A -C gpfs
      mmcrcluster: Performing preliminary node verification ...
      mmcrcluster: Processing quorum and other critical nodes ...
      mmcrcluster: Finalizing the cluster data structures ...
      # 删除iptables
      yum remove -y iptables
    • 报错2:

      which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
      Tue Sep 12 06:17:05 EDT 2023: mmstartup: Starting GPFS ...
      which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
      node4:  which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
      node3:  which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
      node4:  The GPFS subsystem is already active.
      node3:  The GPFS subsystem is already active.
      yum install iproute -y
  • 如果执行失败或者中断,可以通过一下命令清除

    [root@gpfs1 ~]# mmdelnode -f
    mmdelnode: [W] This option should only be used to remove all GPFS configuration files on a node that has already been deleted from a cluster.  If the node is still a member of a cluster, and it is then added to the same or to another cluster after 'mmdelnode -f' is issued, results will be unpredictable, possibly leading to mmfsd daemon failure.
    Do you want to continue? (yes/no) yes
    mmdelnode: All GPFS configuration files on node gpfs1 have been removed.
  • 查看GPFS集群:

    [root@node1 ~]# mmlscluster
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    ​
    GPFS cluster information
    ========================GPFS cluster name:         gpfs.node1GPFS cluster id:           1484988891360413006GPFS UID domain:           gpfs.node1Remote shell command:      /usr/bin/sshRemote file copy command:  /usr/bin/scpRepository type:           CCR
    ​Node  Daemon node name  IP address      Admin node name  Designation
    ----------------------------------------------------------------------1   node1             192.168.10.101  node1            quorum-manager2   node2             192.168.10.102  node2            quorum-manager
  • 授权:(服务节点或quorum节点用server,其它节点用client)

    [root@node1 ~]# mmchlicense server --accept -N node1,node2
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    ​
    The following nodes will be designated as possessing server licenses:node2node1
    mmchlicense: Command successfully completed
    mmchlicense: Propagating the cluster configuration data to allaffected nodes.  This is an asynchronous process.

11.启动集群:

  • 启动集群:

    [root@node1 ~]# mmstartup -a    # -a启动所有节点
    Thu Aug 31 23:49:52 EDT 2023: mmstartup: Starting GPFS ...
  • 报错问题1:

    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    2023年 08月 31日 星期四 04:03:03 EDT: mmstartup: Starting GPFS ...
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    node2:  which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    node1:  which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    node2:  mmremote: startSubsys: The /lib/modules/3.10.0-1160.el7.x86_64/extra/mmfslinux.ko kernel extension does not exist.  Use mmbuildgpl command to create the needed kernel extension for your kernel or copy the binaries from another node with the identical environment.
    node2:  mmremote: startSubsys: Unable to verify kernel/module configuration.
    node1:  mmremote: startSubsys: The /lib/modules/3.10.0-1160.el7.x86_64/extra/mmfslinux.ko kernel extension does not exist.  Use mmbuildgpl command to create the needed kernel extension for your kernel or copy the binaries from another node with the identical environment.
    node1:  mmremote: startSubsys: Unable to verify kernel/module configuration.
    mmdsh: node2 remote shell process had return code 1.
    mmdsh: node1 remote shell process had return code 1.
    mmstartup: Command failed. Examine previous error messages to determine cause.
    # 原因:mmfslinux.ko文件在编译过程中根据你(kernel-devel-3.10.0-1160.el7.x86_64版本)的生成,并且生成在/lib/modules/3.10.0-1160.el7.x86_64/extra下。如果你使用的kernel-devel版本是3.10.0-1160.95.1.el7.x86_64,那生成的mmfslinux.ko路径会是/lib/modules/3.10.0-1160.95.1.el7.x86_64/extra。
    # 所以我这里的解决方法是:下载kernel-devel-3.10.0-1160.el7.x86_64
    [root@node1 ~]# rpm -qa | grep kernel
    kernel-3.10.0-1160.el7.x86_64
    kernel-headers-3.10.0-1160.95.1.el7.x86_64
    kernel-tools-3.10.0-1160.el7.x86_64
    kernel-tools-libs-3.10.0-1160.el7.x86_64
    kernel-devel-3.10.0-1160.el7.x86_64
  • 报错2:

    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    Tue Sep 12 06:17:05 EDT 2023: mmstartup: Starting GPFS ...
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    node4:  which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    node3:  which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    node4:  The GPFS subsystem is already active.
    node3:  The GPFS subsystem is already active.
    yum install iproute -y

12.查看集群状态:

[root@node1 ~]# mmgetstate -Lsa
​Node number  Node name       Quorum  Nodes up  Total nodes  GPFS state  Remarks    
------------------------------------------------------------------------------------1      node1              2        0          2       arbitrating quorum node2      node2              2        0          2       arbitrating quorum node
​Summary information 
---------------------
mmgetstate: Information cannot be displayed.  Either none of thenodes in the cluster are reachable, or GPFS is down on all of the nodes.

13.查看GPFS集群日志:

[root@node1 ras]# tail -f /var/adm/ras/mmsdrserv.log 
2023-08-31_01:57:40.570-0400: 2063787904 [N] Starting CCR serv ...
2023-08-31_02:11:42.723-0400: 2022106880 [N] CCR: Resetting previous state before 'initialization' enter
2023-08-31_02:11:42.728-0400: 2022106880 [N] CCR: initialization complete; cluster 1484988891360405094 node 1 epoch 0 err 0
2023-08-31_02:35:16.673-0400: 2617968512 [N] Starting CCR serv ...
2023-08-31_02:48:53.968-0400: 2576287488 [N] CCR: Resetting previous state before 'initialization' enter
2023-08-31_02:48:53.983-0400: 2576287488 [N] CCR: initialization complete; cluster 1484988891360408201 node 1 epoch 0 err 0
which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
2023-08-31_03:49:15.246-0400: 2769160064 [N] Starting CCR serv ...
2023-08-31_03:49:15.712-0400: 2727479040 [N] CCR: Resetting previous state before 'initialization' enter
2023-08-31_03:49:15.717-0400: 2727479040 [N] CCR: initialization complete; cluster 1484988891360413006 node 1 epoch 0 err 0

14.释放文件锁:

  • 有时候会出现无法执行命令无法读取配置文件的错误

  • 原因:有命令正在执行没有释放文件锁,所以我们无法获取

  • 解决方法如下:

  • 查看是否存在配置文件锁:

    [root@node1 ~]# mmcommon showLocks
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    lockServer                  lockName         lockHolder                  PID     Extended Info
    ----------------------------------------------------------------------------------------------
    node1                       mmfsEnvLock      node1                       12546    12546   2432 /usr/lpp/mmfs/bin/mmksh /usr/lpp/mmfs/bin/mmdelnsd -p C0A80A6564F056B9
    CCR                         mmSdrLock        node1                       12546    12546   2432 /usr/lpp/mmfs/bin/mmksh /usr/lpp/mmfs/bin/mmdelnsd -p C0A80A6564F056B9
  • 释放文件锁:

    [root@node1 ~]# mmcommon freeLocks mmfsEnvLock

14.创建NSD磁盘:

  • 修改配置文件:

    usage属性值说明
    dataAndMetadata表示该磁盘存储GPFS文件系统的数据和元数据(默认情况);用于系统池中的磁盘
    dataOnly表示该磁盘只存储GPFS文件系统的数据;
    metadataOnly表示该磁盘只存储GPFS文件系统的元数据;
    descOnly表示该磁盘既没有元数据也没有数据;仅用于保存文件系统描述符(灾难恢复)
    localCache表示该磁盘作为本地只读缓存
    # NSD磁盘的名称
    %nsd: nsd=NSD_1
    # 磁盘路径
    device=/dev/sdb
    # 节点列表,最前的最先IO,如果前面的节点故障后面的接管
    servers=node1 node2
    # GPFS文件系统的存储方式
    usage=dataAndMetadata
    # 用于指定NSD(Network Shared Disk)共享磁盘所属的故障组,如果将多个NSD分配到同一个故障组中,GPFS将确保文件系统的数据在这些NSD之间分布均匀,以提供冗余和容错性。
    failureGroup=100
    # 用于指定NSD(Network Shared Disk)共享磁盘所属的存储池,存储池是GPFS中的一个概念,它允许您将存储资源组织和分配给不同的文件系统或目录。通过将NSD分配给特定的存储池,您可以更好地控制和管理文件系统的存储资源。
    pool=system
    cat << eof > /tmp/nsd.node
    %nsd: nsd=NSD_1
    device=/dev/sdb
    servers=node1,node2
    usage=dataAndMetadata
    failureGroup=100
    pool=system
    ​
    %nsd: nsd=NSD_2
    device=/dev/sdc
    servers=node1,node2
    usage=dataAndMetadata
    failureGroup=100
    pool=system
    eof

  • 使用mmcrnsd命令创建NSD磁盘

    mmcrnsd命令参数说明
    -F指定配置文件
    -v验证磁盘是否已格式化为NSD(默认yes),
    -A指定是否将NSD标记为可共享,即是否允许多个节点访问(默认no)
    -p用于指定NSD(Network Shared Disk)共享磁盘所属的存储池,
    -t指定NSD的描述文本,提供有关该NSD的描述信息
    -s指定NSD的大小。通常,如果未指定 -s 参数,GPFS 会自动检测磁盘的大小
    -f用于指定NSD(Network Shared Disk)共享磁盘所属的故障组
    -h显示命令的帮助信息
    -m将NSD分配给的存储池的编号
    [root@node1 src]# mmcrnsd -F /tmp/nsd.node -v no
    mmcrnsd: Processing disk sdb
    mmcrnsd: Processing disk sdc
    mmcrnsd: Processing disk sdb
    mmcrnsd: Processing disk sdc
    mmcrnsd: Propagating the cluster configuration data to allaffected nodes.  This is an asynchronous process.
  • 查看nsd信息:

    [root@node1 ~]# mmlsnsd -m
    ​Disk name    NSD volume ID      Device         Node name                Remarks       
    ---------------------------------------------------------------------------------------NSD_1        C0A80A656501153A   /dev/sdb       node1                    server nodeNSD_1        C0A80A656501153A   /dev/sdb       node2                    server nodeNSD_2        C0A80A656501153C   /dev/sdc       node1                    server nodeNSD_2        C0A80A656501153C   /dev/sdc       node2                    server node
  • 查看NSD配置文件:

    [root@node1 ~]# cat cat /tmp/nsd.node
    cat: cat: No such file or directory
    # /dev/sdb:node1::dataAndMetadata:1:nsd1:
    nsd1:::dataAndMetadata:1::system
    # /dev/sdc:node2::dataAndMetadata:1:nsd2:
    nsd2:::dataAndMetadata:1::system

15.配置tiebreaker仲裁盘:

  • 仲裁盘作用:

    • 当定义的仲裁盘有一半的磁盘不可用时,该集群不可用。

    • 有效磁盘数小于等于整个磁盘数一半时,整个文件系统不可用

  • 配置仲裁盘:

    mmchconfig tiebreakerDisks="NSD_1;NSD_2"

16.在线添加NSD:

  • 添加一块共享硬盘:

    [root@node3 ~]# lsblk
    NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda               8:0    0   20G  0 disk 
    |-sda1            8:1    0    1G  0 part /boot
    `-sda2            8:2    0   19G  0 part |-centos-root 253:0    0   17G  0 lvm  /`-centos-swap 253:1    0    2G  0 lvm  [SWAP]
    sdb               8:16   0    5G  0 disk 
    `-sdb1            8:17   0    5G  0 part 
    sdc               8:32   0    5G  0 disk 
    `-sdc1            8:33   0    5G  0 part 
    sdd               8:48   0    5G  0 disk 
    sr0              11:0    1  9.5G  0 rom  /mnt/cdrom
  • 修改配置文件:

    usage属性值说明
    dataAndMetadata表示该磁盘存储GPFS文件系统的数据和元数据(默认情况);用于系统池中的磁盘
    dataOnly表示该磁盘只存储GPFS文件系统的数据;
    metadataOnly表示该磁盘只存储GPFS文件系统的元数据;
    descOnly表示该磁盘既没有元数据也没有数据;仅用于保存文件系统描述符(灾难恢复)
    localCache表示该磁盘作为本地只读缓存
    # NSD磁盘的名称
    %nsd: nsd=NSD_1
    # 磁盘路径
    device=/dev/sdb
    # 节点列表,最前的最先IO,如果前面的节点故障后面的接管
    servers=node1 node2
    # GPFS文件系统的存储方式
    usage=dataAndMetadata
    # 用于指定NSD(Network Shared Disk)共享磁盘所属的故障组,如果将多个NSD分配到同一个故障组中,GPFS将确保文件系统的数据在这些NSD之间分布均匀,以提供冗余和容错性。
    failureGroup=100
    # 用于指定NSD(Network Shared Disk)共享磁盘所属的存储池,存储池是GPFS中的一个概念,它允许您将存储资源组织和分配给不同的文件系统或目录。通过将NSD分配给特定的存储池,您可以更好地控制和管理文件系统的存储资源。
    pool=system
    cat << eof > /tmp/nsd.node
    %nsd: nsd=NSD_1
    device=/dev/sdb
    servers=node1,node2
    usage=dataAndMetadata
    failureGroup=100
    pool=system
    ​
    %nsd: nsd=NSD_2
    device=/dev/sdc
    servers=node1,node2
    usage=dataAndMetadata
    failureGroup=100
    pool=system
    ​
    %nsd: nsd=NSD_3
    device=/dev/sdd
    servers=node1,node2
    usage=dataAndMetadata
    failureGroup=100
    pool=system
    eof
  • 使用mmcrnsd命令创建NSD磁盘:

    mmcrnsd命令参数说明
    -F指定配置文件
    -v验证磁盘是否已格式化为NSD(默认yes),
    -A指定是否将NSD标记为可共享,即是否允许多个节点访问(默认no)
    -p用于指定NSD(Network Shared Disk)共享磁盘所属的存储池,
    -t指定NSD的描述文本,提供有关该NSD的描述信息
    -s指定NSD的大小。通常,如果未指定 -s 参数,GPFS 会自动检测磁盘的大小
    -f用于指定NSD(Network Shared Disk)共享磁盘所属的故障组
    -h显示命令的帮助信息
    -m将NSD分配给的存储池的编号
    [root@node1 src]# mmcrnsd -F /tmp/nsd.node -v no
    mmcrnsd: Processing disk sdb
    mmcrnsd: Processing disk sdc
    mmcrnsd: Processing disk sdb
    mmcrnsd: Processing disk sdc
    mmcrnsd: Propagating the cluster configuration data to allaffected nodes.  This is an asynchronous process.
  • 查看nsd信息:

    [root@node1 ~]# mmlsnsd -m
    ​Disk name    NSD volume ID      Device         Node name                Remarks       
    ---------------------------------------------------------------------------------------NSD_1        C0A80A656501153A   /dev/sdb       node1                    server nodeNSD_1        C0A80A656501153A   /dev/sdb       node2                    server nodeNSD_2        C0A80A656501153C   /dev/sdc       node1                    server nodeNSD_2        C0A80A656501153C   /dev/sdc       node2                    server nodeNSD_3        C0A80A6565011BB5   /dev/sdd       node1                    server nodeNSD_3        C0A80A6565011BB5   /dev/sdd       node2                    server node

17.删除NSD磁盘:

  • 查看是否存在配置文件锁:

    [root@node1 ~]# mmcommon showLocks
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    lockServer                  lockName         lockHolder                  PID     Extended Info
    ----------------------------------------------------------------------------------------------
    node1                       mmfsEnvLock      node1                       12546    12546   2432 /usr/lpp/mmfs/bin/mmksh /usr/lpp/mmfs/bin/mmdelnsd -p C0A80A6564F056B9
    CCR                         mmSdrLock        node1                       12546    12546   2432 /usr/lpp/mmfs/bin/mmksh /usr/lpp/mmfs/bin/mmdelnsd -p C0A80A6564F056B9
  • 释放文件锁:

    [root@node1 ~]# mmcommon freeLocks mmfsEnvLock
  • 查看存在的NSD磁盘:

    [root@node1 ~]# mmlsnsd -m
    which: no ip in (/bin:/usr/bin:/sbin:/usr/sbin:/usr/lpp/mmfs/bin)
    ​Disk name    NSD volume ID      Device         Node name                Remarks       
    ---------------------------------------------------------------------------------------nsd1         C0A80A6564F056B9   /dev/sdb       node1                    server nodensd1         C0A80A6564F056B9   /dev/sdb       node2                    nsd2         C0A80A6564F056BB   /dev/sdc       node1                    server nodensd2         C0A80A6564F056BB   /dev/sdc       node2                    nsd3         C0A80A6664F056BC   /dev/sdd       node1                    nsd3         C0A80A6664F056BC   /dev/sdd       node2                    server nodensd4         C0A80A6664F056BE   /dev/sde       node1                    nsd4         C0A80A6664F056BE   /dev/sde       node2                    server node
  • 删除NSD磁盘:

    [root@node1 ~]# mmdelnsd nsd1
    [root@node1 ~]# mmdelnsd -F /tmp/nsd.node

18.创建GPFS文件系统:

  • 参数:

    参数说明
    /gpfs1文件系统 mount 点名称
    /dev/gpfs1指定文件系统 lv 名称
    -F指定 NSD 的文件名
    -A自动 mount 选项为 yes
    -B块大小为512K
    -n代表该集群最大支持节点数
    -j代表存储工作方式为集群方式
    -Q代表打开磁盘配额管理功能
  • 创建GPFS文件系统:

    [root@node1 ~]# mmcrfs /gpfs1 /dev/gpfs1 -F /tmp/nsd.node -A yes -B 512k -m 1 -M 2 -r 1 -R 2 -n 512 -j cluster -Q yes
    ​
    The following disks of gpfs1 will be formatted on node node1:nsd1: size 5120 MBnsd2: size 5120 MB
    Formatting file system ...
    Disks up to size 596 GB can be added to storage pool system.
    Creating Inode File
    Creating Allocation Maps
    Creating Log Files
    Clearing Inode Allocation Map
    Clearing Block Allocation Map
    Formatting Allocation Map for storage pool system
    Completed creation of file system /dev/gpfs1.
    mmcrfs: Propagating the cluster configuration data to allaffected nodes.  This is an asynchronous process.
  • 查看集群状态:

    [root@node1 ~]# mmgetstate -a                    # 查看集群状态,所有节点为active,则集群正常启动
    ​Node number  Node name        GPFS state 
    ------------------------------------------1      node1            active2      node2            active
    [root@node1 ~]# mmlsconfig
    Configuration data for cluster gpfs-node1-2.node1:
    --------------------------------------------------
    clusterName gpfs-node1-2.node1
    clusterId 1484988891361513241
    autoload yes
    dmapiFileHandleSize 32
    minReleaseLevel 4.2.3.9
    ccrEnabled yes
    cipherList AUTHONLY
    tiebreakerDisks NSD_1;NSD_2
    adminMode central
    ​
    File systems in cluster gpfs-node1-2.node1:
    -------------------------------------------
    /dev/gpfs1

19.挂载GPFS文件系统:

mmmount all -a                             # 在所有节点挂载所有GPFS
mmmount /gpfs1 -N node1                    # 在某节点挂载某GPFS文件系统
[root@node1 src]# mmlsmount gpfs1 -LFile system gpfs1 is mounted on 3 nodes:192.168.10.101  node1                     192.168.10.102  node2                     192.168.10.111  client-side    
  • 报错1:

    [root@node1 gpfs1]# mmumount gpfs1 -N node2 
    Wed Sep 13 10:19:32 EDT 2023: mmumount: Unmounting file systems ...
    node2:  /bin/ksh: /usr/lpp/mmfs/bin/mmremote: not found
    mmumount: Command failed. Examine previous error messages to determine cause.
    # 安装gpfs-base软件包
    rpm -ivh gpfs.base-4.2.3-22.x86_64.rpm

相关文章:

搭建GPFS双机集群

1.环境说明&#xff1a; 系统主机名IP地址内存添加共享磁盘大小Centos7.9gpfs1192.168.10.1012G20GCentos7.9gpfs2192.168.10.1022G20G 2.环境配置&#xff1a; 配置网路IP地址&#xff1a; 修改网卡会话&#xff1a; nmcli connection modify ipv4.method manual ipv4.addre…...

【试题032】C语言关系运算符例题

1.题目&#xff1a;设int a2,b4,c5;&#xff0c;则表达式ab!c>b>a的值为&#xff1f; 2.代码分析&#xff1a; //设int a2,b4,c5;&#xff0c;则表达式ab!c>b>a的值为?int a 2, b 4, c 5;printf("%d\n", (a b ! c > b > a));//分析&#xff…...

系列四、FileReader和FileWriter

一、概述 FileReader 和 FileWriter 是字符流&#xff0c;按照字符来操作IO。 1.1、继承体系 二、FileReader常用方法 new FileReader(File/String)# 每次读取单个字符就返回&#xff0c;如果读取到文件末尾返回-1 read()# 批量读取多个字符到数组&#xff0c;返回读取的字节…...

【C++面向对象】2.构造函数、析构函数

文章目录 【 1. 构造函数 】1.1 带参构造函数--传入数据1.2 无参构造函数--不传入数据1.3 实例1.4 拷贝构造函数 【 2. 析构函数 】 【 1. 构造函数 】 类的构造函数是类的一种特殊的成员函数&#xff0c;它会 在每次创建类的新对象时执行。 构造函数的名称与类的名称是完全相同…...

uniapp:使用subNVue原生子窗体在map上层添加自定义组件

我们想要在地图上层添加自定义组件&#xff0c;比如一个数据提示框&#xff0c;点一下会展开&#xff0c;再点一下收起&#xff0c;在h5段显示正常&#xff0c;但是到app端真机测试发现组件显示不出来&#xff0c;这是因为map是内置原生组件&#xff0c;层级最高&#xff0c;自…...

Flutter开发GridView控件详解

GridView跟ListView很类似&#xff0c;Listview主要以列表形式显示数据&#xff0c;GridView则是以网格形式显示数据&#xff0c;掌握ListView使用方法后&#xff0c;会很轻松的掌握GridView的使用方法。 在某种界面设计中&#xff0c;如果需要很多个类似的控件整齐的排列&…...

Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

一、Object.defineProperty 定义&#xff1a;Object.defineProperty() 方法会直接在一个对象上定义一个新属性&#xff0c;或者修改一个对象的现有属性&#xff0c;并返回此对象 为什么能实现响应式 通过defineProperty 两个属性&#xff0c;get及set get 属性的 getter 函…...

pytest利用request fixture实现个性化测试需求详解

这篇文章主要为大家详细介绍了pytest如何利用request fixture实现个性化测试需求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下− 前言 在深入理解 pytest-repeat 插件的工作原理这篇文章中&#xff0c;我们看到pytest_repeat源码中有这样一段 import pyt…...

算法练习16——O(1) 时间插入、删除和获取随机元素

LeetCode 380 O(1) 时间插入、删除和获取随机元素 实现RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象 bool insert(int val) 当元素 val 不存在时&#xff0c;向集合中插入该项&#xff0c;并返回 true &#xff1b;否则&#xff0c;返回 false 。 …...

实时数据更新与Apollo:探索GraphQL订阅

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…...

VMware Workstation里面安装ubuntu20.04的流程

文章目录 前言一、获取 desktop ubuntu20.04 安装镜像二、VMware Workstation下安装ubuntu20.041. VMware Workstation 创建一个新的虚拟机2. ubuntu20.04的安装过程3. 登录ubuntu20.044. 移除 ubuntu20.04 安装镜像总结参考资料前言 本文主要介绍如何在PC上的虚拟机(VMware W…...

pnpm的环境安装以及安装成功后无法使用的问题

文章目录 前言1、使用npm 安装2、安装后的注意点3、遇到问题4、配置path的环境变量&#xff08;1&#xff09;找到环境变量&#xff08;2&#xff09;找到并双击path的系统变量&#xff08;3&#xff09;复制第1步中使用npm安装的红框部分的路径&#xff08;4&#xff09;将第&…...

华为eNSP配置专题-浮动路由及BFD的配置

文章目录 华为eNSP配置专题-浮动路由及BFD的配置0、参考文档1、前置环境1.1、宿主机1.2、eNSP模拟器 2、基本环境搭建2.1、基本终端构成和连接2.2、基本终端配置 3、浮动路由配置3.1、浮动路由的基本配置3.2、浮动路由的负载均衡问题3.3、浮动路由的优先级调整 4、BFD的配置4.1…...

光储并网直流微电网simulink仿真模型,光伏采用mppt实现最大功率输出研究

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

面试题-React(十六):理解Redux及其工作原理

在现代前端开发中&#xff0c;状态管理是一个关键的问题。Redux是一个广泛使用的状态管理库&#xff0c;可以帮助开发者更有效地管理应用的状态。 一、什么是Redux&#xff1f; Redux是一个JavaScript状态管理库&#xff0c;用于管理应用中的状态&#xff08;state&#xff0…...

Crypto(4)NewStarCTF 2023 week2 Crypto Rotate Xor

题目代码: # 导入所需的库和从secret模块加载"flag" from secret import flag from os import urandom from pwn import xor from Cryptodome.Util.number import *# 生成两个随机的 64 位素数&#xff0c;分别存储在变量 k1 和 k2 中 k1 getPrime(64) k2 getPrim…...

小程序-uni-app:将页面(html+css)生成图片/海报/名片,进行下载 保存到手机

一、需要描述 本文实现&#xff0c;uniapp微信小程序&#xff0c;把页面内容保存为图片&#xff0c;并且下载到手机上。 说实话网上找了很多资料&#xff0c;但是效果不理想&#xff0c;直到看了一个开源项目&#xff0c;我知道可以实现了。 本文以开源项目uniapp-wxml-to-can…...

Vue非单文件组件

组件就是用来实现局部特定功能效果的代码集合&#xff0c;为的就是复用编码&#xff0c;简化项目编码&#xff0c;提高运行效率。 组件分为非单文件组件和单文件组件&#xff0c;这里介绍的是非单文件组件。 一、创建组件 创建组件的语法格式如下&#xff1a; const 组件名 …...

批量xls转换为xlsx

import win32com.client as win32 import os# 另存为xlsx的文件路径 xlsx_file r"F:\志丹\1020Excel汇总\成果表备份\xlsx" xls_file r"F:\志丹\1020Excel汇总\成果表备份" for file in os.scandir(xls_file):suffix file.name.split(".")[-1…...

行情分析——加密货币市场大盘走势(10.20)

大饼昨日迅猛上涨&#xff0c;并在今日依然上涨&#xff0c;目前处在蓝色上涨趋势线&#xff0c;上涨趋势依然在。中长线可以考虑过几天止损或者继续持有。目前MACD日线呈现绿色实心5天&#xff0c;预计明后天可能会绿色空心&#xff0c;注意后续空头的到来&#xff0c;注意多单…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...