23年的头一天上班安装数据库,因为ssh工具来回切换失误,犯下不可饶恕的错误,居然将生产数据库全部删除,工作十几年头一次干这种蠢事,第一时间反应是一世英名毁于一旦,赶紧跑路。第二反应还是想办法看能否挽回,无非扣钱。。。
1 mysql数据库编译安装
为什么会出现这个问题,是因为我在一台高配置的机器上编译安装mysql
CentOS7.9-源码编译安装mysql5.7.33【详细步骤】
编译安装MySQL
Mysql 5.7 编译安装
# 安装依赖
yum -y install wget gcc gcc-c++ cmake openssl-devel ncurses-devel zlib-devel bzip2
mkdir -p /appdata/mysqldata
groupadd -r -g 27 mysql
useradd -s /sbin/nologin -r -u 27 -g 27 -d /appdata/mysqldata mysql
# 下载mysql和boost
wget https://mirrors.tuna.tsinghua.edu.cn/mysql/downloads/MySQL-5.7/mysql-5.7.38-el7-x86_64.tar.gz
tar -zxvf mysql-5.7.38-el7-x86_64.tar.gz
wget https://mirrors.tuna.tsinghua.edu.cn/mysql/downloads/MySQL-5.7/mysql-boost-5.7.38.tar.gz
tar -zxvf mysql-boost-5.7.38.tar.gz
# 将boost解压后的文件移动到下面的目录
mv mysql-5.7.38 mysql-5.7.38-el7-x86_64/boost
#
cd /appdata/download/mysql-5.7.38-el7-x86_64/boost
# 执行编译
cmake . \
-DCMAKE_INSTALL_PREFIX=/appdata/mysql \
-DWITH_BOOST=/appdata/download/mysql-5.7.38-el7-x86_64/boost/boost/boost_1_59_0 \
-DMYSQL_UNIX_ADDR=/appdata/mysql/tmp/mysql.sock \
-DMYSQL_DATADIR=/appdata/mysqldata \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/appdata/mysqldata \
-DMYSQL_USER=mysql \
-DMYSQL_TCP_PORT=3306 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITHOUT_MROONGA_STORAGE_ENGINE=1 \
-DWITH_XTRADB_STORAGE_ENGINE=1 \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_EXTRA_CHARSETS=1 \
-DEXTRA_CHARSETS=all \
-DWITH_BIG_TABLES=1 \
-DWITH_DEBUG=0 \
-DWITH_READLINE=1 \
-DWITH_SSL=system \
-DWITH_ZLIB=system \
-DWITH_LIBWRAP=0 \
-DENABLED_LOCAL_INFILE=1 \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci
# 根据系统核心数启动编译进程加快编译速度
make -j `lscpu | grep -i '^cpu(s)'| tr -s ' ' '%' | cut -d% -f2` && make install
# 配置my.cnf
mkdir -p /appdata/mysql/tmp
mkdir -p /appdata/mysql/logs
touch /appdata/mysql/logs/bs6.bsspirit.cn.err
touch /appdata/mysql/bs6.bsspirit.cn.pid
touch /appdata/mysql/logs/sql_query_slow.log
chown -R mysql.mysql /appdata/mysql
chown -R mysql.mysql /appdata/mysqldata
# 添加环境变量
echo "PATH=$PATH:/appdata/mysql/bin" >> /etc/profile #将mysql变量加入系统变量
source /etc/profile #刷新环境变量文件
# 初始化数据库
cd /appdata/mysql/bin
./mysqld --initialize-insecure --user=mysql --basedir=/appdata/mysql --datadir=/appdata/mysqldata
cp /appdata/mysql/support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
service mysqld start
# 第一次回车即可,设置root用户的密码
mysqladmin -u root -p password "xxxxxx"
# 开启3306端口
systemctl status firewalld
firewall-cmd --permanent --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
# 修改root用户的登录访问限制
[root@bs6 appdata]# netstat -antp |grep 3306
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 49874/mysqld
tcp 0 0 192.168.0.6:3306 10.101.2.100:61307 TIME_WAIT -
# 进入到mysql中执行
flush hosts;
update user set host=@'%' where user='root' and host='localhost' limit 1;
2 还原数据库
mysqldata中的文件删掉,这个时候进程对应的句柄还在,此时千万不要重启mysql,否则这些数据都会丢失。
首先要做的是先将用户和订单等重要数据,通过程序的方式保存下载,因为如果连接还在,数据还可以获取到。
接着通过文件句柄恢复文件
cd /proc/进程id/fd
cp 199 /appdata/mysqldata/bsas/JSB_Info.ibd
# 接着一个个还原
执行ls -lR | grep "^-" | wc -l
核对每个目录文件与句柄数量是否一致了,我以为可以重启mysql了,结果发现下面的异常:
2023-01-03T19:25:18.384724+08:00 0 [Warning] InnoDB: Unable to open "./ib_logfile0" to check native AIO read support.
2023-01-03T19:25:18.384735+08:00 0 [Warning] InnoDB: Linux Native AIO disabled.
2023-01-03T19:25:18.385738+08:00 0 [Note] InnoDB: Initializing buffer pool, total size = 25.875G, instances = 23, chunk size = 128M
2023-01-03T19:25:19.824702+08:00 0 [Note] InnoDB: Completed initialization of buffer pool
2023-01-03T19:25:19.966630+08:00 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2023-01-03T19:25:19.978422+08:00 0 [ERROR] InnoDB: Cannot create log files in read-only mode
2023-01-03T19:25:19.978471+08:00 0 [ERROR] InnoDB: Plugin initialization aborted with error Read only transaction
调整/etc/my.cnf
的配置
#直接设置数据库的可读性
read_only=0
#在mysql中innodb_force_recovery参数是用来恢复数据库使用的 掉电恢复时会将innodb设为只读
innodb_force_recovery=0
再次重启,结果出现下面的异常,句柄中并没有sys_config
这张表,很无奈,如此恢复失败了。
2023-01-03T19:26:52.554150+08:00 0 [ERROR] InnoDB: Cannot open datafile for read-only: './sys/sys_config.ibd' OS error: 71
2023-01-03T19:26:52.554157+08:00 0 [ERROR] InnoDB: Operating system error number 2 in a file operation.
2023-01-03T19:26:52.554162+08:00 0 [ERROR] InnoDB: The error means the system cannot find the path specified.
2023-01-03T19:26:52.554167+08:00 0 [ERROR] InnoDB: If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them.
2023-01-03T19:26:52.554174+08:00 0 [ERROR] InnoDB: Could not find a valid tablespace file for `sys/sys_config`. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.
2023-01-03T19:26:52.554182+08:00 0 [Warning] InnoDB: Ignoring tablespace `sys/sys_config` because it could not be opened.
接着想到另外一个办法,既然数据文件的ibd
找到了,那么是否可以通过ibd
文件来恢复数据了。
于是在另外一个机器上部署mysql,然后在这台机器上创建对应数据库和数据表
在目标mysql中执行
truncate JSB_Info;
truncate SMS_push_record;
truncate User_Info;
alter table JSB_Info discard tablespace;
alter table SMS_push_record discard tablespace;
alter table User_Info discard tablespace;
在问题mysql中执行,将文件传到目标机器上
scp JSB_Info.ibd SMS_push_record.ibd User_Info.ibd root@192.168.0.6:/appdata/mysqldata/bsas
再回到目标mysql中
cd /appdata/mysqldata/bsas
chown mysql:mysql *
alter table JSB_Info import tablespace;
alter table SMS_push_record import tablespace;
alter table User_Info import tablespace;
这样mysql的数据在目标机器上就还原了。当然还有缺陷,因为当问题mysql没有启动的时候,数据还是会在写入,这部分数据怎么办?
另外一个问题是 lower_case_table_names=0
,因为C++的程序大小写敏感,所以不要将数据表更名字。
lower_case_table_names=0 表名存储为给定的大小和比较是区分大小写的
lower_case_table_names=1 表名存储在磁盘是小写的,但是比较的时候是不区分大小写
lower_case_table_names=2 表名存储为给定的大小写但是比较的时候是小写的
出现下面的问题,应该是你删除了数据库的ibd
文件,与缓存中不匹配,重启mysql即可
2023-01-03T21:10:45.092130+08:00 15 [Warning] InnoDB: Tablespace 'bskj/trial_info_bsjl' exists in the cache with id 229 != 305
2023-01-03T21:10:45.099017+08:00 15 [Warning] InnoDB: Tablespace 'bskj/user_info' exists in the cache with id 230 != 306
2023-01-03T21:11:10.520171+08:00 15 [Warning] InnoDB: Tablespace 'bskj/user_login' exists in the cache with id 231 != 308
2023-01-03T21:11:28.121068+08:00 15 [Note] Aborted connection 15 to db: 'bskj' user: 'root' host: 'localhost' (Query execution was interrupted)
2023-01-03T21:19:33.085640+08:00 65 [Warning] InnoDB: Tablespace 'bskj/czy_setmeal' exists in the cache with id 172 != 386