Error: ERROR 505 (42000): Table is read only. (state=42000,code=505)
org.apache.phoenix.schema.ReadOnlyTableException: ERROR 505 (42000): Table is read only.
at org.apache.phoenix.query.ConnectionQueryServicesImpl.generateTableDescriptor(ConnectionQueryServicesImpl.java:765)
at org.apache.phoenix.query.ConnectionQueryServicesImpl.ensureTableCreated(ConnectionQueryServicesImpl.java:991)
at org.apache.phoenix.query.ConnectionQueryServicesImpl.createTable(ConnectionQueryServicesImpl.java:1369)
at org.apache.phoenix.schema.MetaDataClient.createTableInternal(MetaDataClient.java:2116)
at org.apache.phoenix.schema.MetaDataClient.createTable(MetaDataClient.java:828)
at org.apache.phoenix.compile.CreateTableCompiler$2.execute(CreateTableCompiler.java:183)
at org.apache.phoenix.jdbc.PhoenixStatement$2.call(PhoenixStatement.java:338)
at org.apache.phoenix.jdbc.PhoenixStatement$2.call(PhoenixStatement.java:326)
at org.apache.phoenix.call.CallRunner.run(CallRunner.java:53)
at org.apache.phoenix.jdbc.PhoenixStatement.executeMutation(PhoenixStatement.java:324)
at org.apache.phoenix.jdbc.PhoenixStatement.execute(PhoenixStatement.java:1345)
at sqlline.Commands.execute(Commands.java:822)
at sqlline.Commands.sql(Commands.java:732)
at sqlline.SqlLine.dispatch(SqlLine.java:808)
at sqlline.SqlLine.begin(SqlLine.java:681)
at sqlline.SqlLine.start(SqlLine.java:398)
at sqlline.SqlLine.main(SqlLine.java:292)
解决办法:
1.如果使用了hbase中的自定义namespace,不仅仅使用default,那么在phoenix中与之对应的是schema的概念,但是默认并没有开启,需要在hbase-site.xml中增加以下配置项:
<property>
<name>phoenix.schema.isNamespaceMappingEnabled</name>
<value>true</value>
</property>
<property>
<name>phoenix.schema.mapSystemTablesToNamespace</name>
<value>true</value>
</property>
2.hbase严格区分大小写,表名和列族以及列名需要用双引号括起来,并且需要加上命名空间
create view “TEST:USER”(pk varchar primary key,“url”.“id” varchar,“url”.“url_id” varchar,“url”.“url_name” varchar) as select * from “TEST:USER”
注意:如果是:APACHE整合的CDH的版本
使用 create view TEST.USER(pk varchar primary key,url.id varchar,url.url_id varchar,url.url_name varchar) as select * from TEST.USER;
引号全去掉,命名空间修改为TEST.USER
查询方式也要修改
select * from TEST.USER;
3.在Phoenix中查询时需要加上命名空间和双引号
select * from “TEST:USER”;
4.如果是创建table(TEST为自定义命名空间)
create tableTEST.USER(pk varchar primary key,url.id varchar,url.url_id varchar,url.url_name varchar)
这里有几点需要注意:
a) Phoenix 对表名和列名都是区分大小写的,但是,如果不加双引号,则默认为大写。
b) 表名要和 HBase 中建立的表名一致。HBase 默认的主列名是 ROW,所以要将“ROW”设置为主键。列簇和列名也要用双引号括起来,要不然小写会自动变成大写。
特别注意:如果你使用的是 Phoenix 4.10 及以上的版本,可能会遇到查不出数据的情况:
那么如何解决这个问题呢?
在使用 Phoenix 创建表的时候,需要设置 COLUMN_ENCODED_BYTES 属性为 0,即不让 Phoenix 对 column family 进行编码。
create table TEST.USER(pk varchar primary key,url.id varchar,url.url_id varchar,url.url_name varchar) column_encoded_bytes=0;
另外,根据官方文档的内容,“One can set the column mapping property only at the time of creating the table. ”,也就是说只有在创建表的时候才能够设置属性。如果在创建的时候没有设置,之后怎么去设置就不太清楚了,可能是无法改变,至少目前我还没有找到相关方法。所以大家在创建映射表的时候一定要注意设置属性。