记一次MySQL数据恢复处理

前因:

今天星期六,上午正在逛市场,突然老板打电话来说服务器掉线了,刚开始以为只是普通问题,让自己联系机房就好了,先把服务器跑起来,让用户可以访问,一些自动化处理程序等我回去了再启动。

结果机房说服务器系统坏了,跑不起来,只能重新搭建服务
于是赶紧回家,让机房把硬盘挂到别的机器上,想办法把数据给弄出来
把旧硬盘挂到新机器后,开始了数据操作,一开始想的是把旧硬盘的MySQL跑起来,在用工具导出来就好了,结果MySQL跑不起来了。

由于新机器没有按照任何环境,无法直接使用systemctl start mysql,新机器也没有MySQL的配置文件,于是另辟蹊径

1.找个新的配置文件(my.cnf) 放到 /etc/my.conf(刚好旧硬盘里有之前的my.cnf文件)
2.进入MySQL的安装目录直接操作 ./mysql --defaults-file=/etc/my.cnf (--defaults-file=/etc/my.cnf 指定启动的配置文件)
3.启动

报错

[root@xslmbllajezxnqw bin]# ./mysqld --defaults-file=/etc/my.cnf
2024-11-23T15:00:17.085523Z 0 [Warning] [MY-000081] [Server] option 'max_allowed_packet': unsigned value 107374182400 adjusted to 1073741824.
2024-11-23T15:00:17.085604Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2024-11-23T15:00:17.085714Z 0 [System] [MY-010116] [Server] /data/www/server/mysql/bin/mysqld (mysqld 8.0.24) starting as process 31595
2024-11-23T15:00:17.099843Z 0 [ERROR] [MY-010123] [Server] Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!
2024-11-23T15:00:17.100066Z 0 [ERROR] [MY-010119] [Server] Aborting
2024-11-23T15:00:17.118879Z 0 [System] [MY-010910] [Server] /data/www/server/mysql/bin/mysqld: Shutdown complete (mysqld 8.0.24)  Source distribution

注意报错信息同有个 Please read "Security" section of the manual to find out how to run mysqld as root! 提示,要求不能使用root用户启动

于是再创建一个账户useradd www
将MySQL的数据目录所有权更改为www用户

再次启动./mysqld --defaults-file=/etc/my.cnf --user=www

[root@xslmbllajezxnqw bin]# ./mysqld --defaults-file=/etc/my.cnf --user=www
2024-11-23T07:48:47.965407Z 0 [Warning] [MY-000081] [Server] option 'max_allowed_packet': unsigned value 107374182400 adjusted to 1073741824.
2024-11-23T07:48:47.965490Z 0 [Warning] [MY-010915] [Server] 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release.
2024-11-23T07:48:47.965601Z 0 [System] [MY-010116] [Server] /data/www/server/mysql/bin/mysqld (mysqld 8.0.24) starting as process 26261
2024-11-23T07:48:48.008578Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2024-11-23T07:48:54.506873Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2024-11-23T07:48:54.745099Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /tmp/mysqlx.sock
2024-11-23T07:48:55.075232Z 0 [Warning] [MY-013595] [Server] Failed to initialize TLS for channel: mysql_main. See below for the description of exact issue.
2024-11-23T07:48:55.075566Z 0 [Warning] [MY-010069] [Server] Failed to set up SSL because of the following SSL library error: <%.*s|%.*s
2024-11-23T07:48:55.138937Z 0 [Warning] [MY-011302] [Server] Plugin mysqlx reported: 'Failed at SSL configuration: "SSL context is not usable without certificate and private key"'
2024-11-23T07:48:55.139080Z 0 [System] [MY-010931] [Server] /data/www/server/mysql/bin/mysqld: ready for connections. Version: '8.0.24'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution.

成功

只要MySQL跑起来,后面安装普遍流程来操作就可以了

  • navcat
  • mysqldump

用上面的任一都行

写这篇文章用时30分钟不到,按照我一开始的想法是对的,但实际解决这个问题搞了大半天,期间老板一直再问好了吗? ,搞得我快要爆炸了

使用shell拉取代码并部署

#!/bin/bash

# @Author: admin
# @Date:   2023-11-22 17:20:22
# @Last Modified by:   admin
# @Last Modified time: 2023-11-22 20:58:01

# 添加部署脚本
# 首先给脚本执行权限 chmod +x ./deploy.sh
# 使用: ./gitee.sh
# 或: ./deploy.sh www  // www为最终发布目录的所属用户
# 源码将发布到 destDir设置的目录下

# read -p "请输入gitee账号 :" username

# while true
# do
#         if [ ! -n "$username" ];then
#                 read -p "必须输入请输入gitee账号 或者q退出:" username

#         else
#                 if [ "$username" = "q" ];then
#                         exit 0
#                     else
#                         break
#                 fi

#         fi

# done

# read -p "请输入gitee密码 :" password

# while true
# do
#         if [ ! -n "$password" ];then
#                 read -p "必须输入请输入gitee密码 或者q退出:" password

#         else
#                 if [ "$password" = "q" ];then
#                         exit 0
#                     else
#                         break
#                 fi

#         fi

# done


echo '--初始化目录--'
# 临时目录,多个仓库应该使用不同的临时目录
tmpDir="$(pwd)/.qqmasterTemp"
# 部署目录不能与脚本所有目录相同
newDir="$(pwd)/qqmaster"


if [ ! -e "$tmpDir" ];then

    mkdir "$tmpDir"
fi

if [ ! -e "$newDir" ];then

    mkdir "$newDir"
fi



# 代码仓库目录 deploy:gitlab-ci-token修改为部署令牌和密码,也可以是gitlab用户和密码
repository="https://gitee.com/wangzh/qqmaster.git"


# if [ -d $tmpDir ]
# then
#     rm -rf $tmpDir
# fi

echo '--拉取代码--'
git clone $repository $tmpDir

echo '--拉取完成--'

#切換分支
echo '--切換分支--'
cd $tmpDir && git checkout dev

echo '--刪除不能覆蓋的文件--'
cd $tmpDir && rm -rf ApiAdmin/.env && rm -rf ApiAdmin/config && rm -rf ApiAdmin/.git && rm -rf ApiAdmin/cert


# 拷贝源码到部署目录
echo '--拷贝源码到部署目录--'
cd $tmpDir && cp -rf "./" $newDir

echo '--为项目赋权--'
cd $newDir && sudo -S chown -R www:www ./*  && sudo -S chmod -R 755 ./*

echo '--移除临时目录--'
rm -rf $tmpDir


echo "--发布完成--"

此方法的好处是可以避免一些冲突提示

此方法的缺点是仓库用的是码云的,每次使用https方式拉取都要输入账号密码

Linux硬盘挂载

输入 lsblk-f 查看所有设备的挂载情况
2023-11-13T03:12:04.png
例如我的是 /dev/sdb

将新添加的硬盘分区 输入命令fdisk /dev/sdb
2023-11-13T03:12:11.png
输入p创建主分区
2023-11-13T03:12:29.png
默认1即可
2023-11-13T03:13:00.png

分区创建好了之后 输入 w 保存退出
2023-11-13T03:14:18.png

分区创建好了之后 将分区格式化 格式化命令 mkfs -t ext4 /dev/sdb
2023-11-13T03:14:55.png

所有操作完成后就可以开始挂载了
mount /dev/sdb /指定文件的路径

挂载完后后设置开机自动挂载

先使用 df -TH 查看硬盘列表
2023-11-13T03:17:24.png

查看挂载的磁盘属性
2023-11-13T03:18:44.png

打开配置文件,写入自动配置
2023-11-13T03:19:42.png

参数说明:
第一列为UUID,此处填写查询到的磁盘分区的UUID
第二列为磁盘分区的挂载目录,可以通过df -TH命令查询
第三列为磁盘分区的文件系统格式,可以通过df -TH命令查询
第四列为磁盘分区的挂载选项,此处通常设置为defaults即可
第五列为Linux dump备份选项
(1) 0表示不使用Linux dump备份。现在通常不使用dump备份,此处设置为0即可。
(2) 表示使用Linux dump备份。
第六列为fsck选项,即开机时是否使用fsck检查磁盘。
(1) 0表示不检验。
(2) 挂载点为(/)根目录的分区,此处必须填写1。
(3) 根分区设置为1,其他分区只能从2开始,系统会按照数字从小到大依次检查下去。

最后保存配置即可

sh脚本拉取线上代码部署网站

#!/bin/bash

# 添加部署脚本
# 首先给脚本执行权限 chmod +x ./deploy.sh
# 使用: ./deploy.sh
# 或: ./deploy.sh www  // www为最终发布目录的所属用户
# 源码将发布到 destDir设置的目录下

user=${1:-"none"}
# 当前用户密码,用于sudo提权
sudoPwd=""
# 临时目录,多个仓库应该使用不同的临时目录
tmpDir="$(pwd)/.deploy"
# 部署目录不能与脚本所有目录相同
destDir="$(pwd)/destDir"
# 代码仓库目录 deploy:gitlab-ci-token修改为部署令牌和密码,也可以是gitlab用户和密码
repository="http://deploy:gitlab-ci-token@git仓库地址"

echo '初始化目录'
if [ -d $tmpDir ]
then
    rm -rf $tmpDir
fi

echo '拉取代码'
git clone $repository $tmpDir

rm -rf $tmpDir/.git
echo '发布代码'
# 拷贝源码到部署目录
cp -rf $tmpDir $destDir

if [ "$user" != "none" ]
then
    if [ "$sudoPwd" = "" ]
    then
        echo '缺少用户密码'
        exit 1
    fi
    # 修改目录权限
    echo "$sudoPwd" | sudo -S chown -R $user: $destDir
fi

echo '移除仓库'
rm -rf $tmpDir

echo '发布完成'

搭建ssr

CentOS 6和7/Debian6+/Ubuntu14+ ShadowsocksR/Shadowsocks一键部署管理脚本:

yum -y install wget
wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubiBackup/doubi/master/ss-go.sh && chmod +x ss-go.sh && bash ss-go.sh
  • 如果搭建SSR账号,请使用脚本一,目前推荐的SSR参数设置为以下,有利于突破网络封锁,参数如下:
  1. 加密方式:none 协议:origin 混淆:tls1.2_ticket_auth
  2. 加密方式:none 协议:auth_chain_a 混淆:tls1.2_ticket_auth
  3. 如果搭建SS账号,请使用脚本二,加密方式可选aes-256-gcm,或者高阶篇的SS+插件模式(推荐)
  4. 推荐搭建SSR账号。

安装完成后,快捷管理命令:

bash ssr.sh

编写shell脚本快速切换PHP版本

由于我是在windows的wsl搭建的PHP环境,包括7.3、7.4、8.0多个PHP版本,测试的时候,有的程序需要某个版本才能运行,手动创建环境变量太麻烦,于是写了我的第一个shell,于是记录下

#!/bin/bash
#第一次提示
read -p "请输入版本号【7.3】、【7.4】、【8】:" version

#如果未输入,则强制要求输入
while [ ! "$version" ]
        do
        if [ ! -n "$version" ]; then
                read -p "必须输入版本号【7.3】、【7.4】、【8】:" version
        fi
done


#先删除现在的环境
rm -rf /usr/bin/php
rm -rf /usr/bin/phpize
rm -rf /usr/bin/php-fpm

#根据输入的版本号创建新的环境变量
case $version in
        7.3)
                #echo "你输入了${version} (7.3 对吗?)"
                ln -s  /usr/local/php/bin/php /usr/bin/php
                ln -s  /usr/local/php/bin/phpize /usr/bin/phpize
                ln -s  /usr/local/php/sbin/php-fpm /usr/bin/php-fpm
        ;;
        7.4)
                #echo "你输入了${version}(7.4对吗)"
                ln -s  /usr/php/74/bin/php /usr/bin/php
                ln -s  /usr/php/74/bin/phpize /usr/bin/phpize
                ln -s  /usr/php/74/sbin/php-fpm /usr/bin/php-fpm
        ;;
        8)
                #echo "你输入了${version}(8对吗)"
                ln -s  /usr/local/php8/bin/php /usr/bin/php
                ln -s  /usr/local/php8/bin/phpize /usr/bin/phpize
                ln -s  /usr/local/php8/sbin/php-fpm /usr/bin/php-fpm
        ;;
        *)
                echo "当前系统未安装此版本号的PHP,无法切换"
        ;;
esac

#检查下是否成功切换
        echo "你已成功切换到${version}"![微信截图_20211029113209.png][1]
        echo "======================================================"
                php -v
        echo "======================================================"

请输入图片描述

解决TP5在命令行创建文件没有权限写入的方法

例如workerman指定user为www运行
在cli模式下创建的文件是root权限的,无法写入log导致程序无法执行

找到 thinkphp\library\think\log\driver\File.php 文件
write 方法中 最后一行添加以下代码

try {
//判断操作文件不是0777权限 就修改
if (substr(base_convert(fileperms($destination),10,8),-4) != '0777') {
  chmod($destination, 0777);
}
            
} catch (\Exception $e) {

}

Linux命令输出头(标题)、输出结果排序技巧

1、 Linux命令输出头(标题)
在使用Linux命令时,如果命令中有管道“|”,则输出的信息中,头(标题)信息丢失,要想看每一列代表什么意思很不方便。

这里有一个简单的办法,通过2条命令叠加,获取头和内容。例如ps auxw:

$ ps axuw
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  37888  5952 ?        Ss   01:21   0:02 /sbin/init noprompt
root         2  0.0  0.0      0     0 ?        S    01:21   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    01:21   0:00 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   01:21   0:00 [kworker/0:0H]

再加上管道符后

$ ps axuw | grep java
faster    8502  0.0  0.0  12948   972 pts/1    S+   02:15   0:00 grep java

可以看到头(标题)已经丢失。

怎么显示标题呢,这有一个简单的办法:

$ ps axuw | head -1;ps axuw | grep java
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
faster    8510  0.0  0.0  12948   940 pts/1    S+   02:17   0:00 grep java

也就是先用命令本身加“| head -1”取到头(标题),然后再使用该命令输出内容,两者叠加输出即得到所要结果。

2、输出结果排序
按列排序,数字大的在前:

root@ubuntu:/home/faster/Fastdfs/FastDFS# ps auxw | sort -rn -k6
root       851  0.2  1.6 408816 33224 ?        Ssl  01:21   0:10 /usr/bin/docker daemon -H fd://
root       868  0.0  0.6 213068 13320 ?        Ssl  01:21   0:02 containerd -l /var/run/docker/libcontainerd/docker-containerd.sock --runtime runc --start-timeout 2m
root      8452  0.0  0.3  95584  7212 ?        Ss   01:47   0:00 sshd: tiger [priv]
root       980  0.0  0.3  95464  7088 ?        Ss   01:21   0:00 sshd: tiger [priv]
root      1044  0.0  0.3  95464  7048 ?        Ss   01:23   0:00 sshd: tiger [priv]
root       854  0.0  0.3  65612  6616 ?        Ss   01:21   0:00 /usr/sbin/sshd -D
root       592  0.0  0.3 274592  6240 ?        Ssl  01:21   0:00 /usr/lib/accountsservice/accou

该例子,将第6列进行排序,最大的数排前面。

若只想看前10条的内容:

ps auxw | sort -rn -k6 | head -10

3、综合例子
将实际内存消耗最大的10个进程显示出来的命令:

ps auxw|head -1;ps auxw|sort -rn -k6|head -10

$ ps auxw|head -1;ps auxw|sort -rn -k6|head -10
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       851  0.2  1.6 408816 33224 ?        Ssl  01:21   0:11 /usr/bin/docker daemon -H fd://
root       868  0.0  0.6 213068 13320 ?        Ssl  01:21   0:03 containerd -l /var/run/docker/libcontainerd/docker-containerd.sock --runtime runc --start-timeout 2m
root      8452  0.0  0.3  95584  7212 ?        Ss   01:47   0:00 sshd: tiger [priv]
root       980  0.0  0.3  95464  7088 ?        Ss   01:21   0:00 sshd: tiger [priv]
root      1044  0.0  0.3  95464  7048 ?        Ss   01:23   0:00 sshd: tiger [priv]
root       854  0.0  0.3  65612  6616 ?        Ss   01:21   0:00 /usr/sbin/sshd -D
root       592  0.0  0.3 274592  6240 ?        Ssl  01:21   0:00 /usr/lib/accountsservice/accounts-daemon
root         1  0.0  0.2  37888  5952 ?        Ss   01:21   0:02 /sbin/init noprompt
syslog     576  0.0  0.2 256396  5372 ?        Ssl  01:21   0:00 /usr/sbin/rsyslogd -n
faster    1137  0.0  0.2  21224  5272 pts/0    S    01:37   0:00 -su

该命令亦可使用ps auxw --sort=-rss|head -10命令替代。