Eclipse中Spark集成Hive遇只读数据库权限错误及Derby替代MySQL问题
解决Spark-Hive集成中Derby只读异常及MySQL元存储未加载问题
嘿,从你贴的异常栈、配置和代码来看,核心问题有两个:
- Spark根本没加载到你配置的MySQL元存储, fallback到了默认的嵌入式Derby数据库——这就是为啥异常信息来自Derby而非MySQL的原因
- 非root用户运行时,对Derby默认的存储目录(一般是当前项目目录下的
metastore_db)没有读写权限,直接触发了只读模式的错误
下面一步步帮你解决:
一、先让Spark用上MySQL元存储
Spark默认会从classpath里读hive-site.xml,但Eclipse项目里经常会出现配置没生效的情况,给你几个靠谱的解决方式:
1. 确保hive-site.xml在正确的路径
- 把你的
hive-site.xml复制到Spark安装目录的conf文件夹(比如$SPARK_HOME/conf) - 或者在你的Eclipse项目里,把
hive-site.xml放到src/main/resources目录下,这样项目编译时它会自动被加到classpath里
2. 代码里直接硬编码元存储配置(兜底方案)
如果上面的方法还是不生效,直接在SparkSession构建时加上配置,彻底避免依赖外部文件:
SparkSession spark = SparkSession.builder() .appName("Spark Hive Test") .master("local[*]") .config("spark.sql.warehouse.dir", "/user/hive/warehouse") // 手动指定MySQL元存储的连接参数 .config("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true") .config("javax.jdo.option.ConnectionDriverName", "com.mysql.jdbc.Driver") .config("javax.jdo.option.ConnectionUserName", "hive") .config("javax.jdo.option.ConnectionPassword", "password") .config("hive.metastore.uris", "thrift://localhost:33306") // 和你hive-site.xml里的端口对应 .enableHiveSupport() .getOrCreate();
二、验证MySQL的权限和连接
别光顾着配Spark,先确保MySQL这边没问题:
- 登录MySQL,给
hive用户开全权限:
GRANT ALL PRIVILEGES ON hive.* TO 'hive'@'localhost' IDENTIFIED BY 'password'; FLUSH PRIVILEGES;
- 用命令行或数据库客户端测试下
jdbc:mysql://localhost:3306/hive能不能正常连接,看看hive数据库有没有自动创建出来
三、搞定非root用户的权限问题
就算切换到MySQL,也要确保几个关键路径有读写权限:
spark.sql.warehouse.dir指定的/user/hive/warehouse:执行chown -R 你的用户名:你的用户名 /user/hive/warehouse,比如chown -R m_usr:m_usr /user/hive/warehouse- 加载数据的本地文件
/home/m_usr/temp/hiveTest.txt:确保这个文件对当前用户有读权限,不行就chmod 644 /home/m_usr/temp/hiveTest.txt
为啥root用户跑起来没问题?
其实很好理解:root用户拥有系统所有目录的读写权限,就算Spark用了默认的Derby,root也能随便写metastore_db目录,不会触发只读异常;而且root环境下的Spark配置可能更完整,刚好读到了正确的hive-site.xml。
最后提醒下,Derby只是Hive默认的嵌入式元存储,只适合单节点临时测试,实际开发还是用MySQL这种独立数据库更靠谱。
内容的提问来源于stack exchange,提问作者Joseph Hwang
相关产品推荐
相关产品推荐

