MYSQL8.0默认使用caching_sha2_password导致备份process进程错误

56人浏览 / 0人评论 / 添加收藏

最近在用java写一个备份数据库的服务:

代码如下:

// 备份命令
        StringBuilder cmd = new StringBuilder().append("mysqldump ")
                .append("--no-tablespaces ")
                .append("-h").append(ip)
                .append(" -u").append(userName)
                .append(" -p").append(password)
                // 排除MySQL备份表
                .append(" --ignore-table ").append(database_name).append(".mysql_backups ")
                .append(database_name)
                .append(" > ").append(absoultePath);
        // 判断文件是否保存成功
        if (!FileUtil.exists(filePath)) {
            FileUtils.forceMkdir(new File(filePath));
            throw new RuntimeException("备份失败,文件保存异常,请查看文件内容后重新尝试!");
        }
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase();
        String[] command = new String[0];
        if (Constants.isSystem(osName)) {
            // Windows
            command = new String[]{"cmd", "/c", String.valueOf(cmd)};
        } else {
            // Linux
            command = new String[]{"/bin/sh", "-c", String.valueOf(cmd)};
        }


        log.info("数据库备份命令为:{}", cmd);
        // 获取Runtime实例
        Process process = null;
        try {
            //有可能发生执行命令的时候发生错误,参考这个文章:https://www.cnblogs.com/A121/p/17806596.html
            //主要是mysql8默认的密码插件是aching_sha2_password,而我们默认的是mysql_native_password,所以可能会存在问题
            //如果发现执行错误的话,就检查下这个问题
            process = Runtime.getRuntime().exec(command);
            if (process.waitFor() == 0) {
                log.info("Mysql 数据库备份成功,备份文件名:{}", mysqlFileName);
            }else{
                log.error("执行命令行错误,脚本运行不成功,请检查。");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

执行到

process = Runtime.getRuntime().exec(command);

process变量会显示not exited,死活不成功,后面排查发现在容器执行mysqldump -h -p -u这个命令导出整库的时候会发现这个错误:

错误提示:The server requested authentication method unknown to the client [caching_sha2_password]

让我想起来数据库我使用的是mysql8,所以按照这个文章进行修改:

mysql> use mysql;
mysql> select host,user,select_priv,plugin from user;
+---------------+------------------+-------------+-----------------------+
| host          | user             | select_priv | plugin                |
+---------------+------------------+-------------+-----------------------+
| %             | root             | N           | caching_sha2_password |
| localhost     | mysql.infoschema | Y           | caching_sha2_password |
| localhost     | mysql.session    | N           | caching_sha2_password |
| localhost     | mysql.sys        | N           | caching_sha2_password |
| localhost     | robot            | Y           | caching_sha2_password |
+---------------+------------------+-------------+-----------------------+
7 rows in set (0.00 sec)
mysql> alter user 'root'@'%' identified with mysql_native_password by '123456';
Query OK, 0 rows affected (0.04 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)

再执行上面的代码就可以了,大家一定要注意这个mysql8默认的密码登录模式引起的代码问题。

全部评论