rust 学习

最开始是通过官方网站上这本书来学习 https://doc.rust-lang.org/book/

通读之后开始学习 https://github.com/rust-lang/rustlings/

中间参与了一个开源项目 https://github.com/database-mesh/pisanix/tree/master

最近开始学习 https://exercism.org/tracks/rust

最近 rust 学习又有了一些新突破

从零手写文本编辑器 https://www.flenker.blog/hecto/ 这个教程里分成了多个 commit 带着你一步步的完成编辑器,看着自己的代码逐步变成可以使用的文本编辑器,真的很不错哦。

Connection is not avaible

Connection is not available, request timed out after 30000ms

最近碰到一个这个异常,前端是 xxl-job 任务,后端将 shardingsphere-proxy 作为数据源来使用。

  1. 偶发,频率比较高

网络上相关解释 从 Hikari 拿连接,但是拿不到,要不就是达到最大连接数了 https://stackoverflow.com/questions/32968530/hikaricp-connection-is-not-available

  1. Mysql 连接数上看,两台实例 205, 206 都是没有超过 1000 最大连接数 20000

  2. 这个是业务的报错,想拿 connection 拿不到,不确定是 proxy 报的还是业务报的, proxy 无异常日志 根据日志找到了业务的库配置

spring.datasource.dynamic.datasource.sharding0.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.sharding0.druid.initial-size = 5
spring.datasource.dynamic.datasource.sharding0.druid.max-active = 100
spring.datasource.dynamic.datasource.sharding0.druid.max-wait = 60000
spring.datasource.dynamic.datasource.sharding0.druid.min-idle = 5
spring.datasource.dynamic.datasource.sharding0.druid.validation-query = select 1
spring.datasource.dynamic.datasource.sharding0.password = root
spring.datasource.dynamic.datasource.sharding0.url = jdbc:mysql://xxx?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.dynamic.datasource.sharding0.username = root

奇怪的是为什么是 druid 连接池,但是却没有 druid 相关信息?

使用idea创建的 jar 文件都是 .java 而不是 .class

通过如下步骤打包后发现 jar 包中的文件都是 .java 文件,而不是 .class 文件

经过了一下午的尝试,发现手动创建包,然后指定 .class 文件可以成功打包。

不过没有特别需求还是直接用 maven 吧,简单些,无需添加任何插件,直接 mvn clean install 即可。

如果 result set 仅有一个结果集,是否可以用 if(resultset.next()) ?

今天写代码时遇到一个异常。如下

java.sql.SQLException: Streaming result set com.mysql.jdbc.RowDataDynamic@4b76a937 is still active. No statements may be issued when any streaming result sets are open and in use on a given connection. Ensure that you have called .close() on any active streaming result sets before attempting more queries.
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:869)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:865)
	at com.mysql.jdbc.MysqlIO.checkForOutstandingStreamingData(MysqlIO.java:3172)

我推测可能是结果集没有关闭,然后想要继续创建结果集。 发现跟之前的代码唯一的区别如下

是否可以在 jdbc 查询数据的同时获取本次查询的数据量?

背景

在优化全局二级索引的过程中,有一个优化点是如果二级索引的数据量太大,那么带回主表再查可能引起一些问题,例如效率不高,OOM 或者 SQL 超长等问题,因此考虑二级索引表数据量大的时候,直接查询主表。 因此需要查询二级索引表的数据量。 这里考虑能否直接查询二级索引表的同时获取本次查询结果的数据量。

实践

方式一

通过 ResultSet.TYPE_SCROLL_INSENSITIVE 可以将游标放到最后,然后根据 getRow() 方法获取

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true", "root", "123456");
        // 设置游标可以滚动,默认是 forward only
        try (PreparedStatement preparedStatement = connection.prepareStatement("select * from t_single", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                ResultSet resultSet = preparedStatement.executeQuery()) {
            int count = 0;
            // 移动到最后
            if (resultSet.last()) {
                // 获取最后一行的行号
                count = resultSet.getRow();
            }
            System.out.println("total:" + count);
            resultSet.beforeFirst();
            int columnIndex = 1;
            while (resultSet.next()) {
                System.out.println(resultSet.getObject(columnIndex ++));
            }
        }
    }

但是为什么之前的很多框架都采用的 count sql,而不用这种方式呢?例如 pageHelper 等 https://cloud.tencent.com/developer/article/1433806 搜索到相关文章,发现 TYPE_SCROLL_INSENSITIVE 会将结果集缓存起来,容易 OOM。那么这种方式可能问题就比较大了。 如果二级索引表查询出的数据量比较大,缓存结果集的风险就比较大了。